Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

705 lines
17 KiB

/*--------------------------------------------------------------
*
* FILE: SKEYDLL.C
*
* PURPOSE: The file contains the SerialKeys DLL Functions
*
* CREATION: June 1994
*
* COPYRIGHT: Black Diamond Software (C) 1994
*
* AUTHOR: Ronald Moak
*
* $Header: %Z% %F% %H% %T% %I%
*
*------------------------------------------------------------*/
#include "windows.h"
#include "..\skeys\sk_dllif.h"
#include "..\skeys\sk_dll.h"
#include "..\skeys\sk_reg.h"
#include "skeys.h"
#include <malloc.h>
#include "w95trace.c"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define RUNNINGEVENT TEXT("SkeysRunning")
#define ONE_MINUTE (60 * 1000)
static BOOL SerialKeysInstall(void);
static BOOL IsSerialKeysRunning();
static BOOL IsServiceStartAllowed();
static BOOL WaitForServiceRunning();
/*---------------------------------------------------------------
*
* FUNCTION int APIENTRY LibMain
*
* TYPE Global
*
* PURPOSE LibMain is called by Windows when
* the DLL is initialized, Thread Attached, and other times.
* Refer to SDK documentation, as to the different ways this
* may be called.
*
* The LibMain function should perform additional initialization
* tasks required by the DLL. In this example, no initialization
* tasks are required. LibMain should return a value of 1 if
* the initialization is successful.
*
* INPUTS
*
* RETURNS TRUE - Transfer Ok
* FALSE- Transfer Failed
*
*---------------------------------------------------------------*/
INT APIENTRY LibMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReserved)
{
return 1;
UNREFERENCED_PARAMETER(hInst);
UNREFERENCED_PARAMETER(ul_reason_being_called);
UNREFERENCED_PARAMETER(lpReserved);
}
/*---------------------------------------------------------------
*
* FUNCTION void SkeyGetRegistryValues()
*
* TYPE Global
*
* PURPOSE Reads the values from the registry into the
* SerialKeys structure
*
* INPUTS None
*
* RETURNS None
*
*---------------------------------------------------------------*/
static BOOL SkeyGetRegistryValues(HKEY hkey, LPSERIALKEYS psk)
{
LONG lErr;
DWORD dwType;
DWORD cbData;
psk->iPortState = 0;
psk->iActive = 0;
psk->dwFlags = 0;
cbData = sizeof(psk->dwFlags);
lErr = RegQueryValueEx(
hkey,
REG_FLAGS,
0,
&dwType,
(LPBYTE)&psk->dwFlags,
&cbData);
if (ERROR_SUCCESS != lErr || dwType != REG_DWORD)
{
psk->dwFlags = 0;
}
psk->dwFlags |= SERKF_AVAILABLE;
if (NULL != psk->lpszActivePort)
{
cbData = MAX_PATH * sizeof(*psk->lpszActivePort);
lErr = RegQueryValueEx(
hkey,
REG_ACTIVEPORT,
0,
&dwType,
(LPBYTE)psk->lpszActivePort,
&cbData);
psk->lpszActivePort[ MAX_PATH - 1 ] = '\0'; // ports are all MAX_PATH tchars
if (ERROR_SUCCESS != lErr || dwType != REG_SZ)
{
lstrcpy(psk->lpszActivePort, TEXT("COM1"));
}
}
if (NULL != psk->lpszPort)
{
cbData = MAX_PATH * sizeof(*psk->lpszPort);
lErr = RegQueryValueEx(
hkey,
REG_PORT,
0,
&dwType,
(LPBYTE)psk->lpszPort,
&cbData);
psk->lpszPort[ MAX_PATH - 1 ] = '\0'; // ports are all MAX_PATH tchars
if (ERROR_SUCCESS != lErr || dwType != REG_SZ)
{
lstrcpy(psk->lpszPort, TEXT("COM1"));
}
}
cbData = sizeof(psk->iBaudRate);
lErr = RegQueryValueEx(
hkey,
REG_BAUD,
0,&dwType,
(LPBYTE)&psk->iBaudRate,
&cbData);
if (ERROR_SUCCESS != lErr || dwType != REG_DWORD)
{
psk->iBaudRate = 300;
}
return TRUE;
}
/*---------------------------------------------------------------
*
* FUNCTION BOOL SkeyGetUserValues()
*
* TYPE Local
*
* PURPOSE Read the registery an collect the data for the current
* user.
*
* RETURNS TRUE - User wants Serial Keys Enabled
* FALSE- User wants Serial Keys Disabled
*
*---------------------------------------------------------------*/
BOOL SkeyGetUserValues(LPSERIALKEYS psk)
{
BOOL fOk = FALSE;
HKEY hkey;
DWORD dwRet;
DWORD dwDisposition;
dwRet = RegCreateKeyEx( HKEY_CURRENT_USER,
TEXT("Control Panel\\Accessibility\\SerialKeys"),
0,
NULL, // CLASS NAME??
0, // by default is non-volatile
KEY_READ,
NULL, // default security descriptor
&hkey,
&dwDisposition); // yes we throw this away
if (ERROR_SUCCESS == dwRet)
{
fOk = SkeyGetRegistryValues(hkey, psk);
RegCloseKey(hkey);
}
if (fOk)
{
// Not available unless the service is running or this
// user can start it
if (IsSerialKeysRunning() || IsServiceStartAllowed())
{
psk->dwFlags |= SERKF_AVAILABLE;
}
else
{
psk->dwFlags &= ~SERKF_AVAILABLE;
}
}
return(fOk);
}
/*---------------------------------------------------------------
*
* FUNCTION void SetRegistryValues()
*
* TYPE Global
*
* PURPOSE Writes the values in the SerialKeys structure to
* the Registry.
*
* INPUTS None
*
* RETURNS None
*
*---------------------------------------------------------------*/
static BOOL SkeySetRegistryValues(HKEY hkey, LPSERIALKEYS psk)
{
LONG lErr;
BOOL fOk;
DWORD dwFlags;
dwFlags = psk->dwFlags | SERKF_AVAILABLE;
lErr = RegSetValueEx( // Write dwFlags
hkey,
REG_FLAGS,
0,REG_DWORD,
(CONST LPBYTE)&dwFlags,
sizeof(DWORD));
fOk = (ERROR_SUCCESS == lErr);
if (fOk)
{
lErr = RegSetValueEx( // Write Active Port
hkey,
REG_ACTIVEPORT,
0,REG_SZ,
(CONST LPBYTE) psk->lpszActivePort,
(NULL == psk->lpszActivePort) ? 0 :
(lstrlen(psk->lpszActivePort) + 1) *
sizeof(*psk->lpszActivePort));
fOk = (ERROR_SUCCESS == lErr);
}
if (fOk)
{
lErr = RegSetValueEx( // Write Active Port
hkey,
REG_PORT,
0,REG_SZ,
(CONST LPBYTE)psk->lpszPort,
(NULL == psk->lpszPort) ? 0 :
(lstrlen(psk->lpszPort) + 1) * sizeof(*psk->lpszPort));
fOk = (ERROR_SUCCESS == lErr);
}
if (fOk)
{
lErr = RegSetValueEx( // Write Active Port
hkey,
REG_BAUD,
0,REG_DWORD,
(CONST LPBYTE) &psk->iBaudRate,
sizeof(psk->iBaudRate));
fOk = (ERROR_SUCCESS == lErr);
}
return fOk;
}
/*---------------------------------------------------------------
*
* FUNCTION void SetUserValues()
*
* TYPE Global
*
* PURPOSE This function writes out information to the
* registry.
*
* INPUTS None
*
* RETURNS TRUE - Write Successful
* FALSE- Write Failed
*
*---------------------------------------------------------------*/
BOOL SkeySetUserValues(LPSERIALKEYS psk)
{
BOOL fOk = FALSE;
HKEY hkey;
DWORD dwRet;
DWORD dwDisposition;
dwRet = RegCreateKeyEx(
HKEY_CURRENT_USER,
TEXT("Control Panel\\Accessibility\\SerialKeys"),
0,
NULL, // class name
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL, // default security descriptor
&hkey,
&dwDisposition); // yes we throw this away
if (ERROR_SUCCESS == dwRet)
{
fOk = SkeySetRegistryValues(hkey, psk);
RegCloseKey(hkey);
}
return(fOk);
}
#if 0 // This old code is no longer needed ////////////////////////////////////
/*---------------------------------------------------------------
*
* FUNCTION BOOL IsSerialKeysInstalled();
*
* TYPE Local
*
* PURPOSE This function passes the information from the
* Serial Keys application to the Server
*
* INPUTS None
*
* RETURNS TRUE - SerialKeys is Installed
* FALSE- SerialKeys Not Installed
*
*---------------------------------------------------------------*/
static BOOL IsSerialKeysInstalled()
{
SC_HANDLE schService = NULL;
SC_HANDLE schSCManager = NULL;
BOOL fOk = FALSE;
//
// Check if the Serial Keys Service is installed
schSCManager = OpenSCManager
(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (NULL != schSCManager)
{
schService = OpenService(schSCManager, "SerialKeys", SERVICE_ALL_ACCESS);
if (NULL != schService)
{
CloseServiceHandle(schService);
fOk = TRUE;
}
CloseServiceHandle(schSCManager);
}
return fOk;
}
#endif ////////////////////////////////////////////////////////////////////////
BOOL IsSerialKeysRunning()
{
BOOL fRunning = FALSE;
HANDLE hEventSkeysServiceRunning;
hEventSkeysServiceRunning = OpenEvent(SYNCHRONIZE, FALSE, RUNNINGEVENT);
if (NULL != hEventSkeysServiceRunning)
{
DWORD dwWait;
dwWait = WaitForSingleObject(hEventSkeysServiceRunning, 0);
fRunning = (WAIT_OBJECT_0 == dwWait);
CloseHandle(hEventSkeysServiceRunning);
}
return fRunning;
}
BOOL IsServiceStartAllowed()
{
BOOL fServiceStartAllowed = FALSE;
SC_HANDLE schSCManager = NULL;
schSCManager = OpenSCManager( // Open Service Manager
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_CREATE_SERVICE); // access required
if (NULL != schSCManager) // Did Open Service succeed?
{
CloseServiceHandle(schSCManager);
fServiceStartAllowed = TRUE;
}
return fServiceStartAllowed;
}
BOOL SkeyServiceRequest(UINT uAction, LPSERIALKEYS psk, BOOL fWinIni)
{
BOOL fOk = FALSE;
SKEYDLL SKeyDLL;
DWORD bytesRead;
if (IsSerialKeysRunning())
{
memset(&SKeyDLL, 0, sizeof(SKeyDLL));
SKeyDLL.Message = uAction;
if (psk->lpszActivePort != NULL)
{
strcpy(SKeyDLL.szActivePort,psk->lpszActivePort);
}
if (psk->lpszPort != NULL)
{
strcpy(SKeyDLL.szPort,psk->lpszPort);
}
SKeyDLL.dwFlags = psk->dwFlags | SERKF_AVAILABLE;
SKeyDLL.iBaudRate = psk->iBaudRate;
SKeyDLL.iPortState = psk->iPortState;
SKeyDLL.iSave = fWinIni;
fOk = CallNamedPipe(
SKEY_NAME, // Pipe name
&SKeyDLL,
sizeof(SKeyDLL),
&SKeyDLL,
sizeof(SKeyDLL),
&bytesRead,
NMPWAIT_USE_DEFAULT_WAIT);
if (fOk)
{
if (psk->lpszActivePort != NULL)
{
strcpy(psk->lpszActivePort,SKeyDLL.szActivePort);
}
if (psk->lpszPort != NULL)
{
strcpy(psk->lpszPort,SKeyDLL.szPort);
}
psk->dwFlags = SKeyDLL.dwFlags | SERKF_AVAILABLE;
psk->iBaudRate = SKeyDLL.iBaudRate;
psk->iPortState = SKeyDLL.iPortState;
}
}
return fOk;
}
BOOL SkeyInitUser()
{
BOOL fOk;
SERIALKEYS sk;
TCHAR szActivePort[MAX_PATH]; // all ports are expected to be MAX_PATH tchars
TCHAR szPort[MAX_PATH]; // all ports are expected to be MAX_PATH tchars
memset(&sk, 0, sizeof(sk));
sk.cbSize = sizeof(sk);
sk.lpszActivePort = szActivePort;
sk.lpszPort = szPort;
fOk = SkeyGetUserValues(&sk);
if (fOk)
{
fOk = SkeyServiceRequest(SPI_SETSERIALKEYS, &sk, FALSE);
}
return fOk;
}
/*---------------------------------------------------------------
*
* FUNCTION int APIENTRY SKEY_SystemParameterInfo
*
* TYPE Global
*
* PURPOSE This function passes the information from the
* Serial Keys application to the Server
*
* INPUTS
*
* RETURNS TRUE - Transfer Ok
* FALSE- Transfer Failed
*
*---------------------------------------------------------------*/
BOOL APIENTRY SKEY_SystemParametersInfo(
UINT uAction,
UINT uParam,
LPSERIALKEYS psk,
BOOL fWinIni)
{
BOOL fOk;
BOOL fStarted;
fOk = ((uAction == SK_SPI_INITUSER) ||
(NULL != psk && (0 != psk->cbSize)));
if (fOk)
{
switch (uAction)
{
case SPI_SETSERIALKEYS:
fOk = SkeySetUserValues(psk);
if (fOk && (psk->dwFlags & SERKF_SERIALKEYSON) && IsServiceStartAllowed())
{
fOk = SerialKeysInstall();
}
if (fOk && IsSerialKeysRunning())
{
fOk = SkeyInitUser();
}
break;
case SPI_GETSERIALKEYS:
fOk = SkeyGetUserValues(psk);
if (fOk && (psk->dwFlags & SERKF_SERIALKEYSON) &&
!IsSerialKeysRunning() && IsServiceStartAllowed())
{
fOk = SerialKeysInstall();
}
if (fOk && IsSerialKeysRunning())
{
fOk = SkeyInitUser();
}
break;
case SK_SPI_INITUSER:
// give the service a chance to start
fStarted = WaitForServiceRunning();
if (!fStarted)
{
// service does not seem to be running
// let's try to start it
fOk = SkeyGetUserValues(psk);
if (fOk && (psk->dwFlags & SERKF_SERIALKEYSON) &&
!IsSerialKeysRunning() && IsServiceStartAllowed())
{
SerialKeysInstall();
}
if (IsSerialKeysRunning())
{
fOk = SkeyInitUser();
}
}
break;
default:
fOk = FALSE; // No - Fail
}
}
return fOk;
}
/*****************************************************************************/
/* WaitForServiceRunning - wait up to one minute for the SerialKeys service
* to signal it is ready. CreateEvent has been called by SKeys.exe before
* this function is executed.
*/
BOOL WaitForServiceRunning()
{
BOOL fOk = FALSE;
HANDLE hEventSkeysServiceRunning = OpenEvent(SYNCHRONIZE, FALSE, RUNNINGEVENT);
if (hEventSkeysServiceRunning)
{
DWORD dwWait = WaitForSingleObject(hEventSkeysServiceRunning, ONE_MINUTE);
CloseHandle(hEventSkeysServiceRunning);
fOk = (WAIT_OBJECT_0 == dwWait);
}
return fOk;
}
/****************************************************************************/
BOOL SerialKeysInstall(void)
{
BOOL fStarted = FALSE;
SERVICE_STATUS ssStatus;
DWORD dwOldCheckPoint;
TCHAR szFileName[MAX_PATH + 1];
SC_HANDLE schService = NULL;
SC_HANDLE schSCManager = NULL;
schSCManager = OpenSCManager( // Open Service Manager
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS); // access required
if (NULL != schSCManager) // Did Open Service succeed?
{
schService = OpenService(
schSCManager ,
__TEXT("SerialKeys"),
SERVICE_ALL_ACCESS);
if (NULL != schService)
{
// insure the serivce is auto-start
ChangeServiceConfig(
schService,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, // when to start service
SERVICE_NO_CHANGE, // severity if service fails to start
NULL, // pointer to service binary file name
NULL, // pointer to load ordering group name
NULL, // pointer to variable to get tag identifier
NULL, // pointer to array of dependency names
NULL, // pointer to account name of service
NULL, // pointer to password for service account
__TEXT("SerialKeys")); // name to display
}
else
{
if (!GetWindowsDirectory(szFileName, ARRAY_SIZE(szFileName)))
return FALSE; // PREFIX #113665 don't use szFileName if call fails
lstrcat(szFileName, __TEXT("\\system32\\skeys.exe"));
// Is Service File installed?
if (0xFFFFFFFF != GetFileAttributes(szFileName))
{
schService = CreateService(
schSCManager, // SCManager database
__TEXT("SerialKeys"), // name of service
__TEXT("SerialKeys"), // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szFileName, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
}
}
if (NULL != schService)
{
BOOL fOk = QueryServiceStatus(schService,&ssStatus);
if (fOk && ssStatus.dwCurrentState != SERVICE_RUNNING)
{
static PTSTR pszArg = TEXT("F\0"); // force service to start
PTSTR apszArg[] = {pszArg, NULL};
if (StartService(schService, 1, apszArg))
{
while(fOk && ssStatus.dwCurrentState != SERVICE_RUNNING)
{
dwOldCheckPoint = ssStatus.dwCheckPoint;
Sleep(max(ssStatus.dwWaitHint, 1000));
fOk = QueryServiceStatus(schService,&ssStatus);
fOk = (fOk && (dwOldCheckPoint >= ssStatus.dwCheckPoint));
}
}
}
fStarted = fOk && (ssStatus.dwCurrentState == SERVICE_RUNNING);
CloseServiceHandle(schService);
if (fStarted)
{
fStarted = WaitForServiceRunning();
}
}
CloseServiceHandle(schSCManager);
}
return fStarted;
}