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.

1027 lines
25 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. wowreg.c
  5. Abstract:
  6. This is the surragate process for registration of 32 dlls from a 64 bit process.
  7. And vice-versa.
  8. The parent process passes relevent IPC data on the cmdline, and the surragate
  9. process then coordinates the registration of this data with the parent process.
  10. Author:
  11. Andrew Ritz (andrewr) 3-Feb-2000
  12. Revision History:
  13. Andrew Ritz (andrewr) 3-Feb-2000 - Created It
  14. --*/
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. #include <windows.h>
  19. #include <shellapi.h>
  20. #include <tchar.h>
  21. #include <stdio.h>
  22. #include <setupapi.h>
  23. #include <spapip.h>
  24. #include <ole2.h>
  25. #include <rc_ids.h>
  26. #ifndef UNICODE
  27. #error UNICODE assumed
  28. #endif
  29. #ifndef _WIN64
  30. #include <wow64t.h>
  31. #endif
  32. #include "..\unicode\msg.h"
  33. #include "memory.h"
  34. #include "..\sputils\locking.h"
  35. #include "childreg.h"
  36. #include "cntxtlog.h"
  37. #define DLLINSTALL "DllInstall"
  38. #define DLLREGISTER "DllRegisterServer"
  39. #define DLLUNREGISTER "DllUnregisterServer"
  40. typedef struct _OLE_CONTROL_DATA {
  41. LPTSTR FullPath;
  42. UINT RegType;
  43. PVOID LogContext;
  44. BOOL Register; // or unregister
  45. LPCTSTR Argument;
  46. } OLE_CONTROL_DATA, *POLE_CONTROL_DATA;
  47. #if DBG
  48. VOID
  49. WowRegAssertFailed(
  50. IN PSTR FileName,
  51. IN UINT LineNumber,
  52. IN PSTR Condition
  53. )
  54. {
  55. int i;
  56. CHAR Name[MAX_PATH];
  57. PCHAR p;
  58. LPSTR Msg;
  59. DWORD MsgLen;
  60. DWORD GlobalSetupFlags = pSetupGetGlobalFlags();
  61. //
  62. // Use dll name as caption
  63. //
  64. GetModuleFileNameA(NULL,Name,MAX_PATH);
  65. if(p = strrchr(Name,'\\')) {
  66. p++;
  67. } else {
  68. p = Name;
  69. }
  70. MsgLen = strlen(p)+strlen(FileName)+strlen(Condition)+128;
  71. try {
  72. Msg = _alloca(MsgLen);
  73. wsprintfA(
  74. Msg,
  75. "Assertion failure at line %u in file %s!%s: %s%s",
  76. LineNumber,
  77. p,
  78. FileName,
  79. Condition,
  80. (GlobalSetupFlags & PSPGF_NONINTERACTIVE) ? "\r\n" : "\n\nCall DebugBreak()?"
  81. );
  82. OutputDebugStringA(Msg);
  83. if(GlobalSetupFlags & PSPGF_NONINTERACTIVE) {
  84. i = IDYES;
  85. } else {
  86. i = MessageBoxA(
  87. NULL,
  88. Msg,
  89. p,
  90. MB_YESNO | MB_TASKMODAL | MB_ICONSTOP | MB_SETFOREGROUND
  91. );
  92. }
  93. } except (EXCEPTION_EXECUTE_HANDLER) {
  94. OutputDebugStringA("WOWREG32 ASSERT!!!! (out of stack)\r\n");
  95. i=IDYES;
  96. }
  97. if(i == IDYES) {
  98. DebugBreak();
  99. }
  100. }
  101. #define MYASSERT(x) if(!(x)) { WowRegAssertFailed(__FILE__,__LINE__,#x); }
  102. #else
  103. #define MYASSERT(x)
  104. #endif
  105. VOID
  106. DebugPrintEx(
  107. DWORD Level,
  108. PCTSTR format,
  109. ... OPTIONAL
  110. )
  111. /*++
  112. Routine Description:
  113. Send a formatted string to the debugger.
  114. Arguments:
  115. format - standard printf format string.
  116. Return Value:
  117. NONE.
  118. --*/
  119. {
  120. TCHAR buf[1026]; // bigger than max size
  121. va_list arglist;
  122. va_start(arglist, format);
  123. wvsprintf(buf, format, arglist);
  124. DbgPrintEx(DPFLTR_SETUP_ID, Level, (PCH)"%ws",buf);
  125. }
  126. BOOL
  127. RegisterUnregisterControl(
  128. PWOW_IPC_REGION_TOSURRAGATE pControlDataFromRegion,
  129. PDWORD FailureCode);
  130. #define IDLE_TIMER 1000*60 // 60 seconds
  131. //
  132. // Keep statistics...
  133. //
  134. INT RegisteredControls = 0;
  135. PWSTR RegionName;
  136. PWSTR SignalReadyEvent;
  137. PWSTR SignalCompleteEvent;
  138. PWSTR ThisProgramName;
  139. #ifndef _WIN64
  140. BOOL Wow64 = FALSE;
  141. #endif
  142. BOOL
  143. ParseArgs(
  144. IN int argc,
  145. IN PWSTR *argv
  146. )
  147. {
  148. int i;
  149. ThisProgramName = argv[0];
  150. if(argc != 7) { // program name plus 3 required switches and their input
  151. return(FALSE);
  152. }
  153. for (i = 0; i < argc; i++) {
  154. if (0 == _wcsicmp(argv[i],SURRAGATE_REGIONNAME_SWITCH)) {
  155. RegionName = argv[i+1];
  156. }
  157. if (0 == _wcsicmp(argv[i],SURRAGATE_SIGNALREADY_SWITCH)) {
  158. SignalReadyEvent = argv[i+1];
  159. }
  160. if (0 == _wcsicmp(argv[i],SURRAGATE_SIGNALCOMPLETE_SWITCH)) {
  161. SignalCompleteEvent = argv[i+1];
  162. }
  163. }
  164. if (!SignalCompleteEvent || !SignalReadyEvent || !RegionName) {
  165. return(FALSE);
  166. }
  167. return(TRUE);
  168. }
  169. void
  170. Usage(
  171. VOID
  172. )
  173. {
  174. TCHAR Buffer[2048];
  175. if(LoadString(GetModuleHandle(NULL),IDS_WRONGUSE,Buffer,sizeof(Buffer)/sizeof(TCHAR))) {
  176. _ftprintf( stderr,TEXT("%s\n"),Buffer);
  177. }
  178. }
  179. int
  180. __cdecl
  181. main(
  182. IN int argc,
  183. IN char *argvA[]
  184. )
  185. {
  186. BOOL b;
  187. PWSTR *argv;
  188. HANDLE hReady = NULL;
  189. HANDLE hComplete = NULL;
  190. HANDLE hFileMap = NULL;
  191. PVOID Region = NULL;
  192. PWOW_IPC_REGION_TOSURRAGATE pInput;
  193. PWOW_IPC_REGION_FROMSURRAGATE pOutput;
  194. HANDLE hEvent[1];
  195. DWORD WaitResult, FailureCode;
  196. #ifndef _WIN64
  197. {
  198. ULONG_PTR ul = 0;
  199. NTSTATUS st;
  200. st = NtQueryInformationProcess(NtCurrentProcess(),
  201. ProcessWow64Information,
  202. &ul,
  203. sizeof(ul),
  204. NULL);
  205. if (NT_SUCCESS(st) && (0 != ul)) {
  206. // 32-bit code running on Win64
  207. Wow64 = TRUE;
  208. }
  209. }
  210. #endif
  211. //
  212. // Assume failure.
  213. //
  214. b = FALSE;
  215. argv = CommandLineToArgvW(GetCommandLine(), &argc);
  216. if (!argv) {
  217. //
  218. // out of memory ?
  219. //
  220. DebugPrintEx(
  221. DPFLTR_ERROR_LEVEL,
  222. L"WOWREG32: Low Memory\n");
  223. goto exit;
  224. }
  225. if(!ParseArgs(argc,argv)) {
  226. DebugPrintEx(
  227. DPFLTR_ERROR_LEVEL,
  228. L"WOWREG32: Invalid Usage\n");
  229. Usage();
  230. goto exit;
  231. }
  232. //
  233. // open the region and the named events
  234. //
  235. hFileMap = OpenFileMapping(
  236. FILE_MAP_READ| FILE_MAP_WRITE,
  237. FALSE,
  238. RegionName
  239. );
  240. if (!hFileMap) {
  241. DebugPrintEx(
  242. DPFLTR_ERROR_LEVEL,
  243. L"WOWREG32: OpenFileMapping (%s) failed, ec = %x\n", RegionName, GetLastError());
  244. goto exit;
  245. }
  246. Region = MapViewOfFile(
  247. hFileMap,
  248. FILE_MAP_READ | FILE_MAP_WRITE,
  249. 0,
  250. 0,
  251. 0
  252. );
  253. if (!Region) {
  254. DebugPrintEx(
  255. DPFLTR_ERROR_LEVEL,
  256. L"WOWREG32: MapViewOfFile failed, ec = %x\n", GetLastError());
  257. goto exit;
  258. }
  259. hReady = OpenEvent(EVENT_MODIFY_STATE | SYNCHRONIZE,FALSE, SignalReadyEvent);
  260. if (!hReady) {
  261. DebugPrintEx(
  262. DPFLTR_ERROR_LEVEL,
  263. L"WOWREG32: OpenEvent (%s) failed, ec = %x\n", SignalReadyEvent, GetLastError());
  264. goto exit;
  265. }
  266. hComplete = OpenEvent(EVENT_MODIFY_STATE | SYNCHRONIZE,FALSE, SignalCompleteEvent);
  267. if (!hComplete) {
  268. DebugPrintEx(
  269. DPFLTR_ERROR_LEVEL,
  270. L"WOWREG32: OpenEvent (%s) failed, ec = %x\n", SignalCompleteEvent, GetLastError());
  271. goto exit;
  272. }
  273. pInput = (PWOW_IPC_REGION_TOSURRAGATE) Region;
  274. pOutput = (PWOW_IPC_REGION_FROMSURRAGATE) Region;
  275. //
  276. // the process is now initialized. we now wait for either our event to be
  277. // signalled or for our idle timer to fire, in which case we will exit the
  278. // program
  279. //
  280. hEvent[0] = hReady;
  281. while (1) {
  282. do {
  283. WaitResult = MsgWaitForMultipleObjectsEx(
  284. 1,
  285. &hEvent[0],
  286. IDLE_TIMER,
  287. QS_ALLINPUT,
  288. MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
  289. if (WaitResult == WAIT_OBJECT_0 + 1) {
  290. MSG msg;
  291. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
  292. TranslateMessage(&msg);
  293. DispatchMessage(&msg);
  294. }
  295. }
  296. } while(WaitResult != WAIT_TIMEOUT &&
  297. WaitResult != WAIT_OBJECT_0 &&
  298. WaitResult != WAIT_FAILED);
  299. if (WaitResult == WAIT_TIMEOUT) {
  300. //
  301. // we hit the idle timer, so let the process unwind and go away now.
  302. //
  303. //
  304. // it doesn't matter too much, but make the return code "false" if the
  305. // process has gone away without ever registering any controls.
  306. //
  307. b = (RegisteredControls != 0);
  308. break;
  309. }
  310. MYASSERT(WaitResult == WAIT_OBJECT_0);
  311. //
  312. // reset our event so we only process each control one time
  313. //
  314. ResetEvent(hReady);
  315. //
  316. // register the control
  317. //
  318. b = RegisterUnregisterControl(pInput,&FailureCode);
  319. #ifdef PRERELEASE
  320. if (!b) {
  321. DebugPrintEx(
  322. DPFLTR_ERROR_LEVEL,
  323. L"First call to register control failed, trying again.\n"
  324. L"If you have a debugger attached to this process, it will"
  325. L" now call DebugBreak() so that you can debug this registration failure\n" );
  326. if (IsDebuggerPresent()) {
  327. DebugBreak();
  328. }
  329. b = RegisterUnregisterControl(pInput,&FailureCode);
  330. }
  331. #endif
  332. //
  333. // write an output status. Note that you cannot access pInput after
  334. // this point because pOutput and pInput are overloaded views of the
  335. // same memory region.
  336. //
  337. pOutput->Win32Error = b ? ERROR_SUCCESS : GetLastError();
  338. pOutput->FailureCode= b ? SPREG_SUCCESS : FailureCode;
  339. //
  340. // set an event to tell the parent process to read our status and give
  341. // us the next control to register.
  342. //
  343. SetEvent(hComplete);
  344. if (b) {
  345. RegisteredControls += 1;
  346. }
  347. }
  348. fprintf( stdout,"Registered %d controls\n", RegisteredControls );
  349. DebugPrintEx(
  350. DPFLTR_INFO_LEVEL,
  351. L"WOWREG32: registered %d controls\n", RegisteredControls);
  352. exit:
  353. if (Region) {
  354. UnmapViewOfFile( Region );
  355. }
  356. if (hFileMap) {
  357. CloseHandle(hFileMap);
  358. }
  359. if (hReady) {
  360. CloseHandle(hReady);
  361. }
  362. if (hComplete) {
  363. CloseHandle(hComplete);
  364. }
  365. return(b);
  366. }
  367. DWORD
  368. pSetupRegisterDllInstall(
  369. IN POLE_CONTROL_DATA OleControlData,
  370. IN HMODULE ControlDll,
  371. IN PDWORD ExtendedStatus
  372. )
  373. /*++
  374. Routine Description:
  375. call the "DllInstall" entrypoint for the specified dll
  376. Arguments:
  377. OleControlData - pointer to the OLE_CONTROL_DATA structure for the dll
  378. to be registered
  379. ControlDll - module handle to the dll to be registered
  380. ExtendedStatus - receives updated SPREG_* flag indicating outcome
  381. Return Value:
  382. Win32 error code indicating outcome.
  383. --*/
  384. {
  385. LPEXCEPTION_POINTERS ExceptionPointers = NULL;
  386. HRESULT (__stdcall *InstallRoutine) (BOOL bInstall, LPCTSTR pszCmdLine);
  387. HRESULT InstallStatus;
  388. DWORD d = NO_ERROR;
  389. //
  390. // parameter validation
  391. //
  392. if (!ControlDll) {
  393. *ExtendedStatus = SPREG_UNKNOWN;
  394. return ERROR_INVALID_PARAMETER;
  395. }
  396. //
  397. // get function pointer to "DllInstall" entrypoint
  398. //
  399. InstallRoutine = NULL; // shut up PreFast
  400. try {
  401. (FARPROC)InstallRoutine = GetProcAddress(
  402. ControlDll, DLLINSTALL );
  403. } except (
  404. ExceptionPointers = GetExceptionInformation(),
  405. EXCEPTION_EXECUTE_HANDLER) {
  406. }
  407. if(ExceptionPointers) {
  408. //
  409. // something went wrong...record an error
  410. //
  411. d = ExceptionPointers->ExceptionRecord->ExceptionCode;
  412. WriteLogEntry(
  413. OleControlData->LogContext,
  414. SETUP_LOG_ERROR,
  415. MSG_LOG_OLE_CONTROL_INTERNAL_EXCEPTION,
  416. NULL,
  417. OleControlData->FullPath
  418. );
  419. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: ...exception in GetProcAddress handled\n");
  420. *ExtendedStatus = SPREG_GETPROCADDR;
  421. } else if(InstallRoutine) {
  422. //
  423. // now call the function
  424. //
  425. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: installing...\n");
  426. *ExtendedStatus = SPREG_DLLINSTALL;
  427. try {
  428. InstallStatus = InstallRoutine(OleControlData->Register, OleControlData->Argument);
  429. if(FAILED(InstallStatus)) {
  430. d = InstallStatus;
  431. WriteLogEntry(
  432. OleControlData->LogContext,
  433. SETUP_LOG_ERROR|SETUP_LOG_BUFFER,
  434. MSG_LOG_OLE_CONTROL_API_FAILED,
  435. NULL,
  436. OleControlData->FullPath,
  437. TEXT(DLLINSTALL)
  438. );
  439. WriteLogError(OleControlData->LogContext,
  440. SETUP_LOG_ERROR,
  441. d);
  442. } else if(InstallStatus) {
  443. WriteLogEntry(OleControlData->LogContext,
  444. SETUP_LOG_WARNING,
  445. MSG_LOG_OLE_CONTROL_API_WARN,
  446. NULL,
  447. OleControlData->FullPath,
  448. TEXT(DLLINSTALL),
  449. InstallStatus
  450. );
  451. } else {
  452. WriteLogEntry(
  453. OleControlData->LogContext,
  454. SETUP_LOG_VERBOSE,
  455. MSG_LOG_OLE_CONTROL_API_OK,
  456. NULL,
  457. OleControlData->FullPath,
  458. TEXT(DLLINSTALL)
  459. );
  460. }
  461. } except (
  462. ExceptionPointers = GetExceptionInformation(),
  463. EXCEPTION_EXECUTE_HANDLER) {
  464. d = ExceptionPointers->ExceptionRecord->ExceptionCode;
  465. WriteLogEntry(
  466. OleControlData->LogContext,
  467. SETUP_LOG_ERROR,
  468. MSG_LOG_OLE_CONTROL_API_EXCEPTION,
  469. NULL,
  470. OleControlData->FullPath,
  471. TEXT(DLLINSTALL)
  472. );
  473. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: ...exception in DllInstall handled\n");
  474. }
  475. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: ...installed\n");
  476. } else {
  477. *ExtendedStatus = SPREG_GETPROCADDR;
  478. }
  479. return d;
  480. }
  481. DWORD
  482. pSetupRegisterDllRegister(
  483. IN POLE_CONTROL_DATA OleControlData,
  484. IN HMODULE ControlDll,
  485. IN PDWORD ExtendedStatus
  486. )
  487. /*++
  488. Routine Description:
  489. call the "DllRegisterServer" or "DllUnregisterServer" entrypoint for the
  490. specified dll
  491. Arguments:
  492. OleControlData - contains data about dll to be registered
  493. ControlDll - module handle to the dll to be registered
  494. ExtendedStatus - receives an extended status depending on the outcome of
  495. this operation
  496. Return Value:
  497. Win32 error code indicating outcome.
  498. --*/
  499. {
  500. LPEXCEPTION_POINTERS ExceptionPointers = NULL;
  501. HRESULT (__stdcall *RegisterRoutine) (VOID);
  502. HRESULT RegisterStatus;
  503. DWORD d = NO_ERROR;
  504. //
  505. // parameter validation
  506. //
  507. if (!ControlDll) {
  508. return ERROR_INVALID_PARAMETER;
  509. }
  510. //
  511. // get the function pointer to the actual routine we want to call
  512. //
  513. RegisterRoutine = NULL; // shut up preFast
  514. try {
  515. (FARPROC)RegisterRoutine = GetProcAddress(
  516. ControlDll, OleControlData->Register ? DLLREGISTER : DLLUNREGISTER);
  517. } except (
  518. ExceptionPointers = GetExceptionInformation(),
  519. EXCEPTION_EXECUTE_HANDLER) {
  520. }
  521. if(ExceptionPointers) {
  522. //
  523. // something went wrong, horribly wrong
  524. //
  525. d = ExceptionPointers->ExceptionRecord->ExceptionCode;
  526. WriteLogEntry(
  527. OleControlData->LogContext,
  528. SETUP_LOG_ERROR,
  529. MSG_LOG_OLE_CONTROL_INTERNAL_EXCEPTION,
  530. NULL,
  531. OleControlData->FullPath
  532. );
  533. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: ...exception in GetProcAddress handled\n");
  534. *ExtendedStatus = SPREG_GETPROCADDR;
  535. } else if(RegisterRoutine) {
  536. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: registering...\n");
  537. *ExtendedStatus = SPREG_REGSVR;
  538. try {
  539. RegisterStatus = RegisterRoutine();
  540. if(FAILED(RegisterStatus)) {
  541. d = RegisterStatus;
  542. WriteLogEntry(OleControlData->LogContext,
  543. SETUP_LOG_ERROR | SETUP_LOG_BUFFER,
  544. MSG_LOG_OLE_CONTROL_API_FAILED,
  545. NULL,
  546. OleControlData->FullPath,
  547. OleControlData->Register ? TEXT(DLLREGISTER) : TEXT(DLLUNREGISTER)
  548. );
  549. WriteLogError(OleControlData->LogContext,
  550. SETUP_LOG_ERROR,
  551. d);
  552. } else if(RegisterStatus) {
  553. WriteLogEntry(OleControlData->LogContext,
  554. SETUP_LOG_WARNING,
  555. MSG_LOG_OLE_CONTROL_API_WARN,
  556. NULL,
  557. OleControlData->FullPath,
  558. OleControlData->Register ? TEXT(DLLREGISTER) : TEXT(DLLUNREGISTER),
  559. RegisterStatus
  560. );
  561. } else {
  562. WriteLogEntry(OleControlData->LogContext,
  563. SETUP_LOG_VERBOSE,
  564. MSG_LOG_OLE_CONTROL_API_OK,
  565. NULL,
  566. OleControlData->FullPath,
  567. OleControlData->Register ? TEXT(DLLREGISTER) : TEXT(DLLUNREGISTER)
  568. );
  569. }
  570. } except (
  571. ExceptionPointers = GetExceptionInformation(),
  572. EXCEPTION_EXECUTE_HANDLER) {
  573. d = ExceptionPointers->ExceptionRecord->ExceptionCode;
  574. WriteLogEntry(
  575. OleControlData->LogContext,
  576. SETUP_LOG_ERROR,
  577. MSG_LOG_OLE_CONTROL_API_EXCEPTION,
  578. NULL,
  579. OleControlData->FullPath,
  580. OleControlData->Register ? TEXT(DLLREGISTER) : TEXT(DLLUNREGISTER)
  581. );
  582. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: ...exception in DllRegisterServer handled\n");
  583. }
  584. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: ...registered\n");
  585. } else {
  586. d = GetLastError();
  587. WriteLogEntry(OleControlData->LogContext,
  588. SETUP_LOG_ERROR | SETUP_LOG_BUFFER,
  589. MSG_LOG_OLE_CONTROL_NOT_REGISTERED_GETPROC_FAILED,
  590. NULL,
  591. OleControlData->FullPath,
  592. OleControlData->Register ? TEXT(DLLREGISTER) : TEXT(DLLUNREGISTER)
  593. );
  594. WriteLogError(OleControlData->LogContext,
  595. SETUP_LOG_ERROR,
  596. d);
  597. *ExtendedStatus = SPREG_GETPROCADDR;
  598. }
  599. return d;
  600. }
  601. DWORD
  602. pSetupRegisterLoadDll(
  603. IN POLE_CONTROL_DATA OleControlData,
  604. OUT HMODULE *ControlDll
  605. )
  606. /*++
  607. Routine Description:
  608. get the module handle to the specified dll
  609. Arguments:
  610. OleControlData - contains path to dll to be loaded
  611. ControlDll - module handle for the dll
  612. Return Value:
  613. Win32 error code indicating outcome.
  614. --*/
  615. {
  616. LPEXCEPTION_POINTERS ExceptionPointers = NULL;
  617. DWORD d = NO_ERROR;
  618. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: loading dll...\n");
  619. #ifndef _WIN64
  620. if(Wow64) {
  621. //
  622. // don't remap directory the directory that the caller provided
  623. //
  624. Wow64DisableFilesystemRedirector(OleControlData->FullPath);
  625. }
  626. #endif
  627. try {
  628. *ControlDll = LoadLibrary(OleControlData->FullPath);
  629. } except (
  630. ExceptionPointers = GetExceptionInformation(),
  631. EXCEPTION_EXECUTE_HANDLER) {
  632. }
  633. #ifndef _WIN64
  634. if(Wow64) {
  635. //
  636. // re-enable the redirection on this file
  637. //
  638. Wow64EnableFilesystemRedirector();
  639. }
  640. #endif
  641. if(ExceptionPointers) {
  642. WriteLogEntry(
  643. OleControlData->LogContext,
  644. SETUP_LOG_ERROR,
  645. MSG_LOG_OLE_CONTROL_LOADLIBRARY_EXCEPTION,
  646. NULL,
  647. OleControlData->FullPath
  648. );
  649. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: ...exception in LoadLibrary handled\n");
  650. d = ExceptionPointers->ExceptionRecord->ExceptionCode;
  651. } else if (!*ControlDll) {
  652. d = GetLastError();
  653. //
  654. // LoadLibrary failed.
  655. // File not found is not an error. We want to know about
  656. // other errors though.
  657. //
  658. d = GetLastError();
  659. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: ...dll not loaded (%u)\n",d);
  660. WriteLogEntry(
  661. OleControlData->LogContext,
  662. SETUP_LOG_ERROR|SETUP_LOG_BUFFER,
  663. MSG_LOG_OLE_CONTROL_LOADLIBRARY_FAILED,
  664. NULL,
  665. OleControlData->FullPath
  666. );
  667. WriteLogError(
  668. OleControlData->LogContext,
  669. SETUP_LOG_ERROR,
  670. d
  671. );
  672. } else {
  673. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: ...dll loaded\n");
  674. }
  675. return d;
  676. }
  677. BOOL
  678. RegisterUnregisterControl(
  679. PWOW_IPC_REGION_TOSURRAGATE RegistrationData,
  680. PDWORD FailureCode
  681. )
  682. /*++
  683. Routine Description:
  684. main registration routine for registering a dll.
  685. Arguments:
  686. RegistrationData - pointer to WOW_IPC_REGION_TOSURRAGATE structure indicating
  687. file to be processed
  688. FailureCode - SPREG_* code indicating outcome of operation.
  689. Return Value:
  690. Win32 error code indicating outcome.
  691. --*/
  692. {
  693. LPEXCEPTION_POINTERS ExceptionPointers = NULL;
  694. HMODULE ControlDll = NULL;
  695. PTSTR Extension;
  696. DWORD d = NO_ERROR;
  697. DWORD Count;
  698. OLE_CONTROL_DATA OleControlData;
  699. WCHAR Path[MAX_PATH];
  700. PWSTR p;
  701. //
  702. // could use CoInitializeEx as an optimization as OleInitialize is
  703. // probably overkill...but this is probably just a perf hit at
  704. // worst
  705. //
  706. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: calling OleInitialize\n");
  707. OleControlData.FullPath = RegistrationData->FullPath;
  708. OleControlData.Argument = RegistrationData->Argument;
  709. OleControlData.LogContext = NULL;
  710. OleControlData.Register = RegistrationData->Register;
  711. OleControlData.RegType = RegistrationData->RegType;
  712. wcscpy(Path,RegistrationData->FullPath);
  713. p = wcsrchr(Path,'\\');
  714. if (p) {
  715. *p = L'\0';
  716. }
  717. SetCurrentDirectory( Path );
  718. d = (DWORD)OleInitialize(NULL);
  719. if (d != NO_ERROR) {
  720. *FailureCode = SPREG_UNKNOWN;
  721. DebugPrintEx(DPFLTR_ERROR_LEVEL,L"WOWREG32: OleInitialize failed, ec = 0x%08x\n", d);
  722. goto clean0;
  723. }
  724. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: back from OleInitialize\n");
  725. try {
  726. //
  727. // protect everything in TRY-EXCEPT, we're calling unknown code (DLL's)
  728. //
  729. d = pSetupRegisterLoadDll( &OleControlData, &ControlDll );
  730. if (d == NO_ERROR) {
  731. //
  732. // We successfully loaded it. Now call the appropriate routines.
  733. //
  734. //
  735. // On register, do DLLREGISTER, then DLLINSTALL
  736. // On unregister, do DLLINSTALL, then DLLREGISTER
  737. //
  738. if (OleControlData.Register) {
  739. if (OleControlData.RegType & FLG_REGSVR_DLLREGISTER && (d == NO_ERROR) ) {
  740. d = pSetupRegisterDllRegister(
  741. &OleControlData,
  742. ControlDll,
  743. FailureCode );
  744. }
  745. if (OleControlData.RegType & FLG_REGSVR_DLLINSTALL && (d == NO_ERROR) ) {
  746. d = pSetupRegisterDllInstall(
  747. &OleControlData,
  748. ControlDll,
  749. FailureCode );
  750. }
  751. } else {
  752. if (OleControlData.RegType & FLG_REGSVR_DLLINSTALL && (d == NO_ERROR) ) {
  753. d = pSetupRegisterDllInstall(
  754. &OleControlData,
  755. ControlDll,
  756. FailureCode );
  757. }
  758. if (OleControlData.RegType & FLG_REGSVR_DLLREGISTER && (d == NO_ERROR) ) {
  759. d = pSetupRegisterDllRegister(
  760. &OleControlData,
  761. ControlDll,
  762. FailureCode );
  763. }
  764. }
  765. } else {
  766. ControlDll = NULL;
  767. *FailureCode = SPREG_LOADLIBRARY;
  768. }
  769. } except(EXCEPTION_EXECUTE_HANDLER) {
  770. //
  771. // If our exception was an AV, then use Win32 invalid param error, otherwise, assume it was
  772. // an inpage error dealing with a mapped-in file.
  773. //
  774. d = ERROR_INVALID_DATA;
  775. *FailureCode = SPREG_UNKNOWN;
  776. }
  777. if (ControlDll) {
  778. FreeLibrary(ControlDll);
  779. }
  780. OleUninitialize();
  781. DebugPrintEx(DPFLTR_TRACE_LEVEL,L"WOWREG32: back from OleUninitialize, exit RegisterUnregisterDll\n");
  782. clean0:
  783. if (d == NO_ERROR) {
  784. *FailureCode = SPREG_SUCCESS;
  785. }
  786. SetLastError(d);
  787. return (d == NO_ERROR);
  788. }