壹、原理
在NT/2000/XP/2003中交互式的登陸支持是由WinLogon調用GINA?DLL實現的,GINA?DLL提供了壹個交互式的界面為用戶登陸提供認證請求。WinLogon會和GINA?DLL進行交互,缺省是MSGINA.DLL(在System32目錄下)。微軟同時也為我們提供了接口,我們可以自己編寫GINA?DLL來代替MSGINA.DLL。
WinLogon初始化時會創建3個桌面:
winlogon桌面:主要顯示Windows?安全等界面,如妳按下CTRL+ALT+DEL,登陸的界面等
應用程序桌面:我們平時見到的那個有我的電腦的界面
屏幕保護桌面:屏幕保護顯示界面。
在默認情況下,GINA顯示登陸對話框,用戶輸入用戶名及密碼?。所以要獲得用戶名和密碼?,則可以寫壹個新的GINA?DLL,其中提供接口調用msgina.dll的函數WlxLoggedOutSAS。
二、程序實現
GINA?DLL要輸出下列函數(winlogon會調用):
(表壹)GINA?函數壹覽表
函數? 描述
WlxActivateUserShell? 激活用戶外殼程序
WlxDisplayLockedNotice? 允許GINA?DLL?顯示鎖定信息
WlxDisplaySASNotice? 當沒有用戶登陸時,Winlogon調用此函數
WlxDisplayStatusMessage? Winlogon?用壹個狀態信息調用此函數進行顯示
WlxGetConsoleSwitchCredentials? Winlogon調用此函數讀取當前登陸用戶的信任信息,並透明地將它們傳到目標會話
WlxGetStatusMessage? Winlogon?調用此函數獲取當前狀態信息
WlxInitialize? 針對指定的窗口位置進行GINA?DLL初始化
WlxIsLockOk? 驗證工作站正常鎖定
WlxIslogoffOk? 驗證註銷正常
WlxLoggedOnSAS? 用戶已登陸並且工作站沒有被加鎖,如果此時接收到SAS事件,則Winlogon?調用此函數
WlxLoggedOutSAS? 沒有用戶登陸,如果此時收到SAS事件,則Winlogon?調用此函數,?This?indicates?that?a?logon?attempt?should?be?made?。
WlxLogoff? 請求註銷操作時通知GINA?DLL?
WlxNegotiate? 表示當前的Winlogon版本是否能使用GINA?DLL
WlxNetworkProviderLoad? 在加載網絡服務提供程序收集了身份和認證信息後,Winlogon?調用此函數
WlxRemoveStatusMessage? Winlogon?調用此函數告訴GINA?DLL?停止顯示狀態信息
WlxScreensaverNotify? 允許GINA與屏幕保護操作交互
WlxShutdown? 在關閉之前Winlogon?調用此函數,允許GINA實現任何關閉任務,例如從讀卡器中退出智能卡
WlxStartApplication? 當系統需要在用戶的上下文中啟動應用程序時調用此函數
WlxWkstaLockedSAS? 當工作站被鎖定,如果接收到壹個SAS,則Winlogon?調用此函數
為了簡化編程,我們從MSGINA.DLL中動態獲取上述函數,在自定義的DLL中(以下稱為MyGina.DLL)中直接調用MSGINA.DLL的函數即可。現在我們要處理的就是WlxLoggedOutSAS函數:
int?WINAPI?WlxLoggedOutSAS(PVOIDpWlxContext,
DWORDdwSasType, PLUIDpAuthenticationId, PSID?pLogonSid, PDWORDpdwOptions, PHANDLE?phToken, PWLX_MPR_NOTIFY_INFO?pMprNotifyInfo, PVOID?*?pProfile){
//=========================加入我的登陸=========================
Clogin?login; if?(login.DoModal()==IDCANCEL) {return?WLX_SAS_ACTION_NONE;
} if(login.bCLOSE==TRUE) { return?WLX_SAS_ACTION_SHUTDOWN; } if(login.DoModal()==IDOK) { char?UserName[40]; char?PassWord[40]; char?PassWord2[40]; strcpy(UserName,theApp.MyUser); strcpy(PassWord,theApp.MyPass);//為了便於演示,直接在程序裏面比較密碼,並且把默認管理員帳號設置為自動登陸
//自動登陸函數SetAutoLogon
strcpy(PassWord2,theApp.MyPass2); //?AfxMessageBox(UserName); //?AfxMessageBox(PassWord);? if(!strcmp(UserName,"Administrator"))if(!strcmp(PassWord,"123"))
if(!strcmp(PassWord2,"456"))
{
SetAutoLogon("administrator","","123"); return?theApp.MyWlxLoggedOutSAS(pWlxContext,dwSasType,pAuthenticationId, ?pLogonSid,pdwOptions,phToken,pMprNotifyInfo,pProfile);}
} AfxMessageBox("密碼或者用戶名錯誤!不能登陸!"); return?WLX_SAS_ACTION_NONE;}
然後設計登陸框,實現自己的界面。本示例如圖所示。
三、安裝和註意事項:
(壹) 在編寫GIAN?DLL中要註意,GINA?DLL使用的是unicode。
(二) 安裝GINA?DLL的安裝:
1.?添加註冊表
鍵名?:
\HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon
變量名?:?GinaDLL
變量類型?:?[REG_SZ]
內容?:?"妳的GINA?DLL的名稱"?如:"MyGina.DLL:
2.?將妳的GINA?DLL(MyGina.dll)拷貝到系統目錄下(system32);
3.?重啟機器,妳的GINA?DLL(MyGina.dll)就會運行。
註意
1) 如果出現進不了妳的系統,那妳進入DOS後,將msgina.dll拷貝成妳的GINA?DLL(MyGina.dll)就可進入了;或者進入安全模式,刪除掉那個鍵值(?GinaDLL?)。
2) Console?程序如果想使用MFC類,必須包含<afx.h>,同時註釋掉<windows.h>。
3) 如果出現這種錯誤:“LINK?:?fatal?error?LNK1104:?cannot?open?file?"mfc42u.lib"?”,那麽說明?lib路徑的設置問題,妳的鏈接器在指定的目錄下沒有找到這個的文件,妳應該添加新的目錄以便編譯器找到所需的庫文件。具體位置:IDE中菜單Tools\Options\Directories\show?directories?for\?<library?files>。
4) 如果出現這種錯誤:“uafxcwd.lib(dllmodul.obj)?:?error?LNK2005:?_DllMain@12?already?defined?in?main.obj?”或者“mfcs42ud.lib(dllmodul.obj)?:?error?LNK2005:?_DllMain@12?already?defined?in?main.obj?”,那麽“See?if?you?have?_AFXDLL?and?_USRDLL?in?the?preprocessor?definitions.?Try?removing?one?of?them”。具體位置:IDE中?菜單Project?\?Setting?\?C/C++?\?preprocessor?definition?。