|
|
/*******************************************************************************
* * procs.cpp * * implementation of ProcEnumerateProcesses function * * copyright notice: Copyright 1997, Citrix Systems Inc. * Copyright (c) 1998 - 1999 Microsoft Corporation * * $Author: BillG $ Don Messerli * * $Log: X:\NT\PRIVATE\UTILS\CITRIX\WINUTILS\WINADMIN\VCS\PROCS.CPP $ * * Rev 1.1 02 Dec 1997 16:30:10 BillG * alpha update * * Rev 1.0 30 Jul 1997 17:12:02 butchd * Initial revision. * *******************************************************************************/
#ifndef UNICODE
#define UNICODE
#endif
//#ifndef _X86_
//#define _X86_
//#endif
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntcsrsrv.h>
#include <ntlsa.h>
#include <ntsam.h>
#include <windows.h>
#include <lmaccess.h>
#include <lmserver.h>
#include <lmwksta.h>
#include <lmapibuf.h>
#include <winsta.h>
#include <procs.h>
#define MAX_PROCESSNAME 18
VOID FetchProcessIDAndImageName(PTS_SYS_PROCESS_INFORMATION ProcessInfo, PULONG pPID, LPTSTR pImageName) { int i; TCHAR ImageName[MAX_PROCESSNAME+1]; //
// Set the PID.
//
*pPID = (ULONG)(ULONG_PTR)(ProcessInfo->UniqueProcessId);
//
// Fetch and convert counted UNICODE string into a NULL
// terminated UNICODE string.
//
if( !ProcessInfo->ImageName.Length == 0 ) { wcsncpy( ImageName, ProcessInfo->ImageName.Buffer, min(MAX_PROCESSNAME, ProcessInfo->ImageName.Length/2)); }
ImageName[min(MAX_PROCESSNAME, ProcessInfo->ImageName.Length/2)] = 0;
/*
* We're UNICODE: simply copy the converted ImageName buffer * into the m_PLObject->m_ImageName field. */ lstrcpy(pImageName, ImageName);
_wcslwr(pImageName);
}
/*******************************************************************************
* * EnumerateProcesses - WinFrame helper function * * Enumerate all processes in system, passing back one with each call to this * routine. * * * ENTRY: * hServer: * handle of the aimed server * pEnumToken * pointer to the current token * pImageName (output) * Points to a buffer to store process name in. NOTE: this buffer is expected * to be at least MAX_PROCESSNAME+1 characters in size. * pLogonId (output) * Points to variable to store process LogonId in. * pPID (output) * Points to variable to store process PID in. * ppSID (output) * Points to a pointer which is set to point to the process' SID on exit. * * EXIT: * TRUE - information for the next process in the system has been placed into * the referenced PLObject and pSID variables. * FALSE - if the enumeration is done, GetLastError() will contain the * ERROR_NO_MORE_ITEMS error code. If another (true error) is * encountered, that code will be set. * ******************************************************************************/
BOOL WINAPI ProcEnumerateProcesses( HANDLE hServer, PENUMTOKEN pEnumToken, LPTSTR pImageName, PULONG pLogonId, PULONG pPID, PSID *ppSID ) { int i; PTS_SYS_PROCESS_INFORMATION ProcessInfo; PCITRIX_PROCESS_INFORMATION CitrixInfo;
if ((pEnumToken == NULL) || (pImageName == NULL) || (pLogonId == NULL) || (pPID == NULL) || (ppSID == NULL) ) { return FALSE; }
/*
* Check for done with enumeration. */ if ( pEnumToken->Current == (ULONG)-1 ) {
SetLastError(ERROR_NO_MORE_ITEMS);
if (pEnumToken->bGAP == TRUE) // we used the GAP (GetAllProcesses) interface
{ //
// Free ProcessArray and all child pointers allocated by the client stub.
//
WinStationFreeGAPMemory(GAP_LEVEL_BASIC, pEnumToken->ProcessArray, pEnumToken->NumberOfProcesses); pEnumToken->ProcessArray = NULL; pEnumToken->NumberOfProcesses = 0;
return(FALSE); } else // we used the old Hydra 4 interface
{ WinStationFreeMemory(pEnumToken->pProcessBuffer); pEnumToken->pProcessBuffer = NULL; return(FALSE); } }
/*
* Check for beginning enumeration. */ if ( pEnumToken->Current == 0 ) {
//
// Try the new interface first (NT5 server ?)
//
if (WinStationGetAllProcesses( hServer, GAP_LEVEL_BASIC, &(pEnumToken->NumberOfProcesses), (PVOID *)&(pEnumToken->ProcessArray) ) ) { pEnumToken->bGAP = TRUE; } else { //
// Check the return code indicating that the interface is not available.
//
DWORD dwError = GetLastError(); if (dwError != RPC_S_PROCNUM_OUT_OF_RANGE) { pEnumToken->pProcessBuffer = NULL; return(FALSE); } else // maybe a Hydra 4 server ?
{
if ( WinStationEnumerateProcesses( hServer, (PVOID *)&(pEnumToken->pProcessBuffer))) { pEnumToken->bGAP = FALSE; } else { DWORD error = GetLastError(); if(pEnumToken->pProcessBuffer != NULL) { WinStationFreeMemory(pEnumToken->pProcessBuffer); pEnumToken->pProcessBuffer = NULL; } return(FALSE); } } } }
if (pEnumToken->bGAP == TRUE) { ProcessInfo = (PTS_SYS_PROCESS_INFORMATION)((pEnumToken->ProcessArray)[pEnumToken->Current].pTsProcessInfo);
FetchProcessIDAndImageName(ProcessInfo,pPID,pImageName);
//
// Set the SessionId
//
*pLogonId = ProcessInfo->SessionId;
//
// set the SID
//
*ppSID = (pEnumToken->ProcessArray)[pEnumToken->Current].pSid;
(pEnumToken->Current)++;
if ( (pEnumToken->Current) >= (pEnumToken->NumberOfProcesses) ) { pEnumToken->Current = (ULONG)-1; // sets the end of enumeration
} } else {
/*
* Parse and store the next process' information. */
ProcessInfo = (PTS_SYS_PROCESS_INFORMATION) &(((PUCHAR)(pEnumToken->pProcessBuffer))[pEnumToken->Current]);
FetchProcessIDAndImageName(ProcessInfo,pPID,pImageName);
/*
* Point to the CITRIX_INFORMATION which follows the Threads */ CitrixInfo = (PCITRIX_PROCESS_INFORMATION) (((PUCHAR)ProcessInfo) + SIZEOF_TS4_SYSTEM_PROCESS_INFORMATION + (SIZEOF_TS4_SYSTEM_THREAD_INFORMATION * (int)ProcessInfo->NumberOfThreads));
/*
* Fetch the LogonId and point to this SID for the primary * thread to use (copy). */ if( CitrixInfo->MagicNumber == CITRIX_PROCESS_INFO_MAGIC ) {
*pLogonId = CitrixInfo->LogonId; *ppSID = CitrixInfo->ProcessSid;
} else {
*pLogonId = (ULONG)(-1); *ppSID = NULL; }
/*
* Increment the total offset count for next call. If this is the * last process, set the offset to -1 so that next call will indicate * the end of the enumeration. */ if ( ProcessInfo->NextEntryOffset != 0 ) (pEnumToken->Current) += ProcessInfo->NextEntryOffset; else pEnumToken->Current = (ULONG)-1; } return(TRUE);
} // end EnumerateProcesses
|