stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
system.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023 Amebis
4*/
5
6#pragma once
7
8#ifdef _WIN32
9#define NOMINMAX // Collides with std::min/max
10#include <windows.h>
11#include <intsafe.h>
12#include <tchar.h>
13#else
14#include <unistd.h>
15#endif
16#include "sal.hpp"
17#include <assert.h>
18#include <stdexcept>
19
20// In case somebody #included <windows.h> before us and didn't #define NOMINMAX
21#ifdef _WIN32
22#ifdef min
23#undef min
24#endif
25#ifdef max
26#undef max
27#endif
28#endif
29
30namespace stdex
31{
35#if defined(_WIN32)
36 using sys_handle = HANDLE;
37 const sys_handle invalid_handle = INVALID_HANDLE_VALUE;
38#else
39 using sys_handle = int;
40 const sys_handle invalid_handle = (sys_handle)-1;
41#endif
42
46#if defined(_WIN32)
47 using sys_char = TCHAR;
48#else
49 using sys_char = char;
50#define _T(x) x
51#endif
52
57 {
58 public:
59 sys_object(_In_opt_ sys_handle h = invalid_handle) : m_h(h) {}
60
61 sys_object(_In_ const sys_object& other) : m_h(other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle) {}
62
63 sys_object& operator =(_In_ const sys_object& other)
64 {
65 if (this != std::addressof(other)) {
66 if (m_h != invalid_handle)
67 close(m_h);
68 m_h = other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle;
69 }
70 return *this;
71 }
72
73 sys_object(_Inout_ sys_object&& other) noexcept : m_h(other.m_h)
74 {
75 other.m_h = invalid_handle;
76 }
77
78 sys_object& operator =(_Inout_ sys_object&& other) noexcept
79 {
80 if (this != std::addressof(other)) {
81 if (m_h != invalid_handle)
82 close(m_h);
83 m_h = other.m_h;
84 other.m_h = invalid_handle;
85 }
86 return *this;
87 }
88
89 virtual ~sys_object()
90 {
91 if (m_h != invalid_handle)
92 close(m_h);
93 }
94
98 virtual void close()
99 {
100 if (m_h != invalid_handle) {
101 close(m_h);
102 m_h = invalid_handle;
103 }
104 }
105
109 inline operator bool() const noexcept { return m_h != invalid_handle; }
110
114 inline sys_handle get() const noexcept { return m_h; }
115
116 protected:
120 static void close(sys_handle h)
121 {
122#ifdef _WIN32
123 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
124#else
125 if (close(h) >= 0 || errno == EBADF)
126#endif
127 return;
128 throw std::runtime_error("failed to close handle");
129 }
130
134 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit)
135 {
136 sys_handle h_new;
137#ifdef _WIN32
138 HANDLE process = GetCurrentProcess();
139 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
140#else
141 UNREFERENCED_PARAMETER(inherit);
142 if ((h_new = dup(h)) >= 0)
143#endif
144 return h_new;
145 throw std::runtime_error("failed to duplicate handle");
146 }
147
148 protected:
149 sys_handle m_h;
150 };
151
152#ifdef _WIN32
153 template <class T>
154 class safearray_accessor
155 {
156 public:
157 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
158 {
159 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
160 if (FAILED(hr))
161 throw std::invalid_argument("SafeArrayAccessData failed");
162 }
163
164 ~safearray_accessor()
165 {
166 SafeArrayUnaccessData(m_sa);
167 }
168
169 T* data() const { return m_data; }
170
171 protected:
172 LPSAFEARRAY m_sa;
173 T* m_data;
174 };
175
179 struct SafeArrayDestroy_delete
180 {
184 void operator()(_In_ LPSAFEARRAY sa) const
185 {
186 SafeArrayDestroy(sa);
187 }
188 };
189
193 struct SysFreeString_delete
194 {
198 void operator()(_In_ BSTR sa) const
199 {
200 SysFreeString(sa);
201 }
202 };
203#endif
204}
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:57
sys_handle get() const noexcept
Returns object handle.
Definition system.hpp:114
virtual void close()
Closes object.
Definition system.hpp:98
static sys_handle duplicate(sys_handle h, bool inherit)
Duplicates given object.
Definition system.hpp:134
static void close(sys_handle h)
Closes object.
Definition system.hpp:120