TBarnekov.WinHandle
1.0.0
See the version list below for details.
dotnet add package TBarnekov.WinHandle --version 1.0.0
NuGet\Install-Package TBarnekov.WinHandle -Version 1.0.0
<PackageReference Include="TBarnekov.WinHandle" Version="1.0.0" />
paket add TBarnekov.WinHandle --version 1.0.0
#r "nuget: TBarnekov.WinHandle, 1.0.0"
// Install TBarnekov.WinHandle as a Cake Addin #addin nuget:?package=TBarnekov.WinHandle&version=1.0.0 // Install TBarnekov.WinHandle as a Cake Tool #tool nuget:?package=TBarnekov.WinHandle&version=1.0.0
WinHandle
WinHandle is a simple and easy to use C++20 wrapper for managing the lifetime of Windows handles. It mimics a shared pointer to ensure the handle is released when its reference count drops to zero.
Installation
Download WinHandle.h from this repository and place it in the include path of your project.
Usage
Simple example
The WinHandle template takes the type of the owned handle as the first template parameter.
#include "WinHandle.h"
int main(int argc, char** argv)
{
WinHandle<HANDLE> dc{ &DeleteDC };
dc = CreateDC(TEXT("DISPLAY"), nullptr, nullptr, nullptr);
...
}
NULL handle values
Some Windows handles use a value other than NULL to signify an invalid handle value. The null value can be specified as the second template parameter. For instance, CreateFile returns INVALID_HANDLE_VALUE to signal an invalid handle.
WinHandle<HANDLE, INVALID_HANDLE_VALUE> hFile { &CloseHandle };
hFile = CreateFile(TEXT("file.txt"), GENERIC_READ, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, 0, nullptr);
if (hFile.valid())
{
...
}
Getting a handle as an OUT parameter
Some handles are acquired by calling a function with a pointer to the handle as a parameter. WinHandle supports this using the .ptr() member function.
WinHandle<HCRYPTPROV> hProv;
if (CryptAcquireContext(hProv.ptr(), TEXT("MyKeyContainer"), NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
...
}
If the WinHandle already contains a valid handle, that handle will be released and replaced by the new handle.
Handle release with additional parameters
Some handles must be released using functions that take more parameters than just the handle. If the handle is the first parameter of the release function, the additional parameters can be specified in the WinHandle constructor. For instance, CryptReleaseContext takes an additional DWORD parameter.
WinHandle<HCRYPTPROV> hProv{ &CryptReleaseContext, static_cast<DWORD>(0) };
if (CryptAcquireContext(hProv.ptr(), TEXT("MyKeyContainer"), NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{
...
}
Custom release functions
You can specify a custom function to be called when the handle should be released. WinHandle supports std::function, plain function pointers and member function pointers as handle release functions.
// std::function
WinHandle<HANDLE> { [](Handle h) { return TRUE; } };
// Function pointer
WinHandle<HANDLE> { &CloseHandle };
// Member function pointer
MyClass cls;
WinHandle<HANDLE> { &MyClass::releaseHandle, &cls };
Assignment
// Initialize a WinHandle with a HANDLE to a file
WinHandle<HANDLE, INVALID_HANDLE_VALUE> handle1 { CreateFile(TEXT("File1.txt"), GENERIC_READ, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, 0, nullptr), &CloseHandle };
// Assigning a new handle will release the original handle.
handle1 = CreateFile(TEXT("File2.txt", GENERIC_READ, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, 0, nullptr);
// Create a new WinHandle
WinHandle<HANDLE, INVALID_HANDLE_VALUE> handle2 { CreateFile(TEXT("File1.txt"), GENERIC_READ, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, 0, nullptr), &CloseHandle };
// The handle owned by handle1 is released and handle1 and handle2 will reference the same handle
handle1 = handle2;
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
License
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.