1 // Copyright (c) 2018 Klemens D. Morgenstern
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef BOOST_PROCESS_DETAIL_WINDOWS_HANDLE_WORKAROUND_HPP_
7 #define BOOST_PROCESS_DETAIL_WINDOWS_HANDLE_WORKAROUND_HPP_
8
9 #include <boost/winapi/basic_types.hpp>
10 #include <boost/winapi/dll.hpp>
11 #include <boost/winapi/access_rights.hpp>
12 //#define BOOST_USE_WINDOWS_H 1
13
14 #if defined( BOOST_USE_WINDOWS_H )
15 #include <Winternl.h>
16 #endif
17
18
19 namespace boost { namespace process { namespace detail { namespace windows { namespace workaround
20 {
21
22
23 typedef struct _SYSTEM_HANDLE_ENTRY_
24 {
25 ::boost::winapi::ULONG_ OwnerPid;
26 ::boost::winapi::BYTE_ ObjectType;
27 ::boost::winapi::BYTE_ HandleFlags;
28 ::boost::winapi::USHORT_ HandleValue;
29 ::boost::winapi::PVOID_ ObjectPointer;
30 ::boost::winapi::ULONG_ AccessMask;
31 } SYSTEM_HANDLE_ENTRY_, *PSYSTEM_HANDLE_ENTRY_;
32
33 typedef struct _SYSTEM_HANDLE_INFORMATION_
34 {
35 ::boost::winapi::ULONG_ Count;
36 SYSTEM_HANDLE_ENTRY_ Handle[1];
37 } SYSTEM_HANDLE_INFORMATION_, *PSYSTEM_HANDLE_INFORMATION_;
38
39 #if defined( BOOST_USE_WINDOWS_H )
40
41 using UNICODE_STRING_ = ::UNICODE_STRING;
42 using GENERIC_MAPPING_ = ::GENERIC_MAPPING;
43 using OBJECT_INFORMATION_CLASS_ = ::OBJECT_INFORMATION_CLASS;
44
45 constexpr static OBJECT_INFORMATION_CLASS_ ObjectTypeInformation = ::OBJECT_INFORMATION_CLASS::ObjectTypeInformation;
46
47 typedef struct _OBJECT_TYPE_INFORMATION_ {
48 UNICODE_STRING TypeName;
49 ULONG TotalNumberOfObjects;
50 ULONG TotalNumberOfHandles;
51 ULONG TotalPagedPoolUsage;
52 ULONG TotalNonPagedPoolUsage;
53 ULONG TotalNamePoolUsage;
54 ULONG TotalHandleTableUsage;
55 ULONG HighWaterNumberOfObjects;
56 ULONG HighWaterNumberOfHandles;
57 ULONG HighWaterPagedPoolUsage;
58 ULONG HighWaterNonPagedPoolUsage;
59 ULONG HighWaterNamePoolUsage;
60 ULONG HighWaterHandleTableUsage;
61 ULONG InvalidAttributes;
62 GENERIC_MAPPING GenericMapping;
63 ULONG ValidAccessMask;
64 BOOLEAN SecurityRequired;
65 BOOLEAN MaintainHandleCount;
66 UCHAR TypeIndex;
67 CHAR ReservedByte;
68 ULONG PoolType;
69 ULONG DefaultPagedPoolCharge;
70 ULONG DefaultNonPagedPoolCharge;
71 } OBJECT_TYPE_INFORMATION_, *POBJECT_TYPE_INFORMATION_;
72
73 #else
74
75 typedef enum _OBJECT_INFORMATION_CLASS_
76 {
77 ObjectBasicInformation,
78 ObjectNameInformation,
79 ObjectTypeInformation,
80 ObjectAllInformation,
81 ObjectDataInformation
82 } OBJECT_INFORMATION_CLASS_, *POBJECT_INFORMATION_CLASS_;
83
84 typedef struct _UNICODE_STRING_ {
85 ::boost::winapi::USHORT_ Length;
86 ::boost::winapi::USHORT_ MaximumLength;
87 ::boost::winapi::LPWSTR_ Buffer;
88 } UNICODE_STRING_, *PUNICODE_STRING_;
89
90 typedef struct _GENERIC_MAPPING_ {
91 ::boost::winapi::ACCESS_MASK_ GenericRead;
92 ::boost::winapi::ACCESS_MASK_ GenericWrite;
93 ::boost::winapi::ACCESS_MASK_ GenericExecute;
94 ::boost::winapi::ACCESS_MASK_ GenericAll;
95 } GENERIC_MAPPING_;
96
97 #endif
98
99 typedef struct _OBJECT_BASIC_INFORMATION {
100 ::boost::winapi::ULONG_ Attributes;
101 ::boost::winapi::ACCESS_MASK_ GrantedAccess;
102 ::boost::winapi::ULONG_ HandleCount;
103 ::boost::winapi::ULONG_ PointerCount;
104 ::boost::winapi::ULONG_ PagedPoolUsage;
105 ::boost::winapi::ULONG_ NonPagedPoolUsage;
106 ::boost::winapi::ULONG_ Reserved[3];
107 ::boost::winapi::ULONG_ NameInformationLength;
108 ::boost::winapi::ULONG_ TypeInformationLength;
109 ::boost::winapi::ULONG_ SecurityDescriptorLength;
110 ::boost::winapi::LARGE_INTEGER_ CreateTime;
111 } OBJECT_BASIC_INFORMATION_, *POBJECT_BASIC_INFORMATION_;
112
113 typedef struct _OBJECT_NAME_INFORMATION {
114 UNICODE_STRING_ Name;
115 } OBJECT_NAME_INFORMATION_, *POBJECT_NAME_INFORMATION_;
116
117
118 #if defined( BOOST_USE_WINDOWS_H )
119
120 extern "C"
121 {
122
123 using SYSTEM_INFORMATION_CLASS_ = ::SYSTEM_INFORMATION_CLASS;
124 constexpr static SYSTEM_INFORMATION_CLASS_ SystemHandleInformation_ = static_cast<SYSTEM_INFORMATION_CLASS_>(16);
125
nt_system_query_information(SYSTEM_INFORMATION_CLASS SystemInformationClass,void * SystemInformation,::boost::winapi::ULONG_ SystemInformationLength,::boost::winapi::PULONG_ ReturnLength)126 inline ::boost::winapi::NTSTATUS_ nt_system_query_information(
127 SYSTEM_INFORMATION_CLASS SystemInformationClass,
128 void * SystemInformation,
129 ::boost::winapi::ULONG_ SystemInformationLength,
130 ::boost::winapi::PULONG_ ReturnLength)
131 {
132 return ::NtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
133 }
134
nt_query_object(::boost::winapi::HANDLE_ Handle,OBJECT_INFORMATION_CLASS_ ObjectInformationClass,::boost::winapi::PVOID_ ObjectInformation,::boost::winapi::ULONG_ ObjectInformationLength,::boost::winapi::PULONG_ ReturnLength)135 inline ::boost::winapi::NTSTATUS_ nt_query_object(
136 ::boost::winapi::HANDLE_ Handle,
137 OBJECT_INFORMATION_CLASS_ ObjectInformationClass,
138 ::boost::winapi::PVOID_ ObjectInformation,
139 ::boost::winapi::ULONG_ ObjectInformationLength,
140 ::boost::winapi::PULONG_ ReturnLength
141 )
142 {
143 return ::NtQueryObject(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength);
144 }
145
146 }
147
148 #else
149
150 //this import workaround is to keep it a header-only library. and enums cannot be imported from the winapi.
151
152 extern "C"
153 {
154
155 typedef enum _SYSTEM_INFORMATION_CLASS_
156 {
157 SystemBasicInformation_ = 0,
158 SystemProcessorInformation_ = 1,
159 SystemPerformanceInformation_ = 2,
160 SystemTimeOfDayInformation_ = 3,
161 SystemProcessInformation_ = 5,
162 SystemProcessorPerformanceInformation_ = 8,
163 SystemHandleInformation_ = 16,
164 SystemPagefileInformation_ = 18,
165 SystemInterruptInformation_ = 23,
166 SystemExceptionInformation_ = 33,
167 SystemRegistryQuotaInformation_ = 37,
168 SystemLookasideInformation_ = 45
169 } SYSTEM_INFORMATION_CLASS_;
170
171
172 typedef struct _OBJECT_TYPE_INFORMATION_ {
173 UNICODE_STRING_ TypeName;
174 ::boost::winapi::ULONG_ TotalNumberOfObjects;
175 ::boost::winapi::ULONG_ TotalNumberOfHandles;
176 ::boost::winapi::ULONG_ TotalPagedPoolUsage;
177 ::boost::winapi::ULONG_ TotalNonPagedPoolUsage;
178 ::boost::winapi::ULONG_ TotalNamePoolUsage;
179 ::boost::winapi::ULONG_ TotalHandleTableUsage;
180 ::boost::winapi::ULONG_ HighWaterNumberOfObjects;
181 ::boost::winapi::ULONG_ HighWaterNumberOfHandles;
182 ::boost::winapi::ULONG_ HighWaterPagedPoolUsage;
183 ::boost::winapi::ULONG_ HighWaterNonPagedPoolUsage;
184 ::boost::winapi::ULONG_ HighWaterNamePoolUsage;
185 ::boost::winapi::ULONG_ HighWaterHandleTableUsage;
186 ::boost::winapi::ULONG_ InvalidAttributes;
187 GENERIC_MAPPING_ GenericMapping;
188 ::boost::winapi::ULONG_ ValidAccessMask;
189 ::boost::winapi::BOOLEAN_ SecurityRequired;
190 ::boost::winapi::BOOLEAN_ MaintainHandleCount;
191 ::boost::winapi::UCHAR_ TypeIndex;
192 ::boost::winapi::CHAR_ ReservedByte;
193 ::boost::winapi::ULONG_ PoolType;
194 ::boost::winapi::ULONG_ DefaultPagedPoolCharge;
195 ::boost::winapi::ULONG_ DefaultNonPagedPoolCharge;
196 } OBJECT_TYPE_INFORMATION_, *POBJECT_TYPE_INFORMATION_;
197
198
199
200 /*
201 __kernel_entry NTSTATUS NtQuerySystemInformation(
202 IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
203 OUT PVOID SystemInformation,
204 IN ULONG SystemInformationLength,
205 OUT PULONG ReturnLength
206 );
207 */
208 typedef ::boost::winapi::NTSTATUS_ (__kernel_entry *nt_system_query_information_p )(
209 SYSTEM_INFORMATION_CLASS_,
210 void *,
211 ::boost::winapi::ULONG_,
212 ::boost::winapi::PULONG_);
213 /*
214 __kernel_entry NTSYSCALLAPI NTSTATUS NtQueryObject(
215 HANDLE Handle,
216 OBJECT_INFORMATION_CLASS ObjectInformationClass,
217 PVOID ObjectInformation,
218 ULONG ObjectInformationLength,
219 PULONG ReturnLength
220 );
221 */
222
223 typedef ::boost::winapi::NTSTATUS_ (__kernel_entry *nt_query_object_p )(
224 ::boost::winapi::HANDLE_,
225 OBJECT_INFORMATION_CLASS_,
226 void *,
227 ::boost::winapi::ULONG_,
228 ::boost::winapi::PULONG_);
229
230 }
231
nt_system_query_information(SYSTEM_INFORMATION_CLASS_ SystemInformationClass,void * SystemInformation,::boost::winapi::ULONG_ SystemInformationLength,::boost::winapi::PULONG_ ReturnLength)232 inline ::boost::winapi::NTSTATUS_ nt_system_query_information(
233 SYSTEM_INFORMATION_CLASS_ SystemInformationClass,
234 void *SystemInformation,
235 ::boost::winapi::ULONG_ SystemInformationLength,
236 ::boost::winapi::PULONG_ ReturnLength)
237 {
238 static ::boost::winapi::HMODULE_ h = ::boost::winapi::get_module_handle(L"Ntdll.dll");
239 static nt_system_query_information_p f = reinterpret_cast<nt_system_query_information_p>(::boost::winapi::get_proc_address(h, "NtQuerySystemInformation"));
240
241 return (*f)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
242 }
243
244
nt_query_object(::boost::winapi::HANDLE_ Handle,OBJECT_INFORMATION_CLASS_ ObjectInformationClass,void * ObjectInformation,::boost::winapi::ULONG_ ObjectInformationLength,::boost::winapi::PULONG_ ReturnLength)245 inline ::boost::winapi::BOOL_ nt_query_object(
246 ::boost::winapi::HANDLE_ Handle,
247 OBJECT_INFORMATION_CLASS_ ObjectInformationClass,
248 void *ObjectInformation,
249 ::boost::winapi::ULONG_ ObjectInformationLength,
250 ::boost::winapi::PULONG_ ReturnLength)
251 {
252 static ::boost::winapi::HMODULE_ h = ::boost::winapi::get_module_handle(L"Ntdll.dll");
253 static nt_query_object_p f = reinterpret_cast<nt_query_object_p>(::boost::winapi::get_proc_address(h, "NtQueryObject"));
254
255 return (*f)(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength);
256 }
257
258 #endif
259
260 }}}}}
261
262 #endif /* BOOST_PROCESS_DETAIL_WINDOWS_JOB_WORKAROUND_HPP_ */
263