425 lines
10 KiB
C
425 lines
10 KiB
C
/******************************Module*Header*******************************\
|
|
* Module Name: dllinit.c
|
|
*
|
|
* MCD library initialization routine(s).
|
|
*
|
|
* Created: 02-Apr-1996 21:25:47
|
|
* Author: Gilman Wong [gilmanw]
|
|
*
|
|
* Copyright (c) 1996 Microsoft Corporation
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include <stddef.h>
|
|
#include <windows.h>
|
|
#include <wtypes.h>
|
|
#include <windef.h>
|
|
#include <wingdi.h>
|
|
#include <winddi.h>
|
|
#include <mcdesc.h>
|
|
#include "mcdrv.h"
|
|
#include <mcd2hack.h>
|
|
#include "mcd.h"
|
|
#include "mcdint.h"
|
|
#include "debug.h"
|
|
|
|
//
|
|
// Global flags read from the registry.
|
|
//
|
|
|
|
ULONG McdFlags = 0;
|
|
ULONG McdPrivateFlags = MCDPRIVATE_MCD_ENABLED;
|
|
#if DBG
|
|
ULONG McdDebugFlags = 0;
|
|
#endif
|
|
|
|
long GetMcdRegValue(HKEY hkMcd, REGSAM samAccess, LPSTR lpstrValueName,
|
|
long lDefaultData);
|
|
void GetMcdFlags(void);
|
|
|
|
#ifdef MCD95
|
|
//
|
|
// Local driver semaphore.
|
|
//
|
|
|
|
CRITICAL_SECTION gsemMcd;
|
|
|
|
extern MCDENGESCFILTERFUNC pMCDEngEscFilter;
|
|
#endif
|
|
|
|
/******************************Public*Routine******************************\
|
|
* McdDllInitialize
|
|
*
|
|
* This is the entry point for MCD32.DLL, which is called each time
|
|
* a process or thread that is linked to it is created or terminated.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL McdDllInitialize(HMODULE hModule, ULONG Reason, PVOID Reserved)
|
|
{
|
|
//
|
|
// Suppress compiler warnings.
|
|
//
|
|
|
|
hModule;
|
|
Reserved;
|
|
|
|
//
|
|
// Do appropriate attach/detach processing.
|
|
//
|
|
|
|
switch (Reason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
#ifdef MCD95
|
|
//
|
|
// Initialize local driver semaphore.
|
|
//
|
|
|
|
__try
|
|
{
|
|
InitializeCriticalSection(&gsemMcd);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
#endif
|
|
|
|
//
|
|
// On process attach, read setup information from registry.
|
|
//
|
|
|
|
GetMcdFlags();
|
|
|
|
#ifdef WINNT
|
|
//
|
|
// Quick hack to work around multimon problems.
|
|
// If there's more than one monitor, completely disable
|
|
// MCD.
|
|
//
|
|
|
|
if (GetSystemMetrics(SM_CMONITORS) > 1)
|
|
{
|
|
McdPrivateFlags &= ~MCDPRIVATE_MCD_ENABLED;
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
#ifdef MCD95
|
|
//
|
|
// MCD is now closed!
|
|
//
|
|
|
|
pMCDEngEscFilter = (MCDENGESCFILTERFUNC) NULL;
|
|
|
|
//
|
|
// Delete local driver sempahore.
|
|
//
|
|
|
|
DeleteCriticalSection((LPCRITICAL_SECTION) &gsemMcd);
|
|
#endif
|
|
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
|
|
//
|
|
// Nothing to do yet for thread attach/detach.
|
|
//
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* MCDGetMcdCritSect__priv
|
|
*
|
|
* MCD95 ONLY
|
|
*
|
|
* Return pointer to local MCD semaphore. Used to synchronize MCD32.DLL and
|
|
* MCDSRV32.DLL.
|
|
*
|
|
* Returns:
|
|
* Pointer to semaphore. Returns NULL on non-MCD95 builds.
|
|
*
|
|
* History:
|
|
* 18-Mar-1997 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
LPCRITICAL_SECTION APIENTRY MCDGetMcdCritSect__priv()
|
|
{
|
|
#ifdef MCD95
|
|
return &gsemMcd;
|
|
#else
|
|
return (LPCRITICAL_SECTION) NULL;
|
|
#endif
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* GetMcdRegValue
|
|
*
|
|
* Get the data for the specified value. If the value cannot be found in
|
|
* the specified registry key or is of a type other than REG_DWORD, then
|
|
* the value is created (or recreated) with the supplied default data.
|
|
*
|
|
* History:
|
|
* 02-Apr-1996 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
long GetMcdRegValue(HKEY hkMcd, REGSAM samAccess, LPSTR lpstrValueName,
|
|
long lDefaultData)
|
|
{
|
|
DWORD dwDataType;
|
|
DWORD cjSize;
|
|
long lData;
|
|
|
|
//
|
|
// For specified value, attempt to fetch the data.
|
|
//
|
|
|
|
cjSize = sizeof(long);
|
|
if ( (RegQueryValueExA(hkMcd,
|
|
lpstrValueName,
|
|
(LPDWORD) NULL,
|
|
&dwDataType,
|
|
(LPBYTE) &lData,
|
|
&cjSize) != ERROR_SUCCESS)
|
|
|| (dwDataType != REG_DWORD) )
|
|
{
|
|
//
|
|
// Since we couldn't get the data, create the value using the
|
|
// specified default data.
|
|
//
|
|
|
|
if (samAccess & KEY_WRITE)
|
|
{
|
|
cjSize = sizeof(long);
|
|
if ( (RegSetValueExA(hkMcd,
|
|
lpstrValueName,
|
|
0, // Reserved
|
|
REG_DWORD,
|
|
(BYTE *) &lDefaultData,
|
|
cjSize) != ERROR_SUCCESS) )
|
|
{
|
|
DBGPRINT1("GetMcdRegValue: RegSetValueExA(%s) failed",
|
|
lpstrValueName);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Whether or not the value was created in the registry key, return
|
|
// the default data.
|
|
//
|
|
|
|
lData = lDefaultData;
|
|
}
|
|
|
|
return lData;
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* GetMcdFlags
|
|
*
|
|
* Fetch the MCD flags from the registry.
|
|
* If the registry entries do not exist, create them.
|
|
*
|
|
* History:
|
|
* 02-Apr-1996 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
#define STR_MCDKEY (PCSTR)"Software\\Microsoft\\Windows\\CurrentVersion\\MCD"
|
|
#define STR_ENABLE (LPSTR)"Enable"
|
|
#define STR_SWAPSYNC (LPSTR)"SwapSync"
|
|
#define STR_8BPP (LPSTR)"Palettized Formats"
|
|
#define STR_IOPRIORITY (LPSTR)"IO Priority"
|
|
#define STR_GENSTENCIL (LPSTR)"Use Generic Stencil"
|
|
#define STR_EMULATEICD (LPSTR)"Enumerate as ICD"
|
|
#define STR_DEBUG (LPSTR)"Debug"
|
|
|
|
void GetMcdFlags()
|
|
{
|
|
HKEY hkMcd;
|
|
DWORD dwAction;
|
|
REGSAM samAccess;
|
|
ULONG ulDefMcdFlags;
|
|
ULONG ulDefMcdFlagsPriv;
|
|
long lTmp;
|
|
|
|
//
|
|
// Default values for McdFlags and McdPrivateFlags.
|
|
// If you want to change the defaults, change them here!
|
|
//
|
|
|
|
ulDefMcdFlags = MCDCONTEXT_SWAPSYNC;
|
|
ulDefMcdFlagsPriv = MCDPRIVATE_MCD_ENABLED |
|
|
MCDPRIVATE_PALETTEFORMATS |
|
|
MCDPRIVATE_USEGENERICSTENCIL;
|
|
|
|
//
|
|
// Set initial values.
|
|
//
|
|
|
|
McdFlags = 0;
|
|
#if DBG
|
|
McdDebugFlags = 0;
|
|
#endif
|
|
|
|
//
|
|
// First try for read/write access. Create the key
|
|
// if necessary.
|
|
//
|
|
|
|
if ( RegCreateKeyExA(HKEY_LOCAL_MACHINE,
|
|
STR_MCDKEY,
|
|
0, // Reserved
|
|
(LPSTR) NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_READ | KEY_WRITE,
|
|
(LPSECURITY_ATTRIBUTES) NULL,
|
|
&hkMcd,
|
|
&dwAction) == ERROR_SUCCESS )
|
|
{
|
|
samAccess = KEY_READ | KEY_WRITE;
|
|
}
|
|
|
|
//
|
|
// Next try read-only access. Do not try to create
|
|
// key. Write permission is required to create and
|
|
// we do not have that permission.
|
|
//
|
|
|
|
else if ( RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
|
STR_MCDKEY,
|
|
0, // Reserved
|
|
KEY_READ,
|
|
&hkMcd) == ERROR_SUCCESS )
|
|
{
|
|
samAccess = KEY_READ;
|
|
}
|
|
|
|
//
|
|
// Finally, the key does not exist and we do not have
|
|
// write access. Fall back on the defaults and return.
|
|
//
|
|
|
|
else
|
|
{
|
|
McdFlags = ulDefMcdFlags;
|
|
McdPrivateFlags = ulDefMcdFlagsPriv;
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// "Enable" value. Default is 1 (enabled).
|
|
//
|
|
|
|
lTmp = (ulDefMcdFlagsPriv & MCDPRIVATE_MCD_ENABLED) ? 1:0;
|
|
if (GetMcdRegValue(hkMcd, samAccess, STR_ENABLE, lTmp))
|
|
McdPrivateFlags |= MCDPRIVATE_MCD_ENABLED;
|
|
else
|
|
McdPrivateFlags &= (~MCDPRIVATE_MCD_ENABLED);
|
|
|
|
//
|
|
// "SwapSync" value. Default is 1 (enabled).
|
|
//
|
|
|
|
lTmp = (ulDefMcdFlags & MCDCONTEXT_SWAPSYNC) ? 1:0;
|
|
lTmp = GetMcdRegValue(hkMcd, samAccess, STR_SWAPSYNC, lTmp);
|
|
if (lTmp != 0)
|
|
{
|
|
McdFlags |= MCDCONTEXT_SWAPSYNC;
|
|
}
|
|
|
|
//
|
|
// "Palettized Formats" value. Default is 1 (enabled).
|
|
//
|
|
|
|
lTmp = (ulDefMcdFlagsPriv & MCDPRIVATE_PALETTEFORMATS) ? 1:0;
|
|
lTmp = GetMcdRegValue(hkMcd, samAccess, STR_8BPP, lTmp);
|
|
if (lTmp != 0)
|
|
{
|
|
McdPrivateFlags |= MCDPRIVATE_PALETTEFORMATS;
|
|
}
|
|
|
|
//
|
|
// "IO Priority" value. Default is 0 (disabled).
|
|
//
|
|
|
|
lTmp = (ulDefMcdFlags & MCDCONTEXT_IO_PRIORITY) ? 1:0;
|
|
lTmp = GetMcdRegValue(hkMcd, samAccess, STR_IOPRIORITY, lTmp);
|
|
if (lTmp != 0)
|
|
{
|
|
McdFlags |= MCDCONTEXT_IO_PRIORITY;
|
|
}
|
|
|
|
//
|
|
// "Use Generic Stencil" value. Default is 1 (enabled).
|
|
//
|
|
|
|
lTmp = (ulDefMcdFlagsPriv & MCDPRIVATE_USEGENERICSTENCIL) ? 1:0;
|
|
lTmp = GetMcdRegValue(hkMcd, samAccess, STR_GENSTENCIL, lTmp);
|
|
if (lTmp != 0)
|
|
{
|
|
McdPrivateFlags |= MCDPRIVATE_USEGENERICSTENCIL;
|
|
}
|
|
|
|
//
|
|
// "Enumerate as ICD" value. Default is 0 (disabled).
|
|
//
|
|
|
|
lTmp = (ulDefMcdFlagsPriv & MCDPRIVATE_EMULATEICD) ? 1:0;
|
|
lTmp = GetMcdRegValue(hkMcd, samAccess, STR_EMULATEICD, lTmp);
|
|
if (lTmp != 0)
|
|
{
|
|
McdPrivateFlags |= MCDPRIVATE_EMULATEICD;
|
|
}
|
|
|
|
#if DBG
|
|
//
|
|
// "Debug" value.
|
|
//
|
|
// Unlike the other settings, we do not create the Debug value if
|
|
// it does not exist.
|
|
//
|
|
|
|
{
|
|
DWORD dwDataType;
|
|
DWORD cjSize;
|
|
|
|
cjSize = sizeof(long);
|
|
if ( (RegQueryValueExA(hkMcd,
|
|
STR_DEBUG,
|
|
(LPDWORD) NULL,
|
|
&dwDataType,
|
|
(LPBYTE) &lTmp,
|
|
&cjSize) == ERROR_SUCCESS)
|
|
&& (dwDataType == REG_DWORD) )
|
|
{
|
|
McdDebugFlags = lTmp;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// We're done, so close the registry key.
|
|
//
|
|
|
|
RegCloseKey(hkMcd);
|
|
}
|