|
|
/****************************************************************************
Copyright (c) Microsoft Corporation 1998 All rights reserved
File: ApplDlg.CPP
***************************************************************************/
#include "pch.h"
#include <winperf.h>
#include "utils.h"
#include <commctrl.h>
DEFINE_MODULE("RIPREP")
#define INITIAL_SIZE 51200
#define EXTEND_SIZE 25600
#define REGKEY_PERF L"software\\microsoft\\windows nt\\currentversion\\perflib"
#define REGSUBKEY_COUNTERS L"Counters"
#define PROCESS_COUNTER L"process"
// Globals
LPBYTE g_pBuffer = NULL; DWORD g_cbBuffer = 1;
typedef struct _TASKITEM { LPWSTR pszImageName; LPWSTR pszServiceName; DWORD dwProcessId; } TASKITEM, * LPTASKITEM;
//
// GetServiceProcessInfo( )
//
// BORROWED FROM "TLIST"'s common.c
//
DWORD GetServiceProcessInfo( LPENUM_SERVICE_STATUS_PROCESS* ppInfo )
/*++
Routine Description:
Provides an API for getting a list of process information for Win 32 services that are running at the time of the API call.
Arguments:
ppInfo - address of a pointer to return the information. *ppInfo points to memory allocated with malloc.
Return Value:
Number of ENUM_SERVICE_STATUS_PROCESS structures pointed at by *ppInfo.
--*/
{ DWORD dwNumServices = 0; SC_HANDLE hScm;
TraceFunc( "GetServiceProcessInfo( )\n" );
// Initialize the output parmeter.
*ppInfo = NULL;
// Connect to the service controller.
//
hScm = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE); if (hScm) { LPENUM_SERVICE_STATUS_PROCESS pInfo = NULL; DWORD cbInfo = 4 * 1024; DWORD dwErr = ERROR_SUCCESS; DWORD dwResume = 0; DWORD cLoop = 0; const DWORD cLoopMax = 2;
// First pass through the loop allocates from an initial guess. (4K)
// If that isn't sufficient, we make another pass and allocate
// what is actually needed. (We only go through the loop a
// maximum of two times.)
//
do {
if (pInfo != NULL) { TraceFree(pInfo); } pInfo = (LPENUM_SERVICE_STATUS_PROCESS)TraceAlloc( LMEM_FIXED, cbInfo ); if (!pInfo) { dwErr = ERROR_OUTOFMEMORY; break; }
dwErr = ERROR_SUCCESS; if (!EnumServicesStatusEx( hScm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, (LPBYTE)pInfo, cbInfo, &cbInfo, &dwNumServices, &dwResume, NULL)) { dwErr = GetLastError(); } } while ((ERROR_MORE_DATA == dwErr) && (++cLoop < cLoopMax));
if ((ERROR_SUCCESS == dwErr) && dwNumServices) { *ppInfo = pInfo; } else { if (pInfo != NULL) { TraceFree(pInfo); pInfo = NULL; } dwNumServices = 0; }
CloseServiceHandle(hScm); }
RETURN(dwNumServices); }
//
// EnumWindowsProc( )
//
BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ) { // TraceFunc( "EnumWindowsProc( )\n" );
LPTASKITEM pTask = (LPTASKITEM) lParam; DWORD pid; DWORD dwLen;
if (!GetWindowThreadProcessId( hwnd, &pid )) { // RETURN(TRUE); // keep enumerating
return TRUE; }
if ( pTask->dwProcessId != pid ) { // RETURN(TRUE); // keep enumerating
return TRUE; }
if ( GetWindow( hwnd, GW_OWNER ) || !(GetWindowLong( hwnd, GWL_STYLE ) & WS_VISIBLE ) ) { // not a top level window
// RETURN(TRUE); // keep enumerating
return TRUE; }
dwLen = GetWindowTextLength( hwnd ) + 1; pTask->pszServiceName = (LPWSTR) TraceAllocString( LMEM_FIXED, dwLen ); if ( pTask->pszServiceName ) { GetWindowText( hwnd, pTask->pszServiceName, dwLen ); }
// RETURN(FALSE); // hummm ... found it - stop enumeration
return FALSE; }
//
// CheckForRunningApplications( )
//
// Returns: TRUE - possibly "unsafe" running applications/services
// FALSE - Ok to continue.
//
BOOL CheckForRunningApplications( HWND hwndList ) { PSYSTEM_PROCESS_INFORMATION ProcessInfo; NTSTATUS status; ULONG TotalOffset; LV_ITEM lvI; LPENUM_SERVICE_STATUS_PROCESS pServiceInfo = NULL; BOOL fReturn = FALSE; SC_HANDLE hScm = 0; LPTASKITEM pTask = NULL; HKEY hkey = 0; LRESULT lResult = 0; DWORD dwNumServices = 0;
TraceFunc( "CheckForRunningApplications( )\n" );
ListView_DeleteAllItems( hwndList );
lvI.mask = LVIF_TEXT | LVIF_PARAM; lvI.iSubItem = 0;
hScm = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
lResult = RegOpenKey( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services", &hkey ); Assert( lResult == ERROR_SUCCESS );
if( lResult != ERROR_SUCCESS ) { goto Cleanup; }
dwNumServices = GetServiceProcessInfo( &pServiceInfo );
hScm = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE); retry:
if ( g_pBuffer == NULL ) { g_pBuffer = (LPBYTE) VirtualAlloc ( NULL, g_cbBuffer, MEM_COMMIT, PAGE_READWRITE); if ( g_pBuffer == NULL ) { RRETURN(TRUE); // be paranoid and show page
} }
status = NtQuerySystemInformation( SystemProcessInformation, g_pBuffer, g_cbBuffer, NULL );
if ( status == STATUS_INFO_LENGTH_MISMATCH ) { g_cbBuffer += 8192; VirtualFree ( g_pBuffer, 0, MEM_RELEASE ); g_pBuffer = NULL; goto retry; }
if( !NT_SUCCESS(status) ) { goto Cleanup; }
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION) g_pBuffer; TotalOffset = 0; while ( TRUE ) { LPWSTR pszImageName; INT iCount = 0;
if ( ProcessInfo->ImageName.Buffer ) { pszImageName = wcsrchr( ProcessInfo->ImageName.Buffer, L'\\' ); if ( pszImageName ) { pszImageName++; } else { pszImageName = ProcessInfo->ImageName.Buffer; } } else { goto skiptask; // system process, skip it
}
if (g_hCompatibilityInf != INVALID_HANDLE_VALUE) { INFCONTEXT Context; if (SetupFindFirstLine( g_hCompatibilityInf, L"ProcessesToIgnore", pszImageName, &Context )) { DebugMsg( "Skipping process %s, it's listed in inf exemption list...\n", pszImageName ); goto skiptask; } }
#ifdef DEBUG
if ( StrStrI( L"MSDEV.EXE", pszImageName ) || StrStrI( L"NTSD.EXE", pszImageName ) ) goto skiptask; // allowed process
#endif
//
// othewize, it is an unknown or not allowed process
// add it to the listview
//
fReturn = TRUE;
pTask = (LPTASKITEM) TraceAlloc( LMEM_FIXED, sizeof(TASKITEM) ); if ( !pTask ) goto skiptask; pTask->pszImageName = (LPWSTR) TraceStrDup( pszImageName ); if ( !pTask->pszImageName ) goto skiptask; pTask->dwProcessId = (DWORD)(DWORD_PTR)ProcessInfo->UniqueProcessId; pTask->pszServiceName = NULL;
if ( dwNumServices ) { // For each service with this process id, append it's service
// name to the buffer. Separate each with a comma.
//
DWORD iSvc; WCHAR szText[ MAX_PATH ]; // random
for ( iSvc = 0; iSvc < dwNumServices; iSvc++ ) { if ( pTask->dwProcessId == pServiceInfo[iSvc].ServiceStatusProcess.dwProcessId ) { LPWSTR pszServiceName = pServiceInfo[iSvc].lpServiceName;
if (hScm) { ULONG cbSize = ARRAYSIZE(szText); if ( GetServiceDisplayName( hScm, pServiceInfo[iSvc].lpServiceName, szText, &cbSize ) ) { pszServiceName = szText; } }
size_t cch = wcslen( pszServiceName ) + 1;
if ( !pTask->pszServiceName ) { pTask->pszServiceName = (LPWSTR) TraceAllocString( LMEM_FIXED, cch); if ( pTask->pszServiceName ) { wcscpy( pTask->pszServiceName, pszServiceName ); } } else { // not the most efficent, but it'll work
LPWSTR pszNew = (LPWSTR) TraceAllocString( LMEM_FIXED, wcslen(pTask->pszServiceName) + 1 + cch ); if ( pszNew ) { wcscpy( pszNew, pTask->pszServiceName ); wcscat( pszNew, L"," ); wcscat( pszNew, pszServiceName ); TraceFree( pTask->pszServiceName ); pTask->pszServiceName = pszNew; } } } } }
if ( hkey && !pTask->pszServiceName ) { DWORD iSvc = 0; WCHAR szService[ MAX_PATH ]; // random
while ( RegEnumKey( hkey, iSvc, szService, ARRAYSIZE(szService) ) ) { HKEY hkeyService; WCHAR szPath[ MAX_PATH ]; LONG cb = ARRAYSIZE(szPath); lResult = RegOpenKey( hkey, szService, &hkeyService ); Assert( lResult == ERROR_SUCCESS ); if( lResult != ERROR_SUCCESS ) { goto Cleanup; }
lResult = RegQueryValue( hkeyService, L"ImagePath", szPath, &cb ); Assert( lResult == ERROR_SUCCESS ); if( lResult != ERROR_SUCCESS ) { goto Cleanup; }
if ( StrStrI( szPath, pTask->pszImageName ) ) { // match!
WCHAR szText[ MAX_PATH ]; // random
cb = ARRAYSIZE(szText); lResult = RegQueryValue( hkeyService, L"DisplayName", szText, &cb ); if ( lResult == ERROR_SUCCESS ) { pTask->pszServiceName = (LPWSTR) TraceStrDup( szText ); break; } }
RegCloseKey( hkeyService ); iSvc++; } }
if ( !pTask->pszServiceName ) { EnumWindows( &EnumWindowsProc, (LPARAM) pTask ); }
lvI.cchTextMax = wcslen(pTask->pszImageName); lvI.lParam = (LPARAM) pTask; lvI.iItem = iCount; lvI.pszText = pTask->pszImageName;
iCount = ListView_InsertItem( hwndList, &lvI ); Assert( iCount != -1 ); if ( iCount == -1 ) goto skiptask;
if ( pTask->pszServiceName ) { ListView_SetItemText( hwndList, iCount, 1, pTask->pszServiceName ); }
skiptask: if ( ProcessInfo->NextEntryOffset == 0 ) { break; }
TotalOffset += ProcessInfo->NextEntryOffset; ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)&g_pBuffer[TotalOffset]; }
Cleanup:
if ( hScm ) { CloseServiceHandle(hScm); }
if ( pServiceInfo ) { TraceFree( pServiceInfo ); }
if( hkey ) { RegCloseKey( hkey ); }
RETURN(fReturn); }
//
// ApplicationDlgProc()
//
INT_PTR CALLBACK ApplicationDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { UNREFERENCED_PARAMETER(wParam); switch (uMsg) { default: return FALSE;
case WM_INITDIALOG: { LV_COLUMN lvC; WCHAR szText[ 80 ]; INT i; HWND hwndList = GetDlgItem( hDlg, IDC_L_PROCESSES ); RECT rect; DWORD dw;
// Create the columns
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvC.fmt = LVCFMT_LEFT; lvC.pszText = szText;
// Add first column
lvC.iSubItem = 0; lvC.cx = 100; dw = LoadString( g_hinstance, IDS_PROCESS_NAME_COLUMN, szText, ARRAYSIZE(szText)); Assert( dw ); i = ListView_InsertColumn ( hwndList, 0, &lvC ); Assert( i != -1 );
// Add second column
lvC.iSubItem++; GetWindowRect( hwndList, &rect ); lvC.cx = ( rect.right - rect.left ) - lvC.cx; // autosize - make Tony happy
dw = LoadString( g_hinstance, IDS_APPL_NAME_COLUMN, szText, ARRAYSIZE(szText)); Assert( dw ); i = ListView_InsertColumn ( hwndList, lvC.iSubItem, &lvC ); Assert( i != -1 ); } return FALSE;
case WM_DESTROY: VirtualFree ( g_pBuffer, 0, MEM_RELEASE ); g_pBuffer = NULL; // paranoid
break;
case WM_NOTIFY: SetWindowLongPtr( hDlg, DWLP_MSGRESULT, FALSE ); LPNMHDR lpnmhdr = (LPNMHDR) lParam; switch ( lpnmhdr->code ) { case PSN_QUERYCANCEL: return VerifyCancel( hDlg );
case PSN_WIZNEXT: #if 0
if ( CheckForRunningApplications( GetDlgItem( hDlg, IDC_L_PROCESSES ) ) ) { MessageBoxFromStrings( hDlg, IDS_NOT_ALL_PROCESSES_KILLED_TITLE, IDS_NOT_ALL_PROCESSES_KILLED_TEXT, MB_OK ); SetWindowLongPtr( hDlg, DWLP_MSGRESULT, -1 ); // don't show
} #endif
break;
case PSN_SETACTIVE: { if ( !CheckForRunningApplications( GetDlgItem( hDlg, IDC_L_PROCESSES ) ) ) { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, -1 ); // don't show
break; } PropSheet_SetWizButtons( GetParent( hDlg ), PSWIZB_NEXT | PSWIZB_BACK ); ClearMessageQueue( ); } break;
case LVN_DELETEALLITEMS: DebugMsg( "LVN_DELETEALLITEMS - Deleting all items.\n" ); break;
case LVN_DELETEITEM: DebugMsg( "LVN_DELETEITEM - Deleting an item.\n" ); { LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam; HWND hwndList = GetDlgItem( hDlg, IDC_L_PROCESSES ); LPTASKITEM pTask; LVITEM lvi; BOOL b;
lvi.iItem = pnmv->iItem; lvi.iSubItem = 0; lvi.mask = LVIF_PARAM; b = ListView_GetItem( hwndList, &lvi ); Assert( b ); pTask = (LPTASKITEM) lvi.lParam; Assert( pTask ); if( pTask ) { TraceFree( pTask->pszImageName ); TraceFree( pTask->pszServiceName ); TraceFree( pTask ); } } break; } break; }
return TRUE; }
|