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.

586 lines
17 KiB

  1. /*********************************************************************************************
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. GpResult.cpp
  5. Abstract:
  6. This file contains the main entry point function for this tool and also the
  7. function to parse the command line arguments.
  8. Author:
  9. Wipro Technologies
  10. Revision History:
  11. 20-Feb-2001 : Created It.
  12. *********************************************************************************************/
  13. #include "pch.h"
  14. #include "GpResult.h"
  15. #include "wmi.h"
  16. /*********************************************************************************************
  17. Routine Description:
  18. This is main entry point for this utility. Different function calls are made from here,
  19. depending on the command line parameters passed to this utility.
  20. Arguments:
  21. [in] argc : Number of Command line arguments.
  22. [in] argv : Pointer to Command line arguments.
  23. Return Value:
  24. Zero on success
  25. Corresponding error code on failure.
  26. *********************************************************************************************/
  27. DWORD _cdecl _tmain( DWORD argc, LPCWSTR argv[] )
  28. {
  29. // local variables
  30. CGpResult GpResult;
  31. DWORD dwi = 0;
  32. BOOL bResult = FALSE;
  33. BOOL bNeedUsageMsg = FALSE;
  34. try
  35. {
  36. // initialize the GpResult utility
  37. if( GpResult.Initialize() == FALSE )
  38. {
  39. CHString strBuffer;
  40. strBuffer.Format( L"%s %s", TAG_ERROR, GetReason() );
  41. ShowMessage( stderr, strBuffer );
  42. EXIT_PROCESS( ERROR_EXIT );
  43. }
  44. bResult = GpResult.ProcessOptions( argc, argv, &bNeedUsageMsg );
  45. if( bResult == FALSE )
  46. {
  47. CHString strBuffer;
  48. strBuffer.Format( L"%s %s", TAG_ERROR, GetReason() );
  49. ShowMessage( stderr, strBuffer );
  50. if( bNeedUsageMsg == TRUE )
  51. {
  52. strBuffer.Format( GetResString( IDS_TYPE_USAGE ), argv[ 0 ] );
  53. ShowMessage( stderr, strBuffer );
  54. }
  55. EXIT_PROCESS( ERROR_EXIT );
  56. }
  57. }
  58. catch( ... )
  59. {
  60. // display the error message
  61. SetLastError( E_OUTOFMEMORY );
  62. SaveLastError();
  63. ShowMessage( stderr, GetResString( IDS_ERROR ) );
  64. ShowMessage( stderr, GetReason() );
  65. }
  66. // Check if help is specified in the commandline
  67. if( (argc == 2) && ( ( lstrcmp ( argv[1], HELP_OPTION ) == 0)
  68. || (lstrcmp ( argv[1], HELP_OPTION1 ) == 0) ) )
  69. {
  70. GpResult.DisplayUsage();
  71. EXIT_PROCESS( CLEAN_EXIT );
  72. }
  73. // Call GetLoggingData to get the data for the Logging mode
  74. if( GpResult.GetLoggingData() == FALSE )
  75. {
  76. EXIT_PROCESS( ERROR_EXIT );
  77. }
  78. EXIT_PROCESS( CLEAN_EXIT );
  79. }
  80. /*********************************************************************************************
  81. Routine Description
  82. This function displays the help for GpResult utility
  83. Arguments:
  84. None.
  85. Return Value
  86. None
  87. *********************************************************************************************/
  88. VOID CGpResult::DisplayUsage( void )
  89. {
  90. DWORD dwIndex = 0;
  91. // Displaying main usage
  92. for( dwIndex = ID_HELP_START; dwIndex <= ID_HELP_END; dwIndex++ )
  93. {
  94. ShowMessage( stdout, GetResString( dwIndex ) );
  95. }
  96. }
  97. /*********************************************************************************************
  98. Routine Description
  99. This function processes the command line for the main options
  100. Arguments:
  101. [in] argc : Number of Command line arguments.
  102. [in] argv : Pointer to Command line arguments.
  103. Return Value
  104. TRUE on success
  105. FALSE on failure
  106. *********************************************************************************************/
  107. BOOL CGpResult::ProcessOptions( DWORD argc, LPCWSTR argv[], BOOL *pbNeedUsageMsg )
  108. {
  109. // local variables
  110. PTCMDPARSER pcmdOptions = NULL;
  111. __STRING_64 szScope = NULL_STRING;
  112. // temporary local variables
  113. LPWSTR pwszUserName = NULL;
  114. LPWSTR pwszPassword = NULL;
  115. LPWSTR pwszUser = NULL;
  116. LPWSTR pwszServerName = NULL;
  117. PTCMDPARSER pOption = NULL;
  118. PTCMDPARSER pOptionServer = NULL;
  119. PTCMDPARSER pOptionUserName = NULL;
  120. PTCMDPARSER pOptionPassword = NULL;
  121. PTCMDPARSER pOptionUser = NULL;
  122. PTCMDPARSER pOptionVerbose = NULL;
  123. PTCMDPARSER pOptionSuperVerbose = NULL;
  124. //
  125. // prepare the command options
  126. pcmdOptions = new TCMDPARSER[ MAX_CMDLINE_OPTIONS ];
  127. if ( pcmdOptions == NULL )
  128. {
  129. SetLastError( E_OUTOFMEMORY );
  130. SaveLastError();
  131. return FALSE;
  132. }
  133. try
  134. {
  135. // get the memory
  136. pwszServerName = m_strServerName.GetBufferSetLength( MAX_STRING_LENGTH );
  137. pwszUserName = m_strUserName.GetBufferSetLength( MAX_STRING_LENGTH );
  138. pwszPassword = m_strPassword.GetBufferSetLength( MAX_STRING_LENGTH );
  139. pwszUser = m_strUser.GetBufferSetLength( MAX_STRING_LENGTH );
  140. // init the password value
  141. lstrcpy( pwszPassword, _T( "*" ) );
  142. }
  143. catch( ... )
  144. {
  145. SetLastError( E_OUTOFMEMORY );
  146. SaveLastError();
  147. return FALSE;
  148. }
  149. // initialize to ZERO's
  150. ZeroMemory( pcmdOptions, MAX_CMDLINE_OPTIONS * sizeof( TCMDPARSER ) );
  151. // -?
  152. pOption = pcmdOptions + OI_USAGE;
  153. pOption->dwCount = 1;
  154. pOption->dwActuals = 0;
  155. pOption->dwFlags = 0;
  156. pOption->pValue = &m_bUsage;
  157. pOption->pFunction = NULL;
  158. pOption->pFunctionData = NULL;
  159. lstrcpy( pOption->szValues, NULL_STRING );
  160. lstrcpy( pOption->szOption, OPTION_USAGE );
  161. // -s
  162. pOption = pcmdOptions + OI_SERVER;
  163. pOption->dwCount = 1;
  164. pOption->dwActuals = 0;
  165. pOption->pValue = pwszServerName;
  166. pOption->pFunction = NULL;
  167. pOption->pFunctionData = NULL;
  168. pOption->dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY;
  169. lstrcpy( pOption->szValues, NULL_STRING );
  170. lstrcpy( pOption->szOption, OPTION_SERVER );
  171. // -u
  172. pOption = pcmdOptions + OI_USERNAME;
  173. pOption->dwCount = 1;
  174. pOption->dwActuals = 0;
  175. pOption->dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY;
  176. pOption->pValue = pwszUserName;
  177. pOption->pFunction = NULL;
  178. pOption->pFunctionData = NULL;
  179. lstrcpy( pOption->szValues, NULL_STRING );
  180. lstrcpy( pOption->szOption, OPTION_USERNAME );
  181. // -p
  182. pOption = pcmdOptions + OI_PASSWORD;
  183. pOption->dwCount = 1;
  184. pOption->dwActuals = 0;
  185. pOption->dwFlags = CP_TYPE_TEXT | CP_VALUE_OPTIONAL;
  186. pOption->pValue = pwszPassword;
  187. pOption->pFunction = NULL;
  188. pOption->pFunctionData = NULL;
  189. lstrcpy( pOption->szValues, NULL_STRING );
  190. lstrcpy( pOption->szOption, OPTION_PASSWORD );
  191. // -v
  192. pOption = pcmdOptions + OI_VERBOSE;
  193. pOption->dwCount = 1;
  194. pOption->dwActuals = 0;
  195. pOption->dwFlags = 0;
  196. pOption->pValue = &m_bVerbose;
  197. pOption->pFunction = NULL;
  198. pOption->pFunctionData = NULL;
  199. lstrcpy( pOption->szValues, NULL_STRING );
  200. lstrcpy( pOption->szOption, OPTION_VERBOSE );
  201. // -z
  202. pOption = pcmdOptions + OI_SUPER_VERBOSE;
  203. pOption->dwCount = 1;
  204. pOption->dwActuals = 0;
  205. pOption->dwFlags = 0;
  206. pOption->pValue = &m_bSuperVerbose;
  207. pOption->pFunction = NULL;
  208. pOption->pFunctionData = NULL;
  209. lstrcpy( pOption->szValues, NULL_STRING );
  210. lstrcpy( pOption->szOption, OPTION_SUPER_VERBOSE );
  211. // -User
  212. pOption = pcmdOptions + OI_USER;
  213. pOption->dwCount = 1;
  214. pOption->dwActuals = 0;
  215. pOption->dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY;
  216. pOption->pValue = pwszUser;
  217. pOption->pFunction = NULL;
  218. pOption->pFunctionData = NULL;
  219. lstrcpy( pOption->szValues, NULL_STRING );
  220. lstrcpy( pOption->szOption, OPTION_USER );
  221. // -scope
  222. pOption = pcmdOptions + OI_SCOPE;
  223. pOption->dwCount = 1;
  224. pOption->dwActuals = 0;
  225. pOption->dwFlags = CP_TYPE_TEXT | CP_VALUE_MANDATORY | CP_MODE_VALUES;
  226. pOption->pValue = &szScope;
  227. pOption->pFunction = NULL;
  228. pOption->pFunctionData = NULL;
  229. lstrcpy( pOption->szValues, TEXT_SCOPE_VALUES );
  230. lstrcpy( pOption->szOption, OPTION_SCOPE);
  231. //
  232. // do the parsing
  233. if( DoParseParam( argc, argv, MAX_CMDLINE_OPTIONS, pcmdOptions ) == FALSE )
  234. {
  235. delete [] pcmdOptions; // clear memory
  236. pcmdOptions = NULL;
  237. return FALSE; // invalid syntax
  238. }
  239. // Do Parse Param succeded so set the flag to indicate that we have to
  240. // show an additional line alongwith the error message
  241. *pbNeedUsageMsg = TRUE;
  242. // release the buffers
  243. m_strServerName.ReleaseBuffer();
  244. m_strUserName.ReleaseBuffer();
  245. m_strPassword.ReleaseBuffer();
  246. m_strUser.ReleaseBuffer();
  247. // check the usage option
  248. if( m_bUsage && ( argc > 2 ) )
  249. {
  250. // No options are accepted with -?
  251. SetReason( ERROR_USAGE );
  252. delete [] pcmdOptions; // clear the cmd parser config info
  253. return FALSE;
  254. }
  255. else if( m_bUsage == TRUE )
  256. {
  257. // should not do the furthur validations
  258. delete [] pcmdOptions; // clear the cmd parser config info
  259. return TRUE;
  260. }
  261. // Check what has been entered for the scope variable
  262. // and set the flag appropriately
  263. if( lstrcmpi( szScope, TEXT_SCOPE_USER ) == 0 )
  264. {
  265. m_dwScope = SCOPE_USER;
  266. }
  267. else if( lstrcmpi( szScope, TEXT_SCOPE_COMPUTER ) == 0 )
  268. {
  269. m_dwScope = SCOPE_COMPUTER;
  270. }
  271. //
  272. // now, check the mutually exclusive options
  273. pOptionServer = pcmdOptions + OI_SERVER;
  274. pOptionUserName = pcmdOptions + OI_USERNAME;
  275. pOptionPassword = pcmdOptions + OI_PASSWORD;
  276. pOptionUser = pcmdOptions + OI_USER;
  277. pOptionVerbose = pcmdOptions + OI_VERBOSE;
  278. pOptionSuperVerbose = pcmdOptions + OI_SUPER_VERBOSE;
  279. // "-z" and "-v" are mutually exclusive options
  280. if( pOptionVerbose->dwActuals != 0 && pOptionSuperVerbose->dwActuals != 0 )
  281. {
  282. // invalid syntax
  283. SetReason( ERROR_VERBOSE_SYNTAX );
  284. delete [] pcmdOptions; // clear the cmd parser config info
  285. return FALSE; // indicate failure
  286. }
  287. // "-u" should not be specified without machine names
  288. if( pOptionServer->dwActuals == 0 && pOptionUserName->dwActuals != 0 )
  289. {
  290. // invalid syntax
  291. SetReason( ERROR_USERNAME_BUT_NOMACHINE );
  292. delete [] pcmdOptions; // clear the cmd parser config info
  293. return FALSE; // indicate failure
  294. }
  295. // "-p" should not be specified without "-u"
  296. if( pOptionUserName->dwActuals == 0 && pOptionPassword->dwActuals != 0 )
  297. {
  298. // invalid syntax
  299. SetReason( ERROR_PASSWORD_BUT_NOUSERNAME );
  300. delete [] pcmdOptions; // clear the cmd parser config info
  301. return FALSE;
  302. }
  303. // empty server name is not valid
  304. if( pOptionServer->dwActuals != 0 && m_strServerName.GetLength() == 0 )
  305. {
  306. SetReason( ERROR_SERVERNAME_EMPTY );
  307. delete [] pcmdOptions;
  308. return FALSE;
  309. }
  310. // empty user is not valid
  311. if( pOptionUserName->dwActuals != 0 && m_strUserName.GetLength() == 0 )
  312. {
  313. SetReason( ERROR_USERNAME_EMPTY );
  314. delete [] pcmdOptions;
  315. return FALSE;
  316. }
  317. // empty user is not valid, for the target user
  318. if( pOptionUser->dwActuals != 0 && m_strUser.GetLength() == 0 )
  319. {
  320. SetReason( ERROR_TARGET_EMPTY );
  321. delete [] pcmdOptions;
  322. return FALSE;
  323. }
  324. // if user has specified -s (or) -u and no "-p", then utility should accept password
  325. // the user will be prompted for the password only if establish connection
  326. // fails without the credentials information
  327. m_bNeedPassword = FALSE;
  328. if ( pOptionPassword->dwActuals != 0 && m_strPassword.Compare( L"*" ) == 0 )
  329. {
  330. // user wants the utility to prompt for the password before trying to connect
  331. m_bNeedPassword = TRUE;
  332. }
  333. else if ( pOptionPassword->dwActuals == 0 &&
  334. ( pOptionServer->dwActuals != 0 || pOptionUserName->dwActuals != 0 ) )
  335. {
  336. // utility needs to try to connect first and if it fails then prompt for the password
  337. m_bNeedPassword = TRUE;
  338. m_strPassword.Empty();
  339. }
  340. // Check wether we are querying for the local system
  341. if( pOptionServer->dwActuals == 0 )
  342. {
  343. m_bLocalSystem = TRUE;
  344. }
  345. // command-line parsing is successfull
  346. // clear the cmd parser config info
  347. delete [] pcmdOptions;
  348. return TRUE;
  349. }
  350. /*********************************************************************************************
  351. Routine Description:
  352. CGpResult constructor
  353. Arguments:
  354. NONE
  355. Return Value:
  356. NONE
  357. *********************************************************************************************/
  358. CGpResult::CGpResult()
  359. {
  360. // initialize the member variables to defaults
  361. m_pWbemLocator = NULL;
  362. m_pEnumObjects = NULL;
  363. m_pWbemServices = NULL;
  364. m_pAuthIdentity = NULL;
  365. m_strServerName = L"";
  366. m_strUserName = L"";
  367. m_strPassword = L"";
  368. m_strUser = L"";
  369. m_strADSIDomain = L"";
  370. m_strADSIServer = L"";
  371. m_pwszPassword = NULL;
  372. m_hOutput = NULL;
  373. m_bVerbose = FALSE;
  374. m_dwScope = SCOPE_ALL;
  375. m_bNeedPassword = FALSE;
  376. m_bLocalSystem = FALSE;
  377. m_bUsage = FALSE;
  378. m_hMutex = CreateMutex( NULL, FALSE, MUTEX_NAME );
  379. }
  380. /*********************************************************************************************
  381. Routine Description:
  382. CGpResult destructor
  383. Arguments:
  384. NONE
  385. Return Value:
  386. NONE
  387. *********************************************************************************************/
  388. CGpResult::~CGpResult()
  389. {
  390. //
  391. // release WMI / COM interfaces
  392. SAFE_RELEASE( m_pWbemLocator );
  393. SAFE_RELEASE( m_pWbemServices );
  394. SAFE_RELEASE( m_pEnumObjects );
  395. // free authentication identity structure
  396. // release the existing auth identity structure
  397. WbemFreeAuthIdentity( &m_pAuthIdentity );
  398. // un-initialize the COM library
  399. CoUninitialize();
  400. // Release the object
  401. if( m_hMutex != NULL )
  402. {
  403. CloseHandle( m_hMutex );
  404. }
  405. }
  406. /*********************************************************************************************
  407. Routine Description:
  408. Initializes the GpResult utility
  409. Arguments:
  410. NONE
  411. Return Value:
  412. TRUE : if filters are appropriately specified
  413. FALSE : if filters are errorneously specified
  414. *********************************************************************************************/
  415. BOOL CGpResult::Initialize()
  416. {
  417. // if at all an error occurs, we know that is because of the
  418. // failure in memory allocation, so set the error initially
  419. SetLastError( E_OUTOFMEMORY );
  420. SaveLastError();
  421. // initialize the COM library
  422. if ( InitializeCom( &m_pWbemLocator ) == FALSE )
  423. {
  424. return FALSE;
  425. }
  426. //
  427. // Init the console scree buffer structure to zero's
  428. // and then get the console handle and screen buffer information
  429. //
  430. // prepare for status display.
  431. // for this get a handle to the screen output buffer
  432. // but this handle will be null if the output is being redirected. so do not check
  433. // for the validity of the handle. instead try to get the console buffer information
  434. // only in case you have a valid handle to the output screen buffer
  435. ZeroMemory( &m_csbi, sizeof( CONSOLE_SCREEN_BUFFER_INFO ) );
  436. m_hOutput = GetStdHandle( STD_ERROR_HANDLE );
  437. if ( m_hOutput != NULL )
  438. {
  439. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  440. }
  441. // initialization is successful
  442. SetLastError( NOERROR ); // clear the error
  443. SetReason( NULL_STRING ); // clear the reason
  444. return TRUE;
  445. }
  446. /*********************************************************************************************
  447. Routine Description:
  448. Initializes the GpResult utility
  449. Arguments:
  450. [in] HANDLE : Handle to the output console
  451. [in] LPCWSTR : String to display
  452. [in] const CONSOLE_SCREEN_BUFFER_INFO& : pointer to the screen buffer
  453. Return Value:
  454. NONE
  455. *********************************************************************************************/
  456. VOID PrintProgressMsg( HANDLE hOutput, LPCWSTR pwszMsg,
  457. const CONSOLE_SCREEN_BUFFER_INFO& csbi )
  458. {
  459. // local variables
  460. COORD coord;
  461. DWORD dwSize = 0;
  462. WCHAR wszSpaces[ 80 ] = L"";
  463. // check the handle. if it is null, it means that output is being redirected. so return
  464. if( hOutput == NULL )
  465. {
  466. return;
  467. }
  468. // set the cursor position
  469. coord.X = 0;
  470. coord.Y = csbi.dwCursorPosition.Y;
  471. // first erase contents on the current line
  472. ZeroMemory( wszSpaces, 80 );
  473. SetConsoleCursorPosition( hOutput, coord );
  474. WriteConsoleW( hOutput, Replicate( wszSpaces, L"", 79 ), 79, &dwSize, NULL );
  475. // now display the message ( if exists )
  476. SetConsoleCursorPosition( hOutput, coord );
  477. if( pwszMsg != NULL )
  478. {
  479. WriteConsoleW( hOutput, pwszMsg, lstrlen( pwszMsg ), &dwSize, NULL );
  480. }
  481. }