Leaked source code of windows server 2003
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.

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