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