//---------------------------------------------------------------------------- // // HandleHelpers.h // // Wrapper classes for the system handles. // // Copyright (c) Microsoft. All rights reserved. //---------------------------------------------------------------------------- #pragma once #define RemoveEntryList(Entry) {\ PLIST_ENTRY _EX_Blink;\ PLIST_ENTRY _EX_Flink;\ _EX_Flink = (Entry)->Flink;\ _EX_Blink = (Entry)->Blink;\ _EX_Blink->Flink = _EX_Flink;\ _EX_Flink->Blink = _EX_Blink;\ } #define InitializeListHead(ListHead) (\ (ListHead)->Flink = (ListHead)->Blink = (ListHead)) #define InsertTailList(ListHead,Entry) {\ PLIST_ENTRY _EX_Blink;\ PLIST_ENTRY _EX_ListHead;\ _EX_ListHead = (ListHead);\ _EX_Blink = _EX_ListHead->Blink;\ (Entry)->Flink = _EX_ListHead;\ (Entry)->Blink = _EX_Blink;\ _EX_Blink->Flink = (Entry);\ _EX_ListHead->Blink = (Entry);\ } namespace GdbSrvControllerLib { class HandleWrapper { public: HandleWrapper() : m_handle(INVALID_HANDLE_VALUE) { } HandleWrapper(_In_ HANDLE handle) : m_handle(handle) { } ~HandleWrapper() { Close(); } HANDLE Detach() { HANDLE handle = m_handle; m_handle = INVALID_HANDLE_VALUE; return handle; } HANDLE Get() const { return m_handle; } bool IsValid() const { return m_handle != INVALID_HANDLE_VALUE; } HANDLE *operator&() { //Used to pass to a _Out_ PHANDLE argument. Similar to CComPtr in ATL. //If the handle is already valid, such use case will lead to a handle leak. assert(m_handle == INVALID_HANDLE_VALUE); return &m_handle; } void Close() { if (m_handle == INVALID_HANDLE_VALUE) { return; } CloseHandle(m_handle); m_handle = INVALID_HANDLE_VALUE; } void Attach(_In_ HANDLE handle) { assert(handle != nullptr); Close(); m_handle = handle; } static void CloseAndInvalidate(_Inout_ HANDLE *pHandle) { assert(pHandle != nullptr); CloseHandle(*pHandle); *pHandle = INVALID_HANDLE_VALUE; } private: HANDLE m_handle; HandleWrapper(_In_ const HandleWrapper &anotherHandleWrapper); void operator=(_In_ const HandleWrapper &anotherHandleWrapper); }; class ValidHandleWrapper : public HandleWrapper { public: ValidHandleWrapper(_In_ HANDLE handle) : HandleWrapper(handle) { assert(handle != INVALID_HANDLE_VALUE); } }; class scoped_lock { public: _Acquires_lock_(cs) scoped_lock(_In_ CRITICAL_SECTION& cs) : pCS(&cs) { EnterCriticalSection(this->pCS); } _Releases_lock_(*(this->pCS)) ~scoped_lock() { LeaveCriticalSection(this->pCS); } private: CRITICAL_SECTION * pCS; }; }