Chinaunix首页 | 论坛 | 博客
  • 博客访问: 28778
  • 博文数量: 25
  • 博客积分: 150
  • 博客等级: 入伍新兵
  • 技术积分: 160
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-01 16:32
文章分类
文章存档

2012年(25)

我的朋友
最近访客

分类:

2012-03-01 16:36:37

本文介绍了一种简单易行的方法,实现在用户登录成功后,按下Ctrl+Alt+Del不再弹出"Windows安全"对话框。

关键词:GINA(Graphical Identification aNd Authentication) SAS(Secure Attention Sequence)

一. 开发原理

首先介绍一下Winlogon。Windows 2000/NT有三种系统状态:没有用户登录状态、用户成功登录状态以及工作站锁定状态。Winlogon是Windows 2000/NT操作系统提供交互式登录支持的组件。Winlogon有三个组成部分:可执行文件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: NT\\CurrentVersion\\ Winlogon

value Name: GinaDLL

value Type: [REG_SZ]

value: MyGina.dll

重新启动计算机Gina.dll即投入使用。

二. 应用实例

应用要求:在用户登录成功状态下,按下Ctrl+Alt+Del时系统不再弹出"Widows安全"对话框。由于并不需要改变用户名、密码这种标准的认证模式,所以可以仍然使用msgina.dll中导出的函数接口,而对WlxLoggedOnSAS函数的实现进行必要的改变。

开发环境:Windows 2000,PII 400

开发工具:Microsoft Visual C++ 6.0

开发步骤:

1.新建项目,选择MFC AppWizard(dll),项目名输入为MyGina。按下"OK"后,选择Regular DLL with MFC statically linked,按下"Finish"。

2.使用View->ClassWizard为CmyGinaApp增加InitInstance和ExitInstance两个函数的覆盖。

3.在MyGina.h文件中说明"extern CMyGinaApp theApp",以便于程序其他地方对theApp的引用;在类CMyGinaApp中定义成员变量(具体内容见代码部分);

4.由于要导入msgina.dll的接口函数,所以在MyGina.h中定义接口函数变量类型,如下:

typedef (WINAPI * NEGOTIATE)       (DWORD,PDWORD);
typedef (WINAPI * INITIALIZE)      (LPWSTR,HANDLE,PVOID,PVOID,PVOID *);
typedef (WINAPI * ACTIVATE_USHELL) (PVOID,PWSTR,PWSTR,PVOID);
typedef (WINAPI * PARAM_PVOID)     (PVOID);
typedef (WINAPI * DISP_STATUS)     (PVOID,HDESK,DWORD,PWSTR,PWSTR);
typedef (WINAPI * GET_STATUS)      (PVOID,DWORD *,PWSTR,DWORD);
typedef (WINAPI * LOGON_SAS)       (PVOID,DWORD,PVOID);
typedef (WINAPI * LOGOUT_SAS)      (PVOID,DWORD,PLUID,PSID,PDWORD, PHANDLE,WLX_MPR_NOTIFY_INFO,PVOID *);
typedef (WINAPI * NETWORK_LOAD)    (PVOID,PWLX_MPR_NOTIFY_INFO);
typedef (WINAPI * SCR_SAVER)       (PVOID,BOOL  *);
typedef (WINAPI * SHUT_DOWN)       (PVOID,DWORD);
typedef (WINAPI * START_APP)       (PVOID,PWSTR,PVOID,PWSTR);
typedef (WINAPI * LOCKED_SAS)      (PVOID,DWORD);
并在类CmyGinaApp中定义成员变量,如下:
private:
    HMODULE   hMsDll;
public:
    NEGOTIATE         MyWlxNegotiate;
    INITIALIZE        MyWlxInitialize;
    ACTIVATE_USHELL   MyWlxActivateUserShell;
    PARAM_PVOID       MyWlxDisplayLockedNotice;
    PARAM_PVOID       MyWlxDisplaySASNotice;
    DISP_STATUS       MyWlxDisplayStatusMessage;
    GET_STATUS        MyWlxGetStatusMessage;
    PARAM_PVOID       MyWlxIsLockOk;
    PARAM_PVOID       MyWlxIsLogoffOk;
    LOGON_SAS         MyWlxLoggedOnSAS;
    LOGOUT_SAS        MyWlxLoggedOutSAS;
    PARAM_PVOID       MyWlxLogoff;
    NETWORK_LOAD      MyWlxNetworkProviderLoad;
    PARAM_PVOID       MyWlxRemoveStatusMessage;
    SCR_SAVER         MyWlxScreenSaverNotify;
    SHUT_DOWN         MyWlxShutdown;
    START_APP         MyWlxStartApplication;
    LOCKED_SAS        MyWlxWkstaLockedSAS;

注意在MyGina.h中说明extern CMyGinaApp theApp;以便于程序其他地方对theApp的引用。

4.在MyGina.cpp中,实现InitInstance如下:

    // 得到默认的gina dll
    if (hMsDll == NULL)
    {
        hMsDll = ::LoadLibrary("msgina.dll");
    }
    // 导入各个接口函数
    if (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");
    MyWlxScreenSaverNotify = (SCR_SAVER)    GetProcAddress(hMsDll,"WlxScreenSaverNotify");
    MyWlxShutdown             = (SHUT_DOWN)       GetProcAddress(hMsDll,"WlxShutdown");
    MyWlxStartApplication     = (START_APP)       GetProcAddress(hMsDll,"WlxStartApplication");
    MyWlxWkstaLockedSAS   = (LOCKED_SAS)     GetProcAddress(hMsDll,"WlxWkstaLockedSAS");
    }
实现ExitInstance如下:
    // 卸载dll
    if (hMsDll != NULL)
    {
        ::FreeLibrary(hMsDll);
        hMsDll = NULL;
    }

5.实现接口函数。由于本应用仍然保持msgina.dll的大部分操作,所以MyGina.dll的接口函数的实现较为简单。重点需要注意的是WlxLoggedOnSAS函数的实现。当在成功登录状态下,不管接收到什么SAS事件,该函数直接返回WLX_SAS_ACTION_NONE而不做其他处理。由于实现的函数较多(必须的18个),笔者仅列出代表性的五个,其余的依理类推。

// Winlogon.exe调用的gina dll中的第一个函数
// 使gina dll确认是否支持当前版本的Winlogon.exe
// 传递给winlogon.exe需要那个版本的接口函数
BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)
{
// 直接调用从msgina.dll中导入的函数
    return theApp.MyWlxNegotiate(dwWinLogonVersion,pdwDllVersion);
}

// 初始化,winlogon.exe向gina dll传递需要版本的接口函数分配表
BOOL WINAPI WlxInitialize(LPWSTR    lpWinsta,
                          HANDLE    hWlx,
                          PVOID     pvReserved,
                          PVOID     pWinlogonFunctions,
                          PVOID *   pWlxContext
                          )
{
// 直接调用从msgina.dll中导入的函数
    return theApp.MyWlxInitialize(lpWinsta,hWlx,pvReserved,pWinlogonFunctions,pWlxContext);
}
// 当系统处于锁定状态时,Winlogon.exe调用该函数
// 显示一些信息,如锁定者、锁定时间等
VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
{
    theApp.MyWlxDisplayLockedNotice(pWlxContext);
}
// 在系统关闭之前,Winlogon.exe调用该函数
// 允许gina dll处理一些系统关闭前的处理
VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
{
    theApp.MyWlxShutdown(pWlxContext,ShutdownType);
}
// 当系统处于登陆成功,没有锁定的状态下
// Winlogon接收到SAS事件,于是调用该函数
// 现屏蔽所有事件,直接返回
int WINAPI WlxLoggedOnSAS(PVOID pWlxContext,
                          DWORD dwSasType,
                          PVOID pReserved)
{
    return WLX_SAS_ACTION_NONE;
}

6.将MyGina.dll中实现的所有接口函数,在MyGina.def中定义导出

转载:http://dev.firnow.com/course/3_program/vc/vc_js/20100630/266432.html
阅读(838) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:适用于Windows NT5.0 / 5.1 / 5.2 的GINA模板代码

给主人留下些什么吧!~~