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.

561 lines
16 KiB

  1. /****************************************************************************
  2. Copyright (c) Microsoft Corporation 1998
  3. All rights reserved
  4. File: ApplDlg.CPP
  5. ***************************************************************************/
  6. #include "pch.h"
  7. #include <winperf.h>
  8. #include "utils.h"
  9. #include <commctrl.h>
  10. DEFINE_MODULE("RIPREP")
  11. #define INITIAL_SIZE 51200
  12. #define EXTEND_SIZE 25600
  13. #define REGKEY_PERF L"software\\microsoft\\windows nt\\currentversion\\perflib"
  14. #define REGSUBKEY_COUNTERS L"Counters"
  15. #define PROCESS_COUNTER L"process"
  16. // Globals
  17. LPBYTE g_pBuffer = NULL;
  18. DWORD g_cbBuffer = 1;
  19. typedef struct _TASKITEM {
  20. LPWSTR pszImageName;
  21. LPWSTR pszServiceName;
  22. DWORD dwProcessId;
  23. } TASKITEM, * LPTASKITEM;
  24. //
  25. // GetServiceProcessInfo( )
  26. //
  27. // BORROWED FROM "TLIST"'s common.c
  28. //
  29. DWORD
  30. GetServiceProcessInfo(
  31. LPENUM_SERVICE_STATUS_PROCESS* ppInfo
  32. )
  33. /*++
  34. Routine Description:
  35. Provides an API for getting a list of process information for Win 32
  36. services that are running at the time of the API call.
  37. Arguments:
  38. ppInfo - address of a pointer to return the information.
  39. *ppInfo points to memory allocated with malloc.
  40. Return Value:
  41. Number of ENUM_SERVICE_STATUS_PROCESS structures pointed at by *ppInfo.
  42. --*/
  43. {
  44. DWORD dwNumServices = 0;
  45. SC_HANDLE hScm;
  46. TraceFunc( "GetServiceProcessInfo( )\n" );
  47. // Initialize the output parmeter.
  48. *ppInfo = NULL;
  49. // Connect to the service controller.
  50. //
  51. hScm = OpenSCManager(
  52. NULL,
  53. NULL,
  54. SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
  55. if (hScm) {
  56. LPENUM_SERVICE_STATUS_PROCESS pInfo = NULL;
  57. DWORD cbInfo = 4 * 1024;
  58. DWORD dwErr = ERROR_SUCCESS;
  59. DWORD dwResume = 0;
  60. DWORD cLoop = 0;
  61. const DWORD cLoopMax = 2;
  62. // First pass through the loop allocates from an initial guess. (4K)
  63. // If that isn't sufficient, we make another pass and allocate
  64. // what is actually needed. (We only go through the loop a
  65. // maximum of two times.)
  66. //
  67. do {
  68. if (pInfo != NULL) {
  69. TraceFree(pInfo);
  70. }
  71. pInfo = (LPENUM_SERVICE_STATUS_PROCESS)TraceAlloc( LMEM_FIXED, cbInfo );
  72. if (!pInfo) {
  73. dwErr = ERROR_OUTOFMEMORY;
  74. break;
  75. }
  76. dwErr = ERROR_SUCCESS;
  77. if (!EnumServicesStatusEx(
  78. hScm,
  79. SC_ENUM_PROCESS_INFO,
  80. SERVICE_WIN32,
  81. SERVICE_ACTIVE,
  82. (LPBYTE)pInfo,
  83. cbInfo,
  84. &cbInfo,
  85. &dwNumServices,
  86. &dwResume,
  87. NULL)) {
  88. dwErr = GetLastError();
  89. }
  90. }
  91. while ((ERROR_MORE_DATA == dwErr) && (++cLoop < cLoopMax));
  92. if ((ERROR_SUCCESS == dwErr) && dwNumServices) {
  93. *ppInfo = pInfo;
  94. } else {
  95. if (pInfo != NULL) {
  96. TraceFree(pInfo);
  97. pInfo = NULL;
  98. }
  99. dwNumServices = 0;
  100. }
  101. CloseServiceHandle(hScm);
  102. }
  103. RETURN(dwNumServices);
  104. }
  105. //
  106. // EnumWindowsProc( )
  107. //
  108. BOOL CALLBACK
  109. EnumWindowsProc(
  110. HWND hwnd,
  111. LPARAM lParam
  112. )
  113. {
  114. // TraceFunc( "EnumWindowsProc( )\n" );
  115. LPTASKITEM pTask = (LPTASKITEM) lParam;
  116. DWORD pid;
  117. DWORD dwLen;
  118. if (!GetWindowThreadProcessId( hwnd, &pid ))
  119. {
  120. // RETURN(TRUE); // keep enumerating
  121. return TRUE;
  122. }
  123. if ( pTask->dwProcessId != pid )
  124. {
  125. // RETURN(TRUE); // keep enumerating
  126. return TRUE;
  127. }
  128. if ( GetWindow( hwnd, GW_OWNER )
  129. || !(GetWindowLong( hwnd, GWL_STYLE ) & WS_VISIBLE ) )
  130. { // not a top level window
  131. // RETURN(TRUE); // keep enumerating
  132. return TRUE;
  133. }
  134. dwLen = GetWindowTextLength( hwnd ) + 1;
  135. pTask->pszServiceName = (LPWSTR) TraceAllocString( LMEM_FIXED, dwLen );
  136. if ( pTask->pszServiceName )
  137. {
  138. GetWindowText( hwnd, pTask->pszServiceName, dwLen );
  139. }
  140. // RETURN(FALSE); // hummm ... found it - stop enumeration
  141. return FALSE;
  142. }
  143. //
  144. // CheckForRunningApplications( )
  145. //
  146. // Returns: TRUE - possibly "unsafe" running applications/services
  147. // FALSE - Ok to continue.
  148. //
  149. BOOL
  150. CheckForRunningApplications(
  151. HWND hwndList )
  152. {
  153. PSYSTEM_PROCESS_INFORMATION ProcessInfo;
  154. NTSTATUS status;
  155. ULONG TotalOffset;
  156. LV_ITEM lvI;
  157. LPENUM_SERVICE_STATUS_PROCESS pServiceInfo = NULL;
  158. BOOL fReturn = FALSE;
  159. SC_HANDLE hScm = 0;
  160. LPTASKITEM pTask = NULL;
  161. HKEY hkey = 0;
  162. LRESULT lResult = 0;
  163. DWORD dwNumServices = 0;
  164. TraceFunc( "CheckForRunningApplications( )\n" );
  165. ListView_DeleteAllItems( hwndList );
  166. lvI.mask = LVIF_TEXT | LVIF_PARAM;
  167. lvI.iSubItem = 0;
  168. hScm = OpenSCManager(
  169. NULL,
  170. NULL,
  171. SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
  172. lResult = RegOpenKey( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services", &hkey );
  173. Assert( lResult == ERROR_SUCCESS );
  174. if( lResult != ERROR_SUCCESS ) {
  175. goto Cleanup;
  176. }
  177. dwNumServices = GetServiceProcessInfo( &pServiceInfo );
  178. hScm = OpenSCManager(
  179. NULL,
  180. NULL,
  181. SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
  182. retry:
  183. if ( g_pBuffer == NULL )
  184. {
  185. g_pBuffer = (LPBYTE) VirtualAlloc ( NULL, g_cbBuffer, MEM_COMMIT, PAGE_READWRITE);
  186. if ( g_pBuffer == NULL )
  187. {
  188. RRETURN(TRUE); // be paranoid and show page
  189. }
  190. }
  191. status = NtQuerySystemInformation( SystemProcessInformation,
  192. g_pBuffer,
  193. g_cbBuffer,
  194. NULL );
  195. if ( status == STATUS_INFO_LENGTH_MISMATCH ) {
  196. g_cbBuffer += 8192;
  197. VirtualFree ( g_pBuffer, 0, MEM_RELEASE );
  198. g_pBuffer = NULL;
  199. goto retry;
  200. }
  201. if( !NT_SUCCESS(status) ) {
  202. goto Cleanup;
  203. }
  204. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION) g_pBuffer;
  205. TotalOffset = 0;
  206. while ( TRUE )
  207. {
  208. LPWSTR pszImageName;
  209. INT iCount = 0;
  210. if ( ProcessInfo->ImageName.Buffer )
  211. {
  212. pszImageName = wcsrchr( ProcessInfo->ImageName.Buffer, L'\\' );
  213. if ( pszImageName ) {
  214. pszImageName++;
  215. }
  216. else {
  217. pszImageName = ProcessInfo->ImageName.Buffer;
  218. }
  219. }
  220. else {
  221. goto skiptask; // system process, skip it
  222. }
  223. if (g_hCompatibilityInf != INVALID_HANDLE_VALUE) {
  224. INFCONTEXT Context;
  225. if (SetupFindFirstLine(
  226. g_hCompatibilityInf,
  227. L"ProcessesToIgnore",
  228. pszImageName,
  229. &Context )) {
  230. DebugMsg( "Skipping process %s, it's listed in inf exemption list...\n", pszImageName );
  231. goto skiptask;
  232. }
  233. }
  234. #ifdef DEBUG
  235. if ( StrStrI( L"MSDEV.EXE", pszImageName ) || StrStrI( L"NTSD.EXE", pszImageName ) )
  236. goto skiptask; // allowed process
  237. #endif
  238. //
  239. // othewize, it is an unknown or not allowed process
  240. // add it to the listview
  241. //
  242. fReturn = TRUE;
  243. pTask = (LPTASKITEM) TraceAlloc( LMEM_FIXED, sizeof(TASKITEM) );
  244. if ( !pTask )
  245. goto skiptask;
  246. pTask->pszImageName = (LPWSTR) TraceStrDup( pszImageName );
  247. if ( !pTask->pszImageName )
  248. goto skiptask;
  249. pTask->dwProcessId = (DWORD)(DWORD_PTR)ProcessInfo->UniqueProcessId;
  250. pTask->pszServiceName = NULL;
  251. if ( dwNumServices )
  252. {
  253. // For each service with this process id, append it's service
  254. // name to the buffer. Separate each with a comma.
  255. //
  256. DWORD iSvc;
  257. WCHAR szText[ MAX_PATH ]; // random
  258. for ( iSvc = 0; iSvc < dwNumServices; iSvc++ )
  259. {
  260. if ( pTask->dwProcessId == pServiceInfo[iSvc].ServiceStatusProcess.dwProcessId )
  261. {
  262. LPWSTR pszServiceName = pServiceInfo[iSvc].lpServiceName;
  263. if (hScm)
  264. {
  265. ULONG cbSize = ARRAYSIZE(szText);
  266. if ( GetServiceDisplayName( hScm, pServiceInfo[iSvc].lpServiceName, szText, &cbSize ) )
  267. {
  268. pszServiceName = szText;
  269. }
  270. }
  271. size_t cch = wcslen( pszServiceName ) + 1;
  272. if ( !pTask->pszServiceName )
  273. {
  274. pTask->pszServiceName = (LPWSTR) TraceAllocString( LMEM_FIXED, cch);
  275. if ( pTask->pszServiceName )
  276. {
  277. wcscpy( pTask->pszServiceName, pszServiceName );
  278. }
  279. }
  280. else
  281. { // not the most efficent, but it'll work
  282. LPWSTR pszNew = (LPWSTR) TraceAllocString( LMEM_FIXED, wcslen(pTask->pszServiceName) + 1 + cch );
  283. if ( pszNew )
  284. {
  285. wcscpy( pszNew, pTask->pszServiceName );
  286. wcscat( pszNew, L"," );
  287. wcscat( pszNew, pszServiceName );
  288. TraceFree( pTask->pszServiceName );
  289. pTask->pszServiceName = pszNew;
  290. }
  291. }
  292. }
  293. }
  294. }
  295. if ( hkey && !pTask->pszServiceName )
  296. {
  297. DWORD iSvc = 0;
  298. WCHAR szService[ MAX_PATH ]; // random
  299. while ( RegEnumKey( hkey, iSvc, szService, ARRAYSIZE(szService) ) )
  300. {
  301. HKEY hkeyService;
  302. WCHAR szPath[ MAX_PATH ];
  303. LONG cb = ARRAYSIZE(szPath);
  304. lResult = RegOpenKey( hkey, szService, &hkeyService );
  305. Assert( lResult == ERROR_SUCCESS );
  306. if( lResult != ERROR_SUCCESS ) {
  307. goto Cleanup;
  308. }
  309. lResult = RegQueryValue( hkeyService, L"ImagePath", szPath, &cb );
  310. Assert( lResult == ERROR_SUCCESS );
  311. if( lResult != ERROR_SUCCESS ) {
  312. goto Cleanup;
  313. }
  314. if ( StrStrI( szPath, pTask->pszImageName ) )
  315. { // match!
  316. WCHAR szText[ MAX_PATH ]; // random
  317. cb = ARRAYSIZE(szText);
  318. lResult = RegQueryValue( hkeyService, L"DisplayName", szText, &cb );
  319. if ( lResult == ERROR_SUCCESS )
  320. {
  321. pTask->pszServiceName = (LPWSTR) TraceStrDup( szText );
  322. break;
  323. }
  324. }
  325. RegCloseKey( hkeyService );
  326. iSvc++;
  327. }
  328. }
  329. if ( !pTask->pszServiceName )
  330. {
  331. EnumWindows( &EnumWindowsProc, (LPARAM) pTask );
  332. }
  333. lvI.cchTextMax = wcslen(pTask->pszImageName);
  334. lvI.lParam = (LPARAM) pTask;
  335. lvI.iItem = iCount;
  336. lvI.pszText = pTask->pszImageName;
  337. iCount = ListView_InsertItem( hwndList, &lvI );
  338. Assert( iCount != -1 );
  339. if ( iCount == -1 )
  340. goto skiptask;
  341. if ( pTask->pszServiceName )
  342. {
  343. ListView_SetItemText( hwndList, iCount, 1, pTask->pszServiceName );
  344. }
  345. skiptask:
  346. if ( ProcessInfo->NextEntryOffset == 0 ) {
  347. break;
  348. }
  349. TotalOffset += ProcessInfo->NextEntryOffset;
  350. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&g_pBuffer[TotalOffset];
  351. }
  352. Cleanup:
  353. if ( hScm )
  354. {
  355. CloseServiceHandle(hScm);
  356. }
  357. if ( pServiceInfo )
  358. {
  359. TraceFree( pServiceInfo );
  360. }
  361. if( hkey ) {
  362. RegCloseKey( hkey );
  363. }
  364. RETURN(fReturn);
  365. }
  366. //
  367. // ApplicationDlgProc()
  368. //
  369. INT_PTR CALLBACK
  370. ApplicationDlgProc(
  371. HWND hDlg,
  372. UINT uMsg,
  373. WPARAM wParam,
  374. LPARAM lParam )
  375. {
  376. UNREFERENCED_PARAMETER(wParam);
  377. switch (uMsg)
  378. {
  379. default:
  380. return FALSE;
  381. case WM_INITDIALOG:
  382. {
  383. LV_COLUMN lvC;
  384. WCHAR szText[ 80 ];
  385. INT i;
  386. HWND hwndList = GetDlgItem( hDlg, IDC_L_PROCESSES );
  387. RECT rect;
  388. DWORD dw;
  389. // Create the columns
  390. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  391. lvC.fmt = LVCFMT_LEFT;
  392. lvC.pszText = szText;
  393. // Add first column
  394. lvC.iSubItem = 0;
  395. lvC.cx = 100;
  396. dw = LoadString( g_hinstance, IDS_PROCESS_NAME_COLUMN, szText, ARRAYSIZE(szText));
  397. Assert( dw );
  398. i = ListView_InsertColumn ( hwndList, 0, &lvC );
  399. Assert( i != -1 );
  400. // Add second column
  401. lvC.iSubItem++;
  402. GetWindowRect( hwndList, &rect );
  403. lvC.cx = ( rect.right - rect.left ) - lvC.cx; // autosize - make Tony happy
  404. dw = LoadString( g_hinstance, IDS_APPL_NAME_COLUMN, szText, ARRAYSIZE(szText));
  405. Assert( dw );
  406. i = ListView_InsertColumn ( hwndList, lvC.iSubItem, &lvC );
  407. Assert( i != -1 );
  408. }
  409. return FALSE;
  410. case WM_DESTROY:
  411. VirtualFree ( g_pBuffer, 0, MEM_RELEASE );
  412. g_pBuffer = NULL; // paranoid
  413. break;
  414. case WM_NOTIFY:
  415. SetWindowLongPtr( hDlg, DWLP_MSGRESULT, FALSE );
  416. LPNMHDR lpnmhdr = (LPNMHDR) lParam;
  417. switch ( lpnmhdr->code )
  418. {
  419. case PSN_QUERYCANCEL:
  420. return VerifyCancel( hDlg );
  421. case PSN_WIZNEXT:
  422. #if 0
  423. if ( CheckForRunningApplications( GetDlgItem( hDlg, IDC_L_PROCESSES ) ) )
  424. {
  425. MessageBoxFromStrings( hDlg, IDS_NOT_ALL_PROCESSES_KILLED_TITLE, IDS_NOT_ALL_PROCESSES_KILLED_TEXT, MB_OK );
  426. SetWindowLongPtr( hDlg, DWLP_MSGRESULT, -1 ); // don't show
  427. }
  428. #endif
  429. break;
  430. case PSN_SETACTIVE:
  431. {
  432. if ( !CheckForRunningApplications( GetDlgItem( hDlg, IDC_L_PROCESSES ) ) )
  433. {
  434. SetWindowLongPtr( hDlg, DWLP_MSGRESULT, -1 ); // don't show
  435. break;
  436. }
  437. PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK );
  438. ClearMessageQueue( );
  439. }
  440. break;
  441. case LVN_DELETEALLITEMS:
  442. DebugMsg( "LVN_DELETEALLITEMS - Deleting all items.\n" );
  443. break;
  444. case LVN_DELETEITEM:
  445. DebugMsg( "LVN_DELETEITEM - Deleting an item.\n" );
  446. {
  447. LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
  448. HWND hwndList = GetDlgItem( hDlg, IDC_L_PROCESSES );
  449. LPTASKITEM pTask;
  450. LVITEM lvi;
  451. BOOL b;
  452. lvi.iItem = pnmv->iItem;
  453. lvi.iSubItem = 0;
  454. lvi.mask = LVIF_PARAM;
  455. b = ListView_GetItem( hwndList, &lvi );
  456. Assert( b );
  457. pTask = (LPTASKITEM) lvi.lParam;
  458. Assert( pTask );
  459. if( pTask ) {
  460. TraceFree( pTask->pszImageName );
  461. TraceFree( pTask->pszServiceName );
  462. TraceFree( pTask );
  463. }
  464. }
  465. break;
  466. }
  467. break;
  468. }
  469. return TRUE;
  470. }