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