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.

505 lines
14 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. CWMICommandLine g_wmiCmd;
  30. _TCHAR* g_pszBuffer = NULL;
  31. /*------------------------------------------------------------------------
  32. Name :_tmain
  33. Synopsis :This function takes the error code as input and return
  34. an error string
  35. Type :Member Function
  36. Input parameters :
  37. argc :argument count
  38. argv :Pointer to string array storing command line arguments
  39. Output parameters :None
  40. Return Type :Integer
  41. Global Variables :None
  42. Calling Syntax :
  43. Calls :CWMICommandLine::Initialize,
  44. CWMICommandLine::UnInitialize,
  45. CFormatEngine::DisplayResults,
  46. CWMICommandLine::ProcessCommandAndDisplayResults
  47. Called by :None
  48. Notes :None
  49. ------------------------------------------------------------------------*/
  50. __cdecl _tmain(WMICLIINT argc, _TCHAR **argv)
  51. {
  52. SESSIONRETCODE ssnRetCode = SESSION_SUCCESS;
  53. BOOL bFileEmpty = FALSE;
  54. BOOL bIndirectionInput = FALSE;
  55. FILE *fpInputFile = NULL;
  56. WMICLIUINT uErrLevel = 0;
  57. try
  58. {
  59. _bstr_t bstrBuf;
  60. // Initailize the CWMICommandLine object.
  61. if (g_wmiCmd.Initialize())
  62. {
  63. HANDLE hStd=GetStdHandle(STD_INPUT_HANDLE);
  64. if(hStd != (HANDLE)0x00000003 && hStd != INVALID_HANDLE_VALUE &&
  65. hStd != (HANDLE)0x0000000f)
  66. {
  67. if (!(g_wmiCmd.ReadXMLOrBatchFile(hStd)) ||
  68. (fpInputFile = _tfopen(TEMP_BATCH_FILE, _T("r"))) == NULL)
  69. {
  70. g_wmiCmd.SetSessionErrorLevel(SESSION_ERROR);
  71. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  72. g_wmiCmd.Uninitialize();
  73. return uErrLevel;
  74. }
  75. bIndirectionInput = TRUE;
  76. }
  77. // If no command line arguments are specified.
  78. if (argc == 1)
  79. {
  80. // Allocate memory for the g_pszBuffer
  81. g_pszBuffer = new _TCHAR[MAX_BUFFER];
  82. // If memory allocation successfull
  83. if (g_pszBuffer)
  84. {
  85. while (TRUE)
  86. {
  87. OUTPUTSPEC opsOutOpt = g_wmiCmd.GetParsedInfoObject().
  88. GetGlblSwitchesObject().
  89. GetOutputOrAppendOption(TRUE);
  90. OUTPUTSPEC opsSavedOutOpt = opsOutOpt;
  91. CHString chsSavedOutFileName;
  92. if ( opsSavedOutOpt == FILEOUTPUT )
  93. chsSavedOutFileName =
  94. g_wmiCmd.GetParsedInfoObject().
  95. GetGlblSwitchesObject().
  96. GetOutputOrAppendFileName(TRUE);
  97. // Make propmt to be diplayed to stdout.
  98. if ( opsOutOpt != STDOUT )
  99. {
  100. g_wmiCmd.GetParsedInfoObject().
  101. GetGlblSwitchesObject().
  102. SetOutputOrAppendOption(STDOUT, TRUE);
  103. }
  104. // Preserve append file pointer.
  105. FILE* fpAppend =
  106. g_wmiCmd.GetParsedInfoObject().
  107. GetGlblSwitchesObject().
  108. GetOutputOrAppendFilePointer(FALSE);
  109. // Set append file pointer = null.
  110. g_wmiCmd.GetParsedInfoObject().
  111. GetGlblSwitchesObject().
  112. SetOutputOrAppendFilePointer(NULL, FALSE);
  113. // Display the prompt;
  114. bstrBuf = _bstr_t(EXEC_NAME);
  115. bstrBuf += _bstr_t(":");
  116. bstrBuf += _bstr_t(g_wmiCmd.GetParsedInfoObject().
  117. GetGlblSwitchesObject().GetRole());
  118. bstrBuf += _bstr_t(">");
  119. DisplayMessage(bstrBuf, CP_OEMCP, FALSE, FALSE);
  120. // To handle Ctrl+C at propmt, Start accepting command
  121. g_wmiCmd.SetAcceptCommand(TRUE);
  122. // To handle batch input from file.
  123. _TCHAR *pBuf = NULL;
  124. while(TRUE)
  125. {
  126. if ( bIndirectionInput == TRUE )
  127. pBuf = _fgetts(g_pszBuffer, MAX_BUFFER-1,
  128. fpInputFile);
  129. else
  130. pBuf = _fgetts(g_pszBuffer, MAX_BUFFER-1, stdin);
  131. if(pBuf != NULL)
  132. {
  133. if ( bIndirectionInput == TRUE )
  134. {
  135. DisplayMessage(g_pszBuffer, CP_OEMCP,
  136. FALSE, FALSE);
  137. }
  138. LONG lInStrLen = lstrlen(g_pszBuffer);
  139. if(g_pszBuffer[lInStrLen - 1] == _T('\n'))
  140. g_pszBuffer[lInStrLen - 1] = _T('\0');
  141. break;
  142. }
  143. // Indicates end of file
  144. if (pBuf == NULL)
  145. {
  146. // Set the bFileEmpty flag to TRUE
  147. bFileEmpty = TRUE;
  148. break;
  149. }
  150. }
  151. // To handle Ctrl+C at propmt, End accepting command
  152. // and start of executing command
  153. g_wmiCmd.SetAcceptCommand(FALSE);
  154. // Set append file pointer = saved.
  155. g_wmiCmd.GetParsedInfoObject().
  156. GetGlblSwitchesObject().
  157. SetOutputOrAppendFilePointer(fpAppend, FALSE);
  158. // Redirect the output back to file specified.
  159. if ( opsOutOpt != STDOUT )
  160. {
  161. g_wmiCmd.GetParsedInfoObject().
  162. GetGlblSwitchesObject().
  163. SetOutputOrAppendOption(opsOutOpt, TRUE);
  164. }
  165. // Set the error level to success.
  166. g_wmiCmd.SetSessionErrorLevel(SESSION_SUCCESS);
  167. // If all the commands in the batch file got executed.
  168. if (bFileEmpty)
  169. {
  170. SAFEDELETE(g_pszBuffer);
  171. break;
  172. }
  173. // Set Break Event to False
  174. g_wmiCmd.SetBreakEvent(FALSE);
  175. // Clear the clipboard.
  176. g_wmiCmd.EmptyClipBoardBuffer();
  177. // Process the command and display results.
  178. ssnRetCode = g_wmiCmd.ProcessCommandAndDisplayResults
  179. (g_pszBuffer);
  180. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  181. // Break the loop if "QUIT" keyword is keyed-in.
  182. if(ssnRetCode == SESSION_QUIT)
  183. {
  184. SAFEDELETE(g_pszBuffer);
  185. break;
  186. }
  187. opsOutOpt = g_wmiCmd.GetParsedInfoObject().
  188. GetGlblSwitchesObject().
  189. GetOutputOrAppendOption(TRUE);
  190. if ( opsOutOpt == CLIPBOARD )
  191. CopyToClipBoard(g_wmiCmd.GetClipBoardBuffer());
  192. if ( ( opsOutOpt != FILEOUTPUT &&
  193. CloseOutputFile() == FALSE ) ||
  194. CloseAppendFile() == FALSE )
  195. {
  196. SAFEDELETE(g_pszBuffer);
  197. break;
  198. }
  199. if ( g_wmiCmd.GetParsedInfoObject().
  200. GetCmdSwitchesObject().
  201. GetOutputSwitchFlag() == TRUE )
  202. {
  203. if ( opsOutOpt == FILEOUTPUT &&
  204. CloseOutputFile() == FALSE )
  205. {
  206. SAFEDELETE(g_pszBuffer);
  207. break;
  208. }
  209. g_wmiCmd.GetParsedInfoObject().
  210. GetCmdSwitchesObject().
  211. SetOutputSwitchFlag(FALSE);
  212. if ( opsOutOpt == FILEOUTPUT )
  213. g_wmiCmd.GetParsedInfoObject().
  214. GetGlblSwitchesObject().
  215. SetOutputOrAppendFileName(NULL, TRUE);
  216. g_wmiCmd.GetParsedInfoObject().
  217. GetGlblSwitchesObject().
  218. SetOutputOrAppendOption(opsSavedOutOpt
  219. , TRUE);
  220. if ( opsSavedOutOpt == FILEOUTPUT )
  221. g_wmiCmd.GetParsedInfoObject().
  222. GetGlblSwitchesObject().
  223. SetOutputOrAppendFileName(
  224. _bstr_t((LPCWSTR)chsSavedOutFileName),
  225. TRUE);
  226. }
  227. }
  228. }
  229. else
  230. {
  231. ssnRetCode = SESSION_ERROR;
  232. g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().
  233. SetErrataCode(OUT_OF_MEMORY);
  234. g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
  235. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  236. }
  237. }
  238. // If command line arguments are specified.
  239. else
  240. {
  241. // Obtain the command line string
  242. g_pszBuffer = GetCommandLine();
  243. if (g_pszBuffer != NULL)
  244. {
  245. // Set the error level to success.
  246. g_wmiCmd.SetSessionErrorLevel(SESSION_SUCCESS);
  247. // Process the command and display results.
  248. while( *(++g_pszBuffer) != _T(' '));
  249. ssnRetCode = g_wmiCmd.ProcessCommandAndDisplayResults(g_pszBuffer);
  250. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  251. }
  252. }
  253. // Call the uninitialize function of the CWMICommandLine object.
  254. g_wmiCmd.Uninitialize();
  255. if ( bIndirectionInput == TRUE )
  256. {
  257. fclose(fpInputFile);
  258. DeleteFile(TEMP_BATCH_FILE);
  259. }
  260. }
  261. else
  262. {
  263. ssnRetCode = SESSION_ERROR;
  264. // If COM error.
  265. if (g_wmiCmd.GetParsedInfoObject().
  266. GetCmdSwitchesObject().GetCOMError())
  267. {
  268. g_wmiCmd.GetFormatObject().
  269. DisplayResults(g_wmiCmd.GetParsedInfoObject());
  270. }
  271. g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
  272. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  273. g_wmiCmd.Uninitialize();
  274. }
  275. }
  276. catch(...)
  277. {
  278. ssnRetCode = SESSION_ERROR;
  279. g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().
  280. SetErrataCode(UNKNOWN_ERROR);
  281. g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
  282. DisplayString(IDS_E_WMIC_UNKNOWN_ERROR, CP_OEMCP,
  283. NULL, TRUE, TRUE);
  284. uErrLevel = g_wmiCmd.GetSessionErrorLevel();
  285. g_wmiCmd.Uninitialize();
  286. SAFEDELETE(g_pszBuffer);
  287. if ( bIndirectionInput == TRUE )
  288. {
  289. fclose(fpInputFile);
  290. DeleteFile(TEMP_BATCH_FILE);
  291. }
  292. }
  293. return uErrLevel;
  294. }
  295. /*------------------------------------------------------------------------
  296. Name :CtrlHandler
  297. Synopsis :Handler routine to handle CTRL + C so as free
  298. the memory allocated during the program execution.
  299. Type :Global Function
  300. Input parameters :
  301. fdwCtrlType - control handler type
  302. Output parameters :None
  303. Return Type :BOOL
  304. Global Variables :
  305. g_pszBuffer - command buffer
  306. g_wmiCmd - wmi command line object
  307. Notes :None
  308. ------------------------------------------------------------------------*/
  309. BOOL CtrlHandler(DWORD fdwCtrlType)
  310. {
  311. BOOL bRet = FALSE;
  312. switch (fdwCtrlType)
  313. {
  314. case CTRL_C_EVENT:
  315. // if at command propmt
  316. if ( g_wmiCmd.GetAcceptCommand() == TRUE )
  317. {
  318. SAFEDELETE(g_pszBuffer);
  319. g_wmiCmd.Uninitialize();
  320. bRet = FALSE;
  321. }
  322. else // executing command
  323. {
  324. g_wmiCmd.SetBreakEvent(TRUE);
  325. bRet = TRUE;
  326. }
  327. break;
  328. case CTRL_CLOSE_EVENT:
  329. default:
  330. SAFEDELETE(g_pszBuffer);
  331. g_wmiCmd.Uninitialize();
  332. bRet = FALSE;
  333. break;
  334. }
  335. return bRet;
  336. }
  337. /*------------------------------------------------------------------------
  338. Name :CloseOutputFile
  339. Synopsis :Close the output file.
  340. Type :Global Function
  341. Input parameters :None
  342. Output parameters :None
  343. Return Type :BOOL
  344. Global Variables :
  345. g_wmiCmd - wmi command line object
  346. Calling Syntax :CloseOutputFile()
  347. Notes :None
  348. ------------------------------------------------------------------------*/
  349. BOOL CloseOutputFile()
  350. {
  351. BOOL bRet = TRUE;
  352. // TRUE for getting output file pointer.
  353. FILE* fpOutputFile =
  354. g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
  355. GetOutputOrAppendFilePointer(TRUE);
  356. // If currently output is going to file close the file.
  357. if ( fpOutputFile != NULL )
  358. {
  359. if ( fclose(fpOutputFile) == EOF )
  360. {
  361. DisplayString(IDS_E_CLOSE_OUT_FILE_ERROR, CP_OEMCP,
  362. NULL, TRUE, TRUE);
  363. bRet = FALSE;
  364. }
  365. else // TRUE for setting output file pointer.
  366. g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
  367. SetOutputOrAppendFilePointer(NULL, TRUE);
  368. }
  369. return bRet;
  370. }
  371. /*------------------------------------------------------------------------
  372. Name :CloseAppendFile
  373. Synopsis :Close the append file.
  374. Type :Global Function
  375. Input parameters :None
  376. Output parameters :None
  377. Return Type :BOOL
  378. Global Variables :
  379. g_wmiCmd - wmi command line object
  380. Calling Syntax :CloseAppendFile()
  381. Notes :None
  382. ------------------------------------------------------------------------*/
  383. BOOL CloseAppendFile()
  384. {
  385. BOOL bRet = TRUE;
  386. // FALSE for getting append file pointer.
  387. FILE* fpAppendFile =
  388. g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
  389. GetOutputOrAppendFilePointer(FALSE);
  390. if ( fpAppendFile != NULL )
  391. {
  392. if ( fclose(fpAppendFile) == EOF )
  393. {
  394. DisplayString(IDS_E_CLOSE_APPEND_FILE_ERROR, CP_OEMCP,
  395. NULL, TRUE, TRUE);
  396. bRet = FALSE;
  397. }
  398. else // FASLE for setting output file pointer.
  399. g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
  400. SetOutputOrAppendFilePointer(NULL, FALSE);
  401. }
  402. return bRet;
  403. }
  404. /*------------------------------------------------------------------------
  405. Name :CopyToClipBoard
  406. Synopsis :Copy data to clip board.
  407. Type :Global Function
  408. Input parameters :
  409. bstrClipBoardBuffer - reference to object of type _bstr_t.
  410. Output parameters :None
  411. Return Type :void
  412. Global Variables :None
  413. Calling Syntax :CopyToClipBoard(bstrClipBoardBuffer)
  414. Notes :None
  415. ------------------------------------------------------------------------*/
  416. void CopyToClipBoard(_bstr_t& bstrClipBoardBuffer)
  417. {
  418. HGLOBAL hMem = CopyStringToHGlobal(bstrClipBoardBuffer);
  419. if (hMem != NULL)
  420. {
  421. if (OpenClipboard(NULL))
  422. {
  423. EmptyClipboard();
  424. SetClipboardData(CF_UNICODETEXT, hMem);
  425. CloseClipboard();
  426. }
  427. else
  428. GlobalFree(hMem); //We must clean up.
  429. }
  430. }
  431. /*------------------------------------------------------------------------
  432. Name :CopyStringToHGlobal
  433. Synopsis :Copy string to global memory.
  434. Type :Global Function
  435. Input parameters :
  436. psz - LPTSTR type, specifying string to get memory allocated.
  437. Output parameters :None
  438. Return Type :HGLOBAL
  439. Global Variables :None
  440. Calling Syntax :CopyStringToHGlobal(psz)
  441. Notes :None
  442. ------------------------------------------------------------------------*/
  443. HGLOBAL CopyStringToHGlobal(LPTSTR psz)
  444. {
  445. HGLOBAL hMem;
  446. LPTSTR pszDst;
  447. hMem = GlobalAlloc(GHND, (DWORD) (lstrlen(psz)+1) * sizeof(TCHAR));
  448. if (hMem != NULL)
  449. {
  450. pszDst = (LPTSTR) GlobalLock(hMem);
  451. lstrcpy(pszDst, psz);
  452. GlobalUnlock(hMem);
  453. }
  454. return hMem;
  455. }