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.

810 lines
17 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. sources
  5. Abstract:
  6. main file for the wow64svc
  7. Author:
  8. ATM Shafiqul Khalid (askhalid) 3-March-2000
  9. Revision History:
  10. --*/
  11. #include "Wow64svc.h"
  12. BOOL
  13. SetWow64InitialRegistryLayout ();
  14. SERVICE_STATUS Wow64ServiceStatus;
  15. SERVICE_STATUS_HANDLE Wow64ServiceStatusHandle;
  16. BOOL ServiceDebug;
  17. HANDLE Wow64SvcHeapHandle;
  18. SERVICE_TABLE_ENTRY ServiceDispatchTable[] = {
  19. { WOW64_SERVICE_NAME, Wow64ServiceMain },
  20. { NULL, NULL }
  21. };
  22. LPTSTR NextParam (
  23. LPTSTR lpStr
  24. )
  25. /*++
  26. Routine Description
  27. Point to the next parameter in the commandline.
  28. Arguments:
  29. lpStr - pointer to the current command line
  30. Return Value:
  31. TRUE if the function succeed, FALSE otherwise.
  32. --*/
  33. {
  34. WCHAR ch = L' ';
  35. if (lpStr == NULL )
  36. return NULL;
  37. if ( *lpStr == 0 )
  38. return lpStr;
  39. while ( ( *lpStr != 0 ) && ( lpStr[0] != ch )) {
  40. if ( ( lpStr [0] == L'\"') || ( lpStr [0] == L'\'') )
  41. ch = lpStr [0];
  42. lpStr++;
  43. }
  44. if ( ch !=L' ' ) lpStr++;
  45. while ( ( *lpStr != 0 ) && (lpStr[0] == L' ') )
  46. lpStr++;
  47. return lpStr;
  48. }
  49. DWORD CopyParam (
  50. LPTSTR lpDestParam,
  51. LPTSTR lpCommandParam
  52. )
  53. /*++
  54. Routine Description
  55. Copy the current parameter to lpDestParam.
  56. Arguments:
  57. lpDestParam - that receive current parameter
  58. lpCommandParam - pointer to the current command line
  59. Return Value:
  60. TRUE if the function succeed, FALSE otherwise.
  61. --*/
  62. {
  63. DWORD dwLen = 0;
  64. WCHAR ch = L' ';
  65. *lpDestParam = 0;
  66. if ( ( lpCommandParam [0] == L'\"') || ( lpCommandParam [0] == L'\'') ) {
  67. ch = lpCommandParam [0];
  68. lpCommandParam++;
  69. };
  70. while ( ( lpCommandParam [0] ) != ch && ( lpCommandParam [0] !=0 ) ) {
  71. *lpDestParam++ = *lpCommandParam++;
  72. dwLen++;
  73. if ( dwLen>255 ) return FALSE;
  74. }
  75. if ( ch != L' ' && ch != lpCommandParam [0] )
  76. return FALSE;
  77. else lpCommandParam++;
  78. *lpDestParam = 0;
  79. return TRUE;
  80. }
  81. int __cdecl
  82. main()
  83. /*++
  84. Routine Description:
  85. Main entry point for the TIFF image viewer.
  86. Arguments:
  87. None.
  88. Return Value:
  89. Return code, zero for success.
  90. --*/
  91. {
  92. int rVal;
  93. HKEY hKey;
  94. DWORD Ret;
  95. LPTSTR p;
  96. DWORD Action = 0;
  97. LPTSTR Username;
  98. LPTSTR Password;
  99. PWCHAR lptCmdLine = GetCommandLine ();
  100. SvcDebugPrint(("\nWow64svc module......%S", lptCmdLine));
  101. lptCmdLine = NextParam ( lptCmdLine );
  102. while ( ( lptCmdLine != NULL ) && ( lptCmdLine[0] != 0 ) ) {
  103. if ( lptCmdLine[0] != L'-' && lptCmdLine[0] != L'/') {
  104. SvcDebugPrint ( ("\nSorry! incorrect parameter....."));
  105. SvcDebugPrint ( ("\n Uses: wow64svc -[i/r/d]"));
  106. return FALSE;
  107. }
  108. switch ( lptCmdLine[1] ) {
  109. case L'i':
  110. case L'I':
  111. //
  112. // Temporary heck ignore installing this service
  113. // You can delete the registry key as well for the initial sync
  114. //
  115. InitializeWow64OnBoot (2);
  116. //
  117. // write sync value Key.....
  118. //
  119. hKey = OpenNode (L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce");
  120. if (hKey != NULL)
  121. {
  122. Ret = RegSetValueEx(
  123. hKey,
  124. L"WOW64_SYNC",
  125. 0,
  126. REG_SZ,
  127. (PBYTE)L"wow64.exe -y",
  128. sizeof (L"wow64.exe -y")
  129. );
  130. RegCloseKey (hKey);
  131. }
  132. return 0;
  133. case L'r':
  134. case L'R':Action = 2;
  135. break;
  136. case L'd':
  137. case L'D':
  138. Action = 3;
  139. break;
  140. case L's':
  141. case L'S':
  142. StartWow64Service ();
  143. return 0;
  144. break;
  145. case L'x':
  146. case L'X':
  147. StopWow64Service ();
  148. return 0;
  149. break;
  150. case L'q':
  151. case L'Q':
  152. QueryWow64Service ();
  153. return 0;
  154. break;
  155. case L'y':
  156. case L'Y':
  157. //
  158. // Initial Sync registry
  159. //
  160. Wow64SyncCLSID ();
  161. return 0;
  162. default:
  163. SvcDebugPrint ( ("\nSorry! incorrect parameter.....pass2"));
  164. SvcDebugPrint ( ("\n Uses: wow64svc -[i/r/d]"));
  165. return FALSE;
  166. }
  167. lptCmdLine = NextParam ( lptCmdLine );
  168. }
  169. switch( Action ) {
  170. case 1:
  171. rVal = InstallService( NULL, NULL );
  172. if (rVal == 0) {
  173. //LogMessage( MSG_INSTALL_SUCCESS );
  174. } else {
  175. //LogMessage( MSG_INSTALL_FAIL, GetLastErrorText( rVal ) );
  176. }
  177. return rVal;
  178. case 2:
  179. rVal = RemoveService();
  180. if (rVal == 0) {
  181. //LogMessage( MSG_REMOVE_SUCCESS );
  182. } else {
  183. //LogMessage( MSG_REMOVE_FAIL, GetLastErrorText( rVal ) );
  184. }
  185. return rVal;
  186. case 3:
  187. ServiceDebug = TRUE;
  188. //ConsoleDebugOutput = TRUE;
  189. return ServiceStart();
  190. }
  191. SvcDebugPrint ( ("\nAttempt to run as a survice ......."));
  192. if (!InitReflector ())
  193. SvcDebugPrint ( ("\nSorry! couldn't initialize reflector thread, exiting"));
  194. if (!StartServiceCtrlDispatcher( ServiceDispatchTable)) {
  195. rVal = GetLastError();
  196. SvcDebugPrint(( "StartServiceCtrlDispatcher error =%d", rVal ));
  197. return rVal;
  198. }
  199. return 0;
  200. }
  201. DWORD
  202. InstallService(
  203. LPTSTR Username,
  204. LPTSTR Password
  205. )
  206. /*++
  207. Routine Description:
  208. Service installation function. This function just
  209. calls the service controller to install the Wow64 service.
  210. It is required that the Wow64 service run in the context
  211. of a user so that the service can access MAPI, files on
  212. disk, the network, etc.
  213. Arguments:
  214. Username - User name where the service runs.
  215. Password - Password for the user name.
  216. Return Value:
  217. Return code. Return zero for success, all other
  218. values indicate errors.
  219. --*/
  220. {
  221. DWORD rVal = 0;
  222. SC_HANDLE hSvcMgr;
  223. SC_HANDLE hService;
  224. //
  225. // do the registration for the reflector thread in the registry.
  226. //
  227. PopulateReflectorTable ();
  228. SvcDebugPrint ( ("\nInstalling service........"));
  229. hSvcMgr = OpenSCManager(
  230. NULL,
  231. NULL,
  232. SC_MANAGER_ALL_ACCESS
  233. );
  234. if (!hSvcMgr) {
  235. rVal = GetLastError();
  236. SvcDebugPrint(( "\ncould not open service manager: error code = %u", rVal ));
  237. return rVal;
  238. }
  239. hService = CreateService(
  240. hSvcMgr,
  241. WOW64_SERVICE_NAME,
  242. WOW64_DISPLAY_NAME,
  243. SERVICE_ALL_ACCESS,
  244. SERVICE_WIN32_OWN_PROCESS,
  245. SERVICE_AUTO_START, //SERVICE_DEMAND_START, //SERVICE_AUTO_START,
  246. SERVICE_ERROR_NORMAL,
  247. WOW64_IMAGE_NAME,
  248. NULL,
  249. NULL,
  250. NULL,
  251. Username,
  252. Password
  253. );
  254. if (!hService) {
  255. rVal = GetLastError();
  256. SvcDebugPrint(( "\ncould not create Wow64 service: error code = %u", rVal ));
  257. return rVal;
  258. }
  259. CloseServiceHandle( hService );
  260. CloseServiceHandle( hSvcMgr );
  261. SvcDebugPrint ( ("\nInstalled services with ret code: %d", rVal));
  262. return rVal;
  263. }
  264. DWORD
  265. RemoveService(
  266. void
  267. )
  268. /*++
  269. Routine Description:
  270. Service removal function. This function just
  271. calls the service controller to remove the Wow64 service.
  272. Arguments:
  273. None.
  274. Return Value:
  275. Return code. Return zero for success, all other
  276. values indicate errors.
  277. --*/
  278. {
  279. DWORD rVal = 0;
  280. SC_HANDLE hSvcMgr;
  281. SC_HANDLE hService;
  282. hSvcMgr = OpenSCManager(
  283. NULL,
  284. NULL,
  285. SC_MANAGER_ALL_ACCESS
  286. );
  287. if (!hSvcMgr) {
  288. rVal = GetLastError();
  289. SvcDebugPrint(( "could not open service manager: error code = %u", rVal ));
  290. return rVal;
  291. }
  292. hService = OpenService(
  293. hSvcMgr,
  294. WOW64_SERVICE_NAME,
  295. SERVICE_ALL_ACCESS
  296. );
  297. if (!hService) {
  298. rVal = GetLastError();
  299. SvcDebugPrint(( "could not open the Wow64 service: error code = %u", rVal ));
  300. return rVal;
  301. }
  302. if (ControlService( hService, SERVICE_CONTROL_STOP, &Wow64ServiceStatus )) {
  303. //
  304. // wait for 1 second
  305. //
  306. Sleep( 1000 );
  307. while( QueryServiceStatus( hService, &Wow64ServiceStatus ) ) {
  308. if ( Wow64ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING ) {
  309. Sleep( 1000 );
  310. } else {
  311. break;
  312. }
  313. }
  314. if (Wow64ServiceStatus.dwCurrentState != SERVICE_STOPPED) {
  315. rVal = GetLastError();
  316. SvcDebugPrint(("could not stop the Wow64 service: error code = %u", rVal ));
  317. return rVal;
  318. }
  319. }
  320. if (!DeleteService( hService )) {
  321. rVal = GetLastError();
  322. SvcDebugPrint(( "could not delete the Wow64 service: error code = %u", rVal ));
  323. return rVal;
  324. }
  325. CloseServiceHandle( hService );
  326. CloseServiceHandle( hSvcMgr );
  327. return rVal;
  328. }
  329. VOID
  330. Wow64ServiceMain(
  331. DWORD argc,
  332. LPTSTR *argv
  333. )
  334. /*++
  335. Routine Description:
  336. This is the service main that is called by the
  337. service controller.
  338. Arguments:
  339. argc - argument count
  340. argv - argument array
  341. Return Value:
  342. None.
  343. --*/
  344. {
  345. DWORD Rval;
  346. //
  347. // Setup initial registry link and layout for wow64 after boot.
  348. //
  349. SetWow64InitialRegistryLayout ();
  350. Wow64ServiceStatus.dwServiceType = SERVICE_WIN32;
  351. Wow64ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
  352. Wow64ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
  353. Wow64ServiceStatus.dwWin32ExitCode = 0;
  354. Wow64ServiceStatus.dwServiceSpecificExitCode = 0;
  355. Wow64ServiceStatus.dwCheckPoint = 0;
  356. Wow64ServiceStatus.dwWaitHint = 0;
  357. Wow64ServiceStatusHandle = RegisterServiceCtrlHandler(
  358. WOW64_SERVICE_NAME,
  359. Wow64ServiceCtrlHandler
  360. );
  361. if (!Wow64ServiceStatusHandle) {
  362. SvcDebugPrint(( "RegisterServiceCtrlHandler failed %d", GetLastError() ));
  363. return;
  364. }
  365. Rval = ServiceStart();
  366. if (Rval) {
  367. //
  368. // the service failed to start correctly
  369. //
  370. ReportServiceStatus( SERVICE_RUNNING, 0, 0);
  371. return;
  372. }
  373. ReportServiceStatus( SERVICE_RUNNING, 0, 0);
  374. return;
  375. }
  376. VOID
  377. Wow64ServiceCtrlHandler(
  378. DWORD Opcode
  379. )
  380. /*++
  381. Routine Description:
  382. This is the Wow64 service control dispatch function.
  383. Arguments:
  384. Opcode - requested control code
  385. Return Value:
  386. None.
  387. --*/
  388. {
  389. switch(Opcode) {
  390. case SERVICE_CONTROL_PAUSE:
  391. ReportServiceStatus( SERVICE_PAUSED, 0, 0 );
  392. break;
  393. case SERVICE_CONTROL_CONTINUE:
  394. ReportServiceStatus( SERVICE_RUNNING, 0, 0 );
  395. break;
  396. case SERVICE_CONTROL_STOP:
  397. if (ServiceStop () == 0)
  398. ReportServiceStatus( SERVICE_STOPPED, 0, 0 );
  399. return;
  400. case SERVICE_CONTROL_INTERROGATE:
  401. // fall through to send current status
  402. break;
  403. default:
  404. SvcDebugPrint(( "Unrecognized opcode %ld", Opcode ));
  405. break;
  406. }
  407. ReportServiceStatus( 0, 0, 0 );
  408. return;
  409. }
  410. DWORD
  411. ReportServiceStatus(
  412. DWORD CurrentState,
  413. DWORD Win32ExitCode,
  414. DWORD WaitHint
  415. )
  416. /*++
  417. Routine Description:
  418. This function updates the service control manager's status information for the Wow64 service.
  419. Arguments:
  420. CurrentState - Indicates the current state of the service
  421. Win32ExitCode - Specifies a Win32 error code that the service uses to
  422. report an error that occurs when it is starting or stopping.
  423. WaitHint - Specifies an estimate of the amount of time, in milliseconds,
  424. that the service expects a pending start, stop, or continue
  425. operation to take before the service makes its next call to the
  426. SetServiceStatus function with either an incremented dwCheckPoint
  427. value or a change in dwCurrentState.
  428. Return Value:
  429. Return code. Return zero for success, all other
  430. values indicate errors.
  431. --*/
  432. {
  433. static DWORD CheckPoint = 1;
  434. BOOL rVal;
  435. Wow64ServiceStatus.dwCurrentState = CurrentState;
  436. /*
  437. if (CurrentState == SERVICE_START_PENDING) {
  438. Wow64ServiceStatus.dwControlsAccepted = 0;
  439. } else {
  440. Wow64ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  441. }
  442. if (CurrentState) {
  443. Wow64ServiceStatus.dwCurrentState = CurrentState;
  444. }
  445. Wow64ServiceStatus.dwWin32ExitCode = Win32ExitCode;
  446. Wow64ServiceStatus.dwWaitHint = WaitHint;
  447. if ((Wow64ServiceStatus.dwCurrentState == SERVICE_RUNNING) ||
  448. (Wow64ServiceStatus.dwCurrentState == SERVICE_STOPPED ) ) {
  449. Wow64ServiceStatus.dwCheckPoint = 0;
  450. } else {
  451. Wow64ServiceStatus.dwCheckPoint = CheckPoint++;
  452. }
  453. */
  454. //
  455. // Report the status of the service to the service control manager.
  456. //
  457. rVal = SetServiceStatus( Wow64ServiceStatusHandle, &Wow64ServiceStatus );
  458. if (!rVal) {
  459. SvcDebugPrint(( "SetServiceStatus() failed: ec=%d", GetLastError() ));
  460. }
  461. return rVal;
  462. }
  463. DWORD
  464. StartWow64Service ()
  465. /*++
  466. Routine Description:
  467. This function Start wow64 service.
  468. Arguments:
  469. None.
  470. Return Value:
  471. Return code. Return zero for success, all other
  472. values indicate errors.
  473. --*/
  474. {
  475. DWORD rVal=0;
  476. SC_HANDLE hSvcMgr;
  477. SC_HANDLE hService;
  478. SvcDebugPrint ( ("\ntrying to start service......"));
  479. hSvcMgr = OpenSCManager(
  480. NULL,
  481. NULL,
  482. SC_MANAGER_ALL_ACCESS
  483. );
  484. if (!hSvcMgr) {
  485. rVal = GetLastError();
  486. SvcDebugPrint(( "\ncould not open service manager: error code = %u", rVal ));
  487. return rVal;
  488. }
  489. hService = OpenService( hSvcMgr, WOW64_SERVICE_NAME, SERVICE_ALL_ACCESS );
  490. if ( !hService ) {
  491. rVal = GetLastError();
  492. SvcDebugPrint(( "\ncould not open service:%s error code = %u", WOW64_SERVICE_NAME, rVal ));
  493. return rVal;
  494. }
  495. if (! StartService( hService, 0, NULL) ) {
  496. rVal = GetLastError();
  497. SvcDebugPrint(( "\ncould not start service:%s error code = %u", WOW64_SERVICE_NAME, rVal ));
  498. return rVal;
  499. }
  500. SvcDebugPrint(( "\nservice:%s started successfully error code = %u", WOW64_SERVICE_NAME, rVal ));
  501. return 0;
  502. }
  503. DWORD
  504. StopWow64Service ()
  505. /*++
  506. Routine Description:
  507. This function Stop wow64 service.
  508. Arguments:
  509. None.
  510. Return Value:
  511. Return code. Return zero for success, all other
  512. values indicate errors.
  513. --*/
  514. {
  515. DWORD rVal=0;
  516. SC_HANDLE hSvcMgr;
  517. SC_HANDLE hService;
  518. SvcDebugPrint ( ("\ntrying to start service......"));
  519. hSvcMgr = OpenSCManager(
  520. NULL,
  521. NULL,
  522. SC_MANAGER_ALL_ACCESS
  523. );
  524. if (!hSvcMgr) {
  525. rVal = GetLastError();
  526. SvcDebugPrint(( "\ncould not open service manager: error code = %u", rVal ));
  527. return rVal;
  528. }
  529. hService = OpenService( hSvcMgr, WOW64_SERVICE_NAME, SERVICE_ALL_ACCESS );
  530. if ( !hService ) {
  531. rVal = GetLastError();
  532. SvcDebugPrint(( "\ncould not open service:%S error code = %u", WOW64_SERVICE_NAME, rVal ));
  533. return rVal;
  534. }
  535. if (!ControlService( hService, SERVICE_CONTROL_PAUSE, &Wow64ServiceStatus )) {
  536. rVal = GetLastError();
  537. SvcDebugPrint(( "\nSorry! couldn't stop the service:%S error code = %u", WOW64_SERVICE_NAME, rVal ));
  538. return rVal;
  539. }
  540. SvcDebugPrint(( "\nservice:%S stopped successfully error code = %u", WOW64_SERVICE_NAME, rVal ));
  541. return 0;
  542. }
  543. DWORD
  544. QueryWow64Service ()
  545. /*++
  546. Routine Description:
  547. This function log the current status of wow64 service.
  548. Arguments:
  549. None.
  550. Return Value:
  551. Return code. Return zero for success, all other
  552. values indicate errors.
  553. --*/
  554. {
  555. DWORD rVal=0;
  556. SC_HANDLE hSvcMgr;
  557. SC_HANDLE hService;
  558. SvcDebugPrint ( ("\ntrying to start service......"));
  559. hSvcMgr = OpenSCManager(
  560. NULL,
  561. NULL,
  562. SC_MANAGER_ALL_ACCESS
  563. );
  564. if (!hSvcMgr) {
  565. rVal = GetLastError();
  566. SvcDebugPrint(( "\ncould not open service manager: error code = %u", rVal ));
  567. return rVal;
  568. }
  569. hService = OpenService( hSvcMgr, WOW64_SERVICE_NAME, SERVICE_ALL_ACCESS );
  570. if ( !hService ) {
  571. rVal = GetLastError();
  572. SvcDebugPrint(( "\ncould not open service:%S error code = %u", WOW64_SERVICE_NAME, rVal ));
  573. return rVal;
  574. }
  575. QueryServiceStatus( hService, &Wow64ServiceStatus );
  576. {
  577. SvcDebugPrint ( ("\nStatus: %d, [pending %d] [running %d]",Wow64ServiceStatus.dwCurrentState, SERVICE_STOP_PENDING, SERVICE_RUNNING));
  578. }
  579. SvcDebugPrint(( "\nservice:%S started successfully error code = %u", WOW64_SERVICE_NAME, rVal ));
  580. return 0;
  581. }