#include "priv.h" #include "deskcmmn.h" #include #include static const TCHAR sc_szDeskAppletSoftwareKey[] = REGSTR_PATH_CONTROLSFOLDER TEXT("\\Display"); LPTSTR SubStrEnd(LPTSTR pszTarget, LPTSTR pszScan) { int i; for (i = 0; pszScan[i] != TEXT('\0') && pszTarget[i] != TEXT('\0') && CharUpperChar(pszScan[i]) == CharUpperChar(pszTarget[i]); i++); if (pszTarget[i] == TEXT('\0')) { // we found the substring return pszScan + i; } return pszScan; } BOOL GetDeviceRegKey(LPCTSTR pstrDeviceKey, HKEY* phKey, BOOL* pbReadOnly) { //ASSERT(lstrlen(pstrDeviceKey) < MAX_PATH); if(lstrlen(pstrDeviceKey) >= MAX_PATH) return FALSE; BOOL bRet = FALSE; // copy to local string TCHAR szBuffer[MAX_PATH]; lstrcpy(szBuffer, pstrDeviceKey); // // At this point, szBuffer has something like: // \REGISTRY\Machine\System\ControlSet001\Services\Jazzg300\Device0 // // To use the Win32 registry calls, we have to strip off the \REGISTRY // and convert \Machine to HKEY_LOCAL_MACHINE // LPTSTR pszRegistryPath = SubStrEnd(SZ_REGISTRYMACHINE, szBuffer); if(pszRegistryPath) { // Open the registry key bRet = (RegOpenKeyEx(HKEY_LOCAL_MACHINE, pszRegistryPath, 0, KEY_ALL_ACCESS, phKey) == ERROR_SUCCESS); if(bRet) { *pbReadOnly = FALSE; } else { bRet = (RegOpenKeyEx(HKEY_LOCAL_MACHINE, pszRegistryPath, 0, KEY_READ, phKey) == ERROR_SUCCESS); if (bRet) { *pbReadOnly = TRUE; } } } return bRet; } int GetDisplayCPLPreference(LPCTSTR szRegVal) { int val = -1; HKEY hk; if (RegOpenKeyEx(HKEY_CURRENT_USER, sc_szDeskAppletSoftwareKey, 0, KEY_READ, &hk) == ERROR_SUCCESS) { TCHAR sz[64]; DWORD cb = sizeof(sz); *sz = 0; if ((RegQueryValueEx(hk, szRegVal, NULL, NULL, (LPBYTE)sz, &cb) == ERROR_SUCCESS) && *sz) { val = StrToInt(sz); } RegCloseKey(hk); } if (val == -1 && RegOpenKeyEx(HKEY_LOCAL_MACHINE, sc_szDeskAppletSoftwareKey, 0, KEY_READ, &hk) == ERROR_SUCCESS) { TCHAR sz[64]; DWORD cb = sizeof(sz); *sz = 0; if ((RegQueryValueEx(hk, szRegVal, NULL, NULL, (LPBYTE)sz, &cb) == ERROR_SUCCESS) && *sz) { val = StrToInt(sz); } RegCloseKey(hk); } return val; } int GetDynaCDSPreference() { //DLI: until we figure out if this command line stuff is still needed. // if (g_fCommandLineModeSet) // return DCDSF_YES; int iRegVal = GetDisplayCPLPreference(REGSTR_VAL_DYNASETTINGSCHANGE); if (iRegVal == -1) iRegVal = DCDSF_DYNA; // Apply dynamically return iRegVal; } void SetDisplayCPLPreference(LPCTSTR szRegVal, int val) { HKEY hk; if (RegCreateKeyEx(HKEY_CURRENT_USER, sc_szDeskAppletSoftwareKey, 0, TEXT(""), 0, KEY_WRITE, NULL, &hk, NULL) == ERROR_SUCCESS) { TCHAR sz[64]; wsprintf(sz, TEXT("%d"), val); RegSetValueEx(hk, szRegVal, NULL, REG_SZ, (LPBYTE)sz, lstrlen(sz) + 1); RegCloseKey(hk); } } BOOL AllocAndReadInterfaceName( IN LPTSTR pDeviceKey, OUT LPWSTR* ppInterfaceName ) /* Note: If this function retuns success, the caller is responsible to free the memory pointed by *ppInterfaceName */ { BOOL bSuccess = FALSE; LPTSTR pszPath = NULL; HKEY hkDevice = 0; HKEY hkVolatileSettings = 0; //ASSERT (pDeviceKey != NULL); pszPath = SubStrEnd(SZ_REGISTRYMACHINE, pDeviceKey); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, pszPath, 0, KEY_READ, &hkDevice) != ERROR_SUCCESS) { hkDevice = 0; goto Cleanup; } if (RegOpenKeyEx(hkDevice, SZ_VOLATILE_SETTINGS, 0, KEY_READ, &hkVolatileSettings) != ERROR_SUCCESS) { hkVolatileSettings = 0; goto Cleanup; } bSuccess = AllocAndReadValue(hkVolatileSettings, SZ_DISPLAY_ADAPTER_INTERFACE_NAME, ppInterfaceName); Cleanup: if (hkVolatileSettings) { RegCloseKey(hkVolatileSettings); } if (hkDevice) { RegCloseKey(hkDevice); } return bSuccess; } BOOL AllocAndReadInstanceID( IN LPTSTR pDeviceKey, OUT LPWSTR* ppInstanceID ) /* Note: If this function retuns success, the caller is responsible to free the memory pointed by *ppInstanceID */ { LPTSTR pDeviceKeyCopy = NULL, pDeviceKeyCopy2 = NULL; LPTSTR pTemp = NULL, pX = NULL; BOOL bSuccess = FALSE; HKEY hkEnum = 0; HKEY hkService = 0; HKEY hkCommon = 0; DWORD Count = 0; DWORD cb = 0, len = 0; //ASSERT (pDeviceKey != NULL); // // Make a copy of pDeviceKey // len = (DWORD)max (256, (lstrlen(pDeviceKey) + 6) * sizeof(TCHAR)); pDeviceKeyCopy2 = pDeviceKeyCopy = (LPTSTR)LocalAlloc(LPTR, len); if (pDeviceKeyCopy == NULL) { goto Cleanup; } lstrcpy(pDeviceKeyCopy, pDeviceKey); pTemp = SubStrEnd(SZ_REGISTRYMACHINE, pDeviceKeyCopy); pDeviceKeyCopy = pTemp; // // Open the service key // pTemp = pDeviceKeyCopy + lstrlen(pDeviceKeyCopy); while ((pTemp != pDeviceKeyCopy) && (*pTemp != TEXT('\\'))) { pTemp--; } if (pTemp == pDeviceKeyCopy) { goto Cleanup; } pX = SubStrEnd(SZ_DEVICE, pTemp); if (pX == pTemp) { // // The new key is used: CCS\Control\Video\[GUID]\000X // *pTemp = UNICODE_NULL; lstrcat(pDeviceKeyCopy, SZ_COMMON_SUBKEY); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, pDeviceKeyCopy, 0, KEY_READ, &hkCommon) != ERROR_SUCCESS) { hkCommon = 0; goto Cleanup; } pDeviceKeyCopy = pDeviceKeyCopy2; ZeroMemory(pDeviceKeyCopy, len); lstrcpy(pDeviceKeyCopy, SZ_SERVICES_PATH); cb = len - (lstrlen(pDeviceKeyCopy) + 1) * sizeof(TCHAR); if (RegQueryValueEx(hkCommon, SZ_SERVICE, NULL, NULL, (LPBYTE)(pDeviceKeyCopy + lstrlen(pDeviceKeyCopy)), &cb) != ERROR_SUCCESS) { goto Cleanup; } } else { // // The old key is used: CCS\Services\[SrvName]\DeviceX // *pTemp = UNICODE_NULL; } // // Open the ServiceName key // if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, pDeviceKeyCopy, 0, KEY_READ, &hkService) != ERROR_SUCCESS) { hkService = 0; goto Cleanup; } // // Open the "Enum" key under the devicename // if (RegOpenKeyEx(hkService, SZ_ENUM, 0, KEY_READ, &hkEnum) != ERROR_SUCCESS) { hkEnum = 0; goto Cleanup; } cb = sizeof(Count); if ((RegQueryValueEx(hkEnum, SZ_VU_COUNT, NULL, NULL, (LPBYTE)&Count, &cb) != ERROR_SUCCESS) || (Count != 1)) { // // Igonore the case when there are at least 2 devices. // goto Cleanup; } bSuccess = AllocAndReadValue(hkEnum, TEXT("0"), ppInstanceID); Cleanup: if (hkEnum != 0) { RegCloseKey(hkEnum); } if (hkService != 0) { RegCloseKey(hkService); } if (hkCommon != 0) { RegCloseKey(hkCommon); } if (pDeviceKeyCopy2 != NULL) { LocalFree(pDeviceKeyCopy2); } return bSuccess; } BOOL AllocAndReadValue( IN HKEY hkKey, IN LPTSTR pValueName, OUT LPWSTR* ppwValueData ) /* Note: If this function retuns success, the caller is responsible to free the memory pointed by *ppwValueData */ { LPWSTR pwValueData = NULL; DWORD AllocUnit = 64; DWORD cBytes = 0; BOOL bSuccess = FALSE; LONG Error = ERROR_SUCCESS; while (!bSuccess) { AllocUnit *= 2; cBytes = AllocUnit * sizeof(WCHAR); pwValueData = (LPWSTR)(LocalAlloc(LPTR, cBytes)); if (pwValueData == NULL) break; Error = RegQueryValueEx(hkKey, pValueName, NULL, NULL, (LPBYTE)pwValueData, &cBytes); bSuccess = (Error == ERROR_SUCCESS); if (!bSuccess) { LocalFree(pwValueData); pwValueData = NULL; if (Error != ERROR_MORE_DATA) break; } } if (bSuccess) { *ppwValueData = pwValueData; } return bSuccess; } BOOL DeleteKeyAndSubkeys( HKEY hKey, LPCTSTR lpSubKey ) { HKEY hkDeleteKey; TCHAR szChild[MAX_PATH + 1]; BOOL bReturn = FALSE; if (RegOpenKey(hKey, lpSubKey, &hkDeleteKey) == ERROR_SUCCESS) { bReturn = TRUE; while (RegEnumKey(hkDeleteKey, 0, szChild, MAX_PATH) == ERROR_SUCCESS) { if (!DeleteKeyAndSubkeys(hkDeleteKey, szChild)) { bReturn = FALSE; break; } } RegCloseKey(hkDeleteKey); if (bReturn) bReturn = (RegDeleteKey(hKey, lpSubKey) == ERROR_SUCCESS); } return bReturn; }