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.

282 lines
8.3 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2002.
  5. //
  6. // File: reghelp.cxx
  7. //
  8. // Contents: Registry helper functions for accessing HKCR
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // Notes:
  15. // The registry APIs do a surprising thing when you access
  16. // HKEY_CLASSES_ROOT. They will determine which user hive to use
  17. // based on whoever was impersonating when the first access was made for
  18. // the process, and it will use that mapping no matte who is impersonated
  19. // later. As such, it is impossible to know at any point in time where you
  20. // will be picking up your user mapping when you access HKCR.
  21. // This could present security holes if a malicious user were able to force
  22. // their own hive to be the first one accessed. So, for example, a
  23. // malicious user could force their own InprocServer32 value to be used
  24. // instead of one from a different user's hive.
  25. //
  26. // The APIs in this file provide a reliable means of accessing HKCR, so that
  27. // you always know what the mapping will be. These functions will use
  28. // HKEY_USERS\SID_ProcessToken\Software\Classes instead of trying to get
  29. // the current user's token.
  30. //
  31. //----------------------------------------------------------------------------
  32. #include<nt.h>
  33. #include<ntrtl.h>
  34. #include<nturtl.h>
  35. #include <windows.h>
  36. #include <reghelp.hxx>
  37. //+-------------------------------------------------------------------
  38. //
  39. // Function: Impersonation helper functions
  40. //
  41. //--------------------------------------------------------------------
  42. inline void ResumeImpersonate( HANDLE hToken )
  43. {
  44. if (hToken != NULL)
  45. {
  46. BOOL fResult = SetThreadToken( NULL, hToken );
  47. ASSERT(fResult);
  48. CloseHandle( hToken );
  49. }
  50. }
  51. inline void SuspendImpersonate( HANDLE *pHandle )
  52. {
  53. if(OpenThreadToken( GetCurrentThread(), TOKEN_IMPERSONATE,
  54. TRUE, pHandle ))
  55. {
  56. BOOL fResult = SetThreadToken(NULL, NULL);
  57. ASSERT(fResult);
  58. }
  59. else
  60. {
  61. *pHandle = NULL;
  62. }
  63. }
  64. //+-------------------------------------------------------------------
  65. //
  66. // Function: OpenClassesRootKeyExW, private
  67. //
  68. // Synopsis: See the comments above. This is the special verision of
  69. // RegOpenKeyExW for HKCR-based hives.
  70. //
  71. //--------------------------------------------------------------------
  72. LONG WINAPI OpenClassesRootKeyExW(LPCWSTR pszSubKey,REGSAM samDesired,HKEY *phkResult)
  73. {
  74. LONG lResult = ERROR_SUCCESS;
  75. HANDLE hImpToken = NULL;
  76. HANDLE hProcToken = NULL;
  77. HKEY hkcr = NULL;
  78. if(phkResult == NULL)
  79. return ERROR_INVALID_PARAMETER;
  80. *phkResult = NULL;
  81. SuspendImpersonate(&hImpToken);
  82. BOOL fRet = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hProcToken);
  83. if (fRet)
  84. {
  85. lResult = RegOpenUserClassesRoot(hProcToken, 0, MAXIMUM_ALLOWED, &hkcr);
  86. if (lResult != ERROR_SUCCESS)
  87. {
  88. // Failed to open the user's HKCR. We're going to use
  89. // HKLM\Software\Classes.
  90. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  91. L"Software\\Classes",
  92. 0,
  93. MAXIMUM_ALLOWED,
  94. &hkcr);
  95. }
  96. CloseHandle(hProcToken);
  97. }
  98. else
  99. {
  100. lResult = GetLastError();
  101. }
  102. ResumeImpersonate(hImpToken);
  103. if(lResult == ERROR_SUCCESS)
  104. {
  105. if( (pszSubKey != NULL) && (pszSubKey[0]) )
  106. {
  107. lResult = RegOpenKeyEx(hkcr,pszSubKey,0,samDesired,phkResult);
  108. RegCloseKey(hkcr);
  109. }
  110. else
  111. {
  112. *phkResult = hkcr;
  113. }
  114. }
  115. return lResult;
  116. }
  117. //+-------------------------------------------------------------------
  118. //
  119. // Function: OpenClassesRootKeyW, private
  120. //
  121. // Synopsis: See the comments above. This is the special verision of
  122. // RegOpenKeyW for HKCR-based hives.
  123. //
  124. //--------------------------------------------------------------------
  125. LONG WINAPI OpenClassesRootKeyW(LPCWSTR pszSubKey,HKEY *phkResult)
  126. {
  127. return OpenClassesRootKeyExW(pszSubKey,MAXIMUM_ALLOWED,phkResult);
  128. }
  129. //+-------------------------------------------------------------------
  130. //
  131. // Function: QueryClassesRootValueW, private
  132. //
  133. // Synopsis: See the comments above. This is the special verision of
  134. // RegQueryValue for HKCR-based hives.
  135. //
  136. //--------------------------------------------------------------------
  137. LONG WINAPI QueryClassesRootValueW(LPCWSTR pszSubKey,LPWSTR pszValue,PLONG lpcbValue)
  138. {
  139. HKEY hkcr = NULL;
  140. LONG lResult = OpenClassesRootKeyW(NULL,&hkcr);
  141. if(lResult == ERROR_SUCCESS)
  142. {
  143. lResult = RegQueryValueW(hkcr,pszSubKey,pszValue,lpcbValue);
  144. RegCloseKey(hkcr);
  145. }
  146. return lResult;
  147. }
  148. //+-------------------------------------------------------------------
  149. //
  150. // Function: OpenClassesRootKeyExA, private
  151. //
  152. // Synopsis: See the comments above. This is the special verision of
  153. // RegOpenKeyExA for HKCR-based hives.
  154. //
  155. //--------------------------------------------------------------------
  156. LONG WINAPI OpenClassesRootKeyExA(LPCSTR pszSubKey,REGSAM samDesired,HKEY *phkResult)
  157. {
  158. LONG lResult = ERROR_SUCCESS;
  159. HANDLE hImpToken = NULL;
  160. HANDLE hProcToken = NULL;
  161. HKEY hkcr = NULL;
  162. if(phkResult == NULL)
  163. return ERROR_INVALID_PARAMETER;
  164. *phkResult = NULL;
  165. SuspendImpersonate(&hImpToken);
  166. BOOL fRet = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hProcToken);
  167. if (fRet)
  168. {
  169. lResult = RegOpenUserClassesRoot(hProcToken, 0, MAXIMUM_ALLOWED, &hkcr);
  170. if (lResult != ERROR_SUCCESS)
  171. {
  172. // Failed to open the user's HKCR. We're going to use
  173. // HKLM\Software\Classes.
  174. lResult = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  175. "Software\\Classes",
  176. 0,
  177. MAXIMUM_ALLOWED,
  178. &hkcr);
  179. }
  180. CloseHandle(hProcToken);
  181. }
  182. else
  183. {
  184. lResult = GetLastError();
  185. }
  186. ResumeImpersonate(hImpToken);
  187. if(lResult == ERROR_SUCCESS)
  188. {
  189. if( (pszSubKey != NULL) && (pszSubKey[0]) )
  190. {
  191. lResult = RegOpenKeyExA(hkcr,pszSubKey,0,samDesired,phkResult);
  192. RegCloseKey(hkcr);
  193. }
  194. else
  195. {
  196. *phkResult = hkcr;
  197. }
  198. }
  199. return lResult;
  200. }
  201. //+-------------------------------------------------------------------
  202. //
  203. // Function: OpenClassesRootKeyA, private
  204. //
  205. // Synopsis: See the comments above. This is the special verision of
  206. // RegOpenKeyA for HKCR-based hives.
  207. //
  208. //--------------------------------------------------------------------
  209. LONG WINAPI OpenClassesRootKeyA(LPCSTR pszSubKey,HKEY *phkResult)
  210. {
  211. return OpenClassesRootKeyExA(pszSubKey,MAXIMUM_ALLOWED,phkResult);
  212. }
  213. //+-------------------------------------------------------------------
  214. //
  215. // Function: QueryClassesRootValueA, private
  216. //
  217. // Synopsis: See the comments above. This is the special verision of
  218. // RegQueryValueA for HKCR-based hives.
  219. //
  220. //--------------------------------------------------------------------
  221. LONG WINAPI QueryClassesRootValueA(LPCSTR pszSubKey,LPSTR pszValue,PLONG lpcbValue)
  222. {
  223. HKEY hkcr = NULL;
  224. LONG lResult = OpenClassesRootKeyA(NULL,&hkcr);
  225. if(lResult == ERROR_SUCCESS)
  226. {
  227. lResult = RegQueryValueA(hkcr,pszSubKey,pszValue,lpcbValue);
  228. RegCloseKey(hkcr);
  229. }
  230. return lResult;
  231. }
  232. //+-------------------------------------------------------------------
  233. //
  234. // Function: SetClassesRootValueW, private
  235. //
  236. // Synopsis: See the comments above. This is the special verision of
  237. // RegSetValueW for HKCR-based hives.
  238. //
  239. //--------------------------------------------------------------------
  240. LONG WINAPI SetClassesRootValueW(LPCWSTR pszSubKey,DWORD dwType,LPCWSTR pszData,DWORD cbData)
  241. {
  242. HKEY hkcr = NULL;
  243. LONG lResult = OpenClassesRootKeyW(NULL,&hkcr);
  244. if(lResult == ERROR_SUCCESS)
  245. {
  246. lResult = RegSetValueW(hkcr,pszSubKey,dwType,pszData,cbData);
  247. RegCloseKey(hkcr);
  248. }
  249. return lResult;
  250. }