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 <oaidl.h>
13#include <tchar.h>
14#else
15#include <unistd.h>
16#endif
17#include "sal.hpp"
18#include <assert.h>
19#include <stdexcept>
20#include <string>
21
22// In case somebody #included <windows.h> before us and didn't #define NOMINMAX
23#ifdef _WIN32
24#ifdef min
25#undef min
26#endif
27#ifdef max
28#undef max
29#endif
30#endif
31
32namespace stdex
33{
37#if defined(_WIN32)
38 using sys_handle = HANDLE;
39 const sys_handle invalid_handle = INVALID_HANDLE_VALUE;
40#else
41 using sys_handle = int;
42 const sys_handle invalid_handle = (sys_handle)-1;
43#endif
44
48#if defined(_WIN32)
49 using schar_t = TCHAR;
50#else
51 using schar_t = char;
52#define _T(x) x
53#endif
54
59 using sys_char = schar_t;
60
64 using sstring = std::basic_string<stdex::schar_t>;
65
70 using sys_string = sstring;
71
76 {
77 public:
78 sys_object(_In_opt_ sys_handle h = invalid_handle) : m_h(h) {}
79
80 sys_object(_In_ const sys_object& other) : m_h(other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle) {}
81
82 sys_object& operator =(_In_ const sys_object& other)
83 {
84 if (this != std::addressof(other)) {
85 if (m_h != invalid_handle)
86 close(m_h);
87 m_h = other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle;
88 }
89 return *this;
90 }
91
92 sys_object(_Inout_ sys_object&& other) noexcept : m_h(other.m_h)
93 {
94 other.m_h = invalid_handle;
95 }
96
97 sys_object& operator =(_Inout_ sys_object&& other) noexcept
98 {
99 if (this != std::addressof(other)) {
100 if (m_h != invalid_handle)
101 close(m_h);
102 m_h = other.m_h;
103 other.m_h = invalid_handle;
104 }
105 return *this;
106 }
107
108 virtual ~sys_object()
109 {
110 if (m_h != invalid_handle)
111 close(m_h);
112 }
113
117 virtual void close()
118 {
119 if (m_h != invalid_handle) {
120 close(m_h);
121 m_h = invalid_handle;
122 }
123 }
124
128 inline operator bool() const noexcept { return m_h != invalid_handle; }
129
133 inline sys_handle get() const noexcept { return m_h; }
134
135 protected:
139 static void close(sys_handle h)
140 {
141#ifdef _WIN32
142 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
143#else
144 if (close(h) >= 0 || errno == EBADF)
145#endif
146 return;
147 throw std::runtime_error("failed to close handle");
148 }
149
153 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit)
154 {
155 sys_handle h_new;
156#ifdef _WIN32
157 HANDLE process = GetCurrentProcess();
158 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
159#else
160 UNREFERENCED_PARAMETER(inherit);
161 if ((h_new = dup(h)) >= 0)
162#endif
163 return h_new;
164 throw std::runtime_error("failed to duplicate handle");
165 }
166
167 protected:
168 sys_handle m_h;
169 };
170
171#ifdef _WIN32
172 template <class T>
173 class safearray_accessor
174 {
175 public:
176 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
177 {
178 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
179 if (FAILED(hr))
180 throw std::invalid_argument("SafeArrayAccessData failed");
181 }
182
183 ~safearray_accessor()
184 {
185 SafeArrayUnaccessData(m_sa);
186 }
187
188 T* data() const { return m_data; }
189
190 protected:
191 LPSAFEARRAY m_sa;
192 T* m_data;
193 };
194
198 struct SafeArrayDestroy_delete
199 {
203 void operator()(_In_ LPSAFEARRAY sa) const
204 {
205 SafeArrayDestroy(sa);
206 }
207 };
208
212 struct SysFreeString_delete
213 {
217 void operator()(_In_ BSTR sa) const
218 {
219 SysFreeString(sa);
220 }
221 };
222#endif
223}
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:76
sys_handle get() const noexcept
Returns object handle.
Definition system.hpp:133
virtual void close()
Closes object.
Definition system.hpp:117
static sys_handle duplicate(sys_handle h, bool inherit)
Duplicates given object.
Definition system.hpp:153
static void close(sys_handle h)
Closes object.
Definition system.hpp:139