398 lines
11 KiB
C++
398 lines
11 KiB
C++
|
|
||
|
#include "stdafx.h"
|
||
|
|
||
|
#include "DXSvr.h"
|
||
|
#include <regstr.h>
|
||
|
|
||
|
//***************************************************************************************
|
||
|
// Globals
|
||
|
|
||
|
HINSTANCE g_hMainInstance; // Main instance handle
|
||
|
BOOL g_bIsTest; // Is in test mode?
|
||
|
BOOL g_bIsPreview; // Is in preview mode?
|
||
|
HWND g_hWnd; // Handle of the rendering window
|
||
|
HWND g_hRefWindow; // Reference window (for preview mode)
|
||
|
LPSTR g_szCommandLine; // Command line
|
||
|
|
||
|
BOOL g_bCheckingPassword;
|
||
|
BOOL g_bShuttingDown;
|
||
|
|
||
|
ID3DXContext* g_pXContext; // X-Library context
|
||
|
IDirect3DDevice7* g_pDevice; // D3D Device
|
||
|
|
||
|
//***************************************************************************************
|
||
|
|
||
|
BOOL g_bIsWin9x;
|
||
|
BOOL g_bWait;
|
||
|
|
||
|
DWORD g_dwMouseMoveCount;
|
||
|
|
||
|
BOOL InitD3D(HWND hWnd);
|
||
|
void KillD3D();
|
||
|
|
||
|
//***************************************************************************************
|
||
|
// Password stuff
|
||
|
|
||
|
const TCHAR szScreenSaverKey[] = REGSTR_PATH_SCREENSAVE;
|
||
|
TCHAR szPasswordActiveValue[] = REGSTR_VALUE_USESCRPASSWORD;
|
||
|
const TCHAR szPasswordValue[] = REGSTR_VALUE_SCRPASSWORD;
|
||
|
|
||
|
TCHAR szPwdDLL[] = TEXT("PASSWORD.CPL");
|
||
|
char szFnName[] = "VerifyScreenSavePwd";
|
||
|
|
||
|
typedef BOOL (FAR PASCAL * VERIFYPWDPROC) (HWND);
|
||
|
|
||
|
VERIFYPWDPROC VerifyPassword = NULL;
|
||
|
HINSTANCE hInstPwdDLL = NULL;
|
||
|
|
||
|
static LPTSTR szMprDll = TEXT("MPR.DLL");
|
||
|
static LPTSTR szProviderName = TEXT("SCRSAVE");
|
||
|
|
||
|
static const char szPwdChangePW[] = "PwdChangePasswordA";
|
||
|
|
||
|
typedef DWORD (FAR PASCAL *PWCHGPROC)(LPCTSTR, HWND, DWORD, LPVOID);
|
||
|
|
||
|
//***************************************************************************************
|
||
|
void ScreenSaverChangePassword(HWND hParent)
|
||
|
{
|
||
|
HINSTANCE mpr = LoadLibrary(szMprDll);
|
||
|
|
||
|
if (mpr)
|
||
|
{
|
||
|
PWCHGPROC pwd = (PWCHGPROC)GetProcAddress(mpr, szPwdChangePW);
|
||
|
|
||
|
if (pwd)
|
||
|
pwd(szProviderName, hParent, 0, NULL);
|
||
|
|
||
|
FreeLibrary(mpr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//***************************************************************************************
|
||
|
void LoadPwdDLL()
|
||
|
{
|
||
|
// Don't bother unless we're on 9x
|
||
|
if (!g_bIsWin9x)
|
||
|
return;
|
||
|
|
||
|
// look in registry to see if password turned on, otherwise don't
|
||
|
// bother to load password handler DLL
|
||
|
HKEY hKey;
|
||
|
if (RegOpenKey(HKEY_CURRENT_USER,szScreenSaverKey,&hKey) ==
|
||
|
ERROR_SUCCESS)
|
||
|
{
|
||
|
DWORD dwVal,dwSize=sizeof(dwVal);
|
||
|
|
||
|
if ((RegQueryValueEx(hKey,szPasswordActiveValue,
|
||
|
NULL,NULL,(BYTE *) &dwVal,&dwSize) == ERROR_SUCCESS)
|
||
|
&& dwVal)
|
||
|
{
|
||
|
|
||
|
// try to load the DLL that contains password proc.
|
||
|
hInstPwdDLL = LoadLibrary(szPwdDLL);
|
||
|
if (hInstPwdDLL)
|
||
|
{
|
||
|
VerifyPassword = (VERIFYPWDPROC) GetProcAddress(hInstPwdDLL, szFnName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//***************************************************************************************
|
||
|
int DXSvrMain(HINSTANCE hInstance, HINSTANCE hInstPrev, LPSTR pszCmdLine, int)
|
||
|
{
|
||
|
// Store our instance handle for later use
|
||
|
g_hMainInstance = hInstance;
|
||
|
|
||
|
// Figure out if we're on 9x or NT (password stuff is different)
|
||
|
OSVERSIONINFO osvi;
|
||
|
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
||
|
GetVersionEx(&osvi);
|
||
|
g_bIsWin9x = (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
|
||
|
|
||
|
// Load the password DLL
|
||
|
LoadPwdDLL();
|
||
|
|
||
|
// Parse the command line
|
||
|
g_szCommandLine = pszCmdLine;
|
||
|
LPCSTR pszSwitch = StrChrA(pszCmdLine, '/');
|
||
|
|
||
|
if (pszSwitch == NULL)
|
||
|
{
|
||
|
return ScreenSaverDoConfig();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pszSwitch++; // Skip past the '/'.
|
||
|
switch (*pszSwitch)
|
||
|
{
|
||
|
case 't':
|
||
|
case 'T':
|
||
|
g_bIsTest = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'p':
|
||
|
case 'P':
|
||
|
while (*pszSwitch && !isdigit(*pszSwitch))
|
||
|
pszSwitch++;
|
||
|
if (isdigit(*pszSwitch))
|
||
|
{
|
||
|
LONGLONG llSize;
|
||
|
|
||
|
if (StrToInt64ExA(pszSwitch, 0, &llSize))
|
||
|
{
|
||
|
g_hRefWindow = HWND(llSize);
|
||
|
}
|
||
|
if (g_hRefWindow != NULL)
|
||
|
g_bIsPreview = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'a':
|
||
|
case 'A':
|
||
|
while (*pszSwitch && !isdigit(*pszSwitch))
|
||
|
pszSwitch++;
|
||
|
if (isdigit(*pszSwitch))
|
||
|
{
|
||
|
LONGLONG llSize;
|
||
|
|
||
|
if (StrToInt64ExA(pszSwitch, 0, &llSize))
|
||
|
{
|
||
|
g_hRefWindow = HWND(llSize);
|
||
|
}
|
||
|
}
|
||
|
ScreenSaverChangePassword(g_hRefWindow);
|
||
|
return 0;
|
||
|
|
||
|
case 'c':
|
||
|
case 'C':
|
||
|
return ScreenSaverDoConfig();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Register the window class
|
||
|
WNDCLASS cls;
|
||
|
cls.hCursor = NULL;
|
||
|
cls.hIcon = NULL;
|
||
|
cls.lpszMenuName = NULL;
|
||
|
cls.lpszClassName = TEXT("DXSvrWindow");
|
||
|
cls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
|
||
|
cls.hInstance = g_hMainInstance;
|
||
|
cls.style = CS_VREDRAW|CS_HREDRAW|CS_SAVEBITS|CS_DBLCLKS;
|
||
|
cls.lpfnWndProc = ScreenSaverProc;
|
||
|
cls.cbWndExtra = 0;
|
||
|
cls.cbClsExtra = 0;
|
||
|
RegisterClass(&cls);
|
||
|
|
||
|
g_bWait = TRUE;
|
||
|
|
||
|
// Create the window
|
||
|
RECT rect;
|
||
|
if (g_bIsTest)
|
||
|
{
|
||
|
rect.left = rect.top = 40;
|
||
|
rect.right = rect.left+640;
|
||
|
rect.bottom = rect.top+480;
|
||
|
AdjustWindowRect(&rect , WS_VISIBLE|WS_OVERLAPPED|WS_CAPTION|WS_POPUP , FALSE);
|
||
|
g_hWnd = CreateWindow(TEXT("DXSvrWindow"), TEXT("ScreenSaverTest"),
|
||
|
WS_VISIBLE|WS_OVERLAPPED|WS_CAPTION|WS_POPUP , rect.left , rect.top ,
|
||
|
rect.right-rect.left , rect.bottom-rect.top , NULL ,
|
||
|
NULL , g_hMainInstance , NULL);
|
||
|
}
|
||
|
else if (g_bIsPreview)
|
||
|
{
|
||
|
GetClientRect(g_hRefWindow , &rect);
|
||
|
ClientToScreen(g_hRefWindow , (POINT*)(&rect));
|
||
|
rect.right += rect.left; rect.bottom += rect.top;
|
||
|
AdjustWindowRect(&rect , WS_VISIBLE|WS_CHILD , FALSE);
|
||
|
g_hWnd = CreateWindow(TEXT("DXSvrWindow"), TEXT("ScreenSaverPreview"),
|
||
|
WS_VISIBLE|WS_CHILD , rect.left , rect.top ,
|
||
|
rect.right-rect.left , rect.bottom-rect.top , g_hRefWindow ,
|
||
|
NULL , g_hMainInstance , NULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
g_hWnd = CreateWindowEx(WS_EX_TOPMOST , TEXT("DXSvrWindow"), TEXT("ScreenSaver"),
|
||
|
WS_MAXIMIZE|WS_VISIBLE|WS_POPUP , 0 , 0 , 640 , 480 , NULL ,
|
||
|
NULL , g_hMainInstance , NULL);
|
||
|
}
|
||
|
|
||
|
if (g_hWnd == NULL)
|
||
|
return 0;
|
||
|
|
||
|
// Prevent task switching if we're on 9x
|
||
|
BOOL dummy;
|
||
|
if (!g_bIsTest && !g_bIsPreview && g_bIsWin9x)
|
||
|
SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, &dummy, 0);
|
||
|
|
||
|
// Pump messages
|
||
|
MSG msg;
|
||
|
msg.message = 0;
|
||
|
while (msg.message != WM_QUIT)
|
||
|
{
|
||
|
if (g_bWait)
|
||
|
{
|
||
|
GetMessage(&msg , NULL , 0 , 0);
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
g_bWait = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (PeekMessage(&msg , NULL , 0 , 0 , PM_REMOVE))
|
||
|
{
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
else
|
||
|
ScreenSaverDrawFrame();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Allow task switching if we disabled it
|
||
|
if (!g_bIsTest && !g_bIsPreview && g_bIsWin9x)
|
||
|
SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &dummy, 0);
|
||
|
|
||
|
// Unload the password DLL
|
||
|
if (hInstPwdDLL)
|
||
|
FreeLibrary(hInstPwdDLL);
|
||
|
|
||
|
// Done
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void _stdcall ModuleEntry(void)
|
||
|
{
|
||
|
CHAR szCmdLine[MAX_PATH];
|
||
|
LPCTSTR pszCmdLine = GetCommandLine();
|
||
|
|
||
|
SHTCharToAnsi(pszCmdLine, szCmdLine, ARRAYSIZE(szCmdLine));
|
||
|
int nReturn = DXSvrMain(GetModuleHandle(NULL), NULL, szCmdLine, SW_SHOWDEFAULT);
|
||
|
ExitProcess(nReturn);
|
||
|
}
|
||
|
|
||
|
|
||
|
//***************************************************************************************
|
||
|
BOOL DoPasswordCheck(HWND hWnd)
|
||
|
{
|
||
|
// Don't check if we're already checking or being shut down
|
||
|
if (g_bCheckingPassword || g_bShuttingDown)
|
||
|
return FALSE;
|
||
|
|
||
|
// If no VerifyPassword function, then no password is set or we're on NT. Either way just
|
||
|
// say the password was okay.
|
||
|
if (VerifyPassword == NULL)
|
||
|
return TRUE;
|
||
|
|
||
|
g_bCheckingPassword = TRUE;
|
||
|
|
||
|
if (g_pXContext != NULL)
|
||
|
{
|
||
|
IDirectDraw7* dd = g_pXContext->GetDD();
|
||
|
if (dd != NULL)
|
||
|
{
|
||
|
dd->FlipToGDISurface();
|
||
|
dd->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL password_okay = VerifyPassword(hWnd);
|
||
|
g_bCheckingPassword = FALSE;
|
||
|
|
||
|
if (!password_okay)
|
||
|
SetCursor(NULL);
|
||
|
|
||
|
g_dwMouseMoveCount = 0;
|
||
|
|
||
|
return password_okay;
|
||
|
}
|
||
|
|
||
|
//***************************************************************************************
|
||
|
LONG DefDXScreenSaverProc(HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
|
||
|
{
|
||
|
switch (message)
|
||
|
{
|
||
|
case WM_CREATE:
|
||
|
if (!InitD3D(hWnd))
|
||
|
return -1;
|
||
|
if (!ScreenSaverInit())
|
||
|
return -1;
|
||
|
g_bWait = FALSE;
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
ScreenSaverShutdown();
|
||
|
KillD3D();
|
||
|
PostQuitMessage(0);
|
||
|
g_bWait = TRUE;
|
||
|
break;
|
||
|
|
||
|
case WM_SETCURSOR:
|
||
|
SetCursor(NULL);
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_CHAR:
|
||
|
if (g_bIsTest)
|
||
|
DestroyWindow(hWnd);
|
||
|
else if (!g_bIsPreview)
|
||
|
PostMessage(hWnd , WM_CLOSE , 0 , 0);
|
||
|
break;
|
||
|
|
||
|
case WM_PAINT:
|
||
|
{
|
||
|
PAINTSTRUCT ps;
|
||
|
BeginPaint(hWnd , &ps);
|
||
|
EndPaint(hWnd , &ps);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
case WM_ERASEBKGND:
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_MOUSEMOVE:
|
||
|
if (!g_bIsTest && !g_bIsPreview)
|
||
|
{
|
||
|
g_dwMouseMoveCount++;
|
||
|
if (g_dwMouseMoveCount >= 3)
|
||
|
PostMessage(hWnd , WM_CLOSE , 0 , 0);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_LBUTTONDOWN:
|
||
|
case WM_RBUTTONDOWN:
|
||
|
case WM_MBUTTONDOWN:
|
||
|
if (!g_bIsTest && !g_bIsPreview)
|
||
|
PostMessage(hWnd , WM_CLOSE , 0 , 0);
|
||
|
break;
|
||
|
|
||
|
case WM_CLOSE:
|
||
|
if (g_bIsWin9x && !g_bIsPreview)
|
||
|
{
|
||
|
if (!DoPasswordCheck(hWnd))
|
||
|
return FALSE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_SYSCOMMAND:
|
||
|
if (!g_bIsPreview && !g_bIsTest)
|
||
|
{
|
||
|
switch (wParam)
|
||
|
{
|
||
|
case SC_NEXTWINDOW:
|
||
|
case SC_PREVWINDOW:
|
||
|
case SC_SCREENSAVE:
|
||
|
return FALSE;
|
||
|
};
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return DefWindowProc(hWnd , message , wParam , lParam);
|
||
|
}
|