Leaked source code of windows server 2003
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.

649 lines
16 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. WINMGMT.CPP
  5. Abstract:
  6. If started with /kill argument, it will stop any running exes or services.
  7. If started with /? or /help dumps out information.
  8. History:
  9. a-davj 04-Mar-97 Created.
  10. --*/
  11. #include "precomp.h"
  12. #include <malloc.h>
  13. #include <Shellapi.h> // for CommandLineToArgvW
  14. #include <wbemidl.h>
  15. #include <reg.h> // for Registry
  16. #include <wbemutil.h> // for DEBUGTRACE
  17. #include <cominit.h> // for InitializeCom
  18. #include <genutils.h> // EnablePrivilege
  19. #include <mofcomp.h>
  20. #include <winmgmtr.h>
  21. #include <arrtempl.h>
  22. #include "servutil.h"
  23. #include "WinMgmt.h"
  24. #include "STRINGS.h"
  25. #define BUFF_MAX 200
  26. HINSTANCE ghInstance;
  27. DWORD RegServer();
  28. DWORD UnregServer();
  29. void DoResyncPerf();
  30. void DoClearAdap();
  31. // to accomodate revert-to-alone
  32. DWORD DoSetToAlone(CHAR * pszLevel);
  33. DWORD DoSetToShared(CHAR * pszLevel);
  34. // for Back-up Restore
  35. int DoBackup();
  36. int DoRestore();
  37. void DisplayWbemError(HRESULT hresError, DWORD dwLongFormatString, DWORD dwShortFormatString, DWORD dwTitle);
  38. //***************************************************************************
  39. //
  40. // void TerminateRunning
  41. //
  42. // DESCRIPTION:
  43. //
  44. // Stops another running copy even if it is a service.
  45. //
  46. //***************************************************************************
  47. void TerminateRunning()
  48. {
  49. StopService(__TEXT("wmiapsrv"), 15);
  50. StopService(__TEXT("WinMgmt"), 15);
  51. return;
  52. }
  53. //***************************************************************************
  54. //
  55. // void DisplayMessage
  56. //
  57. // DESCRIPTION:
  58. //
  59. // Displays a usage message box.
  60. //
  61. //***************************************************************************
  62. void DisplayMessage()
  63. {
  64. //
  65. // ISSUE: these might not be enought for certain localized strings
  66. //
  67. wchar_t tBuff[BUFF_MAX];
  68. wchar_t tBig[1024];
  69. tBig[0] = 0;
  70. UINT ui;
  71. for(ui = ID1; ui <= ID9; ui++)
  72. {
  73. int iRet = LoadStringW(ghInstance, ui, tBuff, BUFF_MAX);
  74. if(iRet > 0)
  75. StringCchCatW(tBig, 1024, tBuff);
  76. }
  77. if(lstrlenW(tBig) > 0)
  78. MessageBoxW(NULL, tBig, L"WinMgmt", MB_OK);
  79. }
  80. //***************************************************************************
  81. //
  82. // int APIENTRY WinMain
  83. //
  84. // DESCRIPTION:
  85. //
  86. // Entry point for windows applications. If this is running under
  87. // NT, then this will run as a service, unless the "/EXE" command line
  88. // argument is used.
  89. //
  90. // PARAMETERS:
  91. //
  92. // hInstance Instance handle
  93. // hPrevInstance not used in win32
  94. // szCmdLine command line argument
  95. // nCmdShow how window is to be shown(ignored)
  96. //
  97. // RETURN VALUE:
  98. //
  99. // 0
  100. //***************************************************************************
  101. int APIENTRY WinMain(
  102. IN HINSTANCE hInstance,
  103. IN HINSTANCE hPrevInstance,
  104. IN LPSTR szCmdLine,
  105. IN int nCmdShow)
  106. {
  107. // This should not be uninitialized! It is here to prevent the class factory from being called during
  108. // shutdown.
  109. ghInstance = hInstance;
  110. DEBUGTRACE((LOG_WINMGMT,"\nStarting WinMgmt, ProcID = %x, CmdLine = %s", GetCurrentProcessId(), szCmdLine));
  111. if(szCmdLine && (szCmdLine[0] == '-' || szCmdLine[0] == '/' ))
  112. {
  113. if(!wbem_stricmp("RegServer",szCmdLine+1))
  114. return RegServer();
  115. else if(!wbem_stricmp("UnregServer",szCmdLine+1))
  116. return UnregServer();
  117. else if(!wbem_stricmp("kill",szCmdLine+1))
  118. {
  119. TerminateRunning();
  120. return 0;
  121. }
  122. else if (wbem_strnicmp("backup ", szCmdLine+1, strlen("backup ")) == 0)
  123. {
  124. return DoBackup();
  125. }
  126. else if (wbem_strnicmp("restore ", szCmdLine+1, strlen("restore ")) == 0)
  127. {
  128. return DoRestore();
  129. }
  130. else if(wbem_strnicmp("resyncperf", szCmdLine+1, strlen("resyncperf")) == 0)
  131. {
  132. DoResyncPerf();
  133. return 0;
  134. }
  135. else if(wbem_strnicmp("clearadap", szCmdLine+1, strlen("clearadap")) == 0)
  136. {
  137. DoClearAdap();
  138. return 0;
  139. }
  140. else if (0 == wbem_strnicmp("cncnt",szCmdLine+1,strlen("cnct")))
  141. {
  142. CHAR pNumber[16];
  143. StringCchPrintfA(pNumber, 16, "%d", RPC_C_AUTHN_LEVEL_CONNECT); // our OLD default
  144. return DoSetToAlone(pNumber);
  145. }
  146. else if (0 == wbem_strnicmp("pkt",szCmdLine+1, strlen("pkt")))
  147. {
  148. // NULL means default means PKT
  149. return DoSetToShared(NULL);
  150. }
  151. else if(0 == wbem_strnicmp("?", szCmdLine+1,strlen("?")))
  152. {
  153. DisplayMessage();
  154. return 0;
  155. }
  156. }
  157. return 0;
  158. }
  159. //***************************************************************************
  160. //
  161. // int RegServer
  162. //
  163. // DESCRIPTION:
  164. //
  165. // Self registers the dll.
  166. //
  167. //***************************************************************************
  168. typedef HRESULT (__stdcall * pfnDllRegisterServer)(void);
  169. DWORD RegServer()
  170. {
  171. HMODULE hMod = LoadLibraryExW(SERVICE_DLL,NULL,0);
  172. DWORD dwRes = 0;
  173. if (hMod)
  174. {
  175. pfnDllRegisterServer DllRegisterServer = (pfnDllRegisterServer)GetProcAddress(hMod,"DllRegisterServer");
  176. if(DllRegisterServer)
  177. {
  178. dwRes = DllRegisterServer();
  179. }
  180. else
  181. {
  182. dwRes = GetLastError();
  183. }
  184. FreeLibrary(hMod);
  185. }
  186. else
  187. {
  188. dwRes = GetLastError();
  189. }
  190. return dwRes;
  191. }
  192. //***************************************************************************
  193. //
  194. // int UnregServer
  195. //
  196. // DESCRIPTION:
  197. //
  198. // Unregisters the exe.
  199. //
  200. //***************************************************************************
  201. typedef HRESULT (__stdcall * pfnDllUnregisterServer)(void);
  202. DWORD UnregServer()
  203. {
  204. HMODULE hMod = LoadLibraryExW(SERVICE_DLL,NULL,0);
  205. DWORD dwRes = 0;
  206. if (hMod)
  207. {
  208. pfnDllUnregisterServer DllUnregisterServer = (pfnDllUnregisterServer)GetProcAddress(hMod,"DllUnregisterServer");
  209. if(DllUnregisterServer)
  210. {
  211. dwRes = DllUnregisterServer();
  212. }
  213. else
  214. {
  215. dwRes = GetLastError();
  216. }
  217. FreeLibrary(hMod);
  218. }
  219. else
  220. {
  221. dwRes = GetLastError();
  222. }
  223. return dwRes;
  224. }
  225. //
  226. //
  227. // move in a segregate svchost, to allow OLD connect level
  228. //
  229. ///////////////////////////////////////////////////////////
  230. typedef
  231. void (CALLBACK * pfnMoveToAlone)(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
  232. DWORD
  233. DoSetToAlone(CHAR * pszLevel)
  234. {
  235. HMODULE hMod = LoadLibraryExW(SERVICE_DLL,NULL,0);
  236. DWORD dwRes = 0;
  237. if (hMod)
  238. {
  239. pfnMoveToAlone MoveToAlone = (pfnMoveToAlone)GetProcAddress(hMod,"MoveToAlone");
  240. if(MoveToAlone)
  241. {
  242. MoveToAlone(NULL,hMod,pszLevel,0);
  243. }
  244. else
  245. {
  246. dwRes = GetLastError();
  247. }
  248. FreeLibrary(hMod);
  249. }
  250. else
  251. {
  252. dwRes = GetLastError();
  253. }
  254. return dwRes;
  255. };
  256. //
  257. //
  258. // move in a shares svchost
  259. //
  260. ///////////////////////////////////////////////////////////
  261. typedef
  262. void (CALLBACK * pfnMoveToShared)(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
  263. DWORD DoSetToShared(char * pszLevel)
  264. {
  265. HMODULE hMod = LoadLibraryExW(SERVICE_DLL,NULL,0);
  266. DWORD dwRes = 0;
  267. if (hMod)
  268. {
  269. pfnMoveToShared MoveToShared = (pfnMoveToAlone)GetProcAddress(hMod,"MoveToShared");
  270. if(MoveToShared)
  271. {
  272. MoveToShared(NULL,hMod,pszLevel,0);
  273. }
  274. else
  275. {
  276. dwRes = GetLastError();
  277. }
  278. FreeLibrary(hMod);
  279. }
  280. else
  281. {
  282. dwRes = GetLastError();
  283. }
  284. return dwRes;
  285. };
  286. //***************************************************************************
  287. //
  288. // int DoBackup
  289. //
  290. // DESCRIPTION:
  291. //
  292. // Calls into IWbemBackupRestore::Backup to backup the repository.
  293. //
  294. //***************************************************************************
  295. int DoBackup()
  296. {
  297. int hr = WBEM_S_NO_ERROR;
  298. //*************************************************
  299. // Split up command line and validate parameters
  300. //*************************************************
  301. wchar_t *wszCommandLine = GetCommandLineW();
  302. if (wszCommandLine == NULL)
  303. {
  304. hr = WBEM_E_OUT_OF_MEMORY;
  305. DisplayWbemError(hr, ID_ERROR_LONG, ID_ERROR_SHORT, ID_BACKUP_TITLE);
  306. }
  307. int nNumArgs = 0;
  308. wchar_t **wszCommandLineArgv = NULL;
  309. if (SUCCEEDED(hr))
  310. {
  311. wszCommandLineArgv = CommandLineToArgvW(wszCommandLine, &nNumArgs);
  312. if ((wszCommandLineArgv == NULL) || (nNumArgs != 3))
  313. {
  314. hr = WBEM_E_INVALID_PARAMETER;
  315. DisplayMessage();
  316. }
  317. }
  318. //wszCommandLineArgv[0] = winmgmt.exe
  319. //wszCommandLineArgv[1] = /backup
  320. //wszCommandLineArgv[2] = <backup filename>
  321. if (SUCCEEDED(hr))
  322. {
  323. InitializeCom();
  324. IWbemBackupRestore* pBackupRestore = NULL;
  325. hr = CoCreateInstance(CLSID_WbemBackupRestore, 0, CLSCTX_LOCAL_SERVER,
  326. IID_IWbemBackupRestore, (LPVOID *) &pBackupRestore);
  327. if (SUCCEEDED(hr))
  328. {
  329. EnablePrivilege(TOKEN_PROCESS,SE_BACKUP_NAME);
  330. hr = pBackupRestore->Backup(wszCommandLineArgv[2], 0);
  331. if (FAILED(hr))
  332. {
  333. DisplayWbemError(hr, ID_ERROR_LONG, ID_ERROR_SHORT, ID_BACKUP_TITLE);
  334. }
  335. pBackupRestore->Release();
  336. }
  337. else
  338. {
  339. DisplayWbemError(hr, ID_ERROR_LONG, ID_ERROR_SHORT, ID_BACKUP_TITLE);
  340. }
  341. CoUninitialize();
  342. }
  343. return hr;
  344. }
  345. //***************************************************************************
  346. //
  347. // int DoRestore
  348. //
  349. // DESCRIPTION:
  350. //
  351. // Calls into IWbemBackupRestore::Restore to restore the repository.
  352. //
  353. //***************************************************************************
  354. int DoRestore()
  355. {
  356. int hr = WBEM_S_NO_ERROR;
  357. //*************************************************
  358. // Split up command line and validate parameters
  359. //*************************************************
  360. wchar_t *wszCommandLine = GetCommandLineW();
  361. if (wszCommandLine == NULL)
  362. {
  363. hr = WBEM_E_OUT_OF_MEMORY;
  364. DisplayWbemError(hr, ID_ERROR_LONG, ID_ERROR_SHORT, ID_RESTORE_TITLE);
  365. }
  366. int nNumArgs = 0;
  367. wchar_t **wszCommandLineArgv = NULL;
  368. if (SUCCEEDED(hr))
  369. {
  370. wszCommandLineArgv = CommandLineToArgvW(wszCommandLine, &nNumArgs);
  371. if ((wszCommandLineArgv == NULL) || (nNumArgs != 4))
  372. {
  373. hr = WBEM_E_INVALID_PARAMETER;
  374. DisplayMessage();
  375. }
  376. }
  377. //wszCommandLineArgv[0] = winmgmt.exe
  378. //wszCommandLineArgv[1] = /restore
  379. //wszCommandLineArgv[2] = <restore filename>
  380. //wszcommandLineArgv[3] = <restore options>
  381. //*****************************************************
  382. // Validate restore option
  383. //*****************************************************
  384. if (SUCCEEDED(hr))
  385. {
  386. if ((wcscmp(wszCommandLineArgv[3], L"0") != 0) &&
  387. (wcscmp(wszCommandLineArgv[3], L"1") != 0))
  388. {
  389. hr = WBEM_E_INVALID_PARAMETER;
  390. DisplayMessage();
  391. }
  392. }
  393. long lFlags = 0;
  394. //*****************************************************
  395. // Retrieve restore option
  396. //*****************************************************
  397. if (SUCCEEDED(hr))
  398. {
  399. lFlags = (long) (*wszCommandLineArgv[3] - L'0');
  400. }
  401. //*****************************************************
  402. // Create the IWbemBackupRestore interface and get that
  403. // to do the restore for us...
  404. //*****************************************************
  405. if (SUCCEEDED(hr))
  406. {
  407. InitializeCom();
  408. IWbemBackupRestore* pBackupRestore = NULL;
  409. hr = CoCreateInstance(CLSID_WbemBackupRestore, 0, CLSCTX_LOCAL_SERVER,
  410. IID_IWbemBackupRestore, (LPVOID *) &pBackupRestore);
  411. if (SUCCEEDED(hr))
  412. {
  413. EnablePrivilege(TOKEN_PROCESS,SE_RESTORE_NAME);
  414. hr = pBackupRestore->Restore(wszCommandLineArgv[2], lFlags);
  415. if (FAILED(hr))
  416. {
  417. DisplayWbemError(hr, ID_ERROR_LONG, ID_ERROR_SHORT, ID_RESTORE_TITLE);
  418. }
  419. pBackupRestore->Release();
  420. }
  421. else
  422. {
  423. DisplayWbemError(hr, ID_ERROR_LONG, ID_ERROR_SHORT, ID_RESTORE_TITLE);
  424. }
  425. CoUninitialize();
  426. }
  427. //**************************************************
  428. //All done!
  429. //**************************************************
  430. return hr;
  431. }
  432. void DisplayWbemError(HRESULT hresError, DWORD dwLongFormatString, DWORD dwShortFormatString, DWORD dwTitle)
  433. {
  434. wchar_t* szError = new wchar_t[2096];
  435. if (!szError)
  436. return;
  437. CVectorDeleteMe<wchar_t> delme1(szError);
  438. szError[0] = 0;
  439. wchar_t* szFacility = new wchar_t[2096];
  440. if (!szFacility)
  441. return;
  442. CVectorDeleteMe<wchar_t> delme2(szFacility);
  443. szFacility[0] = 0;
  444. wchar_t* szMsg = new wchar_t[2096];
  445. if (!szMsg)
  446. return;
  447. CVectorDeleteMe<wchar_t> delme3(szMsg);
  448. szMsg[0] = 0;
  449. wchar_t* szFormat = new wchar_t[100];
  450. if (!szFormat)
  451. return;
  452. CVectorDeleteMe<wchar_t> delme4(szFormat);
  453. szFormat[0] = 0;
  454. wchar_t* szTitle = new wchar_t[100];
  455. if (!szTitle)
  456. return;
  457. CVectorDeleteMe<wchar_t> delme5(szTitle);
  458. szTitle[0] = 0;
  459. IWbemStatusCodeText * pStatus = NULL;
  460. SCODE sc = CoCreateInstance(CLSID_WbemStatusCodeText, 0, CLSCTX_INPROC_SERVER,
  461. IID_IWbemStatusCodeText, (LPVOID *) &pStatus);
  462. if(sc == S_OK)
  463. {
  464. BSTR bstr = 0;
  465. sc = pStatus->GetErrorCodeText(hresError, 0, 0, &bstr);
  466. if(sc == S_OK)
  467. {
  468. StringCchCopyW(szError, 2096, bstr);
  469. SysFreeString(bstr);
  470. bstr = 0;
  471. }
  472. sc = pStatus->GetFacilityCodeText(hresError, 0, 0, &bstr);
  473. if(sc == S_OK)
  474. {
  475. StringCchCopyW(szFacility, 2096, bstr);
  476. SysFreeString(bstr);
  477. bstr = 0;
  478. }
  479. pStatus->Release();
  480. }
  481. if(wcslen(szFacility) == 0 || wcslen(szError) == 0)
  482. {
  483. if (LoadStringW(GetModuleHandle(NULL), dwShortFormatString, szFormat, 100))
  484. StringCchPrintfW(szMsg, 2096, szFormat, hresError);
  485. }
  486. else
  487. {
  488. if (LoadStringW(GetModuleHandle(NULL), dwLongFormatString, szFormat, 100))
  489. StringCchPrintfW(szMsg, 2095, szFormat, hresError, szFacility, szError);
  490. }
  491. LoadStringW(GetModuleHandle(NULL), dwTitle, szTitle, 100);
  492. MessageBoxW(0, szMsg, szTitle, MB_ICONERROR | MB_OK);
  493. }
  494. void DoResyncPerf()
  495. {
  496. PROCESS_INFORMATION pi;
  497. STARTUPINFO si;
  498. memset(&si, 0, sizeof(si));
  499. si.cb = sizeof(si);
  500. si.dwFlags = STARTF_FORCEOFFFEEDBACK;
  501. // Get the appropriate cmdline and attach the proper command line switches
  502. LPTSTR pCmdLine = GetWMIADAPCmdLine( 64 );
  503. CVectorDeleteMe<TCHAR> vdm( pCmdLine );
  504. if ( NULL == pCmdLine )
  505. {
  506. return;
  507. }
  508. wchar_t pPassedCmdLine[64];
  509. StringCchCopyW(pPassedCmdLine, 64, L"wmiadap.exe /F");
  510. if ( CreateProcessW( pCmdLine, pPassedCmdLine, NULL, NULL, FALSE, CREATE_NO_WINDOW,
  511. NULL, NULL, &si, &pi ) )
  512. {
  513. // Cleanup handles right away
  514. // ==========================
  515. CloseHandle( pi.hThread );
  516. CloseHandle( pi.hProcess );
  517. }
  518. return;
  519. }
  520. void DoClearAdap()
  521. {
  522. PROCESS_INFORMATION pi;
  523. STARTUPINFO si;
  524. memset(&si, 0, sizeof(si));
  525. si.cb = sizeof(si);
  526. si.dwFlags = STARTF_FORCEOFFFEEDBACK;
  527. // Get the appropriate cmdline and attach the proper command line switches
  528. LPTSTR pCmdLine = GetWMIADAPCmdLine( 64 );
  529. CVectorDeleteMe<TCHAR> vdm( pCmdLine );
  530. if ( NULL == pCmdLine )
  531. {
  532. return;
  533. }
  534. wchar_t pPassedCmdLine[64];
  535. StringCchCopyW(pPassedCmdLine, 64, L"wmiadap.exe /C");
  536. if ( CreateProcessW( pCmdLine, pPassedCmdLine, NULL, NULL, FALSE, CREATE_NO_WINDOW,
  537. NULL, NULL, &si, &pi) )
  538. {
  539. // Cleanup handles right away
  540. // ==========================
  541. CloseHandle( pi.hThread );
  542. CloseHandle( pi.hProcess );
  543. }
  544. return;
  545. }