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.

587 lines
16 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]) 26-Nov-2000
  16. //
  17. // Revision History:
  18. //
  19. // Sunil G.V.N. Murali ([email protected]) 26-Nov-2000 : Created It.
  20. //
  21. // *********************************************************************************
  22. #include "pch.h"
  23. #include "wmi.h"
  24. #include "taskkill.h"
  25. CTaskKill::CTaskKill()
  26. /*++
  27. Routine Description:
  28. CTaskKill contructor
  29. Arguments:
  30. NONE
  31. Return Value:
  32. NONE
  33. --*/
  34. {
  35. // init to defaults
  36. m_arrFilters = NULL;
  37. m_arrTasksToKill = NULL;
  38. m_bUsage = FALSE;
  39. m_bTree = FALSE;
  40. m_bForce = FALSE;
  41. m_dwCurrentPid = 0;
  42. m_bNeedPassword = FALSE;
  43. m_arrFiltersEx = NULL;
  44. m_bNeedServicesInfo = FALSE;
  45. m_bNeedUserContextInfo = FALSE;
  46. m_bNeedModulesInfo = FALSE;
  47. m_pfilterConfigs = NULL;
  48. m_arrWindowTitles = NULL;
  49. m_pWbemLocator = NULL;
  50. m_pWbemServices = NULL;
  51. m_pWbemEnumObjects = NULL;
  52. m_pWbemTerminateInParams = NULL;
  53. m_bIsHydra = FALSE;
  54. m_hWinstaLib = NULL;
  55. m_pProcessInfo = NULL;
  56. m_ulNumberOfProcesses = 0;
  57. m_bCloseConnection = FALSE;
  58. m_dwServicesCount = 0;
  59. m_pServicesInfo = NULL;
  60. m_bUseRemote = FALSE;
  61. m_pdb = NULL;
  62. m_pfnWinStationFreeMemory = NULL;
  63. m_pfnWinStationOpenServerW = NULL;
  64. m_pfnWinStationCloseServer = NULL;
  65. m_pfnWinStationFreeGAPMemory = NULL;
  66. m_pfnWinStationGetAllProcesses = NULL;
  67. m_pfnWinStationEnumerateProcesses = NULL;
  68. m_arrRecord = NULL;
  69. m_pAuthIdentity = NULL;
  70. m_bTasksOptimized = FALSE;
  71. m_bFiltersOptimized = FALSE;
  72. }
  73. CTaskKill::~CTaskKill()
  74. /*++
  75. Routine Description:
  76. CTaskKill destructor
  77. Arguments:
  78. NONE
  79. Return Value:
  80. NONE
  81. --*/
  82. {
  83. //
  84. // de-allocate memory allocations
  85. //
  86. //
  87. // destroy dynamic arrays
  88. DESTROY_ARRAY( m_arrRecord );
  89. DESTROY_ARRAY( m_arrFilters );
  90. DESTROY_ARRAY( m_arrFiltersEx );
  91. DESTROY_ARRAY( m_arrWindowTitles );
  92. DESTROY_ARRAY( m_arrTasksToKill );
  93. //
  94. // memory ( with new operator )
  95. RELEASE_MEMORY_EX( m_pfilterConfigs );
  96. //
  97. // release WMI / COM interfaces
  98. SAFE_RELEASE( m_pWbemLocator );
  99. SAFE_RELEASE( m_pWbemServices );
  100. SAFE_RELEASE( m_pWbemEnumObjects );
  101. SAFE_RELEASE( m_pWbemTerminateInParams );
  102. // free the wmi authentication structure
  103. WbemFreeAuthIdentity( &m_pAuthIdentity );
  104. // if connection to the remote system opened with NET API has to be closed .. do it
  105. if ( m_bCloseConnection == TRUE )
  106. {
  107. CloseConnection( m_strServer );
  108. }
  109. // free the memory allocated for services variables
  110. FreeMemory( ( LPVOID * )&m_pServicesInfo );
  111. // free the memory allocated for performance block
  112. FreeMemory( ( LPVOID * ) &m_pdb );
  113. //
  114. // free winstation block
  115. if ( ( FALSE == m_bIsHydra ) && ( NULL != m_pProcessInfo ) )
  116. {
  117. // free the GAP memory block
  118. WinStationFreeGAPMemory( GAP_LEVEL_BASIC,
  119. (PTS_ALL_PROCESSES_INFO) m_pProcessInfo, m_ulNumberOfProcesses );
  120. // ...
  121. m_pProcessInfo = NULL;
  122. }
  123. else
  124. {
  125. if ( ( TRUE == m_bIsHydra ) && ( NULL != m_pProcessInfo ) )
  126. {
  127. // free the winsta memory block
  128. WinStationFreeMemory( m_pProcessInfo );
  129. m_pProcessInfo = NULL;
  130. }
  131. }
  132. // free the library
  133. if ( NULL != m_hWinstaLib )
  134. {
  135. FreeLibrary( m_hWinstaLib );
  136. m_hWinstaLib = NULL;
  137. m_pfnWinStationFreeMemory = NULL;
  138. m_pfnWinStationOpenServerW = NULL;
  139. m_pfnWinStationCloseServer = NULL;
  140. m_pfnWinStationFreeGAPMemory = NULL;
  141. m_pfnWinStationGetAllProcesses = NULL;
  142. m_pfnWinStationEnumerateProcesses = NULL;
  143. }
  144. // uninitialize the com library
  145. CoUninitialize();
  146. }
  147. BOOL
  148. CTaskKill::Initialize(
  149. void
  150. )
  151. /*++
  152. Routine Description:
  153. initialize the task list utility
  154. Arguments:
  155. NONE
  156. Return Value:
  157. TRUE : if filters are appropriately specified
  158. FALSE : if filters are errorneously specified
  159. --*/
  160. {
  161. //
  162. // memory allocations
  163. // if at all any occurs, we know that is 'coz of the
  164. // failure in memory allocation ... so set the error
  165. SetLastError( ( DWORD )E_OUTOFMEMORY );
  166. SaveLastError();
  167. // get the current process id and save it
  168. m_dwCurrentPid = GetCurrentProcessId();
  169. // filters ( user supplied )
  170. if ( NULL == m_arrFilters )
  171. {
  172. m_arrFilters = CreateDynamicArray();
  173. if ( NULL == m_arrFilters )
  174. {
  175. return FALSE;
  176. }
  177. }
  178. // tasks to be killed ( user supplied )
  179. if ( NULL == m_arrTasksToKill )
  180. {
  181. m_arrTasksToKill = CreateDynamicArray();
  182. if ( NULL == m_arrTasksToKill )
  183. {
  184. return FALSE;
  185. }
  186. }
  187. // filters ( program generated parsed filters )
  188. if ( NULL == m_arrFiltersEx )
  189. {
  190. m_arrFiltersEx = CreateDynamicArray();
  191. if ( NULL == m_arrFiltersEx )
  192. {
  193. return FALSE;
  194. }
  195. }
  196. // filters configuration info
  197. if ( NULL == m_pfilterConfigs )
  198. {
  199. m_pfilterConfigs = ( TFILTERCONFIG * )AllocateMemory( sizeof( TFILTERCONFIG ) * MAX_FILTERS );
  200. if ( NULL == m_pfilterConfigs )
  201. {
  202. return FALSE;
  203. }
  204. // init to ZERO's
  205. SecureZeroMemory( m_pfilterConfigs, MAX_FILTERS * sizeof( TFILTERCONFIG ) );
  206. }
  207. // window titles
  208. if ( NULL == m_arrWindowTitles )
  209. {
  210. m_arrWindowTitles = CreateDynamicArray();
  211. if ( NULL == m_arrWindowTitles )
  212. {
  213. return FALSE;
  214. }
  215. }
  216. // tasks
  217. if ( NULL == m_arrRecord )
  218. {
  219. m_arrRecord = CreateDynamicArray();
  220. if ( NULL == m_arrRecord )
  221. {
  222. return FALSE;
  223. }
  224. }
  225. // initialize the COM library
  226. if ( FALSE == InitializeCom( &m_pWbemLocator ) )
  227. {
  228. return FALSE;
  229. }
  230. //
  231. // load the winsta library and needed functions
  232. // NOTE: do not raise any error if loading of winsta dll fails
  233. { // Local variabels should be destroyed inside this block.
  234. // +1 is for terminating NULL character.
  235. LPWSTR lpszSystemPath = NULL;
  236. DWORD dwLength = MAX_PATH + 1;
  237. DWORD dwExpectedLength = 0;
  238. DWORD dwActualBufLen = 0;
  239. do
  240. {
  241. dwActualBufLen = dwLength + 5 + StringLength( WINSTA_DLLNAME, 0 );
  242. // Length of 'System32' + Length of '\' + Length of 'WINSTA_DLLNAME' + Length of '\0'.
  243. // 3 WCHARS are extra, to be on safer side.
  244. lpszSystemPath = (LPWSTR) AllocateMemory( dwActualBufLen * sizeof( WCHAR ) );
  245. if( NULL == lpszSystemPath )
  246. { // Out of memory.
  247. m_hWinstaLib = NULL;
  248. break;
  249. }
  250. dwExpectedLength = GetSystemDirectory( lpszSystemPath, dwLength );
  251. if( ( 0 != dwExpectedLength ) ||
  252. ( dwLength > dwExpectedLength ) )
  253. { // Successful
  254. StringConcat( lpszSystemPath, L"\\", dwActualBufLen );
  255. StringConcat( lpszSystemPath, WINSTA_DLLNAME, dwActualBufLen );
  256. m_hWinstaLib = ::LoadLibrary( lpszSystemPath );
  257. FreeMemory( (LPVOID * )&lpszSystemPath );
  258. break;
  259. }
  260. FreeMemory( (LPVOID * )&lpszSystemPath );
  261. m_hWinstaLib = NULL;
  262. // +1 is for terminating NULL character.
  263. dwLength = dwExpectedLength + 1;
  264. }while( 0 != dwExpectedLength );
  265. }
  266. if ( NULL != m_hWinstaLib )
  267. {
  268. // library loaded successfully ... now load the addresses of functions
  269. m_pfnWinStationFreeMemory = (FUNC_WinStationFreeMemory) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationFreeMemory );
  270. m_pfnWinStationCloseServer = (FUNC_WinStationCloseServer) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationCloseServer );
  271. m_pfnWinStationOpenServerW = (FUNC_WinStationOpenServerW) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationOpenServerW );
  272. m_pfnWinStationFreeGAPMemory = (FUNC_WinStationFreeGAPMemory) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationFreeGAPMemory );
  273. m_pfnWinStationGetAllProcesses = (FUNC_WinStationGetAllProcesses) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationGetAllProcesses );
  274. m_pfnWinStationEnumerateProcesses = (FUNC_WinStationEnumerateProcesses) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationEnumerateProcesses );
  275. // we will keep the library loaded in memory only if all the functions were loaded successfully
  276. if ( ( NULL == m_pfnWinStationFreeMemory ) ||
  277. ( NULL == m_pfnWinStationCloseServer ) ||
  278. ( NULL == m_pfnWinStationOpenServerW ) ||
  279. ( NULL == m_pfnWinStationFreeGAPMemory ) ||
  280. ( NULL == m_pfnWinStationGetAllProcesses ) ||
  281. ( NULL == m_pfnWinStationEnumerateProcesses )
  282. )
  283. {
  284. // some (or) all of the functions were not loaded ... unload the library
  285. FreeLibrary( m_hWinstaLib );
  286. m_hWinstaLib = NULL;
  287. m_pfnWinStationFreeMemory = NULL;
  288. m_pfnWinStationOpenServerW = NULL;
  289. m_pfnWinStationCloseServer = NULL;
  290. m_pfnWinStationFreeGAPMemory = NULL;
  291. m_pfnWinStationGetAllProcesses = NULL;
  292. m_pfnWinStationEnumerateProcesses = NULL;
  293. }
  294. }
  295. // initialization is successful
  296. SetLastError( ( DWORD )NOERROR ); // clear the error
  297. SetReason( NULL_STRING ); // clear the reason
  298. return TRUE;
  299. }
  300. BOOL
  301. CTaskKill::EnableDebugPriv(
  302. void
  303. )
  304. /*++
  305. Routine Description:
  306. Enables the debug privliges for the current process so that
  307. this utility can terminate the processes on local system without any problem
  308. Arguments:
  309. NONE
  310. Return Value:
  311. TRUE upon successfull and FALSE if failed
  312. --*/
  313. {
  314. // local variables
  315. LUID luidValue ;
  316. BOOL bResult = FALSE;
  317. HANDLE hToken = NULL;
  318. TOKEN_PRIVILEGES tkp;
  319. SecureZeroMemory( &luidValue, sizeof( LUID ) );
  320. SecureZeroMemory( &tkp, sizeof( TOKEN_PRIVILEGES ) );
  321. // Retrieve a handle of the access token
  322. bResult = OpenProcessToken( GetCurrentProcess(),
  323. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken );
  324. if ( FALSE == bResult )
  325. {
  326. // save the error messaage and return
  327. SaveLastError();
  328. return FALSE;
  329. }
  330. // Enable the SE_DEBUG_NAME privilege or disable
  331. // all privileges, depends on this flag.
  332. bResult = LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luidValue );
  333. if ( FALSE == bResult )
  334. {
  335. // save the error messaage and return
  336. SaveLastError();
  337. CloseHandle( hToken );
  338. return FALSE;
  339. }
  340. // prepare the token privileges structure
  341. tkp.PrivilegeCount = 1;
  342. tkp.Privileges[ 0 ].Luid = luidValue;
  343. tkp.Privileges[ 0 ].Attributes = SE_PRIVILEGE_ENABLED;
  344. // now enable the debug privileges in the token
  345. bResult = AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof( TOKEN_PRIVILEGES ),
  346. ( PTOKEN_PRIVILEGES ) NULL, ( PDWORD ) NULL );
  347. if ( FALSE == bResult )
  348. {
  349. // The return value of AdjustTokenPrivileges be texted
  350. SaveLastError();
  351. CloseHandle( hToken );
  352. return FALSE;
  353. }
  354. // close the opened token handle
  355. CloseHandle( hToken );
  356. // enabled ... inform success
  357. return TRUE;
  358. }
  359. BOOLEAN
  360. CTaskKill::WinStationFreeMemory(
  361. IN PVOID pBuffer
  362. )
  363. /*++
  364. Routine Description:
  365. Free memory.
  366. Arguments:
  367. [in] pBuffer : Cotains memory location to free.
  368. Return Value:
  369. TRUE if successful else FALSE is returned.
  370. --*/
  371. {
  372. // check the buffer and act
  373. if ( NULL == pBuffer )
  374. {
  375. return TRUE;
  376. }
  377. // check whether pointer exists or not
  378. if ( NULL == m_pfnWinStationFreeMemory )
  379. {
  380. return FALSE;
  381. }
  382. // call and return the same
  383. return ((FUNC_WinStationFreeMemory) m_pfnWinStationFreeMemory)( pBuffer );
  384. }
  385. BOOLEAN
  386. CTaskKill::WinStationCloseServer(
  387. IN HANDLE hServer
  388. )
  389. /*++
  390. Routine Description:
  391. Handle to window station is closed.
  392. Arguments:
  393. [in] hServer : Handle to window station.
  394. Return Value:
  395. TRUE if successful else FALSE is returned.
  396. --*/
  397. {
  398. // check the input
  399. if ( NULL == hServer )
  400. {
  401. return TRUE;
  402. }
  403. // check whether the function pointer exists or not
  404. if ( NULL == m_pfnWinStationCloseServer )
  405. {
  406. return FALSE;
  407. }
  408. // call and return
  409. return ((FUNC_WinStationCloseServer) m_pfnWinStationCloseServer)( hServer );
  410. }
  411. HANDLE
  412. CTaskKill::WinStationOpenServerW(
  413. IN LPWSTR pwszServerName
  414. )
  415. /*++
  416. Routine Description:
  417. Retrieves a handle to an window station on a system.
  418. Arguments:
  419. [in] pwszServerName : System name from where to retrieve window station handle.
  420. Return Value:
  421. Valid handle is returned if successful else NULL is returned.
  422. --*/
  423. {
  424. // check the input & also check whether function pointer exists or not
  425. if ( ( NULL == pwszServerName ) ||
  426. ( NULL == m_pfnWinStationOpenServerW ) )
  427. {
  428. return NULL;
  429. }
  430. // call and return
  431. return ((FUNC_WinStationOpenServerW) m_pfnWinStationOpenServerW)( pwszServerName );
  432. }
  433. BOOLEAN
  434. CTaskKill::WinStationEnumerateProcesses(
  435. IN HANDLE hServer,
  436. OUT PVOID* ppProcessBuffer
  437. )
  438. /*++
  439. Routine Description:
  440. Retrieves process running on a system.
  441. Arguments:
  442. [in] hServer : Cotains handle to window station.
  443. [ out ] ppProcessBuffer : Contains process infomration on remote system.
  444. Return Value:
  445. TRUE if successful else FALSE is returned.
  446. --*/
  447. {
  448. // check the input and also check whether function pointer exists or not
  449. if ( ( NULL == ppProcessBuffer ) ||
  450. ( NULL == m_pfnWinStationEnumerateProcesses ) )
  451. {
  452. return FALSE;
  453. }
  454. // call and return
  455. return ((FUNC_WinStationEnumerateProcesses)
  456. m_pfnWinStationEnumerateProcesses)( hServer, ppProcessBuffer );
  457. }
  458. BOOLEAN
  459. CTaskKill::WinStationFreeGAPMemory(
  460. IN ULONG ulLevel,
  461. IN PVOID pProcessArray,
  462. IN ULONG ulCount
  463. )
  464. /*++
  465. Routine Description:
  466. Free gap memory block.
  467. Arguments:
  468. [in] ulLevel : Contains information level of data.
  469. [ in ] pProcessArray : Contains data to be freed.
  470. [ in ] ulCount : Contains number of blocks to be freed.
  471. Return Value:
  472. TRUE if successful else FALSE is returned.
  473. --*/
  474. {
  475. // check the input
  476. if ( NULL == pProcessArray )
  477. {
  478. return TRUE;
  479. }
  480. // check whether function pointer exists or not
  481. if ( NULL == m_pfnWinStationFreeGAPMemory )
  482. {
  483. return FALSE;
  484. }
  485. // call and return
  486. return ((FUNC_WinStationFreeGAPMemory)
  487. m_pfnWinStationFreeGAPMemory)( ulLevel, pProcessArray, ulCount );
  488. }
  489. BOOLEAN
  490. CTaskKill::WinStationGetAllProcesses(
  491. IN HANDLE hServer,
  492. IN ULONG ulLevel,
  493. OUT ULONG* pNumberOfProcesses,
  494. OUT PVOID* ppProcessArray
  495. )
  496. /*++
  497. Routine Description:
  498. Retrieves process information running on a system.
  499. Arguments:
  500. [in] hServer : Cotains handle to window station.
  501. [ in ] ulLevel : Contains information level of data.
  502. [ out ] pNumberOfProcesses : Contains number of process retrieved.
  503. [ out ] ppProcessArray : Contains process realted infomration.
  504. Return Value:
  505. TRUE if successful else FALSE is returned.
  506. --*/
  507. {
  508. // check the input & check whether function pointer exists or not
  509. if ( ( NULL == pNumberOfProcesses ) ||
  510. ( NULL == ppProcessArray ) ||
  511. ( NULL == m_pfnWinStationGetAllProcesses ) )
  512. {
  513. return FALSE;
  514. }
  515. return ((FUNC_WinStationGetAllProcesses)
  516. m_pfnWinStationGetAllProcesses)( hServer, ulLevel, pNumberOfProcesses, ppProcessArray );
  517. }