windows-nt/Source/XPSP1/NT/shell/lib/generic/kernelresources.cpp
2020-09-26 16:20:57 +08:00

1271 lines
34 KiB
C++

// --------------------------------------------------------------------------
// 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);
}