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#include <string>
20
21// In case somebody #included <windows.h> before us and didn't #define NOMINMAX
22#ifdef _WIN32
23#ifdef min
24#undef min
25#endif
26#ifdef max
27#undef max
28#endif
29#endif
30
31namespace stdex
32{
36#if defined(_WIN32)
37 using sys_handle = HANDLE;
38 const sys_handle invalid_handle = INVALID_HANDLE_VALUE;
39#else
40 using sys_handle = int;
41 const sys_handle invalid_handle = (sys_handle)-1;
42#endif
43
47#if defined(_WIN32)
48 using sys_char = TCHAR;
49#else
50 using sys_char = char;
51#define _T(x) x
52#endif
53
57 using sys_string = std::basic_string<stdex::sys_char>;
58
63 {
64 public:
65 sys_object(_In_opt_ sys_handle h = invalid_handle) : m_h(h) {}
66
67 sys_object(_In_ const sys_object& other) : m_h(other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle) {}
68
69 sys_object& operator =(_In_ const sys_object& other)
70 {
71 if (this != std::addressof(other)) {
72 if (m_h != invalid_handle)
73 close(m_h);
74 m_h = other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle;
75 }
76 return *this;
77 }
78
79 sys_object(_Inout_ sys_object&& other) noexcept : m_h(other.m_h)
80 {
81 other.m_h = invalid_handle;
82 }
83
84 sys_object& operator =(_Inout_ sys_object&& other) noexcept
85 {
86 if (this != std::addressof(other)) {
87 if (m_h != invalid_handle)
88 close(m_h);
89 m_h = other.m_h;
90 other.m_h = invalid_handle;
91 }
92 return *this;
93 }
94
95 virtual ~sys_object()
96 {
97 if (m_h != invalid_handle)
98 close(m_h);
99 }
100
104 virtual void close()
105 {
106 if (m_h != invalid_handle) {
107 close(m_h);
108 m_h = invalid_handle;
109 }
110 }
111
115 inline operator bool() const noexcept { return m_h != invalid_handle; }
116
120 inline sys_handle get() const noexcept { return m_h; }
121
122 protected:
126 static void close(sys_handle h)
127 {
128#ifdef _WIN32
129 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
130#else
131 if (close(h) >= 0 || errno == EBADF)
132#endif
133 return;
134 throw std::runtime_error("failed to close handle");
135 }
136
140 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit)
141 {
142 sys_handle h_new;
143#ifdef _WIN32
144 HANDLE process = GetCurrentProcess();
145 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
146#else
147 UNREFERENCED_PARAMETER(inherit);
148 if ((h_new = dup(h)) >= 0)
149#endif
150 return h_new;
151 throw std::runtime_error("failed to duplicate handle");
152 }
153
154 protected:
155 sys_handle m_h;
156 };
157
158#ifdef _WIN32
159 template <class T>
160 class safearray_accessor
161 {
162 public:
163 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
164 {
165 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
166 if (FAILED(hr))
167 throw std::invalid_argument("SafeArrayAccessData failed");
168 }
169
170 ~safearray_accessor()
171 {
172 SafeArrayUnaccessData(m_sa);
173 }
174
175 T* data() const { return m_data; }
176
177 protected:
178 LPSAFEARRAY m_sa;
179 T* m_data;
180 };
181
185 struct SafeArrayDestroy_delete
186 {
190 void operator()(_In_ LPSAFEARRAY sa) const
191 {
192 SafeArrayDestroy(sa);
193 }
194 };
195
199 struct SysFreeString_delete
200 {
204 void operator()(_In_ BSTR sa) const
205 {
206 SysFreeString(sa);
207 }
208 };
209#endif
210}
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:63
sys_handle get() const noexcept
Returns object handle.
Definition system.hpp:120
virtual void close()
Closes object.
Definition system.hpp:104
static sys_handle duplicate(sys_handle h, bool inherit)
Duplicates given object.
Definition system.hpp:140
static void close(sys_handle h)
Closes object.
Definition system.hpp:126