#define UNICODE
#include <windows.h>
#include <Winwlx.h>
#include "main.h"
//在启动后,按CTRL_ALT_DEL,系统回调用WlxLoggedOnSAS!
//将这个DLL拷到system32目录下,并在注册表中加入:
//\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
//加一个GinaDLL,类型RegSZ, 内容为你的dll名,如:'NoReboot.dll'.
//重起机器,系统就会使用你的dll,GINA可以实现很多东西,值得研究!
//按下CTRL+ALT+DEL屏幕会闪一下,那是因为屏幕从Winsta0转到Desktop!
//须要用unicode,如果改了后必启动不了,请将msgina.dll拷贝成你的dll,再启动!#define _DEBUG //是否记录日志HINSTANCE myHandle = NULL;
HANDLE hf = NULL;
typedef struct {
  HANDLE hWlx;
  LPWSTR station;
  //PWLX_DISPATCH_VERSION_1_3 pWlxFuncs;
  HANDLE hDllInstance;
  HANDLE UserToken;
} GINA_CONTEXT, * PGINA_CONTEXT;PWSTR DupString(PWSTR pszString);
void WriteInfo(const char * buf);BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,
  DWORD fdwReason,
  LPVOID lpvReserved
  )
{
switch (fdwReason){
case DLL_PROCESS_ATTACH:
hf = CreateFile(L"c:\\gina.txt", GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
WriteInfo("start \r\n");
myHandle = hinstDLL;
if (LoadMsGina()){
WriteInfo("Init gina ok \r\n");
}
else
WriteInfo("Init gina false \r\n"); break;
case DLL_PROCESS_DETACH:
ReleaseMsGina();
WriteInfo("release gina ok \r\n");
if (hf != INVALID_HANDLE_VALUE){
CloseHandle(hf);
}
break;
} return TRUE;
}BOOL WINAPI 
WlxActivateUserShell (
  PVOID pWlxContext,
  PWSTR pszDesktopName,
  PWSTR pszMprLogonScript,
  PVOID pEnvironment)
{
WriteInfo("WlxActivateUserShell \r\n"); return prcWlxActivateUserShell (
  pWlxContext,
  pszDesktopName,
  pszMprLogonScript,
  pEnvironment);
}VOID WINAPI WlxDisplaySASNotice (
  PVOID pWlxContext)
{
prcWlxDisplaySASNotice(pWlxContext);
}BOOL WINAPI WlxInitialize (
  LPWSTR  lpWinsta,
  HANDLE  hWlx,
  PVOID   pvReserved,
  PVOID   pWinlogonFunctions,
  PVOID * pWlxContext)
{
return prcWlxInitialize (
  lpWinsta,
  hWlx,
  pvReserved,
  pWinlogonFunctions,
  pWlxContext);
}int WINAPI WlxLoggedOnSAS (
  PVOID pWlxContext,
  DWORD dwSasType,
  PVOID pReserved)
{
HANDLE hMutex;
   WriteInfo("WlxLoggedOnSAS \r\n");   if (dwSasType == WLX_SAS_TYPE_CTRL_ALT_DEL){ //屏蔽CTRL_ALT_DEL,也可以根据特定条件来决定是否要屏蔽
   //我采用了Mutex来控制是否屏蔽,(注意:要用unicode)
   hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, L"_ac952_z_cn_CTRL_ALT_DEL");
   if (hMutex){
   CloseHandle(hMutex);
   WriteInfo("disble CTRL+ALT+DEL \r\n");
  return WLX_SAS_ACTION_NONE;
   }
   else
WriteInfo("not disble CTRL+ALT+DEL \r\n");
   }

return prcWlxLoggedOnSAS (
  pWlxContext,
  dwSasType,
  pReserved);
}int WINAPI WlxLoggedOutSAS (
  PVOID                pWlxContext,
  DWORD                dwSasType,
  PLUID                pAuthenticationId,
  PSID                 pLogonSid,
  PDWORD               pdwOptions,
  PHANDLE              phToken,
  PWLX_MPR_NOTIFY_INFO pMprNotifyInfo,
  PVOID *              pProfile)
{
  
    WriteInfo("WlxLoggedOutSAS \r\n");  return prcWlxLoggedOutSAS (
  pWlxContext,
  dwSasType,
  pAuthenticationId,
  pLogonSid,
  pdwOptions,
  phToken,
  pMprNotifyInfo,
  pProfile);}
PWSTR DupString(PWSTR pszString)
{
  DWORD cbString;
  PWSTR pszNewString;   cbString = (wcslen(pszString) + 1) * sizeof(WCHAR);
  pszNewString = LocalAlloc(LMEM_FIXED, cbString);
  if (pszNewString)
  {
CopyMemory(pszNewString, pszString, cbString);
  }
  return(pszNewString);
}VOID WINAPI WlxLogoff (PVOID pWlxContext)
{
   WriteInfo("WlxLogoff \r\n");   prcWlxLogoff(pWlxContext);
}BOOL WINAPI WlxNegotiate (
  DWORD  dwWinlogonVersion,
  PDWORD pdwDllVersion)
{
   WriteInfo("WlxNegotiate \r\n");
return prcWlxNegotiate (
dwWinlogonVersion,
pdwDllVersion);
}
BOOL WINAPI WlxScreenSaverNotify (
  PVOID  pWlxContext,
  BOOL  *pSecure)
{ WriteInfo("WlxScreenSaverNotify \r\n");
return prcWlxScreenSaverNotify (
  pWlxContext,
  pSecure);
}VOID WINAPI WlxShutdown(
  PVOID pWlxContext,
  DWORD ShutdownType)
{ WriteInfo("WlxShutdown \r\n"); prcWlxShutdown(pWlxContext, ShutdownType);
}BOOL WINAPI WlxStartApplication (
  PVOID pWlxContext,
  PWSTR pszDesktopName,
  PVOID pEnvironment,
  PWSTR pszCmdLine)
{
WriteInfo("WlxStartApplication \r\n");
return prcWlxStartApplication (
  pWlxContext,
  pszDesktopName,
  pEnvironment,
  pszCmdLine);
}int WINAPI WlxWkstaLockedSAS (
  PVOID pWlxContext,
  DWORD dwSasType
)
{
WriteInfo("WlxWkstaLockedSAS \r\n");
return prcWlxWkstaLockedSAS (
  pWlxContext,
  dwSasType
);
}VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
{
prcWlxDisplayLockedNotice(pWlxContext);
}BOOL WINAPI WlxDisplayStatusMessage(
  PVOID pWlxContext,
  HDESK hDesktop,
  DWORD dwOptions,
  PWSTR pTitle,
  PWSTR pMessage
  ){
return prcWlxDisplayStatusMessage(
  pWlxContext,
  hDesktop,
  dwOptions,
  pTitle,
  pMessage
);
}
BOOL WINAPI WlxGetStatusMessage(
  PVOID pWlxContext,
  DWORD *pdwOptions,
  PWSTR pMessage,
  DWORD dwBufferSize
)
{
WriteInfo("WlxGetStatusMessage \r\n");
return prcWlxGetStatusMessage(
  pWlxContext,
  pdwOptions,
  pMessage,
  dwBufferSize
);
// return FALSE;
}BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
{
return prcWlxIsLockOk(pWlxContext);

}BOOL WINAPI WlxIsLogoffOk(
  PVOID pWlxContext
)
{
WriteInfo("WlxIsLogoffOk \r\n");
return prcWlxIsLogoffOk(
pWlxContext
);
}

BOOL WINAPI WlxNetworkProviderLoad(
  PVOID pWlxContext,
  PWLX_MPR_NOTIFY_INFO pNprNotifyInfo
)
{
WriteInfo("WlxNetworkProviderLoad \r\n");
return prcWlxNetworkProviderLoad(
pWlxContext,
pNprNotifyInfo
);
}BOOL WINAPI WlxRemoveStatusMessage(
  PVOID pWlxContext
)
{
   WriteInfo("WlxRemoveStatusMessage \r\n");
return prcWlxRemoveStatusMessage(
  pWlxContext
);
}void WriteInfo(const char * buf)
{
#ifdef _DEBUG DWORD dwRt;
int i = 0;
if (hf != INVALID_HANDLE_VALUE){
while (TRUE){
if (!buf[i])
break;
else
i++;
}
i++;

WriteFile(hf, buf, i, &dwRt, NULL);
} #endif
}