、 实现思路方法
首先介绍下WinlogonWindows 2000/NT有 3种系统状态:没有用户登录状态、用户成功登录状态以及工作站锁定状态Winlogon是Windows 2000/NT操作系统提供交互式登录支持组件Winlogon有 3个组成部分:可执行文件winlogon.exe提供图形界面认证功能动态库Gina Dll以及些网络服务提供动态库Network Provider Dll参考模型如下:
winlogon.exe处理些下层导出接口而认证策略是在Gina Dll中独立设计在系统启动时Gina Dll被winlogon.exe装载Microsoft提供了个默认Gina Dll--Winnt\\system32\\msgina.dll提供了标准用户名、密码认证模式Gina Dll是可替换用户可以设计自己Gina Dll以提供其他如智能卡、视网膜、指纹或其他些认证机制
开发自定义Gina Dll必须实现并导出和winlogon.exe交互18个标准接口包括WlxNegotiate、WlxInitialize、WlxLoggedOnSAS等(其他接口请参考Msdn)其中WlxNegotiate是winlogon.exe第个接口进行必要版本判断随后是WlxInitialize主要完成winlogon.exe特定版本分派表向Gina Dll传递笔者还要介绍说明是WlxLoggedOnSAS这个主要功能是当winlogon在登录成功状态下接收到SAS事件于是这个进行SAS事件识别以及进行各事件相应处理
自定义Gina Dll使用比如开发Gina Dll文件名为MyGina.dll将该文件放到以下路径:Winnt\\system32并修改注册表如下:
Key Name: \\HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\ Winlogon
Value Name: GinaDLL
Value Type: [REG_SZ]
Value: MyGina.dll
重新启动计算机MyGina.dll即投入使用在用户登录成功状态下按下Ctrl+Alt+Del时系统不再弹出\"Widows安全\"对话框由于并不需要改变用户名、密码这种标准认证模式所以可以仍然使用msgina.dll中导出接口而对WlxLoggedOnSAS实现进行必要改变不管接收到什么SAS事件该直接返回WLX_SAS_ACTION_NONE而不做其他处理
2、编程步骤
1、启动Visual C6.0新建个项目选择MFC AppWizard(dll),项目名输入为MyGina按下\"OK\"后选择Regular DLL with MFC ally linked按下\"Finish\";
2、使用Class Wizard重载CmyGinaApp类InitInstance()和ExitInstance()两个并注意在Stdafx.h中加入# <Winwlx.h>;
3、在MyGina.h文件中介绍说明\"extern CMyGinaApp theApp\"以便于其他地方对theApp引用;在类CMyGinaApp中定义成员变量(具体内容见代码部分);
4、添加代码编译
3、代码
// //////////////////////////////////////////MyGina.h : header file for the MYGINA DLL
# !d(AFX_MYGINA_H__5959C4FD_1D31_4E51_B3CD_B5649C8473B7__INCLUDED_)
# AFX_MYGINA_H__5959C4FD_1D31_4E51_B3CD_B5649C8473B7__INCLUDED_
# _MSC_VER > 1000
#pragma _disibledevent=>
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP
};
extern CMyGinaApp theApp;
#end
//////////////////
# \"stdafx.h\"
# \"MyGina.h\"
#def _DEBUG
# DEBUG_NEW
#undef THIS_FILE
char THIS_FILE = __FILE__;
#end
/////////////////////////////////////////////////////////////////////////////// CMyGinaApp
BEGIN_MESSAGE_MAP(CMyGinaApp, CWinApp)
//{{AFX_MSG_MAP(CMyGinaApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP
////////////////////////////////////////////// CMyGinaApp construction
CMyGinaApp::CMyGinaApp
{
// 化各变量
hMsDll = NULL;
MyWlxNegotiate = NULL;
MyWlxInitialize = NULL;
MyWlxActivateUserShell = NULL;
MyWlxDisplayLockedNotice = NULL;
MyWlxDisplaySASNotice = NULL;
MyWlxDisplayStatusMessage = NULL;
MyWlxGetStatusMessage = NULL;
MyWlxIsLockOk = NULL;
MyWlxIsLogoffOk = NULL;
MyWlxLoggedOnSAS = NULL;
MyWlxLoggedOutSAS = NULL;
MyWlxLogoff = NULL;
MyWlxNetworkProviderLoad = NULL;
MyWlxRemoveStatusMessage = NULL;
MyWlxScreenSaverNoty = NULL;
MyWlxShutdown = NULL;
MyWlxStartApplication = NULL;
MyWlxWkstaLockedSAS = NULL;
}
CMyGinaApp theApp;
BOOL CMyGinaApp::InitInstance
{
// 得到默认gina dll
(hMsDll NULL)
{
hMsDll = ::LoadLibrary(\"msgina.dll\");
}
// 导入各个接口
(hMsDll != NULL)
{
MyWlxNegotiate= (NEGOTIATE) GetProcAddress(hMsDll,\"WlxNegotiate\");
MyWlxInitialize= (INITIALIZE) GetProcAddress(hMsDll,\"WlxInitialize\");
MyWlxActivateUserShell= (ACTIVATE_USHELL)GetProcAddress(hMsDll,\"WlxActivateUserShell\");
MyWlxDisplayLockedNotice= (PARAM_PVOID)GetProcAddress(hMsDll,\"WlxDisplayLockedNotice\");
MyWlxDisplaySASNotice= (PARAM_PVOID)GetProcAddress(hMsDll,\"WlxDisplaySASNotice\");
MyWlxDisplayStatusMessage= (DISP_STATUS)GetProcAddress(hMsDll,\"WlxDisplayStatusMessage\");
MyWlxGetStatusMessage= (GET_STATUS)GetProcAddress(hMsDll,\"WlxGetStatusMessage\");
MyWlxIsLockOk= (PARAM_PVOID)GetProcAddress(hMsDll,\"WlxIsLockOk\");
MyWlxIsLogoffOk= (PARAM_PVOID)GetProcAddress(hMsDll,\"WlxIsLogoffOk\");
MyWlxLoggedOnSAS= (LOGON_SAS)GetProcAddress(hMsDll,\"WlxLoggedOnSAS\");
MyWlxLoggedOutSAS= (LOGOUT_SAS)GetProcAddress(hMsDll,\"WlxLoggedOutSAS\");
MyWlxLogoff= (PARAM_PVOID) GetProcAddress(hMsDll,\"WlxLogoff\");
MyWlxNetworkProviderLoad= (NETWORK_LOAD)GetProcAddress(hMsDll,\"WlxNetworkProviderLoad\");
MyWlxRemoveStatusMessage= (PARAM_PVOID)GetProcAddress(hMsDll,\"WlxRemoveStatusMessage\");
MyWlxScreenSaverNoty= (SCR_SAVER)GetProcAddress(hMsDll,\"WlxScreenSaverNoty\");
MyWlxShutdown= (SHUT_DOWN)GetProcAddress(hMsDll,\"WlxShutdown\");
MyWlxStartApplication= (START_APP)GetProcAddress(hMsDll,\"WlxStartApplication\");
MyWlxWkstaLockedSAS= (LOCKED_SAS)GetProcAddress(hMsDll,\"WlxWkstaLockedSAS\");
}
CWinApp::InitInstance;
}
CMyGinaApp::ExitInstance
{
(hMsDll != NULL)
{
::FreeLibrary(hMsDll);//卸载动态链接库;
hMsDll = NULL;
}
CWinApp::ExitInstance;
}
////////////////////////////////////////////消息处理实现;
# \"StdAfx.h\"
# \"MyGina.h\"
// Winlogon.exegina dll中第个
// 使gina dll确认是否支持当前版本Winlogon.exe
// 传递给winlogon.exe需要那个版本接口
BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)
{
theApp.MyWlxNegotiate(dwWinLogonVersion,pdwDllVersion);
}
// 化winlogon.exe向gina dll传递需要版本接口分配表
BOOL WINAPI WlxInitialize(LPWSTR lpWinsta,HANDLE hWlx,PVOID pvReserved,PVOID pWinlogonFunctions,PVOID * pWlxContext)
{
theApp.MyWlxInitialize(lpWinsta,hWlx,pvReserved,pWinlogonFunctions,pWlxContext);
}
// 用户登陆成功后Winlogon.exe该启动用户外壳
BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext,PWSTR pszDesktopName,PWSTR pszMprLogonScript,PVOID pEnvironment)
{
theApp.MyWlxActivateUserShell(pWlxContext,pszDesktopName,pszMprLogonScript,pEnvironment);
}
// 当系统处于锁定状态时Winlogon.exe该
// 显示些信息如锁定者、锁定时间等
VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
{
theApp.MyWlxDisplayLockedNotice(pWlxContext);
}
// 当没有任何用户登陆时Winlogon.exe该显示些提示信息
// 可以根据用户动作模拟SAS事件发送
VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
{
theApp.MyWlxDisplaySASNotice(pWlxContext);
}
// 当gina dll要显示些信息时Winlogon.exe该
// 直接返回TRUE表示信息已经显示
BOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext,
HDESK hDesktop,
DWORD dwOptions,
PWSTR pTitle,
PWSTR pMessage)
{
theApp.MyWlxDisplayStatusMessage(pWlxContext,hDesktop,dwOptions,pTitle,pMessage);
// TRUE;
}
// Winlogon.exe该得到gina dll显示状态信息
// 直接返回TRUE表示信息已经接收
BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext,
DWORD *pdwOptions,
PWSTR pMessage,
DWORD dwBufferSize)
{
theApp.MyWlxGetStatusMessage(pWlxContext,pdwOptions,pMessage,dwBufferSize);
// TRUE;
}
// 在试图锁定工作站的前Winlogon.exe该判断是否可以锁定
// 直接返回FALSE表示不能锁定
BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
{
theApp.MyWlxIsLockOk(pWlxContext);
// FALSE;
}
// 在试图注销时Winlogon.exe该判断能否注销
// 直接返回FALSE表示不能注销
BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
{
theApp.MyWlxIsLogoffOk(pWlxContext);
// FALSE;
}
// 当系统处于登陆成功没有锁定状态下
// Winlogon接收到SAS事件于是该
// 现屏蔽所有事件直接返回
WINAPI WlxLoggedOnSAS(PVOID pWlxContext,
DWORD dwSasType,
PVOID pReserved)
{
WLX_SAS_ACTION_NONE;
}
// 在没有任何个用户登陆情况下Winlogon.exe接收到SAS事件该
WINAPI WlxLoggedOutSAS(PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pMprNotyInfo,
PVOID * pProfile)
{
theApp.MyWlxLoggedOutSAS(pWlxContext,dwSasType,pAuthenticationId,
pLogonSid,pdwOptions,phToken,pMprNotyInfo,pProfile);
}
// Winlogon.exe该通知gina dll用户注销操作
// 允许gina dll做出相应处理
VOID WINAPI WlxLogoff(PVOID pWlxContext)
{
theApp.MyWlxLogoff(pWlxContext);
}
// Winlogon.exe该收集有效认证信息
// 返回TRUE表示用户被识别
BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext,
PWLX_MPR_NOTIFY_INFO pNprNotyInfo)
{
theApp.MyWlxNetworkProviderLoad(pWlxContext,pNprNotyInfo);
// TRUE;
}
// Winlogon.exe该告诉gina dll停止显示状态信息
// 直接返回TRUE表示信息已经删除
BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
{
theApp.MyWlxRemoveStatusMessage(pWlxContext);
// TRUE;
}
// 在屏保启动前瞬Winlogon.exe该允许gina dll同屏保交互
// 返回FALSE表示屏保不能启动
BOOL WINAPI WlxScreenSaverNoty(PVOID pWlxContext, BOOL *pSecure)
{
theApp.MyWlxScreenSaverNoty(pWlxContext,pSecure);
}
// 在系统关闭的前Winlogon.exe该
// 允许gina dll处理些系统关闭前处理
VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
{
theApp.MyWlxShutdown(pWlxContext,ShutdownType);
}
// 当系统要求在用户上下文中启动Winlogon.exe该
// 这种情况发生在:浏览器非正常关闭需要重启或需要启动扩展任务管理器
// 该接口gina dll可以选择性实现
BOOL WINAPI WlxStartApplication(PVOID pWlxContext,PWSTR pszDesktopName,PVOID pEnvironment,PWSTR pszCmdLine)
{
theApp.MyWlxStartApplication(pWlxContext,pszDesktopName,pEnvironment,pszCmdLine);
}
// 在锁定状态下Winlogon.exe接收到SAS事件该
WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
{
theApp.MyWlxWkstaLockedSAS(pWlxContext,dwSasType);
}
最新评论