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.

264 lines
7.3 KiB

  1. #include "precomp.h"
  2. LONG SHCleanUpValue(HKEY hk, PCTSTR pszKey, PCTSTR pszValue /*= NULL*/)
  3. {
  4. TCHAR szKey[MAX_PATH];
  5. LPTSTR pszCurrent;
  6. HKEY hkAux;
  7. HRESULT hr;
  8. LONG lResult;
  9. if (hk == NULL)
  10. return E_INVALIDARG;
  11. if (StrLen(pszKey) >= countof(szKey))
  12. return E_OUTOFMEMORY;
  13. StrCpy(szKey, pszKey);
  14. if (pszValue != NULL) {
  15. lResult = SHOpenKey(hk, pszKey, KEY_SET_VALUE, &hkAux);
  16. if (lResult == ERROR_SUCCESS) {
  17. lResult = RegDeleteValue(hkAux, pszValue);
  18. SHCloseKey(hkAux);
  19. if (lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND)
  20. return E_FAIL;
  21. }
  22. }
  23. for (pszCurrent = szKey + StrLen(szKey); TRUE; *pszCurrent = TEXT('\0')) {
  24. hr = SHIsKeyEmpty(hk, szKey);
  25. if (FAILED(hr))
  26. if (hr == STG_E_PATHNOTFOUND)
  27. continue;
  28. else
  29. return E_FAIL;
  30. if (hr == S_FALSE)
  31. break;
  32. RegDeleteKey(hk, szKey);
  33. pszCurrent = StrRChr(szKey, pszCurrent, TEXT('\\'));
  34. if (pszCurrent == NULL)
  35. break;
  36. }
  37. return S_OK;
  38. }
  39. void SHCopyKey(HKEY hkFrom, HKEY hkTo)
  40. {
  41. TCHAR szData[1024],
  42. szValue[MAX_PATH];
  43. DWORD dwSize, dwVal, dwSizeData, dwType;
  44. HKEY hkSubkeyFrom, hkSubkeyTo;
  45. dwVal = 0;
  46. dwSize = countof(szValue);
  47. dwSizeData = sizeof(szData);
  48. while (ERROR_SUCCESS == RegEnumValue(hkFrom, dwVal++, szValue, &dwSize, NULL, &dwType, (LPBYTE)szData, &dwSizeData)) {
  49. RegSetValueEx(hkTo, szValue, 0, dwType, (LPBYTE)szData, dwSizeData);
  50. dwSize = countof(szValue);
  51. dwSizeData = sizeof(szData);
  52. }
  53. dwVal = 0;
  54. while (ERROR_SUCCESS == RegEnumKey(hkFrom, dwVal++, szValue, countof(szValue)))
  55. if (ERROR_SUCCESS == SHOpenKey(hkFrom, szValue, KEY_DEFAULT_ACCESS, &hkSubkeyFrom))
  56. if (SHCreateKey(hkTo, szValue, KEY_DEFAULT_ACCESS, &hkSubkeyTo) == ERROR_SUCCESS)
  57. SHCopyKey(hkSubkeyFrom, hkSubkeyTo);
  58. }
  59. HRESULT SHCopyValue(HKEY hkFrom, HKEY hkTo, PCTSTR pszValue)
  60. {
  61. PBYTE pData;
  62. DWORD dwType,
  63. cbData;
  64. LONG lResult;
  65. if (NULL == hkFrom || NULL == hkTo)
  66. return E_INVALIDARG;
  67. if (S_OK != SHValueExists(hkFrom, pszValue))
  68. return STG_E_FILENOTFOUND;
  69. cbData = 0;
  70. lResult = RegQueryValueEx(hkFrom, pszValue, NULL, &dwType, NULL, &cbData);
  71. if (ERROR_SUCCESS != lResult)
  72. return E_FAIL;
  73. pData = (PBYTE)CoTaskMemAlloc(cbData);
  74. if (NULL == pData)
  75. return E_OUTOFMEMORY;
  76. // ZeroMemory(pData, cbData); // don't really have to do this
  77. lResult = RegQueryValueEx(hkFrom, pszValue, NULL, NULL, pData, &cbData);
  78. ASSERT(ERROR_SUCCESS == lResult);
  79. lResult = RegSetValueEx(hkTo, pszValue, 0, dwType, pData, cbData);
  80. CoTaskMemFree(pData);
  81. return (ERROR_SUCCESS == lResult) ? S_OK : HRESULT_FROM_WIN32(lResult);
  82. }
  83. HRESULT SHCopyValue(HKEY hkFrom, PCTSTR pszSubkeyFrom, HKEY hkTo, PCTSTR pszSubkeyTo, PCTSTR pszValue)
  84. {
  85. HKEY hkSubkeyFrom, hkSubkeyTo;
  86. HRESULT hr;
  87. LONG lResult;
  88. hkSubkeyFrom = NULL;
  89. hkSubkeyTo = NULL;
  90. hr = E_FAIL;
  91. if (NULL == hkFrom || NULL == pszSubkeyFrom ||
  92. NULL == hkTo || NULL == pszSubkeyTo) {
  93. hr = E_INVALIDARG;
  94. goto Exit;
  95. }
  96. lResult = SHOpenKey(hkFrom, pszSubkeyFrom, KEY_QUERY_VALUE, &hkSubkeyFrom);
  97. if (ERROR_SUCCESS != lResult) {
  98. hr = (ERROR_FILE_NOT_FOUND == lResult) ? STG_E_PATHNOTFOUND : E_FAIL;
  99. goto Exit;
  100. }
  101. lResult = SHCreateKey(hkTo, pszSubkeyTo, KEY_SET_VALUE, &hkSubkeyTo);
  102. if (ERROR_SUCCESS != lResult)
  103. goto Exit;
  104. hr = SHCopyValue(hkSubkeyFrom, hkSubkeyTo, pszValue);
  105. Exit:
  106. SHCloseKey(hkSubkeyFrom);
  107. SHCloseKey(hkSubkeyTo);
  108. return hr;
  109. }
  110. HRESULT SHIsKeyEmpty(HKEY hk)
  111. {
  112. DWORD dwKeys, dwValues;
  113. LONG lResult;
  114. if (hk == NULL)
  115. return E_INVALIDARG;
  116. lResult = RegQueryInfoKey(hk, NULL, NULL, NULL, &dwKeys, NULL, NULL, &dwValues, NULL, NULL, NULL, NULL);
  117. if (lResult != ERROR_SUCCESS)
  118. return E_FAIL;
  119. return (dwKeys == 0 && dwValues == 0) ? S_OK : S_FALSE;
  120. }
  121. HRESULT SHIsKeyEmpty(HKEY hk, PCTSTR pszSubKey)
  122. {
  123. HKEY hkAux;
  124. HRESULT hr;
  125. LONG lResult;
  126. lResult = SHOpenKey(hk, pszSubKey, KEY_QUERY_VALUE, &hkAux);
  127. if (lResult != ERROR_SUCCESS)
  128. return (lResult == ERROR_FILE_NOT_FOUND) ? STG_E_PATHNOTFOUND : E_FAIL;
  129. hr = SHIsKeyEmpty(hkAux);
  130. SHCloseKey(hkAux);
  131. return hr;
  132. }
  133. HRESULT SHKeyExists(HKEY hk, PCTSTR pszSubKey)
  134. {
  135. HKEY hkAux;
  136. HRESULT hr;
  137. DWORD lResult;
  138. if (hk == NULL)
  139. return E_INVALIDARG;
  140. hkAux = NULL;
  141. lResult = SHOpenKey(hk, pszSubKey, KEY_QUERY_VALUE, &hkAux);
  142. SHCloseKey(hkAux);
  143. hr = S_OK;
  144. if (lResult != ERROR_SUCCESS)
  145. hr = (lResult == ERROR_FILE_NOT_FOUND) ? S_FALSE : E_FAIL;
  146. return hr;
  147. }
  148. HRESULT SHValueExists(HKEY hk, PCTSTR pszValue)
  149. {
  150. HRESULT hr;
  151. DWORD lResult;
  152. if (hk == NULL)
  153. return E_INVALIDARG;
  154. if (pszValue != NULL && *pszValue != TEXT('\0'))
  155. lResult = RegQueryValueEx(hk, pszValue, NULL, NULL, NULL, NULL);
  156. else {
  157. DWORD dwValueDataLen;
  158. TCHAR szDummyBuf[1];
  159. // On Win95, for the default value name, its existence is checked as follows:
  160. // - pass in a dummy buffer for the value data but pass in the size of the buffer as 0
  161. // - the query would succeed if and only if there is no value data set
  162. // - for all other cases, including the case where the value data is just the empty string,
  163. // the query would fail and dwValueDataLen would contain the no. of bytes needed to
  164. // fit in the value data
  165. // On NT4.0, if no value data is set, the query returns ERROR_FILE_NOT_FOUND
  166. dwValueDataLen = 0;
  167. lResult = RegQueryValueEx(hk, pszValue, NULL, NULL, (LPBYTE)szDummyBuf, &dwValueDataLen);
  168. if (lResult == ERROR_SUCCESS)
  169. lResult = ERROR_FILE_NOT_FOUND;
  170. }
  171. hr = S_OK;
  172. if (lResult != ERROR_SUCCESS)
  173. hr = (lResult == ERROR_FILE_NOT_FOUND) ? S_FALSE : E_FAIL;
  174. return hr;
  175. }
  176. HRESULT SHValueExists(HKEY hk, PCTSTR pszSubKey, PCTSTR pszValue)
  177. {
  178. HKEY hkAux;
  179. HRESULT hr;
  180. LONG lResult;
  181. lResult = SHOpenKey(hk, pszSubKey, KEY_QUERY_VALUE, &hkAux);
  182. if (lResult != ERROR_SUCCESS)
  183. return (lResult == ERROR_FILE_NOT_FOUND) ? STG_E_PATHNOTFOUND : E_FAIL;
  184. hr = SHValueExists(hkAux, pszValue);
  185. SHCloseKey(hkAux);
  186. return hr;
  187. }
  188. DWORD RegSaveRestoreDWORD(HKEY hk, PCTSTR pcszValue, DWORD dwVal)
  189. {
  190. DWORD dwRet, dwSize;
  191. // Note: we assume that a value of 0 is equivalent to the value not being there at all
  192. dwSize = sizeof(dwRet);
  193. if (SHQueryValueEx(hk, pcszValue, NULL, NULL, (LPVOID)&dwRet, &dwSize) != ERROR_SUCCESS)
  194. dwRet = 0;
  195. if (dwVal == 0)
  196. RegDeleteValue(hk, pcszValue);
  197. else
  198. RegSetValueEx(hk, pcszValue, 0, REG_DWORD, (CONST BYTE *)&dwVal, sizeof(dwVal));
  199. return dwRet; // return the value we overwrite in the registry
  200. }