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

// *********************************************************************************
//
// Copyright (c) Microsoft Corporation
//
// Module Name:
//
// Init.cpp
//
// Abstract:
//
// This module implements the general initialization stuff
//
// Author:
//
// Sunil G.V.N. Murali ([email protected]) 26-Nov-2000
//
// Revision History:
//
// Sunil G.V.N. Murali ([email protected]) 26-Nov-2000 : Created It.
//
// *********************************************************************************
#include "pch.h"
#include "wmi.h"
#include "taskkill.h"
CTaskKill::CTaskKill()
/*++
Routine Description:
CTaskKill contructor
Arguments:
NONE
Return Value:
NONE
--*/
{
// init to defaults
m_arrFilters = NULL;
m_arrTasksToKill = NULL;
m_bUsage = FALSE;
m_bTree = FALSE;
m_bForce = FALSE;
m_dwCurrentPid = 0;
m_bNeedPassword = FALSE;
m_arrFiltersEx = NULL;
m_bNeedServicesInfo = FALSE;
m_bNeedUserContextInfo = FALSE;
m_bNeedModulesInfo = FALSE;
m_pfilterConfigs = NULL;
m_arrWindowTitles = NULL;
m_pWbemLocator = NULL;
m_pWbemServices = NULL;
m_pWbemEnumObjects = NULL;
m_pWbemTerminateInParams = NULL;
m_bIsHydra = FALSE;
m_hWinstaLib = NULL;
m_pProcessInfo = NULL;
m_ulNumberOfProcesses = 0;
m_bCloseConnection = FALSE;
m_dwServicesCount = 0;
m_pServicesInfo = NULL;
m_bUseRemote = FALSE;
m_pdb = NULL;
m_pfnWinStationFreeMemory = NULL;
m_pfnWinStationOpenServerW = NULL;
m_pfnWinStationCloseServer = NULL;
m_pfnWinStationFreeGAPMemory = NULL;
m_pfnWinStationGetAllProcesses = NULL;
m_pfnWinStationEnumerateProcesses = NULL;
m_arrRecord = NULL;
m_pAuthIdentity = NULL;
m_bTasksOptimized = FALSE;
m_bFiltersOptimized = FALSE;
}
CTaskKill::~CTaskKill()
/*++
Routine Description:
CTaskKill destructor
Arguments:
NONE
Return Value:
NONE
--*/
{
//
// de-allocate memory allocations
//
//
// destroy dynamic arrays
DESTROY_ARRAY( m_arrRecord );
DESTROY_ARRAY( m_arrFilters );
DESTROY_ARRAY( m_arrFiltersEx );
DESTROY_ARRAY( m_arrWindowTitles );
DESTROY_ARRAY( m_arrTasksToKill );
//
// memory ( with new operator )
RELEASE_MEMORY_EX( m_pfilterConfigs );
//
// release WMI / COM interfaces
SAFE_RELEASE( m_pWbemLocator );
SAFE_RELEASE( m_pWbemServices );
SAFE_RELEASE( m_pWbemEnumObjects );
SAFE_RELEASE( m_pWbemTerminateInParams );
// free the wmi authentication structure
WbemFreeAuthIdentity( &m_pAuthIdentity );
// if connection to the remote system opened with NET API has to be closed .. do it
if ( m_bCloseConnection == TRUE )
{
CloseConnection( m_strServer );
}
// free the memory allocated for services variables
FreeMemory( ( LPVOID * )&m_pServicesInfo );
// free the memory allocated for performance block
FreeMemory( ( LPVOID * ) &m_pdb );
//
// free winstation block
if ( ( FALSE == m_bIsHydra ) && ( NULL != m_pProcessInfo ) )
{
// free the GAP memory block
WinStationFreeGAPMemory( GAP_LEVEL_BASIC,
(PTS_ALL_PROCESSES_INFO) m_pProcessInfo, m_ulNumberOfProcesses );
// ...
m_pProcessInfo = NULL;
}
else
{
if ( ( TRUE == m_bIsHydra ) && ( NULL != m_pProcessInfo ) )
{
// free the winsta memory block
WinStationFreeMemory( m_pProcessInfo );
m_pProcessInfo = NULL;
}
}
// free the library
if ( NULL != m_hWinstaLib )
{
FreeLibrary( m_hWinstaLib );
m_hWinstaLib = NULL;
m_pfnWinStationFreeMemory = NULL;
m_pfnWinStationOpenServerW = NULL;
m_pfnWinStationCloseServer = NULL;
m_pfnWinStationFreeGAPMemory = NULL;
m_pfnWinStationGetAllProcesses = NULL;
m_pfnWinStationEnumerateProcesses = NULL;
}
// uninitialize the com library
CoUninitialize();
}
BOOL
CTaskKill::Initialize(
void
)
/*++
Routine Description:
initialize the task list utility
Arguments:
NONE
Return Value:
TRUE : if filters are appropriately specified
FALSE : if filters are errorneously specified
--*/
{
//
// memory allocations
// if at all any occurs, we know that is 'coz of the
// failure in memory allocation ... so set the error
SetLastError( ( DWORD )E_OUTOFMEMORY );
SaveLastError();
// get the current process id and save it
m_dwCurrentPid = GetCurrentProcessId();
// filters ( user supplied )
if ( NULL == m_arrFilters )
{
m_arrFilters = CreateDynamicArray();
if ( NULL == m_arrFilters )
{
return FALSE;
}
}
// tasks to be killed ( user supplied )
if ( NULL == m_arrTasksToKill )
{
m_arrTasksToKill = CreateDynamicArray();
if ( NULL == m_arrTasksToKill )
{
return FALSE;
}
}
// filters ( program generated parsed filters )
if ( NULL == m_arrFiltersEx )
{
m_arrFiltersEx = CreateDynamicArray();
if ( NULL == m_arrFiltersEx )
{
return FALSE;
}
}
// filters configuration info
if ( NULL == m_pfilterConfigs )
{
m_pfilterConfigs = ( TFILTERCONFIG * )AllocateMemory( sizeof( TFILTERCONFIG ) * MAX_FILTERS );
if ( NULL == m_pfilterConfigs )
{
return FALSE;
}
// init to ZERO's
SecureZeroMemory( m_pfilterConfigs, MAX_FILTERS * sizeof( TFILTERCONFIG ) );
}
// window titles
if ( NULL == m_arrWindowTitles )
{
m_arrWindowTitles = CreateDynamicArray();
if ( NULL == m_arrWindowTitles )
{
return FALSE;
}
}
// tasks
if ( NULL == m_arrRecord )
{
m_arrRecord = CreateDynamicArray();
if ( NULL == m_arrRecord )
{
return FALSE;
}
}
// initialize the COM library
if ( FALSE == InitializeCom( &m_pWbemLocator ) )
{
return FALSE;
}
//
// load the winsta library and needed functions
// NOTE: do not raise any error if loading of winsta dll fails
{ // Local variabels should be destroyed inside this block.
// +1 is for terminating NULL character.
LPWSTR lpszSystemPath = NULL;
DWORD dwLength = MAX_PATH + 1;
DWORD dwExpectedLength = 0;
DWORD dwActualBufLen = 0;
do
{
dwActualBufLen = dwLength + 5 + StringLength( WINSTA_DLLNAME, 0 );
// Length of 'System32' + Length of '\' + Length of 'WINSTA_DLLNAME' + Length of '\0'.
// 3 WCHARS are extra, to be on safer side.
lpszSystemPath = (LPWSTR) AllocateMemory( dwActualBufLen * sizeof( WCHAR ) );
if( NULL == lpszSystemPath )
{ // Out of memory.
m_hWinstaLib = NULL;
break;
}
dwExpectedLength = GetSystemDirectory( lpszSystemPath, dwLength );
if( ( 0 != dwExpectedLength ) ||
( dwLength > dwExpectedLength ) )
{ // Successful
StringConcat( lpszSystemPath, L"\\", dwActualBufLen );
StringConcat( lpszSystemPath, WINSTA_DLLNAME, dwActualBufLen );
m_hWinstaLib = ::LoadLibrary( lpszSystemPath );
FreeMemory( (LPVOID * )&lpszSystemPath );
break;
}
FreeMemory( (LPVOID * )&lpszSystemPath );
m_hWinstaLib = NULL;
// +1 is for terminating NULL character.
dwLength = dwExpectedLength + 1;
}while( 0 != dwExpectedLength );
}
if ( NULL != m_hWinstaLib )
{
// library loaded successfully ... now load the addresses of functions
m_pfnWinStationFreeMemory = (FUNC_WinStationFreeMemory) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationFreeMemory );
m_pfnWinStationCloseServer = (FUNC_WinStationCloseServer) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationCloseServer );
m_pfnWinStationOpenServerW = (FUNC_WinStationOpenServerW) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationOpenServerW );
m_pfnWinStationFreeGAPMemory = (FUNC_WinStationFreeGAPMemory) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationFreeGAPMemory );
m_pfnWinStationGetAllProcesses = (FUNC_WinStationGetAllProcesses) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationGetAllProcesses );
m_pfnWinStationEnumerateProcesses = (FUNC_WinStationEnumerateProcesses) ::GetProcAddress( m_hWinstaLib, FUNCNAME_WinStationEnumerateProcesses );
// we will keep the library loaded in memory only if all the functions were loaded successfully
if ( ( NULL == m_pfnWinStationFreeMemory ) ||
( NULL == m_pfnWinStationCloseServer ) ||
( NULL == m_pfnWinStationOpenServerW ) ||
( NULL == m_pfnWinStationFreeGAPMemory ) ||
( NULL == m_pfnWinStationGetAllProcesses ) ||
( NULL == m_pfnWinStationEnumerateProcesses )
)
{
// some (or) all of the functions were not loaded ... unload the library
FreeLibrary( m_hWinstaLib );
m_hWinstaLib = NULL;
m_pfnWinStationFreeMemory = NULL;
m_pfnWinStationOpenServerW = NULL;
m_pfnWinStationCloseServer = NULL;
m_pfnWinStationFreeGAPMemory = NULL;
m_pfnWinStationGetAllProcesses = NULL;
m_pfnWinStationEnumerateProcesses = NULL;
}
}
// initialization is successful
SetLastError( ( DWORD )NOERROR ); // clear the error
SetReason( NULL_STRING ); // clear the reason
return TRUE;
}
BOOL
CTaskKill::EnableDebugPriv(
void
)
/*++
Routine Description:
Enables the debug privliges for the current process so that
this utility can terminate the processes on local system without any problem
Arguments:
NONE
Return Value:
TRUE upon successfull and FALSE if failed
--*/
{
// local variables
LUID luidValue ;
BOOL bResult = FALSE;
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tkp;
SecureZeroMemory( &luidValue, sizeof( LUID ) );
SecureZeroMemory( &tkp, sizeof( TOKEN_PRIVILEGES ) );
// Retrieve a handle of the access token
bResult = OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken );
if ( FALSE == bResult )
{
// save the error messaage and return
SaveLastError();
return FALSE;
}
// Enable the SE_DEBUG_NAME privilege or disable
// all privileges, depends on this flag.
bResult = LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luidValue );
if ( FALSE == bResult )
{
// save the error messaage and return
SaveLastError();
CloseHandle( hToken );
return FALSE;
}
// prepare the token privileges structure
tkp.PrivilegeCount = 1;
tkp.Privileges[ 0 ].Luid = luidValue;
tkp.Privileges[ 0 ].Attributes = SE_PRIVILEGE_ENABLED;
// now enable the debug privileges in the token
bResult = AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof( TOKEN_PRIVILEGES ),
( PTOKEN_PRIVILEGES ) NULL, ( PDWORD ) NULL );
if ( FALSE == bResult )
{
// The return value of AdjustTokenPrivileges be texted
SaveLastError();
CloseHandle( hToken );
return FALSE;
}
// close the opened token handle
CloseHandle( hToken );
// enabled ... inform success
return TRUE;
}
BOOLEAN
CTaskKill::WinStationFreeMemory(
IN PVOID pBuffer
)
/*++
Routine Description:
Free memory.
Arguments:
[in] pBuffer : Cotains memory location to free.
Return Value:
TRUE if successful else FALSE is returned.
--*/
{
// check the buffer and act
if ( NULL == pBuffer )
{
return TRUE;
}
// check whether pointer exists or not
if ( NULL == m_pfnWinStationFreeMemory )
{
return FALSE;
}
// call and return the same
return ((FUNC_WinStationFreeMemory) m_pfnWinStationFreeMemory)( pBuffer );
}
BOOLEAN
CTaskKill::WinStationCloseServer(
IN HANDLE hServer
)
/*++
Routine Description:
Handle to window station is closed.
Arguments:
[in] hServer : Handle to window station.
Return Value:
TRUE if successful else FALSE is returned.
--*/
{
// check the input
if ( NULL == hServer )
{
return TRUE;
}
// check whether the function pointer exists or not
if ( NULL == m_pfnWinStationCloseServer )
{
return FALSE;
}
// call and return
return ((FUNC_WinStationCloseServer) m_pfnWinStationCloseServer)( hServer );
}
HANDLE
CTaskKill::WinStationOpenServerW(
IN LPWSTR pwszServerName
)
/*++
Routine Description:
Retrieves a handle to an window station on a system.
Arguments:
[in] pwszServerName : System name from where to retrieve window station handle.
Return Value:
Valid handle is returned if successful else NULL is returned.
--*/
{
// check the input & also check whether function pointer exists or not
if ( ( NULL == pwszServerName ) ||
( NULL == m_pfnWinStationOpenServerW ) )
{
return NULL;
}
// call and return
return ((FUNC_WinStationOpenServerW) m_pfnWinStationOpenServerW)( pwszServerName );
}
BOOLEAN
CTaskKill::WinStationEnumerateProcesses(
IN HANDLE hServer,
OUT PVOID* ppProcessBuffer
)
/*++
Routine Description:
Retrieves process running on a system.
Arguments:
[in] hServer : Cotains handle to window station.
[ out ] ppProcessBuffer : Contains process infomration on remote system.
Return Value:
TRUE if successful else FALSE is returned.
--*/
{
// check the input and also check whether function pointer exists or not
if ( ( NULL == ppProcessBuffer ) ||
( NULL == m_pfnWinStationEnumerateProcesses ) )
{
return FALSE;
}
// call and return
return ((FUNC_WinStationEnumerateProcesses)
m_pfnWinStationEnumerateProcesses)( hServer, ppProcessBuffer );
}
BOOLEAN
CTaskKill::WinStationFreeGAPMemory(
IN ULONG ulLevel,
IN PVOID pProcessArray,
IN ULONG ulCount
)
/*++
Routine Description:
Free gap memory block.
Arguments:
[in] ulLevel : Contains information level of data.
[ in ] pProcessArray : Contains data to be freed.
[ in ] ulCount : Contains number of blocks to be freed.
Return Value:
TRUE if successful else FALSE is returned.
--*/
{
// check the input
if ( NULL == pProcessArray )
{
return TRUE;
}
// check whether function pointer exists or not
if ( NULL == m_pfnWinStationFreeGAPMemory )
{
return FALSE;
}
// call and return
return ((FUNC_WinStationFreeGAPMemory)
m_pfnWinStationFreeGAPMemory)( ulLevel, pProcessArray, ulCount );
}
BOOLEAN
CTaskKill::WinStationGetAllProcesses(
IN HANDLE hServer,
IN ULONG ulLevel,
OUT ULONG* pNumberOfProcesses,
OUT PVOID* ppProcessArray
)
/*++
Routine Description:
Retrieves process information running on a system.
Arguments:
[in] hServer : Cotains handle to window station.
[ in ] ulLevel : Contains information level of data.
[ out ] pNumberOfProcesses : Contains number of process retrieved.
[ out ] ppProcessArray : Contains process realted infomration.
Return Value:
TRUE if successful else FALSE is returned.
--*/
{
// check the input & check whether function pointer exists or not
if ( ( NULL == pNumberOfProcesses ) ||
( NULL == ppProcessArray ) ||
( NULL == m_pfnWinStationGetAllProcesses ) )
{
return FALSE;
}
return ((FUNC_WinStationGetAllProcesses)
m_pfnWinStationGetAllProcesses)( hServer, ulLevel, pNumberOfProcesses, ppProcessArray );
}