|
|
// --------------------------------------------------------------------------
// Module Name: KernelResources.cpp
//
// Copyright (c) 1999-2000, Microsoft Corporation
//
// General class definitions that assist in resource management. These are
// typically stack based objects where constructors initialize to a known
// state. Member functions operate on that resource. Destructors release
// resources when the object goes out of scope.
//
// History: 1999-08-18 vtan created
// 1999-11-16 vtan separate file
// 2000-02-01 vtan moved from Neptune to Whistler
// --------------------------------------------------------------------------
#include "StandardHeader.h"
#include "KernelResources.h"
#include "StatusCode.h"
// --------------------------------------------------------------------------
// CHandle::CHandle
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Initializes the CHandle object.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CHandle::CHandle (HANDLE handle) : _handle(handle)
{ }
// --------------------------------------------------------------------------
// CHandle::~CHandle
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Releases resources used by the CHandle object.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CHandle::~CHandle (void)
{ ReleaseHandle(_handle); }
// --------------------------------------------------------------------------
// CHandle::operator HANDLE
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Magically converts a CHandle to a HANDLE.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CHandle::operator HANDLE (void) const
{ return(_handle); }
// --------------------------------------------------------------------------
// CEvent::CEvent
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Initializes the CEvent object. No event is created.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CEvent::CEvent (void) : _hEvent(NULL)
{ }
// --------------------------------------------------------------------------
// CEvent::CEvent
//
// Arguments: copyObject = Object to copy on construction.
//
// Returns: <none>
//
// Purpose: Copy constructor for the CEvent object. An event is
// duplicated.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CEvent::CEvent (const CEvent& copyObject) : _hEvent(NULL)
{ *this = copyObject; }
// --------------------------------------------------------------------------
// CEvent::CEvent
//
// Arguments: pszName = Optional name of an event object to create on
// construction.
//
// Returns: <none>
//
// Purpose: Initializes the CEvent object. A named event is created.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CEvent::CEvent (const TCHAR *pszName) : _hEvent(NULL)
{ TSTATUS(Create(pszName)); }
// --------------------------------------------------------------------------
// CEvent::~CEvent
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Releases resources used by the CEvent object.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CEvent::~CEvent (void)
{ TSTATUS(Close()); }
// --------------------------------------------------------------------------
// CEvent::operator =
//
// Arguments: assignObject = Object being assigned.
//
// Returns: const CEvent&
//
// Purpose: Overloaded operator = to ensure that the event is properly
// duplicated with another handle referencing the same object.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
const CEvent& CEvent::operator = (const CEvent& assignObject)
{ if (this != &assignObject) { TSTATUS(Close()); TBOOL(DuplicateHandle(GetCurrentProcess(), assignObject._hEvent, GetCurrentProcess(), &_hEvent, 0, FALSE, DUPLICATE_SAME_ACCESS)); } return(*this); }
// --------------------------------------------------------------------------
// CEvent::operator HANDLE
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Magically converts a CEvent to a HANDLE.
//
// History: 1999-09-21 vtan created
// --------------------------------------------------------------------------
CEvent::operator HANDLE (void) const
{ return(_hEvent); }
// --------------------------------------------------------------------------
// CEvent::Open
//
// Arguments: pszName = Optional name of the event object to open.
// dwAccess = Access level required.
//
// Returns: NTSTATUS
//
// Purpose: Opens the event object.
//
// History: 1999-10-26 vtan created
// --------------------------------------------------------------------------
NTSTATUS CEvent::Open (const TCHAR *pszName, DWORD dwAccess)
{ NTSTATUS status;
TSTATUS(Close()); _hEvent = OpenEvent(dwAccess, FALSE, pszName); if (_hEvent != NULL) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CEvent::Create
//
// Arguments: pszName = Optional name of the event object to create. It
// is possible to create un-named events.
//
// Returns: NTSTATUS
//
// Purpose: Creates the event object. The event is manually reset and NOT
// signaled initially.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
NTSTATUS CEvent::Create (const TCHAR *pszName)
{ NTSTATUS status;
TSTATUS(Close()); _hEvent = CreateEvent(NULL, TRUE, FALSE, pszName); if (_hEvent != NULL) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CEvent::Set
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Set the event object state to signaled.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
NTSTATUS CEvent::Set (void) const
{ NTSTATUS status;
ASSERTMSG(_hEvent != NULL, "No event object in CEvent::Set"); if (SetEvent(_hEvent) != FALSE) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CEvent::Reset
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Clears the event object state to NOT signaled.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
NTSTATUS CEvent::Reset (void) const
{ NTSTATUS status;
ASSERTMSG(_hEvent != NULL, "No event object in CEvent::Reset"); if (ResetEvent(_hEvent) != FALSE) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CEvent::Pulse
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Set the event object state to signaled, releases any threads
// waiting on this event and clears the event object state to
// NOT signaled.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
NTSTATUS CEvent::Pulse (void) const
{ NTSTATUS status;
ASSERTMSG(_hEvent != NULL, "No event object in CEvent::Pulse"); if (PulseEvent(_hEvent) != FALSE) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CEvent::Wait
//
// Arguments: dwMilliseconds = Number of milliseconds to wait until the
// event becomes signaled.
// pdwWaitResult = Result from kernel32!WaitForSingleObject.
//
// Returns: NTSTATUS
//
// Purpose: Waits for the event object to become signaled.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
NTSTATUS CEvent::Wait (DWORD dwMilliseconds, DWORD *pdwWaitResult) const
{ NTSTATUS status; DWORD dwWaitResult;
ASSERTMSG(_hEvent != NULL, "No event object in CEvent::Wait"); dwWaitResult = WaitForSingleObject(_hEvent, dwMilliseconds); if (pdwWaitResult != NULL) { *pdwWaitResult = dwWaitResult; } if (dwWaitResult == WAIT_OBJECT_0) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CEvent::Wait
//
// Arguments: dwMilliseconds = Number of milliseconds to wait until the
// event becomes signaled.
// pdwWaitResult = Result from kernel32!WaitForSingleObject.
//
// Returns: NTSTATUS
//
// Purpose: Waits for the event object to become signaled.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
NTSTATUS CEvent::WaitWithMessages (DWORD dwMilliseconds, DWORD *pdwWaitResult) const
{ NTSTATUS status; DWORD dwWaitResult;
do {
// When waiting for the object check to see that it's not signaled.
// If signaled then abandon the wait loop. Otherwise allow user32
// to continue processing messages for this thread.
dwWaitResult = WaitForSingleObject(_hEvent, 0); if (dwWaitResult != WAIT_OBJECT_0) { dwWaitResult = MsgWaitForMultipleObjects(1, &_hEvent, FALSE, dwMilliseconds, QS_ALLINPUT); if (dwWaitResult == WAIT_OBJECT_0 + 1) { MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != FALSE) { (BOOL)TranslateMessage(&msg); (LRESULT)DispatchMessage(&msg); } } } } while (dwWaitResult == WAIT_OBJECT_0 + 1); if (pdwWaitResult != NULL) { *pdwWaitResult = dwWaitResult; } if (dwWaitResult == WAIT_OBJECT_0) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CEvent::IsSignaled
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Returns whether the event is signaled without waiting.
//
// History: 2000-08-09 vtan created
// --------------------------------------------------------------------------
bool CEvent::IsSignaled (void) const
{ return(WAIT_OBJECT_0 == WaitForSingleObject(_hEvent, 0)); }
// --------------------------------------------------------------------------
// CEvent::Close
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Closes the event object HANDLE.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
NTSTATUS CEvent::Close (void)
{ ReleaseHandle(_hEvent); return(STATUS_SUCCESS); }
// --------------------------------------------------------------------------
// CJob::CJob
//
// Arguments: pszName = Optional name of an event object to create on
// construction.
//
// Returns: <none>
//
// Purpose: Initializes the CJob object. A named event is created.
//
// History: 1999-10-07 vtan created
// --------------------------------------------------------------------------
CJob::CJob (const TCHAR *pszName) : _hJob(NULL)
{ _hJob = CreateJobObject(NULL, pszName); ASSERTMSG(_hJob != NULL, "Job object creation failed iN CJob::CJob"); }
// --------------------------------------------------------------------------
// CJob::~CJob
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Releases resources used by the CJob object.
//
// History: 1999-10-07 vtan created
// --------------------------------------------------------------------------
CJob::~CJob (void)
{ ReleaseHandle(_hJob); }
// --------------------------------------------------------------------------
// CJob::AddProcess
//
// Arguments: hProcess = Handle to the process to add to this job.
//
// Returns: NTSTATUS
//
// Purpose: Adds the process to this job.
//
// History: 1999-10-07 vtan created
// --------------------------------------------------------------------------
NTSTATUS CJob::AddProcess (HANDLE hProcess) const
{ NTSTATUS status;
ASSERTMSG(_hJob != NULL, "Must have job object in CJob::AddProcess"); if (AssignProcessToJobObject(_hJob, hProcess) != FALSE) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CJob::SetCompletionPort
//
// Arguments: hCompletionPort = IO completion port for job completion
// messages.
//
// Returns: NTSTATUS
//
// Purpose: Set the IO completion port for this job. The caller should
// watch this port for messages related to this job.
//
// History: 1999-10-07 vtan created
// --------------------------------------------------------------------------
NTSTATUS CJob::SetCompletionPort (HANDLE hCompletionPort) const
{ NTSTATUS status; JOBOBJECT_ASSOCIATE_COMPLETION_PORT associateCompletionPort;
ASSERTMSG(_hJob != NULL, "Must have job object in CJob::SetCompletionPort"); associateCompletionPort.CompletionKey = NULL; associateCompletionPort.CompletionPort = hCompletionPort;
// If the job completion port cannot be set then don't use it.
if (SetInformationJobObject(_hJob, JobObjectAssociateCompletionPortInformation, &associateCompletionPort, sizeof(associateCompletionPort)) != FALSE) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CJob:SetActiveProcessLimit
//
// Arguments: dwActiveProcessLimit = Maximum number of processes.
//
// Returns: NTSTATUS
//
// Purpose: Sets the limit for the number of processes related to this
// job. Typically you can use this to restrict a process from
// starting another process whena quota (such as 1) is reached.
//
// History: 1999-10-07 vtan created
// --------------------------------------------------------------------------
NTSTATUS CJob::SetActiveProcessLimit (DWORD dwActiveProcessLimit) const
{ NTSTATUS status; DWORD dwReturnLength; JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimitInformation;
ASSERTMSG(_hJob != NULL, "Must have job object in CJob::SetActiveProcessLimit"); if (QueryInformationJobObject(_hJob, JobObjectBasicLimitInformation, &basicLimitInformation, sizeof(basicLimitInformation), &dwReturnLength) != FALSE) { if (dwActiveProcessLimit == 0) { basicLimitInformation.LimitFlags &= ~JOB_OBJECT_LIMIT_ACTIVE_PROCESS; basicLimitInformation.ActiveProcessLimit = 0; } else { basicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS; basicLimitInformation.ActiveProcessLimit = dwActiveProcessLimit; } if (SetInformationJobObject(_hJob, JobObjectBasicLimitInformation, &basicLimitInformation, sizeof(basicLimitInformation)) != FALSE) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
NTSTATUS CJob::SetPriorityClass (DWORD dwPriorityClass) const
{ NTSTATUS status; DWORD dwReturnLength; JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimitInformation;
ASSERTMSG(_hJob != NULL, "Must have job object in CJob::SetPriorityClass"); if (QueryInformationJobObject(_hJob, JobObjectBasicLimitInformation, &basicLimitInformation, sizeof(basicLimitInformation), &dwReturnLength) != FALSE) { if (dwPriorityClass == 0) { basicLimitInformation.LimitFlags &= ~JOB_OBJECT_LIMIT_PRIORITY_CLASS; basicLimitInformation.PriorityClass = NORMAL_PRIORITY_CLASS; } else { basicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_PRIORITY_CLASS; basicLimitInformation.PriorityClass = dwPriorityClass; } if (SetInformationJobObject(_hJob, JobObjectBasicLimitInformation, &basicLimitInformation, sizeof(basicLimitInformation)) != FALSE) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CJob:RestrictAccessUIAll
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Restricts process in the job from accessing UI components.
// Take care when using this feature.
//
// History: 1999-10-07 vtan created
// --------------------------------------------------------------------------
NTSTATUS CJob::RestrictAccessUIAll (void) const
{ NTSTATUS status; JOBOBJECT_BASIC_UI_RESTRICTIONS basicUIRestrictions;
ASSERTMSG(_hJob != NULL, "Must have job object in CJob::RestrictAccessUIAll"); basicUIRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS | JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_GLOBALATOMS | JOB_OBJECT_UILIMIT_HANDLES | JOB_OBJECT_UILIMIT_READCLIPBOARD | JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD; if (SetInformationJobObject(_hJob, JobObjectBasicUIRestrictions, &basicUIRestrictions, sizeof(basicUIRestrictions)) != FALSE) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CMutex::Initialize
//
// Arguments: pszMutexName = Name of the mutex to create.
//
// Returns: NTSTATUS
//
// Purpose: Create or open a mutex object. It always tries to create the
// mutex so a name MUST be specified.
//
// History: 1999-10-13 vtan created
// --------------------------------------------------------------------------
NTSTATUS CMutex::Initialize (const TCHAR *pszMutexName)
{ NTSTATUS status;
ASSERTMSG(pszMutexName != NULL, "Must specify a mutex name in CMutex::Initialize"); _hMutex = CreateMutex(NULL, FALSE, pszMutexName); if (_hMutex != NULL) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CMutex::Terminate
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Releases the mutex object resource.
//
// History: 1999-10-13 vtan created
// --------------------------------------------------------------------------
NTSTATUS CMutex::Terminate (void)
{ ReleaseHandle(_hMutex); return(STATUS_SUCCESS); }
// --------------------------------------------------------------------------
// CMutex::Acquire
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Acquires the mutex object. This will block indefinitely and
// will also block a message pump. Use this with caution!
//
// History: 1999-10-13 vtan created
// --------------------------------------------------------------------------
void CMutex::Acquire (void)
{ if (_hMutex != NULL) { (DWORD)WaitForSingleObject(_hMutex, INFINITE); } }
// --------------------------------------------------------------------------
// CMutex::Release
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Releases ownership of the mutex object.
//
// History: 1999-10-13 vtan created
// --------------------------------------------------------------------------
void CMutex::Release (void)
{ if (_hMutex != NULL) { TBOOL(ReleaseMutex(_hMutex)); } }
// --------------------------------------------------------------------------
// CCriticalSection::CCriticalSection
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Initializes the critical section object.
//
// History: 1999-11-06 vtan created
// --------------------------------------------------------------------------
CCriticalSection::CCriticalSection (void)
{ _status = RtlInitializeCriticalSection(&_criticalSection); }
// --------------------------------------------------------------------------
// CCriticalSection::~CCriticalSection
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Destroys the critical section object.
//
// History: 1999-11-06 vtan created
// --------------------------------------------------------------------------
CCriticalSection::~CCriticalSection (void)
{ if (NT_SUCCESS(_status)) { TSTATUS(RtlDeleteCriticalSection(&_criticalSection)); } }
// --------------------------------------------------------------------------
// CCriticalSection::Acquire
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Acquire the critical section object.
//
// History: 1999-11-06 vtan created
// --------------------------------------------------------------------------
void CCriticalSection::Acquire (void)
{ if (NT_SUCCESS(_status)) { EnterCriticalSection(&_criticalSection); } }
// --------------------------------------------------------------------------
// CCriticalSection::Release
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Release the critical section object.
//
// History: 1999-11-06 vtan created
// --------------------------------------------------------------------------
void CCriticalSection::Release (void)
{ if (NT_SUCCESS(_status)) { LeaveCriticalSection(&_criticalSection); } }
// --------------------------------------------------------------------------
// CCriticalSection::Status
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Returns the construction status.
//
// History: 2000-12-09 vtan created
// --------------------------------------------------------------------------
NTSTATUS CCriticalSection::Status (void) const
{ return(_status); }
// --------------------------------------------------------------------------
// CCriticalSection::IsOwned
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Returns whether the critical section is owned.
//
// History: 2001-04-05 vtan created
// --------------------------------------------------------------------------
bool CCriticalSection::IsOwned (void) const
{ return(NT_SUCCESS(_status) && (_criticalSection.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)); }
// --------------------------------------------------------------------------
// CModule::CModule
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Initializes the CModule object. Opens the given dynamic link
// library.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CModule::CModule (const TCHAR *pszModuleName) : _hModule(NULL)
{ _hModule = LoadLibrary(pszModuleName); }
// --------------------------------------------------------------------------
// CModule::~CModule
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Releases resources used by the CModule object. Closes the
// library if opened.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CModule::~CModule (void)
{ if (_hModule != NULL) { TBOOL(FreeLibrary(_hModule)); _hModule = NULL; } }
// --------------------------------------------------------------------------
// CModule::operator HMODULE
//
// Arguments: <none>
//
// Returns: HMODULE
//
// Purpose: Returns the HMODULE for the loaded library.
//
// History: 2000-10-12 vtan created
// --------------------------------------------------------------------------
CModule::operator HMODULE (void) const
{ return(_hModule); }
// --------------------------------------------------------------------------
// CModule::GetProcAddress
//
// Arguments: pszProcName = Name of function entry point to retrieve
// in the given dynamic link library. This is
// ANSI by definition.
//
// Returns: void* = Address of the function if it exists or NULL if
// failed.
//
// Purpose: Retrieves the function entry point in a dynamic link library.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
void* CModule::GetProcAddress (LPCSTR pszProcName) const
{ void* pfnResult;
pfnResult = NULL; if (_hModule != NULL) { pfnResult = ::GetProcAddress(_hModule, pszProcName); } return(pfnResult); }
// --------------------------------------------------------------------------
// CFile::CFile
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Initializes the CFile object.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CFile::CFile (void) : _hFile(NULL)
{ }
// --------------------------------------------------------------------------
// CFile::~CFile
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Releases resources used by the CFile object.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
CFile::~CFile (void)
{ ReleaseHandle(_hFile); }
// --------------------------------------------------------------------------
// CFile::Open
//
// Arguments: See the platform SDK under kernel32!CreateFile.
//
// Returns: LONG
//
// Purpose: See kernel32!CreateFile.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
LONG CFile::Open (const TCHAR *pszFilepath, DWORD dwDesiredAccess, DWORD dwShareMode)
{ LONG errorCode;
ASSERTMSG((_hFile == NULL) || (_hFile == INVALID_HANDLE_VALUE), "Open file HANDLE exists in CFile::GetSize"); _hFile = CreateFile(pszFilepath, dwDesiredAccess, dwShareMode, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (_hFile != INVALID_HANDLE_VALUE) { errorCode = ERROR_SUCCESS; } else { errorCode = GetLastError(); } return(errorCode); }
// --------------------------------------------------------------------------
// CFile::GetSize
//
// Arguments: See the platform SDK under kernel32!GetFileSize.
//
// Returns: LONG
//
// Purpose: See kernel32!GetFileSize.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
LONG CFile::GetSize (DWORD& dwLowSize, DWORD *pdwHighSize) const
{ LONG errorCode;
ASSERTMSG((_hFile != NULL) && (_hFile != INVALID_HANDLE_VALUE), "No open file HANDLE in CFile::GetSize"); dwLowSize = GetFileSize(_hFile, pdwHighSize); if (dwLowSize != static_cast<DWORD>(-1)) { errorCode = ERROR_SUCCESS; } else { errorCode = GetLastError(); } return(errorCode); }
// --------------------------------------------------------------------------
// CFile::Read
//
// Arguments: See the platform SDK under kernel32!ReadFile.
//
// Returns: LONG
//
// Purpose: See kernel32!ReadFile.
//
// History: 1999-08-18 vtan created
// --------------------------------------------------------------------------
LONG CFile::Read (void *pvBuffer, DWORD dwBytesToRead, DWORD *pdwBytesRead) const
{ LONG errorCode;
ASSERTMSG((_hFile != NULL) && (_hFile != INVALID_HANDLE_VALUE), "No open file HANDLE in CFile::GetSize"); if (ReadFile(_hFile, pvBuffer, dwBytesToRead, pdwBytesRead, NULL) != FALSE) { errorCode = ERROR_SUCCESS; } else { errorCode = GetLastError(); } return(errorCode); }
// --------------------------------------------------------------------------
// CDesktop::CDesktop
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Constructor for CDesktop. Saves the current thread's desktop.
//
// History: 2001-02-06 vtan created
// --------------------------------------------------------------------------
CDesktop::CDesktop (void) : _hDeskCurrent(GetThreadDesktop(GetCurrentThreadId())), _hDesk(NULL)
{ }
// --------------------------------------------------------------------------
// CDesktop::~CDesktop
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Destructor for CDesktop. Restores the thread's desktop to
// its previous state prior to the object's scope.
//
// History: 2001-02-06 vtan created
// --------------------------------------------------------------------------
CDesktop::~CDesktop (void)
{ TBOOL(SetThreadDesktop(_hDeskCurrent)); if (_hDesk != NULL) { TBOOL(CloseDesktop(_hDesk)); _hDesk = NULL; } _hDeskCurrent = NULL; }
// --------------------------------------------------------------------------
// CDesktop::Set
//
// Arguments: pszName = Name of desktop to set the thread to.
//
// Returns: NTSTATUS
//
// Purpose: Opens the named desktop with MAXIMUM_ALLOWED access and sets
// the current thread's desktop to it.
//
// History: 2001-02-06 vtan created
// --------------------------------------------------------------------------
NTSTATUS CDesktop::Set (const TCHAR *pszName)
{ NTSTATUS status;
_hDesk = OpenDesktop(pszName, 0, FALSE, MAXIMUM_ALLOWED); if (_hDesk != NULL) { status = Set(); } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CDesktop::SetInput
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Opens the input desktop and sets the current thread's desktop
// to it.
//
// History: 2001-02-06 vtan created
// --------------------------------------------------------------------------
NTSTATUS CDesktop::SetInput (void)
{ NTSTATUS status;
_hDesk = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED); if (_hDesk != NULL) { status = Set(); } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
// --------------------------------------------------------------------------
// CDesktop::Set
//
// Arguments: <none>
//
// Returns: NTSTATUS
//
// Purpose: Sets the thread's desktop to the given HDESK.
//
// History: 2001-02-06 vtan created
// --------------------------------------------------------------------------
NTSTATUS CDesktop::Set (void)
{ NTSTATUS status;
if (SetThreadDesktop(_hDesk) != FALSE) { status = STATUS_SUCCESS; } else { status = CStatusCode::StatusCodeOfLastError(); } return(status); }
|