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

  1. #include "priv.h"
  2. #include "deskcmmn.h"
  3. #include <regstr.h>
  4. #include <ccstock.h>
  5. static const TCHAR sc_szDeskAppletSoftwareKey[] = REGSTR_PATH_CONTROLSFOLDER TEXT("\\Display");
  6. LPTSTR SubStrEnd(LPTSTR pszTarget, LPTSTR pszScan)
  7. {
  8. int i;
  9. for (i = 0; pszScan[i] != TEXT('\0') && pszTarget[i] != TEXT('\0') &&
  10. CharUpperChar(pszScan[i]) == CharUpperChar(pszTarget[i]); i++);
  11. if (pszTarget[i] == TEXT('\0'))
  12. {
  13. // we found the substring
  14. return pszScan + i;
  15. }
  16. return pszScan;
  17. }
  18. BOOL GetDeviceRegKey(LPCTSTR pstrDeviceKey, HKEY* phKey, BOOL* pbReadOnly)
  19. {
  20. //ASSERT(lstrlen(pstrDeviceKey) < MAX_PATH);
  21. if(lstrlen(pstrDeviceKey) >= MAX_PATH)
  22. return FALSE;
  23. BOOL bRet = FALSE;
  24. // copy to local string
  25. TCHAR szBuffer[MAX_PATH];
  26. lstrcpy(szBuffer, pstrDeviceKey);
  27. //
  28. // At this point, szBuffer has something like:
  29. // \REGISTRY\Machine\System\ControlSet001\Services\Jazzg300\Device0
  30. //
  31. // To use the Win32 registry calls, we have to strip off the \REGISTRY
  32. // and convert \Machine to HKEY_LOCAL_MACHINE
  33. //
  34. LPTSTR pszRegistryPath = SubStrEnd(SZ_REGISTRYMACHINE, szBuffer);
  35. if(pszRegistryPath)
  36. {
  37. // Open the registry key
  38. bRet = (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  39. pszRegistryPath,
  40. 0,
  41. KEY_ALL_ACCESS,
  42. phKey) == ERROR_SUCCESS);
  43. if(bRet)
  44. {
  45. *pbReadOnly = FALSE;
  46. }
  47. else
  48. {
  49. bRet = (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  50. pszRegistryPath,
  51. 0,
  52. KEY_READ,
  53. phKey) == ERROR_SUCCESS);
  54. if (bRet)
  55. {
  56. *pbReadOnly = TRUE;
  57. }
  58. }
  59. }
  60. return bRet;
  61. }
  62. int GetDisplayCPLPreference(LPCTSTR szRegVal)
  63. {
  64. int val = -1;
  65. HKEY hk;
  66. if (RegOpenKeyEx(HKEY_CURRENT_USER, sc_szDeskAppletSoftwareKey, 0, KEY_READ, &hk) == ERROR_SUCCESS)
  67. {
  68. TCHAR sz[64];
  69. DWORD cb = sizeof(sz);
  70. *sz = 0;
  71. if ((RegQueryValueEx(hk, szRegVal, NULL, NULL,
  72. (LPBYTE)sz, &cb) == ERROR_SUCCESS) && *sz)
  73. {
  74. val = StrToInt(sz);
  75. }
  76. RegCloseKey(hk);
  77. }
  78. if (val == -1 && RegOpenKeyEx(HKEY_LOCAL_MACHINE, sc_szDeskAppletSoftwareKey, 0, KEY_READ, &hk) == ERROR_SUCCESS)
  79. {
  80. TCHAR sz[64];
  81. DWORD cb = sizeof(sz);
  82. *sz = 0;
  83. if ((RegQueryValueEx(hk, szRegVal, NULL, NULL,
  84. (LPBYTE)sz, &cb) == ERROR_SUCCESS) && *sz)
  85. {
  86. val = StrToInt(sz);
  87. }
  88. RegCloseKey(hk);
  89. }
  90. return val;
  91. }
  92. int GetDynaCDSPreference()
  93. {
  94. //DLI: until we figure out if this command line stuff is still needed.
  95. // if (g_fCommandLineModeSet)
  96. // return DCDSF_YES;
  97. int iRegVal = GetDisplayCPLPreference(REGSTR_VAL_DYNASETTINGSCHANGE);
  98. if (iRegVal == -1)
  99. iRegVal = DCDSF_DYNA; // Apply dynamically
  100. return iRegVal;
  101. }
  102. void SetDisplayCPLPreference(LPCTSTR szRegVal, int val)
  103. {
  104. HKEY hk;
  105. if (RegCreateKeyEx(HKEY_CURRENT_USER, sc_szDeskAppletSoftwareKey, 0, TEXT(""), 0, KEY_WRITE, NULL, &hk, NULL) ==
  106. ERROR_SUCCESS)
  107. {
  108. TCHAR sz[64];
  109. wsprintf(sz, TEXT("%d"), val);
  110. RegSetValueEx(hk, szRegVal, NULL, REG_SZ,
  111. (LPBYTE)sz, lstrlen(sz) + 1);
  112. RegCloseKey(hk);
  113. }
  114. }
  115. BOOL
  116. AllocAndReadInterfaceName(
  117. IN LPTSTR pDeviceKey,
  118. OUT LPWSTR* ppInterfaceName
  119. )
  120. /*
  121. Note: If this function retuns success, the caller is responsible
  122. to free the memory pointed by *ppInterfaceName
  123. */
  124. {
  125. BOOL bSuccess = FALSE;
  126. LPTSTR pszPath = NULL;
  127. HKEY hkDevice = 0;
  128. HKEY hkVolatileSettings = 0;
  129. //ASSERT (pDeviceKey != NULL);
  130. pszPath = SubStrEnd(SZ_REGISTRYMACHINE, pDeviceKey);
  131. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  132. pszPath,
  133. 0,
  134. KEY_READ,
  135. &hkDevice) != ERROR_SUCCESS) {
  136. hkDevice = 0;
  137. goto Cleanup;
  138. }
  139. if (RegOpenKeyEx(hkDevice,
  140. SZ_VOLATILE_SETTINGS,
  141. 0,
  142. KEY_READ,
  143. &hkVolatileSettings) != ERROR_SUCCESS) {
  144. hkVolatileSettings = 0;
  145. goto Cleanup;
  146. }
  147. bSuccess = AllocAndReadValue(hkVolatileSettings,
  148. SZ_DISPLAY_ADAPTER_INTERFACE_NAME,
  149. ppInterfaceName);
  150. Cleanup:
  151. if (hkVolatileSettings) {
  152. RegCloseKey(hkVolatileSettings);
  153. }
  154. if (hkDevice) {
  155. RegCloseKey(hkDevice);
  156. }
  157. return bSuccess;
  158. }
  159. BOOL
  160. AllocAndReadInstanceID(
  161. IN LPTSTR pDeviceKey,
  162. OUT LPWSTR* ppInstanceID
  163. )
  164. /*
  165. Note: If this function retuns success, the caller is responsible
  166. to free the memory pointed by *ppInstanceID
  167. */
  168. {
  169. LPTSTR pDeviceKeyCopy = NULL, pDeviceKeyCopy2 = NULL;
  170. LPTSTR pTemp = NULL, pX = NULL;
  171. BOOL bSuccess = FALSE;
  172. HKEY hkEnum = 0;
  173. HKEY hkService = 0;
  174. HKEY hkCommon = 0;
  175. DWORD Count = 0;
  176. DWORD cb = 0, len = 0;
  177. //ASSERT (pDeviceKey != NULL);
  178. //
  179. // Make a copy of pDeviceKey
  180. //
  181. len = (DWORD)max (256, (lstrlen(pDeviceKey) + 6) * sizeof(TCHAR));
  182. pDeviceKeyCopy2 = pDeviceKeyCopy = (LPTSTR)LocalAlloc(LPTR, len);
  183. if (pDeviceKeyCopy == NULL) {
  184. goto Cleanup;
  185. }
  186. lstrcpy(pDeviceKeyCopy, pDeviceKey);
  187. pTemp = SubStrEnd(SZ_REGISTRYMACHINE, pDeviceKeyCopy);
  188. pDeviceKeyCopy = pTemp;
  189. //
  190. // Open the service key
  191. //
  192. pTemp = pDeviceKeyCopy + lstrlen(pDeviceKeyCopy);
  193. while ((pTemp != pDeviceKeyCopy) && (*pTemp != TEXT('\\'))) {
  194. pTemp--;
  195. }
  196. if (pTemp == pDeviceKeyCopy) {
  197. goto Cleanup;
  198. }
  199. pX = SubStrEnd(SZ_DEVICE, pTemp);
  200. if (pX == pTemp) {
  201. //
  202. // The new key is used: CCS\Control\Video\[GUID]\000X
  203. //
  204. *pTemp = UNICODE_NULL;
  205. lstrcat(pDeviceKeyCopy, SZ_COMMON_SUBKEY);
  206. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  207. pDeviceKeyCopy,
  208. 0,
  209. KEY_READ,
  210. &hkCommon) != ERROR_SUCCESS) {
  211. hkCommon = 0;
  212. goto Cleanup;
  213. }
  214. pDeviceKeyCopy = pDeviceKeyCopy2;
  215. ZeroMemory(pDeviceKeyCopy, len);
  216. lstrcpy(pDeviceKeyCopy, SZ_SERVICES_PATH);
  217. cb = len - (lstrlen(pDeviceKeyCopy) + 1) * sizeof(TCHAR);
  218. if (RegQueryValueEx(hkCommon,
  219. SZ_SERVICE,
  220. NULL,
  221. NULL,
  222. (LPBYTE)(pDeviceKeyCopy + lstrlen(pDeviceKeyCopy)),
  223. &cb) != ERROR_SUCCESS) {
  224. goto Cleanup;
  225. }
  226. } else {
  227. //
  228. // The old key is used: CCS\Services\[SrvName]\DeviceX
  229. //
  230. *pTemp = UNICODE_NULL;
  231. }
  232. //
  233. // Open the ServiceName key
  234. //
  235. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  236. pDeviceKeyCopy,
  237. 0,
  238. KEY_READ,
  239. &hkService) != ERROR_SUCCESS) {
  240. hkService = 0;
  241. goto Cleanup;
  242. }
  243. //
  244. // Open the "Enum" key under the devicename
  245. //
  246. if (RegOpenKeyEx(hkService,
  247. SZ_ENUM,
  248. 0,
  249. KEY_READ,
  250. &hkEnum) != ERROR_SUCCESS) {
  251. hkEnum = 0;
  252. goto Cleanup;
  253. }
  254. cb = sizeof(Count);
  255. if ((RegQueryValueEx(hkEnum,
  256. SZ_VU_COUNT,
  257. NULL,
  258. NULL,
  259. (LPBYTE)&Count,
  260. &cb) != ERROR_SUCCESS) ||
  261. (Count != 1)) {
  262. //
  263. // Igonore the case when there are at least 2 devices.
  264. //
  265. goto Cleanup;
  266. }
  267. bSuccess = AllocAndReadValue(hkEnum, TEXT("0"), ppInstanceID);
  268. Cleanup:
  269. if (hkEnum != 0) {
  270. RegCloseKey(hkEnum);
  271. }
  272. if (hkService != 0) {
  273. RegCloseKey(hkService);
  274. }
  275. if (hkCommon != 0) {
  276. RegCloseKey(hkCommon);
  277. }
  278. if (pDeviceKeyCopy2 != NULL) {
  279. LocalFree(pDeviceKeyCopy2);
  280. }
  281. return bSuccess;
  282. }
  283. BOOL
  284. AllocAndReadValue(
  285. IN HKEY hkKey,
  286. IN LPTSTR pValueName,
  287. OUT LPWSTR* ppwValueData
  288. )
  289. /*
  290. Note: If this function retuns success, the caller is responsible
  291. to free the memory pointed by *ppwValueData
  292. */
  293. {
  294. LPWSTR pwValueData = NULL;
  295. DWORD AllocUnit = 64;
  296. DWORD cBytes = 0;
  297. BOOL bSuccess = FALSE;
  298. LONG Error = ERROR_SUCCESS;
  299. while (!bSuccess) {
  300. AllocUnit *= 2;
  301. cBytes = AllocUnit * sizeof(WCHAR);
  302. pwValueData = (LPWSTR)(LocalAlloc(LPTR, cBytes));
  303. if (pwValueData == NULL)
  304. break;
  305. Error = RegQueryValueEx(hkKey,
  306. pValueName,
  307. NULL,
  308. NULL,
  309. (LPBYTE)pwValueData,
  310. &cBytes);
  311. bSuccess = (Error == ERROR_SUCCESS);
  312. if (!bSuccess) {
  313. LocalFree(pwValueData);
  314. pwValueData = NULL;
  315. if (Error != ERROR_MORE_DATA)
  316. break;
  317. }
  318. }
  319. if (bSuccess) {
  320. *ppwValueData = pwValueData;
  321. }
  322. return bSuccess;
  323. }
  324. BOOL
  325. DeleteKeyAndSubkeys(
  326. HKEY hKey,
  327. LPCTSTR lpSubKey
  328. )
  329. {
  330. HKEY hkDeleteKey;
  331. TCHAR szChild[MAX_PATH + 1];
  332. BOOL bReturn = FALSE;
  333. if (RegOpenKey(hKey, lpSubKey, &hkDeleteKey) == ERROR_SUCCESS) {
  334. bReturn = TRUE;
  335. while (RegEnumKey(hkDeleteKey, 0, szChild, MAX_PATH) ==
  336. ERROR_SUCCESS) {
  337. if (!DeleteKeyAndSubkeys(hkDeleteKey, szChild)) {
  338. bReturn = FALSE;
  339. break;
  340. }
  341. }
  342. RegCloseKey(hkDeleteKey);
  343. if (bReturn)
  344. bReturn = (RegDeleteKey(hKey, lpSubKey) == ERROR_SUCCESS);
  345. }
  346. return bReturn;
  347. }