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.

972 lines
29 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. wow64reg.c
  5. Abstract:
  6. This module implement some APIs for client who need to access registry in a mix way.
  7. The client need to link againest wow64reg.lib files. The available APIs has been defined
  8. in the wow64reg.h files.
  9. The possible scenario is
  10. 1. 32 bit Apps need to access 64 bit registry key.
  11. 2. 64 bit Apps need to access 32-bit registry key.
  12. 3. The actual redirected path from a given path.
  13. Author:
  14. ATM Shafiqul Khalid (askhalid) 10-Nov-1999
  15. Revision History:
  16. --*/
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <windows.h>
  21. #include <stdio.h>
  22. #include <ntregapi.h>
  23. #include <stdlib.h>
  24. #include "regremap.h"
  25. #include "wow64reg.h"
  26. #include "reflectr.h"
  27. VOID
  28. GetPatchedName (
  29. PWCHAR Dest,
  30. LPCTSTR Source,
  31. DWORD Count
  32. )
  33. /*++
  34. Routine Description:
  35. This function patches 32bit equivalent name from a given name and location to patch from.
  36. XX\ ==>> XX\Wow6432Node count==3
  37. XX ==>> XX\Wow6432Node count==2
  38. XX\PP ==>> XX\Wow6432Node count ==3
  39. Arguments:
  40. Dest - receive the result.
  41. Source - Name to patch
  42. Count - where to patch the string.
  43. Return Value:
  44. None.
  45. --*/
  46. {
  47. BOOL PerfectIsnNode = FALSE;
  48. if (Count) {
  49. wcsncpy ( Dest, Source, Count );
  50. if (Dest[Count-1] != L'\\' ) {
  51. Dest[Count] = L'\\'; // at the end case
  52. Count++;
  53. PerfectIsnNode = TRUE;
  54. }
  55. }
  56. wcscpy ( Dest+Count, NODE_NAME_32BIT );
  57. if ( !PerfectIsnNode ) {
  58. wcscat ( Dest, L"\\");
  59. wcscat ( Dest, Source + Count );
  60. }
  61. //
  62. // Make sure that the patched key are not on the exempt list.
  63. //
  64. }
  65. LONG
  66. Wow64RegOpenKeyEx(
  67. HKEY hKey,
  68. LPCTSTR lpSubKey,
  69. DWORD ulOptions,
  70. REGSAM samDesired,
  71. PHKEY phkResult
  72. )
  73. /*++
  74. Routine Description:
  75. This is the equivalent of RegOpenExW to access reggistry in the mix mode. This code will be
  76. compiled only for 64bit environment. In the 32bit environment WOW64 will take care of everything.
  77. We are nor worried much about performance hit due to opening key twice or retranslating path.
  78. Because only few people will access the registry in the mix mode.
  79. Arguments:
  80. hKey - handle to open key
  81. lpSubKey - address of name of subkey to open
  82. ulOptions - typically 0.
  83. samDesired - security access mask might have WOW64_RES flag
  84. KEY_WOW64_32KEY - this will open 32bit equivalent key disregarding
  85. the process.
  86. KEY_WOW64_64KEY - this will open 64bit equivalent key disregarding the process.
  87. phkResult -address of handle to open key
  88. Return Value:
  89. WIN32 Error code.
  90. --*/
  91. {
  92. OBJECT_ATTRIBUTES Obja;
  93. UNICODE_STRING Parent;
  94. WCHAR ParentName[WOW64_MAX_PATH];
  95. WCHAR TempName[WOW64_MAX_PATH];
  96. DWORD dwBuffLen = WOW64_MAX_PATH;
  97. WCHAR NullString;
  98. PWCHAR p32bitNode;
  99. PWCHAR pPatchLoc;
  100. PWCHAR pDivider;
  101. NTSTATUS st;
  102. BOOL bHandle64 = TRUE; // assume all the handle passed in is 64bit.
  103. if( lpSubKey == NULL ) {
  104. NullString = UNICODE_NULL;
  105. lpSubKey = &NullString;
  106. }
  107. //
  108. // check if the WOW64 reserve bit set. If none of them is set we can't proceede.
  109. //
  110. if (!(samDesired & KEY_WOW64_RES) ) {
  111. //
  112. // return ERROR_INVALID_PARAMETER; try to be optimistic
  113. //
  114. return RegOpenKeyEx (
  115. hKey,
  116. lpSubKey,
  117. ulOptions,
  118. samDesired,
  119. phkResult
  120. );
  121. }
  122. if( hKey == NULL ) {
  123. return ERROR_INVALID_HANDLE;
  124. }
  125. //
  126. // makesure that subkey doesn't have the special wow string
  127. //
  128. if ( ( p32bitNode = wcsistr ((PWCHAR)lpSubKey, NODE_NAME_32BIT)) != NULL ) {
  129. //
  130. // if access 64bit hive compress the subkey, if 32bit hive just pass as it is.
  131. //
  132. if ( samDesired & KEY_WOW64_64KEY ) {
  133. wcscpy (ParentName, lpSubKey);
  134. p32bitNode = ParentName + ( p32bitNode- lpSubKey);
  135. wcscpy ( p32bitNode, p32bitNode + NODE_NAME_32BIT_LEN );
  136. }
  137. return RegOpenKeyEx (
  138. hKey,
  139. ParentName,
  140. ulOptions,
  141. samDesired & (~KEY_WOW64_RES),
  142. phkResult
  143. );
  144. }
  145. //
  146. // Check predefined handle like HKEY_CLASSES_ROOT if so you only need to patch subkey
  147. //
  148. //
  149. // Client must pass meaningful handle to this function.
  150. //
  151. if ( hKey == HKEY_CLASSES_ROOT ) {
  152. wcscpy ( ParentName, MACHINE_CLASSES_ROOT);
  153. } else if ( !HandleToKeyName ( hKey, ParentName, &dwBuffLen ) ) {
  154. //
  155. // should we recoved from buffer overflow. We are not going to support all possible combination.
  156. //
  157. return ERROR_INVALID_HANDLE;
  158. }
  159. //
  160. // If parent has already been patched just call the RegOpenKeyEx for 32bit open
  161. //
  162. if ((p32bitNode = wcsistr (ParentName, NODE_NAME_32BIT)) != NULL ) {
  163. //
  164. // [todo] do you need to make sure that the substring mustbe the subkey
  165. // for an ISN node on 64bit registry to satisfy this condition.
  166. // if we assume that noy key will have this name then the checking is
  167. // good enough.
  168. //
  169. bHandle64 = FALSE; // it's not handle to 64 bit Key
  170. }
  171. //
  172. // Get complete qualified path to do sanity check.
  173. //
  174. pDivider = ParentName + wcslen(ParentName)+1; //point to the divider location
  175. *(pDivider-1)= L'\\';
  176. wcscpy (pDivider, (PWCHAR)lpSubKey);
  177. if (IsExemptRedirectedKey(ParentName, TempName)) {
  178. //
  179. // If the path is on the exempt list we access 64bit hive
  180. //
  181. samDesired = (samDesired & (~KEY_WOW64_RES)) | KEY_WOW64_64KEY; //make sure access 64bit hive
  182. }
  183. if ( ( bHandle64 && (samDesired & KEY_WOW64_64KEY ) ) // if totally 64
  184. || ( !bHandle64 && (samDesired & KEY_WOW64_32KEY ) ) // if totally 32
  185. || !IsIsnNode (ParentName, &pPatchLoc) ) { // if not a ISN node don't care
  186. return RegOpenKeyEx (
  187. hKey,
  188. lpSubKey,
  189. ulOptions,
  190. samDesired & (~KEY_WOW64_RES),
  191. phkResult
  192. );
  193. }
  194. //
  195. // Now it might be mix mode access
  196. //
  197. if ( pPatchLoc >= pDivider ) {
  198. //
  199. // patching only the subkey will be good enough
  200. //
  201. if ( samDesired & KEY_WOW64_64KEY ) { // want to access 64bit just disregard
  202. wcscpy ( ParentName, lpSubKey );
  203. } else {
  204. GetPatchedName (ParentName,lpSubKey, (DWORD)(pPatchLoc-pDivider) );
  205. }
  206. return RegOpenKeyEx (
  207. hKey,
  208. ParentName,
  209. ulOptions,
  210. samDesired & (~KEY_WOW64_RES),
  211. phkResult
  212. );
  213. } else {
  214. if ( samDesired & KEY_WOW64_64KEY ) { // want to access 64bit just disregard
  215. if (p32bitNode != NULL) //compress
  216. wcscpy ( p32bitNode, p32bitNode + NODE_NAME_32BIT_LEN );
  217. RtlInitUnicodeString (&Parent, ParentName );
  218. } else {
  219. GetPatchedName (TempName,ParentName, (DWORD)(pPatchLoc-ParentName));
  220. RtlInitUnicodeString (&Parent, TempName );
  221. }
  222. InitializeObjectAttributes (&Obja,
  223. &Parent,
  224. OBJ_CASE_INSENSITIVE,
  225. NULL,
  226. NULL
  227. );
  228. samDesired &= (~KEY_WOW64_RES);
  229. st = NtOpenKey (phkResult, samDesired, &Obja);
  230. if ( !NT_SUCCESS(st))
  231. return RtlNtStatusToDosError (st);
  232. return 0;
  233. }
  234. }
  235. LONG
  236. Wow64RegCreateKeyEx(
  237. HKEY hKey, // handle to an open key
  238. LPCWSTR lpSubKey, // address of subkey name
  239. DWORD Reserved, // reserved
  240. LPWSTR lpClass, // address of class string
  241. DWORD dwOptions, // special options flag
  242. REGSAM samDesired, // desired security access
  243. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  244. // address of key security structure
  245. PHKEY phkResult, // address of buffer for opened handle
  246. LPDWORD lpdwDisposition // address of disposition value buffer
  247. )
  248. /*++
  249. Routine Description:
  250. An existing registry key may be opened, or a new one created,
  251. with NtCreateKey.
  252. If the specified key does not exist, an attempt is made to create it.
  253. For the create attempt to succeed, the new node must be a direct
  254. child of the node referred to by KeyHandle. If the node exists,
  255. it is opened. Its value is not affected in any way.
  256. Share access is computed from desired access.
  257. NOTE:
  258. If CreateOptions has REG_OPTION_BACKUP_RESTORE set, then
  259. DesiredAccess will be ignored. If the caller has the
  260. privilege SeBackupPrivilege asserted, a handle with
  261. KEY_READ | ACCESS_SYSTEM_SECURITY will be returned.
  262. If SeRestorePrivilege, then same but KEY_WRITE rather
  263. than KEY_READ. If both, then both access sets. If neither
  264. privilege is asserted, then the call will fail.
  265. Arguments:
  266. hKey - Handle to a currently open key or one of the following predefined reserved
  267. handle values:
  268. HKEY_CLASSES_ROOT
  269. HKEY_CURRENT_CONFIG
  270. HKEY_CURRENT_USER
  271. HKEY_LOCAL_MACHINE
  272. HKEY_USERS
  273. The key opened or created by the RegCreateKeyEx function is a subkey of the key
  274. identified by the hKey parameter.
  275. lpSubKey - Pointer to a null-terminated string specifying the name of a subkey
  276. that this function opens or creates. The subkey specified must be a subkey of the
  277. key identified by the hKey parameter. This subkey must not begin with the backslash
  278. character ('\'). This parameter cannot be NULL.
  279. Reserved -Reserved; must be zero.
  280. lpClass - Pointer to a null-terminated string that specifies the class (object type)
  281. of this key. This parameter is ignored if the key already exists. No classes are
  282. currently defined; applications should pass a null string.
  283. dwOptions - Specifies special options for the key. This parameter can be one of the
  284. following values.
  285. REG_OPTION_NON_VOLATILE This key is not volatile. This is the default. The
  286. information is stored in a file and is preserved when the system is restarted.
  287. REG_OPTION_VOLATILE
  288. REG_OPTION_BACKUP_RESTORE Windows NT/2000: If this flag is set, the function
  289. ignores the samDesired parameter and attempts to open the key with the access
  290. required to backup or restore the key. If the calling thread has the
  291. SE_BACKUP_NAME privilege enabled, the key is opened with
  292. ACCESS_SYSTEM_SECURITY and KEY_READ access. If the calling thread
  293. has the SE_RESTORE_NAME privilege enabled, the key is opened with
  294. ACCESS_SYSTEM_SECURITY and KEY_WRITE access.
  295. If both privileges are enabled, the key has the combined accesses
  296. for both privileges.
  297. samDesired - Specifies an access mask that specifies the desired security access
  298. for the new key. This parameter can be a combination of the following values:
  299. KEY_ALL_ACCESS Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS,
  300. KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK,
  301. and KEY_SET_VALUE access.
  302. KEY_CREATE_LINK Permission to create a symbolic link.
  303. KEY_CREATE_SUB_KEY Permission to create subkeys.
  304. KEY_ENUMERATE_SUB_KEYS Permission to enumerate subkeys.
  305. KEY_EXECUTE Permission for read access.
  306. KEY_NOTIFY Permission for change notification.
  307. KEY_QUERY_VALUE Permission to query subkey data.
  308. KEY_READ Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access.
  309. KEY_SET_VALUE Permission to set subkey data.
  310. KEY_WRITE Combination of KEY_SET_VALUE and KEY_CREATE_SUB_KEY access.
  311. Security access mask might also have WOW64_RES flag
  312. KEY_WOW64_32KEY this will open 32bit equivalent key disregarding
  313. the process.
  314. KEY_WOW64_64KEY this will open 64bit equivalent key disregarding the process.
  315. lpSecurityAttributes - Pointer to a SECURITY_ATTRIBUTES structure that determines
  316. whether the returned handle can be inherited by child processes. If
  317. lpSecurityAttributes is NULL, the handle cannot be inherited.
  318. phkResult - Pointer to a variable that receives a handle to the opened or
  319. created key. When you no longer need the returned handle, call the RegCloseKey
  320. function to close it.
  321. lpdwDisposition - Pointer to a variable that receives one of the following
  322. disposition values: Value Meaning REG_CREATED_NEW_KEY The key did not exist
  323. and was created. REG_OPENED_EXISTING_KEY The key existed and was simply
  324. opened without being changed. If lpdwDisposition is NULL, no disposition
  325. information is returned.
  326. Return Values:
  327. If the function succeeds, the return value is ERROR_SUCCESS.
  328. If the function fails, the return value is a nonzero error code defined in WINERROR.H.
  329. --*/
  330. {
  331. OBJECT_ATTRIBUTES Obja;
  332. UNICODE_STRING Parent;
  333. WCHAR ParentName[WOW64_MAX_PATH];
  334. WCHAR TempName[WOW64_MAX_PATH];
  335. DWORD dwBuffLen = WOW64_MAX_PATH;
  336. PWCHAR p32bitNode;
  337. PWCHAR pPatchLoc;
  338. PWCHAR pDivider;
  339. NTSTATUS st;
  340. BOOL bHandle64 = TRUE; // assume all the handle passed in is 64bit.
  341. //
  342. // check if the WOW64 reserve bit set. If none of them is set we can't proceede.
  343. //
  344. if (!(samDesired & KEY_WOW64_RES) ) {
  345. //
  346. // return ERROR_INVALID_PARAMETER; try to be optimistic
  347. //
  348. return RegCreateKeyEx (
  349. hKey, // handle to an open key
  350. lpSubKey, // address of subkey name
  351. Reserved, // reserved
  352. lpClass, // address of class string
  353. dwOptions, // special options flag
  354. samDesired, // desired security access
  355. lpSecurityAttributes,
  356. // address of key security structure
  357. phkResult, // address of buffer for opened handle
  358. lpdwDisposition // address of disposition value buffer
  359. );
  360. }
  361. if( hKey == NULL ) {
  362. return ERROR_INVALID_HANDLE;
  363. }
  364. //
  365. // makesure that subkey doesn't have the special wow string
  366. //
  367. if ( ( p32bitNode = wcsistr ((PWCHAR)lpSubKey, NODE_NAME_32BIT)) != NULL ) {
  368. //
  369. // if access 64bit hive compress the subkey, if 32bit hive just pass as it is.
  370. //
  371. if ( samDesired & KEY_WOW64_64KEY ) {
  372. wcscpy (ParentName, lpSubKey);
  373. p32bitNode = ParentName + ( p32bitNode- lpSubKey);
  374. wcscpy ( p32bitNode, p32bitNode + NODE_NAME_32BIT_LEN );
  375. }
  376. return RegCreateKeyEx (
  377. hKey, // handle to an open key
  378. lpSubKey, // address of subkey name
  379. Reserved, // reserved
  380. lpClass, // address of class string
  381. dwOptions, // special options flag
  382. samDesired & (~KEY_WOW64_RES), // desired security access
  383. lpSecurityAttributes,
  384. // address of key security structure
  385. phkResult, // address of buffer for opened handle
  386. lpdwDisposition // address of disposition value buffer
  387. );
  388. }
  389. //
  390. // Check predefined handle like HKEY_CLASSES_ROOT if so you only need to patch subkey
  391. //
  392. //
  393. // Client must pass meaningful handle to this function.
  394. //
  395. if ( hKey == HKEY_CLASSES_ROOT ) {
  396. wcscpy ( ParentName, MACHINE_CLASSES_ROOT);
  397. } else if ( !HandleToKeyName ( hKey, ParentName, &dwBuffLen ) ) {
  398. //
  399. // should we recoved from buffer overflow. We are not going to support all possible combination.
  400. //
  401. return ERROR_INVALID_HANDLE;
  402. }
  403. //
  404. // If parent has already been patched just call the RegOpenKeyEx for 32bit open
  405. //
  406. if ((p32bitNode = wcsistr (ParentName, NODE_NAME_32BIT)) != NULL ) {
  407. //
  408. // [todo] do you need to make sure that the substring mustbe the subkey
  409. // for an ISN node on 64bit registry to satisfy this condition.
  410. // if we assume that noy key will have this name then the checking is
  411. // good enough.
  412. //
  413. bHandle64 = FALSE; // it's not handle to 64 bit Key
  414. }
  415. //
  416. // Get complete qualified path to do sanity check.
  417. //
  418. pDivider = ParentName + wcslen(ParentName)+1; //point to the divider location
  419. *(pDivider-1)= L'\\';
  420. wcscpy (pDivider, (PWCHAR)lpSubKey);
  421. if (IsExemptRedirectedKey(ParentName, TempName)) {
  422. //
  423. // If the path is on the exempt list we access 64bit hive
  424. //
  425. samDesired = (samDesired & (~KEY_WOW64_RES)) | KEY_WOW64_64KEY; //make sure access 64bit hive
  426. }
  427. if ( ( bHandle64 && (samDesired & KEY_WOW64_64KEY ) ) // if totally 64
  428. || ( !bHandle64 && (samDesired & KEY_WOW64_32KEY ) ) // if totally 32
  429. || !IsIsnNode (ParentName, &pPatchLoc) ) { // if not a ISN node don't care
  430. return RegCreateKeyExW (
  431. hKey, // handle to an open key
  432. lpSubKey, // address of subkey name
  433. Reserved, // reserved
  434. lpClass, // address of class string
  435. dwOptions, // special options flag
  436. samDesired & (~KEY_WOW64_RES), // desired security access
  437. lpSecurityAttributes,
  438. // address of key security structure
  439. phkResult, // address of buffer for opened handle
  440. lpdwDisposition // address of disposition value buffer
  441. );
  442. }
  443. //
  444. // Now it might be mix mode access
  445. //
  446. if ( pPatchLoc >= pDivider ) {
  447. //
  448. // patching only the subkey will be good enough
  449. //
  450. if ( samDesired & KEY_WOW64_64KEY ) { // want to access 64bit just disregard
  451. wcscpy ( ParentName, lpSubKey );
  452. } else {
  453. GetPatchedName (ParentName,lpSubKey, (DWORD)(pPatchLoc-pDivider) );
  454. }
  455. return RegCreateKeyExW (
  456. hKey, // handle to an open key
  457. ParentName, // address of subkey name
  458. Reserved, // reserved
  459. lpClass, // address of class string
  460. dwOptions, // special options flag
  461. samDesired & (~KEY_WOW64_RES), // desired security access
  462. lpSecurityAttributes,
  463. // address of key security structure
  464. phkResult, // address of buffer for opened handle
  465. lpdwDisposition // address of disposition value buffer
  466. );
  467. } else {
  468. HKEY hNewParent = NULL;
  469. LONG Ret;
  470. PWCHAR pSubKey;
  471. //
  472. // get new handle on the parent and then create the child
  473. //
  474. if ( samDesired & KEY_WOW64_64KEY ) { // want to access 64bit just disregard
  475. if (p32bitNode != NULL) {//compress
  476. *(p32bitNode-1) = UNICODE_NULL;
  477. wcscpy ( p32bitNode, p32bitNode + NODE_NAME_32BIT_LEN +
  478. (p32bitNode[NODE_NAME_32BIT_LEN]==L'\\'? 1:0));
  479. }
  480. pSubKey = p32bitNode;
  481. RtlInitUnicodeString (&Parent, ParentName );
  482. } else {
  483. pSubKey = pPatchLoc;
  484. GetPatchedName (TempName,ParentName, (DWORD)(pPatchLoc-ParentName));
  485. TempName[pPatchLoc-ParentName+NODE_NAME_32BIT_LEN]=UNICODE_NULL; //repatch
  486. RtlInitUnicodeString (&Parent, TempName );
  487. }
  488. InitializeObjectAttributes (&Obja,
  489. &Parent,
  490. OBJ_CASE_INSENSITIVE,
  491. NULL,
  492. NULL
  493. );
  494. samDesired &= (~KEY_WOW64_RES);
  495. //
  496. // if key doesn't exist try to create
  497. // Try to avoid using NtOpenKey rather use RegOpenKey
  498. //
  499. st = NtOpenKey (&hNewParent,
  500. MAXIMUM_ALLOWED,
  501. &Obja);
  502. if ( !NT_SUCCESS(st))
  503. return RtlNtStatusToDosError (st);
  504. return RegCreateKeyExW (
  505. hNewParent, // handle to an open key
  506. pSubKey, // address of subkey name
  507. Reserved, // reserved
  508. lpClass, // address of class string
  509. dwOptions, // special options flag
  510. samDesired & (~KEY_WOW64_RES), // desired security access
  511. lpSecurityAttributes,
  512. // address of key security structure
  513. phkResult, // address of buffer for opened handle
  514. lpdwDisposition // address of disposition value buffer
  515. );
  516. NtClose (hNewParent);
  517. return 0;
  518. }
  519. }
  520. BOOL
  521. Wow64RegNotifyLoadHive (
  522. PWCHAR Name
  523. )
  524. /*++
  525. Routine Description:
  526. This function will Notify running Wow64 Service that some hive has been loaded in the
  527. system. Wow64 should respond if it care to handle this.
  528. Arguments:
  529. Name - Absolute path of the registry that has been loaded.
  530. Return Value:
  531. TRUE if everything under the has been deleted.
  532. FALSE otherwise.
  533. failure scenarion:
  534. Wow64 service isn't running.
  535. there is nothing the caller do, there for this will be a non blocking call.
  536. In the future caller should try to lunch the service...<TBD>
  537. --*/
  538. {
  539. DWORD Ret;
  540. HANDLE hEvent;
  541. if (!CreateSharedMemory ( OPEN_EXISTING_SHARED_RESOURCES )) {
  542. Wow64RegDbgPrint ( ("\nSorry! Couldn't open shared memory Ret:%d", GetLastError ()) );
  543. return FALSE;
  544. }
  545. if (!Wow64CreateEvent ( OPEN_EXISTING_SHARED_RESOURCES, &hEvent) ) {
  546. CloseSharedMemory ();
  547. Wow64RegDbgPrint ( ("\nSorry! couldn't open event to ping reflector..") );
  548. return FALSE;
  549. }
  550. Ret = EnQueueObject ( Name, HIVE_LOADING);
  551. CloseSharedMemory ();
  552. Wow64CloseEvent ();
  553. return Ret;
  554. }
  555. BOOL
  556. Wow64RegNotifyUnloadHive (
  557. PWCHAR Name
  558. )
  559. /*++
  560. Routine Description:
  561. This function will Notify running Wow64 Service that some hive going to be unloaded
  562. in the system. Wow64 should respond if it care to handle this. Normally Wow64 will
  563. close any open handle to that hive.
  564. Arguments:
  565. Name - Absolute path of the registry that going to unloaded.
  566. Return Value:
  567. TRUE if everything under the has been deleted.
  568. FALSE otherwise.
  569. failure scenarion:
  570. Wow64 service isn't running.
  571. there is nothing the caller do, there for this will be a non blocking call.
  572. In the future caller should try to lunch the service...<TBD>
  573. --*/
  574. {
  575. DWORD Ret;
  576. HANDLE hEvent;
  577. if (!CreateSharedMemory ( OPEN_EXISTING_SHARED_RESOURCES )) {
  578. Wow64RegDbgPrint ( ("\nSorry! Couldn't open shared memory Ret:%d", GetLastError ()));
  579. return FALSE;
  580. }
  581. if (!Wow64CreateEvent ( OPEN_EXISTING_SHARED_RESOURCES, &hEvent) ) {
  582. CloseSharedMemory ();
  583. Wow64RegDbgPrint ( ("\nSorry! couldn't open event to ping reflector..") );
  584. return FALSE;
  585. }
  586. Ret = EnQueueObject ( Name, HIVE_UNLOADING);
  587. CloseSharedMemory ();
  588. Wow64CloseEvent ();
  589. return Ret;
  590. }
  591. BOOL
  592. Wow64RegNotifyLoadHiveByHandle (
  593. HKEY hKey
  594. )
  595. /*++
  596. Routine Description:
  597. This function will Notify running Wow64 Service that some hive has been loaded in the
  598. system. Wow64 should respond if it care to handle this.
  599. Arguments:
  600. hKey - handle to the key that has been loaded.
  601. Return Value:
  602. TRUE if everything under the has been deleted.
  603. FALSE otherwise.
  604. failure scenarion:
  605. Wow64 service isn't running.
  606. there is nothing the caller do, there for this will be a non blocking call.
  607. In the future caller should try to lunch the service...<TBD>
  608. --*/
  609. {
  610. WCHAR Name [256];
  611. DWORD Len = 256;
  612. if (!HandleToKeyName ( hKey, Name, &Len ))
  613. return FALSE;
  614. return Wow64RegNotifyLoadHive( Name );
  615. }
  616. BOOL
  617. Wow64RegNotifyUnloadHiveByHandle (
  618. HKEY hKey
  619. )
  620. /*++
  621. Routine Description:
  622. This function will Notify running Wow64 Service that some hive going to be unloaded
  623. in the system. Wow64 should respond if it care to handle this. Normally Wow64 will
  624. close any open handle to that hive.
  625. Arguments:
  626. hKey - handle to the key that going to unloaded.
  627. Return Value:
  628. TRUE if everything under the has been deleted.
  629. FALSE otherwise.
  630. failure scenarion:
  631. Wow64 service isn't running.
  632. there is nothing the caller do, there for this will be a non blocking call.
  633. In the future caller should try to lunch the service...<TBD>
  634. --*/
  635. {
  636. WCHAR Name [256];
  637. DWORD Len = 256;
  638. if (!HandleToKeyName ( hKey, Name, &Len ))
  639. return FALSE;
  640. return Wow64RegNotifyUnloadHive( Name );
  641. }
  642. BOOL
  643. Wow64RegNotifyLoadHiveUserSid (
  644. PWCHAR lpwUserSid
  645. )
  646. /*++
  647. Routine Description:
  648. This function will Notify running Wow64 Service that some hive has been loaded in the
  649. system. Wow64 should respond if it care to handle this.
  650. Arguments:
  651. hKey - handle to the key that has been loaded.
  652. Return Value:
  653. TRUE if everything under the has been deleted.
  654. FALSE otherwise.
  655. failure scenarion:
  656. Wow64 service isn't running.
  657. there is nothing the caller do, there for this will be a non blocking call.
  658. In the future caller should try to lunch the service...<TBD>
  659. --*/
  660. {
  661. WCHAR Name [256];
  662. HKEY hUserRoot;
  663. wcscpy (Name, L"\\REGISTRY\\USER\\");
  664. wcscat (Name, lpwUserSid );
  665. if (wcsistr (Name, L"_Classes")) {
  666. wcscat (Name, L"\\Wow6432Node");
  667. hUserRoot = OpenNode (Name);
  668. //
  669. // DbgPrint ("\nWow64:Creating Hive %S",Name);
  670. //
  671. // Create the 32bit user hive if applicable
  672. //
  673. if ( hUserRoot == NULL ) {
  674. CreateNode (Name);
  675. } else
  676. NtClose (hUserRoot);
  677. }
  678. return TRUE;
  679. //return Wow64RegNotifyLoadHive( Name );
  680. }
  681. BOOL
  682. Wow64RegNotifyUnloadHiveUserSid (
  683. PWCHAR lpwUserSid
  684. )
  685. /*++
  686. Routine Description:
  687. This function will Notify running Wow64 Service that some hive going to be unloaded
  688. in the system. Wow64 should respond if it care to handle this. Normally Wow64 will
  689. close any open handle to that hive.
  690. Arguments:
  691. hKey - handle to the key that going to unloaded.
  692. Return Value:
  693. TRUE if everything under the has been deleted.
  694. FALSE otherwise.
  695. failure scenarion:
  696. Wow64 service isn't running.
  697. there is nothing the caller do, there for this will be a non blocking call.
  698. In the future caller should try to lunch the service...<TBD>
  699. --*/
  700. {
  701. WCHAR Name [256];
  702. wcscpy (Name, L"\\REGISTRY\\USER\\");
  703. wcscat (Name, lpwUserSid );
  704. //
  705. //return Wow64RegNotifyUnloadHive( Name );
  706. //
  707. return TRUE;
  708. }