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.

644 lines
19 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. BOOL bResult = FALSE;
  32. BOOL bNeedUsageMsg = FALSE;
  33. // initialize the GpResult utility
  34. if( GpResult.Initialize() == FALSE )
  35. {
  36. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  37. EXIT_PROCESS( ERROR_EXIT );
  38. }
  39. bResult = GpResult.ProcessOptions( argc, argv, &bNeedUsageMsg );
  40. if( bResult == FALSE )
  41. {
  42. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  43. if( bNeedUsageMsg == TRUE )
  44. {
  45. ShowMessageEx(stderr, 1, TRUE, GetResString( IDS_TYPE_USAGE ), argv[ 0 ] );
  46. }
  47. EXIT_PROCESS( ERROR_EXIT );
  48. }
  49. // Check if help is specified in the commandline
  50. if( (argc == 2) && ( ( StringCompare ( argv[1], HELP_OPTION, FALSE, 0 ) == 0)
  51. || (StringCompare ( argv[1], HELP_OPTION1, FALSE, 0 ) == 0) ) )
  52. {
  53. GpResult.DisplayUsage();
  54. EXIT_PROCESS( CLEAN_EXIT );
  55. }
  56. // Call GetLoggingData to get the data for the Logging mode
  57. if( GpResult.GetLoggingData() == FALSE )
  58. {
  59. EXIT_PROCESS( ERROR_EXIT );
  60. }
  61. EXIT_PROCESS( CLEAN_EXIT );
  62. }
  63. /*********************************************************************************************
  64. Routine Description
  65. This function displays the help for GpResult utility
  66. Arguments:
  67. None.
  68. Return Value
  69. None
  70. *********************************************************************************************/
  71. VOID CGpResult::DisplayUsage( void )
  72. {
  73. DWORD dwIndex = 0;
  74. // Displaying main usage
  75. for( dwIndex = ID_HELP_START; dwIndex <= ID_HELP_END; dwIndex++ )
  76. {
  77. ShowMessage( stdout, GetResString( dwIndex ) );
  78. }
  79. }
  80. /*********************************************************************************************
  81. Routine Description
  82. This function processes the command line for the main options
  83. Arguments:
  84. [in] argc : Number of Command line arguments.
  85. [in] argv : Pointer to Command line arguments.
  86. Return Value
  87. TRUE on success
  88. FALSE on failure
  89. *********************************************************************************************/
  90. BOOL CGpResult::ProcessOptions( DWORD argc, LPCWSTR argv[], BOOL *pbNeedUsageMsg )
  91. {
  92. // local variables
  93. PTCMDPARSER2 pcmdOptions = NULL;
  94. __STRING_64 szScope = NULL_STRING;
  95. // temporary local variables
  96. LPWSTR pwszPassword = NULL;
  97. LPWSTR pwszUser = NULL;
  98. LPWSTR pwszServerName = NULL;
  99. PTCMDPARSER2 pOption = NULL;
  100. PTCMDPARSER2 pOptionServer = NULL;
  101. PTCMDPARSER2 pOptionUserName = NULL;
  102. PTCMDPARSER2 pOptionPassword = NULL;
  103. PTCMDPARSER2 pOptionUser = NULL;
  104. PTCMDPARSER2 pOptionVerbose = NULL;
  105. PTCMDPARSER2 pOptionSuperVerbose = NULL;
  106. //
  107. // prepare the command options
  108. pcmdOptions = new TCMDPARSER2[ MAX_CMDLINE_OPTIONS ];
  109. if ( pcmdOptions == NULL )
  110. {
  111. SetLastError((DWORD) E_OUTOFMEMORY );
  112. SaveLastError();
  113. return FALSE;
  114. }
  115. try
  116. {
  117. // get the memory
  118. pwszServerName = m_strServerName.GetBufferSetLength( MAX_STRING_LENGTH );
  119. pwszPassword = m_strPassword.GetBufferSetLength( MAX_STRING_LENGTH );
  120. pwszUser = m_strUser.GetBufferSetLength( MAX_STRING_LENGTH );
  121. // init the password value
  122. StringCopy( pwszPassword, _T( "*" ), MAX_STRING_LENGTH );
  123. }
  124. catch( ... )
  125. {
  126. SetLastError((DWORD) E_OUTOFMEMORY );
  127. SaveLastError();
  128. delete [] pcmdOptions; // clear memory
  129. pcmdOptions = NULL;
  130. return FALSE;
  131. }
  132. // initialize to ZERO's
  133. SecureZeroMemory( pcmdOptions, MAX_CMDLINE_OPTIONS * sizeof( TCMDPARSER2 ) );
  134. // -?
  135. pOption = pcmdOptions + OI_USAGE;
  136. pOption->dwCount = 1;
  137. pOption->dwFlags = CP2_USAGE;
  138. pOption->dwType = CP_TYPE_BOOLEAN;
  139. pOption->pValue = &m_bUsage;
  140. pOption->pwszOptions= OPTION_USAGE;
  141. StringCopyA( pOption->szSignature, "PARSER2", 8 );
  142. // -s
  143. pOption = pcmdOptions + OI_SERVER;
  144. pOption->dwCount = 1;
  145. pOption->pValue = pwszServerName;
  146. pOption->dwType = CP_TYPE_TEXT;
  147. pOption->dwFlags = CP_VALUE_MANDATORY;
  148. StringCopyA( pOption->szSignature, "PARSER2", 8 );
  149. pOption->pwszOptions=OPTION_SERVER;
  150. pOption->dwLength = MAX_STRING_LENGTH;
  151. // -u
  152. pOption = pcmdOptions + OI_USERNAME;
  153. pOption->dwCount = 1;
  154. pOption->dwActuals = 0;
  155. pOption->dwType = CP_TYPE_TEXT;
  156. pOption->dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY;
  157. pOption->pValue = NULL;
  158. pOption->pFunction = NULL;
  159. pOption->pFunctionData = NULL;
  160. pOption->pwszOptions=OPTION_USERNAME;
  161. StringCopyA( pOption->szSignature, "PARSER2", 8 );
  162. // -p
  163. pOption = pcmdOptions + OI_PASSWORD;
  164. pOption->dwCount = 1;
  165. pOption->dwType = CP_TYPE_TEXT;
  166. pOption->dwFlags = CP2_VALUE_OPTIONAL;
  167. pOption->pValue = pwszPassword;
  168. pOption->pwszOptions=OPTION_PASSWORD;
  169. pOption->dwLength = MAX_STRING_LENGTH;
  170. StringCopyA( pOption->szSignature, "PARSER2", 8 );
  171. // -v
  172. pOption = pcmdOptions + OI_VERBOSE;
  173. pOption->dwCount = 1;
  174. pOption->dwType = CP_TYPE_BOOLEAN;
  175. pOption->pValue = &m_bVerbose;
  176. pOption->pwszOptions=OPTION_VERBOSE;
  177. StringCopyA( pOption->szSignature, "PARSER2", 8 );
  178. // -z
  179. pOption = pcmdOptions + OI_SUPER_VERBOSE;
  180. pOption->dwCount = 1;
  181. pOption->dwType = CP_TYPE_BOOLEAN;
  182. pOption->pValue = &m_bSuperVerbose;
  183. pOption->pwszOptions=OPTION_SUPER_VERBOSE;
  184. StringCopyA( pOption->szSignature, "PARSER2", 8 );
  185. // -User
  186. pOption = pcmdOptions + OI_USER;
  187. pOption->dwCount = 1;
  188. pOption->dwType = CP_TYPE_TEXT;
  189. pOption->dwFlags = CP_VALUE_MANDATORY;
  190. pOption->pValue = pwszUser;
  191. pOption->dwLength = MAX_STRING_LENGTH;
  192. pOption->pwszOptions=OPTION_USER;
  193. StringCopyA( pOption->szSignature, "PARSER2", 8 );
  194. // -scope
  195. pOption = pcmdOptions + OI_SCOPE;
  196. pOption->dwCount = 1;
  197. pOption->dwActuals = 0;
  198. pOption->dwType = CP_TYPE_TEXT;
  199. pOption->dwFlags = CP_VALUE_MANDATORY | CP2_MODE_VALUES;
  200. pOption->pValue = szScope;
  201. pOption->dwLength = MAX_STRING_LENGTH;
  202. pOption->pwszValues=TEXT_SCOPE_VALUES;
  203. pOption->pwszOptions=OPTION_SCOPE;
  204. StringCopyA( pOption->szSignature, "PARSER2", 8 );
  205. //
  206. // do the parsing
  207. if( DoParseParam2( argc, argv, -1, MAX_CMDLINE_OPTIONS, pcmdOptions, 0 ) == FALSE )
  208. {
  209. delete [] pcmdOptions; // clear memory
  210. pcmdOptions = NULL;
  211. return FALSE; // invalid syntax
  212. }
  213. pOption = pcmdOptions+OI_USERNAME;
  214. m_strUserName =(LPCWSTR) pOption->pValue;
  215. // Do Parse Param succeded so set the flag to indicate that we have to
  216. // show an additional line alongwith the error message
  217. *pbNeedUsageMsg = TRUE;
  218. // release the buffers
  219. m_strServerName.ReleaseBuffer();
  220. m_strPassword.ReleaseBuffer();
  221. m_strUser.ReleaseBuffer();
  222. // check the usage option
  223. if( m_bUsage && ( argc > 2 ) )
  224. {
  225. // No options are accepted with -?
  226. SetReason( ERROR_USAGE );
  227. delete [] pcmdOptions; // clear the cmd parser config info
  228. return FALSE;
  229. }
  230. else if( m_bUsage == TRUE )
  231. {
  232. // should not do the furthur validations
  233. delete [] pcmdOptions; // clear the cmd parser config info
  234. return TRUE;
  235. }
  236. // Check what has been entered for the scope variable
  237. // and set the flag appropriately
  238. if( StringCompare( szScope, TEXT_SCOPE_USER, TRUE, 0 ) == 0 )
  239. {
  240. m_dwScope = SCOPE_USER;
  241. }
  242. else if( StringCompare( szScope, TEXT_SCOPE_COMPUTER, TRUE, 0 ) == 0 )
  243. {
  244. m_dwScope = SCOPE_COMPUTER;
  245. }
  246. //
  247. // now, check the mutually exclusive options
  248. pOptionServer = pcmdOptions + OI_SERVER;
  249. pOptionUserName = pcmdOptions + OI_USERNAME;
  250. pOptionPassword = pcmdOptions + OI_PASSWORD;
  251. pOptionUser = pcmdOptions + OI_USER;
  252. pOptionVerbose = pcmdOptions + OI_VERBOSE;
  253. pOptionSuperVerbose = pcmdOptions + OI_SUPER_VERBOSE;
  254. // "-z" and "-v" are mutually exclusive options
  255. if( pOptionVerbose->dwActuals != 0 && pOptionSuperVerbose->dwActuals != 0 )
  256. {
  257. // invalid syntax
  258. SetReason( ERROR_VERBOSE_SYNTAX );
  259. delete [] pcmdOptions; // clear the cmd parser config info
  260. return FALSE; // indicate failure
  261. }
  262. // "-u" should not be specified without machine names
  263. if( pOptionServer->dwActuals == 0 && pOptionUserName->dwActuals != 0 )
  264. {
  265. // invalid syntax
  266. SetReason( ERROR_USERNAME_BUT_NOMACHINE );
  267. delete [] pcmdOptions; // clear the cmd parser config info
  268. return FALSE; // indicate failure
  269. }
  270. // "-p" should not be specified without "-u"
  271. if( pOptionUserName->dwActuals == 0 && pOptionPassword->dwActuals != 0 )
  272. {
  273. // invalid syntax
  274. SetReason( ERROR_PASSWORD_BUT_NOUSERNAME );
  275. delete [] pcmdOptions; // clear the cmd parser config info
  276. return FALSE;
  277. }
  278. // empty server name is not valid
  279. if( pOptionServer->dwActuals != 0 && m_strServerName.GetLength() == 0 )
  280. {
  281. SetReason( ERROR_SERVERNAME_EMPTY );
  282. delete [] pcmdOptions;
  283. return FALSE;
  284. }
  285. // empty user is not valid
  286. if( pOptionUserName->dwActuals != 0 && m_strUserName.GetLength() == 0 )
  287. {
  288. SetReason( ERROR_USERNAME_EMPTY );
  289. delete [] pcmdOptions;
  290. return FALSE;
  291. }
  292. // empty user is not valid, for the target user
  293. if( pOptionUser->dwActuals != 0 && m_strUser.GetLength() == 0 )
  294. {
  295. SetReason( ERROR_TARGET_EMPTY );
  296. delete [] pcmdOptions;
  297. return FALSE;
  298. }
  299. // if user has specified -s (or) -u and no "-p", then utility should accept password
  300. // the user will be prompted for the password only if establish connection
  301. // fails without the credentials information
  302. m_bNeedPassword = FALSE;
  303. if ( pOptionPassword->dwActuals != 0 && m_strPassword.Compare( L"*" ) == 0 )
  304. {
  305. // user wants the utility to prompt for the password before trying to connect
  306. m_bNeedPassword = TRUE;
  307. }
  308. else if ( pOptionPassword->dwActuals == 0 &&
  309. ( pOptionServer->dwActuals != 0 || pOptionUserName->dwActuals != 0 ) )
  310. {
  311. // utility needs to try to connect first and if it fails then prompt for the password
  312. m_bNeedPassword = TRUE;
  313. m_strPassword.Empty();
  314. }
  315. // Check wether we are querying for the local system
  316. if( pOptionServer->dwActuals == 0 )
  317. {
  318. m_bLocalSystem = TRUE;
  319. }
  320. // command-line parsing is successfull
  321. // clear the cmd parser config info
  322. delete [] pcmdOptions;
  323. return TRUE;
  324. }
  325. /*********************************************************************************************
  326. Routine Description:
  327. CGpResult constructor
  328. Arguments:
  329. NONE
  330. Return Value:
  331. NONE
  332. *********************************************************************************************/
  333. CGpResult::CGpResult()
  334. {
  335. // initialize the member variables to defaults
  336. m_pWbemLocator = NULL;
  337. m_pEnumObjects = NULL;
  338. m_pWbemServices = NULL;
  339. m_pAuthIdentity = NULL;
  340. m_pRsopNameSpace = NULL;
  341. m_strServerName = L"";
  342. m_strUserName = L"";
  343. m_strPassword = L"";
  344. m_strUser = L"";
  345. m_strADSIDomain = L"";
  346. m_strADSIServer = L"";
  347. m_pwszPassword = NULL;
  348. m_hOutput = NULL;
  349. m_bVerbose = FALSE;
  350. m_dwScope = SCOPE_ALL;
  351. m_bNeedPassword = FALSE;
  352. m_bLocalSystem = FALSE;
  353. m_bUsage = FALSE;
  354. m_szUserGroups = NULL;
  355. m_hMutex = NULL;
  356. m_NoOfGroups = 0;
  357. m_bPlanning = FALSE;
  358. m_bLogging = FALSE;
  359. m_bUsage = FALSE;
  360. }
  361. /*********************************************************************************************
  362. Routine Description:
  363. CGpResult destructor
  364. Arguments:
  365. NONE
  366. Return Value:
  367. NONE
  368. *********************************************************************************************/
  369. CGpResult::~CGpResult()
  370. {
  371. //
  372. // release WMI / COM interfaces
  373. SAFE_RELEASE( m_pWbemLocator );
  374. SAFE_RELEASE( m_pWbemServices );
  375. SAFE_RELEASE( m_pEnumObjects );
  376. SAFE_RELEASE( m_pRsopNameSpace );
  377. if( m_szUserGroups != NULL )
  378. {
  379. for( DWORD dw=0;dw<=m_NoOfGroups;dw++ )
  380. {
  381. FreeMemory((LPVOID *) &m_szUserGroups[dw] );
  382. }
  383. FreeMemory((LPVOID *)&m_szUserGroups);
  384. }
  385. // free authentication identity structure
  386. // release the existing auth identity structure
  387. WbemFreeAuthIdentity( &m_pAuthIdentity );
  388. // un-initialize the COM library
  389. CoUninitialize();
  390. // Release the object
  391. if( m_hMutex != NULL )
  392. {
  393. CloseHandle( m_hMutex );
  394. }
  395. }
  396. /*********************************************************************************************
  397. Routine Description:
  398. Initializes the GpResult utility
  399. Arguments:
  400. NONE
  401. Return Value:
  402. TRUE : if filters are appropriately specified
  403. FALSE : if filters are errorneously specified
  404. *********************************************************************************************/
  405. BOOL CGpResult::Initialize()
  406. {
  407. // if at all an error occurs, we know that is because of the
  408. // failure in memory allocation, so set the error initially
  409. SetLastError((DWORD) E_OUTOFMEMORY );
  410. SaveLastError();
  411. // initialize the COM library
  412. if ( InitializeCom( &m_pWbemLocator ) == FALSE )
  413. {
  414. return FALSE;
  415. }
  416. //
  417. // Init the console scree buffer structure to zero's
  418. // and then get the console handle and screen buffer information
  419. //
  420. // prepare for status display.
  421. // for this get a handle to the screen output buffer
  422. // but this handle will be null if the output is being redirected. so do not check
  423. // for the validity of the handle. instead try to get the console buffer information
  424. // only in case you have a valid handle to the output screen buffer
  425. SecureZeroMemory( &m_csbi, sizeof( CONSOLE_SCREEN_BUFFER_INFO ) );
  426. if( IsConsoleFile(stdout) )
  427. m_hOutput = GetStdHandle( STD_OUTPUT_HANDLE );
  428. else if( IsConsoleFile(stderr) )
  429. m_hOutput = GetStdHandle( STD_ERROR_HANDLE );
  430. else
  431. m_hOutput = NULL;
  432. if ( m_hOutput != NULL )
  433. {
  434. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  435. }
  436. // initialization is successful
  437. SetLastError( NOERROR ); // clear the error
  438. SetReason( NULL_STRING ); // clear the reason
  439. return TRUE;
  440. }
  441. /*********************************************************************************************
  442. Routine Description:
  443. Initializes the GpResult utility
  444. Arguments:
  445. [in] HANDLE : Handle to the output console
  446. [in] LPCWSTR : String to display
  447. [in] const CONSOLE_SCREEN_BUFFER_INFO& : pointer to the screen buffer
  448. Return Value:
  449. NONE
  450. *********************************************************************************************/
  451. VOID PrintProgressMsg( HANDLE hOutput, LPCWSTR pwszMsg,
  452. const CONSOLE_SCREEN_BUFFER_INFO& csbi )
  453. {
  454. // local variables
  455. COORD coord;
  456. DWORD dwSize = 0;
  457. WCHAR wszSpaces[ 80 ] = L"";
  458. // check the handle. if it is null, it means that output is being redirected. so return
  459. if( hOutput == NULL )
  460. {
  461. return;
  462. }
  463. // set the cursor position
  464. coord.X = 0;
  465. coord.Y = csbi.dwCursorPosition.Y;
  466. // first erase contents on the current line
  467. SecureZeroMemory( wszSpaces, 80 );
  468. SetConsoleCursorPosition( hOutput, coord );
  469. WriteConsoleW( hOutput, Replicate( wszSpaces, L" ", 79, 79 ), 79, &dwSize, NULL );
  470. // now display the message ( if exists )
  471. SetConsoleCursorPosition( hOutput, coord );
  472. if( pwszMsg != NULL )
  473. {
  474. WriteConsoleW( hOutput, pwszMsg, lstrlen( pwszMsg ), &dwSize, NULL );
  475. }
  476. }
  477. BOOL CGpResult::CreateRsopMutex( LPWSTR szMutexName )
  478. {
  479. BOOL bResult = FALSE;
  480. SECURITY_ATTRIBUTES sa;
  481. PSECURITY_DESCRIPTOR psd = NULL;
  482. //
  483. // first try to open the mutex object by its name
  484. // if that fails it means the mutex is not yet created and
  485. // so create it now
  486. //
  487. m_hMutex = OpenMutex( SYNCHRONIZE, FALSE, szMutexName );
  488. if ( m_hMutex == NULL )
  489. {
  490. // check the error code why it failed to open
  491. if ( GetLastError() == ERROR_FILE_NOT_FOUND )
  492. {
  493. // create the security descriptor -- just set the
  494. // Dicretionary Access Control List (DACL)
  495. // in order to provide security, we will deny WRITE_OWNER and WRITE_DAC
  496. // permission to Everyone except to the owner
  497. bResult = ConvertStringSecurityDescriptorToSecurityDescriptor(
  498. L"D:(D;;WOWD;;;WD)(A;;GA;;;WD)", SDDL_REVISION_1, &psd, NULL );
  499. if ( bResult == FALSE )
  500. {
  501. // we encountered error while creating a security descriptor
  502. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  503. return FALSE;
  504. }
  505. // initialize the SECURITY_ATTRIBUTES structure
  506. SecureZeroMemory( &sa, sizeof( SECURITY_ATTRIBUTES ) );
  507. sa.nLength = sizeof( SECURITY_ATTRIBUTES );
  508. sa.lpSecurityDescriptor = psd;
  509. sa.bInheritHandle = FALSE;
  510. // mutex doesn't exist -- so we need to create it now
  511. m_hMutex = CreateMutex( &sa, FALSE, szMutexName );
  512. if (m_hMutex == NULL )
  513. {
  514. // we are not able to create the mutex
  515. // cannot proceed furthur
  516. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  517. return FALSE;
  518. }
  519. LocalFree(psd);
  520. }
  521. else
  522. {
  523. // we encounter some error
  524. // cannot proceed furthur
  525. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  526. return FALSE;
  527. }
  528. }
  529. return TRUE;
  530. }