/******************************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 #include #include #include #include #include #include #include "mcdrv.h" #include #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); }