• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

VC实现Win2000下屏蔽Ctrl+Alt+Del键

发布: 2007-7-01 20:40 | 作者: admin | 来源: | 查看: 20次 | 进入软件测试论坛讨论

领测软件测试网

  大家知道,Ctrl+Alt+Del是Win2k/NT操作系统默认的系统登录/注销组合键序列,系统级别很高。在应用程序中,想要屏蔽掉该键序列的响应或得到这个"按下"事件,难度是相当大的。本例介绍了一种简单易行的方法,实现在用户登录成功后,按下Ctrl+Alt+Del不再弹出"Windows安全"对话框。需要读者朋友注意的是,本实例必须运行在Windows 2000环境下。

  一、 实现方法

  首先介绍一下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: \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而不做其他处理。

  二、编程步骤

  1、启动Visual C++6.0,新建一个项目,选择MFC AppWizard(dll),项目名输入为MyGina,按下"OK"后,选择Regular DLL with MFC statically linked,按下"Finish";

  2、使用Class Wizard重载CmyGinaApp类的InitInstance()和ExitInstance()两个函数,并注意在Stdafx.h中加入#include <Winwlx.h>;

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

  4、添加代码,编译程序。

  三、程序代码

// //////////////////////////////////////////MyGina.h : main header file for the MYGINA DLL

#if !defined(AFX_MYGINA_H__5959C4FD_1D31_4E51_B3CD_

B5649C8473B7__INCLUDED_)

#define AFX_MYGINA_H__5959C4FD_1D31_4E51_B3CD_

B5649C8473B7__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__

#error include @#stdafx.h@# before including this file for PCH

#endif

#include "resource.h" // main symbols

//定义的函数类型;

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,PWLX_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);

 

class CMyGinaApp : public CWinApp

{

 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;

 public:

  CMyGinaApp();

  // Overrides

  // ClassWizard generated virtual function overrides

  //{{AFX_VIRTUAL(CMyGinaApp)

   public:

    virtual BOOL InitInstance();

    virtual int ExitInstance();

  //}}AFX_VIRTUAL

  //{{AFX_MSG(CMyGinaApp)

  // NOTE - the ClassWizard will add and remove member functions here.

  // DO NOT EDIT what you see in these blocks of generated code !

  //}}AFX_MSG

 DECLARE_MESSAGE_MAP()

};

 

extern CMyGinaApp theApp;

#endif

//////////////////

 

#include "stdafx.h"

#include "MyGina.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////// 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;

 MyWlxScreenSaverNotify = NULL;

 MyWlxShutdown = NULL;

 MyWlxStartApplication = NULL;

 MyWlxWkstaLockedSAS = NULL;

}

 

CMyGinaApp theApp;

 

BOOL CMyGinaApp::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");

 }

 return CWinApp::InitInstance();

}

 

int CMyGinaApp::ExitInstance()

{

 if (hMsDll != NULL)

 {

  ::FreeLibrary(hMsDll);//卸载动态链接库;

  hMsDll = NULL;

 }

 return CWinApp::ExitInstance();

}

////////////////////////////////////////////消息处理函数的实现;

#include "StdAfx.h"

#include "MyGina.h"

// Winlogon.exe调用的gina dll中的第一个函数

// 使gina dll确认是否支持当前版本的Winlogon.exe

// 传递给winlogon.exe需要那个版本的接口函数

BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)

{

 return theApp.MyWlxNegotiate(dwWinLogonVersion,pdwDllVersion);

}

 

// 初始化,winlogon.exe向gina dll传递需要版本的接口函数分配表

BOOL WINAPI WlxInitialize(LPWSTR lpWinsta,HANDLE hWlx,PVOID pvReserved,PVOID pWinlogonFunctions,PVOID * pWlxContext)

{

 return theApp.MyWlxInitialize(lpWinsta,hWlx,pvReserved,pWinlogonFunctions,pWlxContext);

}

 

// 用户登陆成功后,Winlogon.exe调用该函数启动用户外壳程序

BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext,PWSTR pszDesktopName,PWSTR pszMprLogonScript,PVOID pEnvironment)

{

 return 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)

{

 return theApp.MyWlxDisplayStatusMessage(pWlxContext,hDesktop,dwOptions,pTitle,pMessage);

 // return TRUE;

}

 

// Winlogon.exe调用该函数得到gina dll显示的状态信息

// 直接返回TRUE表示信息已经接收

BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext,

DWORD *pdwOptions,

PWSTR pMessage,

DWORD dwBufferSize)

{

 return theApp.MyWlxGetStatusMessage(pWlxContext,pdwOptions,pMessage,dwBufferSize);

 // return TRUE;

}

 

// 在试图锁定工作站之前Winlogon.exe调用该函数,判断是否可以锁定

// 直接返回FALSE表示不能锁定

BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)

{

 return theApp.MyWlxIsLockOk(pWlxContext);

 // return FALSE;

}

 

// 在试图注销时Winlogon.exe调用该函数,判断能否注销

// 直接返回FALSE表示不能注销

BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)

{

 return theApp.MyWlxIsLogoffOk(pWlxContext);

 // return FALSE;

}

 

// 当系统处于登陆成功,没有锁定的状态下

// Winlogon接收到SAS事件,于是调用该函数

// 现屏蔽所有事件,直接返回

int WINAPI WlxLoggedOnSAS(PVOID pWlxContext,

DWORD dwSasType,

PVOID pReserved)

{

 return WLX_SAS_ACTION_NONE;

}

 

// 在没有任何一个用户登陆的情况下,Winlogon.exe接收到SAS事件调用该函数

int WINAPI WlxLoggedOutSAS(PVOID pWlxContext,

DWORD dwSasType,

PLUID pAuthenticationId,

PSID pLogonSid,

PDWORD pdwOptions,

PHANDLE phToken,

PWLX_MPR_NOTIFY_INFO pMprNotifyInfo,

PVOID * pProfile)

{

 return theApp.MyWlxLoggedOutSAS(pWlxContext,dwSasType,pAuthenticationId,

  pLogonSid,pdwOptions,phToken,pMprNotifyInfo,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 pNprNotifyInfo)

{

 return theApp.MyWlxNetworkProviderLoad(pWlxContext,pNprNotifyInfo);

 // return TRUE;

}

 

// Winlogon.exe调用该函数,告诉gina dll停止显示状态信息

// 直接返回TRUE表示信息已经删除

BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)

{

 return theApp.MyWlxRemoveStatusMessage(pWlxContext);

 // return TRUE;

}

 

// 在屏保程序启动前一瞬Winlogon.exe调用该函数,允许gina dll同屏保程序交互

// 返回FALSE表示屏保程序不能启动

BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)

{

 return theApp.MyWlxScreenSaverNotify(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)

{

 return theApp.MyWlxStartApplication(pWlxContext,pszDesktopName,pEnvironment,pszCmdLine);

}

 

// 在锁定状态下,Winlogon.exe接收到SAS事件调用该函数

int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)

{

 return theApp.MyWlxWkstaLockedSAS(pWlxContext,dwSasType);

}

  四、小结

 

  本实例介绍了如何通过自定义一个DLL文件来屏蔽Windows2000下Ctrl+Alt+Del键的方法,对于读者朋友了解Windows的内幕性知识是有帮助的,当然,屏蔽Ctrl+Alt+Del键的方法不止这一种,本实例只是起一个抛砖引玉,开拓思路的作用。

 


文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网