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.

951 lines
24 KiB

  1. // msimeth.cpp : Defines the entry point for the application.
  2. //
  3. // Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. #include <precomp.h>
  6. #include "classfac.h"
  7. #include "methods.h"
  8. #include "msimethod.h"
  9. DWORD g_ProductRegister = 0;
  10. DWORD g_SoftwareFeatureRegister = 0;
  11. long g_lRunning = 0;
  12. BOOL s_Exiting = FALSE ;
  13. BOOL gbShowIcon = FALSE;
  14. HANDLE g_hMutex = NULL;
  15. HANDLE g_hTerminateEvent = NULL;
  16. HANDLE g_hMethodAdd = NULL;
  17. HANDLE g_hMethodRelease = NULL;
  18. UINT g_uiResult = 0;
  19. HANDLE g_hPipe = NULL;
  20. bool g_bPipe = true;
  21. DEFINE_GUID(CLSID_MsiProductMethods,0x3E6A93E0, 0xFDAD, 0x11D2, 0xa9, 0x7B, 0x0, 0xA0, 0xC9, 0x95, 0x49, 0x21);
  22. // {3E6A93E0-FDAD-11D2-A97B-00A0C9954921}
  23. DEFINE_GUID(CLSID_MsiSoftwareFeatureMethods,0xE293BA80, 0xFDAD, 0x11D2, 0xa9, 0x7B, 0x0, 0xA0, 0xC9, 0x95, 0x49, 0x21);
  24. // {E293BA80-FDAD-11D2-A97B-00A0C9954921}
  25. BOOL IsNT()
  26. {
  27. OSVERSIONINFO OSInfo;
  28. OSInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  29. if(GetVersionEx(&OSInfo) && OSInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  30. return TRUE ;
  31. return FALSE ;
  32. }
  33. /*
  34. LRESULT CALLBACK WndProc(IN HWND hWnd, IN UINT message,
  35. IN WPARAM wParam, IN LPARAM lParam)
  36. {
  37. switch (message) {
  38. case WM_QUERYOPEN: //todo, queryend session
  39. return 0;
  40. case WM_QUERYENDSESSION:
  41. return TRUE;
  42. case WM_ENDSESSION:
  43. if(wParam == TRUE){
  44. SetEvent(g_hTerminateEvent);
  45. }
  46. return 0;
  47. case WM_DESTROY:
  48. PostQuitMessage(0);
  49. SetEvent(g_hTerminateEvent);
  50. break;
  51. default:
  52. return (DefWindowProc(hWnd, message, wParam, lParam));
  53. }
  54. return (0);
  55. }
  56. *//*
  57. HWND CreateMsiMethWindow(IN HINSTANCE hInstance)
  58. {
  59. WNDCLASS wndclass;
  60. wndclass.style = 0;
  61. wndclass.lpfnWndProc = WndProc;
  62. wndclass.cbClsExtra = 0;
  63. wndclass.cbWndExtra = 0;
  64. wndclass.hInstance = hInstance;
  65. wndclass.hIcon = LoadIcon(hInstance, TEXT("MsiMeth"));
  66. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  67. wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
  68. wndclass.lpszMenuName = NULL;
  69. wndclass.lpszClassName = TEXT("MSIMETHCLASS");
  70. if(!RegisterClass(&wndclass)) return NULL;
  71. HWND hWnd = CreateWindow(TEXT("MSIMETHCLASS"),
  72. TEXT("MSIMETH"),
  73. WS_OVERLAPPED | WS_SYSMENU,
  74. CW_USEDEFAULT,
  75. CW_USEDEFAULT,
  76. CW_USEDEFAULT,
  77. CW_USEDEFAULT,
  78. NULL, NULL, hInstance, NULL);
  79. if(hWnd == NULL)return NULL;
  80. // This program is visible only for debug builds.
  81. if(gbShowIcon){
  82. ShowWindow(hWnd,SW_MINIMIZE);
  83. UpdateWindow(hWnd);
  84. HMENU hMenu = GetSystemMenu(hWnd, FALSE);
  85. if(hMenu) DeleteMenu(hMenu, SC_RESTORE, MF_BYCOMMAND);
  86. }
  87. return hWnd;
  88. }
  89. *//*
  90. HRESULT UninitComServer ()
  91. {
  92. if(g_ProductRegister) CoRevokeClassObject(g_ProductRegister);
  93. if(g_SoftwareFeatureRegister) CoRevokeClassObject(g_SoftwareFeatureRegister);
  94. CoUninitialize();
  95. return S_OK ;
  96. }
  97. *//*
  98. HRESULT InitInstanceProvider()
  99. {
  100. CMethodsFactory *pClassFactory = new CMethodsFactory();
  101. HRESULT hrResult = S_OK;
  102. if(SUCCEEDED(hrResult = CoRegisterClassObject(CLSID_MsiProductMethods,
  103. (IUnknown *)pClassFactory,
  104. CLSCTX_LOCAL_SERVER,
  105. REGCLS_MULTIPLEUSE,
  106. &g_ProductRegister))){
  107. hrResult = CoRegisterClassObject(CLSID_MsiSoftwareFeatureMethods,
  108. (IUnknown *)pClassFactory,
  109. CLSCTX_LOCAL_SERVER,
  110. REGCLS_MULTIPLEUSE,
  111. &g_SoftwareFeatureRegister);
  112. }
  113. return hrResult ;
  114. }
  115. *//*
  116. HRESULT InitComServer ( DWORD a_AuthenticationLevel , DWORD a_ImpersonationLevel )
  117. {
  118. HRESULT t_Result = S_OK ;
  119. t_Result = CoInitializeEx(0, COINIT_MULTITHREADED);
  120. if(SUCCEEDED(t_Result)){
  121. t_Result = CoInitializeSecurity(NULL, -1, NULL, NULL,
  122. a_AuthenticationLevel, a_ImpersonationLevel,
  123. NULL, EOAC_NONE, 0);
  124. if(FAILED(t_Result)){
  125. CoUninitialize();
  126. return t_Result;
  127. }
  128. }
  129. if(SUCCEEDED(t_Result)) t_Result = InitInstanceProvider();
  130. if(FAILED(t_Result)){
  131. UninitComServer () ;
  132. }
  133. return t_Result ;
  134. }
  135. *//*
  136. void WindowsDispatch()
  137. {
  138. BOOL bWaitAll = FALSE;
  139. HANDLE hEvents[] = {g_hTerminateEvent, g_hMethodAdd, g_hMethodRelease};
  140. int iNumEvents = sizeof(hEvents) / sizeof(HANDLE);
  141. DWORD dwWait = 60000; //60 seconds
  142. while(1){
  143. // listen for server events...exit if dwTime elapses without any requests
  144. DWORD dwObj = WaitForMultipleObjects(iNumEvents, hEvents, bWaitAll, dwWait);
  145. switch(dwObj){
  146. case WAIT_TIMEOUT: // time expired
  147. //we timed out so if there are no active threads it's safe to exit.
  148. if(g_cObj < 1) return;
  149. break;
  150. case WAIT_OBJECT_0: //terminate
  151. if(g_cObj < 1) return;
  152. dwWait = 2000;
  153. break;
  154. case WAIT_OBJECT_0 + 1: //method started
  155. g_lRunning++;
  156. break;
  157. case WAIT_OBJECT_0 + 2: //method ended
  158. g_lRunning--;
  159. break;
  160. }
  161. if(s_Exiting) return ;
  162. }
  163. }
  164. *//*
  165. HRESULT Process ()
  166. {
  167. DWORD t_ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE ;
  168. DWORD t_AuthenticationLevel = RPC_C_AUTHN_LEVEL_CONNECT ;
  169. HRESULT hr = S_OK;
  170. if(SUCCEEDED(hr = InitComServer(t_ImpersonationLevel, t_AuthenticationLevel))){
  171. WindowsDispatch();
  172. UninitComServer();
  173. }
  174. return hr;
  175. }
  176. */
  177. void TerminateRunning()
  178. {
  179. DWORD dwFlag = EVENT_MODIFY_STATE;
  180. if(IsNT()) dwFlag |= SYNCHRONIZE;
  181. HANDLE hTerm = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("MSIPROV_METHODS_SERVER_TERMINATE"));
  182. if(hTerm){
  183. SetEvent(hTerm);
  184. CloseHandle(hTerm);
  185. }
  186. return;
  187. }
  188. /*
  189. BOOL ParseCommandLine ()
  190. {
  191. BOOL t_Exit = FALSE;
  192. LPTSTR t_CommandLine = GetCommandLine();
  193. if(t_CommandLine)
  194. {
  195. TCHAR *t_Arg = NULL;
  196. TCHAR *t_ApplicationArg = NULL;
  197. t_ApplicationArg = _tcstok(t_CommandLine, _TEXT(" \t"));
  198. t_Arg = _tcstok(NULL, _TEXT(" \t"));
  199. if(t_Arg){
  200. if(_tcsicmp(t_Arg, _TEXT ("/RegServer")) == 0){
  201. t_Exit = TRUE;
  202. DllRegisterServer();
  203. }else if(_tcsicmp(t_Arg, _TEXT("/UnRegServer")) == 0){
  204. t_Exit = TRUE;
  205. DllUnregisterServer();
  206. }else if(_tcsicmp(t_Arg, _TEXT("/kill")) == 0){
  207. t_Exit = TRUE;
  208. TerminateRunning();
  209. }else if(_tcsicmp(t_Arg, _TEXT("/admin")) == 0){
  210. int iThread = _ttoi(_tcstok(NULL, _TEXT(" ")));
  211. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" "));
  212. TCHAR ptcOptions[1000];
  213. _tcscpy(ptcOptions, _T(""));
  214. TCHAR *token = _tcstok(NULL, _TEXT(" "));
  215. while(token != NULL){
  216. _tcscat(ptcOptions, _T(" "));
  217. _tcscat(ptcOptions, token);
  218. token = _tcstok(NULL, _TEXT(" "));
  219. }
  220. SetFileApisToOEM();
  221. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  222. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  223. //synchronize us with the parent process
  224. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  225. if(g_hMutex)
  226. WaitForSingleObject(g_hMutex, INFINITE);
  227. ReleaseMutex(g_hMutex);
  228. // call the server with a pipe set up to deal with
  229. //status messages
  230. CMethods *pMeth = new CMethods();
  231. pMeth->Admin((LPWSTR)ptcPackage, (LPWSTR)ptcOptions, &g_uiResult, iThread);
  232. t_Exit = TRUE;
  233. CloseHandle(g_hPipe);
  234. delete pMeth;
  235. }else if(_tcsicmp(t_Arg, _TEXT("/advertise")) == 0){
  236. int iThread = _ttoi(_tcstok(NULL, _TEXT(" ")));
  237. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" "));
  238. TCHAR ptcOptions[1000];
  239. _tcscpy(ptcOptions, _T(""));
  240. TCHAR *token = _tcstok(NULL, _TEXT(" "));
  241. while(token != NULL){
  242. _tcscat(ptcOptions, _T(" "));
  243. _tcscat(ptcOptions, token);
  244. token = _tcstok(NULL, _TEXT(" "));
  245. }
  246. SetFileApisToOEM();
  247. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  248. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  249. //synchronize us with the parent process
  250. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  251. if(g_hMutex)
  252. WaitForSingleObject(g_hMutex, INFINITE);
  253. ReleaseMutex(g_hMutex);
  254. // call the server with a pipe set up to deal with
  255. //status messages
  256. CMethods *pMeth = new CMethods();
  257. pMeth->Advertise((LPWSTR)ptcPackage, (LPWSTR)ptcOptions, &g_uiResult, iThread);
  258. t_Exit = TRUE;
  259. CloseHandle(g_hPipe);
  260. delete pMeth;
  261. }else if(_tcsicmp(t_Arg, _TEXT("/configure")) == 0){
  262. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  263. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  264. int iInstallLevel = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  265. int iInstallState = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  266. SetFileApisToOEM();
  267. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  268. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  269. //synchronize us with the parent process
  270. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  271. if(g_hMutex)
  272. WaitForSingleObject(g_hMutex, INFINITE);
  273. ReleaseMutex(g_hMutex);
  274. // call the server with a pipe set up to deal with
  275. //status messages
  276. CMethods *pMeth = new CMethods();
  277. pMeth->Configure((LPWSTR)ptcPackage, iInstallLevel, iInstallState, &g_uiResult, iThread);
  278. t_Exit = TRUE;
  279. CloseHandle(g_hPipe);
  280. delete pMeth;
  281. }else if(_tcsicmp(t_Arg, _TEXT("/install")) == 0){
  282. int iThread = _ttoi(_tcstok(NULL, _TEXT(" ")));
  283. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" "));
  284. TCHAR ptcOptions[1000];
  285. _tcscpy(ptcOptions, _T(""));
  286. TCHAR *token = _tcstok(NULL, _TEXT(" "));
  287. while(token != NULL){
  288. _tcscat(ptcOptions, _T(" "));
  289. _tcscat(ptcOptions, token);
  290. token = _tcstok(NULL, _TEXT(" "));
  291. }
  292. SetFileApisToOEM();
  293. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  294. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  295. //synchronize us with the parent process
  296. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  297. if(g_hMutex)
  298. WaitForSingleObject(g_hMutex, INFINITE);
  299. ReleaseMutex(g_hMutex);
  300. // call the server with a pipe set up to deal with
  301. //status messages
  302. CMethods *pMeth = new CMethods();
  303. pMeth->Install((LPWSTR)ptcPackage, (LPWSTR)ptcOptions, &g_uiResult, iThread);
  304. t_Exit = TRUE;
  305. CloseHandle(g_hPipe);
  306. delete pMeth;
  307. }else if(_tcsicmp(t_Arg, _TEXT("/reinstall")) == 0){
  308. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  309. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  310. DWORD dwReinstallMode = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  311. SetFileApisToOEM();
  312. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  313. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  314. //synchronize us with the parent process
  315. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  316. if(g_hMutex)
  317. WaitForSingleObject(g_hMutex, INFINITE);
  318. ReleaseMutex(g_hMutex);
  319. // call the server with a pipe set up to deal with
  320. //status messages
  321. CMethods *pMeth = new CMethods();
  322. pMeth->Reinstall((LPWSTR)ptcPackage, dwReinstallMode, &g_uiResult, iThread);
  323. t_Exit = TRUE;
  324. CloseHandle(g_hPipe);
  325. delete pMeth;
  326. }else if(_tcsicmp(t_Arg, _TEXT("/uninstall")) == 0){
  327. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  328. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  329. SetFileApisToOEM();
  330. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  331. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  332. //synchronize us with the parent process
  333. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  334. if(g_hMutex)
  335. WaitForSingleObject(g_hMutex, INFINITE);
  336. ReleaseMutex(g_hMutex);
  337. // call the server with a pipe set up to deal with
  338. //status messages
  339. CMethods *pMeth = new CMethods();
  340. pMeth->Uninstall((LPWSTR)ptcPackage, &g_uiResult, iThread);
  341. t_Exit = TRUE;
  342. CloseHandle(g_hPipe);
  343. delete pMeth;
  344. }else if(_tcsicmp(t_Arg, _TEXT("/upgrade")) == 0){
  345. int iThread = _ttoi(_tcstok(NULL, _TEXT(" ")));
  346. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" "));
  347. TCHAR ptcOptions[1000];
  348. _tcscpy(ptcOptions, _T(""));
  349. TCHAR *token = _tcstok(NULL, _TEXT(" "));
  350. while(token != NULL){
  351. _tcscat(ptcOptions, _T(" "));
  352. _tcscat(ptcOptions, token);
  353. token = _tcstok(NULL, _TEXT(" "));
  354. }
  355. SetFileApisToOEM();
  356. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  357. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  358. //synchronize us with the parent process
  359. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  360. if(g_hMutex)
  361. WaitForSingleObject(g_hMutex, INFINITE);
  362. ReleaseMutex(g_hMutex);
  363. // call the server with a pipe set up to deal with
  364. //status messages
  365. CMethods *pMeth = new CMethods();
  366. pMeth->Upgrade((LPWSTR)ptcPackage, (LPWSTR)ptcOptions, &g_uiResult, iThread);
  367. t_Exit = TRUE;
  368. CloseHandle(g_hPipe);
  369. delete pMeth;
  370. }else if(_tcsicmp(t_Arg, _TEXT("/sfconfigure")) == 0){
  371. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  372. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  373. TCHAR *ptcFeature = _tcstok(NULL, _TEXT(" \t"));
  374. int iInstallState = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  375. SetFileApisToOEM();
  376. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  377. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  378. //synchronize us with the parent process
  379. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  380. if(g_hMutex)
  381. WaitForSingleObject(g_hMutex, INFINITE);
  382. ReleaseMutex(g_hMutex);
  383. // call the server with a pipe set up to deal with
  384. //status messages
  385. CMethods *pMeth = new CMethods();
  386. pMeth->ConfigureSF((LPWSTR)ptcPackage, (LPWSTR)ptcFeature, iInstallState,
  387. &g_uiResult, iThread);
  388. t_Exit = TRUE;
  389. CloseHandle(g_hPipe);
  390. delete pMeth;
  391. }else if(_tcsicmp(t_Arg, _TEXT("/sfreinstall")) == 0){
  392. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  393. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  394. TCHAR *ptcFeature = _tcstok(NULL, _TEXT(" \t"));
  395. DWORD dwReinstallMode = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  396. SetFileApisToOEM();
  397. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  398. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  399. //synchronize us with the parent process
  400. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  401. if(g_hMutex)
  402. WaitForSingleObject(g_hMutex, INFINITE);
  403. ReleaseMutex(g_hMutex);
  404. // call the server with a pipe set up to deal with
  405. //status messages
  406. CMethods *pMeth = new CMethods();
  407. pMeth->ReinstallSF((LPWSTR)ptcPackage, (LPWSTR)ptcFeature, dwReinstallMode,
  408. &g_uiResult, iThread);
  409. t_Exit = TRUE;
  410. CloseHandle(g_hPipe);
  411. delete pMeth;
  412. }
  413. }
  414. }
  415. return t_Exit ;
  416. }
  417. */
  418. int APIENTRY WinMain(HINSTANCE hInstance,
  419. HINSTANCE hPrevInstance,
  420. LPSTR lpCmdLine,
  421. int nCmdShow)
  422. {
  423. // BOOL t_Exit = FALSE;
  424. g_uiResult = 0;
  425. LPTSTR t_CommandLine = GetCommandLine();
  426. if(t_CommandLine)
  427. {
  428. TCHAR *t_Arg = NULL;
  429. TCHAR *t_ApplicationArg = NULL;
  430. t_ApplicationArg = _tcstok(t_CommandLine, _TEXT(" \t"));
  431. t_Arg = _tcstok(NULL, _TEXT(" \t"));
  432. if(t_Arg){
  433. if(_tcsicmp(t_Arg, _TEXT ("/RegServer")) == 0){
  434. // t_Exit = TRUE;
  435. DllRegisterServer();
  436. }else if(_tcsicmp(t_Arg, _TEXT("/UnRegServer")) == 0){
  437. // t_Exit = TRUE;
  438. DllUnregisterServer();
  439. }else if(_tcsicmp(t_Arg, _TEXT("/kill")) == 0){
  440. // t_Exit = TRUE;
  441. TerminateRunning();
  442. }else if(_tcsicmp(t_Arg, _TEXT("/admin")) == 0){
  443. int iThread = _ttoi(_tcstok(NULL, _TEXT(" ")));
  444. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" "));
  445. TCHAR ptcOptions[1000];
  446. _tcscpy(ptcOptions, _T(""));
  447. TCHAR *token = _tcstok(NULL, _TEXT(" "));
  448. while(token != NULL){
  449. _tcscat(ptcOptions, _T(" "));
  450. _tcscat(ptcOptions, token);
  451. token = _tcstok(NULL, _TEXT(" "));
  452. }
  453. SetFileApisToOEM();
  454. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  455. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  456. //synchronize us with the parent process
  457. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  458. if(g_hMutex)
  459. WaitForSingleObject(g_hMutex, INFINITE);
  460. ReleaseMutex(g_hMutex);
  461. // call the server with a pipe set up to deal with
  462. //status messages
  463. CMethods *pMeth = new CMethods();
  464. pMeth->Admin((LPWSTR)ptcPackage, (LPWSTR)ptcOptions, &g_uiResult, iThread);
  465. // t_Exit = TRUE;
  466. CloseHandle(g_hPipe);
  467. delete pMeth;
  468. }else if(_tcsicmp(t_Arg, _TEXT("/advertise")) == 0){
  469. int iThread = _ttoi(_tcstok(NULL, _TEXT(" ")));
  470. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" "));
  471. TCHAR ptcOptions[1000];
  472. _tcscpy(ptcOptions, _T(""));
  473. TCHAR *token = _tcstok(NULL, _TEXT(" "));
  474. while(token != NULL){
  475. _tcscat(ptcOptions, _T(" "));
  476. _tcscat(ptcOptions, token);
  477. token = _tcstok(NULL, _TEXT(" "));
  478. }
  479. SetFileApisToOEM();
  480. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  481. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  482. //synchronize us with the parent process
  483. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  484. if(g_hMutex)
  485. WaitForSingleObject(g_hMutex, INFINITE);
  486. ReleaseMutex(g_hMutex);
  487. // call the server with a pipe set up to deal with
  488. //status messages
  489. CMethods *pMeth = new CMethods();
  490. pMeth->Advertise((LPWSTR)ptcPackage, (LPWSTR)ptcOptions, &g_uiResult, iThread);
  491. // t_Exit = TRUE;
  492. CloseHandle(g_hPipe);
  493. delete pMeth;
  494. }else if(_tcsicmp(t_Arg, _TEXT("/configure")) == 0){
  495. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  496. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  497. int iInstallLevel = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  498. int iInstallState = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  499. SetFileApisToOEM();
  500. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  501. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  502. //synchronize us with the parent process
  503. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  504. if(g_hMutex)
  505. WaitForSingleObject(g_hMutex, INFINITE);
  506. ReleaseMutex(g_hMutex);
  507. // call the server with a pipe set up to deal with
  508. //status messages
  509. CMethods *pMeth = new CMethods();
  510. pMeth->Configure((LPWSTR)ptcPackage, iInstallLevel, iInstallState, &g_uiResult, iThread);
  511. // t_Exit = TRUE;
  512. CloseHandle(g_hPipe);
  513. delete pMeth;
  514. }else if(_tcsicmp(t_Arg, _TEXT("/install")) == 0){
  515. int iThread = _ttoi(_tcstok(NULL, _TEXT(" ")));
  516. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" "));
  517. TCHAR ptcOptions[1000];
  518. _tcscpy(ptcOptions, _T(""));
  519. TCHAR *token = _tcstok(NULL, _TEXT(" "));
  520. while(token != NULL){
  521. _tcscat(ptcOptions, _T(" "));
  522. _tcscat(ptcOptions, token);
  523. token = _tcstok(NULL, _TEXT(" "));
  524. }
  525. SetFileApisToOEM();
  526. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  527. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  528. //synchronize us with the parent process
  529. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  530. if(g_hMutex)
  531. WaitForSingleObject(g_hMutex, INFINITE);
  532. ReleaseMutex(g_hMutex);
  533. // call the server with a pipe set up to deal with
  534. //status messages
  535. CMethods *pMeth = new CMethods();
  536. pMeth->Install((LPWSTR)ptcPackage, (LPWSTR)ptcOptions, &g_uiResult, iThread);
  537. // t_Exit = TRUE;
  538. CloseHandle(g_hPipe);
  539. delete pMeth;
  540. }else if(_tcsicmp(t_Arg, _TEXT("/reinstall")) == 0){
  541. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  542. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  543. DWORD dwReinstallMode = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  544. SetFileApisToOEM();
  545. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  546. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  547. //synchronize us with the parent process
  548. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  549. if(g_hMutex)
  550. WaitForSingleObject(g_hMutex, INFINITE);
  551. ReleaseMutex(g_hMutex);
  552. // call the server with a pipe set up to deal with
  553. //status messages
  554. CMethods *pMeth = new CMethods();
  555. pMeth->Reinstall((LPWSTR)ptcPackage, dwReinstallMode, &g_uiResult, iThread);
  556. // t_Exit = TRUE;
  557. CloseHandle(g_hPipe);
  558. delete pMeth;
  559. }else if(_tcsicmp(t_Arg, _TEXT("/uninstall")) == 0){
  560. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  561. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  562. SetFileApisToOEM();
  563. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  564. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  565. //synchronize us with the parent process
  566. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  567. if(g_hMutex)
  568. WaitForSingleObject(g_hMutex, INFINITE);
  569. ReleaseMutex(g_hMutex);
  570. // call the server with a pipe set up to deal with
  571. //status messages
  572. CMethods *pMeth = new CMethods();
  573. pMeth->Uninstall((LPWSTR)ptcPackage, &g_uiResult, iThread);
  574. // t_Exit = TRUE;
  575. CloseHandle(g_hPipe);
  576. delete pMeth;
  577. }else if(_tcsicmp(t_Arg, _TEXT("/upgrade")) == 0){
  578. int iThread = _ttoi(_tcstok(NULL, _TEXT(" ")));
  579. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" "));
  580. TCHAR ptcOptions[1000];
  581. _tcscpy(ptcOptions, _T(""));
  582. TCHAR *token = _tcstok(NULL, _TEXT(" "));
  583. while(token != NULL){
  584. _tcscat(ptcOptions, _T(" "));
  585. _tcscat(ptcOptions, token);
  586. token = _tcstok(NULL, _TEXT(" "));
  587. }
  588. SetFileApisToOEM();
  589. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  590. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  591. //synchronize us with the parent process
  592. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  593. if(g_hMutex)
  594. WaitForSingleObject(g_hMutex, INFINITE);
  595. ReleaseMutex(g_hMutex);
  596. // call the server with a pipe set up to deal with
  597. //status messages
  598. CMethods *pMeth = new CMethods();
  599. pMeth->Upgrade((LPWSTR)ptcPackage, (LPWSTR)ptcOptions, &g_uiResult, iThread);
  600. // t_Exit = TRUE;
  601. CloseHandle(g_hPipe);
  602. delete pMeth;
  603. }else if(_tcsicmp(t_Arg, _TEXT("/sfconfigure")) == 0){
  604. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  605. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  606. TCHAR *ptcFeature = _tcstok(NULL, _TEXT(" \t"));
  607. int iInstallState = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  608. SetFileApisToOEM();
  609. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  610. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  611. //synchronize us with the parent process
  612. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  613. if(g_hMutex)
  614. WaitForSingleObject(g_hMutex, INFINITE);
  615. ReleaseMutex(g_hMutex);
  616. // call the server with a pipe set up to deal with
  617. //status messages
  618. CMethods *pMeth = new CMethods();
  619. pMeth->ConfigureSF((LPWSTR)ptcPackage, (LPWSTR)ptcFeature, iInstallState,
  620. &g_uiResult, iThread);
  621. // t_Exit = TRUE;
  622. CloseHandle(g_hPipe);
  623. delete pMeth;
  624. }else if(_tcsicmp(t_Arg, _TEXT("/sfreinstall")) == 0){
  625. int iThread = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  626. TCHAR *ptcPackage = _tcstok(NULL, _TEXT(" \t"));
  627. TCHAR *ptcFeature = _tcstok(NULL, _TEXT(" \t"));
  628. DWORD dwReinstallMode = _ttoi(_tcstok(NULL, _TEXT(" \t")));
  629. SetFileApisToOEM();
  630. g_hPipe = CreateFileW(L"\\\\.\\pipe\\msimeth_pipe", GENERIC_WRITE, 0, NULL,
  631. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  632. //synchronize us with the parent process
  633. g_hMutex = CreateMutex(NULL, FALSE, TEXT("MSIPROV_METHODS_SERVER"));
  634. if(g_hMutex)
  635. WaitForSingleObject(g_hMutex, INFINITE);
  636. ReleaseMutex(g_hMutex);
  637. // call the server with a pipe set up to deal with
  638. //status messages
  639. CMethods *pMeth = new CMethods();
  640. pMeth->ReinstallSF((LPWSTR)ptcPackage, (LPWSTR)ptcFeature, dwReinstallMode,
  641. &g_uiResult, iThread);
  642. // t_Exit = TRUE;
  643. CloseHandle(g_hPipe);
  644. delete pMeth;
  645. }
  646. }
  647. }
  648. return g_uiResult;
  649. }