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.

484 lines
14 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. // ***************************************************************************
  26. // Routine Description:
  27. // CTaskKill contructor
  28. //
  29. // Arguments:
  30. // NONE
  31. //
  32. // Return Value:
  33. // NONE
  34. //
  35. // ***************************************************************************
  36. CTaskKill::CTaskKill()
  37. {
  38. // init to defaults
  39. m_arrFilters = NULL;
  40. m_arrTasksToKill = NULL;
  41. m_bUsage = FALSE;
  42. m_bTree = FALSE;
  43. m_bForce = FALSE;
  44. m_dwCurrentPid = 0;
  45. m_bNeedPassword = FALSE;
  46. m_arrFiltersEx = NULL;
  47. m_bNeedServicesInfo = FALSE;
  48. m_bNeedUserContextInfo = FALSE;
  49. m_bNeedModulesInfo = FALSE;
  50. m_pfilterConfigs = NULL;
  51. m_arrWindowTitles = NULL;
  52. m_pWbemLocator = NULL;
  53. m_pWbemServices = NULL;
  54. m_pWbemEnumObjects = NULL;
  55. m_pWbemTerminateInParams = NULL;
  56. m_bIsHydra = FALSE;
  57. m_hWinstaLib = NULL;
  58. m_pProcessInfo = NULL;
  59. m_ulNumberOfProcesses = 0;
  60. m_bCloseConnection = FALSE;
  61. m_dwServicesCount = 0;
  62. m_pServicesInfo = NULL;
  63. m_bUseRemote = FALSE;
  64. m_pdb = NULL;
  65. m_pfnWinStationFreeMemory = NULL;
  66. m_pfnWinStationOpenServerW = NULL;
  67. m_pfnWinStationCloseServer = NULL;
  68. m_pfnWinStationFreeGAPMemory = NULL;
  69. m_pfnWinStationGetAllProcesses = NULL;
  70. m_pfnWinStationEnumerateProcesses = NULL;
  71. m_arrRecord = NULL;
  72. m_pAuthIdentity = NULL;
  73. m_bTasksOptimized = FALSE;
  74. m_bFiltersOptimized = FALSE;
  75. m_hOutput = NULL;
  76. }
  77. // ***************************************************************************
  78. // Routine Description:
  79. // CTaskKill destructor
  80. //
  81. // Arguments:
  82. // NONE
  83. //
  84. // Return Value:
  85. // NONE
  86. //
  87. // ***************************************************************************
  88. CTaskKill::~CTaskKill()
  89. {
  90. //
  91. // de-allocate memory allocations
  92. //
  93. //
  94. // destroy dynamic arrays
  95. DESTROY_ARRAY( m_arrRecord );
  96. DESTROY_ARRAY( m_arrFilters );
  97. DESTROY_ARRAY( m_arrFiltersEx );
  98. DESTROY_ARRAY( m_arrWindowTitles );
  99. DESTROY_ARRAY( m_arrTasksToKill );
  100. //
  101. // memory ( with new operator )
  102. RELEASE_MEMORY_EX( m_pfilterConfigs );
  103. //
  104. // release WMI / COM interfaces
  105. SAFE_RELEASE( m_pWbemLocator );
  106. SAFE_RELEASE( m_pWbemServices );
  107. SAFE_RELEASE( m_pWbemEnumObjects );
  108. SAFE_RELEASE( m_pWbemTerminateInParams );
  109. // free the wmi authentication structure
  110. WbemFreeAuthIdentity( &m_pAuthIdentity );
  111. // if connection to the remote system opened with NET API has to be closed .. do it
  112. if ( m_bCloseConnection == TRUE )
  113. CloseConnection( m_strServer );
  114. // free the memory allocated for services variables
  115. __free( m_pServicesInfo );
  116. // free the memory allocated for performance block
  117. if ( m_pdb != NULL )
  118. {
  119. HeapFree( GetProcessHeap(), 0, m_pdb );
  120. m_pdb = NULL;
  121. }
  122. //
  123. // free winstation block
  124. if ( m_bIsHydra == FALSE && m_pProcessInfo != NULL )
  125. {
  126. // free the GAP memory block
  127. WinStationFreeGAPMemory( GAP_LEVEL_BASIC,
  128. (PTS_ALL_PROCESSES_INFO) m_pProcessInfo, m_ulNumberOfProcesses );
  129. // ...
  130. m_pProcessInfo = NULL;
  131. }
  132. else if ( m_bIsHydra == TRUE && m_pProcessInfo != NULL )
  133. {
  134. // free the winsta memory block
  135. WinStationFreeMemory( m_pProcessInfo );
  136. m_pProcessInfo = NULL;
  137. }
  138. // free the library
  139. if ( m_hWinstaLib != NULL )
  140. {
  141. FreeLibrary( m_hWinstaLib );
  142. m_hWinstaLib = NULL;
  143. m_pfnWinStationFreeMemory = NULL;
  144. m_pfnWinStationOpenServerW = NULL;
  145. m_pfnWinStationCloseServer = NULL;
  146. m_pfnWinStationFreeGAPMemory = NULL;
  147. m_pfnWinStationGetAllProcesses = NULL;
  148. m_pfnWinStationEnumerateProcesses = NULL;
  149. }
  150. // uninitialize the com library
  151. CoUninitialize();
  152. }
  153. // ***************************************************************************
  154. // Routine Description:
  155. // initialize the task list utility
  156. //
  157. // Arguments:
  158. // NONE
  159. //
  160. // Return Value:
  161. // TRUE : if filters are appropriately specified
  162. // FALSE : if filters are errorneously specified
  163. //
  164. // ***************************************************************************
  165. BOOL CTaskKill::Initialize()
  166. {
  167. //
  168. // memory allocations
  169. // if at all any occurs, we know that is 'coz of the
  170. // failure in memory allocation ... so set the error
  171. SetLastError( E_OUTOFMEMORY );
  172. SaveLastError();
  173. // get the current process id and save it
  174. m_dwCurrentPid = GetCurrentProcessId();
  175. // filters ( user supplied )
  176. if ( m_arrFilters == NULL )
  177. {
  178. m_arrFilters = CreateDynamicArray();
  179. if ( m_arrFilters == NULL )
  180. return FALSE;
  181. }
  182. // tasks to be killed ( user supplied )
  183. if ( m_arrTasksToKill == NULL )
  184. {
  185. m_arrTasksToKill = CreateDynamicArray();
  186. if ( m_arrTasksToKill == NULL )
  187. return FALSE;
  188. }
  189. // filters ( program generated parsed filters )
  190. if ( m_arrFiltersEx == NULL )
  191. {
  192. m_arrFiltersEx = CreateDynamicArray();
  193. if ( m_arrFiltersEx == NULL )
  194. return FALSE;
  195. }
  196. // filters configuration info
  197. if ( m_pfilterConfigs == NULL )
  198. {
  199. m_pfilterConfigs = new TFILTERCONFIG[ MAX_FILTERS ];
  200. if ( m_pfilterConfigs == NULL )
  201. return FALSE;
  202. // init to ZERO's
  203. ZeroMemory( m_pfilterConfigs, MAX_FILTERS * sizeof( TFILTERCONFIG ) );
  204. }
  205. // window titles
  206. if ( m_arrWindowTitles == NULL )
  207. {
  208. m_arrWindowTitles = CreateDynamicArray();
  209. if ( m_arrWindowTitles == NULL )
  210. return FALSE;
  211. }
  212. // tasks
  213. if ( m_arrRecord == NULL )
  214. {
  215. m_arrRecord = CreateDynamicArray();
  216. if ( m_arrRecord == NULL )
  217. return FALSE;
  218. }
  219. // initialize the COM library
  220. if ( InitializeCom( &m_pWbemLocator ) == FALSE )
  221. return FALSE;
  222. //
  223. // load the winsta library and needed functions
  224. // NOTE: do not raise any error if loading of winsta dll fails
  225. m_hWinstaLib = ::LoadLibrary( WINSTA_DLLNAME );
  226. if ( m_hWinstaLib != NULL )
  227. {
  228. // library loaded successfully ... now load the addresses of functions
  229. m_pfnWinStationFreeMemory = (FUNC_WinStationFreeMemory) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationFreeMemory );
  230. m_pfnWinStationCloseServer = (FUNC_WinStationCloseServer) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationCloseServer );
  231. m_pfnWinStationOpenServerW = (FUNC_WinStationOpenServerW) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationOpenServerW );
  232. m_pfnWinStationFreeGAPMemory = (FUNC_WinStationFreeGAPMemory) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationFreeGAPMemory );
  233. m_pfnWinStationGetAllProcesses = (FUNC_WinStationGetAllProcesses) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationGetAllProcesses );
  234. m_pfnWinStationEnumerateProcesses = (FUNC_WinStationEnumerateProcesses) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationEnumerateProcesses );
  235. // we will keep the library loaded in memory only if all the functions were loaded successfully
  236. if ( m_pfnWinStationFreeMemory == NULL || m_pfnWinStationCloseServer == NULL ||
  237. m_pfnWinStationOpenServerW == NULL || m_pfnWinStationFreeGAPMemory == NULL ||
  238. m_pfnWinStationGetAllProcesses == NULL || m_pfnWinStationEnumerateProcesses == NULL )
  239. {
  240. // some (or) all of the functions were not loaded ... unload the library
  241. FreeLibrary( m_hWinstaLib );
  242. m_hWinstaLib = NULL;
  243. m_pfnWinStationFreeMemory = NULL;
  244. m_pfnWinStationOpenServerW = NULL;
  245. m_pfnWinStationCloseServer = NULL;
  246. m_pfnWinStationFreeGAPMemory = NULL;
  247. m_pfnWinStationGetAllProcesses = NULL;
  248. m_pfnWinStationEnumerateProcesses = NULL;
  249. }
  250. }
  251. //
  252. // init the console scree buffer structure to zero's
  253. // and then get the console handle and screen buffer information
  254. //
  255. // prepare for status display.
  256. // for this get a handle to the screen output buffer
  257. // but this handle will be null if the output is being redirected. so do not check
  258. // for the validity of the handle. instead try to get the console buffer information
  259. // only in case you have a valid handle to the output screen buffer
  260. ZeroMemory( &m_csbi, sizeof( CONSOLE_SCREEN_BUFFER_INFO ) );
  261. m_hOutput = GetStdHandle( STD_ERROR_HANDLE );
  262. if ( m_hOutput != NULL )
  263. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  264. // initialization is successful
  265. SetLastError( NOERROR ); // clear the error
  266. SetReason( NULL_STRING ); // clear the reason
  267. return TRUE;
  268. }
  269. // ***************************************************************************
  270. // Routine Description:
  271. // Enables the debug privliges for the current process so that
  272. // this utility can terminate the processes on local system without any problem
  273. //
  274. // Arguments:
  275. // NONE
  276. //
  277. // Return Value:
  278. // TRUE upon successfull and FALSE if failed
  279. //
  280. // ***************************************************************************
  281. BOOL CTaskKill::EnableDebugPriv()
  282. {
  283. // local variables
  284. LUID luidValue;
  285. BOOL bResult = FALSE;
  286. HANDLE hToken = NULL;
  287. TOKEN_PRIVILEGES tkp;
  288. // Retrieve a handle of the access token
  289. bResult = OpenProcessToken( GetCurrentProcess(),
  290. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken );
  291. if ( bResult == FALSE )
  292. {
  293. // save the error messaage and return
  294. SaveLastError();
  295. return FALSE;
  296. }
  297. // Enable the SE_DEBUG_NAME privilege or disable
  298. // all privileges, depends on this flag.
  299. bResult = LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luidValue );
  300. if ( bResult == FALSE )
  301. {
  302. // save the error messaage and return
  303. SaveLastError();
  304. CloseHandle( hToken );
  305. return FALSE;
  306. }
  307. // prepare the token privileges structure
  308. tkp.PrivilegeCount = 1;
  309. tkp.Privileges[ 0 ].Luid = luidValue;
  310. tkp.Privileges[ 0 ].Attributes = SE_PRIVILEGE_ENABLED;
  311. // now enable the debug privileges in the token
  312. bResult = AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof( TOKEN_PRIVILEGES ),
  313. ( PTOKEN_PRIVILEGES ) NULL, ( PDWORD ) NULL );
  314. if ( bResult == FALSE )
  315. {
  316. // The return value of AdjustTokenPrivileges be texted
  317. SaveLastError();
  318. CloseHandle( hToken );
  319. return FALSE;
  320. }
  321. // close the opened handle object
  322. CloseHandle( hToken );
  323. // enabled ... inform success
  324. return TRUE;
  325. }
  326. // ***************************************************************************
  327. // Routine Description:
  328. //
  329. // Arguments:
  330. //
  331. // Return Value:
  332. //
  333. // ***************************************************************************
  334. BOOLEAN CTaskKill::WinStationFreeMemory( PVOID pBuffer )
  335. {
  336. // check the buffer and act
  337. if ( pBuffer == NULL )
  338. return TRUE;
  339. // check whether pointer exists or not
  340. if ( m_pfnWinStationFreeMemory == NULL )
  341. return FALSE;
  342. // call and return the same
  343. return ((FUNC_WinStationFreeMemory) m_pfnWinStationFreeMemory)( pBuffer );
  344. }
  345. // ***************************************************************************
  346. // Routine Description:
  347. //
  348. // Arguments:
  349. //
  350. // Return Value:
  351. //
  352. // ***************************************************************************
  353. BOOLEAN CTaskKill::WinStationCloseServer( HANDLE hServer )
  354. {
  355. // check the input
  356. if ( hServer == NULL )
  357. return TRUE;
  358. // check whether the function pointer exists or not
  359. if ( m_pfnWinStationCloseServer == NULL )
  360. return FALSE;
  361. // call and return
  362. return ((FUNC_WinStationCloseServer) m_pfnWinStationCloseServer)( hServer );
  363. }
  364. // ***************************************************************************
  365. // Routine Description:
  366. //
  367. // Arguments:
  368. //
  369. // Return Value:
  370. //
  371. // ***************************************************************************
  372. HANDLE CTaskKill::WinStationOpenServerW( LPWSTR pwszServerName )
  373. {
  374. // check the input & also check whether function pointer exists or not
  375. if ( pwszServerName == NULL || m_pfnWinStationOpenServerW == NULL )
  376. return NULL;
  377. // call and return
  378. return ((FUNC_WinStationOpenServerW) m_pfnWinStationOpenServerW)( pwszServerName );
  379. }
  380. // ***************************************************************************
  381. // Routine Description:
  382. //
  383. // Arguments:
  384. //
  385. // Return Value:
  386. //
  387. // ***************************************************************************
  388. BOOLEAN CTaskKill::WinStationEnumerateProcesses( HANDLE hServer, PVOID* ppProcessBuffer )
  389. {
  390. // check the input and also check whether function pointer exists or not
  391. if ( ppProcessBuffer == NULL || m_pfnWinStationEnumerateProcesses == NULL )
  392. return FALSE;
  393. // call and return
  394. return ((FUNC_WinStationEnumerateProcesses)
  395. m_pfnWinStationEnumerateProcesses)( hServer, ppProcessBuffer );
  396. }
  397. // ***************************************************************************
  398. // Routine Description:
  399. //
  400. // Arguments:
  401. //
  402. // Return Value:
  403. //
  404. // ***************************************************************************
  405. BOOLEAN CTaskKill::WinStationFreeGAPMemory( ULONG ulLevel, PVOID pProcessArray, ULONG ulCount )
  406. {
  407. // check the input
  408. if ( pProcessArray == NULL )
  409. return TRUE;
  410. // check whether function pointer exists or not
  411. if ( m_pfnWinStationFreeGAPMemory == NULL )
  412. return FALSE;
  413. // call and return
  414. return ((FUNC_WinStationFreeGAPMemory)
  415. m_pfnWinStationFreeGAPMemory)( ulLevel, pProcessArray, ulCount );
  416. }
  417. // ***************************************************************************
  418. // Routine Description:
  419. //
  420. // Arguments:
  421. //
  422. // Return Value:
  423. //
  424. // ***************************************************************************
  425. BOOLEAN CTaskKill::WinStationGetAllProcesses( HANDLE hServer, ULONG ulLevel,
  426. ULONG* pNumberOfProcesses, PVOID* ppProcessArray )
  427. {
  428. // check the input & check whether function pointer exists or not
  429. if (pNumberOfProcesses == NULL || ppProcessArray == NULL || m_pfnWinStationGetAllProcesses == NULL)
  430. return FALSE;
  431. return ((FUNC_WinStationGetAllProcesses)
  432. m_pfnWinStationGetAllProcesses)( hServer, ulLevel, pNumberOfProcesses, ppProcessArray );
  433. }