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.

632 lines
18 KiB

  1. /****************************************************************************
  2. Copyright information : Copyright (c) 1998-1999 Microsoft Corporation
  3. File Name : wcmain.cpp
  4. Project Name : WMI Command Line
  5. Author Name : Ch. Sriramachandramurthy
  6. Date of Creation (dd/mm/yy) : 27th-September-2000
  7. Version Number : 1.0
  8. Brief Description : The _tmain function is the entry point of the
  9. WMICli program.
  10. Revision History :
  11. Last Modified by :Biplab Mistry
  12. Last Modified date :4/11/00
  13. ****************************************************************************/
  14. // wcmain.cpp :main function implementation file
  15. #include "Precomp.h"
  16. #include "CommandSwitches.h"
  17. #include "GlobalSwitches.h"
  18. #include "HelpInfo.h"
  19. #include "ErrorLog.h"
  20. #include "ParsedInfo.h"
  21. #include "CmdTokenizer.h"
  22. #include "CmdAlias.h"
  23. #include "ParserEngine.h"
  24. #include "ExecEngine.h"
  25. #include "ErrorInfo.h"
  26. #include "WmiCliXMLLog.h"
  27. #include "FormatEngine.h"
  28. #include "WmiCmdLn.h"
  29. #include <string>
  30. #include <ScopeGuard.h>
  31. CWMICommandLine g_wmiCmd;
  32. wstring g_pszBuffer;
  33. //
  34. // COM initialization
  35. //
  36. class COMInitializator
  37. {
  38. protected:
  39. BOOL m_bIsInitialized ;
  40. public :
  41. COMInitializator ( ) : m_bIsInitialized ( FALSE )
  42. {
  43. // Initialize the COM library
  44. if ( SUCCEEDED ( CoInitializeEx(NULL, COINIT_MULTITHREADED) ) )
  45. {
  46. m_bIsInitialized = TRUE ;
  47. }
  48. }
  49. ~COMInitializator ()
  50. {
  51. if ( TRUE == m_bIsInitialized )
  52. {
  53. CoUninitialize () ;
  54. }
  55. }
  56. BOOL IsInitialized () const
  57. {
  58. return m_bIsInitialized ;
  59. }
  60. };
  61. /*------------------------------------------------------------------------
  62. Name :_tmain
  63. Synopsis :This function takes the error code as input and return
  64. an error string
  65. Type :Member Function
  66. Input parameters :
  67. argc :argument count
  68. argv :Pointer to string array storing command line arguments
  69. Output parameters :None
  70. Return Type :Integer
  71. Global Variables :None
  72. Calling Syntax :
  73. Calls :CWMICommandLine::Initialize,
  74. CWMICommandLine::UnInitialize,
  75. CFormatEngine::DisplayResults,
  76. CWMICommandLine::ProcessCommandAndDisplayResults
  77. Called by :None
  78. Notes :None
  79. ------------------------------------------------------------------------*/
  80. __cdecl _tmain(WMICLIINT argc, _TCHAR **argv)
  81. {
  82. SESSIONRETCODE ssnRetCode = SESSION_SUCCESS;
  83. BOOL bFileEmpty = FALSE;
  84. bool bIndirectionInput = false;
  85. FILE *fpInputFile = NULL;
  86. WMICLIUINT uErrLevel = 0;
  87. try
  88. {
  89. //
  90. // initialization
  91. //
  92. COMInitializator InitCOM;
  93. if ( InitCOM.IsInitialized () )
  94. {
  95. _bstr_t bstrBuf;
  96. if (g_wmiCmd.GetCtrlHandlerError())
  97. {
  98. g_wmiCmd.SetCtrlHandlerError(FALSE);
  99. //Set the sucess flag to FALSE
  100. g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().
  101. SetSuccessFlag(FALSE);
  102. ssnRetCode = SESSION_ERROR;
  103. g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
  104. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  105. }
  106. else if ( g_wmiCmd.Initialize () )
  107. {
  108. ON_BLOCK_EXIT_OBJ ( g_wmiCmd, CWMICommandLine::Uninitialize ) ;
  109. HANDLE hStd=GetStdHandle(STD_INPUT_HANDLE);
  110. if(hStd != (HANDLE)0x00000003 && hStd != INVALID_HANDLE_VALUE && hStd != (HANDLE)0x0000000f)
  111. {
  112. if (!(g_wmiCmd.ReadXMLOrBatchFile(hStd)) || (fpInputFile = _tfopen(TEMP_BATCH_FILE, _T("r"))) == NULL)
  113. {
  114. g_wmiCmd.SetSessionErrorLevel(SESSION_ERROR);
  115. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  116. return uErrLevel;
  117. }
  118. bIndirectionInput = true;
  119. }
  120. ON_BLOCK_EXIT_IF ( bIndirectionInput, fclose, fpInputFile ) ;
  121. ON_BLOCK_EXIT_IF ( bIndirectionInput, DeleteFile, TEMP_BATCH_FILE ) ;
  122. // If no command line arguments are specified.
  123. if (argc == 1)
  124. {
  125. BOOL bSuccessScreen = TRUE;
  126. if ( hStd != (HANDLE)0x00000013 )
  127. {
  128. // avoid setting screen buffer for telnet
  129. bSuccessScreen = g_wmiCmd.ScreenBuffer ();
  130. }
  131. while (TRUE)
  132. {
  133. OUTPUTSPEC opsOutOpt = g_wmiCmd.GetParsedInfoObject().
  134. GetGlblSwitchesObject().
  135. GetOutputOrAppendOption(TRUE);
  136. OUTPUTSPEC opsSavedOutOpt = opsOutOpt;
  137. CHString chsSavedOutFileName;
  138. if ( opsSavedOutOpt == FILEOUTPUT )
  139. chsSavedOutFileName =
  140. g_wmiCmd.GetParsedInfoObject().
  141. GetGlblSwitchesObject().
  142. GetOutputOrAppendFileName(TRUE);
  143. // Make propmt to be diplayed to stdout.
  144. if ( opsOutOpt != STDOUT )
  145. {
  146. g_wmiCmd.GetParsedInfoObject().
  147. GetGlblSwitchesObject().
  148. SetOutputOrAppendOption(STDOUT, TRUE);
  149. }
  150. // Preserve append file pointer.
  151. FILE* fpAppend =
  152. g_wmiCmd.GetParsedInfoObject().
  153. GetGlblSwitchesObject().
  154. GetOutputOrAppendFilePointer(FALSE);
  155. // Set append file pointer = null.
  156. g_wmiCmd.GetParsedInfoObject().
  157. GetGlblSwitchesObject().
  158. SetOutputOrAppendFilePointer(NULL, FALSE);
  159. //Set Interactive Mode ON
  160. g_wmiCmd.GetParsedInfoObject().
  161. GetGlblSwitchesObject().
  162. SetInteractiveMode(TRUE);
  163. // Display the prompt;
  164. bstrBuf = _bstr_t(EXEC_NAME);
  165. bstrBuf += _bstr_t(":");
  166. bstrBuf += _bstr_t(g_wmiCmd.GetParsedInfoObject().
  167. GetGlblSwitchesObject().GetRole());
  168. bstrBuf += _bstr_t(">");
  169. DisplayMessage(bstrBuf, CP_OEMCP, FALSE, FALSE);
  170. // To handle Ctrl+C at propmt, Start accepting command
  171. g_wmiCmd.SetAcceptCommand(TRUE);
  172. // To handle batch input from file.
  173. _TCHAR *pBuf = NULL;
  174. while(TRUE)
  175. {
  176. WCHAR* buffer = NULL ;
  177. if ( NULL != ( buffer = new WCHAR [ MAX_BUFFER ] ) )
  178. {
  179. ScopeGuard bufferAuto = MakeGuard ( deleteArray < WCHAR >, ByRef ( buffer ) ) ;
  180. if ( bIndirectionInput == true )
  181. {
  182. pBuf = _fgetts(buffer, MAX_BUFFER-1, fpInputFile);
  183. }
  184. else
  185. {
  186. pBuf = _fgetts(buffer, MAX_BUFFER-1, stdin);
  187. }
  188. if(pBuf != NULL)
  189. {
  190. //
  191. // fgetws applies mbtowc to each byte
  192. // prior to returning wide string
  193. //
  194. //
  195. // wmic must revert and provide correct conversion
  196. //
  197. LPSTR pszBuffer = NULL ;
  198. if ( Revert_mbtowc ( buffer, &pszBuffer ) )
  199. {
  200. ScopeGuard pszBufferAuto = MakeGuard ( deleteArray < CHAR >, pszBuffer ) ;
  201. LPWSTR wszBuffer = NULL ;
  202. ScopeGuard wszBufferAuto = MakeGuard ( deleteArray < WCHAR >, ByRef ( wszBuffer ) ) ;
  203. if ( ConvertMBCSToWC ( pszBuffer, (LPVOID*) &wszBuffer, CP_OEMCP ) )
  204. {
  205. g_pszBuffer = wszBuffer ;
  206. }
  207. else
  208. {
  209. // Set the bFileEmpty flag to TRUE to break main loop
  210. bFileEmpty = TRUE;
  211. ssnRetCode = SESSION_ERROR;
  212. g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().SetErrataCode(OUT_OF_MEMORY);
  213. g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
  214. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  215. break ;
  216. }
  217. }
  218. else
  219. {
  220. // Set the bFileEmpty flag to TRUE to break main loop
  221. bFileEmpty = TRUE;
  222. ssnRetCode = SESSION_ERROR;
  223. g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().SetErrataCode(OUT_OF_MEMORY);
  224. g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
  225. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  226. break ;
  227. }
  228. if ( bIndirectionInput == true )
  229. {
  230. DisplayMessage ( g_pszBuffer.begin (), CP_OEMCP, FALSE, FALSE ) ;
  231. }
  232. LONG lInStrLen = g_pszBuffer.size();
  233. if(g_pszBuffer[lInStrLen - 1] == _T('\n'))
  234. g_pszBuffer[lInStrLen - 1] = _T('\0');
  235. break;
  236. }
  237. else
  238. {
  239. // Set the bFileEmpty flag to TRUE
  240. bFileEmpty = TRUE;
  241. break;
  242. }
  243. }
  244. else
  245. {
  246. // Set the bFileEmpty flag to TRUE to break main loop
  247. bFileEmpty = TRUE;
  248. ssnRetCode = SESSION_ERROR;
  249. g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().SetErrataCode(OUT_OF_MEMORY);
  250. g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
  251. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  252. break ;
  253. }
  254. }
  255. // To handle Ctrl+C at propmt, End accepting command
  256. // and start of executing command
  257. g_wmiCmd.SetAcceptCommand(FALSE);
  258. // Set append file pointer = saved.
  259. g_wmiCmd.GetParsedInfoObject().
  260. GetGlblSwitchesObject().
  261. SetOutputOrAppendFilePointer(fpAppend, FALSE);
  262. // Redirect the output back to file specified.
  263. if ( opsOutOpt != STDOUT )
  264. {
  265. g_wmiCmd.GetParsedInfoObject().
  266. GetGlblSwitchesObject().
  267. SetOutputOrAppendOption(opsOutOpt, TRUE);
  268. }
  269. // Set the error level to success.
  270. g_wmiCmd.SetSessionErrorLevel(SESSION_SUCCESS);
  271. // If all the commands in the batch file got executed.
  272. if (bFileEmpty)
  273. {
  274. break;
  275. }
  276. // Set Break Event to False
  277. g_wmiCmd.SetBreakEvent(FALSE);
  278. // Clear the clipboard.
  279. g_wmiCmd.EmptyClipBoardBuffer();
  280. // Process the command and display results.
  281. ssnRetCode = g_wmiCmd.ProcessCommandAndDisplayResults ( g_pszBuffer.begin () );
  282. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  283. // Break the loop if "QUIT" keyword is keyed-in.
  284. if(ssnRetCode == SESSION_QUIT)
  285. {
  286. break;
  287. }
  288. opsOutOpt = g_wmiCmd.GetParsedInfoObject().
  289. GetGlblSwitchesObject().
  290. GetOutputOrAppendOption(TRUE);
  291. if ( opsOutOpt == CLIPBOARD )
  292. CopyToClipBoard(g_wmiCmd.GetClipBoardBuffer());
  293. if ( ( opsOutOpt != FILEOUTPUT &&
  294. CloseOutputFile() == FALSE ) ||
  295. CloseAppendFile() == FALSE )
  296. {
  297. break;
  298. }
  299. if ( g_wmiCmd.GetParsedInfoObject().
  300. GetCmdSwitchesObject().
  301. GetOutputSwitchFlag() == TRUE )
  302. {
  303. if ( opsOutOpt == FILEOUTPUT &&
  304. CloseOutputFile() == FALSE )
  305. {
  306. break;
  307. }
  308. g_wmiCmd.GetParsedInfoObject().
  309. GetCmdSwitchesObject().
  310. SetOutputSwitchFlag(FALSE);
  311. if ( opsOutOpt == FILEOUTPUT )
  312. g_wmiCmd.GetParsedInfoObject().
  313. GetGlblSwitchesObject().
  314. SetOutputOrAppendFileName(NULL, TRUE);
  315. g_wmiCmd.GetParsedInfoObject().
  316. GetGlblSwitchesObject().
  317. SetOutputOrAppendOption(opsSavedOutOpt, TRUE);
  318. if ( opsSavedOutOpt == FILEOUTPUT )
  319. g_wmiCmd.GetParsedInfoObject().
  320. GetGlblSwitchesObject().
  321. SetOutputOrAppendFileName(
  322. _bstr_t((LPCWSTR)chsSavedOutFileName),
  323. TRUE);
  324. }
  325. }
  326. if ( hStd != (HANDLE)0x00000013 )
  327. {
  328. // avoid re-setting screen buffer for telnet
  329. bSuccessScreen = g_wmiCmd.ScreenBuffer ( FALSE );
  330. }
  331. }
  332. // If command line arguments are specified.
  333. else
  334. {
  335. // Obtain the command line string
  336. g_pszBuffer = GetCommandLine();
  337. if ( FALSE == g_pszBuffer.empty() )
  338. {
  339. // Set the error level to success.
  340. g_wmiCmd.SetSessionErrorLevel(SESSION_SUCCESS);
  341. // Process the command and display results.
  342. wstring::iterator BufferIter = g_pszBuffer.begin () ;
  343. while( BufferIter != g_pszBuffer.end() )
  344. {
  345. if ( *BufferIter == L' ' )
  346. {
  347. break ;
  348. }
  349. BufferIter++ ;
  350. }
  351. if ( BufferIter != g_pszBuffer.end () )
  352. {
  353. ssnRetCode = g_wmiCmd.ProcessCommandAndDisplayResults ( BufferIter ) ;
  354. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  355. OUTPUTSPEC opsOutOpt;
  356. opsOutOpt = g_wmiCmd.GetParsedInfoObject().
  357. GetGlblSwitchesObject().
  358. GetOutputOrAppendOption(TRUE);
  359. if ( opsOutOpt == CLIPBOARD )
  360. CopyToClipBoard(g_wmiCmd.GetClipBoardBuffer());
  361. }
  362. }
  363. }
  364. }
  365. }
  366. else
  367. {
  368. // If COM error.
  369. if (g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().GetCOMError())
  370. {
  371. g_wmiCmd.GetFormatObject().DisplayResults(g_wmiCmd.GetParsedInfoObject());
  372. }
  373. g_wmiCmd.SetSessionErrorLevel ( SESSION_ERROR ) ;
  374. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  375. }
  376. }
  377. catch(...)
  378. {
  379. g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().SetErrataCode(UNKNOWN_ERROR);
  380. g_wmiCmd.SetSessionErrorLevel(SESSION_ERROR);
  381. DisplayString(IDS_E_WMIC_UNKNOWN_ERROR, CP_OEMCP, NULL, TRUE, TRUE);
  382. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  383. }
  384. return uErrLevel;
  385. }
  386. /*------------------------------------------------------------------------
  387. Name :CtrlHandler
  388. Synopsis :Handler routine to handle CTRL + C so as free
  389. the memory allocated during the program execution.
  390. Type :Global Function
  391. Input parameters :
  392. fdwCtrlType - control handler type
  393. Output parameters :None
  394. Return Type :BOOL
  395. Global Variables :
  396. g_wmiCmd - wmi command line object
  397. Notes :None
  398. ------------------------------------------------------------------------*/
  399. BOOL CtrlHandler(DWORD fdwCtrlType)
  400. {
  401. BOOL bRet = FALSE;
  402. COMInitializator InitCOM ;
  403. if ( InitCOM.IsInitialized () )
  404. {
  405. switch (fdwCtrlType)
  406. {
  407. case CTRL_C_EVENT:
  408. // if at command propmt
  409. if ( g_wmiCmd.GetAcceptCommand() == TRUE )
  410. {
  411. g_wmiCmd.Uninitialize();
  412. bRet = FALSE;
  413. }
  414. else // executing command
  415. {
  416. g_wmiCmd.SetBreakEvent(TRUE);
  417. bRet = TRUE;
  418. }
  419. break;
  420. case CTRL_CLOSE_EVENT:
  421. default:
  422. g_wmiCmd.Uninitialize();
  423. bRet = FALSE;
  424. break;
  425. }
  426. }
  427. return bRet;
  428. }
  429. /*------------------------------------------------------------------------
  430. Name :CloseOutputFile
  431. Synopsis :Close the output file.
  432. Type :Global Function
  433. Input parameters :None
  434. Output parameters :None
  435. Return Type :BOOL
  436. Global Variables :
  437. g_wmiCmd - wmi command line object
  438. Calling Syntax :CloseOutputFile()
  439. Notes :None
  440. ------------------------------------------------------------------------*/
  441. BOOL CloseOutputFile()
  442. {
  443. BOOL bRet = TRUE;
  444. // TRUE for getting output file pointer.
  445. FILE* fpOutputFile =
  446. g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
  447. GetOutputOrAppendFilePointer(TRUE);
  448. // If currently output is going to file close the file.
  449. if ( fpOutputFile != NULL )
  450. {
  451. if ( fclose(fpOutputFile) == EOF )
  452. {
  453. DisplayString(IDS_E_CLOSE_OUT_FILE_ERROR, CP_OEMCP,
  454. NULL, TRUE, TRUE);
  455. bRet = FALSE;
  456. }
  457. else // TRUE for setting output file pointer.
  458. g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
  459. SetOutputOrAppendFilePointer(NULL, TRUE);
  460. }
  461. return bRet;
  462. }
  463. /*------------------------------------------------------------------------
  464. Name :CloseAppendFile
  465. Synopsis :Close the append file.
  466. Type :Global Function
  467. Input parameters :None
  468. Output parameters :None
  469. Return Type :BOOL
  470. Global Variables :
  471. g_wmiCmd - wmi command line object
  472. Calling Syntax :CloseAppendFile()
  473. Notes :None
  474. ------------------------------------------------------------------------*/
  475. BOOL CloseAppendFile()
  476. {
  477. BOOL bRet = TRUE;
  478. // FALSE for getting append file pointer.
  479. FILE* fpAppendFile =
  480. g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
  481. GetOutputOrAppendFilePointer(FALSE);
  482. if ( fpAppendFile != NULL )
  483. {
  484. if ( fclose(fpAppendFile) == EOF )
  485. {
  486. DisplayString(IDS_E_CLOSE_APPEND_FILE_ERROR, CP_OEMCP,
  487. NULL, TRUE, TRUE);
  488. bRet = FALSE;
  489. }
  490. else // FASLE for setting output file pointer.
  491. g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
  492. SetOutputOrAppendFilePointer(NULL, FALSE);
  493. }
  494. return bRet;
  495. }
  496. /*------------------------------------------------------------------------
  497. Name :CopyToClipBoard
  498. Synopsis :Copy data to clip board.
  499. Type :Global Function
  500. Input parameters :
  501. chsClipBoardBuffer - reference to object of type CHString.
  502. Output parameters :None
  503. Return Type :void
  504. Global Variables :None
  505. Calling Syntax :CopyToClipBoard(chsClipBoardBuffer)
  506. Notes :None
  507. ------------------------------------------------------------------------*/
  508. void CopyToClipBoard(CHString& chsClipBoardBuffer)
  509. {
  510. HGLOBAL hMem = CopyStringToHGlobal((LPCWSTR)chsClipBoardBuffer);
  511. if (hMem != NULL)
  512. {
  513. if (OpenClipboard(NULL))
  514. {
  515. EmptyClipboard();
  516. SetClipboardData(CF_UNICODETEXT, hMem);
  517. CloseClipboard();
  518. }
  519. else
  520. GlobalFree(hMem); //We must clean up.
  521. }
  522. }
  523. /*------------------------------------------------------------------------
  524. Name :CopyStringToHGlobal
  525. Synopsis :Copy string to global memory.
  526. Type :Global Function
  527. Input parameters :
  528. psz - LPCWSTR type, specifying string to get memory allocated.
  529. Output parameters :None
  530. Return Type :HGLOBAL
  531. Global Variables :None
  532. Calling Syntax :CopyStringToHGlobal(psz)
  533. Notes :None
  534. ------------------------------------------------------------------------*/
  535. HGLOBAL CopyStringToHGlobal(LPCWSTR psz)
  536. {
  537. HGLOBAL hMem;
  538. LPTSTR pszDst;
  539. hMem = GlobalAlloc(GHND, (DWORD) (lstrlen(psz)+1) * sizeof(TCHAR));
  540. if (hMem != NULL)
  541. {
  542. pszDst = (LPTSTR) GlobalLock(hMem);
  543. lstrcpy(pszDst, psz);
  544. GlobalUnlock(hMem);
  545. }
  546. return hMem;
  547. }