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