1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2015. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10
11 #ifndef BOOST_INTERPROCESS_WIN32_API_HPP
12 #define BOOST_INTERPROCESS_WIN32_API_HPP
13
14 #ifndef BOOST_CONFIG_HPP
15 # include <boost/config.hpp>
16 #endif
17 #
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
19 # pragma once
20 #endif
21
22 #include <boost/interprocess/detail/config_begin.hpp>
23 #include <boost/interprocess/detail/workaround.hpp>
24 #include <boost/date_time/filetime_functions.hpp>
25 #include <cstddef>
26 #include <cstring>
27 #include <cstdlib>
28 #include <cstdio>
29
30 #include <boost/assert.hpp>
31 #include <string>
32 #include <vector>
33
34 //#define BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME
35 //#define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
36 //#define BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED
37
38 #ifdef BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME
39 # define BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME_VALUE 1
40 #else
41 # define BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME_VALUE 0
42 #endif
43
44 #ifdef BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
45 # define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED_VALUE 1
46 #else
47 # define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED_VALUE 0
48 #endif
49
50 #ifdef BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED
51 # define BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED_VALUE 1
52 #else
53 # define BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED_VALUE 0
54 #endif
55
56 #define BOOST_INTERPROCESS_BOOTSTAMP_VALUE_SUM \
57 (BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED_VALUE + \
58 BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED_VALUE + \
59 BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME_VALUE)
60
61 #if 1 < BOOST_INTERPROCESS_BOOTSTAMP_VALUE_SUM
62 # error "Only one of BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME, \
63 BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED and \
64 BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED can be defined"
65 #endif
66
67 #if 0 == BOOST_INTERPROCESS_BOOTSTAMP_VALUE_SUM
68 # define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
69 #endif
70
71 #ifdef BOOST_USE_WINDOWS_H
72 #include <windows.h>
73 # if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME)
74 # include <wbemidl.h>
75 # include <objbase.h>
76 # endif
77
78 #include <shlobj.h>
79 #endif
80
81 #if defined(_MSC_VER)
82 # pragma once
83 # pragma comment( lib, "Advapi32.lib" )
84 # pragma comment( lib, "oleaut32.lib" )
85 # pragma comment( lib, "Ole32.lib" )
86 # pragma comment( lib, "Shell32.lib" ) //SHGetFolderPath
87 #endif
88
89 #if defined (BOOST_INTERPROCESS_WINDOWS)
90 # include <cstdarg>
91 # include <boost/detail/interlocked.hpp>
92 #else
93 # error "This file can only be included in Windows OS"
94 #endif
95
96 //////////////////////////////////////////////////////////////////////////////
97 //
98 // Declaration of Windows structures or typedefs if BOOST_USE_WINDOWS_H is used
99 //
100 //////////////////////////////////////////////////////////////////////////////
101
102
103 #if defined(BOOST_GCC)
104 //Ignore -pedantic errors here (anonymous structs, etc.)
105 # if (BOOST_GCC >= 40600)
106 # pragma GCC diagnostic push
107 # if (BOOST_GCC >= 40800)
108 # pragma GCC diagnostic ignored "-Wpedantic"
109 # else
110 # pragma GCC diagnostic ignored "-pedantic"
111 # endif
112 # pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
113 # else
114 # pragma GCC system_header
115 # endif
116 //When loading DLLs we have no option but reinterpret casting function types
117 # if (BOOST_GCC >= 80000)
118 # pragma GCC diagnostic ignored "-Wcast-function-type"
119 # endif
120 #endif
121
122 namespace boost {
123 namespace interprocess {
124 namespace winapi {
125
126 //Own defines
127 static const unsigned long MaxPath = 260;
128
129 #ifndef BOOST_USE_WINDOWS_H
130
131 struct GUID_BIPC
132 {
133 unsigned long Data1;
134 unsigned short Data2;
135 unsigned short Data3;
136 unsigned char Data4[8];
137 };
138
139 #if defined(_MSC_VER)
140 #pragma warning (push)
141 #pragma warning (disable : 4201) // nonstandard extension used
142 #endif
143
144 struct decimal
145 {
146 unsigned short wReserved;
147 union {
148 struct {
149 unsigned char scale;
150 unsigned char sign;
151 };
152 unsigned short signscale;
153 };
154 unsigned long Hi32;
155 union {
156 struct {
157 unsigned long Lo32;
158 unsigned long Mid32;
159 };
160 ::boost::ulong_long_type Lo64;
161 };
162 };
163
164 typedef unsigned short *bstr;
165
166
167 struct wchar_variant
168 {
169 union
170 {
171 struct
172 {
173 unsigned short vt;
174 unsigned short wReserved1;
175 unsigned short wReserved2;
176 unsigned short wReserved3;
177 union
178 {
179 bstr bstrVal;
180 struct
181 {
182 void* pvRecord;
183 void* pRecInfo;
184 };
185 };
186 };
187 decimal decVal;
188 };
189 };
190
191 #if defined(_MSC_VER)
192 #pragma warning (pop)
193 #endif
194
195 struct IUnknown_BIPC
196 {
197 public:
198 virtual long __stdcall QueryInterface(
199 const GUID_BIPC &riid, // [in]
200 void **ppvObject) = 0; // [iid_is][out]
201
202 virtual unsigned long __stdcall AddRef (void) = 0;
203 virtual unsigned long __stdcall Release(void) = 0;
204 };
205
206 struct IWbemClassObject_BIPC : public IUnknown_BIPC
207 {
208 public:
209 virtual long __stdcall GetQualifierSet(
210 /* [out] */ void **ppQualSet) = 0;
211
212 virtual long __stdcall Get(
213 /* [string][in] */ const bstr wszName,
214 /* [in] */ long lFlags,
215 /* [unique][in][out] */ wchar_variant *pVal,
216 /* [unique][in][out] */ long *pType,
217 /* [unique][in][out] */ long *plFlavor) = 0;
218
219 virtual long __stdcall Put(
220 /* [string][in] */ const bstr wszName,
221 /* [in] */ long lFlags,
222 /* [in] */ wchar_variant *pVal,
223 /* [in] */ long Type) = 0;
224
225 virtual long __stdcall Delete(
226 /* [string][in] */ const bstr wszName) = 0;
227
228 virtual long __stdcall GetNames(
229 /* [string][in] */ const bstr wszQualifierName,
230 /* [in] */ long lFlags,
231 /* [in] */ wchar_variant *pQualifierVal,
232 /* [out] */ void * *pNames) = 0;
233
234 virtual long __stdcall BeginEnumeration(
235 /* [in] */ long lEnumFlags) = 0;
236
237 virtual long __stdcall Next(
238 /* [in] */ long lFlags,
239 /* [unique][in][out] */ bstr *strName,
240 /* [unique][in][out] */ wchar_variant *pVal,
241 /* [unique][in][out] */ long *pType,
242 /* [unique][in][out] */ long *plFlavor) = 0;
243
244 virtual long __stdcall EndEnumeration( void) = 0;
245
246 virtual long __stdcall GetPropertyQualifierSet(
247 /* [string][in] */ const bstr wszProperty,
248 /* [out] */ void **ppQualSet) = 0;
249
250 virtual long __stdcall Clone(
251 /* [out] */ IWbemClassObject_BIPC **ppCopy) = 0;
252
253 virtual long __stdcall GetObjectText(
254 /* [in] */ long lFlags,
255 /* [out] */ bstr *pstrObjectText) = 0;
256
257 virtual long __stdcall SpawnDerivedClass(
258 /* [in] */ long lFlags,
259 /* [out] */ IWbemClassObject_BIPC **ppNewClass) = 0;
260
261 virtual long __stdcall SpawnInstance(
262 /* [in] */ long lFlags,
263 /* [out] */ IWbemClassObject_BIPC **ppNewInstance) = 0;
264
265 virtual long __stdcall CompareTo(
266 /* [in] */ long lFlags,
267 /* [in] */ IWbemClassObject_BIPC *pCompareTo) = 0;
268
269 virtual long __stdcall GetPropertyOrigin(
270 /* [string][in] */ const bstr wszName,
271 /* [out] */ bstr *pstrClassName) = 0;
272
273 virtual long __stdcall InheritsFrom(
274 /* [in] */ const bstr strAncestor) = 0;
275
276 virtual long __stdcall GetMethod(
277 /* [string][in] */ const bstr wszName,
278 /* [in] */ long lFlags,
279 /* [out] */ IWbemClassObject_BIPC **ppInSignature,
280 /* [out] */ IWbemClassObject_BIPC **ppOutSignature) = 0;
281
282 virtual long __stdcall PutMethod(
283 /* [string][in] */ const bstr wszName,
284 /* [in] */ long lFlags,
285 /* [in] */ IWbemClassObject_BIPC *pInSignature,
286 /* [in] */ IWbemClassObject_BIPC *pOutSignature) = 0;
287
288 virtual long __stdcall DeleteMethod(
289 /* [string][in] */ const bstr wszName) = 0;
290
291 virtual long __stdcall BeginMethodEnumeration(
292 /* [in] */ long lEnumFlags) = 0;
293
294 virtual long __stdcall NextMethod(
295 /* [in] */ long lFlags,
296 /* [unique][in][out] */ bstr *pstrName,
297 /* [unique][in][out] */ IWbemClassObject_BIPC **ppInSignature,
298 /* [unique][in][out] */ IWbemClassObject_BIPC **ppOutSignature) = 0;
299
300 virtual long __stdcall EndMethodEnumeration( void) = 0;
301
302 virtual long __stdcall GetMethodQualifierSet(
303 /* [string][in] */ const bstr wszMethod,
304 /* [out] */ void **ppQualSet) = 0;
305
306 virtual long __stdcall GetMethodOrigin(
307 /* [string][in] */ const bstr wszMethodName,
308 /* [out] */ bstr *pstrClassName) = 0;
309
310 };
311
312 struct IWbemContext_BIPC : public IUnknown_BIPC
313 {
314 public:
315 virtual long __stdcall Clone(
316 /* [out] */ IWbemContext_BIPC **ppNewCopy) = 0;
317
318 virtual long __stdcall GetNames(
319 /* [in] */ long lFlags,
320 /* [out] */ void * *pNames) = 0;
321
322 virtual long __stdcall BeginEnumeration(
323 /* [in] */ long lFlags) = 0;
324
325 virtual long __stdcall Next(
326 /* [in] */ long lFlags,
327 /* [out] */ bstr *pstrName,
328 /* [out] */ wchar_variant *pValue) = 0;
329
330 virtual long __stdcall EndEnumeration( void) = 0;
331
332 virtual long __stdcall SetValue(
333 /* [string][in] */ const bstr wszName,
334 /* [in] */ long lFlags,
335 /* [in] */ wchar_variant *pValue) = 0;
336
337 virtual long __stdcall GetValue(
338 /* [string][in] */ const bstr wszName,
339 /* [in] */ long lFlags,
340 /* [out] */ wchar_variant *pValue) = 0;
341
342 virtual long __stdcall DeleteValue(
343 /* [string][in] */ const bstr wszName,
344 /* [in] */ long lFlags) = 0;
345
346 virtual long __stdcall DeleteAll( void) = 0;
347
348 };
349
350
351 struct IEnumWbemClassObject_BIPC : public IUnknown_BIPC
352 {
353 public:
354 virtual long __stdcall Reset( void) = 0;
355
356 virtual long __stdcall Next(
357 /* [in] */ long lTimeout,
358 /* [in] */ unsigned long uCount,
359 /* [length_is][size_is][out] */ IWbemClassObject_BIPC **apObjects,
360 /* [out] */ unsigned long *puReturned) = 0;
361
362 virtual long __stdcall NextAsync(
363 /* [in] */ unsigned long uCount,
364 /* [in] */ void *pSink) = 0;
365
366 virtual long __stdcall Clone(
367 /* [out] */ void **ppEnum) = 0;
368
369 virtual long __stdcall Skip(
370 /* [in] */ long lTimeout,
371 /* [in] */ unsigned long nCount) = 0;
372
373 };
374
375 struct IWbemServices_BIPC : public IUnknown_BIPC
376 {
377 public:
378 virtual long __stdcall OpenNamespace(
379 /* [in] */ const bstr strNamespace,
380 /* [in] */ long lFlags,
381 /* [in] */ void *pCtx,
382 /* [unique][in][out] */ void **ppWorkingNamespace,
383 /* [unique][in][out] */ void **ppResult) = 0;
384
385 virtual long __stdcall CancelAsyncCall(
386 /* [in] */ void *pSink) = 0;
387
388 virtual long __stdcall QueryObjectSink(
389 /* [in] */ long lFlags,
390 /* [out] */ void **ppResponseHandler) = 0;
391
392 virtual long __stdcall GetObject(
393 /* [in] */ const bstr strObjectPath,
394 /* [in] */ long lFlags,
395 /* [in] */ void *pCtx,
396 /* [unique][in][out] */ void **ppObject,
397 /* [unique][in][out] */ void **ppCallResult) = 0;
398
399 virtual long __stdcall GetObjectAsync(
400 /* [in] */ const bstr strObjectPath,
401 /* [in] */ long lFlags,
402 /* [in] */ void *pCtx,
403 /* [in] */ void *pResponseHandler) = 0;
404
405 virtual long __stdcall PutClass(
406 /* [in] */ IWbemClassObject_BIPC *pObject,
407 /* [in] */ long lFlags,
408 /* [in] */ void *pCtx,
409 /* [unique][in][out] */ void **ppCallResult) = 0;
410
411 virtual long __stdcall PutClassAsync(
412 /* [in] */ IWbemClassObject_BIPC *pObject,
413 /* [in] */ long lFlags,
414 /* [in] */ void *pCtx,
415 /* [in] */ void *pResponseHandler) = 0;
416
417 virtual long __stdcall DeleteClass(
418 /* [in] */ const bstr strClass,
419 /* [in] */ long lFlags,
420 /* [in] */ void *pCtx,
421 /* [unique][in][out] */ void **ppCallResult) = 0;
422
423 virtual long __stdcall DeleteClassAsync(
424 /* [in] */ const bstr strClass,
425 /* [in] */ long lFlags,
426 /* [in] */ void *pCtx,
427 /* [in] */ void *pResponseHandler) = 0;
428
429 virtual long __stdcall CreateClassEnum(
430 /* [in] */ const bstr strSuperclass,
431 /* [in] */ long lFlags,
432 /* [in] */ void *pCtx,
433 /* [out] */ void **ppEnum) = 0;
434
435 virtual long __stdcall CreateClassEnumAsync(
436 /* [in] */ const bstr strSuperclass,
437 /* [in] */ long lFlags,
438 /* [in] */ void *pCtx,
439 /* [in] */ void *pResponseHandler) = 0;
440
441 virtual long __stdcall PutInstance(
442 /* [in] */ void *pInst,
443 /* [in] */ long lFlags,
444 /* [in] */ void *pCtx,
445 /* [unique][in][out] */ void **ppCallResult) = 0;
446
447 virtual long __stdcall PutInstanceAsync(
448 /* [in] */ void *pInst,
449 /* [in] */ long lFlags,
450 /* [in] */ void *pCtx,
451 /* [in] */ void *pResponseHandler) = 0;
452
453 virtual long __stdcall DeleteInstance(
454 /* [in] */ const bstr strObjectPath,
455 /* [in] */ long lFlags,
456 /* [in] */ void *pCtx,
457 /* [unique][in][out] */ void **ppCallResult) = 0;
458
459 virtual long __stdcall DeleteInstanceAsync(
460 /* [in] */ const bstr strObjectPath,
461 /* [in] */ long lFlags,
462 /* [in] */ void *pCtx,
463 /* [in] */ void *pResponseHandler) = 0;
464
465 virtual long __stdcall CreateInstanceEnum(
466 /* [in] */ const bstr strFilter,
467 /* [in] */ long lFlags,
468 /* [in] */ void *pCtx,
469 /* [out] */ void **ppEnum) = 0;
470
471 virtual long __stdcall CreateInstanceEnumAsync(
472 /* [in] */ const bstr strFilter,
473 /* [in] */ long lFlags,
474 /* [in] */ void *pCtx,
475 /* [in] */ void *pResponseHandler) = 0;
476
477 virtual long __stdcall ExecQuery(
478 /* [in] */ const bstr strQueryLanguage,
479 /* [in] */ const bstr strQuery,
480 /* [in] */ long lFlags,
481 /* [in] */ IWbemContext_BIPC *pCtx,
482 /* [out] */ IEnumWbemClassObject_BIPC **ppEnum) = 0;
483
484 virtual long __stdcall ExecQueryAsync(
485 /* [in] */ const bstr strQueryLanguage,
486 /* [in] */ const bstr strQuery,
487 /* [in] */ long lFlags,
488 /* [in] */ IWbemContext_BIPC *pCtx,
489 /* [in] */ void *pResponseHandler) = 0;
490
491 virtual long __stdcall ExecNotificationQuery(
492 /* [in] */ const bstr strQueryLanguage,
493 /* [in] */ const bstr strQuery,
494 /* [in] */ long lFlags,
495 /* [in] */ IWbemContext_BIPC *pCtx,
496 /* [out] */ void **ppEnum) = 0;
497
498 virtual long __stdcall ExecNotificationQueryAsync(
499 /* [in] */ const bstr strQueryLanguage,
500 /* [in] */ const bstr strQuery,
501 /* [in] */ long lFlags,
502 /* [in] */ IWbemContext_BIPC *pCtx,
503 /* [in] */ void *pResponseHandler) = 0;
504
505 virtual long __stdcall ExecMethod(
506 /* [in] */ const bstr strObjectPath,
507 /* [in] */ const bstr strMethodName,
508 /* [in] */ long lFlags,
509 /* [in] */ IWbemContext_BIPC *pCtx,
510 /* [in] */ IWbemClassObject_BIPC *pInParams,
511 /* [unique][in][out] */ IWbemClassObject_BIPC **ppOutParams,
512 /* [unique][in][out] */ void **ppCallResult) = 0;
513
514 virtual long __stdcall ExecMethodAsync(
515 /* [in] */ const bstr strObjectPath,
516 /* [in] */ const bstr strMethodName,
517 /* [in] */ long lFlags,
518 /* [in] */ IWbemContext_BIPC *pCtx,
519 /* [in] */ IWbemClassObject_BIPC *pInParams,
520 /* [in] */ void *pResponseHandler) = 0;
521
522 };
523
524 struct IWbemLocator_BIPC : public IUnknown_BIPC
525 {
526 public:
527 virtual long __stdcall ConnectServer(
528 /* [in] */ const bstr strNetworkResource,
529 /* [in] */ const bstr strUser,
530 /* [in] */ const bstr strPassword,
531 /* [in] */ const bstr strLocale,
532 /* [in] */ long lSecurityFlags,
533 /* [in] */ const bstr strAuthority,
534 /* [in] */ void *pCtx,
535 /* [out] */ IWbemServices_BIPC **ppNamespace) = 0;
536
537 };
538
539 struct interprocess_overlapped
540 {
541 unsigned long *internal;
542 unsigned long *internal_high;
543 union {
544 struct {
545 unsigned long offset;
546 unsigned long offset_high;
547 }dummy;
548 void *pointer;
549 };
550
551 void *h_event;
552 };
553
554
555 struct interprocess_filetime
556 {
557 unsigned long dwLowDateTime;
558 unsigned long dwHighDateTime;
559 };
560
561 struct win32_find_data
562 {
563 unsigned long dwFileAttributes;
564 interprocess_filetime ftCreationTime;
565 interprocess_filetime ftLastAccessTime;
566 interprocess_filetime ftLastWriteTime;
567 unsigned long nFileSizeHigh;
568 unsigned long nFileSizeLow;
569 unsigned long dwReserved0;
570 unsigned long dwReserved1;
571 char cFileName[MaxPath];
572 char cAlternateFileName[14];
573 };
574
575 struct interprocess_security_attributes
576 {
577 unsigned long nLength;
578 void *lpSecurityDescriptor;
579 int bInheritHandle;
580 };
581
582 struct system_info {
583 union {
584 unsigned long dwOemId; // Obsolete field...do not use
585 struct {
586 unsigned short wProcessorArchitecture;
587 unsigned short wReserved;
588 } dummy;
589 };
590 unsigned long dwPageSize;
591 void * lpMinimumApplicationAddress;
592 void * lpMaximumApplicationAddress;
593 unsigned long * dwActiveProcessorMask;
594 unsigned long dwNumberOfProcessors;
595 unsigned long dwProcessorType;
596 unsigned long dwAllocationGranularity;
597 unsigned short wProcessorLevel;
598 unsigned short wProcessorRevision;
599 };
600
601 struct interprocess_acl
602 {
603 unsigned char AclRevision;
604 unsigned char Sbz1;
605 unsigned short AclSize;
606 unsigned short AceCount;
607 unsigned short Sbz2;
608 };
609
610 struct interprocess_security_descriptor
611 {
612 unsigned char Revision;
613 unsigned char Sbz1;
614 unsigned short Control;
615 void *Owner;
616 void *Group;
617 interprocess_acl *Sacl;
618 interprocess_acl *Dacl;
619 };
620
621 struct interprocess_by_handle_file_information
622 {
623 unsigned long dwFileAttributes;
624 interprocess_filetime ftCreationTime;
625 interprocess_filetime ftLastAccessTime;
626 interprocess_filetime ftLastWriteTime;
627 unsigned long dwVolumeSerialNumber;
628 unsigned long nFileSizeHigh;
629 unsigned long nFileSizeLow;
630 unsigned long nNumberOfLinks;
631 unsigned long nFileIndexHigh;
632 unsigned long nFileIndexLow;
633 };
634
635 struct interprocess_eventlogrecord
636 {
637 unsigned long Length; // Length of full record
638 unsigned long Reserved; // Used by the service
639 unsigned long RecordNumber; // Absolute record number
640 unsigned long TimeGenerated; // Seconds since 1-1-1970
641 unsigned long TimeWritten; // Seconds since 1-1-1970
642 unsigned long EventID;
643 unsigned short EventType;
644 unsigned short NumStrings;
645 unsigned short EventCategory;
646 unsigned short ReservedFlags; // For use with paired events (auditing)
647 unsigned long ClosingRecordNumber; // For use with paired events (auditing)
648 unsigned long StringOffset; // Offset from beginning of record
649 unsigned long UserSidLength;
650 unsigned long UserSidOffset;
651 unsigned long DataLength;
652 unsigned long DataOffset; // Offset from beginning of record
653 //
654 // Then follow:
655 //
656 // wchar_t SourceName[]
657 // wchar_t Computername[]
658 // SID UserSid
659 // wchar_t Strings[]
660 // BYTE Data[]
661 // CHAR Pad[]
662 // unsigned long Length;
663 //
664 };
665
666 union large_integer
667 {
668 __int64 QuadPart;
669 };
670
671 struct hinstance_struct { int unused; };
672 typedef hinstance_struct *hmodule;
673
674 struct hkey_struct;
675 typedef hkey_struct *hkey;
676
677 #ifdef _WIN64
678 typedef __int64 (__stdcall *farproc_t)();
679 #else
680 typedef int (__stdcall *farproc_t)();
681 #endif // _WIN64
682
683 #else //#ifndef BOOST_USE_WINDOWS_H
684
685 typedef GUID GUID_BIPC;
686 typedef VARIANT wchar_variant;
687
688 #if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME)
689
690 typedef IUnknown IUnknown_BIPC;
691
692 typedef IWbemClassObject IWbemClassObject_BIPC;
693
694 typedef IWbemContext IWbemContext_BIPC;
695
696 typedef IEnumWbemClassObject IEnumWbemClassObject_BIPC;
697
698 typedef IWbemServices IWbemServices_BIPC;
699
700 typedef IWbemLocator IWbemLocator_BIPC;
701
702 #endif
703
704 typedef OVERLAPPED interprocess_overlapped;
705
706 typedef FILETIME interprocess_filetime;
707
708 typedef WIN32_FIND_DATAA win32_find_data;
709
710 typedef SECURITY_ATTRIBUTES interprocess_security_attributes;
711
712 typedef SYSTEM_INFO system_info;
713
714 typedef ACL interprocess_acl;
715
716 typedef SECURITY_DESCRIPTOR interprocess_security_descriptor;
717
718 typedef BY_HANDLE_FILE_INFORMATION interprocess_by_handle_file_information;
719
720 typedef EVENTLOGRECORD interprocess_eventlogrecord;
721
722 typedef LARGE_INTEGER large_integer;
723
724 typedef HMODULE hmodule;
725
726 typedef HKEY hkey;
727
728 typedef BSTR bstr;
729
730 typedef FARPROC farproc_t;
731
732 #endif //#ifndef BOOST_USE_WINDOWS_H
733
734 //////////////////////////////////////////////////////////////////////////////
735 //
736 // Nt native structures
737 //
738 //////////////////////////////////////////////////////////////////////////////
739
740 struct interprocess_semaphore_basic_information
741 {
742 unsigned int count; // current semaphore count
743 unsigned int limit; // max semaphore count
744 };
745
746 struct interprocess_section_basic_information
747 {
748 void * base_address;
749 unsigned long section_attributes;
750 __int64 section_size;
751 };
752
753 struct file_rename_information_t {
754 int Replace;
755 void *RootDir;
756 unsigned long FileNameLength;
757 wchar_t FileName[1];
758 };
759
760 struct unicode_string_t {
761 unsigned short Length;
762 unsigned short MaximumLength;
763 wchar_t *Buffer;
764 };
765
766 struct object_attributes_t {
767 unsigned long Length;
768 void * RootDirectory;
769 unicode_string_t *ObjectName;
770 unsigned long Attributes;
771 void *SecurityDescriptor;
772 void *SecurityQualityOfService;
773 };
774
775 struct io_status_block_t {
776 union {
777 long Status;
778 void *Pointer;
779 };
780
781 unsigned long *Information;
782 };
783
784 union system_timeofday_information
785 {
786 struct data_t
787 {
788 __int64 liKeBootTime;
789 __int64 liKeSystemTime;
790 __int64 liExpTimeZoneBias;
791 unsigned long uCurrentTimeZoneId;
792 unsigned long dwReserved;
793 ::boost::ulong_long_type ullBootTimeBias;
794 ::boost::ulong_long_type ullSleepTimeBias;
795 } data;
796 unsigned char Reserved1[sizeof(data_t)];
797 };
798
799 static const long BootstampLength = sizeof(__int64);
800 static const long BootAndSystemstampLength = sizeof(__int64)*2;
801 static const long SystemTimeOfDayInfoLength = sizeof(system_timeofday_information::data_t);
802
803 struct object_name_information_t
804 {
805 unicode_string_t Name;
806 wchar_t NameBuffer[1];
807 };
808
809 enum file_information_class_t {
810 file_directory_information = 1,
811 file_full_directory_information,
812 file_both_directory_information,
813 file_basic_information,
814 file_standard_information,
815 file_internal_information,
816 file_ea_information,
817 file_access_information,
818 file_name_information,
819 file_rename_information,
820 file_link_information,
821 file_names_information,
822 file_disposition_information,
823 file_position_information,
824 file_full_ea_information,
825 file_mode_information,
826 file_alignment_information,
827 file_all_information,
828 file_allocation_information,
829 file_end_of_file_information,
830 file_alternate_name_information,
831 file_stream_information,
832 file_pipe_information,
833 file_pipe_local_information,
834 file_pipe_remote_information,
835 file_mailslot_query_information,
836 file_mailslot_set_information,
837 file_compression_information,
838 file_copy_on_write_information,
839 file_completion_information,
840 file_move_cluster_information,
841 file_quota_information,
842 file_reparse_point_information,
843 file_network_open_information,
844 file_object_id_information,
845 file_tracking_information,
846 file_ole_directory_information,
847 file_content_index_information,
848 file_inherit_content_index_information,
849 file_ole_information,
850 file_maximum_information
851 };
852
853 enum semaphore_information_class {
854 semaphore_basic_information = 0
855 };
856
857
858 enum system_information_class {
859 system_basic_information = 0,
860 system_performance_information = 2,
861 system_time_of_day_information = 3,
862 system_process_information = 5,
863 system_processor_performance_information = 8,
864 system_interrupt_information = 23,
865 system_exception_information = 33,
866 system_registry_quota_information = 37,
867 system_lookaside_information = 45
868 };
869
870 enum object_information_class
871 {
872 object_basic_information,
873 object_name_information,
874 object_type_information,
875 object_all_information,
876 object_data_information
877 };
878
879 enum section_information_class
880 {
881 section_basic_information,
882 section_image_information
883 };
884
885 //////////////////////////////////////////////////////////////////////////////
886 //
887 // Forward declaration of winapi
888 //
889 //////////////////////////////////////////////////////////////////////////////
890
891 #ifndef BOOST_USE_WINDOWS_H
892
893 //Kernel32.dll
894
895 //Some windows API declarations
896 extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
897 extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
898 extern "C" __declspec(dllimport) int __stdcall GetProcessTimes
899 ( void *hProcess, interprocess_filetime* lpCreationTime
900 , interprocess_filetime *lpExitTime,interprocess_filetime *lpKernelTime
901 , interprocess_filetime *lpUserTime );
902 extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
903 extern "C" __declspec(dllimport) unsigned long __stdcall GetTickCount(void);
904 extern "C" __declspec(dllimport) int __stdcall SwitchToThread();
905 extern "C" __declspec(dllimport) unsigned long __stdcall GetLastError();
906 extern "C" __declspec(dllimport) void __stdcall SetLastError(unsigned long);
907 extern "C" __declspec(dllimport) void * __stdcall GetCurrentProcess();
908 extern "C" __declspec(dllimport) int __stdcall CloseHandle(void*);
909 extern "C" __declspec(dllimport) int __stdcall DuplicateHandle
910 ( void *hSourceProcessHandle, void *hSourceHandle
911 , void *hTargetProcessHandle, void **lpTargetHandle
912 , unsigned long dwDesiredAccess, int bInheritHandle
913 , unsigned long dwOptions);
914 extern "C" __declspec(dllimport) long __stdcall GetFileType(void *hFile);
915 extern "C" __declspec(dllimport) void *__stdcall FindFirstFileA(const char *lpFileName, win32_find_data *lpFindFileData);
916 extern "C" __declspec(dllimport) int __stdcall FindNextFileA(void *hFindFile, win32_find_data *lpFindFileData);
917 extern "C" __declspec(dllimport) int __stdcall FindClose(void *hFindFile);
918 //extern "C" __declspec(dllimport) void __stdcall GetSystemTimeAsFileTime(interprocess_filetime*);
919 //extern "C" __declspec(dllimport) int __stdcall FileTimeToLocalFileTime(const interprocess_filetime *in, const interprocess_filetime *out);
920 extern "C" __declspec(dllimport) void * __stdcall CreateMutexA(interprocess_security_attributes*, int, const char *);
921 extern "C" __declspec(dllimport) void * __stdcall OpenMutexA(unsigned long, int, const char *);
922 extern "C" __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void *, unsigned long);
923 extern "C" __declspec(dllimport) int __stdcall ReleaseMutex(void *);
924 extern "C" __declspec(dllimport) int __stdcall UnmapViewOfFile(void *);
925 extern "C" __declspec(dllimport) void * __stdcall CreateSemaphoreA(interprocess_security_attributes*, long, long, const char *);
926 extern "C" __declspec(dllimport) int __stdcall ReleaseSemaphore(void *, long, long *);
927 extern "C" __declspec(dllimport) void * __stdcall OpenSemaphoreA(unsigned long, int, const char *);
928 extern "C" __declspec(dllimport) void * __stdcall CreateFileMappingA (void *, interprocess_security_attributes*, unsigned long, unsigned long, unsigned long, const char *);
929 extern "C" __declspec(dllimport) void * __stdcall MapViewOfFileEx (void *, unsigned long, unsigned long, unsigned long, std::size_t, void*);
930 extern "C" __declspec(dllimport) void * __stdcall OpenFileMappingA (unsigned long, int, const char *);
931 extern "C" __declspec(dllimport) void * __stdcall CreateFileA (const char *, unsigned long, unsigned long, struct interprocess_security_attributes*, unsigned long, unsigned long, void *);
932 extern "C" __declspec(dllimport) void __stdcall GetSystemInfo (struct system_info *);
933 extern "C" __declspec(dllimport) int __stdcall FlushViewOfFile (void *, std::size_t);
934 extern "C" __declspec(dllimport) int __stdcall VirtualUnlock (void *, std::size_t);
935 extern "C" __declspec(dllimport) int __stdcall VirtualProtect (void *, std::size_t, unsigned long, unsigned long *);
936 extern "C" __declspec(dllimport) int __stdcall FlushFileBuffers (void *);
937 extern "C" __declspec(dllimport) int __stdcall GetFileSizeEx (void *, large_integer *size);
938 extern "C" __declspec(dllimport) unsigned long __stdcall FormatMessageA
939 (unsigned long dwFlags, const void *lpSource, unsigned long dwMessageId,
940 unsigned long dwLanguageId, char *lpBuffer, unsigned long nSize,
941 std::va_list *Arguments);
942 extern "C" __declspec(dllimport) void *__stdcall LocalFree (void *);
943 extern "C" __declspec(dllimport) unsigned long __stdcall GetFileAttributesA(const char *);
944 extern "C" __declspec(dllimport) int __stdcall CreateDirectoryA(const char *, interprocess_security_attributes*);
945 extern "C" __declspec(dllimport) int __stdcall RemoveDirectoryA(const char *lpPathName);
946 extern "C" __declspec(dllimport) int __stdcall GetTempPathA(unsigned long length, char *buffer);
947 extern "C" __declspec(dllimport) int __stdcall CreateDirectory(const char *, interprocess_security_attributes*);
948 extern "C" __declspec(dllimport) int __stdcall SetFileValidData(void *, __int64 size);
949 extern "C" __declspec(dllimport) int __stdcall SetEndOfFile(void *);
950 extern "C" __declspec(dllimport) int __stdcall SetFilePointerEx(void *, large_integer distance, large_integer *new_file_pointer, unsigned long move_method);
951 extern "C" __declspec(dllimport) int __stdcall LockFile (void *hnd, unsigned long offset_low, unsigned long offset_high, unsigned long size_low, unsigned long size_high);
952 extern "C" __declspec(dllimport) int __stdcall UnlockFile(void *hnd, unsigned long offset_low, unsigned long offset_high, unsigned long size_low, unsigned long size_high);
953 extern "C" __declspec(dllimport) int __stdcall LockFileEx(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
954 extern "C" __declspec(dllimport) int __stdcall UnlockFileEx(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
955 extern "C" __declspec(dllimport) int __stdcall WriteFile(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped);
956 extern "C" __declspec(dllimport) int __stdcall ReadFile(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped);
957 extern "C" __declspec(dllimport) int __stdcall InitializeSecurityDescriptor(interprocess_security_descriptor *pSecurityDescriptor, unsigned long dwRevision);
958 extern "C" __declspec(dllimport) int __stdcall SetSecurityDescriptorDacl(interprocess_security_descriptor *pSecurityDescriptor, int bDaclPresent, interprocess_acl *pDacl, int bDaclDefaulted);
959 extern "C" __declspec(dllimport) hmodule __stdcall LoadLibraryA(const char *);
960 extern "C" __declspec(dllimport) int __stdcall FreeLibrary(hmodule);
961 extern "C" __declspec(dllimport) farproc_t __stdcall GetProcAddress(void *, const char*);
962 extern "C" __declspec(dllimport) hmodule __stdcall GetModuleHandleA(const char*);
963 extern "C" __declspec(dllimport) void *__stdcall GetFileInformationByHandle(void *, interprocess_by_handle_file_information*);
964
965 //Advapi32.dll
966 extern "C" __declspec(dllimport) long __stdcall RegOpenKeyExA(hkey, const char *, unsigned long, unsigned long, hkey*);
967 extern "C" __declspec(dllimport) long __stdcall RegQueryValueExA(hkey, const char *, unsigned long*, unsigned long*, unsigned char *, unsigned long*);
968 extern "C" __declspec(dllimport) long __stdcall RegCloseKey(hkey);
969
970 //Ole32.dll
971 extern "C" __declspec(dllimport) long __stdcall CoInitializeEx(void *pvReserved, unsigned long dwCoInit);
972 extern "C" __declspec(dllimport) long __stdcall CoInitializeSecurity(
973 void* pSecDesc,
974 long cAuthSvc,
975 void * asAuthSvc,
976 void *pReserved1,
977 unsigned long dwAuthnLevel,
978 unsigned long dwImpLevel,
979 void *pAuthList,
980 unsigned long dwCapabilities,
981 void *pReserved3 );
982
983 extern "C" __declspec(dllimport) long __stdcall CoSetProxyBlanket(
984 IUnknown_BIPC *pProxy,
985 unsigned long dwAuthnSvc,
986 unsigned long dwAuthzSvc,
987 wchar_t *pServerPrincName,
988 unsigned long dwAuthnLevel,
989 unsigned long dwImpLevel,
990 void *pAuthInfo,
991 unsigned long dwCapabilities);
992 extern "C" __declspec(dllimport) long __stdcall CoCreateInstance(const GUID_BIPC & rclsid, IUnknown_BIPC *pUnkOuter,
993 unsigned long dwClsContext, const GUID_BIPC & riid, void** ppv);
994 extern "C" __declspec(dllimport) void __stdcall CoUninitialize(void);
995
996 //OleAut32.dll
997 extern "C" __declspec(dllimport) long __stdcall VariantClear(wchar_variant * pvarg);
998
999 //Shell32.dll
1000 extern "C" __declspec(dllimport) int __stdcall SHGetSpecialFolderPathA
1001 (void* hwnd, const char *pszPath, int csidl, int fCreate);
1002
1003 extern "C" __declspec(dllimport) int __stdcall SHGetFolderPathA(void *hwnd, int csidl, void *hToken, unsigned long dwFlags, const char *pszPath);
1004
1005 //EventLog access functions
1006
1007 extern "C" __declspec(dllimport) void* __stdcall OpenEventLogA
1008 (const char* lpUNCServerName, const char* lpSourceName);
1009
1010 extern "C" __declspec(dllimport) int __stdcall CloseEventLog(void *hEventLog);
1011
1012 extern "C" __declspec(dllimport) int __stdcall ReadEventLogA
1013 (void *hEventLog,
1014 unsigned long dwReadFlags,
1015 unsigned long dwRecordOffset,
1016 void *lpBuffer,
1017 unsigned long nNumberOfBytesToRead,
1018 unsigned long *pnBytesRead,
1019 unsigned long *pnMinNumberOfBytesNeeded
1020 );
1021
1022 #endif //#ifndef BOOST_USE_WINDOWS_H
1023
1024 //kernel32.dll
1025 typedef int (__stdcall *QueryPerformanceCounter_t) (__int64 *lpPerformanceCount);
1026 typedef int (__stdcall *QueryPerformanceFrequency_t)(__int64 *lpFrequency);
1027
1028 //ntdll.dll
1029 typedef long (__stdcall *NtDeleteFile_t)(object_attributes_t *ObjectAttributes);
1030 typedef long (__stdcall *NtSetInformationFile_t)(void *FileHandle, io_status_block_t *IoStatusBlock, void *FileInformation, unsigned long Length, int FileInformationClass );
1031 typedef long (__stdcall *NtOpenFile)(void **FileHandle, unsigned long DesiredAccess, object_attributes_t *ObjectAttributes
1032 , io_status_block_t *IoStatusBlock, unsigned long ShareAccess, unsigned long Length, unsigned long OpenOptions);
1033 typedef long (__stdcall *NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
1034 typedef long (__stdcall *NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
1035 typedef long (__stdcall *NtQuerySemaphore_t)(void*, unsigned int info_class, interprocess_semaphore_basic_information *pinfo, unsigned int info_size, unsigned int *ret_len);
1036 typedef long (__stdcall *NtQuerySection_t)(void*, section_information_class, interprocess_section_basic_information *pinfo, unsigned long info_size, unsigned long *ret_len);
1037 typedef long (__stdcall *NtQueryInformationFile_t)(void *,io_status_block_t *,void *, long, int);
1038 typedef long (__stdcall *NtOpenFile_t)(void*,unsigned long ,object_attributes_t*,io_status_block_t*,unsigned long,unsigned long);
1039 typedef long (__stdcall *NtClose_t) (void*);
1040 typedef long (__stdcall *NtQueryTimerResolution_t) (unsigned long* LowestResolution, unsigned long* HighestResolution, unsigned long* CurrentResolution);
1041 typedef long (__stdcall *NtSetTimerResolution_t) (unsigned long RequestedResolution, int Set, unsigned long* ActualResolution);
1042
1043 } //namespace winapi {
1044 } //namespace interprocess {
1045 } //namespace boost {
1046
1047 //////////////////////////////////////////////////////////////////////////////
1048 //
1049 // Forward declaration of constants
1050 //
1051 //////////////////////////////////////////////////////////////////////////////
1052
1053 namespace boost {
1054 namespace interprocess {
1055 namespace winapi {
1056
1057 //Some used constants
1058 static const unsigned long infinite_time = 0xFFFFFFFF;
1059 static const unsigned long error_already_exists = 183L;
1060 static const unsigned long error_invalid_handle = 6L;
1061 static const unsigned long error_sharing_violation = 32L;
1062 static const unsigned long error_file_not_found = 2u;
1063 static const unsigned long error_no_more_files = 18u;
1064 static const unsigned long error_not_locked = 158L;
1065 //Retries in CreateFile, see http://support.microsoft.com/kb/316609
1066 static const unsigned long error_sharing_violation_tries = 3L;
1067 static const unsigned long error_sharing_violation_sleep_ms = 250L;
1068 static const unsigned long error_file_too_large = 223L;
1069 static const unsigned long error_insufficient_buffer = 122L;
1070 static const unsigned long error_handle_eof = 38L;
1071 static const unsigned long semaphore_all_access = (0x000F0000L)|(0x00100000L)|0x3;
1072 static const unsigned long mutex_all_access = (0x000F0000L)|(0x00100000L)|0x0001;
1073
1074 static const unsigned long page_readonly = 0x02;
1075 static const unsigned long page_readwrite = 0x04;
1076 static const unsigned long page_writecopy = 0x08;
1077 static const unsigned long page_noaccess = 0x01;
1078
1079 static const unsigned long standard_rights_required = 0x000F0000L;
1080 static const unsigned long section_query = 0x0001;
1081 static const unsigned long section_map_write = 0x0002;
1082 static const unsigned long section_map_read = 0x0004;
1083 static const unsigned long section_map_execute = 0x0008;
1084 static const unsigned long section_extend_size = 0x0010;
1085 static const unsigned long section_all_access = standard_rights_required |
1086 section_query |
1087 section_map_write |
1088 section_map_read |
1089 section_map_execute |
1090 section_extend_size;
1091
1092 static const unsigned long file_map_copy = section_query;
1093 static const unsigned long file_map_write = section_map_write;
1094 static const unsigned long file_map_read = section_map_read;
1095 static const unsigned long file_map_all_access = section_all_access;
1096 static const unsigned long delete_access = 0x00010000L;
1097 static const unsigned long file_flag_backup_semantics = 0x02000000;
1098 static const long file_flag_delete_on_close = 0x04000000;
1099
1100 //Native API constants
1101 static const unsigned long file_open_for_backup_intent = 0x00004000;
1102 static const int file_share_valid_flags = 0x00000007;
1103 static const long file_delete_on_close = 0x00001000L;
1104 static const long obj_case_insensitive = 0x00000040L;
1105 static const long delete_flag = 0x00010000L;
1106
1107 static const unsigned long movefile_copy_allowed = 0x02;
1108 static const unsigned long movefile_delay_until_reboot = 0x04;
1109 static const unsigned long movefile_replace_existing = 0x01;
1110 static const unsigned long movefile_write_through = 0x08;
1111 static const unsigned long movefile_create_hardlink = 0x10;
1112 static const unsigned long movefile_fail_if_not_trackable = 0x20;
1113
1114 static const unsigned long file_share_read = 0x00000001;
1115 static const unsigned long file_share_write = 0x00000002;
1116 static const unsigned long file_share_delete = 0x00000004;
1117
1118 static const unsigned long file_attribute_readonly = 0x00000001;
1119 static const unsigned long file_attribute_hidden = 0x00000002;
1120 static const unsigned long file_attribute_system = 0x00000004;
1121 static const unsigned long file_attribute_directory = 0x00000010;
1122 static const unsigned long file_attribute_archive = 0x00000020;
1123 static const unsigned long file_attribute_device = 0x00000040;
1124 static const unsigned long file_attribute_normal = 0x00000080;
1125 static const unsigned long file_attribute_temporary = 0x00000100;
1126
1127 static const unsigned long generic_read = 0x80000000L;
1128 static const unsigned long generic_write = 0x40000000L;
1129
1130 static const unsigned long wait_object_0 = 0;
1131 static const unsigned long wait_abandoned = 0x00000080L;
1132 static const unsigned long wait_timeout = 258L;
1133 static const unsigned long wait_failed = (unsigned long)0xFFFFFFFF;
1134
1135 static const unsigned long duplicate_close_source = (unsigned long)0x00000001;
1136 static const unsigned long duplicate_same_access = (unsigned long)0x00000002;
1137
1138 static const unsigned long format_message_allocate_buffer
1139 = (unsigned long)0x00000100;
1140 static const unsigned long format_message_ignore_inserts
1141 = (unsigned long)0x00000200;
1142 static const unsigned long format_message_from_string
1143 = (unsigned long)0x00000400;
1144 static const unsigned long format_message_from_hmodule
1145 = (unsigned long)0x00000800;
1146 static const unsigned long format_message_from_system
1147 = (unsigned long)0x00001000;
1148 static const unsigned long format_message_argument_array
1149 = (unsigned long)0x00002000;
1150 static const unsigned long format_message_max_width_mask
1151 = (unsigned long)0x000000FF;
1152 static const unsigned long lang_neutral = (unsigned long)0x00;
1153 static const unsigned long sublang_default = (unsigned long)0x01;
1154 static const unsigned long invalid_file_size = (unsigned long)0xFFFFFFFF;
1155 static const unsigned long invalid_file_attributes = ((unsigned long)-1);
1156 static void * const invalid_handle_value = ((void*)(long)(-1));
1157
1158 static const unsigned long file_type_char = 0x0002L;
1159 static const unsigned long file_type_disk = 0x0001L;
1160 static const unsigned long file_type_pipe = 0x0003L;
1161 static const unsigned long file_type_remote = 0x8000L;
1162 static const unsigned long file_type_unknown = 0x0000L;
1163
1164 static const unsigned long create_new = 1;
1165 static const unsigned long create_always = 2;
1166 static const unsigned long open_existing = 3;
1167 static const unsigned long open_always = 4;
1168 static const unsigned long truncate_existing = 5;
1169
1170 static const unsigned long file_begin = 0;
1171 static const unsigned long file_current = 1;
1172 static const unsigned long file_end = 2;
1173
1174 static const unsigned long lockfile_fail_immediately = 1;
1175 static const unsigned long lockfile_exclusive_lock = 2;
1176 static const unsigned long error_lock_violation = 33;
1177 static const unsigned long security_descriptor_revision = 1;
1178
1179 const unsigned long max_record_buffer_size = 0x10000L; // 64K
1180 const unsigned long max_path = 260;
1181
1182 //Keys
1183 static const hkey hkey_local_machine = (hkey)(unsigned long*)(long)(0x80000002);
1184 static unsigned long key_query_value = 0x0001;
1185
1186 //COM API
1187 const unsigned long RPC_C_AUTHN_LEVEL_PKT_BIPC = 4;
1188 const unsigned long RPC_C_AUTHN_DEFAULT_BIPC = 0xffffffffL;
1189 const unsigned long RPC_C_AUTHZ_DEFAULT_BIPC = 0xffffffffL;
1190 const unsigned long RPC_C_IMP_LEVEL_IMPERSONATE_BIPC = 3;
1191 const signed long EOAC_NONE_BIPC = 0;
1192 const signed long CLSCTX_INPROC_SERVER_BIPC = 0x1;
1193 const signed long CLSCTX_LOCAL_SERVER_BIPC = 0x4;
1194 const signed long WBEM_FLAG_RETURN_IMMEDIATELY_BIPC = 0x10;
1195 const signed long WBEM_FLAG_RETURN_WHEN_COMPLETE_BIPC = 0x0;
1196 const signed long WBEM_FLAG_FORWARD_ONLY_BIPC = 0x20;
1197 const signed long WBEM_INFINITE_BIPC = 0xffffffffL;
1198 const signed long RPC_E_TOO_LATE_BIPC = 0x80010119L;
1199 const signed long S_OK_BIPC = 0L;
1200 const signed long S_FALSE_BIPC = 1;
1201 const signed long RPC_E_CHANGED_MODE_BIPC = 0x80010106L;
1202 const unsigned long COINIT_APARTMENTTHREADED_BIPC = 0x2;
1203 const unsigned long COINIT_MULTITHREADED_BIPC = 0x0;
1204 const unsigned long COINIT_DISABLE_OLE1DDE_BIPC = 0x4;
1205 const unsigned long COINIT_SPEED_OVER_MEMORY_BIPC = 0x4;
1206
1207 // Registry types
1208 #define reg_none ( 0 ) // No value type
1209 #define reg_sz ( 1 ) // Unicode nul terminated string
1210 #define reg_expand_sz ( 2 ) // Unicode nul terminated string
1211 // (with environment variable references)
1212 #define reg_binary ( 3 ) // Free form binary
1213 #define reg_dword ( 4 ) // 32-bit number
1214 #define reg_dword_little_endian ( 4 ) // 32-bit number (same as REG_DWORD)
1215 #define reg_dword_big_endian ( 5 ) // 32-bit number
1216 #define reg_link ( 6 ) // Symbolic Link (unicode)
1217 #define reg_multi_sz ( 7 ) // Multiple Unicode strings
1218 #define reg_resource_list ( 8 ) // Resource list in the resource map
1219 #define reg_full_resource_descriptor ( 9 ) // Resource list in the hardware description
1220 #define reg_resource_requirements_list ( 10 )
1221 #define reg_qword ( 11 ) // 64-bit number
1222 #define reg_qword_little_endian ( 11 ) // 64-bit number (same as reg_qword)
1223
1224
1225 //If the user needs to change default COM initialization model,
1226 //it can define BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL to one of these:
1227 //
1228 // COINIT_APARTMENTTHREADED_BIPC
1229 // COINIT_MULTITHREADED_BIPC
1230 // COINIT_DISABLE_OLE1DDE_BIPC
1231 // COINIT_SPEED_OVER_MEMORY_BIPC
1232 #if !defined(BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL)
1233 #define BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL COINIT_APARTMENTTHREADED_BIPC
1234 #elif (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_APARTMENTTHREADED_BIPC) &&\
1235 (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_MULTITHREADED_BIPC) &&\
1236 (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_DISABLE_OLE1DDE_BIPC) &&\
1237 (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_SPEED_OVER_MEMORY_BIPC)
1238 #error "Wrong value for BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL macro"
1239 #endif
1240
1241 const GUID_BIPC CLSID_WbemAdministrativeLocator =
1242 { 0xcb8555cc, 0x9128, 0x11d1, {0xad, 0x9b, 0x00, 0xc0, 0x4f, 0xd8, 0xfd, 0xff}};
1243
1244 const GUID_BIPC IID_IUnknown = { 0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
1245
1246 static const unsigned long eventlog_sequential_read = 0x0001;
1247 static const unsigned long eventlog_backwards_read = 0x0008;
1248
1249 } //namespace winapi {
1250 } //namespace interprocess {
1251 } //namespace boost {
1252
1253
1254 namespace boost {
1255 namespace interprocess {
1256 namespace winapi {
1257
get_last_error()1258 inline unsigned long get_last_error()
1259 { return GetLastError(); }
1260
set_last_error(unsigned long err)1261 inline void set_last_error(unsigned long err)
1262 { return SetLastError(err); }
1263
format_message(unsigned long dwFlags,const void * lpSource,unsigned long dwMessageId,unsigned long dwLanguageId,char * lpBuffer,unsigned long nSize,std::va_list * Arguments)1264 inline unsigned long format_message
1265 (unsigned long dwFlags, const void *lpSource,
1266 unsigned long dwMessageId, unsigned long dwLanguageId,
1267 char *lpBuffer, unsigned long nSize, std::va_list *Arguments)
1268 {
1269 return FormatMessageA
1270 (dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments);
1271 }
1272
1273 //And now, wrapper functions
local_free(void * hmem)1274 inline void * local_free(void *hmem)
1275 { return LocalFree(hmem); }
1276
make_lang_id(unsigned long p,unsigned long s)1277 inline unsigned long make_lang_id(unsigned long p, unsigned long s)
1278 { return ((((unsigned short)(s)) << 10) | (unsigned short)(p)); }
1279
sched_yield()1280 inline void sched_yield()
1281 {
1282 if(!SwitchToThread()){
1283 Sleep(0);
1284 }
1285 }
1286
sleep_tick()1287 inline void sleep_tick()
1288 { Sleep(1); }
1289
sleep(unsigned long ms)1290 inline void sleep(unsigned long ms)
1291 { Sleep(ms); }
1292
get_current_thread_id()1293 inline unsigned long get_current_thread_id()
1294 { return GetCurrentThreadId(); }
1295
get_process_times(void * hProcess,interprocess_filetime * lpCreationTime,interprocess_filetime * lpExitTime,interprocess_filetime * lpKernelTime,interprocess_filetime * lpUserTime)1296 inline bool get_process_times
1297 ( void *hProcess, interprocess_filetime* lpCreationTime
1298 , interprocess_filetime *lpExitTime, interprocess_filetime *lpKernelTime
1299 , interprocess_filetime *lpUserTime )
1300 { return 0 != GetProcessTimes(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime); }
1301
get_current_process_id()1302 inline unsigned long get_current_process_id()
1303 { return GetCurrentProcessId(); }
1304
close_handle(void * handle)1305 inline unsigned int close_handle(void* handle)
1306 { return CloseHandle(handle); }
1307
find_first_file(const char * lpFileName,win32_find_data * lpFindFileData)1308 inline void * find_first_file(const char *lpFileName, win32_find_data *lpFindFileData)
1309 { return FindFirstFileA(lpFileName, lpFindFileData); }
1310
find_next_file(void * hFindFile,win32_find_data * lpFindFileData)1311 inline bool find_next_file(void *hFindFile, win32_find_data *lpFindFileData)
1312 { return FindNextFileA(hFindFile, lpFindFileData) != 0; }
1313
find_close(void * handle)1314 inline bool find_close(void *handle)
1315 { return FindClose(handle) != 0; }
1316
duplicate_current_process_handle(void * hSourceHandle,void ** lpTargetHandle)1317 inline bool duplicate_current_process_handle
1318 (void *hSourceHandle, void **lpTargetHandle)
1319 {
1320 return 0 != DuplicateHandle
1321 ( GetCurrentProcess(), hSourceHandle, GetCurrentProcess()
1322 , lpTargetHandle, 0, 0
1323 , duplicate_same_access);
1324 }
1325
get_file_type(void * hFile)1326 inline unsigned long get_file_type(void *hFile)
1327 {
1328 return GetFileType(hFile);
1329 }
1330
1331 /*
1332 inline void get_system_time_as_file_time(interprocess_filetime *filetime)
1333 { GetSystemTimeAsFileTime(filetime); }
1334
1335 inline bool file_time_to_local_file_time
1336 (const interprocess_filetime *in, const interprocess_filetime *out)
1337 { return 0 != FileTimeToLocalFileTime(in, out); }
1338 */
open_or_create_mutex(const char * name,bool initial_owner,interprocess_security_attributes * attr)1339 inline void *open_or_create_mutex(const char *name, bool initial_owner, interprocess_security_attributes *attr)
1340 { return CreateMutexA(attr, (int)initial_owner, name); }
1341
wait_for_single_object(void * handle,unsigned long time)1342 inline unsigned long wait_for_single_object(void *handle, unsigned long time)
1343 { return WaitForSingleObject(handle, time); }
1344
release_mutex(void * handle)1345 inline int release_mutex(void *handle)
1346 { return ReleaseMutex(handle); }
1347
unmap_view_of_file(void * address)1348 inline int unmap_view_of_file(void *address)
1349 { return UnmapViewOfFile(address); }
1350
open_or_create_semaphore(const char * name,long initial_count,long maximum_count,interprocess_security_attributes * attr)1351 inline void *open_or_create_semaphore(const char *name, long initial_count, long maximum_count, interprocess_security_attributes *attr)
1352 { return CreateSemaphoreA(attr, initial_count, maximum_count, name); }
1353
open_semaphore(const char * name)1354 inline void *open_semaphore(const char *name)
1355 { return OpenSemaphoreA(semaphore_all_access, 0, name); }
1356
release_semaphore(void * handle,long release_count,long * prev_count)1357 inline int release_semaphore(void *handle, long release_count, long *prev_count)
1358 { return ReleaseSemaphore(handle, release_count, prev_count); }
1359
1360 class interprocess_all_access_security
1361 {
1362 interprocess_security_attributes sa;
1363 interprocess_security_descriptor sd;
1364 bool initialized;
1365
1366 public:
interprocess_all_access_security()1367 interprocess_all_access_security()
1368 : initialized(false)
1369 {
1370 if(!InitializeSecurityDescriptor(&sd, security_descriptor_revision))
1371 return;
1372 if(!SetSecurityDescriptorDacl(&sd, true, 0, false))
1373 return;
1374 sa.lpSecurityDescriptor = &sd;
1375 sa.nLength = sizeof(interprocess_security_attributes);
1376 sa.bInheritHandle = false;
1377 initialized = false;
1378 }
1379
get_attributes()1380 interprocess_security_attributes *get_attributes()
1381 { return &sa; }
1382 };
1383
create_file_mapping(void * handle,unsigned long access,::boost::ulong_long_type file_offset,const char * name,interprocess_security_attributes * psec)1384 inline void * create_file_mapping (void * handle, unsigned long access, ::boost::ulong_long_type file_offset, const char * name, interprocess_security_attributes *psec)
1385 {
1386 const unsigned long high_size(file_offset >> 32), low_size((boost::uint32_t)file_offset);
1387 return CreateFileMappingA (handle, psec, access, high_size, low_size, name);
1388 }
1389
open_file_mapping(unsigned long access,const char * name)1390 inline void * open_file_mapping (unsigned long access, const char *name)
1391 { return OpenFileMappingA (access, 0, name); }
1392
map_view_of_file_ex(void * handle,unsigned long file_access,::boost::ulong_long_type offset,std::size_t numbytes,void * base_addr)1393 inline void *map_view_of_file_ex(void *handle, unsigned long file_access, ::boost::ulong_long_type offset, std::size_t numbytes, void *base_addr)
1394 {
1395 const unsigned long offset_low = (unsigned long)(offset & ((::boost::ulong_long_type)0xFFFFFFFF));
1396 const unsigned long offset_high = offset >> 32;
1397 return MapViewOfFileEx(handle, file_access, offset_high, offset_low, numbytes, base_addr);
1398 }
1399
create_file(const char * name,unsigned long access,unsigned long creation_flags,unsigned long attributes,interprocess_security_attributes * psec)1400 inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes, interprocess_security_attributes *psec)
1401 {
1402 for (unsigned int attempt(0); attempt < error_sharing_violation_tries; ++attempt){
1403 void * const handle = CreateFileA(name, access,
1404 file_share_read | file_share_write | file_share_delete,
1405 psec, creation_flags, attributes, 0);
1406 bool const invalid(invalid_handle_value == handle);
1407 if (!invalid){
1408 return handle;
1409 }
1410 if (error_sharing_violation != get_last_error()){
1411 return handle;
1412 }
1413 sleep(error_sharing_violation_sleep_ms);
1414 }
1415 return invalid_handle_value;
1416 }
1417
get_system_info(system_info * info)1418 inline void get_system_info(system_info *info)
1419 { GetSystemInfo(info); }
1420
flush_view_of_file(void * base_addr,std::size_t numbytes)1421 inline bool flush_view_of_file(void *base_addr, std::size_t numbytes)
1422 { return 0 != FlushViewOfFile(base_addr, numbytes); }
1423
virtual_unlock(void * base_addr,std::size_t numbytes)1424 inline bool virtual_unlock(void *base_addr, std::size_t numbytes)
1425 { return 0 != VirtualUnlock(base_addr, numbytes); }
1426
virtual_protect(void * base_addr,std::size_t numbytes,unsigned long flNewProtect,unsigned long & lpflOldProtect)1427 inline bool virtual_protect(void *base_addr, std::size_t numbytes, unsigned long flNewProtect, unsigned long &lpflOldProtect)
1428 { return 0 != VirtualProtect(base_addr, numbytes, flNewProtect, &lpflOldProtect); }
1429
flush_file_buffers(void * handle)1430 inline bool flush_file_buffers(void *handle)
1431 { return 0 != FlushFileBuffers(handle); }
1432
get_file_size(void * handle,__int64 & size)1433 inline bool get_file_size(void *handle, __int64 &size)
1434 { return 0 != GetFileSizeEx(handle, (large_integer*)&size); }
1435
create_directory(const char * name)1436 inline bool create_directory(const char *name)
1437 {
1438 interprocess_all_access_security sec;
1439 return 0 != CreateDirectoryA(name, sec.get_attributes());
1440 }
1441
remove_directory(const char * lpPathName)1442 inline bool remove_directory(const char *lpPathName)
1443 { return 0 != RemoveDirectoryA(lpPathName); }
1444
get_temp_path(unsigned long length,char * buffer)1445 inline unsigned long get_temp_path(unsigned long length, char *buffer)
1446 { return GetTempPathA(length, buffer); }
1447
set_end_of_file(void * handle)1448 inline int set_end_of_file(void *handle)
1449 { return 0 != SetEndOfFile(handle); }
1450
set_file_pointer_ex(void * handle,__int64 distance,__int64 * new_file_pointer,unsigned long move_method)1451 inline bool set_file_pointer_ex(void *handle, __int64 distance, __int64 *new_file_pointer, unsigned long move_method)
1452 {
1453 large_integer d; d.QuadPart = distance;
1454 return 0 != SetFilePointerEx(handle, d, (large_integer*)new_file_pointer, move_method);
1455 }
1456
lock_file_ex(void * hnd,unsigned long flags,unsigned long reserved,unsigned long size_low,unsigned long size_high,interprocess_overlapped * overlapped)1457 inline bool lock_file_ex(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped)
1458 { return 0 != LockFileEx(hnd, flags, reserved, size_low, size_high, overlapped); }
1459
unlock_file_ex(void * hnd,unsigned long reserved,unsigned long size_low,unsigned long size_high,interprocess_overlapped * overlapped)1460 inline bool unlock_file_ex(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped)
1461 { return 0 != UnlockFileEx(hnd, reserved, size_low, size_high, overlapped); }
1462
write_file(void * hnd,const void * buffer,unsigned long bytes_to_write,unsigned long * bytes_written,interprocess_overlapped * overlapped)1463 inline bool write_file(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped)
1464 { return 0 != WriteFile(hnd, buffer, bytes_to_write, bytes_written, overlapped); }
1465
read_file(void * hnd,void * buffer,unsigned long bytes_to_read,unsigned long * bytes_read,interprocess_overlapped * overlapped)1466 inline bool read_file(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped)
1467 { return 0 != ReadFile(hnd, buffer, bytes_to_read, bytes_read, overlapped); }
1468
get_file_information_by_handle(void * hnd,interprocess_by_handle_file_information * info)1469 inline bool get_file_information_by_handle(void *hnd, interprocess_by_handle_file_information *info)
1470 { return 0 != GetFileInformationByHandle(hnd, info); }
1471
interlocked_increment(long volatile * addr)1472 inline long interlocked_increment(long volatile *addr)
1473 { return BOOST_INTERLOCKED_INCREMENT(const_cast<long*>(addr)); }
1474
interlocked_decrement(long volatile * addr)1475 inline long interlocked_decrement(long volatile *addr)
1476 { return BOOST_INTERLOCKED_DECREMENT(const_cast<long*>(addr)); }
1477
interlocked_compare_exchange(long volatile * addr,long val1,long val2)1478 inline long interlocked_compare_exchange(long volatile *addr, long val1, long val2)
1479 { return BOOST_INTERLOCKED_COMPARE_EXCHANGE(const_cast<long*>(addr), val1, val2); }
1480
interlocked_exchange_add(long volatile * addend,long value)1481 inline long interlocked_exchange_add(long volatile* addend, long value)
1482 { return BOOST_INTERLOCKED_EXCHANGE_ADD(const_cast<long*>(addend), value); }
1483
interlocked_exchange(long volatile * addend,long value)1484 inline long interlocked_exchange(long volatile* addend, long value)
1485 { return BOOST_INTERLOCKED_EXCHANGE(const_cast<long*>(addend), value); }
1486
1487 //Forward functions
load_library(const char * name)1488 inline hmodule load_library(const char *name)
1489 { return LoadLibraryA(name); }
1490
free_library(hmodule module)1491 inline bool free_library(hmodule module)
1492 { return 0 != FreeLibrary(module); }
1493
get_proc_address(hmodule module,const char * name)1494 inline farproc_t get_proc_address(hmodule module, const char *name)
1495 { return GetProcAddress(module, name); }
1496
get_current_process()1497 inline void *get_current_process()
1498 { return GetCurrentProcess(); }
1499
get_module_handle(const char * name)1500 inline hmodule get_module_handle(const char *name)
1501 { return GetModuleHandleA(name); }
1502
reg_open_key_ex(hkey hKey,const char * lpSubKey,unsigned long ulOptions,unsigned long samDesired,hkey * phkResult)1503 inline long reg_open_key_ex(hkey hKey, const char *lpSubKey, unsigned long ulOptions, unsigned long samDesired, hkey *phkResult)
1504 { return RegOpenKeyExA(hKey, lpSubKey, ulOptions, samDesired, phkResult); }
1505
reg_query_value_ex(hkey hKey,const char * lpValueName,unsigned long * lpReserved,unsigned long * lpType,unsigned char * lpData,unsigned long * lpcbData)1506 inline long reg_query_value_ex(hkey hKey, const char *lpValueName, unsigned long*lpReserved, unsigned long*lpType, unsigned char *lpData, unsigned long*lpcbData)
1507 { return RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); }
1508
reg_close_key(hkey hKey)1509 inline long reg_close_key(hkey hKey)
1510 { return RegCloseKey(hKey); }
1511
initialize_object_attributes(object_attributes_t * pobject_attr,unicode_string_t * name,unsigned long attr,void * rootdir,void * security_descr)1512 inline void initialize_object_attributes
1513 ( object_attributes_t *pobject_attr, unicode_string_t *name
1514 , unsigned long attr, void *rootdir, void *security_descr)
1515
1516 {
1517 pobject_attr->Length = sizeof(object_attributes_t);
1518 pobject_attr->RootDirectory = rootdir;
1519 pobject_attr->Attributes = attr;
1520 pobject_attr->ObjectName = name;
1521 pobject_attr->SecurityDescriptor = security_descr;
1522 pobject_attr->SecurityQualityOfService = 0;
1523 }
1524
rtl_init_empty_unicode_string(unicode_string_t * ucStr,wchar_t * buf,unsigned short bufSize)1525 inline void rtl_init_empty_unicode_string(unicode_string_t *ucStr, wchar_t *buf, unsigned short bufSize)
1526 {
1527 ucStr->Buffer = buf;
1528 ucStr->Length = 0;
1529 ucStr->MaximumLength = bufSize;
1530 }
1531
1532 //A class that locates and caches loaded DLL function addresses.
1533 template<int Dummy>
1534 struct function_address_holder
1535 {
1536 enum { NtSetInformationFile
1537 , NtQuerySystemInformation
1538 , NtQueryObject
1539 , NtQuerySemaphore
1540 , NtQuerySection
1541 , NtOpenFile
1542 , NtClose
1543 , NtQueryTimerResolution
1544 , QueryPerformanceCounter
1545 , QueryPerformanceFrequency
1546 , NumFunction
1547 };
1548 enum { NtDll_dll, Kernel32_dll, NumModule };
1549
1550 private:
1551 static const char *FunctionNames[NumFunction];
1552 static const char *ModuleNames[NumModule];
1553 static farproc_t FunctionAddresses[NumFunction];
1554 static unsigned int FunctionModules[NumFunction];
1555 static volatile long FunctionStates[NumFunction];
1556 static hmodule ModuleAddresses[NumModule];
1557 static volatile long ModuleStates[NumModule];
1558
get_module_from_idboost::interprocess::winapi::function_address_holder1559 static hmodule get_module_from_id(unsigned int id)
1560 {
1561 BOOST_ASSERT(id < (unsigned int)NumModule);
1562 hmodule addr = get_module_handle(ModuleNames[id]);
1563 BOOST_ASSERT(addr);
1564 return addr;
1565 }
1566
get_moduleboost::interprocess::winapi::function_address_holder1567 static hmodule get_module(const unsigned int id)
1568 {
1569 BOOST_ASSERT(id < (unsigned int)NumModule);
1570 for(unsigned i = 0; ModuleStates[id] < 2; ++i){
1571 if(interlocked_compare_exchange(&ModuleStates[id], 1, 0) == 0){
1572 ModuleAddresses[id] = get_module_from_id(id);
1573 interlocked_increment(&ModuleStates[id]);
1574 break;
1575 }
1576 else if(i & 1){
1577 sched_yield();
1578 }
1579 else{
1580 sleep_tick();
1581 }
1582 }
1583 return ModuleAddresses[id];
1584 }
1585
get_address_from_dllboost::interprocess::winapi::function_address_holder1586 static farproc_t get_address_from_dll(const unsigned int id)
1587 {
1588 BOOST_ASSERT(id < (unsigned int)NumFunction);
1589 farproc_t addr = get_proc_address(get_module(FunctionModules[id]), FunctionNames[id]);
1590 BOOST_ASSERT(addr);
1591 return addr;
1592 }
1593
1594 public:
getboost::interprocess::winapi::function_address_holder1595 static farproc_t get(const unsigned int id)
1596 {
1597 BOOST_ASSERT(id < (unsigned int)NumFunction);
1598 for(unsigned i = 0; FunctionStates[id] < 2; ++i){
1599 if(interlocked_compare_exchange(&FunctionStates[id], 1, 0) == 0){
1600 FunctionAddresses[id] = get_address_from_dll(id);
1601 interlocked_increment(&FunctionStates[id]);
1602 break;
1603 }
1604 else if(i & 1){
1605 sched_yield();
1606 }
1607 else{
1608 sleep_tick();
1609 }
1610 }
1611 return FunctionAddresses[id];
1612 }
1613 };
1614
1615 template<int Dummy>
1616 const char *function_address_holder<Dummy>::FunctionNames[function_address_holder<Dummy>::NumFunction] =
1617 {
1618 "NtSetInformationFile",
1619 "NtQuerySystemInformation",
1620 "NtQueryObject",
1621 "NtQuerySemaphore",
1622 "NtQuerySection",
1623 "NtOpenFile",
1624 "NtClose",
1625 "NtQueryTimerResolution",
1626 "QueryPerformanceCounter",
1627 "QueryPerformanceFrequency"
1628 };
1629
1630 template<int Dummy>
1631 unsigned int function_address_holder<Dummy>::FunctionModules[function_address_holder<Dummy>::NumFunction] =
1632 {
1633 NtDll_dll,
1634 NtDll_dll,
1635 NtDll_dll,
1636 NtDll_dll,
1637 NtDll_dll,
1638 NtDll_dll,
1639 NtDll_dll,
1640 NtDll_dll,
1641 Kernel32_dll,
1642 Kernel32_dll
1643 };
1644
1645 template<int Dummy>
1646 const char *function_address_holder<Dummy>::ModuleNames[function_address_holder<Dummy>::NumModule] =
1647 {
1648 "ntdll.dll",
1649 "kernel32.dll"
1650 };
1651
1652
1653 template<int Dummy>
1654 farproc_t function_address_holder<Dummy>::FunctionAddresses[function_address_holder<Dummy>::NumFunction];
1655
1656 template<int Dummy>
1657 volatile long function_address_holder<Dummy>::FunctionStates[function_address_holder<Dummy>::NumFunction];
1658
1659 template<int Dummy>
1660 hmodule function_address_holder<Dummy>::ModuleAddresses[function_address_holder<Dummy>::NumModule];
1661
1662 template<int Dummy>
1663 volatile long function_address_holder<Dummy>::ModuleStates[function_address_holder<Dummy>::NumModule];
1664
1665
1666 struct dll_func
1667 : public function_address_holder<0>
1668 {};
1669
1670 //Complex winapi based functions...
1671 struct library_unloader
1672 {
1673 hmodule lib_;
library_unloaderboost::interprocess::winapi::library_unloader1674 library_unloader(hmodule module) : lib_(module){}
~library_unloaderboost::interprocess::winapi::library_unloader1675 ~library_unloader(){ free_library(lib_); }
1676 };
1677
1678
get_system_time_of_day_information(system_timeofday_information & info)1679 inline bool get_system_time_of_day_information(system_timeofday_information &info)
1680 {
1681 NtQuerySystemInformation_t pNtQuerySystemInformation = reinterpret_cast<NtQuerySystemInformation_t>
1682 (dll_func::get(dll_func::NtQuerySystemInformation));
1683 unsigned long res;
1684 long status = pNtQuerySystemInformation(system_time_of_day_information, &info, sizeof(info), &res);
1685 if(status){
1686 return false;
1687 }
1688 return true;
1689 }
1690
get_boot_time(unsigned char (& bootstamp)[BootstampLength])1691 inline bool get_boot_time(unsigned char (&bootstamp) [BootstampLength])
1692 {
1693 system_timeofday_information info;
1694 bool ret = get_system_time_of_day_information(info);
1695 if(!ret){
1696 return false;
1697 }
1698 std::memcpy(&bootstamp[0], &info.Reserved1, sizeof(bootstamp));
1699 return true;
1700 }
1701
get_boot_and_system_time(unsigned char (& bootsystemstamp)[BootAndSystemstampLength])1702 inline bool get_boot_and_system_time(unsigned char (&bootsystemstamp) [BootAndSystemstampLength])
1703 {
1704 system_timeofday_information info;
1705 bool ret = get_system_time_of_day_information(info);
1706 if(!ret){
1707 return false;
1708 }
1709 std::memcpy(&bootsystemstamp[0], &info.Reserved1, sizeof(bootsystemstamp));
1710 return true;
1711 }
1712
1713 //Writes the hexadecimal value of the buffer, in the wide character string.
1714 //str must be twice length
buffer_to_wide_str(const void * buf,std::size_t length,wchar_t * str)1715 inline void buffer_to_wide_str(const void *buf, std::size_t length, wchar_t *str)
1716 {
1717 const wchar_t Characters [] =
1718 { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7'
1719 , L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
1720 std::size_t char_counter = 0;
1721 const char *chbuf = static_cast<const char *>(buf);
1722 for(std::size_t i = 0; i != length; ++i){
1723 str[char_counter++] = Characters[(chbuf[i]&0xF0)>>4];
1724 str[char_counter++] = Characters[(chbuf[i]&0x0F)];
1725 }
1726 }
1727
1728 //Writes the hexadecimal value of the buffer, in the narrow character string.
1729 //str must be twice length
buffer_to_narrow_str(const void * buf,std::size_t length,char * str)1730 inline void buffer_to_narrow_str(const void *buf, std::size_t length, char *str)
1731 {
1732 const char Characters [] =
1733 { '0', '1', '2', '3', '4', '5', '6', '7'
1734 , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1735 std::size_t char_counter = 0;
1736 const char *chbuf = static_cast<const char *>(buf);
1737 for(std::size_t i = 0; i != length; ++i){
1738 str[char_counter++] = Characters[(chbuf[i]&0xF0)>>4];
1739 str[char_counter++] = Characters[(chbuf[i]&0x0F)];
1740 }
1741 }
1742
get_boot_time_str(char * bootstamp_str,std::size_t & s)1743 inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s)
1744 //will write BootstampLength chars
1745 {
1746 if(s < (BootstampLength*2))
1747 return false;
1748 system_timeofday_information info;
1749 bool ret = get_system_time_of_day_information(info);
1750 if(!ret){
1751 return false;
1752 }
1753
1754 buffer_to_narrow_str(info.Reserved1, BootstampLength, bootstamp_str);
1755 s = BootstampLength*2;
1756 return true;
1757 }
1758
get_boot_and_system_time_wstr(wchar_t * bootsystemstamp,std::size_t & s)1759 inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp, std::size_t &s)
1760 //will write BootAndSystemstampLength chars
1761 {
1762 if(s < (BootAndSystemstampLength*2))
1763 return false;
1764 system_timeofday_information info;
1765 bool ret = get_system_time_of_day_information(info);
1766 if(!ret){
1767 return false;
1768 }
1769
1770 buffer_to_wide_str(&info.Reserved1[0], BootAndSystemstampLength, bootsystemstamp);
1771 s = BootAndSystemstampLength*2;
1772 return true;
1773 }
1774
1775 class handle_closer
1776 {
1777 void *handle_;
1778 handle_closer(const handle_closer &);
1779 handle_closer& operator=(const handle_closer &);
1780 public:
handle_closer(void * handle)1781 explicit handle_closer(void *handle) : handle_(handle){}
~handle_closer()1782 ~handle_closer()
1783 { close_handle(handle_); }
1784 };
1785
1786 class eventlog_handle_closer
1787 {
1788 void *handle_;
1789 eventlog_handle_closer(const handle_closer &);
1790 eventlog_handle_closer& operator=(const eventlog_handle_closer &);
1791 public:
eventlog_handle_closer(void * handle)1792 explicit eventlog_handle_closer(void *handle) : handle_(handle){}
~eventlog_handle_closer()1793 ~eventlog_handle_closer()
1794 { CloseEventLog(handle_); }
1795 };
1796
1797 union ntquery_mem_t
1798 {
1799 object_name_information_t name;
1800 struct ren_t
1801 {
1802 file_rename_information_t info;
1803 wchar_t buf[1];
1804 } ren;
1805 };
1806
1807 class nt_query_mem_deleter
1808 {
1809 static const std::size_t rename_offset = offsetof(ntquery_mem_t, ren.info.FileName) -
1810 offsetof(ntquery_mem_t, name.Name.Buffer);
1811 // Timestamp process id atomic count
1812 static const std::size_t rename_suffix =
1813 (SystemTimeOfDayInfoLength + sizeof(unsigned long) + sizeof(boost::uint32_t))*2;
1814
1815 public:
nt_query_mem_deleter(std::size_t object_name_information_size)1816 explicit nt_query_mem_deleter(std::size_t object_name_information_size)
1817 : m_size(object_name_information_size + rename_offset + rename_suffix)
1818 , m_buf(new char [m_size])
1819 {}
1820
~nt_query_mem_deleter()1821 ~nt_query_mem_deleter()
1822 {
1823 delete[]m_buf;
1824 }
1825
realloc_mem(std::size_t num_bytes)1826 void realloc_mem(std::size_t num_bytes)
1827 {
1828 num_bytes += rename_suffix + rename_offset;
1829 char *buf = m_buf;
1830 m_buf = new char[num_bytes];
1831 delete[]buf;
1832 m_size = num_bytes;
1833 }
1834
query_mem() const1835 ntquery_mem_t *query_mem() const
1836 { return static_cast<ntquery_mem_t *>(static_cast<void*>(m_buf)); }
1837
object_name_information_size() const1838 unsigned long object_name_information_size() const
1839 {
1840 return static_cast<unsigned long>(m_size - rename_offset - SystemTimeOfDayInfoLength*2);
1841 }
1842
file_rename_information_size() const1843 std::size_t file_rename_information_size() const
1844 { return static_cast<unsigned long>(m_size); }
1845
1846 private:
1847 std::size_t m_size;
1848 char *m_buf;
1849 };
1850
1851 class c_heap_deleter
1852 {
1853 public:
c_heap_deleter(std::size_t size)1854 explicit c_heap_deleter(std::size_t size)
1855 : m_buf(::malloc(size))
1856 {}
1857
~c_heap_deleter()1858 ~c_heap_deleter()
1859 {
1860 if(m_buf) ::free(m_buf);
1861 }
1862
realloc_mem(std::size_t num_bytes)1863 void realloc_mem(std::size_t num_bytes)
1864 {
1865 void *oldBuf = m_buf;
1866 m_buf = ::realloc(m_buf, num_bytes);
1867 if (!m_buf){
1868 free(oldBuf);
1869 }
1870 }
1871
get() const1872 void *get() const
1873 { return m_buf; }
1874
1875 private:
1876 void *m_buf;
1877 };
1878
unlink_file(const char * filename)1879 inline bool unlink_file(const char *filename)
1880 {
1881 //Don't try to optimize doing a DeleteFile first
1882 //as there are interactions with permissions and
1883 //in-use files.
1884 //
1885 //if(!delete_file(filename)){
1886 // (...)
1887 //
1888
1889 //This functions tries to emulate UNIX unlink semantics in windows.
1890 //
1891 //- Open the file and mark the handle as delete-on-close
1892 //- Rename the file to an arbitrary name based on a random number
1893 //- Close the handle. If there are no file users, it will be deleted.
1894 // Otherwise it will be used by already connected handles but the
1895 // file name can't be used to open this file again
1896 try{
1897 NtSetInformationFile_t pNtSetInformationFile =
1898 reinterpret_cast<NtSetInformationFile_t>(dll_func::get(dll_func::NtSetInformationFile));
1899
1900 NtQueryObject_t pNtQueryObject = reinterpret_cast<NtQueryObject_t>(dll_func::get(dll_func::NtQueryObject));
1901
1902 //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
1903 void *fh = create_file(filename, generic_read | delete_access, open_existing, 0, 0);
1904 if(fh == invalid_handle_value){
1905 return false;
1906 }
1907
1908 handle_closer h_closer(fh);
1909 {
1910 //Obtain name length
1911 unsigned long size;
1912 const std::size_t initial_string_mem = 512u;
1913
1914 nt_query_mem_deleter nt_query_mem(sizeof(ntquery_mem_t)+initial_string_mem);
1915 //Obtain file name with guessed length
1916 if(pNtQueryObject(fh, object_name_information, nt_query_mem.query_mem(), nt_query_mem.object_name_information_size(), &size)){
1917 //Obtain file name with exact length buffer
1918 nt_query_mem.realloc_mem(size);
1919 if(pNtQueryObject(fh, object_name_information, nt_query_mem.query_mem(), nt_query_mem.object_name_information_size(), &size)){
1920 return false;
1921 }
1922 }
1923 ntquery_mem_t *pmem = nt_query_mem.query_mem();
1924 file_rename_information_t *pfri = &pmem->ren.info;
1925 const std::size_t RenMaxNumChars =
1926 (((char*)(pmem) + nt_query_mem.file_rename_information_size()) - (char*)&pmem->ren.info.FileName[0])/sizeof(wchar_t);
1927
1928 //Copy filename to the rename member
1929 std::memmove(pmem->ren.info.FileName, pmem->name.Name.Buffer, pmem->name.Name.Length);
1930 std::size_t filename_string_length = pmem->name.Name.Length/sizeof(wchar_t);
1931
1932 //Search '\\' character to replace from it
1933 for(std::size_t i = filename_string_length; i != 0; --filename_string_length){
1934 if(pmem->ren.info.FileName[--i] == L'\\')
1935 break;
1936 }
1937
1938 //Add random number
1939 std::size_t s = RenMaxNumChars - filename_string_length;
1940 if(!get_boot_and_system_time_wstr(&pfri->FileName[filename_string_length], s)){
1941 return false;
1942 }
1943 filename_string_length += s;
1944
1945 //Sometimes the precission of the timestamp is not enough and we need to add another random number.
1946 //The process id (to exclude concurrent processes) and an atomic count (to exclude concurrent threads).
1947 //should be enough
1948 const unsigned long pid = get_current_process_id();
1949 buffer_to_wide_str(&pid, sizeof(pid), &pfri->FileName[filename_string_length]);
1950 filename_string_length += sizeof(pid)*2;
1951
1952 static volatile boost::uint32_t u32_count = 0;
1953 interlocked_decrement(reinterpret_cast<volatile long*>(&u32_count));
1954 buffer_to_wide_str(const_cast<const boost::uint32_t *>(&u32_count), sizeof(boost::uint32_t), &pfri->FileName[filename_string_length]);
1955 filename_string_length += sizeof(boost::uint32_t)*2;
1956
1957 //Fill rename information (FileNameLength is in bytes)
1958 pfri->FileNameLength = static_cast<unsigned long>(sizeof(wchar_t)*(filename_string_length));
1959 pfri->Replace = 1;
1960 pfri->RootDir = 0;
1961
1962 //Cange the name of the in-use file...
1963 io_status_block_t io;
1964 if(0 != pNtSetInformationFile(fh, &io, pfri, nt_query_mem.file_rename_information_size(), file_rename_information)){
1965 return false;
1966 }
1967 }
1968 //...and mark it as delete-on-close
1969 {
1970 //Don't use pNtSetInformationFile with file_disposition_information as it can return STATUS_CANNOT_DELETE
1971 //if the file is still mapped. Reopen it with NtOpenFile and file_delete_on_close
1972 NtOpenFile_t pNtOpenFile = reinterpret_cast<NtOpenFile_t>(dll_func::get(dll_func::NtOpenFile));
1973 NtClose_t pNtClose = reinterpret_cast<NtClose_t>(dll_func::get(dll_func::NtClose));
1974 const wchar_t empty_str [] = L"";
1975 unicode_string_t ustring = { sizeof(empty_str) - sizeof (wchar_t) //length in bytes without null
1976 , sizeof(empty_str) //total size in bytes of memory allocated for Buffer.
1977 , const_cast<wchar_t*>(empty_str)
1978 };
1979 object_attributes_t object_attr;
1980 initialize_object_attributes(&object_attr, &ustring, 0, fh, 0);
1981 void* fh2 = 0;
1982 io_status_block_t io;
1983 pNtOpenFile( &fh2, delete_flag, &object_attr, &io
1984 , file_share_read | file_share_write | file_share_delete, file_delete_on_close);
1985 pNtClose(fh2);
1986 //Even if NtOpenFile fails, the file was renamed and the original no longer exists, so return a success status
1987 return true;
1988 }
1989 }
1990 catch(...){
1991 return false;
1992 }
1993 return true;
1994 }
1995
1996 struct reg_closer
1997 {
1998 hkey key_;
reg_closerboost::interprocess::winapi::reg_closer1999 reg_closer(hkey key) : key_(key){}
~reg_closerboost::interprocess::winapi::reg_closer2000 ~reg_closer(){ reg_close_key(key_); }
2001 };
2002
get_registry_value_buffer(hkey key_type,const char * subkey_name,const char * value_name,void * buf,std::size_t & buflen)2003 inline bool get_registry_value_buffer(hkey key_type, const char *subkey_name, const char *value_name, void *buf, std::size_t &buflen)
2004 {
2005 bool bret = false;
2006 hkey key;
2007 if (reg_open_key_ex( key_type
2008 , subkey_name
2009 , 0
2010 , key_query_value
2011 , &key) == 0){
2012 reg_closer key_closer(key);
2013
2014 //Obtain the value
2015 unsigned long size = buflen;
2016 unsigned long type;
2017 buflen = 0;
2018 bret = 0 == reg_query_value_ex( key, value_name, 0, &type, (unsigned char*)buf, &size);
2019 if(bret)
2020 buflen = (std::size_t)size;
2021 }
2022 return bret;
2023 }
2024
get_registry_value_string(hkey key_type,const char * subkey_name,const char * value_name,std::string & s)2025 inline bool get_registry_value_string(hkey key_type, const char *subkey_name, const char *value_name, std::string &s)
2026 {
2027 bool bret = false;
2028 s.clear();
2029 hkey key;
2030 if (reg_open_key_ex( key_type
2031 , subkey_name
2032 , 0
2033 , key_query_value
2034 , &key) == 0){
2035 reg_closer key_closer(key);
2036
2037 //Obtain the value
2038 unsigned long size;
2039 unsigned long type;
2040 long err = reg_query_value_ex( key, value_name, 0, &type, 0, &size);
2041 if((reg_sz == type || reg_expand_sz == type) && !err){
2042 //Size includes terminating NULL
2043 s.resize(size);
2044 err = reg_query_value_ex( key, value_name, 0, &type, (unsigned char*)(&s[0]), &size);
2045 if(!err){
2046 s.erase(s.end()-1);
2047 bret = true;
2048 }
2049 (void)err;
2050 }
2051 }
2052 return bret;
2053 }
2054
get_shared_documents_folder(std::string & s)2055 inline void get_shared_documents_folder(std::string &s)
2056 {
2057 #if 1 //Original registry search code
2058 get_registry_value_string( hkey_local_machine
2059 , "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
2060 , "Common AppData"
2061 , s);
2062 #else //registry alternative: SHGetFolderPath
2063 const int BIPC_CSIDL_COMMON_APPDATA = 0x0023; // All Users\Application Data
2064 const int BIPC_CSIDL_FLAG_CREATE = 0x8000; // new for Win2K, or this in to force creation of folder
2065 const int BIPC_SHGFP_TYPE_CURRENT = 0; // current value for user, verify it exists
2066
2067 s.clear();
2068 char szPath[max_path];
2069 if(0 == SHGetFolderPathA(0, BIPC_CSIDL_COMMON_APPDATA | BIPC_CSIDL_FLAG_CREATE, 0, BIPC_SHGFP_TYPE_CURRENT, szPath)){
2070 s = szPath;
2071 }
2072
2073 #endif
2074 }
2075
get_registry_value(const char * folder,const char * value_key,std::vector<unsigned char> & s)2076 inline void get_registry_value(const char *folder, const char *value_key, std::vector<unsigned char> &s)
2077 {
2078 s.clear();
2079 hkey key;
2080 if (reg_open_key_ex( hkey_local_machine
2081 , folder
2082 , 0
2083 , key_query_value
2084 , &key) == 0){
2085 reg_closer key_closer(key);
2086
2087 //Obtain the value
2088 unsigned long size;
2089 unsigned long type;
2090 const char *const reg_value = value_key;
2091 //long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
2092 long err = reg_query_value_ex( key, reg_value, 0, &type, 0, &size);
2093 if(!err){
2094 //Size includes terminating NULL
2095 s.resize(size);
2096 //err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
2097 err = reg_query_value_ex( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
2098 if(!err)
2099 s.erase(s.end()-1);
2100 (void)err;
2101 }
2102 }
2103 }
2104
2105 #if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME)
2106
2107 struct co_uninitializer
2108 {
co_uninitializerboost::interprocess::winapi::co_uninitializer2109 co_uninitializer(bool b_uninitialize)
2110 : m_b_uninitialize(b_uninitialize)
2111 {}
2112
~co_uninitializerboost::interprocess::winapi::co_uninitializer2113 ~co_uninitializer()
2114 {
2115 if(m_b_uninitialize){
2116 CoUninitialize();
2117 }
2118 }
2119
2120 private:
2121 const bool m_b_uninitialize;
2122 };
2123
2124 template<class Object>
2125 struct com_releaser
2126 {
2127 Object *&object_;
com_releaserboost::interprocess::winapi::com_releaser2128 com_releaser(Object *&object) : object_(object) {}
~com_releaserboost::interprocess::winapi::com_releaser2129 ~com_releaser() { object_->Release(); object_ = 0; }
2130 };
2131
get_wmi_class_attribute(std::wstring & strValue,const wchar_t * wmi_class,const wchar_t * wmi_class_var)2132 inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_class, const wchar_t *wmi_class_var)
2133 {
2134 //See example http://msdn.microsoft.com/en-us/library/aa390423%28v=VS.85%29.aspx
2135 //
2136 //See BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL definition if you need to change the
2137 //default value of this macro in your application
2138 long co_init_ret = CoInitializeEx(0, BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL);
2139 if(co_init_ret != S_OK_BIPC && co_init_ret != S_FALSE_BIPC && co_init_ret != RPC_E_CHANGED_MODE_BIPC)
2140 return false;
2141 co_uninitializer co_initialize_end(co_init_ret != RPC_E_CHANGED_MODE_BIPC);
2142 (void)co_initialize_end;
2143
2144 bool bRet = false;
2145 long sec_init_ret = CoInitializeSecurity
2146 ( 0 //pVoid
2147 ,-1 //cAuthSvc
2148 , 0 //asAuthSvc
2149 , 0 //pReserved1
2150 , RPC_C_AUTHN_LEVEL_PKT_BIPC //dwAuthnLevel
2151 , RPC_C_IMP_LEVEL_IMPERSONATE_BIPC //dwImpLevel
2152 , 0 //pAuthList
2153 , EOAC_NONE_BIPC //dwCapabilities
2154 , 0 //pReserved3
2155 );
2156 if( 0 == sec_init_ret || RPC_E_TOO_LATE_BIPC == sec_init_ret)
2157 {
2158 IWbemLocator_BIPC * pIWbemLocator = 0;
2159 const wchar_t * bstrNamespace = L"root\\cimv2";
2160
2161 if( 0 != CoCreateInstance(
2162 CLSID_WbemAdministrativeLocator,
2163 0,
2164 CLSCTX_INPROC_SERVER_BIPC | CLSCTX_LOCAL_SERVER_BIPC,
2165 IID_IUnknown, (void **)&pIWbemLocator)){
2166 return false;
2167 }
2168
2169 com_releaser<IWbemLocator_BIPC> IWbemLocator_releaser(pIWbemLocator);
2170
2171 IWbemServices_BIPC *pWbemServices = 0;
2172
2173 if( 0 != pIWbemLocator->ConnectServer(
2174 (bstr)bstrNamespace, // Namespace
2175 0, // Userid
2176 0, // PW
2177 0, // Locale
2178 0, // flags
2179 0, // Authority
2180 0, // Context
2181 &pWbemServices
2182 )
2183 ){
2184 return false;
2185 }
2186
2187 if( S_OK_BIPC != CoSetProxyBlanket(
2188 pWbemServices,
2189 RPC_C_AUTHN_DEFAULT_BIPC,
2190 RPC_C_AUTHZ_DEFAULT_BIPC,
2191 0,
2192 RPC_C_AUTHN_LEVEL_PKT_BIPC,
2193 RPC_C_IMP_LEVEL_IMPERSONATE_BIPC,
2194 0,
2195 EOAC_NONE_BIPC
2196 )
2197 ){
2198 return false;
2199 }
2200
2201 com_releaser<IWbemServices_BIPC> IWbemServices_releaser(pWbemServices);
2202
2203 strValue.clear();
2204 strValue += L"Select ";
2205 strValue += wmi_class_var;
2206 strValue += L" from ";
2207 strValue += wmi_class;
2208
2209 IEnumWbemClassObject_BIPC * pEnumObject = 0;
2210
2211 if ( 0 != pWbemServices->ExecQuery(
2212 (bstr)L"WQL",
2213 (bstr)strValue.c_str(),
2214 //WBEM_FLAG_RETURN_IMMEDIATELY_BIPC,
2215 WBEM_FLAG_RETURN_WHEN_COMPLETE_BIPC | WBEM_FLAG_FORWARD_ONLY_BIPC,
2216 0,
2217 &pEnumObject
2218 )
2219 ){
2220 return false;
2221 }
2222
2223 com_releaser<IEnumWbemClassObject_BIPC> IEnumWbemClassObject_releaser(pEnumObject);
2224
2225 //WBEM_FLAG_FORWARD_ONLY_BIPC incompatible with Reset
2226 //if ( 0 != pEnumObject->Reset() ){
2227 //return false;
2228 //}
2229
2230 wchar_variant vwchar;
2231 unsigned long uCount = 1, uReturned;
2232 IWbemClassObject_BIPC * pClassObject = 0;
2233 while( 0 == pEnumObject->Next( WBEM_INFINITE_BIPC, uCount, &pClassObject, &uReturned ) )
2234 {
2235 com_releaser<IWbemClassObject_BIPC> IWbemClassObject_releaser(pClassObject);
2236 if ( 0 == pClassObject->Get( (bstr)L"LastBootUpTime", 0, &vwchar, 0, 0 ) ){
2237 bRet = true;
2238 strValue = (wchar_t*)vwchar.bstrVal;
2239 VariantClear(&vwchar );
2240 break;
2241 }
2242 }
2243 }
2244 return bRet;
2245 }
2246
2247 //Obtains the bootup time from WMI LastBootUpTime.
2248 //This time seems to change with hibernation and clock synchronization so avoid it.
get_last_bootup_time(std::wstring & strValue)2249 inline bool get_last_bootup_time( std::wstring& strValue )
2250 {
2251 bool ret = get_wmi_class_attribute(strValue, L"Win32_OperatingSystem", L"LastBootUpTime");
2252 std::size_t timezone = strValue.find(L'+');
2253 if(timezone != std::wstring::npos){
2254 strValue.erase(timezone);
2255 }
2256 timezone = strValue.find(L'-');
2257 if(timezone != std::wstring::npos){
2258 strValue.erase(timezone);
2259 }
2260 return ret;
2261 }
2262
get_last_bootup_time(std::string & str)2263 inline bool get_last_bootup_time( std::string& str )
2264 {
2265 std::wstring wstr;
2266 bool ret = get_last_bootup_time(wstr);
2267 str.resize(wstr.size());
2268 for(std::size_t i = 0, max = str.size(); i != max; ++i){
2269 str[i] = '0' + (wstr[i]-L'0');
2270 }
2271 return ret;
2272 }
2273
2274 #endif //BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME
2275
2276 #if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED)
2277
2278 // Loop through the buffer and obtain the contents of the
2279 // requested record in the buffer.
find_record_in_buffer(const void * pBuffer,unsigned long dwBytesRead,const char * provider_name,unsigned int id_to_find,interprocess_eventlogrecord * & pevent_log_record)2280 inline bool find_record_in_buffer( const void* pBuffer, unsigned long dwBytesRead, const char *provider_name
2281 , unsigned int id_to_find, interprocess_eventlogrecord *&pevent_log_record)
2282 {
2283 const unsigned char * pRecord = static_cast<const unsigned char*>(pBuffer);
2284 const unsigned char * pEndOfRecords = pRecord + dwBytesRead;
2285
2286 while (pRecord < pEndOfRecords){
2287 interprocess_eventlogrecord *pTypedRecord = (interprocess_eventlogrecord*)pRecord;
2288 // Check provider, written at the end of the fixed-part of the record
2289 if (0 == std::strcmp(provider_name, (char*)(pRecord + sizeof(interprocess_eventlogrecord))))
2290 {
2291 // Check event id
2292 if(id_to_find == (pTypedRecord->EventID & 0xFFFF)){
2293 pevent_log_record = pTypedRecord;
2294 return true;
2295 }
2296 }
2297
2298 pRecord += pTypedRecord->Length;
2299 }
2300 pevent_log_record = 0;
2301 return false;
2302 }
2303
2304 //Obtains the bootup time from the System Event Log,
2305 //event ID == 6005 (event log started).
2306 //Adapted from http://msdn.microsoft.com/en-us/library/windows/desktop/bb427356.aspx
get_last_bootup_time(std::string & stamp)2307 inline bool get_last_bootup_time(std::string &stamp)
2308 {
2309 const char *source_name = "System";
2310 const char *provider_name = "EventLog";
2311 const unsigned short event_id = 6005u;
2312
2313 unsigned long status = 0;
2314 unsigned long dwBytesToRead = 0;
2315 unsigned long dwBytesRead = 0;
2316 unsigned long dwMinimumBytesToRead = 0;
2317
2318 // The source name (provider) must exist as a subkey of Application.
2319 void *hEventLog = OpenEventLogA(0, source_name);
2320 if (hEventLog){
2321 eventlog_handle_closer hnd_closer(hEventLog); (void)hnd_closer;
2322 // Allocate an initial block of memory used to read event records. The number
2323 // of records read into the buffer will vary depending on the size of each event.
2324 // The size of each event will vary based on the size of the user-defined
2325 // data included with each event, the number and length of insertion
2326 // strings, and other data appended to the end of the event record.
2327 dwBytesToRead = max_record_buffer_size;
2328 c_heap_deleter heap_deleter(dwBytesToRead);
2329
2330 // Read blocks of records until you reach the end of the log or an
2331 // error occurs. The records are read from newest to oldest. If the buffer
2332 // is not big enough to hold a complete event record, reallocate the buffer.
2333 if (heap_deleter.get() != 0){
2334 while (0 == status){
2335 if (!ReadEventLogA(hEventLog,
2336 eventlog_sequential_read | eventlog_backwards_read,
2337 0,
2338 heap_deleter.get(),
2339 dwBytesToRead,
2340 &dwBytesRead,
2341 &dwMinimumBytesToRead)) {
2342 status = get_last_error();
2343 if (error_insufficient_buffer == status) {
2344 status = 0;
2345 dwBytesToRead = dwMinimumBytesToRead;
2346 heap_deleter.realloc_mem(dwMinimumBytesToRead);
2347 if (!heap_deleter.get()){
2348 return false;
2349 }
2350 }
2351 else{ //Not found or EOF
2352 return false;
2353 }
2354 }
2355 else
2356 {
2357 interprocess_eventlogrecord *pTypedRecord;
2358 // Print the contents of each record in the buffer.
2359 if(find_record_in_buffer(heap_deleter.get(), dwBytesRead, provider_name, event_id, pTypedRecord)){
2360 char stamp_str[sizeof(unsigned long)*3+1];
2361 std::sprintf(&stamp_str[0], "%u", ((unsigned int)pTypedRecord->TimeGenerated));
2362 stamp = stamp_str;
2363 break;
2364 }
2365 }
2366 }
2367 }
2368 }
2369 return true;
2370 }
2371
2372 #endif //BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
2373
2374 #if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED)
2375
get_last_bootup_time(std::string & stamp)2376 inline bool get_last_bootup_time(std::string &stamp)
2377 {
2378 unsigned dword_val = 0;
2379 std::size_t dword_size = sizeof(dword_val);
2380 bool b_ret = get_registry_value_buffer( hkey_local_machine
2381 , "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management\\PrefetchParameters"
2382 , "BootId", &dword_val, dword_size);
2383 if (b_ret)
2384 {
2385 char dword_str[sizeof(dword_val)*2u+1];
2386 buffer_to_narrow_str(&dword_val, dword_size, dword_str);
2387 dword_str[sizeof(dword_val)*2] = '\0';
2388 stamp = dword_str;
2389
2390 b_ret = get_registry_value_buffer( hkey_local_machine
2391 , "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power"
2392 , "HybridBootAnimationTime", &dword_val, dword_size);
2393 //Old Windows versions have no HybridBootAnimationTime
2394 if(b_ret)
2395 {
2396 buffer_to_narrow_str(&dword_val, dword_size, dword_str);
2397 dword_str[sizeof(dword_val)*2] = '\0';
2398 stamp += "_";
2399 stamp += dword_str;
2400 }
2401 b_ret = true;
2402 }
2403 return b_ret;
2404 }
2405
2406 #endif //BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED
2407
is_directory(const char * path)2408 inline bool is_directory(const char *path)
2409 {
2410 unsigned long attrib = GetFileAttributesA(path);
2411
2412 return (attrib != invalid_file_attributes &&
2413 (attrib & file_attribute_directory));
2414 }
2415
get_file_mapping_size(void * file_mapping_hnd,__int64 & size)2416 inline bool get_file_mapping_size(void *file_mapping_hnd, __int64 &size)
2417 {
2418 NtQuerySection_t pNtQuerySection =
2419 reinterpret_cast<NtQuerySection_t>(dll_func::get(dll_func::NtQuerySection));
2420 //Obtain file name
2421 interprocess_section_basic_information info;
2422 unsigned long ntstatus =
2423 pNtQuerySection(file_mapping_hnd, section_basic_information, &info, sizeof(info), 0);
2424 size = info.section_size;
2425 return !ntstatus;
2426 }
2427
get_semaphore_info(void * handle,long & count,long & limit)2428 inline bool get_semaphore_info(void *handle, long &count, long &limit)
2429 {
2430 winapi::interprocess_semaphore_basic_information info;
2431 winapi::NtQuerySemaphore_t pNtQuerySemaphore =
2432 reinterpret_cast<winapi::NtQuerySemaphore_t>(dll_func::get(winapi::dll_func::NtQuerySemaphore));
2433 unsigned int ret_len;
2434 long status = pNtQuerySemaphore(handle, winapi::semaphore_basic_information, &info, sizeof(info), &ret_len);
2435 count = info.count;
2436 limit = info.limit;
2437 return !status;
2438 }
2439
query_timer_resolution(unsigned long * lowres,unsigned long * highres,unsigned long * curres)2440 inline bool query_timer_resolution(unsigned long *lowres, unsigned long *highres, unsigned long *curres)
2441 {
2442 winapi::NtQueryTimerResolution_t pNtQueryTimerResolution =
2443 reinterpret_cast<winapi::NtQueryTimerResolution_t>(dll_func::get(winapi::dll_func::NtQueryTimerResolution));
2444 return !pNtQueryTimerResolution(lowres, highres, curres);
2445 }
2446
query_performance_counter(__int64 * lpPerformanceCount)2447 inline bool query_performance_counter(__int64 *lpPerformanceCount)
2448 {
2449 QueryPerformanceCounter_t pQueryPerformanceCounter = reinterpret_cast<QueryPerformanceCounter_t>
2450 (dll_func::get(dll_func::QueryPerformanceCounter));
2451 return 0 != pQueryPerformanceCounter(lpPerformanceCount);
2452 }
2453
query_performance_frequency(__int64 * lpFrequency)2454 inline bool query_performance_frequency(__int64 *lpFrequency)
2455 {
2456 QueryPerformanceCounter_t pQueryPerformanceFrequency = reinterpret_cast<QueryPerformanceFrequency_t>
2457 (dll_func::get(dll_func::QueryPerformanceFrequency));
2458 return 0 != pQueryPerformanceFrequency(lpFrequency);
2459 }
2460
get_tick_count()2461 inline unsigned long get_tick_count()
2462 { return GetTickCount(); }
2463
2464 } //namespace winapi
2465 } //namespace interprocess
2466 } //namespace boost
2467
2468 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
2469 # pragma GCC diagnostic pop
2470 #endif
2471
2472 #include <boost/interprocess/detail/config_end.hpp>
2473
2474 #endif //#ifdef BOOST_INTERPROCESS_WIN32_API_HPP
2475