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 sys_char = TCHAR;
50#else
51 using sys_char = char;
52#define _T(x) x
53#endif
54
58 using sys_string = std::basic_string<stdex::sys_char>;
59
64 {
65 public:
66 sys_object(_In_opt_ sys_handle h = invalid_handle) : m_h(h) {}
67
68 sys_object(_In_ const sys_object& other) : m_h(other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle) {}
69
70 sys_object& operator =(_In_ const sys_object& other)
71 {
72 if (this != std::addressof(other)) {
73 if (m_h != invalid_handle)
74 close(m_h);
75 m_h = other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle;
76 }
77 return *this;
78 }
79
80 sys_object(_Inout_ sys_object&& other) noexcept : m_h(other.m_h)
81 {
82 other.m_h = invalid_handle;
83 }
84
85 sys_object& operator =(_Inout_ sys_object&& other) noexcept
86 {
87 if (this != std::addressof(other)) {
88 if (m_h != invalid_handle)
89 close(m_h);
90 m_h = other.m_h;
91 other.m_h = invalid_handle;
92 }
93 return *this;
94 }
95
96 virtual ~sys_object()
97 {
98 if (m_h != invalid_handle)
99 close(m_h);
100 }
101
105 virtual void close()
106 {
107 if (m_h != invalid_handle) {
108 close(m_h);
109 m_h = invalid_handle;
110 }
111 }
112
116 inline operator bool() const noexcept { return m_h != invalid_handle; }
117
121 inline sys_handle get() const noexcept { return m_h; }
122
123 protected:
127 static void close(sys_handle h)
128 {
129#ifdef _WIN32
130 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
131#else
132 if (close(h) >= 0 || errno == EBADF)
133#endif
134 return;
135 throw std::runtime_error("failed to close handle");
136 }
137
141 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit)
142 {
143 sys_handle h_new;
144#ifdef _WIN32
145 HANDLE process = GetCurrentProcess();
146 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
147#else
148 UNREFERENCED_PARAMETER(inherit);
149 if ((h_new = dup(h)) >= 0)
150#endif
151 return h_new;
152 throw std::runtime_error("failed to duplicate handle");
153 }
154
155 protected:
156 sys_handle m_h;
157 };
158
159#ifdef _WIN32
160 template <class T>
161 class safearray_accessor
162 {
163 public:
164 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
165 {
166 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
167 if (FAILED(hr))
168 throw std::invalid_argument("SafeArrayAccessData failed");
169 }
170
171 ~safearray_accessor()
172 {
173 SafeArrayUnaccessData(m_sa);
174 }
175
176 T* data() const { return m_data; }
177
178 protected:
179 LPSAFEARRAY m_sa;
180 T* m_data;
181 };
182
186 struct SafeArrayDestroy_delete
187 {
191 void operator()(_In_ LPSAFEARRAY sa) const
192 {
193 SafeArrayDestroy(sa);
194 }
195 };
196
200 struct SysFreeString_delete
201 {
205 void operator()(_In_ BSTR sa) const
206 {
207 SysFreeString(sa);
208 }
209 };
210#endif
211}
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:64
sys_handle get() const noexcept
Returns object handle.
Definition system.hpp:121
virtual void close()
Closes object.
Definition system.hpp:105
static sys_handle duplicate(sys_handle h, bool inherit)
Duplicates given object.
Definition system.hpp:141
static void close(sys_handle h)
Closes object.
Definition system.hpp:127