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.

1139 lines
28 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. reflectr.c
  5. Abstract:
  6. This module will register reflector thread and do necessary action while awake up.
  7. Author:
  8. ATM Shafiqul Khalid (askhalid) 16-Feb-2000
  9. Revision History:
  10. --*/
  11. #include <windows.h>
  12. #include <windef.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include "wow64reg.h"
  16. #include <assert.h>
  17. #include <shlwapi.h>
  18. #include "reflectr.h"
  19. REFLECTOR_EVENT eReflector[ISN_NODE_MAX_NUM];
  20. REFLECTR_STATUS ReflectrStatus = Stopped;
  21. HANDLE hRegistryEvent[ISN_NODE_MAX_NUM];
  22. HANDLE hReflector;
  23. DWORD TotalEventCount = 0;
  24. VOID
  25. DbgPrint(
  26. PCHAR FormatString,
  27. ...
  28. );
  29. REFLECTR_STATUS
  30. GetReflectorThreadStatus ()
  31. /*++
  32. Routine Description:
  33. Return current thread status;
  34. Arguments:
  35. None.
  36. Return Value:
  37. REFLECTR_STATUS
  38. --*/
  39. {
  40. return ReflectrStatus;
  41. }
  42. BOOL
  43. NotifyKeyChange (
  44. HKEY hKey,
  45. HANDLE hEvent
  46. )
  47. /*
  48. Routine Description:
  49. Register an event to be fired when something get changed on a key.
  50. Arguments:
  51. hKey - handle to a key that need to be watched.
  52. hEvent event that need to be triggered.
  53. Return Value:
  54. TRUE if the event registration succeed,
  55. FALSE otherwise.
  56. --*/
  57. {
  58. DWORD Ret;
  59. ResetEvent (hEvent);
  60. Ret = RegNotifyChangeKeyValue(
  61. hKey, // need to change to the ISN node
  62. TRUE, // Watch the whole sub-tree
  63. REG_NOTIFY_CHANGE_NAME |
  64. REG_NOTIFY_CHANGE_LAST_SET, // Don't watch for anything
  65. hEvent, // Event Handle
  66. TRUE // Async
  67. );
  68. if ( ERROR_SUCCESS != Ret)
  69. DbgPrint ("\nWow64.exe:Error!! Couldn't register events:%x on handle %x",hEvent, hKey);
  70. return Ret == ERROR_SUCCESS;
  71. }
  72. VOID
  73. RefreshWaitEventTable ()
  74. /*++
  75. Routine Description:
  76. Just copy all event object and we can wail for new event to trigger.
  77. Arguments:
  78. None.
  79. Return Value:
  80. None.
  81. --*/
  82. {
  83. DWORD k;
  84. for (k=0;k<TotalEventCount;k++)
  85. hRegistryEvent[k] = eReflector[k].hRegistryEvent;
  86. }
  87. BOOL
  88. CreateInsertEvent (
  89. PWCHAR Name,
  90. DWORD dwIndex
  91. )
  92. /*++
  93. Routine Description:
  94. Create an event for the key.
  95. Arguments:
  96. Name - Name of the key an event will be created to watch any changes.
  97. dwIndex - is the index to the reflector table. when event is fired up we need to tack the key.
  98. Return Value:
  99. TRUE on success,
  100. FALSE Otherwise
  101. --*/
  102. {
  103. if ( Name == UNICODE_NULL)
  104. return FALSE;
  105. if (wcsstr( Name, (LPCWSTR)L"\\REGISTRY\\USER\\*\\")) {
  106. if (RegOpenKey ( HKEY_CURRENT_USER,
  107. Name+sizeof ( L"\\REGISTRY\\USER\\*")/sizeof(WCHAR),
  108. &eReflector[TotalEventCount].hKey) != ERROR_SUCCESS) {
  109. Wow64RegDbgPrint (("\nSorry! couldn't open Key [%S]",
  110. Name+sizeof ( L"\\REGISTRY\\USER\\*")/sizeof(WCHAR) ) );
  111. return FALSE;
  112. }
  113. } else {
  114. eReflector[TotalEventCount].hKey = OpenNode (Name);
  115. if ( eReflector[TotalEventCount].hKey == NULL ) {
  116. Wow64RegDbgPrint (("\nSorry! couldn't open Key [%S] Len%d %d %d", Name, wcslen (Name), Name[0], UNICODE_NULL ));
  117. return FALSE;
  118. }
  119. }
  120. //
  121. // DO make sure that 32bit version exist on the hive...
  122. //
  123. {
  124. WCHAR TempName[256];
  125. GetMirrorName (Name, TempName);
  126. if ( wcscmp(Name,TempName ) )
  127. CreateNode ( TempName );
  128. // get all kind of name
  129. }
  130. eReflector[TotalEventCount].hRegistryEvent = CreateEvent(
  131. NULL, // Security Attributes
  132. TRUE, // Manual Reset
  133. FALSE, // Initial State
  134. NULL // Unnamed
  135. ) ;
  136. if ( !eReflector[TotalEventCount].hRegistryEvent) {
  137. Wow64RegDbgPrint (("\nUnable to create event"));
  138. RegCloseKey (eReflector[TotalEventCount].hKey);
  139. return FALSE;
  140. }
  141. eReflector[TotalEventCount].dwIndex = dwIndex;
  142. ResetEvent (eReflector[TotalEventCount].hRegistryEvent);
  143. if (!NotifyKeyChange (eReflector[TotalEventCount].hKey,
  144. eReflector[TotalEventCount].hRegistryEvent
  145. )) {
  146. Wow64RegDbgPrint ( ("\nSevere Error!!!! Couldn't hook to registry notify index:%d", TotalEventCount) );
  147. RegCloseKey (eReflector[TotalEventCount].hKey);
  148. CloseHandle (eReflector[TotalEventCount].hRegistryEvent);
  149. return FALSE; //set thread state
  150. }
  151. TotalEventCount++;
  152. return TRUE;
  153. }
  154. DWORD
  155. TotalRelflectorKey()
  156. /*++
  157. Routine Description:
  158. Return the total number of the key in the reflector Table.
  159. Arguments:
  160. None.
  161. Return Value:
  162. Number of entry in the reflector table.
  163. --*/
  164. {
  165. extern ISN_NODE_TYPE *ReflectorTable;
  166. DWORD i;
  167. for (i=0;;i++)
  168. if ( ReflectorTable[i].NodeValue[0] == UNICODE_NULL )
  169. return i;
  170. }
  171. VOID
  172. PrintTable ()
  173. /*++
  174. Routine Description:
  175. Dump the current content of the table, just for debugging purpose.
  176. Arguments:
  177. None.
  178. Return Value:
  179. None.
  180. --*/
  181. {
  182. extern ISN_NODE_TYPE *ReflectorTable;
  183. DWORD Size = TotalRelflectorKey();
  184. DWORD i;
  185. for ( i=0;i<Size;i++)
  186. Wow64RegDbgPrint ( ("\nTableElem [%d], %S", i, ReflectorTable[i].NodeValue));
  187. }
  188. BOOL
  189. RemoveKeyToWatch (
  190. PWCHAR Name
  191. )
  192. /*++
  193. Routine Description:
  194. Remove an entry in from the table to reflector thread need to watch.
  195. Arguments:
  196. Name - Name of the key to remove from the table.
  197. Return Value:
  198. TRUE on success,
  199. FALSE Otherwise
  200. --*/
  201. {
  202. DWORD i;
  203. DWORD k;
  204. extern ISN_NODE_TYPE *ReflectorTable;
  205. DWORD Size;
  206. for (i=1; i<TotalEventCount;i++)
  207. if (!_wcsicmp (Name, ReflectorTable[eReflector[i].dwIndex].NodeValue)) {//found match
  208. // move reflector table entry
  209. // fixup pointer in the ereflectortable
  210. Size = TotalRelflectorKey ();
  211. wcscpy ( ReflectorTable[eReflector[i].dwIndex].NodeValue,
  212. ReflectorTable[Size-1].NodeValue
  213. );
  214. Size--;
  215. ReflectorTable[Size].NodeValue[0]=UNICODE_NULL; //invalidate the place
  216. for (k=1; k<TotalEventCount;k++)
  217. if ( eReflector[k].dwIndex == Size ) {
  218. eReflector[k].dwIndex = eReflector[i].dwIndex; //new location
  219. break;
  220. }
  221. // fixup the table with the new entry
  222. {
  223. REFLECTOR_EVENT Temp = eReflector[i];
  224. eReflector[i] = eReflector[TotalEventCount-1];
  225. eReflector[TotalEventCount-1] = Temp;;
  226. }
  227. TotalEventCount--;
  228. CloseHandle (eReflector[TotalEventCount].hRegistryEvent );
  229. RegCloseKey ( eReflector[TotalEventCount].hKey);
  230. eReflector[TotalEventCount].dwIndex = -1;
  231. //Now remove from the original table
  232. PrintTable();
  233. return TRUE;
  234. }
  235. return FALSE;
  236. }
  237. BOOL
  238. AddKeyToWatch (
  239. PWCHAR Name
  240. )
  241. /*++
  242. Routine Description:
  243. Add an entry in the table to reflector thread need to watch.
  244. Arguments:
  245. Name - Name of the key to watch.
  246. Return Value:
  247. TRUE on success,
  248. FALSE Otherwise
  249. --*/
  250. {
  251. //
  252. // Check for duplicate entry
  253. //
  254. DWORD i;
  255. DWORD k;
  256. extern ISN_NODE_TYPE *ReflectorTable;
  257. DWORD Size;
  258. for (i=1; i<TotalEventCount;i++)
  259. if (!_wcsicmp (Name, ReflectorTable[eReflector[i].dwIndex].NodeValue)) {//found match
  260. return FALSE; //already there
  261. }
  262. Size = TotalRelflectorKey ();
  263. wcscpy ( ReflectorTable[Size].NodeValue, Name );
  264. ReflectorTable[Size+1].NodeValue[0]=UNICODE_NULL; //invalidate the place
  265. if (!CreateInsertEvent ( Name, Size ))
  266. ReflectorTable[Size].NodeValue[0]=UNICODE_NULL; //no point of keeping the bad entry
  267. return TRUE;
  268. }
  269. BOOL
  270. ValidateOpenHandleEventTable (
  271. DWORD dwIndex
  272. )
  273. /*++
  274. Routine Description:
  275. Validate a given node and if something wrong kick out the entry from the
  276. event table.
  277. Arguments:
  278. dwIndex - entry that need to be checked
  279. Return Value:
  280. TRUE if function succeed.
  281. FALSE otherwise.
  282. --*/
  283. {
  284. extern ISN_NODE_TYPE *ReflectorTable;
  285. //
  286. // current implementation will just remove the entry from the table
  287. //
  288. return RemoveKeyToWatch (ReflectorTable[eReflector[dwIndex].dwIndex].NodeValue);
  289. }
  290. VOID
  291. PeocessHiveLoadUnload ()
  292. /*++
  293. Routine Description:
  294. Take necessary action when a hive has been unloaded.
  295. Arguments:
  296. None.
  297. Return Value:
  298. None.
  299. --*/
  300. {
  301. DWORD i;
  302. WCHAR Name[257];
  303. WCHAR Type;
  304. for (;;) {
  305. if (!DeQueueObject ( Name, &Type ))
  306. break;
  307. if ( Type == HIVE_UNLOADING ) { //Closing hive
  308. RemoveKeyToWatch (Name);
  309. } else if ( Type == HIVE_LOADING) { //opening hive
  310. AddKeyToWatch (Name);
  311. }
  312. Wow64RegDbgPrint ( ("\nFired up from shared memory write.....Value..%S [%C]", Name, Type) );
  313. }
  314. }
  315. ULONG
  316. ReflectorFn (
  317. PVOID *pTemp
  318. )
  319. /*++
  320. Routine Description:
  321. Main reflector thread.
  322. Arguments:
  323. pTemp -
  324. Return Value:
  325. return exit code.
  326. --*/
  327. {
  328. DWORD Ret, k;
  329. DWORD LocalWaitTime;
  330. pTemp=NULL;
  331. for (k=0;k<TotalEventCount;k++)
  332. hRegistryEvent[k] = eReflector[k].hRegistryEvent;
  333. for (k=0;k<TotalEventCount;k++) { //reset everything and wait for a fresh event
  334. if (eReflector[k].hRegistryEvent)
  335. NotifyKeyChange ( eReflector[k].hKey, eReflector[k].hRegistryEvent);
  336. }
  337. for (;;) {
  338. if ( ReflectrStatus == PrepareToStop ) {
  339. Wow64RegDbgPrint ( ("\nGoing to stop"));
  340. ReflectrStatus = Stopped;
  341. break; // the thread should stop
  342. }
  343. Wow64RegDbgPrint ( ("\nReflector thread has been started and will wait for event\n.......") );
  344. Sleep (1000*10); //wait 10 sec before reregistering events
  345. LocalWaitTime = WAIT_INTERVAL; //wait infinite
  346. for (;;) {
  347. //DbgPrint ("\nwow64.exe Waiting to liten...");
  348. Ret = WaitForMultipleObjects(TotalEventCount, hRegistryEvent, FALSE, LocalWaitTime );
  349. if (ReflectrStatus == PrepareToStop) {
  350. ReflectrStatus = Stopped;
  351. Wow64RegDbgPrint ( ("\nGoing to stop"));
  352. break; // the thread should stop
  353. }
  354. if ( Ret == WAIT_TIMEOUT )
  355. break; // break the loop and process all dirty hives.
  356. if ( ( Ret-WAIT_OBJECT_0) > TotalEventCount ) { //right index
  357. Wow64RegDbgPrint ( ("\nWaitMultiple object failed!!.. %d LastError:%d", Ret, GetLastError ()) );
  358. Sleep (1000*10); //wait 10 sec before reregistering events
  359. continue;
  360. //break;
  361. }
  362. //
  363. // Checkspecial case like shared memory write
  364. //
  365. if ( (Ret-WAIT_OBJECT_0) == 0){
  366. PeocessHiveLoadUnload ();
  367. ResetEvent (eReflector[0].hRegistryEvent); // reset the event that triggered this
  368. RefreshWaitEventTable ();
  369. continue;
  370. }
  371. //
  372. // set timeout to 10 second, Mark the hive dirty, reset event, and back to sleep
  373. //
  374. LocalWaitTime = 5*1000; // poll the event every 5 second.
  375. Sleep (1000* 3);// Sleep 3 second to reregister the event.
  376. eReflector[Ret-WAIT_OBJECT_0].bDirty = TRUE;
  377. ResetEvent (eReflector[Ret-WAIT_OBJECT_0].hRegistryEvent);
  378. //
  379. // watch for the event again
  380. //
  381. if (!NotifyKeyChange ( eReflector[Ret-WAIT_OBJECT_0].hKey,
  382. eReflector[Ret-WAIT_OBJECT_0].hRegistryEvent)){
  383. //
  384. // if the node get deleted you need to unload the events and everything
  385. //
  386. ValidateOpenHandleEventTable (Ret-WAIT_OBJECT_0);
  387. RefreshWaitEventTable ();
  388. //ReflectrStatus = Abnormal;
  389. //break; //set thread state
  390. }
  391. }
  392. if (ReflectrStatus == PrepareToStop)
  393. break;
  394. //
  395. // Now process all dirty hive.
  396. //
  397. for (k=0;k<TotalEventCount;k++)
  398. if ( eReflector[k].bDirty ) {
  399. CreateIsnNodeSingle( eReflector[k].dwIndex); // reflect changes
  400. eReflector[k].bDirty = FALSE;
  401. //ResetEvent (eReflector[k].hRegistryEvent);
  402. }
  403. } //for loop
  404. Wow64RegDbgPrint ( ("\nReflector thread terminated...."));
  405. return TRUE;
  406. }
  407. BOOL
  408. RegisterReflector()
  409. /*++
  410. Routine Description:
  411. Register the reflector thread after doing necessary initialization.
  412. Arguments:
  413. None.
  414. Return Value:
  415. TRUE if it can launch the reflector thread properly.
  416. FALSE otherwise.
  417. --*/
  418. {
  419. DWORD i;
  420. DWORD Size;
  421. extern ISN_NODE_TYPE *ReflectorTable;
  422. if ( ReflectrStatus == Running )
  423. return TRUE; // already running
  424. if ( ReflectrStatus != Dead )
  425. return FALSE; // last state was invalid I can do nothing
  426. InitializeIsnTableReflector (); //initialize the table with the more list in the registry.
  427. hReflector = NULL;
  428. if (!TotalEventCount)
  429. Wow64RegDbgPrint (("\nSorry! total event count for reflector is zero %d", TotalEventCount));
  430. //
  431. // Now time to create event and sync object for the shared resources
  432. //
  433. for (i=0;i<ISN_NODE_MAX_NUM;i++) {
  434. eReflector[i].hRegistryEvent = NULL;
  435. eReflector[i].hKey = NULL;
  436. eReflector[i].dwIndex = -1;
  437. eReflector[i].bDirty = FALSE; // not dirty so that we need to refresh.
  438. }
  439. if (!CreateSharedMemory ( 0 ))
  440. Wow64RegDbgPrint (("\nSorry Couldn't create/open shared memory Ret:%x", GetLastError ())); //default creation
  441. if (!Wow64CreateEvent ( 0, &eReflector[TotalEventCount].hRegistryEvent ))
  442. Wow64RegDbgPrint ( ("\nSorry Couldn't create events, reflector can listen to others"));
  443. else {
  444. eReflector[TotalEventCount].dwIndex = -1;
  445. TotalEventCount++;
  446. }
  447. Size = TotalRelflectorKey ();
  448. for ( i=0;i<Size;i++) {
  449. //
  450. // Open The Key
  451. //
  452. //
  453. // special case current user
  454. //
  455. CreateInsertEvent ( ReflectorTable[i].NodeValue, i );
  456. }
  457. //
  458. // Now Create a thread to watch the event.
  459. //
  460. hReflector = CreateThread(
  461. NULL, // pointer to security attributes
  462. 0, // initial thread stack size
  463. ReflectorFn, // pointer to thread function
  464. 0, // argument for new thread
  465. 0, // creation flags
  466. NULL // pointer to receive thread ID
  467. );
  468. if ( !hReflector ) {
  469. Wow64RegDbgPrint ( ("\nCouldn't create reflector thread"));
  470. return FALSE;
  471. }
  472. ReflectrStatus = Running;
  473. return TRUE;
  474. }
  475. BOOL
  476. UnRegisterReflector()
  477. /*++
  478. Routine Description:
  479. Unregister reflector thread and cleanup resources used by the reflector thread.
  480. Arguments:
  481. None.
  482. Return Value:
  483. TRUE if the function succeed.
  484. FALSE otherwise.
  485. --*/
  486. {
  487. DWORD i;
  488. DWORD k;
  489. ReflectrStatus = PrepareToStop;
  490. //
  491. // try to signal event in case the thread is wating
  492. //
  493. for (k=0;k<TotalEventCount;k++) { //reset everything and wait for a fresh event
  494. if (eReflector[k].hRegistryEvent)
  495. SetEvent (eReflector[k].hRegistryEvent);
  496. }
  497. //
  498. // Allow reflector thread little bit time to stop.
  499. //
  500. i=0;
  501. while ( ReflectrStatus != Stopped ) {
  502. Sleep(1000);
  503. if ( ReflectrStatus != Running )
  504. break; // why you should wait idle thread or that might be in a abnormal state.
  505. i++;
  506. if (i>60*5)
  507. break; // 5min timeout going to stop anyway.
  508. }
  509. for (i=1;i<TotalEventCount;i++) { // skip the initial event for shared memory
  510. CloseHandle (eReflector[i].hRegistryEvent);
  511. eReflector[i].hRegistryEvent = NULL;
  512. RegCloseKey ( eReflector[i].hKey );
  513. eReflector[i].hKey = NULL;
  514. }
  515. if ( hReflector ) {
  516. CloseHandle (hReflector); //make sure abnormal thread termination doesn't cause any corruption
  517. hReflector = NULL;
  518. }
  519. ReflectrStatus = Dead;
  520. //
  521. // release shared resources
  522. //
  523. CloseSharedMemory ();
  524. Wow64CloseEvent ();
  525. return TRUE;
  526. }
  527. BOOL
  528. InitReflector ()
  529. /*++
  530. Routine Description:
  531. Initialize resources associated with a reflector thread.
  532. Arguments:
  533. None.
  534. Return Value:
  535. TRUE if the function succeed.
  536. FALSE otherwise.
  537. --*/
  538. {
  539. DWORD k;
  540. ReflectrStatus = Dead;
  541. hReflector = NULL;
  542. for (k=0;k<ISN_NODE_MAX_NUM;k++) { //reset everything and wait for a fresh event
  543. eReflector[k].hRegistryEvent = NULL;
  544. eReflector[k].hKey = NULL;
  545. eReflector[k].bDirty = FALSE; // not dirty so that we need to refresh.
  546. }
  547. return TRUE;
  548. }
  549. LONG
  550. RegReflectKey (
  551. HKEY hKey, // handle to open key
  552. LPCTSTR lpSubKey, // subkey name
  553. DWORD dwOption // option flag
  554. )
  555. /*++
  556. Routine Description:
  557. Synchronize registry hive from a given point.
  558. Arguments:
  559. hKey - handle to an open key. Can be predefined handle or NULL to sync all.
  560. lpSubKey - Name of the subkey. This can be NULL.
  561. dwOption - set to zero. for future uses.
  562. Return Value:
  563. ERROR_SUCCESS on success,
  564. WIN32 error otherwise.
  565. --*/
  566. {
  567. HKEY hDest;
  568. WCHAR Path[_MAX_PATH];
  569. DWORD Len = _MAX_PATH;
  570. WCHAR DestNode[_MAX_PATH];
  571. BOOL b64bitSide=TRUE;
  572. BOOL Ret = TRUE;
  573. DestNode[0] = UNICODE_NULL;
  574. //
  575. // present implementation will start from the very top level
  576. //
  577. //
  578. // should interact with the running service, stop the thread, run the reflector and then try again.
  579. //
  580. if (hKey != NULL || dwOption!=0 ) {
  581. Wow64RegDbgPrint (("\nCurrent implementation only take all zero parameters. "));
  582. }
  583. if (!InitializeIsnTable ())
  584. return -1;
  585. if (!InitializeIsnTableReflector ())
  586. return -1;
  587. if (!HandleToKeyName ( hKey, Path, &Len ))
  588. return -1;
  589. //
  590. // Make the complete path
  591. //
  592. if ( lpSubKey != NULL )
  593. if (lpSubKey[0] != UNICODE_NULL ) {
  594. wcscat (Path, L"\\");
  595. wcscat (Path, lpSubKey );
  596. }
  597. //
  598. // MakeSure destination exists
  599. //
  600. //
  601. // must check the value if that exist
  602. //
  603. if ( Is64bitNode ( Path )) {
  604. Map64bitTo32bitKeyName ( Path, DestNode );
  605. } else {
  606. b64bitSide = FALSE;
  607. Map32bitTo64bitKeyName ( Path, DestNode );
  608. }
  609. hDest = OpenNode (DestNode);
  610. if (hDest != NULL)
  611. RegCloseKey ( hDest);
  612. else {
  613. if ( !CreateNode (DestNode))
  614. return -1;
  615. }
  616. SyncNode (Path);
  617. return ERROR_SUCCESS;
  618. }
  619. BOOL
  620. SetWow64InitialRegistryLayout ()
  621. /*++
  622. Routine Description:
  623. This routine does some initial setup for the registry for wow64.
  624. Arguments:
  625. None.
  626. Return Value:
  627. TRUE if the function succeed.
  628. FALSE otherwise.
  629. --*/
  630. {
  631. DWORD Ret;
  632. HKEY Key;
  633. //HKEY Key1;
  634. //
  635. // Create symbolic link {HKLM\software\Wow6432Node\Classes to HKLM\software\classes\wow6432Node}
  636. //
  637. InitializeWow64OnBoot (1);
  638. return TRUE;
  639. Ret = RegCreateKeyEx(
  640. HKEY_LOCAL_MACHINE, // handle to an open key
  641. L"SOFTWARE\\Classes\\Wow6432Node", // address of subkey name
  642. 0, // reserved
  643. NULL, // address of class string
  644. REG_OPTION_NON_VOLATILE, // special options flag
  645. KEY_ALL_ACCESS, // desired security access
  646. NULL, // address of key security structure
  647. &Key, // address of buffer for opened handle
  648. NULL // address of disposition value buffer
  649. );
  650. if ( Ret != ERROR_SUCCESS ) {
  651. Wow64RegDbgPrint ( ("\nSorry! I couldn't create the key SOFTWARE\\Classes\\Wow6432Node") );
  652. return FALSE;
  653. }
  654. RegCloseKey ( Key );
  655. Ret = RegCreateKeyEx(
  656. HKEY_LOCAL_MACHINE, // handle to an open key
  657. L"SOFTWARE\\Wow6432Node", // address of subkey name
  658. 0, // reserved
  659. NULL, // address of class string
  660. REG_OPTION_NON_VOLATILE , // special options flag
  661. KEY_ALL_ACCESS, // desired security access
  662. NULL, // address of key security structure
  663. &Key, // address of buffer for opened handle
  664. NULL // address of disposition value buffer
  665. );
  666. if (Ret != ERROR_SUCCESS ) {
  667. Wow64RegDbgPrint ( ("\nSorry! couldn't create/open SOFTWARE\\Wow6432Node") );
  668. return FALSE;
  669. } else {
  670. //
  671. // Delete the Key if exist
  672. //
  673. Ret = RegDeleteKey ( Key, L"Classes");
  674. RegCloseKey (Key);
  675. }
  676. if (Ret == ERROR_SUCCESS )
  677. Ret = RegCreateKeyEx(
  678. HKEY_LOCAL_MACHINE, // handle to an open key
  679. L"SOFTWARE\\Wow6432Node\\Classes", // address of subkey name
  680. 0, // reserved
  681. NULL, // address of class string
  682. REG_OPTION_NON_VOLATILE | REG_OPTION_OPEN_LINK | REG_OPTION_CREATE_LINK, // special options flag
  683. KEY_ALL_ACCESS | KEY_CREATE_LINK, // desired security access
  684. NULL, // address of key security structure
  685. &Key, // address of buffer for opened handle
  686. NULL // address of disposition value buffer
  687. );
  688. if(Ret == ERROR_SUCCESS) {
  689. Ret = RegSetValueEx(
  690. Key,
  691. L"SymbolicLinkValue",
  692. 0,
  693. REG_LINK,
  694. (PBYTE)WOW64_32BIT_MACHINE_CLASSES_ROOT,
  695. (DWORD ) (wcslen (WOW64_32BIT_MACHINE_CLASSES_ROOT) * sizeof (WCHAR))
  696. );
  697. RegCloseKey(Key);
  698. if ( Ret != ERROR_SUCCESS ) {
  699. Wow64RegDbgPrint ( ("\nSorry! I couldn't create symbolic link to %S", WOW64_32BIT_MACHINE_CLASSES_ROOT));
  700. return FALSE;
  701. }
  702. }else {
  703. Wow64RegDbgPrint ( ("\nWarning!! SOFTWARE\\Wow6432Node\\Classes might be already there\n") );
  704. return FALSE;
  705. }
  706. return TRUE;
  707. }
  708. BOOL
  709. PopulateReflectorTable ()
  710. /*++
  711. Routine Description:
  712. Populate the initial redirector table
  713. Arguments:
  714. None.
  715. Return Value:
  716. TRUE if the function succeed.
  717. FALSE otherwise.
  718. --*/
  719. {
  720. extern ISN_NODE_TYPE *ReflectorTable;
  721. extern ISN_NODE_TYPE *RedirectorTable;
  722. HKEY Key;
  723. LONG Ret;
  724. DWORD dwIndex=0;
  725. //
  726. // delete the entry first
  727. //
  728. SetWow64InitialRegistryLayout ();
  729. Ret = RegCreateKeyEx(
  730. HKEY_LOCAL_MACHINE, // handle to an open key
  731. (LPCWSTR ) WOW64_REGISTRY_SETUP_KEY_NAME_REL, // address of subkey name
  732. 0, // reserved
  733. NULL, // address of class string
  734. REG_OPTION_NON_VOLATILE, // special options flag
  735. KEY_ALL_ACCESS, // desired security access
  736. NULL, // address of key security structure
  737. &Key, // address of buffer for opened handle
  738. NULL // address of disposition value buffer
  739. );
  740. if (Ret != ERROR_SUCCESS ) {
  741. Wow64RegDbgPrint ( ("\nSorry!! couldn't open/create key list at %S", WOW64_REGISTRY_SETUP_REFLECTOR_KEY) );
  742. return FALSE;
  743. }
  744. //
  745. // Now Key point to the right location
  746. //
  747. for ( dwIndex=0;wcslen (RedirectorTable[dwIndex].NodeValue);dwIndex++) {
  748. if (RedirectorTable[dwIndex].Flag==0) { // write the node in the registry
  749. Ret = RegSetValueEx(
  750. Key,
  751. RedirectorTable[dwIndex].NodeName,
  752. 0,
  753. REG_SZ,
  754. (PBYTE)&RedirectorTable[dwIndex].NodeValue[0],
  755. (ULONG)(wcslen (RedirectorTable[dwIndex].NodeValue)+sizeof(UNICODE_NULL))*sizeof(WCHAR)
  756. );
  757. if ( Ret != ERROR_SUCCESS ) {
  758. Wow64RegDbgPrint ( ("\nSorry! couldn't write the key"));
  759. RegCloseKey (Key);
  760. return FALSE;
  761. }
  762. }
  763. }
  764. RegCloseKey (Key);
  765. //
  766. // populate list for reflector
  767. //
  768. Ret = RegCreateKeyEx(
  769. HKEY_LOCAL_MACHINE, // handle to an open key
  770. (LPCWSTR ) WOW64_REGISTRY_SETUP_REFLECTOR_KEY, // address of subkey name
  771. 0, // reserved
  772. NULL, // address of class string
  773. REG_OPTION_NON_VOLATILE, // special options flag
  774. KEY_ALL_ACCESS, // desired security access
  775. NULL, // address of key security structure
  776. &Key, // address of buffer for opened handle
  777. NULL // address of disposition value buffer
  778. );
  779. if (Ret != ERROR_SUCCESS ) {
  780. Wow64RegDbgPrint ( ("\nSorry!! couldn't open/create key list at %S", WOW64_REGISTRY_SETUP_REFLECTOR_KEY));
  781. return FALSE;
  782. }
  783. //
  784. // Now Key point to the right location
  785. //
  786. for ( dwIndex=0;wcslen (ReflectorTable[dwIndex].NodeValue);dwIndex++) {
  787. if (ReflectorTable[dwIndex].Flag==0) { // write the node in the registry
  788. Ret = RegSetValueEx(
  789. Key,
  790. ReflectorTable[dwIndex].NodeName,
  791. 0,
  792. REG_SZ,
  793. (PBYTE)&ReflectorTable[dwIndex].NodeValue[0],
  794. (ULONG)(wcslen (ReflectorTable[dwIndex].NodeValue)+sizeof(UNICODE_NULL))*sizeof(WCHAR)
  795. );
  796. if ( Ret != ERROR_SUCCESS ) {
  797. Wow64RegDbgPrint ( ("\nSorry! couldn't write the key"));
  798. RegCloseKey (Key);
  799. return FALSE;
  800. }
  801. }
  802. }
  803. RegCloseKey (Key);
  804. return TRUE;
  805. }