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.

632 lines
17 KiB

  1. // *********************************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation
  4. //
  5. // Module Name:
  6. //
  7. // Init.cpp
  8. //
  9. // Abstract:
  10. //
  11. // This module implements the general initialization stuff
  12. //
  13. // Author:
  14. //
  15. // Sunil G.V.N. Murali ([email protected]) 24-Nov-2000
  16. //
  17. // Revision History:
  18. //
  19. // Sunil G.V.N. Murali ([email protected]) 24-Nov-2000 : Created It.
  20. //
  21. // *********************************************************************************
  22. #include "pch.h"
  23. #include "wmi.h"
  24. #include "tasklist.h"
  25. //
  26. // macros
  27. //
  28. #define RELEASE_MEMORY( block ) \
  29. if ( (block) != NULL ) \
  30. { \
  31. delete (block); \
  32. (block) = NULL; \
  33. } \
  34. 1
  35. #define RELEASE_MEMORY_EX( block ) \
  36. if ( (block) != NULL ) \
  37. { \
  38. delete [] (block); \
  39. (block) = NULL; \
  40. } \
  41. 1
  42. #define DESTROY_ARRAY( array ) \
  43. if ( (array) != NULL ) \
  44. { \
  45. DestroyDynamicArray( &(array) ); \
  46. (array) = NULL; \
  47. } \
  48. 1
  49. // ***************************************************************************
  50. // Routine Description:
  51. // CTaskList contructor
  52. //
  53. // Arguments:
  54. // NONE
  55. //
  56. // Return Value:
  57. // NONE
  58. //
  59. // ***************************************************************************
  60. CTaskList::CTaskList()
  61. {
  62. // init to defaults
  63. m_pWbemLocator = NULL;
  64. m_pEnumObjects = NULL;
  65. m_pWbemServices = NULL;
  66. m_pAuthIdentity = NULL;
  67. m_bVerbose = FALSE;
  68. m_bAllServices = FALSE;
  69. m_bAllModules = FALSE;
  70. m_dwFormat = 0;
  71. m_arrFilters = NULL;
  72. m_bNeedPassword = FALSE;
  73. m_bNeedModulesInfo = FALSE;
  74. m_bNeedServicesInfo = FALSE;
  75. m_bNeedWindowTitles = FALSE;
  76. m_bNeedUserContextInfo = FALSE;
  77. m_bLocalSystem = FALSE;
  78. m_pColumns = NULL;
  79. m_arrFiltersEx = NULL;
  80. m_arrWindowTitles = NULL;
  81. m_pfilterConfigs = NULL;
  82. m_dwGroupSep = 0;
  83. m_arrTasks = NULL;
  84. m_dwProcessId = 0;
  85. m_bIsHydra = FALSE;
  86. m_hServer = NULL;
  87. m_hWinstaLib = NULL;
  88. m_pProcessInfo = NULL;
  89. m_ulNumberOfProcesses = 0;
  90. m_bCloseConnection = FALSE;
  91. m_dwServicesCount = 0;
  92. m_pServicesInfo = NULL;
  93. m_pdb = NULL;
  94. m_bUseRemote = FALSE;
  95. m_pfnWinStationFreeMemory = NULL;
  96. m_pfnWinStationOpenServerW = NULL;
  97. m_pfnWinStationCloseServer = NULL;
  98. m_pfnWinStationFreeGAPMemory = NULL;
  99. m_pfnWinStationGetAllProcesses = NULL;
  100. m_pfnWinStationNameFromLogonIdW = NULL;
  101. m_pfnWinStationEnumerateProcesses = NULL;
  102. m_bUsage = FALSE;
  103. m_bLocalSystem = TRUE;
  104. m_hOutput = NULL;
  105. }
  106. // ***************************************************************************
  107. // Routine Description:
  108. // CTaskList destructor
  109. //
  110. // Arguments:
  111. // NONE
  112. //
  113. // Return Value:
  114. // NONE
  115. //
  116. // ***************************************************************************
  117. CTaskList::~CTaskList()
  118. {
  119. //
  120. // de-allocate memory allocations
  121. //
  122. //
  123. // destroy dynamic arrays
  124. DESTROY_ARRAY( m_arrTasks );
  125. DESTROY_ARRAY( m_arrFilters );
  126. DESTROY_ARRAY( m_arrFiltersEx );
  127. DESTROY_ARRAY( m_arrWindowTitles );
  128. //
  129. // memory ( with new operator )
  130. // NOTE: should not free m_pszWindowStation and m_pszDesktop
  131. RELEASE_MEMORY_EX( m_pColumns );
  132. RELEASE_MEMORY_EX( m_pfilterConfigs );
  133. //
  134. // release WMI / COM interfaces
  135. SAFE_RELEASE( m_pWbemLocator );
  136. SAFE_RELEASE( m_pWbemServices );
  137. SAFE_RELEASE( m_pEnumObjects );
  138. // free authentication identity structure
  139. // release the existing auth identity structure
  140. WbemFreeAuthIdentity( &m_pAuthIdentity );
  141. // close the connection to the remote machine
  142. if ( m_bCloseConnection == TRUE )
  143. CloseConnection( m_strUNCServer );
  144. // free the memory allocated for services variables
  145. __free( m_pServicesInfo );
  146. // free the memory allocated for performance block
  147. if ( m_pdb != NULL )
  148. {
  149. HeapFree( GetProcessHeap(), 0, m_pdb );
  150. m_pdb = NULL;
  151. }
  152. //
  153. // free winstation block
  154. if ( m_bIsHydra == FALSE && m_pProcessInfo != NULL )
  155. {
  156. // free the GAP memory block
  157. WinStationFreeGAPMemory( GAP_LEVEL_BASIC,
  158. (PTS_ALL_PROCESSES_INFO) m_pProcessInfo, m_ulNumberOfProcesses );
  159. // ...
  160. m_pProcessInfo = NULL;
  161. }
  162. else if ( m_bIsHydra == TRUE && m_pProcessInfo != NULL )
  163. {
  164. // free the winsta memory block
  165. WinStationFreeMemory( m_pProcessInfo );
  166. m_pProcessInfo = NULL;
  167. }
  168. // close the connection window station if needed
  169. if ( m_hServer != NULL )
  170. WinStationCloseServer( m_hServer );
  171. // free the library
  172. if ( m_hWinstaLib != NULL )
  173. {
  174. FreeLibrary( m_hWinstaLib );
  175. m_hWinstaLib = NULL;
  176. m_pfnWinStationFreeMemory = NULL;
  177. m_pfnWinStationOpenServerW = NULL;
  178. m_pfnWinStationCloseServer = NULL;
  179. m_pfnWinStationFreeGAPMemory = NULL;
  180. m_pfnWinStationGetAllProcesses = NULL;
  181. m_pfnWinStationEnumerateProcesses = NULL;
  182. }
  183. // un-initialize the COM library
  184. CoUninitialize();
  185. }
  186. // ***************************************************************************
  187. // Routine Description:
  188. // initialize the task list utility
  189. //
  190. // Arguments:
  191. // NONE
  192. //
  193. // Return Value:
  194. // TRUE : if filters are appropriately specified
  195. // FALSE : if filters are errorneously specified
  196. //
  197. // ***************************************************************************
  198. BOOL CTaskList::Initialize()
  199. {
  200. // local variables
  201. CHString str;
  202. LONG lTemp = 0;
  203. //
  204. // memory allocations
  205. // if at all any occurs, we know that is 'coz of the
  206. // failure in memory allocation ... so set the error
  207. SetLastError( E_OUTOFMEMORY );
  208. SaveLastError();
  209. // filters ( user supplied )
  210. if ( m_arrFilters == NULL )
  211. {
  212. m_arrFilters = CreateDynamicArray();
  213. if ( m_arrFilters == NULL )
  214. return FALSE;
  215. }
  216. // filters ( program generated parsed filters )
  217. if ( m_arrFiltersEx == NULL )
  218. {
  219. m_arrFiltersEx = CreateDynamicArray();
  220. if ( m_arrFiltersEx == NULL )
  221. return FALSE;
  222. }
  223. // columns configuration info
  224. if ( m_pColumns == NULL )
  225. {
  226. m_pColumns = new TCOLUMNS [ MAX_COLUMNS ];
  227. if ( m_pColumns == NULL )
  228. return FALSE;
  229. // init to ZERO's
  230. ZeroMemory( m_pColumns, MAX_COLUMNS * sizeof( TCOLUMNS ) );
  231. }
  232. // filters configuration info
  233. if ( m_pfilterConfigs == NULL )
  234. {
  235. m_pfilterConfigs = new TFILTERCONFIG[ MAX_FILTERS ];
  236. if ( m_pfilterConfigs == NULL )
  237. return FALSE;
  238. // init to ZERO's
  239. ZeroMemory( m_pfilterConfigs, MAX_FILTERS * sizeof( TFILTERCONFIG ) );
  240. }
  241. // window titles
  242. if ( m_arrWindowTitles == NULL )
  243. {
  244. m_arrWindowTitles = CreateDynamicArray();
  245. if ( m_arrWindowTitles == NULL )
  246. return FALSE;
  247. }
  248. // tasks
  249. if ( m_arrTasks == NULL )
  250. {
  251. m_arrTasks = CreateDynamicArray();
  252. if ( m_arrTasks == NULL )
  253. return FALSE;
  254. }
  255. // initialize the COM library
  256. if ( InitializeCom( &m_pWbemLocator ) == FALSE )
  257. return FALSE;
  258. //
  259. // get the locale specific information
  260. //
  261. try
  262. {
  263. // sub-local variables
  264. LPWSTR pwszTemp = NULL;
  265. //
  266. // get the time seperator character
  267. lTemp = GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIME, NULL, 0 );
  268. if ( lTemp == 0 )
  269. {
  270. // set the default seperator
  271. pwszTemp = m_strTimeSep.GetBufferSetLength( 2 );
  272. ZeroMemory( pwszTemp, 2 * sizeof( WCHAR ) );
  273. lstrcpy( pwszTemp, _T( ":" ) );
  274. }
  275. else
  276. {
  277. // get the time field seperator
  278. pwszTemp = m_strTimeSep.GetBufferSetLength( lTemp + 2 );
  279. ZeroMemory( pwszTemp, ( lTemp + 2 ) * sizeof( WCHAR ) );
  280. GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIME, pwszTemp, lTemp );
  281. }
  282. //
  283. // get the group seperator character
  284. lTemp = GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SGROUPING, NULL, 0 );
  285. if ( lTemp == 0 )
  286. {
  287. // we don't know how to resolve this
  288. return FALSE;
  289. }
  290. else
  291. {
  292. // get the group seperation character
  293. pwszTemp = str.GetBufferSetLength( lTemp + 2 );
  294. ZeroMemory( pwszTemp, ( lTemp + 2 ) * sizeof( WCHAR ) );
  295. GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SGROUPING, pwszTemp, lTemp );
  296. // change the group info into appropriate number
  297. lTemp = 0;
  298. m_dwGroupSep = 0;
  299. while ( lTemp < str.GetLength() )
  300. {
  301. if ( AsLong( str.Mid( lTemp, 1 ), 10 ) != 0 )
  302. m_dwGroupSep = m_dwGroupSep * 10 + AsLong( str.Mid( lTemp, 1 ), 10 );
  303. // increment by 2
  304. lTemp += 2;
  305. }
  306. }
  307. //
  308. // get the thousand seperator character
  309. lTemp = GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, NULL, 0 );
  310. if ( lTemp == 0 )
  311. {
  312. // we don't know how to resolve this
  313. return FALSE;
  314. }
  315. else
  316. {
  317. // get the thousand sepeartion charactor
  318. pwszTemp = m_strGroupThousSep.GetBufferSetLength( lTemp + 2 );
  319. ZeroMemory( pwszTemp, ( lTemp + 2 ) * sizeof( WCHAR ) );
  320. GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, pwszTemp, lTemp );
  321. }
  322. // release the CHStrig buffers
  323. str.ReleaseBuffer();
  324. m_strTimeSep.ReleaseBuffer();
  325. m_strGroupThousSep.ReleaseBuffer();
  326. }
  327. catch( ... )
  328. {
  329. // out of memory
  330. return FALSE;
  331. }
  332. //
  333. // load the winsta library and needed functions
  334. // NOTE: do not raise any error if loading of winsta dll fails
  335. m_hWinstaLib = ::LoadLibrary( WINSTA_DLLNAME );
  336. if ( m_hWinstaLib != NULL )
  337. {
  338. // library loaded successfully ... now load the addresses of functions
  339. m_pfnWinStationFreeMemory = (FUNC_WinStationFreeMemory) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationFreeMemory );
  340. m_pfnWinStationCloseServer = (FUNC_WinStationCloseServer) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationCloseServer );
  341. m_pfnWinStationOpenServerW = (FUNC_WinStationOpenServerW) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationOpenServerW );
  342. m_pfnWinStationFreeGAPMemory = (FUNC_WinStationFreeGAPMemory) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationFreeGAPMemory );
  343. m_pfnWinStationGetAllProcesses = (FUNC_WinStationGetAllProcesses) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationGetAllProcesses );
  344. m_pfnWinStationNameFromLogonIdW = (FUNC_WinStationNameFromLogonIdW) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationNameFromLogonIdW );
  345. m_pfnWinStationEnumerateProcesses = (FUNC_WinStationEnumerateProcesses) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationEnumerateProcesses );
  346. // we will keep the library loaded in memory only if all the functions were loaded successfully
  347. if ( m_pfnWinStationFreeMemory == NULL ||
  348. m_pfnWinStationCloseServer == NULL || m_pfnWinStationOpenServerW == NULL ||
  349. m_pfnWinStationFreeGAPMemory == NULL || m_pfnWinStationGetAllProcesses == NULL ||
  350. m_pfnWinStationEnumerateProcesses == NULL || m_pfnWinStationNameFromLogonIdW == NULL )
  351. {
  352. // some (or) all of the functions were not loaded ... unload the library
  353. FreeLibrary( m_hWinstaLib );
  354. m_hWinstaLib = NULL;
  355. m_pfnWinStationFreeMemory = NULL;
  356. m_pfnWinStationOpenServerW = NULL;
  357. m_pfnWinStationCloseServer = NULL;
  358. m_pfnWinStationFreeGAPMemory = NULL;
  359. m_pfnWinStationGetAllProcesses = NULL;
  360. m_pfnWinStationNameFromLogonIdW = NULL;
  361. m_pfnWinStationEnumerateProcesses = NULL;
  362. }
  363. }
  364. //
  365. // init the console scree buffer structure to zero's
  366. // and then get the console handle and screen buffer information
  367. //
  368. // prepare for status display.
  369. // for this get a handle to the screen output buffer
  370. // but this handle will be null if the output is being redirected. so do not check
  371. // for the validity of the handle. instead try to get the console buffer information
  372. // only in case you have a valid handle to the output screen buffer
  373. ZeroMemory( &m_csbi, sizeof( CONSOLE_SCREEN_BUFFER_INFO ) );
  374. m_hOutput = GetStdHandle( STD_ERROR_HANDLE );
  375. if ( m_hOutput != NULL )
  376. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  377. // enable debug privelages
  378. EnableDebugPriv();
  379. // initialization is successful
  380. SetLastError( NOERROR ); // clear the error
  381. SetReason( NULL_STRING ); // clear the reason
  382. return TRUE;
  383. }
  384. // ***************************************************************************
  385. // Routine Description:
  386. // Enables the debug privliges for the current process so that
  387. // this utility can terminate the processes on local system without any problem
  388. //
  389. // Arguments:
  390. // NONE
  391. //
  392. // Return Value:
  393. // TRUE upon successfull and FALSE if failed
  394. //
  395. // ***************************************************************************
  396. BOOL CTaskList::EnableDebugPriv()
  397. {
  398. // local variables
  399. LUID luidValue;
  400. BOOL bResult = FALSE;
  401. HANDLE hToken = NULL;
  402. TOKEN_PRIVILEGES tkp;
  403. // Retrieve a handle of the access token
  404. bResult = OpenProcessToken( GetCurrentProcess(),
  405. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken );
  406. if ( bResult == FALSE )
  407. {
  408. // save the error messaage and return
  409. SaveLastError();
  410. return FALSE;
  411. }
  412. // Enable the SE_DEBUG_NAME privilege or disable
  413. // all privileges, depends on this flag.
  414. bResult = LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luidValue );
  415. if ( bResult == FALSE )
  416. {
  417. // save the error messaage and return
  418. SaveLastError();
  419. CloseHandle( hToken );
  420. return FALSE;
  421. }
  422. // prepare the token privileges structure
  423. tkp.PrivilegeCount = 1;
  424. tkp.Privileges[ 0 ].Luid = luidValue;
  425. tkp.Privileges[ 0 ].Attributes = SE_PRIVILEGE_ENABLED;
  426. // now enable the debug privileges in the token
  427. bResult = AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof( TOKEN_PRIVILEGES ),
  428. ( PTOKEN_PRIVILEGES ) NULL, ( PDWORD ) NULL );
  429. if ( bResult == FALSE )
  430. {
  431. // The return value of AdjustTokenPrivileges be texted
  432. SaveLastError();
  433. CloseHandle( hToken );
  434. return FALSE;
  435. }
  436. // close the opened token handle
  437. CloseHandle( hToken );
  438. // enabled ... inform success
  439. return TRUE;
  440. }
  441. // ***************************************************************************
  442. // Routine Description:
  443. //
  444. // Arguments:
  445. //
  446. // Return Value:
  447. //
  448. // ***************************************************************************
  449. BOOLEAN CTaskList::WinStationFreeMemory( PVOID pBuffer )
  450. {
  451. // check the buffer and act
  452. if ( pBuffer == NULL )
  453. return TRUE;
  454. // check whether pointer exists or not
  455. if ( m_pfnWinStationFreeMemory == NULL )
  456. return FALSE;
  457. // call and return the same
  458. return ((FUNC_WinStationFreeMemory) m_pfnWinStationFreeMemory)( pBuffer );
  459. }
  460. // ***************************************************************************
  461. // Routine Description:
  462. //
  463. // Arguments:
  464. //
  465. // Return Value:
  466. //
  467. // ***************************************************************************
  468. BOOLEAN CTaskList::WinStationCloseServer( HANDLE hServer )
  469. {
  470. // check the input
  471. if ( hServer == NULL )
  472. return TRUE;
  473. // check whether the function pointer exists or not
  474. if ( m_pfnWinStationCloseServer == NULL )
  475. return FALSE;
  476. // call and return
  477. return ((FUNC_WinStationCloseServer) m_pfnWinStationCloseServer)( hServer );
  478. }
  479. // ***************************************************************************
  480. // Routine Description:
  481. //
  482. // Arguments:
  483. //
  484. // Return Value:
  485. //
  486. // ***************************************************************************
  487. HANDLE CTaskList::WinStationOpenServerW( LPWSTR pwszServerName )
  488. {
  489. // check the input & also check whether function pointer exists or not
  490. if ( pwszServerName == NULL || m_pfnWinStationOpenServerW == NULL )
  491. return NULL;
  492. // call and return
  493. return ((FUNC_WinStationOpenServerW) m_pfnWinStationOpenServerW)( pwszServerName );
  494. }
  495. // ***************************************************************************
  496. // Routine Description:
  497. //
  498. // Arguments:
  499. //
  500. // Return Value:
  501. //
  502. // ***************************************************************************
  503. BOOLEAN CTaskList::WinStationEnumerateProcesses( HANDLE hServer, PVOID* ppProcessBuffer )
  504. {
  505. // check the input and also check whether function pointer exists or not
  506. if ( ppProcessBuffer == NULL || m_pfnWinStationEnumerateProcesses == NULL )
  507. return FALSE;
  508. // call and return
  509. return ((FUNC_WinStationEnumerateProcesses)
  510. m_pfnWinStationEnumerateProcesses)( hServer, ppProcessBuffer );
  511. }
  512. // ***************************************************************************
  513. // Routine Description:
  514. //
  515. // Arguments:
  516. //
  517. // Return Value:
  518. //
  519. // ***************************************************************************
  520. BOOLEAN CTaskList::WinStationFreeGAPMemory( ULONG ulLevel, PVOID pProcessArray, ULONG ulCount )
  521. {
  522. // check the input
  523. if ( pProcessArray == NULL )
  524. return TRUE;
  525. // check whether function pointer exists or not
  526. if ( m_pfnWinStationFreeGAPMemory == NULL )
  527. return FALSE;
  528. // call and return
  529. return ((FUNC_WinStationFreeGAPMemory)
  530. m_pfnWinStationFreeGAPMemory)( ulLevel, pProcessArray, ulCount );
  531. }
  532. // ***************************************************************************
  533. // Routine Description:
  534. //
  535. // Arguments:
  536. //
  537. // Return Value:
  538. //
  539. // ***************************************************************************
  540. BOOLEAN CTaskList::WinStationGetAllProcesses( HANDLE hServer, ULONG ulLevel,
  541. ULONG* pNumberOfProcesses, PVOID* ppProcessArray )
  542. {
  543. // check the input & check whether function pointer exists or not
  544. if (pNumberOfProcesses == NULL || ppProcessArray == NULL || m_pfnWinStationGetAllProcesses == NULL)
  545. return FALSE;
  546. return ((FUNC_WinStationGetAllProcesses)
  547. m_pfnWinStationGetAllProcesses)( hServer, ulLevel, pNumberOfProcesses, ppProcessArray );
  548. }
  549. // ***************************************************************************
  550. // Routine Description:
  551. //
  552. // Arguments:
  553. //
  554. // Return Value:
  555. //
  556. // ***************************************************************************
  557. BOOLEAN CTaskList::WinStationNameFromLogonIdW( HANDLE hServer, ULONG ulLogonId, LPWSTR pwszWinStationName )
  558. {
  559. // check the input & check whether function pointer exists or not
  560. if (pwszWinStationName == NULL || m_pfnWinStationNameFromLogonIdW == NULL)
  561. return FALSE;
  562. return ((FUNC_WinStationNameFromLogonIdW)
  563. m_pfnWinStationNameFromLogonIdW)( hServer, ulLogonId, pwszWinStationName );
  564. }