📄 xgina.cpp
字号:
// XGina.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "XGina.h"
#define _WIN32_WINNT 0x0400
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winwlx.h>
#include <assert.h>
#include <lm.h>
#include <Winwlx.h>
//
// MSGINA dialog box IDs.p
//
#define IDD_WLXDIAPLAYSASNOTICE_DIALOG 1400
#define IDD_WLXLOGGEDOUTSAS_DIALOG 1450
#define IDD_CHANGE_PASSWORD_DIALOG 1550
#define IDD_WLXLOGGEDONSAS_DIALOG 1650
#define IDD_WLXWKSTALOCKEDSAS_DIALOG 1850
//
// MSGINA control IDs
//
#define IDC_WLXLOGGEDOUTSAS_USERNAME 1453
#define IDC_WLXLOGGEDOUTSAS_PASSWORD 1454
#define IDC_WLXLOGGEDOUTSAS_DOMAIN 1455
#define IDC_WLXWKSTALOCKEDSAS_DOMAIN 1856
//
// Pointers to redirected functions.
//
static PWLX_DIALOG_BOX_PARAM pfWlxDialogBoxParam = NULL;
//
// Pointers to redirected dialog box.
//
static DLGPROC pfWlxLoggedOutSASDlgProc = NULL;
static DLGPROC pfWlxWkstaLockedSASDlgProc = NULL;
static DLGPROC pfChangePasswordDlgProc = NULL;
static DLGPROC pfWlxDisplaySASDlgProc = NULL;
static DLGPROC pfWlxLoggedOnSASDlgProc = NULL;
//
// Location of the real MSGINA.
//
#define REALGINA_PATH TEXT("MSGINA.DLL")
#define GINASTUB_VERSION (WLX_VERSION_1_3) // Highest version supported at
// this point. Remember to modify
// this as support for newer version
// is added to this program.
//
// Winlogon function dispatch table.
//
static PVOID g_pWinlogon = NULL;
static DWORD g_dwVersion = WLX_VERSION_1_3;
//
// Pointers to the real MSGINA functions.
//
//
// Function prototypes for the GINA interface.
//
typedef BOOL (WINAPI * PFWLXNEGOTIATE) (DWORD, DWORD *);
typedef BOOL (WINAPI * PFWLXINITIALIZE) (LPWSTR, HANDLE, PVOID, PVOID, PVOID *);
typedef VOID (WINAPI * PFWLXDISPLAYSASNOTICE) (PVOID);
typedef int (WINAPI * PFWLXLOGGEDOUTSAS) (PVOID, DWORD, PLUID, PSID, PDWORD,
PHANDLE, PWLX_MPR_NOTIFY_INFO,
PVOID *);
typedef BOOL (WINAPI * PFWLXACTIVATEUSERSHELL) (PVOID, PWSTR, PWSTR, PVOID);
typedef int (WINAPI * PFWLXLOGGEDONSAS) (PVOID, DWORD, PVOID);
typedef VOID (WINAPI * PFWLXDISPLAYLOCKEDNOTICE) (PVOID);
typedef int (WINAPI * PFWLXWKSTALOCKEDSAS) (PVOID, DWORD);
typedef BOOL (WINAPI * PFWLXISLOCKOK) (PVOID);
typedef BOOL (WINAPI * PFWLXISLOGOFFOK) (PVOID);
typedef VOID (WINAPI * PFWLXLOGOFF) (PVOID);
typedef VOID (WINAPI * PFWLXSHUTDOWN) (PVOID, DWORD);
//
// New for version 1.1
//
typedef BOOL (WINAPI * PFWLXSCREENSAVERNOTIFY) (PVOID, BOOL *);
typedef BOOL (WINAPI * PFWLXSTARTAPPLICATION) (PVOID, PWSTR, PVOID, PWSTR);
//
// New for version 1.3
//
typedef BOOL (WINAPI * PFWLXNETWORKPROVIDERLOAD) (PVOID, PWLX_MPR_NOTIFY_INFO);
typedef BOOL (WINAPI * PFWLXDISPLAYSTATUSMESSAGE) (PVOID, HDESK, DWORD, PWSTR, PWSTR);
typedef BOOL (WINAPI * PFWLXGETSTATUSMESSAGE) (PVOID, DWORD *, PWSTR, DWORD);
typedef BOOL (WINAPI * PFWLXREMOVESTATUSMESSAGE) (PVOID);
static PFWLXNEGOTIATE pfWlxNegotiate;
static PFWLXINITIALIZE pfWlxInitialize;
static PFWLXDISPLAYSASNOTICE pfWlxDisplaySASNotice;
static PFWLXLOGGEDOUTSAS pfWlxLoggedOutSAS;
static PFWLXACTIVATEUSERSHELL pfWlxActivateUserShell;
static PFWLXLOGGEDONSAS pfWlxLoggedOnSAS;
static PFWLXDISPLAYLOCKEDNOTICE pfWlxDisplayLockedNotice;
static PFWLXWKSTALOCKEDSAS pfWlxWkstaLockedSAS;
static PFWLXISLOCKOK pfWlxIsLockOk;
static PFWLXISLOGOFFOK pfWlxIsLogoffOk;
static PFWLXLOGOFF pfWlxLogoff;
static PFWLXSHUTDOWN pfWlxShutdown;
//
// New for version 1.1
//
static PFWLXSTARTAPPLICATION pfWlxStartApplication = NULL;
static PFWLXSCREENSAVERNOTIFY pfWlxScreenSaverNotify = NULL;
//
// New for version 1.2 - No new GINA interface was added, except
// a new function in the dispatch table.
//
//
// New for version 1.3
//
static PFWLXNETWORKPROVIDERLOAD pfWlxNetworkProviderLoad = NULL;
static PFWLXDISPLAYSTATUSMESSAGE pfWlxDisplayStatusMessage = NULL;
static PFWLXGETSTATUSMESSAGE pfWlxGetStatusMessage = NULL;
static PFWLXREMOVESTATUSMESSAGE pfWlxRemoveStatusMessage = NULL;
void WINAPI DrawLogo(HWND hwndDlg ,LPCTSTR lpszFileName,INT x ,INT y);
BOOL LoadBitmapFromBMPFile( LPTSTR szFileName, HBITMAP *phBitmap, HPALETTE *phPalette );
#ifdef _DEBUG
#define LOG_PATH TEXT("c:\\xgina.log")
void DEBUG_MSG(const char *szMsg, ... );
#endif
#define IMAGE_FILE TEXT("xgina.dat")
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an example of an exported variable
//CSIGINA_API int nCSIGina=0;
//
// This is an example of an exported function.
//CSIGINA_API int fnCSIGina(void)
//{
// return 42;
//}
//
// This is the constructor of a class that has been exported.
// see CSIGina.h for the class definition
//CCSIGina::CCSIGina()
//{
// return;
//}
//
// Local functions.
//
int WINAPI MyWlxDialogBoxParam (HANDLE, HANDLE, LPWSTR, HWND, DLGPROC, LPARAM);
//
// Local variables.
//
static char g_szLocalMachineName[256] = "";
//
// Hook WlxDialogBoxParam() dispatch function.
//
void HookWlxDialogBoxParam (PVOID pWinlogonFunctions, DWORD dwWlxVersion)
{
//
// Hook WlxDialogBoxParam(). Note that we chould cheat here by always
// casting to (PWLX_DISPATCH_VERSION_1_0) since WlxDialogBoxParam()
// exists in all versions and is always in the same location of the
// dispatch table. But, we will do it the hard way!
//
switch (dwWlxVersion)
{
case WLX_VERSION_1_0:
{
pfWlxDialogBoxParam =
((PWLX_DISPATCH_VERSION_1_0) pWinlogonFunctions)->WlxDialogBoxParam;
((PWLX_DISPATCH_VERSION_1_0) pWinlogonFunctions)->WlxDialogBoxParam =
MyWlxDialogBoxParam;
#ifdef _DEBUG
DEBUG_MSG("PWLX_DISPATCH_VERSION_1_0)");
#endif
break;
}
case WLX_VERSION_1_1:
{
pfWlxDialogBoxParam =
((PWLX_DISPATCH_VERSION_1_1) pWinlogonFunctions)->WlxDialogBoxParam;
((PWLX_DISPATCH_VERSION_1_1) pWinlogonFunctions)->WlxDialogBoxParam =
MyWlxDialogBoxParam;
#ifdef _DEBUG
DEBUG_MSG("PWLX_DISPATCH_VERSION_1_1)");
#endif
break;
}
case WLX_VERSION_1_2:
{
pfWlxDialogBoxParam =
((PWLX_DISPATCH_VERSION_1_2) pWinlogonFunctions)->WlxDialogBoxParam;
((PWLX_DISPATCH_VERSION_1_2) pWinlogonFunctions)->WlxDialogBoxParam =
MyWlxDialogBoxParam;
#ifdef _DEBUG
DEBUG_MSG("PWLX_DISPATCH_VERSION_1_2)");
#endif
break;
}
default:
{
pfWlxDialogBoxParam =
((PWLX_DISPATCH_VERSION_1_3) pWinlogonFunctions)->WlxDialogBoxParam;
((PWLX_DISPATCH_VERSION_1_3) pWinlogonFunctions)->WlxDialogBoxParam =
MyWlxDialogBoxParam;
#ifdef _DEBUG
DEBUG_MSG("PWLX_DISPATCH_VERSION_1_3)");
#endif
break;
}
}
}
//
// Redirected WlxLoggedOutSASDlgProc().
//
BOOL CALLBACK
MyWlxLoggedOutSASDlgProc (HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
BOOL bResult;
//
// Sanity check.
//
assert(pfWlxLoggedOutSASDlgProc != NULL);
//
// Pass on to MSGINA first.
//
bResult = pfWlxLoggedOutSASDlgProc(hwndDlg, uMsg, wParam, lParam);
//
// We are only interested in WM_INITDIALOG message.
//
#ifdef _DEBUG
DEBUG_MSG("Logout dlg msg id : %ld" , uMsg);
#endif
if (uMsg == WM_INITDIALOG)
{
DWORD dwIndex;
HWND hwndDomain;
NET_API_STATUS netstatus;
LPWKSTA_INFO_100 lpWkstaInfo;
#ifdef _DEBUG
DEBUG_MSG("Logout state init");
#endif
//
// Get local machine name.
//
netstatus = NetWkstaGetInfo(NULL, 100, (LPBYTE *) &lpWkstaInfo);
if (netstatus != NERR_Success)
{
return bResult;
}
//
// Convert to ANSI.
//
wcstombs(g_szLocalMachineName, lpWkstaInfo->wki100_computername,
sizeof(g_szLocalMachineName));
//
// and free the buffer.
//
NetApiBufferFree((LPVOID) lpWkstaInfo);
//
// Manipulate the domain combo box so that only some predetermined
// trusted domains are included in the list.
//
// In our case, we restrict logon to local machine only.
//
hwndDomain = GetDlgItem(hwndDlg, IDC_WLXLOGGEDOUTSAS_DOMAIN);
if (hwndDomain == NULL)
{
return bResult;
}
dwIndex = (DWORD) SendMessage(hwndDomain, CB_FINDSTRING,
0, (LPARAM) g_szLocalMachineName);
if (dwIndex != CB_ERR)
{
SendMessage(hwndDomain, CB_SETCURSEL, (WPARAM) dwIndex, 0);
EnableWindow(hwndDomain, FALSE);
}
}
else if ( uMsg == WM_PAINT)
{
RECT rect;
GetClientRect( hwndDlg , &rect);
rect.top = rect.bottom - 33;
DrawLogo(hwndDlg,IMAGE_FILE,rect.left , rect.top);
}
return bResult;
}
//
// Redirected WlxWkstaLockedSASDlgProc().
//
BOOL
CALLBACK
MyWlxWkstaLockedSASDlgProc (HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
BOOL bResult;
//
// Sanity check.
//
assert(pfWlxWkstaLockedSASDlgProc != NULL);
//
// Pass on to MSGINA first.
//
bResult = pfWlxWkstaLockedSASDlgProc(hwndDlg, uMsg, wParam, lParam);
//
// We are only interested in WM_INITDIALOG message.
//
#ifdef _DEBUG
DEBUG_MSG("Lock workstation dlg msg id : %ld" , uMsg);
#endif
if (uMsg == WM_INITDIALOG)
{
DWORD dwIndex;
#ifdef _DEBUG
DEBUG_MSG("Log workstation dlg init");
#endif
//
// Make sure to cover this hole.
//
HWND hwndDomain = GetDlgItem(hwndDlg, IDC_WLXWKSTALOCKEDSAS_DOMAIN);
if (hwndDomain == NULL)
{
return bResult;
}
dwIndex = (DWORD) SendMessage(hwndDomain, CB_FINDSTRING,
0, (LPARAM) g_szLocalMachineName);
if (dwIndex != CB_ERR)
{
SendMessage(hwndDomain, CB_SETCURSEL, (WPARAM) dwIndex, 0);
EnableWindow(hwndDomain, FALSE);
}
}
if ( uMsg == WM_PAINT)
{
// RECT rect;
// GetClientRect( hwndDlg , &rect);
// rect.top = rect.bottom - 60;
// rect.left = rect.right - 214;
// DrawLogo(hwndDlg,IMAGE_FILE,rect.left , rect.top);
}
return bResult;
}
//
// Redirected ChangePasswordDlgProc().
//
BOOL
CALLBACK
MyChangePasswordDlgProc (HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
BOOL bResult;
//
// Sanity check.
//
assert(pfChangePasswordDlgProc != NULL);
//
// Pass on to MSGINA first.
//
bResult = pfChangePasswordDlgProc(hwndDlg, uMsg, wParam, lParam);
//
// We are only interested in WM_INITDIALOG message.
//
#ifdef _DEBUG
DEBUG_MSG("Change pwd dlg msg id : %ld" , uMsg);
#endif
if (uMsg == WM_INITDIALOG)
{
#ifdef _DEBUG
DEBUG_MSG("Change pwd dlg init");
#endif
//
// Manipulate the dialog box to match your needs here. For example,
// you can add a static control to the dialog box or display another
// message to clearly explain the rules for composing a valid password.
//
}
else if ( uMsg == WM_PAINT)
{ RECT rect;
GetClientRect( hwndDlg , &rect);
rect.top = rect.bottom - 33;
rect.left = rect.left + 10;
DrawLogo(hwndDlg,IMAGE_FILE,rect.left , rect.top);
}
return bResult;
}
BOOL
CALLBACK
MyWlxDisplaySASDlgProc (HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
BOOL bResult;
//
// Sanity check.
//
assert(pfWlxDisplaySASDlgProc != NULL);
//
// Pass on to MSGINA first.
//
bResult = pfWlxDisplaySASDlgProc(hwndDlg, uMsg, wParam, lParam);
//
// We are only interested in WM_INITDIALOG message.
//
#ifdef _DEBUG
DEBUG_MSG("display SAS dlg msg id : %ld" , uMsg);
#endif
if (uMsg == WM_INITDIALOG)
{
#ifdef _DEBUG
DEBUG_MSG("display SAS dlg init");
#endif
//
// Manipulate the dialog box to match your needs here. For example,
// you can add a static control to the dialog box or display another
// message to clearly explain the rules for composing a valid password.
//
}
else if ( uMsg == WM_PAINT)
{ RECT rect;
GetClientRect( hwndDlg , &rect);
rect.top = rect.bottom - 33;
DrawLogo(hwndDlg,IMAGE_FILE,rect.left , rect.top);
}
return bResult;
}
BOOL
CALLBACK
MyWlxLoggedOnSASDlgProc (HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
BOOL bResult;
//
// Sanity check.
//
assert(pfWlxLoggedOnSASDlgProc != NULL);
//
// Pass on to MSGINA first.
//
bResult = pfWlxLoggedOnSASDlgProc(hwndDlg, uMsg, wParam, lParam);
//
// We are only interested in WM_INITDIALOG message.
//
#ifdef _DEBUG
DEBUG_MSG("Log on SAS dlg msg id : %ld" , uMsg);
#endif
if (uMsg == WM_INITDIALOG)
{
#ifdef _DEBUG
DEBUG_MSG("Log on SAS dlg init");
#endif
//
// Manipulate the dialog box to match your needs here. For example,
// you can add a static control to the dialog box or display another
// message to clearly explain the rules for composing a valid password.
//
}
else if ( uMsg == WM_PAINT)
{ RECT rect;
GetClientRect( hwndDlg , &rect);
rect.top = rect.bottom - 33;
DrawLogo(hwndDlg,IMAGE_FILE,rect.left , rect.top);
}
return bResult;
}
//
// Redirected WlxDialogBoxParam() function.
//
int
WINAPI
MyWlxDialogBoxParam (HANDLE hWlx,
HANDLE hInst,
LPWSTR lpszTemplate,
HWND hwndOwner,
DLGPROC dlgprc,
LPARAM dwInitParam)
{
//
// Sanity check.
//
assert(pfWlxDialogBoxParam != NULL);
//
// We only know MSGINA dialogs by identifiers.
//
if (!HIWORD(lpszTemplate))
{
//
// Hook appropriate dialog boxes as necessary.
//
#ifdef _DEBUG
DEBUG_MSG("WlxDialogBoxParam :%ld",(DWORD) lpszTemplate);
#endif
switch ((DWORD) lpszTemplate)
{
case IDD_WLXDIAPLAYSASNOTICE_DIALOG:
{
#ifdef _DEBUG
DEBUG_MSG("WlxDialogBoxParam : WLXDIAPLAYSASNOTICE_DIALOG");
#endif
pfWlxDisplaySASDlgProc = dlgprc;
return pfWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,
MyWlxDisplaySASDlgProc, dwInitParam);
}
case 1500:
case IDD_WLXLOGGEDOUTSAS_DIALOG:
{
#ifdef _DEBUG
DEBUG_MSG("WlxDialogBoxParam : WLXLOGGEDOUTSAS_DIALOG");
#endif
pfWlxLoggedOutSASDlgProc = dlgprc;
return pfWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -