Сообщений 26    Оценка 1440 [+3/-0]         Оценить  
Система Orphus

RSDN handle library

Набор классов-оберток для объектов ядра

Авторы: Павел Блудов
Александр Корсуков
Владислав Чистяков
The RSDN Group
Опубликовано: 09.06.2004
Исправлено: 05.01.2007
Версия текста: 2.2

Введение
Краткое описание
CHandle
CFile
CConsole
CCompletionPort
CFileMapping
CNamedPipe
CMailslot
CDevice
CCommFile
CTape
CEvent
CMutex
CSemaphore
CWaitableTimer
CMemoryResourceNotification
CProcess
CThread
CJobObject
CToken
CToolhelpSnapshot
CModule
Вспомогательные функции (chandle.h)
Вспомогательные функции (cproc.h)
Вспомогательные функции (cmodule.h)
Что нового

Исходный текст (24kb)

Введение

Вашему вниманию предлагается небольшая библиотека классов, реализующих обертки (wrappers) над хендлами (handles) таких объектов, как файлы, объекты синхронизации, процессы и нити (threads).

Идея такой библиотеки не нова, на данный момент существует несколько подобных реализаций (например ATL::CHandle, ATL::CEvent и другие из ATL 7.0). Достоинствами предлагаемой библиотеки является ее полная независимость от других библиотек, ее можно использовать в MFC, ATL проектах и просто проектах, написанных на "чистом" API. Библиотека может использоваться в уникодных (Unicode), ANSI и смешанных проектах. Кроме того, в библиотеку включены несколько вспомогательных функций, упрощающих работу с API.

У каждого класса есть пара: класс, с таким же именем, но с суффиксом Handle. Например CProcessHandle. От парного класса, handle-класс отличается тем, что не закрывает свой хеднл в деструкторе. Их удобно использовать в качестве входных параметров процедур:

void DoSmth(RSDN::CProcessHandle h)
{
	h.SetAffinityMask(1);
}

RSDN::CProcess hProcess(dwProcessId, PROCESS_ALL_ACCESS);
if (hProcess)
	DoSmth(hProcess);

Если вместо RSDN::CProcessHandle использовать RSDN::CProcess в качестве входного параметра, произойдет неявный вызов ::DuplicateHandle() перед вызовом процедуры и ::CloseHandle() при выходе из нее.

Все классы содержат одну переменную m_h, в которой находится хендл, ассоциированный с данным объектом. Таким образом, выполняется равенство

sizeof(HANDLE) == sizeof(CHandle) == sizeof(CEvent) == sizeof(CEventHandle); // и т.д.

Порядок следования аргументов в методах классов, вызывающих функции API совпадает с порядком в вызываемых функциях. Кроме тех случаев, если в начале идут параметры практически никогда не используемые. Например, параметр LPSECURITY_ATTRIBUTES у метода RSDN::CEvent::Create() идет последним и равен по умолчанию нулю.

ПРИМЕЧАНИЕ

Если Вы уже использовали класс RSDN::CHandle предыдущих версий, обратите внимание на изменения в функции IsValid(). Проверка на INVALID_HANDLE_VALUE больше не производится. Вместо этого, метод RSDN::CFile::Create() и ему подобные сами проверяют возвращаемое значение и подменяют его с INVALID_HANDLE_VALUE на NULL. Сделано это в связи с тем, что с точки зрения таких функций API, как ::DuplicateHandle(), ::CloseHandle(), ::GetHandleInformation() и им подобных, INVALID_HANDLE_VALUE является допустимым параметром, и функции отрабатывают корректно. Дело в том, что INVALID_HANDLE_VALUE – это значение, возвращаемое функцией API ::GetCurrentProcess(). Таким образом, RSDN::CHandle::Close(), RSDN::IsValidHandle() и RSDN::DuplicateHandle() не должны трактовать INVALID_HANDLE_VALUE как неправильное значение. С другой стороны, для RSDN::CFile такой хендл никак не может быть правильным. Чтобы разрешить это противоречие, все методы, для которых INVALID_HANDLE_VALUE означает ошибку, сразу заменяют его на NULL. К сожалению, INVALID_HANDLE_VALUE все-таки может "прокрасться" через оператор RSDN::CHandle::operator&() или при непосредственном обращении к RSDN::CHandle::m_h. Будьте внимательны.

Еще одно важное замечание: про конструкторы. Если конструктор вызывает какой-либо метод, например Open() или Create(), а тот не отрабатывает успешно, то код ошибки может быть утерян. Если код ошибки важен, лучше явно вызвать соответствующий метод:

RSDN::CProcess hProcess;
if (FALSE == hProcess.Open(dwProcessId, PROCESS_ALL_ACCESS))
	ReportErrorToUser(::GetLastError());

Краткое описание

Далее приведены списки методов классов, в левой колонке название метода, в правой описание или просто функции, вызываемые из этого метода.

CHandle

Базовый класс. Абстрактная обертка над любым хендлом, нуждающемся в вызове ::CloseHandle().

Самое узкое место этого класса – его конструкторы. Дело в том, что будучи нормальным C++ классом, наш RSDN::CHandle должен иметь конструктор копирования, позволяющий использовать одни HANDLE-объект несколькими RSDN::CHandle-объектами. Но с таком случае, только деструктор последнего RSDN::CHandle-объекта должен закрыть единственный HANDLE-объект. Т.е. необходимо реализовать механизм подсчета ссылок. В данном классе эта тяжкая работа поручена операционной системе; используется API ::DuplicateHandle(). Это не самое легковесное решение, и его использование сведено к минимуму. Конструктор копирования использует эту функцию, а обычный конструктор и переопределенный оператор присваивания нет.

RSDN::CHandle hRead, hWrite;
// Duplicate handle не используется
BOOL b = ::CreatePipe(&hRead, &hWrite, NULL, 0);

// Duplicate handle не используется
RSDN::CHandle hEvent = ::CreateEvent(NULL, false, false, NULL);

// Вызывается Duplicate handle
RSDN::CHandle hDup = hRead;

// ОШИБКА: НЕ ВЫЗЫВАЕТСЯ Duplicate handle,
// после уничтожения обного из объектов
// у второго остается недействительный HANDLE
RSDN::CHandle hDup = hRead.m_h;

Обратите внимание, что operator=(const CHandle&) и конструктор копирования CHandle(const CHandle&) неявно вызывают метод DuplicateFrom(). Избегайте использования этих методов, заменяя их на явный вызов DuplicateFrom() или Attach(other.Detach()):

RSDN::CHandle hPrev;
for(/*...*/)
{
    RSDN::CHandle hNext = ::CreateFile(/*...*/);
    // ...
    hPrev = hNext;
}

В этом примере все время происходит вызов функций Duplicate/Close, которых можно избежать, изменив код следующим образом:

RSDN::CHandle hPrev;
for(/*...*/)
{
    RSDN::CHandle hNext = ::CreateFile(/*...*/);
    // ...
    hPrev.Attach(hNext.Detach());
}

Эти методы были добавлены для поддержки вот такого (довольно экзотического) кода:

__STD::vector<CAdapt<RSDN::CHandle> > m_vector;

for(int i = 0; i < 10; i++)
    m_vector.push_back(::CreateThread(/*...*/));

Который, тем не менее, можно (и нужно) переделать в что-то вроде:

__STD::vector<CAdapt<RSDN::CHandle> > m_vector;
m_vector.resize(10);

for(int i = 0; i < 10; i++)
    m_vector[i].m_T = ::CreateThread(/*...*/);

Далее следует полный список методов.

HANDLE m_hЕдинственная переменная, хранящая оригинальный хендл

CHandle()m_h = NULL
CHandle(HANDLE h)Конструктор, DuplicateFrom() не вызывается
CHandle(const CHandle& other)Конструктор, DuplicateFrom() вызывается
~CHandle()Close()

bool operator!() consttrue != IsValid()
operator HANDLE() constПозволяет использовать этот объект вместо HANDLE
LPHANDLE operator&()Возвращает адрес m_h, позволяет использовать этот объект вместо HANDLE*
CHandle& operator=(HANDLE h)m_h = h, DuplicateFrom() не вызывается
CHandle& operator=(const CHandle& other)m_h = other.m_h, DuplicateFrom() вызывается
void Attach(HANDLE h)Вызывает ::Close() если нужно, затем m_h = h, (DuplicateFrom() не вызывается)
HANDLE Detach()Возвращает m_h и выставляет ее в нуль

IsValid()RSDN::IsValidHandle()
Close()::CloseHandle, если нужно
DuplicateFrom()::DuplicateHandle()
DuplicateTo()::DuplicateHandle()

GetInformation()::GetHandleInformation()
SetInformation()::SetHandleInformation()
GetKernelObjectSecurity()::GetKernelObjectSecurity()
SetKernelObjectSecurity()::SetKernelObjectSecurity()

Wait()::WaitForSingleObjectEx()
MsgWait()::MsgWaitForMultipleObjectsEx()
WaitWithMessageLoop()RSDN::WaitForSingleObjectWithMessageLoop()
SignalAndWait()::SignalObjectAndWait()
RegisterWait()::RegisterWaitForSingleObject()
UnregisterWait::UnregisterWaitEx()

CFile

CFile()Create() или ReOpen() (здесь и далее -- в зависимости от параметров)
Create()::CreateFile()
ReOpen()::ReOpenFile()

Read()::ReadFile() или ::ReadFileEx()
ReadScatter()::ReadFileScatter()
Write()::WriteFile() или ::WriteFileEx()
WriteGather()::WriteFileGather()
GetOverlappedResult()::GetOverlappedResult()
Seek()::SetFilePointer()
GetPosition()::SetFilePointer()
SetEndOfFile()::SetEndOfFile()
SetSize()Seek(); затем ::SetEndOfFile()
GetSize()::GetFileSize()

CancelIo()::CancelIo()
CreateIoCompletionPort()::CreateIoCompletionPort()
BindIoCompletionCallback()::BindIoCompletionCallback()
Flush()::FlushFileBuffers()

LockRange()::LockFile()
LockRangeEx()::LockFileEx()
UnlockRange()::UnlockFile()
UnlockRangeEx()::UnlockFileEx()

GetInformation()::GetFileInformationByHandle() или CHandle::GetInformation()
GetType()::GetFileType()
GetTime()::GetFileTime()
SetTime()::SetFileTime()
SetShortName()::SetFileShortName()
SetValidData()::SetFileValidData()

BackupRead()::BackupRead()
BackupSeek()::BackupSeek()
BackupWrite()::BackupWrite()

CConsole

CConsole()CFile::Create() или GetStd()
GetStd()::GetStdHandle()
SetStd()::SetStdHandle()
CreateScreenBuffer()::CreateConsoleScreenBuffer()

SetActiveScreenBuffer()::SetConsoleActiveScreenBuffer()
GetScreenBufferInfo()::GetConsoleScreenBufferInfo()
SetScreenBufferSize()::SetConsoleScreenBufferSize()
ScrollScreenBuffer()::ScrollConsoleScreenBuffer()

PeekInput()::PeekConsoleInput()
ReadInput()::ReadConsoleInput()
WriteInput()::WriteConsoleInput()

ReadOutput()::ReadConsoleOutput()
WriteOutput()::WriteConsoleOutput()
ReadOutputCharacter()::ReadConsoleOutputCharacter()
WriteOutputCharacter()::WriteConsoleOutputCharacter()
ReadOutputAttribute()::ReadConsoleOutputAttribute()
WriteOutputAttribute()::WriteConsoleOutputAttribute()
FillOutputCharacter()::FillConsoleOutputCharacter()
FillOutputAttribute()::FillConsoleOutputAttribute()

GetMode()::GetConsoleMode()
SetMode()::SetConsoleMode()
GetNumberOfInputEvents()::GetNumberOfConsoleInputEvents()
FlushInputBuffer()::FlushConsoleInputBuffer()
GetLargestWindowSize()::GetLargestConsoleWindowSize()
SetWindowInfo()::SetConsoleWindowInfo()
GetCursorInfo()::GetConsoleCursorInfo()
SetCursorInfo()::SetConsoleCursorInfo()
SetCursorPosition()::SetConsoleCursorPosition()
SetTextAttribute()::SetConsoleTextAttribute()
GetCurrentFont()::GetCurrentConsoleFont()
GetFontSize()::GetConsoleFontSize()

Read()::ReadConsole() или CFile::Read()
Write()::WriteConsole() или CFile::Write()

CCompletionPort

CCompletionPort()Create()
Create()::CreateIoCompletionPort()

GetStatus()::GetQueuedCompletionStatus()
PostStatus()::PostQueuedCompletionStatus()

CFileMapping

CFileMapping()Create() или Open()
Create()::CreateFileMapping()
Open()::OpenFileMapping()

MapViewOfFile()::MapViewOfFile()
MapViewOfFileEx()::MapViewOfFileEx()
UnmapViewOfFile()::UnmapViewOfFile()

CNamedPipe

CNamedPipe()Create() или CFile::Create()
Create()::CreateNamedPipe()

Connect()::ConnectNamedPipe()
Disconnect()::DisconnectNamedPipe()
Peek()::PeekNamedPipe()
Transact()::TransactNamedPipe()

GetState()::GetNamedPipeHandleState()
SetState()::SetNamedPipeHandleState()
GetInformation()::GetNamedPipeInfo(), CFile::GetInformation() или CHandle::GetInformation()
ImpersonateClient()::ImpersonateNamedPipeClient()

CMailslot

CMailslot()Create() или CFile::Create()
Create()::CreateMailslot()

GetInformation()::GetMailslotInfo(), CFile::GetInformation() или CHandle::GetInformation()
SetInformation()::SetMailslotInfo() или CHandle::SetInformation()

CDevice

CDevice()CFile::Create()

IoControl()::DeviceIoControl()
RequestWakeup()::RequestDeviceWakeup()
CancelWakeupRequest()::CancelDeviceWakeupRequest()
GetPowerState()::GetDevicePowerState()
SetMessageWaitingIndicator()::SetMessageWaitingIndicator()

CCommFile

CCommFile()CFile::Create()

ClearBreak()::ClearCommBreak()
ClearError()::ClearCommError()
EscapeFunction()::EscapeCommFunction()
GetConfig()::GetCommConfig()
GetMask()::GetCommMask()
GetModemStatus()::GetCommModemStatus()
GetProperties()::GetCommProperties()
GetState()::GetCommState()
GetTimeouts()::GetCommTimeouts()
Purge()::PurgeComm()
SetBreak()::SetCommBreak()
SetConfig()::SetCommConfig()
SetMask()::SetCommMask()
SetState()::SetCommState()
SetTimeouts()::SetCommTimeouts()
Setup()::SetupComm()
TransmitChar()::TransmitCommChar()
WaitEvent()::WaitCommEvent()

CTape

CTape()CFile::Create()

CreatePartition()::CreateTapePartition()
GetParameters()::GetTapeParameters()
GetPosition()::GetTapePosition()
GetStatus()::GetTapeStatus()
Prepare()::PrepareTape()
SetParameters()::SetTapeParameters()
SetPosition()::SetTapePosition()
WriteMark()::WriteTapemark()
Prepare()::PrepareTape()

CEvent

CEvent()Create() или Open()
Create()::CreateEvent()
Open()::OpenEvent()

Pulse()::PulseEvent()
Set()::SetEvent()
Reset()::ResetEvent()
SignalMeAndWaitOther()::SignalObjectAndWait()

CMutex

CMutex()Create() или Open()
Create()::CreateMutex()
Open()::OpenMutex()

Release()::ReleaseMutex()
SignalMeAndWaitOther()::SignalObjectAndWait()

CSemaphore

CSemaphore()Create() или Open()
Create()::CreateSemaphore()
Open()::OpenSemaphore()

Release()::ReleaseSemaphore()
SignalMeAndWaitOther()::SignalObjectAndWait()

CWaitableTimer

CWaitableTimer()Create() или Open()
Create()::CreateWaitableTimer()
Open()::OpenWaitableTimer()

Cancel()::CancelWaitableTimer()
Set()::SetWaitableTimer()

CMemoryResourceNotification

CMemoryResourceNotification()Create()
Create()::CreateMemoryResourceNotification()

Query()::QueryMemoryResourceNotification()

CProcess

CProcess()Create() или Open()
Create()RSDN::CreateProcess()
CreateAsUser()RSDN::CreateProcessAsUser()
CreateWithLogon()RSDN::CreateProcessWithLogon()
CreateWithToken()RSDN::CreateProcessWithToken()
Open()::OpenProcess()
GetCurrent()::GetCurrentProcess()

Terminate()::TerminateProcess()
DebugBreak()::DebugBreakProcess()
CheckRemoteDebuggerPresent()::CheckRemoteDebuggerPresent()
FlushInstructionCache()::FlushInstructionCache()
CreateRemoteThread()::CreateRemoteThread()
CreateRemoteThreadEx()RSDN::CreateRemoteThreadEx()
OpenToken()::OpenProcessToken()

VirtualAllocEx()::VirtualAllocEx()
VirtualFreeEx()::VirtualFreeEx()
VirtualProtectEx()::VirtualProtectEx()
VirtualQueryEx()::VirtualQueryEx()
ReadMemory()::ReadProcessMemory()
WriteMemory()::WriteProcessMemory()
AllocateUserPhysicalPages()::AllocateUserPhysicalPages()
FreeUserPhysicalPages()::FreeUserPhysicalPages()

GetHandleCount()::GetProcessHandleCount()
GetTimes()::GetProcessTimes()
GetIoCounters()::GetProcessIoCounters()
IsWow64()::IsWow64Process()
GetExitCode()::GetExitCodeProcess()
GetId()::GetProcessId()

GetAffinityMask()::GetProcessAffinityMask()
SetAffinityMask()::SetProcessAffinityMask()
GetWorkingSetSize()::GetProcessWorkingSetSize()
GetWorkingSetSizeEx()::GetProcessWorkingSetSizeEx()
SetWorkingSetSize()::SetProcessWorkingSetSize()
SetWorkingSetSizeEx()::SetProcessWorkingSetSizeEx()
GetPriorityBoost()::GetProcessPriorityBoost()
SetPriorityBoost()::SetProcessPriorityBoost()
GetPriorityClass()::GetPriorityClass()
SetPriorityClass()::SetPriorityClass()

AssignToJobObject()::AssignProcessToJobObject()
IsInJobObject()::IsProcessInJobObject()
GetGuiResources()::GetGuiResources()
WaitForInputIdle()::WaitForInputIdle()

CThread

CThread()Create() или Open()
Create()::CreateThread()
CreateRemote()::CreateRemoteThread()
CreateRemoteEx()RSDN::CreateRemoteThreadEx()
Open()::OpenThread()
GetCurrent()::GetCurrentThread()
GetId()::GetProcessId()

Terminate()::TerminateThread()
GetContext()::GetThreadContext()
SetContext()::SetThreadContext()
Suspend()::SuspendThread()
Resume()::ResumeThread()
QueueUserAPC()::QueueUserAPC()
SetToken()::SetThreadToken()
OpenToken()::OpenThreadToken()
ImpersonateAnonymousToken()::ImpersonateAnonymousToken()

GetId()::GetThreadId()
GetProcessId()::GetProcessIdOfThread()
GetTimes()::GetThreadTimes()
GetIOPendingFla()::GetThreadIOPendingFlag()
GetExitCode()::GetExitCodeThread()
GetSelectorEntry()::GetThreadSelectorEntry()

SetAffinityMask()::SetThreadAffinityMask()
SetPriority()::SetThreadPriority()
GetPriority()::GetThreadPriority()
GetPriorityBoost()::GetThreadPriorityBoost()
SetPriorityBoost()::SetThreadPriorityBoost()
SetAffinityMask()::SetProcessAffinityMask()

CJobObject

CJobObject()Create() или Open()
Create()::CreateJobObject()
Open()::OpenJobObject()

AssignProcess()::AssignProcessToJobObject()
QueryInformation()::QueryInformationJobObject()
SetInformation()::SetInformationJobObject() или CHandle::SetInformation()
IsProcessInJob()::IsProcessInJob()
Terminate()::TerminateJobObject()

CToken

LogonUser()::LogonUser()
LogonUserEx()::LogonUserEx()
LogonUserEx()::LogonUserEx()
OpenProcess()::OpenProcessToken()
OpenThread()::OpenThreadToken()
CreateRestricted()::CreateRestrictedToken()
CreateProcessAsUser()RSDN::CreateProcessAsUser()

IsRestricted()::IsTokenRestricted()
IsUntrusted()::IsTokenUntrusted()
DuplicateFrom()::DuplicateToken() или CHandle::DuplicateFrom()
DuplicateTo()::DuplicateToken() или CHandle::DuplicateTo()
ImpersonateLoggedOnUser()::ImpersonateLoggedOnUser()
SetThread()::SetThreadToken()
GetInformation()::GetTokenInformation() или CHandle::GetInformation()
SetInformation()::SetTokenInformation() или CHandle::SetInformation()

AccessCheck()::AccessCheck()
AdjustPrivileges()::AdjustTokenPrivileges()
AdjustGroups()::AdjustTokenGroups()
PrivilegeCheck()::PrivilegeCheck()
ObjectOpenAuditAlarm()::ObjectOpenAuditAlarm()
ObjectPrivilegeAuditAlarm()::ObjectPrivilegeAuditAlarm()
PrivilegedServiceAuditAlarm()::PrivilegedServiceAuditAlarm()
CreatePrivateObjectSecurity()::CreatePrivateObjectSecurity()
SetPrivateObjectSecurity()::SetPrivateObjectSecurity()
CheckMembership()::CheckTokenMembership()
AccessCheckByType()::AccessCheckByType()
AccessCheckByTypeResultList()::AccessCheckByTypeResultList()
AccessCheckByTypeResultListAndAuditAlarmByHandle()::AccessCheckByTypeResultListAndAuditAlarmByHandle()
CreatePrivateObjectSecurityEx()::CreatePrivateObjectSecurityEx()
SetPrivateObjectSecurityEx()::SetPrivateObjectSecurityEx()
CreatePrivateObjectSecurityWithMultipleInheritance()::CreatePrivateObjectSecurityWithMultipleInheritance()
CreateProcessWithToken()RSDN::CreateProcessWithToken()

CToolhelpSnapshot

CToolhelpSnapshot()Create()
Create()::CreateToolhelp32Snapshot()

First()::Heap32ListFirst(), ::Process32First(), ::Module32First() или ::Thread32First()
Next()::Heap32ListNext(), ::Process32Next(), ::Module32Next() или ::Thread32Next()

CModule

CModule()LoadLibrary() или GetHandle()
LoadLibrary()::LoadLibrary()
LoadLibraryEx()::LoadLibraryEx()
GetHandle()::GetModuleHandle()
GetHandleEx()::GetModuleHandleEx()

DuplicateFrom()RSDN::DuplicateModule()
DuplicateTo()RSDN::DuplicateModule()
LoadLibraryRelativeToModule()RSDN::LoadLibraryRelativeToModule()
FreeLibrary()::FreeLibrary()
FreeLibraryAndExitThread()::FreeLibraryAndExitThread()
DisableThreadLibraryCalls() ::DisableThreadLibraryCalls()
GetProcAddress()::GetProcAddress()
EnumResourceLanguages()::EnumResourceLanguages()
EnumResourceNames()::EnumResourceNames()
EnumResourceTypes()::EnumResourceTypes()
FindResource()::FindResource()
FindResourceEx()::FindResourceEx()
LoadResource()::LoadResource()
SizeofResource() ::SizeofResource()
GetFileName()::GetModuleFileName()

GetBaseName()::GetModuleBaseName()
GetFileNameEx()::GetModuleFileNameEx()
GetInformation()::GetModuleInformation()

Вспомогательные функции (chandle.h)

static DWORD WaitForSingleObjectWithMessageLoop
	( HANDLE hEvent
	, DWORD nTimeout = INFINITE
	, BOOL bProcessAPC = FALSE
	);

Ожидает события hEvent не долее чем nTimeout миллисекунд с обработкой сообщений.

При bProcessAPC = TRUE также обрабатываются вызовы асинхронных процедур (APC).

Если во время ожидания события из очереди было изъято сообщение WM_QUIT (что, как правило, говорит об архитектурной ошибке), то на выходе из процедуры это сообщение возвращается обратно в очередь. Если такое поведение не требуется, можно определить макрос RSDN_CHANDLE_NO_WMQUITCHECK перед включением файла <rsdn/chandle.h>.

inline bool IsValidHandle
	( HANDLE h
	);

Просто проверяет значение h на неравенство нулю. Кроме того, если определен макрос _DEBUG, то "правильность" хендла проверяется через вызов API ::GetHandleInformation().

inline BOOL DuplicateHandle
	( HANDLE hSource
	, BOOL bInherit
	, LPHANDLE lpDest
	);

Дублирует хендл для использования в текущем процессе. Это облегченная версия стандартного API ::DuplicateHandle().

Вспомогательные функции (cproc.h)

inline bool IsValidProcess
	( HANDLE hProcess
	);

Версия IsValidHandle(), специально предназначенная для проверки хендлов процессов.

inline bool IsValidThread
	( HANDLE hThread
	);

Версия RSDN::IsValidHandle(), специально предназначенная для проверки хендлов нитей.

inline BOOL CreateProcess
	( LPCTSTR lpApplicationName
	, LPTSTR lpCommandLine
	, LPSECURITY_ATTRIBUTES lpProcessAttributes
	, LPSECURITY_ATTRIBUTES lpThreadAttributes
	, BOOL bInheritHandles
	, DWORD nCreationFlags
	, LPVOID lpEnvironment
	, LPCTSTR lpCurrentDirectory
	, LPSTARTUPINFO lpStartupInfo
	, LPHANDLE lphProcess = NULL
	, LPHANDLE lphThread = NULL
	, LPDWORD lpnProcessId = NULL
	, LPDWORD lpnThreadId = NULL
	);

Аналог стандартного ::CreateProcess(), но возвращающая хендлы и идентификаторы не одной структурой, а четырьмя отдельными параметрами.

Предназначена для облегчения конструкций типа

RSDN::CProcess hProcess;
RSDN::CThread hThread;
BOOL bSuccess = RSDN::CreateProcess(NULL, _T("Program.exe"), NULL, NULL, FALSE, 0, NULL, NULL, &si, &hProcess, &hThread);

Используется в методе RSDN::CProcess::Create();

inline BOOL CreateProcess
	( LPCTSTR lpApplicationName
	, LPTSTR lpCommandLine
	, DWORD nCreationFlags = 0
	, LPSTARTUPINFO lpStartupInfo = NULL
	, LPVOID lpEnvironment = NULL
	, LPCTSTR lpCurrentDirectory = NULL
	, LPHANDLE lphProcess = NULL
	, LPHANDLE lphThread = NULL
	, LPDWORD lpnProcessId = NULL
	, LPDWORD lpnThreadId = NULL
	);

Немного облегченная версия RSDN::CreateProcess().

inline BOOL CreateProcessAsUser
	( HANDLE hToken
	, LPCTSTR lpApplicationName
	, LPSTTR lpCommandLine
	, LPSECURITY_ATTRIBUTES lpProcessAttributes
	, LPSECURITY_ATTRIBUTES lpThreadAttributes
	, BOOL bInheritHandles
	, DWORD nCreationFlags
	, LPVOID lpEnvironment
	, LPCTSTR lpCurrentDirectory
	, LPSTARTUPINFO lpStartupInfo
	, LPHANDLE lphProcess = NULL
	, LPHANDLE lphThread = NULL
	, LPDWORD lpnProcessId = NULL
	, LPDWORD lpnThreadId = NULL
	);
inline BOOL CreateProcessAsUser
	( HANDLE hToken
	, LPCTSTR lpApplicationName
	, LPTSTR lpCommandLine
	, DWORD nCreationFlags = 0
	, LPSTARTUPINFO lpStartupInfo = NULL
	, LPVOID lpEnvironment = NULL
	, LPCTSTR lpCurrentDirectory = NULL
	, LPHANDLE lphProcess = NULL
	, LPHANDLE lphThread = NULL
	, LPDWORD lpnProcessId = NULL
	, LPDWORD lpnThreadId = NULL
	);
inline BOOL CreateProcessWithLogon
	( LPCWSTR lpUsername
	, LPCWSTR lpDomain
	, LPCWSTR lpPassword
	, DWORD   nLogonFlags
	, LPCWSTR lpApplicationName
	, LPWSTR lpCommandLine
	, DWORD nCreationFlags = 0
	, LPSTARTUPINFOW lpStartupInfo = NULL
	, LPVOID lpEnvironment = NULL
	, LPCWSTR lpCurrentDirectory = NULL
	, LPHANDLE lphProcess = NULL
	, LPHANDLE lphThread = NULL
	, LPDWORD lpnProcessId = NULL
	, LPDWORD lpnThreadId = NULL
	);
inline BOOL CreateProcessWithToken
	( HANDLE hToken
	, DWORD nLogonFlags
	, LPCWSTR lpApplicationName
	, LPWSTR lpCommandLine
	, DWORD nCreationFlags = 0
	, LPSTARTUPINFOW lpStartupInfo = NULL
	, LPVOID lpEnvironment = NULL
	, LPCWSTR lpCurrentDirectory = NULL
	, LPHANDLE lphProcess = NULL
	, LPHANDLE lphThread = NULL
	, LPDWORD lpnProcessId = NULL
	, LPDWORD lpnThreadId = NULL
	);

Еще вариации на тему ::CreateProcess()

static HANDLE CreateRemoteThreadEx
	( HANDLE hProcess
	, LPSECURITY_ATTRIBUTES lpThreadAttributes
	, SIZE_T nStackSize
	, LPTHREAD_START_ROUTINE lpStartAddress
	, SIZE_T nStartRoutineSize
	, LPVOID lpParameter = NULL
	, SIZE_T nParameterSize = 0
	, DWORD nCreationFlags = 0
	, LPDWORD lpnThreadId = NULL
	, LPVOID *lplpCodeRemote = NULL
	);
inline HANDLE CreateRemoteThreadEx
	( HANDLE hProcess
	, LPTHREAD_START_ROUTINE lpStartAddress
	, SIZE_T nStartRoutineSize
	, LPVOID lpParameter = NULL
	, SIZE_T nParameterSize = 0
	, DWORD nCreationFlags = 0
	, LPDWORD lpnThreadId = NULL
	, LPVOID *lplpCodeRemote = NULL
	);

Аналог стандартной ::CreateRemoteThread(), с тем отличаем, что эти функции сначала копируют в указанный процесс саму процедуру для выполнения в "чужом" процессе и ее параметры.

inline BOOL FreeRemoteThreadMemory
	( HANDLE hProcess
	, LPVOID lpCodeRemote
	, SIZE_T nStartRoutineSize
	, SIZE_T nParameterSize = 0
	);

Освобождает память, выделенную в RSDN::CreateRemoteThreadEx(). Эту функцию следует вызывать только после того, как созданная нить будет завершена. Поскольку выделение памяти производится в другом процессе и без его ведома, то ее следует освободить явно. В противном случае, по завершении нити, память, выделенная в том процессе так и останется не освобожденной до его завершения.

Вспомогательные функции (cmodule.h)

inline bool IsValidModule
	( HMODULE h
	);

Версия IsValidHandle(), специально предназначенная для проверки хендлов модулей.

inline BOOL DuplicateModule
	( IN HMODULE hSource
	, OUT HMODULE *lpDest
	);

То же, что и DuplicateHandle, только для модулей.

inline HMODULE LoadLibraryRelativeToModule
	( IN HMODULE hSource
	, IN LPCSTR lpLibFileName
	);

Загружает .dll по относительному пути, задаваемом хендлом модуля. Может пригодиться, если нужно загрузить .dll из другой .dll, расположенной в другом каталоге, чем .exe.

Что нового

Апрель 2004


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
    Сообщений 26    Оценка 1440 [+3/-0]         Оценить