466 lines
10 KiB
C++
466 lines
10 KiB
C++
#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;
|
|
}
|
|
|