Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

465 lines
10 KiB

#include "priv.h"
#include "deskcmmn.h"
#include <regstr.h>
#include <ccstock.h>
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;
}