|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
migrate.cpp
Environment:
WIN32 User Mode
--*/
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <initguid.h>
#include "migrate.h"
#include <regstr.h>
#include <ccstock.h>
// this will change when the .h is moved to a public location
#include "comp.h"
const TCHAR szWhackDevice[] = TEXT("\\Device");
#define IsRegStringType(x) (((x) == REG_SZ) || ((x) == REG_EXPAND_SZ) || ((x) == REG_MULTI_SZ))
//
// Data
//
PFN_CM_LOCATE_DEVNODE gpfn_CM_Locate_DevNode = NULL; PFN_SETUP_DI_ENUM_DEVICES_INTERFACES gpfn_SetupDiEnumDeviceInterfaces = NULL; PFN_SETUP_DI_GET_DEVICE_INTERFACE_DETAIL gpfn_SetupDiGetDeviceInterfaceDetail = NULL; PFN_SETUP_DI_CREATE_DEVICE_INTERFACE_REG_KEY gpfn_SetupDiCreateDeviceInterfaceRegKey = NULL; PFN_SETUP_DI_OPEN_DEVICE_INTERFACE_REG_KEY gpfn_SetupDiOpenDeviceInterfaceRegKey = NULL; PFN_SETUP_DI_CREATE_DEVICE_INTERFACE gpfn_SetupDiCreateDeviceInterface = NULL;
//
// DllMain
//
extern "C" {
BOOL APIENTRY DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: break;
case DLL_PROCESS_DETACH: break;
case DLL_THREAD_DETACH: break;
case DLL_THREAD_ATTACH: break;
default: break; }
return TRUE; }
}
BOOL VideoUpgradeCheck( PCOMPAIBILITYCALLBACK CompatibilityCallback, LPVOID Context ) { DWORD dwDisposition; HKEY hKey = 0; OSVERSIONINFO osVer; BOOL bSuccess = FALSE;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, SZ_UPDATE_SETTINGS, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition) != ERROR_SUCCESS) { //
// Oh well, guess we can't write it, no big deal
//
hKey = 0; goto Cleanup; }
ZeroMemory(&osVer, sizeof(osVer)); osVer.dwOSVersionInfoSize = sizeof(osVer);
if (!GetVersionEx(&osVer)) { //
// We can't get the version info, no big deal
//
goto Cleanup; }
//
// Get the current device caps and store them away for the
// display applet to apply later.
// Do it only if this is not a remote session.
//
if (!GetSystemMetrics(SM_REMOTESESSION)) { SaveDisplaySettings(hKey, &osVer); }
//
// Store the OS version we are upgrading from
//
SaveOsInfo(hKey, &osVer);
//
// Save the video services
//
if ((osVer.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osVer.dwMajorVersion <= 4)) { SaveNT4Services(hKey); }
//
// Save the applet extensions
//
if ((osVer.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osVer.dwMajorVersion <= 5)) { SaveAppletExtensions(hKey); }
bSuccess = TRUE;
Cleanup:
if (hKey != 0) { RegCloseKey(hKey); }
return bSuccess; }
VOID SaveOsInfo( HKEY hKey, POSVERSIONINFO posVer ) { DWORD cb;
//
// Can't just dump the struct into the registry b/c of the size
// difference between CHAR and WCHAR (ie, szCSDVersion)
//
cb = sizeof(DWORD); RegSetValueEx(hKey, SZ_UPGRADE_FROM_PLATFORM, 0, REG_DWORD, (PBYTE)&(posVer->dwPlatformId), cb);
cb = sizeof(DWORD); RegSetValueEx(hKey, SZ_UPGRADE_FROM_MAJOR_VERSION, 0, REG_DWORD, (PBYTE)&(posVer->dwMajorVersion), cb);
cb = sizeof(DWORD); RegSetValueEx(hKey, SZ_UPGRADE_FROM_MINOR_VERSION, 0, REG_DWORD, (PBYTE)&(posVer->dwMinorVersion), cb);
cb = sizeof(DWORD); RegSetValueEx(hKey, SZ_UPGRADE_FROM_BUILD_NUMBER, 0, REG_DWORD, (PBYTE)&(posVer->dwBuildNumber), cb);
cb = lstrlen(posVer->szCSDVersion); RegSetValueEx(hKey, SZ_UPGRADE_FROM_VERSION_DESC, 0, REG_SZ, (PBYTE)&(posVer->szCSDVersion), cb); }
BOOL SaveDisplaySettings( HKEY hKey, POSVERSIONINFO posVer ) { PVU_PHYSICAL_DEVICE pPhysicalDevice = NULL; BOOL bSuccess = FALSE;
if ((posVer->dwPlatformId == VER_PLATFORM_WIN32_NT) && (posVer->dwMajorVersion >= 5)) { //
// Try the new way to get the display settings
//
CollectDisplaySettings(&pPhysicalDevice); }
if (pPhysicalDevice == NULL) { //
// Try the old way to get the display settings
//
LegacyCollectDisplaySettings(&pPhysicalDevice); }
if (pPhysicalDevice != NULL) { //
// Save the display settings to registry
//
bSuccess = WriteDisplaySettingsToRegistry(hKey, pPhysicalDevice);
//
// Cleanup
//
FreeAllNodes(pPhysicalDevice); }
return bSuccess; }
BOOL GetDevInfoData( IN LPTSTR pDeviceKey, OUT HDEVINFO* phDevInfo, OUT PSP_DEVINFO_DATA pDevInfoData )
/*
Note: If this function retuns success, the caller is responsible to destroy the device info list returned in phDevInfo
*/
{ LPWSTR pwInterfaceName = NULL; LPWSTR pwInstanceID = NULL; BOOL bSuccess = FALSE;
ASSERT (pDeviceKey != NULL);
if (AllocAndReadInterfaceName(pDeviceKey, &pwInterfaceName)) { bSuccess = GetDevInfoDataFromInterfaceName(pwInterfaceName, phDevInfo, pDevInfoData); LocalFree(pwInterfaceName);
}
if ((!bSuccess) && AllocAndReadInstanceID(pDeviceKey, &pwInstanceID)) { bSuccess = GetDevInfoDataFromInstanceID(pwInstanceID, phDevInfo, pDevInfoData); LocalFree(pwInstanceID);
}
return bSuccess; }
BOOL GetDevInfoDataFromInterfaceName( IN LPWSTR pwInterfaceName, OUT HDEVINFO* phDevInfo, OUT PSP_DEVINFO_DATA pDevInfoData )
/*
Note: If this function retuns success, the caller is responsible to destroy the device info list returned in phDevInfo
*/
{ LPWSTR pwDevicePath = NULL; HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DevInfoData; SP_DEVICE_INTERFACE_DATA InterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL; DWORD InterfaceIndex = 0; DWORD InterfaceSize = 0; BOOL bMatch = FALSE;
ASSERT (pwInterfaceName != NULL); ASSERT (phDevInfo != NULL); ASSERT (pDevInfoData != NULL);
ASSERT(gpfn_SetupDiEnumDeviceInterfaces != NULL); ASSERT(gpfn_SetupDiGetDeviceInterfaceDetail != NULL);
//
// Enumerate all display adapter interfaces
//
hDevInfo = SetupDiGetClassDevs(&GUID_DISPLAY_ADAPTER_INTERFACE, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE) { goto Cleanup; }
InterfaceData.cbSize = sizeof(InterfaceData); while ((*gpfn_SetupDiEnumDeviceInterfaces)(hDevInfo, NULL, &GUID_DISPLAY_ADAPTER_INTERFACE, InterfaceIndex, &InterfaceData)) { //
// Get the required size for the interface
//
InterfaceSize = 0; (*gpfn_SetupDiGetDeviceInterfaceDetail)(hDevInfo, &InterfaceData, NULL, 0, &InterfaceSize, NULL);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { goto Cleanup; }
//
// Alloc memory for the interface
//
pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc(LPTR, InterfaceSize); if (pInterfaceDetailData == NULL) goto Cleanup;
//
// Get the interface
//
pInterfaceDetailData->cbSize = sizeof(*pInterfaceDetailData); DevInfoData.cbSize = sizeof(DevInfoData);
if ((*gpfn_SetupDiGetDeviceInterfaceDetail)(hDevInfo, &InterfaceData, pInterfaceDetailData, InterfaceSize, &InterfaceSize, &DevInfoData)) { //
// Is the InterfaceName the same as the DevicePath?
//
pwDevicePath = pInterfaceDetailData->DevicePath;
//
// The first 4 characters of the interface name are different
// between user mode and kernel mode (e.g. "\\?\" vs "\\.\")
// Therefore, ignore them.
//
bMatch = (_wcsnicmp(pwInterfaceName + 4, pwDevicePath + 4, wcslen(pwInterfaceName + 4)) == 0);
if (bMatch) { //
// We found the device
//
*phDevInfo = hDevInfo; CopyMemory(pDevInfoData, &DevInfoData, sizeof(*pDevInfoData));
break; } }
//
// Clean-up
//
LocalFree(pInterfaceDetailData); pInterfaceDetailData = NULL;
//
// Next interface ...
//
InterfaceData.cbSize = sizeof(InterfaceData); ++InterfaceIndex; }
Cleanup:
if (pInterfaceDetailData != NULL) { LocalFree(pInterfaceDetailData); }
//
// Upon success, the caller is responsible to destroy the list
//
if (!bMatch && (hDevInfo != INVALID_HANDLE_VALUE)) { SetupDiDestroyDeviceInfoList(hDevInfo); }
return bMatch; }
BOOL GetDevInfoDataFromInstanceID( IN LPWSTR pwInstanceID, OUT HDEVINFO* phDevInfo, OUT PSP_DEVINFO_DATA pDevInfoData )
/*
Note: If this function retuns success, the caller is responsible to destroy the device info list returned in phDevInfo
*/
{ LPTSTR pInstanceID = NULL; HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; DWORD DeviceIndex = 0; SP_DEVINFO_DATA DevInfoData; DEVINST DevInst; BOOL bSuccess = FALSE, bLocate = FALSE;
ASSERT (pwInstanceID != NULL); ASSERT (phDevInfo != NULL); ASSERT (pDevInfoData != NULL);
ASSERT (gpfn_CM_Locate_DevNode != NULL);
pInstanceID = pwInstanceID;
bLocate = ((*gpfn_CM_Locate_DevNode)(&DevInst, pInstanceID, 0) == CR_SUCCESS);
if (!bLocate) { goto Cleanup; }
//
// Enumerate all display adapters
//
hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVCLASS_DISPLAY, NULL, NULL, DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE) { goto Cleanup; }
DevInfoData.cbSize = sizeof(DevInfoData); while (SetupDiEnumDeviceInfo(hDevInfo, DeviceIndex, &DevInfoData)) { if (DevInfoData.DevInst == DevInst) { //
// We found it
//
*phDevInfo = hDevInfo; CopyMemory(pDevInfoData, &DevInfoData, sizeof(*pDevInfoData)); bSuccess = TRUE;
break; }
//
// Next display adapter
//
++DeviceIndex; DevInfoData.cbSize = sizeof(DevInfoData); }
Cleanup:
//
// Upon success, the caller is responsible to destroy the list
//
if (!bSuccess && (hDevInfo != INVALID_HANDLE_VALUE)) { SetupDiDestroyDeviceInfoList(hDevInfo); }
return bSuccess; }
VOID CollectDisplaySettings( PVU_PHYSICAL_DEVICE* ppPhysicalDevice ) { DISPLAY_DEVICE DisplayDevice; DEVMODE DevMode; PVU_LOGICAL_DEVICE pLogicalDevice = NULL; DWORD dwEnum = 0; BOOL bGoOn = FALSE; HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DevInfoData; DWORD BusNumber = 0, Address = 0; LPTSTR pDeviceX = NULL, pX = NULL; HINSTANCE hinstSetupApi = NULL; BOOL bInserted = FALSE; HKEY hDeviceKey = NULL;
hinstSetupApi = LoadLibrary(TEXT("SETUPAPI.DLL"));
if (hinstSetupApi == NULL) { goto Cleanup; }
gpfn_CM_Locate_DevNode = (PFN_CM_LOCATE_DEVNODE) GetProcAddress(hinstSetupApi, "CM_Locate_DevNodeW");
gpfn_SetupDiGetDeviceInterfaceDetail = (PFN_SETUP_DI_GET_DEVICE_INTERFACE_DETAIL) GetProcAddress(hinstSetupApi, "SetupDiGetDeviceInterfaceDetailW");
gpfn_SetupDiCreateDeviceInterfaceRegKey = (PFN_SETUP_DI_CREATE_DEVICE_INTERFACE_REG_KEY) GetProcAddress(hinstSetupApi, "SetupDiCreateDeviceInterfaceRegKeyW");
gpfn_SetupDiCreateDeviceInterface = (PFN_SETUP_DI_CREATE_DEVICE_INTERFACE) GetProcAddress(hinstSetupApi, "SetupDiCreateDeviceInterfaceW");
gpfn_SetupDiEnumDeviceInterfaces = (PFN_SETUP_DI_ENUM_DEVICES_INTERFACES) GetProcAddress(hinstSetupApi, "SetupDiEnumDeviceInterfaces");
gpfn_SetupDiOpenDeviceInterfaceRegKey = (PFN_SETUP_DI_OPEN_DEVICE_INTERFACE_REG_KEY) GetProcAddress(hinstSetupApi, "SetupDiOpenDeviceInterfaceRegKey");
if ((gpfn_CM_Locate_DevNode == NULL) || (gpfn_SetupDiEnumDeviceInterfaces == NULL) || (gpfn_SetupDiGetDeviceInterfaceDetail == NULL) || (gpfn_SetupDiCreateDeviceInterfaceRegKey == NULL) || (gpfn_SetupDiOpenDeviceInterfaceRegKey == NULL) || (gpfn_SetupDiCreateDeviceInterface == NULL)) { goto Cleanup; }
//
// Enumerate all video devices
//
DisplayDevice.cb = sizeof(DISPLAY_DEVICE); while (EnumDisplayDevices(NULL, dwEnum, &DisplayDevice, 0)) { bInserted = FALSE; pLogicalDevice = NULL;
//
// Get the device info data corresponding to the current
// video device
//
if (!GetDevInfoData(DisplayDevice.DeviceKey, &hDevInfo, &DevInfoData)) { goto NextDevice; } ASSERT (hDevInfo != INVALID_HANDLE_VALUE);
//
// Retrieve the bus number and address
//
bGoOn = SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_BUSNUMBER, NULL, (PBYTE)&BusNumber, sizeof(BusNumber), NULL) && SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_ADDRESS, NULL, (PBYTE)&Address, sizeof(Address), NULL);
SetupDiDestroyDeviceInfoList(hDevInfo);
if (!bGoOn) { goto NextDevice; }
//
// Allocate memory for the logical device
//
pLogicalDevice = (PVU_LOGICAL_DEVICE) LocalAlloc(LPTR, sizeof(VU_LOGICAL_DEVICE));
if (pLogicalDevice == NULL) { goto NextDevice; }
//
// DeviceX
//
pDeviceX = DisplayDevice.DeviceKey + _tcslen(DisplayDevice.DeviceKey);
while ((pDeviceX != DisplayDevice.DeviceKey) && (*pDeviceX != TEXT('\\'))) { pDeviceX--; }
if (pDeviceX == DisplayDevice.DeviceKey) { goto NextDevice; }
pX = SubStrEnd(SZ_DEVICE, pDeviceX); if (pX == pDeviceX) { //
// The new key is used: CCS\Control\Video\[GUID]\000X
//
pX++; pLogicalDevice->DeviceX = _ttoi(pX); } else { //
// The old key is used: CCS\Services\[SrvName]\DeviceX
//
pLogicalDevice->DeviceX = _ttoi(pX); }
//
// AttachedToDesktop
//
pLogicalDevice->AttachedToDesktop = ((DisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0); pLogicalDevice->ValidFields |= VU_ATTACHED_TO_DESKTOP;
if (pLogicalDevice->AttachedToDesktop) { //
// Get the current mode
//
DevMode.dmSize = sizeof(DEVMODE); if (EnumDisplaySettings(DisplayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &DevMode)) { //
// RelativeX, RelativeY, BitsPerPel, XResolution,
// YResolution, VRefresh & Flags
//
pLogicalDevice->ValidFields |= VU_RELATIVE_X; pLogicalDevice->RelativeX = DevMode.dmPosition.x;
pLogicalDevice->ValidFields |= VU_RELATIVE_Y; pLogicalDevice->RelativeY = DevMode.dmPosition.y;
pLogicalDevice->ValidFields |= VU_BITS_PER_PEL; pLogicalDevice->BitsPerPel = DevMode.dmBitsPerPel;
pLogicalDevice->ValidFields |= VU_X_RESOLUTION; pLogicalDevice->XResolution = DevMode.dmPelsWidth;
pLogicalDevice->ValidFields |= VU_Y_RESOLUTION; pLogicalDevice->YResolution = DevMode.dmPelsHeight;
pLogicalDevice->ValidFields |= VU_VREFRESH; pLogicalDevice->VRefresh = DevMode.dmDisplayFrequency;
pLogicalDevice->ValidFields |= VU_FLAGS; pLogicalDevice->Flags = DevMode.dmDisplayFlags;
//
// Ignore the following settings for now:
// DefaultSettings.XPanning - DevMode.dmPanningWidth
// DefaultSettings.YPanning - DevMode.dmPanningHeight
// DefaultSettings.DriverExtra - DevMode.dmDriverExtra
//
} }
if (GetDeviceRegKey(DisplayDevice.DeviceKey, &hDeviceKey)) { DWORD dwTemp, cb; //
// Hardware acceleration
//
cb = sizeof(dwTemp); if (RegQueryValueEx(hDeviceKey, SZ_HW_ACCELERATION, NULL, NULL, (LPBYTE)&dwTemp, &cb) == ERROR_SUCCESS) { pLogicalDevice->ValidFields |= VU_HW_ACCELERATION; pLogicalDevice->HwAcceleration = dwTemp; } //
// Pruning mode
//
cb = sizeof(dwTemp); if (RegQueryValueEx(hDeviceKey, SZ_PRUNNING_MODE, NULL, NULL, (LPBYTE)&dwTemp, &cb) == ERROR_SUCCESS) { pLogicalDevice->ValidFields |= VU_PRUNING_MODE; pLogicalDevice->PruningMode = dwTemp; }
RegCloseKey(hDeviceKey); }
bInserted = InsertNode(ppPhysicalDevice, pLogicalDevice, 0, BusNumber, Address);
NextDevice:
if (!bInserted && (pLogicalDevice != NULL)) { LocalFree(pLogicalDevice); pLogicalDevice = NULL; }
DisplayDevice.cb = sizeof(DISPLAY_DEVICE); ++dwEnum; }
Cleanup:
if (hinstSetupApi != NULL) { gpfn_CM_Locate_DevNode = NULL; gpfn_SetupDiEnumDeviceInterfaces = NULL; gpfn_SetupDiGetDeviceInterfaceDetail = NULL; gpfn_SetupDiCreateDeviceInterfaceRegKey = NULL; gpfn_SetupDiOpenDeviceInterfaceRegKey = NULL; gpfn_SetupDiCreateDeviceInterface = NULL;
FreeLibrary(hinstSetupApi); } }
BOOL InsertNode( PVU_PHYSICAL_DEVICE* ppPhysicalDevice, PVU_LOGICAL_DEVICE pLogicalDevice, DWORD Legacy, DWORD BusNumber, DWORD Address ) { PVU_PHYSICAL_DEVICE pPhysicalDevice = *ppPhysicalDevice; BOOL bSuccess = FALSE; PVU_LOGICAL_DEVICE pPrevLogicalDevice = NULL; PVU_LOGICAL_DEVICE pNextLogicalDevice = NULL;
ASSERT (pLogicalDevice != NULL); ASSERT((Legacy == 0) || (*ppPhysicalDevice == NULL));
if (Legacy == 0) { //
// If not Legacy, try to find if there is a device
// with the same bus location
//
while (pPhysicalDevice != NULL) { if ((pPhysicalDevice->BusNumber == BusNumber) && (pPhysicalDevice->Address == Address)) { break; }
pPhysicalDevice = pPhysicalDevice->pNextPhysicalDevice; } }
if (pPhysicalDevice != NULL) { //
// There is already a logical device with the same address
//
ASSERT (pPhysicalDevice->pFirstLogicalDevice != NULL);
pPhysicalDevice->CountOfLogicalDevices++;
pPrevLogicalDevice = pNextLogicalDevice = pPhysicalDevice->pFirstLogicalDevice;
while (pNextLogicalDevice && (pNextLogicalDevice->DeviceX <= pLogicalDevice->DeviceX)) { pPrevLogicalDevice = pNextLogicalDevice; pNextLogicalDevice = pNextLogicalDevice->pNextLogicalDevice; }
if (pPrevLogicalDevice == pNextLogicalDevice) { ASSERT (pPrevLogicalDevice == pPhysicalDevice->pFirstLogicalDevice);
pLogicalDevice->pNextLogicalDevice = pPhysicalDevice->pFirstLogicalDevice; pPhysicalDevice->pFirstLogicalDevice = pLogicalDevice;
} else { pPrevLogicalDevice->pNextLogicalDevice = pLogicalDevice; pLogicalDevice->pNextLogicalDevice = pNextLogicalDevice; }
bSuccess = TRUE;
} else { //
// This is a new physical device
//
pPhysicalDevice = (PVU_PHYSICAL_DEVICE) LocalAlloc(LPTR, sizeof(VU_PHYSICAL_DEVICE));
if (pPhysicalDevice != NULL) { pPhysicalDevice->pNextPhysicalDevice = *ppPhysicalDevice; *ppPhysicalDevice = pPhysicalDevice;
pPhysicalDevice->pFirstLogicalDevice = pLogicalDevice; pPhysicalDevice->CountOfLogicalDevices = 1; pPhysicalDevice->Legacy = Legacy; pPhysicalDevice->BusNumber = BusNumber; pPhysicalDevice->Address = Address;
bSuccess = TRUE; } }
return bSuccess; }
VOID FreeAllNodes( PVU_PHYSICAL_DEVICE pPhysicalDevice ) { PVU_PHYSICAL_DEVICE pTempPhysicalDevice = NULL; PVU_LOGICAL_DEVICE pLogicalDevice = NULL, pTempLogicalDevice = NULL;
while (pPhysicalDevice != NULL) { pTempPhysicalDevice = pPhysicalDevice->pNextPhysicalDevice; pLogicalDevice = pPhysicalDevice->pFirstLogicalDevice;
while (pLogicalDevice != NULL) { pTempLogicalDevice = pLogicalDevice->pNextLogicalDevice; LocalFree(pLogicalDevice); pLogicalDevice = pTempLogicalDevice; }
LocalFree(pPhysicalDevice); pPhysicalDevice = pTempPhysicalDevice; } }
BOOL WriteDisplaySettingsToRegistry( HKEY hKey, PVU_PHYSICAL_DEVICE pPhysicalDevice ) { PVU_LOGICAL_DEVICE pLogicalDevice = NULL; DWORD CountOfPhysicalDevices = 0; DWORD CountOfLogicalDevices = 0; HKEY hPysicalDeviceKey = 0; HKEY hLogicalDeviceKey = 0; BOOL bSuccess = FALSE; TCHAR Buffer[20];
while (pPhysicalDevice != NULL) { //
// Create physical device subkey
//
StringCchPrintf(Buffer, ARRAYSIZE(Buffer), TEXT("%s%d"), SZ_VU_PHYSICAL, CountOfPhysicalDevices); DeleteKeyAndSubkeys(hKey, Buffer);
if (RegCreateKeyEx(hKey, Buffer, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hPysicalDeviceKey, NULL) != ERROR_SUCCESS) { hPysicalDeviceKey = 0; goto NextPhysicalDevice; }
if (pPhysicalDevice->Legacy == 0) { //
// BusNumber
//
if (RegSetValueEx(hPysicalDeviceKey, SZ_VU_BUS_NUMBER, 0, REG_DWORD, (PBYTE)&pPhysicalDevice->BusNumber, sizeof(pPhysicalDevice->BusNumber)) != ERROR_SUCCESS) { goto NextPhysicalDevice; }
//
// Address
//
if (RegSetValueEx(hPysicalDeviceKey, SZ_VU_ADDRESS, 0, REG_DWORD, (PBYTE)&pPhysicalDevice->Address, sizeof(pPhysicalDevice->Address)) != ERROR_SUCCESS) { goto NextPhysicalDevice; }
}
pLogicalDevice = pPhysicalDevice->pFirstLogicalDevice; CountOfLogicalDevices = 0;
while (pLogicalDevice != NULL) { //
// Create logical device subkey
//
StringCchPrintf(Buffer, ARRAYSIZE(Buffer), TEXT("%s%d"), SZ_VU_LOGICAL, CountOfLogicalDevices); if (RegCreateKeyEx(hPysicalDeviceKey, Buffer, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hLogicalDeviceKey, NULL) != ERROR_SUCCESS) { hLogicalDeviceKey = 0;
//
// Cannot go on with this physical device.
// The order of logical devices DOES matter in the dual-view case.
//
break; }
//
// AttachedToDesktop
//
if (pLogicalDevice->ValidFields & VU_ATTACHED_TO_DESKTOP) { RegSetValueEx(hLogicalDeviceKey, SZ_VU_ATTACHED_TO_DESKTOP, 0, REG_DWORD, (PBYTE)&pLogicalDevice->AttachedToDesktop, sizeof(pLogicalDevice->AttachedToDesktop)); }
//
// RelativeX
//
if (pLogicalDevice->ValidFields & VU_RELATIVE_X) { RegSetValueEx(hLogicalDeviceKey, SZ_VU_RELATIVE_X, 0, REG_DWORD, (PBYTE)&pLogicalDevice->RelativeX, sizeof(pLogicalDevice->RelativeX)); }
//
// RelativeY
//
if (pLogicalDevice->ValidFields & VU_RELATIVE_Y) { RegSetValueEx(hLogicalDeviceKey, SZ_VU_RELATIVE_Y, 0, REG_DWORD, (PBYTE)&pLogicalDevice->RelativeY, sizeof(pLogicalDevice->RelativeY)); }
//
// BitsPerPel
//
if (pLogicalDevice->ValidFields & VU_BITS_PER_PEL) { RegSetValueEx(hLogicalDeviceKey, SZ_VU_BITS_PER_PEL, 0, REG_DWORD, (PBYTE)&pLogicalDevice->BitsPerPel, sizeof(pLogicalDevice->BitsPerPel)); }
//
// XResolution
//
if (pLogicalDevice->ValidFields & VU_X_RESOLUTION) { RegSetValueEx(hLogicalDeviceKey, SZ_VU_X_RESOLUTION, 0, REG_DWORD, (PBYTE)&pLogicalDevice->XResolution, sizeof(pLogicalDevice->XResolution)); }
//
// YResolution
//
if (pLogicalDevice->ValidFields & VU_Y_RESOLUTION) { RegSetValueEx(hLogicalDeviceKey, SZ_VU_Y_RESOLUTION, 0, REG_DWORD, (PBYTE)&pLogicalDevice->YResolution, sizeof(pLogicalDevice->YResolution)); }
//
// VRefresh
//
if (pLogicalDevice->ValidFields & VU_VREFRESH) { RegSetValueEx(hLogicalDeviceKey, SZ_VU_VREFRESH, 0, REG_DWORD, (PBYTE)&pLogicalDevice->VRefresh, sizeof(pLogicalDevice->VRefresh)); }
//
// Flags
//
if (pLogicalDevice->ValidFields & VU_FLAGS) { RegSetValueEx(hLogicalDeviceKey, SZ_VU_FLAGS, 0, REG_DWORD, (PBYTE)&pLogicalDevice->Flags, sizeof(pLogicalDevice->Flags)); }
//
// Hardware acceleration
//
if (pLogicalDevice->ValidFields & VU_HW_ACCELERATION) { RegSetValueEx(hLogicalDeviceKey, SZ_HW_ACCELERATION, 0, REG_DWORD, (PBYTE)&pLogicalDevice->HwAcceleration, sizeof(pLogicalDevice->HwAcceleration)); }
//
// Pruning mode
//
if (pLogicalDevice->ValidFields & VU_PRUNING_MODE) { RegSetValueEx(hLogicalDeviceKey, SZ_PRUNNING_MODE, 0, REG_DWORD, (PBYTE)&pLogicalDevice->PruningMode, sizeof(pLogicalDevice->PruningMode)); }
++CountOfLogicalDevices;
RegCloseKey(hLogicalDeviceKey); hLogicalDeviceKey = 0;
pLogicalDevice = pLogicalDevice->pNextLogicalDevice; }
if ((CountOfLogicalDevices > 0) && (RegSetValueEx(hPysicalDeviceKey, SZ_VU_COUNT, 0, REG_DWORD, (PBYTE)&CountOfLogicalDevices, sizeof(CountOfLogicalDevices)) == ERROR_SUCCESS)) { ++CountOfPhysicalDevices; }
NextPhysicalDevice:
if (hPysicalDeviceKey != 0) { RegCloseKey(hPysicalDeviceKey); hPysicalDeviceKey = 0; }
pPhysicalDevice = pPhysicalDevice->pNextPhysicalDevice; }
if (CountOfPhysicalDevices > 0) { bSuccess = (RegSetValueEx(hKey, SZ_VU_COUNT, 0, REG_DWORD, (PBYTE)&CountOfPhysicalDevices, sizeof(CountOfPhysicalDevices)) != ERROR_SUCCESS); }
return bSuccess; }
VOID LegacyCollectDisplaySettings( PVU_PHYSICAL_DEVICE* ppPhysicalDevice ) { PVU_LOGICAL_DEVICE pLogicalDevice = NULL; INT Width, Height, Index; BOOL useVga = FALSE; HDC hDisplay; POINT Res[] = { { 640, 480}, { 800, 600}, { 1024, 768}, { 1152, 900}, { 1280, 1024}, { 1600, 1200}, { 0, 0} // end of table
};
ASSERT (*ppPhysicalDevice == NULL);
//
// Allocate memory for the logical device
//
pLogicalDevice = (PVU_LOGICAL_DEVICE) LocalAlloc(LPTR, sizeof(VU_LOGICAL_DEVICE)); if (pLogicalDevice == NULL) { return; }
Width = GetSystemMetrics(SM_CXSCREEN); Height = GetSystemMetrics(SM_CYSCREEN);
if (Width == 0 || Height == 0) { //
// Something went wrong, default to lowest common res
//
useVga = TRUE; }
//
// NT 4.0 multimon via driver vendor, not the OS ... adjust the width and height
// back to normal values. Once setup is complete, the second card will come
// on line and it will be taken care of. In both cases, the video area must
// be rectangular, not like MM on 5.0 where we can have "holes"
//
else if (Width >= 2 * Height) { //
// Wide
//
for (Index = 0; Res[Index].x != 0; Index++) { if (Res[Index].y == Height) { Width = Res[Index].x; break; } }
useVga = (Res[Index].x == 0);
} else if (Height > Width) { //
// Tall
//
for (Index = 0; Res[Index].x != 0; Index++) { if (Res[Index].x == Width) { Height = Res[Index].y; break; } }
useVga = (Res[Index].x == 0); }
if (useVga) { //
// No match, default to VGA
//
Width = 640; Height = 480; }
pLogicalDevice->ValidFields |= VU_ATTACHED_TO_DESKTOP; pLogicalDevice->AttachedToDesktop = 1;
pLogicalDevice->ValidFields |= VU_X_RESOLUTION; pLogicalDevice->XResolution = Width;
pLogicalDevice->ValidFields |= VU_Y_RESOLUTION; pLogicalDevice->YResolution = Height;
hDisplay = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); if (hDisplay) { pLogicalDevice->ValidFields |= VU_BITS_PER_PEL; pLogicalDevice->BitsPerPel = GetDeviceCaps(hDisplay, BITSPIXEL);
pLogicalDevice->ValidFields |= VU_VREFRESH; pLogicalDevice->VRefresh = GetDeviceCaps(hDisplay, VREFRESH); DeleteDC(hDisplay); }
if (!InsertNode(ppPhysicalDevice, pLogicalDevice, 1, 0, 0)) { //
// Clean-up
//
LocalFree(pLogicalDevice); } }
VOID SaveNT4Services( HKEY hKey ) { SC_HANDLE hSCManager = NULL; ENUM_SERVICE_STATUS* pmszAllServices = NULL; QUERY_SERVICE_CONFIG* pServiceConfig = NULL; SC_HANDLE hService = NULL; DWORD cbBytesNeeded = 0; DWORD ServicesReturned = 0; DWORD ResumeHandle = 0; DWORD ServiceLen = 0, TotalLen = 0, AllocatedLen = 128; PTCHAR pmszVideoServices = NULL, pmszTemp = NULL;
//
// Allocate initial memory
//
pmszVideoServices = (PTCHAR)LocalAlloc(LPTR, AllocatedLen * sizeof(TCHAR)); if (pmszVideoServices == NULL) { goto Fallout; } //
// Open the service control manager
//
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hSCManager == NULL) { goto Fallout; }
//
// Get the required size
//
if ((!EnumServicesStatus(hSCManager, SERVICE_DRIVER, SERVICE_STATE_ALL, NULL, 0, &cbBytesNeeded, &ServicesReturned, &ResumeHandle)) && (GetLastError() != ERROR_MORE_DATA)) { goto Fallout; }
//
// Allocate the memory
//
pmszAllServices = (ENUM_SERVICE_STATUS*)LocalAlloc(LPTR, cbBytesNeeded);
if (pmszAllServices == NULL) { goto Fallout; }
//
// Get the services
//
ServicesReturned = ResumeHandle = 0; if (!EnumServicesStatus(hSCManager, SERVICE_DRIVER, SERVICE_STATE_ALL, pmszAllServices, cbBytesNeeded, &cbBytesNeeded, &ServicesReturned, &ResumeHandle)) { goto Fallout; }
while (ServicesReturned--) { //
// Open the service
//
hService = OpenService(hSCManager, pmszAllServices[ServicesReturned].lpServiceName, SERVICE_ALL_ACCESS);
if (hService != NULL) { //
// Get the required size to store the config info
//
cbBytesNeeded = 0; if (QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded) || (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { //
// Allocate the memory
//
pServiceConfig = (QUERY_SERVICE_CONFIG*) LocalAlloc(LPTR, cbBytesNeeded);
if (pServiceConfig != NULL) { //
// Get the config info
//
if (QueryServiceConfig(hService, pServiceConfig, cbBytesNeeded, &cbBytesNeeded) && (pServiceConfig->dwStartType != SERVICE_DISABLED) && (_tcsicmp(pServiceConfig->lpLoadOrderGroup, TEXT("Video")) == 0)) { ServiceLen = _tcslen(pmszAllServices[ServicesReturned].lpServiceName); if (TotalLen + ServiceLen + 2 > AllocatedLen) { AllocatedLen = TotalLen + ServiceLen + 128;
pmszTemp = (PTCHAR)LocalAlloc(LPTR, AllocatedLen * sizeof(TCHAR));
if (pmszTemp == NULL) { goto Fallout; }
CopyMemory(pmszTemp, pmszVideoServices, TotalLen * sizeof(TCHAR));
LocalFree(pmszVideoServices);
pmszVideoServices = pmszTemp; pmszTemp = NULL; }
StringCchCopy(pmszVideoServices + TotalLen, AllocatedLen - TotalLen, pmszAllServices[ServicesReturned].lpServiceName); TotalLen += ServiceLen + 1; }
LocalFree(pServiceConfig); pServiceConfig = NULL; } }
CloseServiceHandle(hService); hService = NULL; } }
//
// Save the services to the registry
//
pmszVideoServices[TotalLen++] = TEXT('\0'); RegSetValueEx(hKey, SZ_SERVICES_TO_DISABLE, 0, REG_MULTI_SZ, (BYTE*)pmszVideoServices, TotalLen * sizeof(TCHAR));
Fallout: if (hService != NULL) { CloseServiceHandle(hService); }
if (pServiceConfig != NULL) { LocalFree(pServiceConfig); }
if (pmszAllServices != NULL) { LocalFree(pmszAllServices); }
if (hSCManager != NULL) { CloseServiceHandle(hSCManager); }
if (pmszVideoServices != NULL) { LocalFree(pmszVideoServices); }
} // SaveNT4Services
BOOL DeleteKeyAndSubkeys( HKEY hKey, LPCTSTR lpSubKey ) { HKEY hkDeleteKey; TCHAR szChild[MAX_PATH + 1]; BOOL bReturn = FALSE;
if (RegOpenKeyEx(hKey, lpSubKey, 0, KEY_READ | KEY_WRITE, &hkDeleteKey) == ERROR_SUCCESS) { bReturn = TRUE; while (RegEnumKey(hkDeleteKey, 0, szChild, ARRAYSIZE(szChild)) == ERROR_SUCCESS) { if (!DeleteKeyAndSubkeys(hkDeleteKey, szChild)) { bReturn = FALSE; break; } }
RegCloseKey(hkDeleteKey);
if (bReturn) bReturn = (RegDeleteKey(hKey, lpSubKey) == ERROR_SUCCESS); }
return bReturn; }
VOID SaveAppletExtensions( HKEY hKey ) { PAPPEXT pAppExt = NULL; PAPPEXT pAppExtTemp; DWORD Len = 0; PTCHAR pmszAppExt = NULL; DWORD cchAppExt; HKEY hkDisplay;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER_DISPLAY_SHEX_PROPSHEET, 0, KEY_READ, &hkDisplay) == ERROR_SUCCESS) { DeskAESnapshot(hkDisplay, &pAppExt);
if (pAppExt != NULL) { pAppExtTemp = pAppExt; while (pAppExtTemp) { Len += lstrlen(pAppExtTemp->szDefaultValue) + 1; pAppExtTemp = pAppExtTemp->pNext; }
cchAppExt = (Len + 1); pmszAppExt = (PTCHAR)LocalAlloc(LPTR, cchAppExt * sizeof(TCHAR)); if (pmszAppExt != NULL) { pAppExtTemp = pAppExt; Len = 0; while (pAppExtTemp) {
StringCchCopy(pmszAppExt + Len, cchAppExt - Len, pAppExtTemp->szDefaultValue); Len += lstrlen(pAppExtTemp->szDefaultValue) + 1; pAppExtTemp = pAppExtTemp->pNext; }
RegSetValueEx(hKey, SZ_APPEXT_TO_DELETE, 0, REG_MULTI_SZ, (BYTE*)pmszAppExt, (Len + 1) * sizeof(TCHAR)); LocalFree(pmszAppExt); }
DeskAECleanup(pAppExt); }
RegCloseKey(hkDisplay); } }
|