Ticket #7923: win32_api.hpp

File win32_api.hpp, 72.8 KB (added by Ion Gaztañaga, 10 years ago)

New try adding process id to the random name

Line 
1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2005-2012. 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_PRIMITIVES_HPP
12#define BOOST_INTERPROCESS_WIN32_PRIMITIVES_HPP
13
14#include <boost/interprocess/detail/config_begin.hpp>
15#include <boost/interprocess/detail/workaround.hpp>
16#include <boost/date_time/filetime_functions.hpp>
17#include <cstddef>
18#include <cstring>
19#include <cassert>
20#include <string>
21#include <vector>
22#include <memory>
23
24#if defined (_MSC_VER) && (_MSC_VER >= 1200)
25# pragma once
26# pragma comment( lib, "advapi32.lib" )
27# pragma comment( lib, "oleaut32.lib" )
28# pragma comment( lib, "Ole32.lib" )
29# pragma comment( lib, "Psapi.lib" )
30#endif
31
32#if (defined BOOST_INTERPROCESS_WINDOWS)
33# include <cstdarg>
34# include <boost/detail/interlocked.hpp>
35#else
36# error "This file can only be included in Windows OS"
37#endif
38
39
40//The structures used in Interprocess with the
41//same binary interface as windows ones
42namespace boost {
43namespace interprocess {
44namespace winapi {
45
46//Some used constants
47static const unsigned long infinite_time = 0xFFFFFFFF;
48static const unsigned long error_already_exists = 183L;
49static const unsigned long error_invalid_handle = 6L;
50static const unsigned long error_sharing_violation = 32L;
51static const unsigned long error_file_not_found = 2u;
52static const unsigned long error_no_more_files = 18u;
53static const unsigned long error_not_locked = 158L;
54//Retries in CreateFile, see http://support.microsoft.com/kb/316609
55static const unsigned int error_sharing_violation_tries = 3u;
56static const unsigned int error_sharing_violation_sleep_ms = 250u;
57static const unsigned int error_file_too_large = 223u;
58
59static const unsigned long semaphore_all_access = (0x000F0000L)|(0x00100000L)|0x3;
60static const unsigned long mutex_all_access = (0x000F0000L)|(0x00100000L)|0x0001;
61
62static const unsigned long page_readonly = 0x02;
63static const unsigned long page_readwrite = 0x04;
64static const unsigned long page_writecopy = 0x08;
65static const unsigned long page_noaccess = 0x01;
66
67static const unsigned long standard_rights_required = 0x000F0000L;
68static const unsigned long section_query = 0x0001;
69static const unsigned long section_map_write = 0x0002;
70static const unsigned long section_map_read = 0x0004;
71static const unsigned long section_map_execute = 0x0008;
72static const unsigned long section_extend_size = 0x0010;
73static const unsigned long section_all_access = standard_rights_required |
74 section_query |
75 section_map_write |
76 section_map_read |
77 section_map_execute |
78 section_extend_size;
79
80static const unsigned long file_map_copy = section_query;
81static const unsigned long file_map_write = section_map_write;
82static const unsigned long file_map_read = section_map_read;
83static const unsigned long file_map_all_access = section_all_access;
84static const unsigned long delete_access = 0x00010000L;
85static const unsigned long file_flag_backup_semantics = 0x02000000;
86static const long file_flag_delete_on_close = 0x04000000;
87
88//Native API constants
89static const unsigned long file_open_for_backup_intent = 0x00004000;
90static const int file_share_valid_flags = 0x00000007;
91static const long file_delete_on_close = 0x00001000L;
92static const long obj_case_insensitive = 0x00000040L;
93static const long delete_flag = 0x00010000L;
94
95static const unsigned long movefile_copy_allowed = 0x02;
96static const unsigned long movefile_delay_until_reboot = 0x04;
97static const unsigned long movefile_replace_existing = 0x01;
98static const unsigned long movefile_write_through = 0x08;
99static const unsigned long movefile_create_hardlink = 0x10;
100static const unsigned long movefile_fail_if_not_trackable = 0x20;
101
102static const unsigned long file_share_read = 0x00000001;
103static const unsigned long file_share_write = 0x00000002;
104static const unsigned long file_share_delete = 0x00000004;
105
106static const unsigned long file_attribute_readonly = 0x00000001;
107static const unsigned long file_attribute_hidden = 0x00000002;
108static const unsigned long file_attribute_system = 0x00000004;
109static const unsigned long file_attribute_directory = 0x00000010;
110static const unsigned long file_attribute_archive = 0x00000020;
111static const unsigned long file_attribute_device = 0x00000040;
112static const unsigned long file_attribute_normal = 0x00000080;
113static const unsigned long file_attribute_temporary = 0x00000100;
114
115static const unsigned long generic_read = 0x80000000L;
116static const unsigned long generic_write = 0x40000000L;
117
118static const unsigned long wait_object_0 = 0;
119static const unsigned long wait_abandoned = 0x00000080L;
120static const unsigned long wait_timeout = 258L;
121static const unsigned long wait_failed = (unsigned long)0xFFFFFFFF;
122
123static const unsigned long duplicate_close_source = (unsigned long)0x00000001;
124static const unsigned long duplicate_same_access = (unsigned long)0x00000002;
125
126static const unsigned long format_message_allocate_buffer
127 = (unsigned long)0x00000100;
128static const unsigned long format_message_ignore_inserts
129 = (unsigned long)0x00000200;
130static const unsigned long format_message_from_string
131 = (unsigned long)0x00000400;
132static const unsigned long format_message_from_hmodule
133 = (unsigned long)0x00000800;
134static const unsigned long format_message_from_system
135 = (unsigned long)0x00001000;
136static const unsigned long format_message_argument_array
137 = (unsigned long)0x00002000;
138static const unsigned long format_message_max_width_mask
139 = (unsigned long)0x000000FF;
140static const unsigned long lang_neutral = (unsigned long)0x00;
141static const unsigned long sublang_default = (unsigned long)0x01;
142static const unsigned long invalid_file_size = (unsigned long)0xFFFFFFFF;
143static const unsigned long invalid_file_attributes = ((unsigned long)-1);
144static void * const invalid_handle_value = ((void*)(long)(-1));
145
146static const unsigned long file_type_char = 0x0002L;
147static const unsigned long file_type_disk = 0x0001L;
148static const unsigned long file_type_pipe = 0x0003L;
149static const unsigned long file_type_remote = 0x8000L;
150static const unsigned long file_type_unknown = 0x0000L;
151
152static const unsigned long create_new = 1;
153static const unsigned long create_always = 2;
154static const unsigned long open_existing = 3;
155static const unsigned long open_always = 4;
156static const unsigned long truncate_existing = 5;
157
158static const unsigned long file_begin = 0;
159static const unsigned long file_current = 1;
160static const unsigned long file_end = 2;
161
162static const unsigned long lockfile_fail_immediately = 1;
163static const unsigned long lockfile_exclusive_lock = 2;
164static const unsigned long error_lock_violation = 33;
165static const unsigned long security_descriptor_revision = 1;
166
167//Own defines
168static const long SystemTimeOfDayInfoLength = 48;
169static const long BootAndSystemstampLength = 16;
170static const long BootstampLength = 8;
171static const unsigned long MaxPath = 260;
172
173//Keys
174static void * const hkey_local_machine = (void*)(unsigned long*)(long)(0x80000002);
175static unsigned long key_query_value = 0x0001;
176
177//COM API
178const unsigned long RPC_C_AUTHN_LEVEL_PKT_BIPC = 4;
179const unsigned long RPC_C_AUTHN_DEFAULT_BIPC = 0xffffffffL;
180const unsigned long RPC_C_AUTHZ_DEFAULT_BIPC = 0xffffffffL;
181const unsigned long RPC_C_IMP_LEVEL_IMPERSONATE_BIPC = 3;
182const signed long EOAC_NONE_BIPC = 0;
183const signed long CLSCTX_INPROC_SERVER_BIPC = 0x1;
184const signed long CLSCTX_LOCAL_SERVER_BIPC = 0x4;
185const signed long WBEM_FLAG_RETURN_IMMEDIATELY_BIPC = 0x10;
186const signed long WBEM_FLAG_RETURN_WHEN_COMPLETE_BIPC = 0x0;
187const signed long WBEM_FLAG_FORWARD_ONLY_BIPC = 0x20;
188const signed long WBEM_INFINITE_BIPC = 0xffffffffL;
189const signed long RPC_E_TOO_LATE_BIPC = 0x80010119L;
190const signed long S_OK_BIPC = 0L;
191const signed long S_FALSE_BIPC = 1;
192const signed long RPC_E_CHANGED_MODE_BIPC = 0x80010106L;
193const unsigned long COINIT_APARTMENTTHREADED_BIPC = 0x2;
194const unsigned long COINIT_MULTITHREADED_BIPC = 0x0;
195const unsigned long COINIT_DISABLE_OLE1DDE_BIPC = 0x4;
196const unsigned long COINIT_SPEED_OVER_MEMORY_BIPC = 0x4;
197
198//If the user needs to change default COM initialization model,
199//it can define BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL to one of these:
200//
201// COINIT_APARTMENTTHREADED_BIPC
202// COINIT_MULTITHREADED_BIPC
203// COINIT_DISABLE_OLE1DDE_BIPC
204// COINIT_SPEED_OVER_MEMORY_BIPC
205#if !defined(BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL)
206 #define BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL COINIT_APARTMENTTHREADED_BIPC
207#elif (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_APARTMENTTHREADED_BIPC) &&\
208 (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_MULTITHREADED_BIPC) &&\
209 (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_DISABLE_OLE1DDE_BIPC) &&\
210 (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_SPEED_OVER_MEMORY_BIPC)
211 #error "Wrong value for BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL macro"
212#endif
213
214} //namespace winapi {
215} //namespace interprocess {
216} //namespace boost {
217
218
219namespace boost {
220namespace interprocess {
221namespace winapi {
222
223struct GUID_BIPC
224{
225 unsigned long Data1;
226 unsigned short Data2;
227 unsigned short Data3;
228 unsigned char Data4[8];
229};
230
231const GUID_BIPC CLSID_WbemAdministrativeLocator =
232 { 0xcb8555cc, 0x9128, 0x11d1, {0xad, 0x9b, 0x00, 0xc0, 0x4f, 0xd8, 0xfd, 0xff}};
233
234const GUID_BIPC IID_IUnknown = { 0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
235
236struct wchar_variant
237{
238 unsigned long long dummy;
239 union value_t{
240 wchar_t *pbstrVal;
241 unsigned long long dummy;
242 } value;
243};
244
245struct IUnknown_BIPC
246{
247 public:
248 virtual long __stdcall QueryInterface(
249 const GUID_BIPC &riid, // [in]
250 void **ppvObject) = 0; // [iid_is][out]
251
252 virtual unsigned long __stdcall AddRef (void) = 0;
253 virtual unsigned long __stdcall Release(void) = 0;
254};
255
256struct IWbemClassObject_BIPC : public IUnknown_BIPC
257{
258 public:
259 virtual long __stdcall GetQualifierSet(
260 /* [out] */ void **ppQualSet) = 0;
261
262 virtual long __stdcall Get(
263 /* [string][in] */ const wchar_t * wszName,
264 /* [in] */ long lFlags,
265 /* [unique][in][out] */ wchar_variant *pVal,
266 /* [unique][in][out] */ long *pType,
267 /* [unique][in][out] */ long *plFlavor) = 0;
268
269 virtual long __stdcall Put(
270 /* [string][in] */ const wchar_t * wszName,
271 /* [in] */ long lFlags,
272 /* [in] */ wchar_variant *pVal,
273 /* [in] */ long Type) = 0;
274
275 virtual long __stdcall Delete(
276 /* [string][in] */ const wchar_t * wszName) = 0;
277
278 virtual long __stdcall GetNames(
279 /* [string][in] */ const wchar_t * wszQualifierName,
280 /* [in] */ long lFlags,
281 /* [in] */ wchar_variant *pQualifierVal,
282 /* [out] */ void * *pNames) = 0;
283
284 virtual long __stdcall BeginEnumeration(
285 /* [in] */ long lEnumFlags) = 0;
286
287 virtual long __stdcall Next(
288 /* [in] */ long lFlags,
289 /* [unique][in][out] */ wchar_t * *strName,
290 /* [unique][in][out] */ wchar_variant *pVal,
291 /* [unique][in][out] */ long *pType,
292 /* [unique][in][out] */ long *plFlavor) = 0;
293
294 virtual long __stdcall EndEnumeration( void) = 0;
295
296 virtual long __stdcall GetPropertyQualifierSet(
297 /* [string][in] */ const wchar_t * wszProperty,
298 /* [out] */ void **ppQualSet) = 0;
299
300 virtual long __stdcall Clone(
301 /* [out] */ IWbemClassObject_BIPC **ppCopy) = 0;
302
303 virtual long __stdcall GetObjectText(
304 /* [in] */ long lFlags,
305 /* [out] */ wchar_t * *pstrObjectText) = 0;
306
307 virtual long __stdcall SpawnDerivedClass(
308 /* [in] */ long lFlags,
309 /* [out] */ IWbemClassObject_BIPC **ppNewClass) = 0;
310
311 virtual long __stdcall SpawnInstance(
312 /* [in] */ long lFlags,
313 /* [out] */ IWbemClassObject_BIPC **ppNewInstance) = 0;
314
315 virtual long __stdcall CompareTo(
316 /* [in] */ long lFlags,
317 /* [in] */ IWbemClassObject_BIPC *pCompareTo) = 0;
318
319 virtual long __stdcall GetPropertyOrigin(
320 /* [string][in] */ const wchar_t * wszName,
321 /* [out] */ wchar_t * *pstrClassName) = 0;
322
323 virtual long __stdcall InheritsFrom(
324 /* [in] */ const wchar_t * strAncestor) = 0;
325
326 virtual long __stdcall GetMethod(
327 /* [string][in] */ const wchar_t * wszName,
328 /* [in] */ long lFlags,
329 /* [out] */ IWbemClassObject_BIPC **ppInSignature,
330 /* [out] */ IWbemClassObject_BIPC **ppOutSignature) = 0;
331
332 virtual long __stdcall PutMethod(
333 /* [string][in] */ const wchar_t * wszName,
334 /* [in] */ long lFlags,
335 /* [in] */ IWbemClassObject_BIPC *pInSignature,
336 /* [in] */ IWbemClassObject_BIPC *pOutSignature) = 0;
337
338 virtual long __stdcall DeleteMethod(
339 /* [string][in] */ const wchar_t * wszName) = 0;
340
341 virtual long __stdcall BeginMethodEnumeration(
342 /* [in] */ long lEnumFlags) = 0;
343
344 virtual long __stdcall NextMethod(
345 /* [in] */ long lFlags,
346 /* [unique][in][out] */ wchar_t * *pstrName,
347 /* [unique][in][out] */ IWbemClassObject_BIPC **ppInSignature,
348 /* [unique][in][out] */ IWbemClassObject_BIPC **ppOutSignature) = 0;
349
350 virtual long __stdcall EndMethodEnumeration( void) = 0;
351
352 virtual long __stdcall GetMethodQualifierSet(
353 /* [string][in] */ const wchar_t * wszMethod,
354 /* [out] */ void **ppQualSet) = 0;
355
356 virtual long __stdcall GetMethodOrigin(
357 /* [string][in] */ const wchar_t * wszMethodName,
358 /* [out] */ wchar_t * *pstrClassName) = 0;
359
360};
361
362struct IWbemContext_BIPC : public IUnknown_BIPC
363{
364public:
365 virtual long __stdcall Clone(
366 /* [out] */ IWbemContext_BIPC **ppNewCopy) = 0;
367
368 virtual long __stdcall GetNames(
369 /* [in] */ long lFlags,
370 /* [out] */ void * *pNames) = 0;
371
372 virtual long __stdcall BeginEnumeration(
373 /* [in] */ long lFlags) = 0;
374
375 virtual long __stdcall Next(
376 /* [in] */ long lFlags,
377 /* [out] */ wchar_t * *pstrName,
378 /* [out] */ wchar_variant *pValue) = 0;
379
380 virtual long __stdcall EndEnumeration( void) = 0;
381
382 virtual long __stdcall SetValue(
383 /* [string][in] */ const wchar_t * wszName,
384 /* [in] */ long lFlags,
385 /* [in] */ wchar_variant *pValue) = 0;
386
387 virtual long __stdcall GetValue(
388 /* [string][in] */ const wchar_t * wszName,
389 /* [in] */ long lFlags,
390 /* [out] */ wchar_variant *pValue) = 0;
391
392 virtual long __stdcall DeleteValue(
393 /* [string][in] */ const wchar_t * wszName,
394 /* [in] */ long lFlags) = 0;
395
396 virtual long __stdcall DeleteAll( void) = 0;
397
398};
399
400
401struct IEnumWbemClassObject_BIPC : public IUnknown_BIPC
402{
403public:
404 virtual long __stdcall Reset( void) = 0;
405
406 virtual long __stdcall Next(
407 /* [in] */ long lTimeout,
408 /* [in] */ unsigned long uCount,
409 /* [length_is][size_is][out] */ IWbemClassObject_BIPC **apObjects,
410 /* [out] */ unsigned long *puReturned) = 0;
411
412 virtual long __stdcall NextAsync(
413 /* [in] */ unsigned long uCount,
414 /* [in] */ void *pSink) = 0;
415
416 virtual long __stdcall Clone(
417 /* [out] */ void **ppEnum) = 0;
418
419 virtual long __stdcall Skip(
420 /* [in] */ long lTimeout,
421 /* [in] */ unsigned long nCount) = 0;
422
423};
424
425struct IWbemServices_BIPC : public IUnknown_BIPC
426{
427public:
428 virtual long __stdcall OpenNamespace(
429 /* [in] */ const wchar_t * strNamespace,
430 /* [in] */ long lFlags,
431 /* [in] */ void *pCtx,
432 /* [unique][in][out] */ void **ppWorkingNamespace,
433 /* [unique][in][out] */ void **ppResult) = 0;
434
435 virtual long __stdcall CancelAsyncCall(
436 /* [in] */ void *pSink) = 0;
437
438 virtual long __stdcall QueryObjectSink(
439 /* [in] */ long lFlags,
440 /* [out] */ void **ppResponseHandler) = 0;
441
442 virtual long __stdcall GetObject(
443 /* [in] */ const wchar_t * strObjectPath,
444 /* [in] */ long lFlags,
445 /* [in] */ void *pCtx,
446 /* [unique][in][out] */ void **ppObject,
447 /* [unique][in][out] */ void **ppCallResult) = 0;
448
449 virtual long __stdcall GetObjectAsync(
450 /* [in] */ const wchar_t * strObjectPath,
451 /* [in] */ long lFlags,
452 /* [in] */ void *pCtx,
453 /* [in] */ void *pResponseHandler) = 0;
454
455 virtual long __stdcall PutClass(
456 /* [in] */ IWbemClassObject_BIPC *pObject,
457 /* [in] */ long lFlags,
458 /* [in] */ void *pCtx,
459 /* [unique][in][out] */ void **ppCallResult) = 0;
460
461 virtual long __stdcall PutClassAsync(
462 /* [in] */ IWbemClassObject_BIPC *pObject,
463 /* [in] */ long lFlags,
464 /* [in] */ void *pCtx,
465 /* [in] */ void *pResponseHandler) = 0;
466
467 virtual long __stdcall DeleteClass(
468 /* [in] */ const wchar_t * strClass,
469 /* [in] */ long lFlags,
470 /* [in] */ void *pCtx,
471 /* [unique][in][out] */ void **ppCallResult) = 0;
472
473 virtual long __stdcall DeleteClassAsync(
474 /* [in] */ const wchar_t * strClass,
475 /* [in] */ long lFlags,
476 /* [in] */ void *pCtx,
477 /* [in] */ void *pResponseHandler) = 0;
478
479 virtual long __stdcall CreateClassEnum(
480 /* [in] */ const wchar_t * strSuperclass,
481 /* [in] */ long lFlags,
482 /* [in] */ void *pCtx,
483 /* [out] */ void **ppEnum) = 0;
484
485 virtual long __stdcall CreateClassEnumAsync(
486 /* [in] */ const wchar_t * strSuperclass,
487 /* [in] */ long lFlags,
488 /* [in] */ void *pCtx,
489 /* [in] */ void *pResponseHandler) = 0;
490
491 virtual long __stdcall PutInstance(
492 /* [in] */ void *pInst,
493 /* [in] */ long lFlags,
494 /* [in] */ void *pCtx,
495 /* [unique][in][out] */ void **ppCallResult) = 0;
496
497 virtual long __stdcall PutInstanceAsync(
498 /* [in] */ void *pInst,
499 /* [in] */ long lFlags,
500 /* [in] */ void *pCtx,
501 /* [in] */ void *pResponseHandler) = 0;
502
503 virtual long __stdcall DeleteInstance(
504 /* [in] */ const wchar_t * strObjectPath,
505 /* [in] */ long lFlags,
506 /* [in] */ void *pCtx,
507 /* [unique][in][out] */ void **ppCallResult) = 0;
508
509 virtual long __stdcall DeleteInstanceAsync(
510 /* [in] */ const wchar_t * strObjectPath,
511 /* [in] */ long lFlags,
512 /* [in] */ void *pCtx,
513 /* [in] */ void *pResponseHandler) = 0;
514
515 virtual long __stdcall CreateInstanceEnum(
516 /* [in] */ const wchar_t * strFilter,
517 /* [in] */ long lFlags,
518 /* [in] */ void *pCtx,
519 /* [out] */ void **ppEnum) = 0;
520
521 virtual long __stdcall CreateInstanceEnumAsync(
522 /* [in] */ const wchar_t * strFilter,
523 /* [in] */ long lFlags,
524 /* [in] */ void *pCtx,
525 /* [in] */ void *pResponseHandler) = 0;
526
527 virtual long __stdcall ExecQuery(
528 /* [in] */ const wchar_t * strQueryLanguage,
529 /* [in] */ const wchar_t * strQuery,
530 /* [in] */ long lFlags,
531 /* [in] */ IWbemContext_BIPC *pCtx,
532 /* [out] */ IEnumWbemClassObject_BIPC **ppEnum) = 0;
533
534 virtual long __stdcall ExecQueryAsync(
535 /* [in] */ const wchar_t * strQueryLanguage,
536 /* [in] */ const wchar_t * strQuery,
537 /* [in] */ long lFlags,
538 /* [in] */ IWbemContext_BIPC *pCtx,
539 /* [in] */ void *pResponseHandler) = 0;
540
541 virtual long __stdcall ExecNotificationQuery(
542 /* [in] */ const wchar_t * strQueryLanguage,
543 /* [in] */ const wchar_t * strQuery,
544 /* [in] */ long lFlags,
545 /* [in] */ IWbemContext_BIPC *pCtx,
546 /* [out] */ void **ppEnum) = 0;
547
548 virtual long __stdcall ExecNotificationQueryAsync(
549 /* [in] */ const wchar_t * strQueryLanguage,
550 /* [in] */ const wchar_t * strQuery,
551 /* [in] */ long lFlags,
552 /* [in] */ IWbemContext_BIPC *pCtx,
553 /* [in] */ void *pResponseHandler) = 0;
554
555 virtual long __stdcall ExecMethod(
556 /* [in] */ const wchar_t * strObjectPath,
557 /* [in] */ const wchar_t * strMethodName,
558 /* [in] */ long lFlags,
559 /* [in] */ IWbemContext_BIPC *pCtx,
560 /* [in] */ IWbemClassObject_BIPC *pInParams,
561 /* [unique][in][out] */ IWbemClassObject_BIPC **ppOutParams,
562 /* [unique][in][out] */ void **ppCallResult) = 0;
563
564 virtual long __stdcall ExecMethodAsync(
565 /* [in] */ const wchar_t * strObjectPath,
566 /* [in] */ const wchar_t * strMethodName,
567 /* [in] */ long lFlags,
568 /* [in] */ IWbemContext_BIPC *pCtx,
569 /* [in] */ IWbemClassObject_BIPC *pInParams,
570 /* [in] */ void *pResponseHandler) = 0;
571
572};
573
574struct IWbemLocator_BIPC : public IUnknown_BIPC
575{
576public:
577 virtual long __stdcall ConnectServer(
578 /* [in] */ const wchar_t * strNetworkResource,
579 /* [in] */ const wchar_t * strUser,
580 /* [in] */ const wchar_t * strPassword,
581 /* [in] */ const wchar_t * strLocale,
582 /* [in] */ long lSecurityFlags,
583 /* [in] */ const wchar_t * strAuthority,
584 /* [in] */ void *pCtx,
585 /* [out] */ IWbemServices_BIPC **ppNamespace) = 0;
586
587};
588
589struct interprocess_overlapped
590{
591 unsigned long *internal;
592 unsigned long *internal_high;
593 union {
594 struct {
595 unsigned long offset;
596 unsigned long offset_high;
597 }dummy;
598 void *pointer;
599 };
600
601 void *h_event;
602};
603
604struct interprocess_semaphore_basic_information
605{
606 unsigned int count; // current semaphore count
607 unsigned int limit; // max semaphore count
608};
609
610struct interprocess_section_basic_information
611{
612 void * base_address;
613 unsigned long section_attributes;
614 __int64 section_size;
615};
616
617struct interprocess_filetime
618{
619 unsigned long dwLowDateTime;
620 unsigned long dwHighDateTime;
621};
622
623struct win32_find_data_t
624{
625 unsigned long dwFileAttributes;
626 interprocess_filetime ftCreationTime;
627 interprocess_filetime ftLastAccessTime;
628 interprocess_filetime ftLastWriteTime;
629 unsigned long nFileSizeHigh;
630 unsigned long nFileSizeLow;
631 unsigned long dwReserved0;
632 unsigned long dwReserved1;
633 char cFileName[MaxPath];
634 char cAlternateFileName[14];
635};
636
637struct interprocess_security_attributes
638{
639 unsigned long nLength;
640 void *lpSecurityDescriptor;
641 int bInheritHandle;
642};
643
644struct system_info {
645 union {
646 unsigned long dwOemId; // Obsolete field...do not use
647 struct {
648 unsigned short wProcessorArchitecture;
649 unsigned short wReserved;
650 } dummy;
651 };
652 unsigned long dwPageSize;
653 void * lpMinimumApplicationAddress;
654 void * lpMaximumApplicationAddress;
655 unsigned long * dwActiveProcessorMask;
656 unsigned long dwNumberOfProcessors;
657 unsigned long dwProcessorType;
658 unsigned long dwAllocationGranularity;
659 unsigned short wProcessorLevel;
660 unsigned short wProcessorRevision;
661};
662
663struct interprocess_memory_basic_information
664{
665 void * BaseAddress;
666 void * AllocationBase;
667 unsigned long AllocationProtect;
668 unsigned long RegionSize;
669 unsigned long State;
670 unsigned long Protect;
671 unsigned long Type;
672};
673
674struct interprocess_acl
675{
676 unsigned char AclRevision;
677 unsigned char Sbz1;
678 unsigned short AclSize;
679 unsigned short AceCount;
680 unsigned short Sbz2;
681};
682
683typedef struct _interprocess_security_descriptor
684{
685 unsigned char Revision;
686 unsigned char Sbz1;
687 unsigned short Control;
688 void *Owner;
689 void *Group;
690 interprocess_acl *Sacl;
691 interprocess_acl *Dacl;
692} interprocess_security_descriptor;
693
694enum file_information_class_t {
695 file_directory_information = 1,
696 file_full_directory_information,
697 file_both_directory_information,
698 file_basic_information,
699 file_standard_information,
700 file_internal_information,
701 file_ea_information,
702 file_access_information,
703 file_name_information,
704 file_rename_information,
705 file_link_information,
706 file_names_information,
707 file_disposition_information,
708 file_position_information,
709 file_full_ea_information,
710 file_mode_information,
711 file_alignment_information,
712 file_all_information,
713 file_allocation_information,
714 file_end_of_file_information,
715 file_alternate_name_information,
716 file_stream_information,
717 file_pipe_information,
718 file_pipe_local_information,
719 file_pipe_remote_information,
720 file_mailslot_query_information,
721 file_mailslot_set_information,
722 file_compression_information,
723 file_copy_on_write_information,
724 file_completion_information,
725 file_move_cluster_information,
726 file_quota_information,
727 file_reparse_point_information,
728 file_network_open_information,
729 file_object_id_information,
730 file_tracking_information,
731 file_ole_directory_information,
732 file_content_index_information,
733 file_inherit_content_index_information,
734 file_ole_information,
735 file_maximum_information
736};
737
738enum semaphore_information_class {
739 semaphore_basic_information = 0
740};
741
742struct file_name_information_t {
743 unsigned long FileNameLength;
744 wchar_t FileName[1];
745};
746
747struct file_rename_information_t {
748 int Replace;
749 void *RootDir;
750 unsigned long FileNameLength;
751 wchar_t FileName[1];
752};
753
754struct unicode_string_t {
755 unsigned short Length;
756 unsigned short MaximumLength;
757 wchar_t *Buffer;
758};
759
760struct object_attributes_t {
761 unsigned long Length;
762 void * RootDirectory;
763 unicode_string_t *ObjectName;
764 unsigned long Attributes;
765 void *SecurityDescriptor;
766 void *SecurityQualityOfService;
767};
768
769struct io_status_block_t {
770 union {
771 long Status;
772 void *Pointer;
773 };
774
775 unsigned long *Information;
776};
777
778union system_timeofday_information
779{
780 struct data_t
781 {
782 __int64 liKeBootTime;
783 __int64 liKeSystemTime;
784 __int64 liExpTimeZoneBias;
785 unsigned long uCurrentTimeZoneId;
786 unsigned long dwReserved;
787 } data;
788 unsigned char Reserved1[SystemTimeOfDayInfoLength];
789};
790
791struct interprocess_by_handle_file_information
792{
793 unsigned long dwFileAttributes;
794 interprocess_filetime ftCreationTime;
795 interprocess_filetime ftLastAccessTime;
796 interprocess_filetime ftLastWriteTime;
797 unsigned long dwVolumeSerialNumber;
798 unsigned long nFileSizeHigh;
799 unsigned long nFileSizeLow;
800 unsigned long nNumberOfLinks;
801 unsigned long nFileIndexHigh;
802 unsigned long nFileIndexLow;
803};
804
805enum system_information_class {
806 system_basic_information = 0,
807 system_performance_information = 2,
808 system_time_of_day_information = 3,
809 system_process_information = 5,
810 system_processor_performance_information = 8,
811 system_interrupt_information = 23,
812 system_exception_information = 33,
813 system_registry_quota_information = 37,
814 system_lookaside_information = 45
815};
816
817enum object_information_class
818{
819 object_basic_information,
820 object_name_information,
821 object_type_information,
822 object_all_information,
823 object_data_information
824};
825
826enum section_information_class
827{
828 section_basic_information,
829 section_image_information
830};
831
832struct object_name_information_t
833{
834 unicode_string_t Name;
835 wchar_t NameBuffer[1];
836};
837
838//Some windows API declarations
839extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
840extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
841extern "C" __declspec(dllimport) int __stdcall GetProcessTimes
842 ( void *hProcess, interprocess_filetime* lpCreationTime
843 , interprocess_filetime *lpExitTime,interprocess_filetime *lpKernelTime
844 , interprocess_filetime *lpUserTime );
845extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
846extern "C" __declspec(dllimport) int __stdcall SwitchToThread();
847extern "C" __declspec(dllimport) unsigned long __stdcall GetLastError();
848extern "C" __declspec(dllimport) void __stdcall SetLastError(unsigned long);
849extern "C" __declspec(dllimport) void * __stdcall GetCurrentProcess();
850extern "C" __declspec(dllimport) int __stdcall CloseHandle(void*);
851extern "C" __declspec(dllimport) int __stdcall DuplicateHandle
852 ( void *hSourceProcessHandle, void *hSourceHandle
853 , void *hTargetProcessHandle, void **lpTargetHandle
854 , unsigned long dwDesiredAccess, int bInheritHandle
855 , unsigned long dwOptions);
856extern "C" __declspec(dllimport) long __stdcall GetFileType(void *hFile);
857extern "C" __declspec(dllimport) void *__stdcall FindFirstFileA(const char *lpFileName, win32_find_data_t *lpFindFileData);
858extern "C" __declspec(dllimport) int __stdcall FindNextFileA(void *hFindFile, win32_find_data_t *lpFindFileData);
859extern "C" __declspec(dllimport) int __stdcall FindClose(void *hFindFile);
860//extern "C" __declspec(dllimport) void __stdcall GetSystemTimeAsFileTime(interprocess_filetime*);
861//extern "C" __declspec(dllimport) int __stdcall FileTimeToLocalFileTime(const interprocess_filetime *in, const interprocess_filetime *out);
862extern "C" __declspec(dllimport) void * __stdcall CreateMutexA(interprocess_security_attributes*, int, const char *);
863extern "C" __declspec(dllimport) void * __stdcall OpenMutexA(unsigned long, int, const char *);
864extern "C" __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void *, unsigned long);
865extern "C" __declspec(dllimport) int __stdcall ReleaseMutex(void *);
866extern "C" __declspec(dllimport) int __stdcall UnmapViewOfFile(void *);
867extern "C" __declspec(dllimport) void * __stdcall CreateSemaphoreA(interprocess_security_attributes*, long, long, const char *);
868extern "C" __declspec(dllimport) int __stdcall ReleaseSemaphore(void *, long, long *);
869extern "C" __declspec(dllimport) void * __stdcall OpenSemaphoreA(unsigned long, int, const char *);
870extern "C" __declspec(dllimport) void * __stdcall CreateFileMappingA (void *, interprocess_security_attributes*, unsigned long, unsigned long, unsigned long, const char *);
871extern "C" __declspec(dllimport) void * __stdcall MapViewOfFileEx (void *, unsigned long, unsigned long, unsigned long, std::size_t, void*);
872extern "C" __declspec(dllimport) void * __stdcall OpenFileMappingA (unsigned long, int, const char *);
873extern "C" __declspec(dllimport) void * __stdcall CreateFileA (const char *, unsigned long, unsigned long, struct interprocess_security_attributes*, unsigned long, unsigned long, void *);
874extern "C" __declspec(dllimport) void * __stdcall CreateFileW (const wchar_t *, unsigned long, unsigned long, struct interprocess_security_attributes*, unsigned long, unsigned long, void *);
875extern "C" __declspec(dllimport) int __stdcall DeleteFileA (const char *);
876extern "C" __declspec(dllimport) int __stdcall MoveFileExA (const char *, const char *, unsigned long);
877extern "C" __declspec(dllimport) void __stdcall GetSystemInfo (struct system_info *);
878extern "C" __declspec(dllimport) int __stdcall FlushViewOfFile (void *, std::size_t);
879extern "C" __declspec(dllimport) int __stdcall VirtualUnlock (void *, std::size_t);
880extern "C" __declspec(dllimport) int __stdcall VirtualProtect (void *, std::size_t, unsigned long, unsigned long *);
881extern "C" __declspec(dllimport) int __stdcall FlushFileBuffers (void *);
882extern "C" __declspec(dllimport) int __stdcall GetFileSizeEx (void *, __int64 *size);
883extern "C" __declspec(dllimport) unsigned long __stdcall FormatMessageA
884 (unsigned long dwFlags, const void *lpSource, unsigned long dwMessageId,
885 unsigned long dwLanguageId, char *lpBuffer, unsigned long nSize,
886 std::va_list *Arguments);
887extern "C" __declspec(dllimport) void *__stdcall LocalFree (void *);
888extern "C" __declspec(dllimport) unsigned long __stdcall GetFileAttributesA(const char *);
889extern "C" __declspec(dllimport) int __stdcall CreateDirectoryA(const char *, interprocess_security_attributes*);
890extern "C" __declspec(dllimport) int __stdcall RemoveDirectoryA(const char *lpPathName);
891extern "C" __declspec(dllimport) int __stdcall GetTempPathA(unsigned long length, char *buffer);
892extern "C" __declspec(dllimport) int __stdcall CreateDirectory(const char *, interprocess_security_attributes*);
893extern "C" __declspec(dllimport) int __stdcall SetFileValidData(void *, __int64 size);
894extern "C" __declspec(dllimport) int __stdcall SetEndOfFile(void *);
895extern "C" __declspec(dllimport) int __stdcall SetFilePointerEx(void *, __int64 distance, __int64 *new_file_pointer, unsigned long move_method);
896extern "C" __declspec(dllimport) int __stdcall LockFile (void *hnd, unsigned long offset_low, unsigned long offset_high, unsigned long size_low, unsigned long size_high);
897extern "C" __declspec(dllimport) int __stdcall UnlockFile(void *hnd, unsigned long offset_low, unsigned long offset_high, unsigned long size_low, unsigned long size_high);
898extern "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);
899extern "C" __declspec(dllimport) int __stdcall UnlockFileEx(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
900extern "C" __declspec(dllimport) int __stdcall WriteFile(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped);
901extern "C" __declspec(dllimport) int __stdcall ReadFile(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped);
902extern "C" __declspec(dllimport) int __stdcall InitializeSecurityDescriptor(interprocess_security_descriptor *pSecurityDescriptor, unsigned long dwRevision);
903extern "C" __declspec(dllimport) int __stdcall SetSecurityDescriptorDacl(interprocess_security_descriptor *pSecurityDescriptor, int bDaclPresent, interprocess_acl *pDacl, int bDaclDefaulted);
904extern "C" __declspec(dllimport) void *__stdcall LoadLibraryA(const char *);
905extern "C" __declspec(dllimport) int __stdcall FreeLibrary(void *);
906extern "C" __declspec(dllimport) void *__stdcall GetProcAddress(void *, const char*);
907extern "C" __declspec(dllimport) void *__stdcall GetModuleHandleA(const char*);
908extern "C" __declspec(dllimport) void *__stdcall GetFileInformationByHandle(void *, interprocess_by_handle_file_information*);
909extern "C" __declspec(dllimport) unsigned long __stdcall GetMappedFileNameW(void *, void *, wchar_t *, unsigned long);
910extern "C" __declspec(dllimport) long __stdcall RegOpenKeyExA(void *, const char *, unsigned long, unsigned long, void **);
911extern "C" __declspec(dllimport) long __stdcall RegQueryValueExA(void *, const char *, unsigned long*, unsigned long*, unsigned char *, unsigned long*);
912extern "C" __declspec(dllimport) long __stdcall RegCloseKey(void *);
913extern "C" __declspec(dllimport) int __stdcall QueryPerformanceCounter(__int64 *lpPerformanceCount);
914
915//COM API
916extern "C" __declspec(dllimport) long __stdcall CoInitializeEx(void *pvReserved, unsigned long dwCoInit);
917extern "C" __declspec(dllimport) long __stdcall CoInitializeSecurity(
918 void* pSecDesc,
919 long cAuthSvc,
920 void * asAuthSvc,
921 void *pReserved1,
922 unsigned long dwAuthnLevel,
923 unsigned long dwImpLevel,
924 void *pAuthList,
925 unsigned long dwCapabilities,
926 void *pReserved3 );
927
928 extern "C" __declspec(dllimport) long __stdcall CoSetProxyBlanket(
929 IUnknown_BIPC *pProxy,
930 unsigned long dwAuthnSvc,
931 unsigned long dwAuthzSvc,
932 wchar_t *pServerPrincName,
933 unsigned long dwAuthnLevel,
934 unsigned long dwImpLevel,
935 void *pAuthInfo,
936 unsigned long dwCapabilities);
937
938extern "C" __declspec(dllimport) long __stdcall VariantClear(wchar_variant * pvarg);
939extern "C" __declspec(dllimport) long __stdcall CoCreateInstance(const GUID_BIPC & rclsid, IUnknown_BIPC *pUnkOuter,
940 unsigned long dwClsContext, const GUID_BIPC & riid, void** ppv);
941extern "C" __declspec(dllimport) void __stdcall CoUninitialize(void);
942
943
944
945//API function typedefs
946//Pointer to functions
947typedef long (__stdcall *NtDeleteFile_t)(object_attributes_t *ObjectAttributes);
948typedef long (__stdcall *NtSetInformationFile_t)(void *FileHandle, io_status_block_t *IoStatusBlock, void *FileInformation, unsigned long Length, int FileInformationClass );
949typedef long (__stdcall *NtOpenFile)(void **FileHandle, unsigned long DesiredAccess, object_attributes_t *ObjectAttributes
950 , io_status_block_t *IoStatusBlock, unsigned long ShareAccess, unsigned long Length, unsigned long OpenOptions);
951typedef long (__stdcall *NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
952typedef long (__stdcall *NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
953typedef long (__stdcall *NtQuerySemaphore_t)(void*, unsigned int info_class, interprocess_semaphore_basic_information *pinfo, unsigned int info_size, unsigned int *ret_len);
954typedef long (__stdcall *NtQuerySection_t)(void*, section_information_class, interprocess_section_basic_information *pinfo, unsigned long info_size, unsigned long *ret_len);
955typedef long (__stdcall *NtQueryInformationFile_t)(void *,io_status_block_t *,void *, long, int);
956typedef long (__stdcall *NtOpenFile_t)(void*,unsigned long ,object_attributes_t*,io_status_block_t*,unsigned long,unsigned long);
957typedef long (__stdcall *NtClose_t) (void*);
958typedef long (__stdcall *RtlCreateUnicodeStringFromAsciiz_t)(unicode_string_t *, const char *);
959typedef void (__stdcall *RtlFreeUnicodeString_t)(unicode_string_t *);
960typedef void (__stdcall *RtlInitUnicodeString_t)( unicode_string_t *, const wchar_t * );
961typedef long (__stdcall *RtlAppendUnicodeToString_t)(unicode_string_t *Destination, const wchar_t *Source);
962typedef unsigned long (__stdcall * GetMappedFileName_t)(void *, void *, wchar_t *, unsigned long);
963typedef long (__stdcall * RegOpenKeyEx_t)(void *, const char *, unsigned long, unsigned long, void **);
964typedef long (__stdcall * RegQueryValueEx_t)(void *, const char *, unsigned long*, unsigned long*, unsigned char *, unsigned long*);
965typedef long (__stdcall * RegCloseKey_t)(void *);
966
967} //namespace winapi {
968} //namespace interprocess {
969} //namespace boost {
970
971namespace boost {
972namespace interprocess {
973namespace winapi {
974
975inline unsigned long get_last_error()
976{ return GetLastError(); }
977
978inline void set_last_error(unsigned long err)
979{ return SetLastError(err); }
980
981inline unsigned long format_message
982 (unsigned long dwFlags, const void *lpSource,
983 unsigned long dwMessageId, unsigned long dwLanguageId,
984 char *lpBuffer, unsigned long nSize, std::va_list *Arguments)
985{
986 return FormatMessageA
987 (dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments);
988}
989
990//And now, wrapper functions
991inline void * local_free(void *hmem)
992{ return LocalFree(hmem); }
993
994inline unsigned long make_lang_id(unsigned long p, unsigned long s)
995{ return ((((unsigned short)(s)) << 10) | (unsigned short)(p)); }
996
997inline void sched_yield()
998{
999 if(!SwitchToThread()){
1000 Sleep(1);
1001 }
1002}
1003
1004inline void sleep(unsigned long ms)
1005{ Sleep(ms); }
1006
1007inline unsigned long get_current_thread_id()
1008{ return GetCurrentThreadId(); }
1009
1010inline bool get_process_times
1011 ( void *hProcess, interprocess_filetime* lpCreationTime
1012 , interprocess_filetime *lpExitTime, interprocess_filetime *lpKernelTime
1013 , interprocess_filetime *lpUserTime )
1014{ return 0 != GetProcessTimes(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime); }
1015
1016inline unsigned long get_current_process_id()
1017{ return GetCurrentProcessId(); }
1018
1019inline unsigned int close_handle(void* handle)
1020{ return CloseHandle(handle); }
1021
1022inline void * find_first_file(const char *lpFileName, win32_find_data_t *lpFindFileData)
1023{ return FindFirstFileA(lpFileName, lpFindFileData); }
1024
1025inline bool find_next_file(void *hFindFile, win32_find_data_t *lpFindFileData)
1026{ return FindNextFileA(hFindFile, lpFindFileData) != 0; }
1027
1028inline bool find_close(void *handle)
1029{ return FindClose(handle) != 0; }
1030
1031inline bool duplicate_current_process_handle
1032 (void *hSourceHandle, void **lpTargetHandle)
1033{
1034 return 0 != DuplicateHandle
1035 ( GetCurrentProcess(), hSourceHandle, GetCurrentProcess()
1036 , lpTargetHandle, 0, 0
1037 , duplicate_same_access);
1038}
1039
1040inline unsigned long get_file_type(void *hFile)
1041{
1042 return GetFileType(hFile);
1043}
1044
1045/*
1046inline void get_system_time_as_file_time(interprocess_filetime *filetime)
1047{ GetSystemTimeAsFileTime(filetime); }
1048
1049inline bool file_time_to_local_file_time
1050 (const interprocess_filetime *in, const interprocess_filetime *out)
1051{ return 0 != FileTimeToLocalFileTime(in, out); }
1052*/
1053inline void *open_or_create_mutex(const char *name, bool initial_owner, interprocess_security_attributes *attr)
1054{ return CreateMutexA(attr, (int)initial_owner, name); }
1055
1056inline unsigned long wait_for_single_object(void *handle, unsigned long time)
1057{ return WaitForSingleObject(handle, time); }
1058
1059inline int release_mutex(void *handle)
1060{ return ReleaseMutex(handle); }
1061
1062inline int unmap_view_of_file(void *address)
1063{ return UnmapViewOfFile(address); }
1064
1065inline void *open_or_create_semaphore(const char *name, long initial_count, long maximum_count, interprocess_security_attributes *attr)
1066{ return CreateSemaphoreA(attr, initial_count, maximum_count, name); }
1067
1068inline void *open_semaphore(const char *name)
1069{ return OpenSemaphoreA(semaphore_all_access, 0, name); }
1070
1071inline int release_semaphore(void *handle, long release_count, long *prev_count)
1072{ return ReleaseSemaphore(handle, release_count, prev_count); }
1073
1074class interprocess_all_access_security
1075{
1076 interprocess_security_attributes sa;
1077 interprocess_security_descriptor sd;
1078 bool initialized;
1079
1080 public:
1081 interprocess_all_access_security()
1082 : initialized(false)
1083 {
1084 if(!InitializeSecurityDescriptor(&sd, security_descriptor_revision))
1085 return;
1086 if(!SetSecurityDescriptorDacl(&sd, true, 0, false))
1087 return;
1088 sa.lpSecurityDescriptor = &sd;
1089 sa.nLength = sizeof(interprocess_security_attributes);
1090 sa.bInheritHandle = false;
1091 initialized = false;
1092 }
1093
1094 interprocess_security_attributes *get_attributes()
1095 { return &sa; }
1096};
1097
1098inline void * create_file_mapping (void * handle, unsigned long access, unsigned __int64 file_offset, const char * name, interprocess_security_attributes *psec)
1099{
1100 const unsigned long high_size(file_offset >> 32), low_size((boost::uint32_t)file_offset);
1101 return CreateFileMappingA (handle, psec, access, high_size, low_size, name);
1102}
1103
1104inline void * open_file_mapping (unsigned long access, const char *name)
1105{ return OpenFileMappingA (access, 0, name); }
1106
1107inline void *map_view_of_file_ex(void *handle, unsigned long file_access, unsigned __int64 offset, std::size_t numbytes, void *base_addr)
1108{
1109 const unsigned long offset_low = (unsigned long)(offset & ((unsigned __int64)0xFFFFFFFF));
1110 const unsigned long offset_high = offset >> 32;
1111 return MapViewOfFileEx(handle, file_access, offset_high, offset_low, numbytes, base_addr);
1112}
1113
1114inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes, interprocess_security_attributes *psec)
1115{
1116 for (unsigned int attempt(0); attempt < error_sharing_violation_tries; ++attempt){
1117 void * const handle = CreateFileA(name, access,
1118 file_share_read | file_share_write | file_share_delete,
1119 psec, creation_flags, attributes, 0);
1120 bool const invalid(invalid_handle_value == handle);
1121 if (!invalid){
1122 return handle;
1123 }
1124 if (error_sharing_violation != get_last_error()){
1125 return handle;
1126 }
1127 sleep(error_sharing_violation_sleep_ms);
1128 }
1129 return invalid_handle_value;
1130}
1131
1132inline bool delete_file(const char *name)
1133{ return 0 != DeleteFileA(name); }
1134
1135inline bool move_file_ex(const char *source_filename, const char *destination_filename, unsigned long flags)
1136{ return 0 != MoveFileExA(source_filename, destination_filename, flags); }
1137
1138inline void get_system_info(system_info *info)
1139{ GetSystemInfo(info); }
1140
1141inline bool flush_view_of_file(void *base_addr, std::size_t numbytes)
1142{ return 0 != FlushViewOfFile(base_addr, numbytes); }
1143
1144inline bool virtual_unlock(void *base_addr, std::size_t numbytes)
1145{ return 0 != VirtualUnlock(base_addr, numbytes); }
1146
1147inline bool virtual_protect(void *base_addr, std::size_t numbytes, unsigned long flNewProtect, unsigned long &lpflOldProtect)
1148{ return 0 != VirtualProtect(base_addr, numbytes, flNewProtect, &lpflOldProtect); }
1149
1150inline bool flush_file_buffers(void *handle)
1151{ return 0 != FlushFileBuffers(handle); }
1152
1153inline bool get_file_size(void *handle, __int64 &size)
1154{ return 0 != GetFileSizeEx(handle, &size); }
1155
1156inline bool create_directory(const char *name)
1157{
1158 interprocess_all_access_security sec;
1159 return 0 != CreateDirectoryA(name, sec.get_attributes());
1160}
1161
1162inline bool remove_directory(const char *lpPathName)
1163{ return 0 != RemoveDirectoryA(lpPathName); }
1164
1165inline unsigned long get_temp_path(unsigned long length, char *buffer)
1166{ return GetTempPathA(length, buffer); }
1167
1168inline int set_end_of_file(void *handle)
1169{ return 0 != SetEndOfFile(handle); }
1170
1171inline bool set_file_pointer_ex(void *handle, __int64 distance, __int64 *new_file_pointer, unsigned long move_method)
1172{ return 0 != SetFilePointerEx(handle, distance, new_file_pointer, move_method); }
1173
1174inline bool lock_file_ex(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped)
1175{ return 0 != LockFileEx(hnd, flags, reserved, size_low, size_high, overlapped); }
1176
1177inline bool unlock_file_ex(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped)
1178{ return 0 != UnlockFileEx(hnd, reserved, size_low, size_high, overlapped); }
1179
1180inline bool write_file(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped)
1181{ return 0 != WriteFile(hnd, buffer, bytes_to_write, bytes_written, overlapped); }
1182
1183inline bool read_file(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped)
1184{ return 0 != ReadFile(hnd, buffer, bytes_to_read, bytes_read, overlapped); }
1185
1186inline bool get_file_information_by_handle(void *hnd, interprocess_by_handle_file_information *info)
1187{ return 0 != GetFileInformationByHandle(hnd, info); }
1188
1189inline long interlocked_increment(long volatile *addr)
1190{ return BOOST_INTERLOCKED_INCREMENT(addr); }
1191
1192inline long interlocked_decrement(long volatile *addr)
1193{ return BOOST_INTERLOCKED_DECREMENT(addr); }
1194
1195inline long interlocked_compare_exchange(long volatile *addr, long val1, long val2)
1196{ return BOOST_INTERLOCKED_COMPARE_EXCHANGE(addr, val1, val2); }
1197
1198inline long interlocked_exchange_add(long volatile* addend, long value)
1199{ return BOOST_INTERLOCKED_EXCHANGE_ADD(const_cast<long*>(addend), value); }
1200
1201inline long interlocked_exchange(long volatile* addend, long value)
1202{ return BOOST_INTERLOCKED_EXCHANGE(const_cast<long*>(addend), value); }
1203
1204//Forward functions
1205inline void *load_library(const char *name)
1206{ return LoadLibraryA(name); }
1207
1208inline bool free_library(void *module)
1209{ return 0 != FreeLibrary(module); }
1210
1211inline void *get_proc_address(void *module, const char *name)
1212{ return GetProcAddress(module, name); }
1213
1214inline void *get_current_process()
1215{ return GetCurrentProcess(); }
1216
1217inline void *get_module_handle(const char *name)
1218{ return GetModuleHandleA(name); }
1219
1220inline unsigned long get_mapped_file_name(void *process, void *lpv, wchar_t *lpfilename, unsigned long nSize)
1221{ return GetMappedFileNameW(process, lpv, lpfilename, nSize); }
1222
1223inline long reg_open_key_ex(void *hKey, const char *lpSubKey, unsigned long ulOptions, unsigned long samDesired, void **phkResult)
1224{ return RegOpenKeyExA(hKey, lpSubKey, ulOptions, samDesired, phkResult); }
1225
1226inline long reg_query_value_ex(void *hKey, const char *lpValueName, unsigned long*lpReserved, unsigned long*lpType, unsigned char *lpData, unsigned long*lpcbData)
1227{ return RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); }
1228
1229inline long reg_close_key(void *hKey)
1230{ return RegCloseKey(hKey); }
1231
1232inline bool query_performance_counter(__int64 *lpPerformanceCount)
1233{
1234 return 0 != QueryPerformanceCounter(lpPerformanceCount);
1235}
1236
1237inline void initialize_object_attributes
1238( object_attributes_t *pobject_attr, unicode_string_t *name
1239 , unsigned long attr, void *rootdir, void *security_descr)
1240
1241{
1242 pobject_attr->Length = sizeof(object_attributes_t);
1243 pobject_attr->RootDirectory = rootdir;
1244 pobject_attr->Attributes = attr;
1245 pobject_attr->ObjectName = name;
1246 pobject_attr->SecurityDescriptor = security_descr;
1247 pobject_attr->SecurityQualityOfService = 0;
1248}
1249
1250inline void rtl_init_empty_unicode_string(unicode_string_t *ucStr, wchar_t *buf, unsigned short bufSize)
1251{
1252 ucStr->Buffer = buf;
1253 ucStr->Length = 0;
1254 ucStr->MaximumLength = bufSize;
1255}
1256
1257//A class that locates and caches loaded DLL function addresses.
1258template<int Dummy>
1259struct function_address_holder
1260{
1261 enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NtQuerySemaphore, NtQuerySection, NtOpenFile, NtClose, NumFunction };
1262 enum { NtDll_dll, NumModule };
1263
1264 private:
1265 static const char *FunctionNames[NumFunction];
1266 static const char *ModuleNames[NumModule];
1267 static void *FunctionAddresses[NumFunction];
1268 static unsigned int FunctionModules[NumFunction];
1269 static volatile long FunctionStates[NumFunction];
1270 static void *ModuleAddresses[NumModule];
1271 static volatile long ModuleStates[NumModule];
1272
1273 static void *get_module_from_id(unsigned int id)
1274 {
1275 assert(id < (unsigned int)NumModule);
1276 return get_module_handle(ModuleNames[id]);
1277 }
1278
1279 static void *get_module(const unsigned int id)
1280 {
1281 assert(id < (unsigned int)NumModule);
1282 while(ModuleStates[id] < 2){
1283 if(interlocked_compare_exchange(&ModuleStates[id], 1, 0) == 0){
1284 ModuleAddresses[id] = get_module_from_id(id);
1285 interlocked_increment(&ModuleStates[id]);
1286 break;
1287 }
1288 else{
1289 sched_yield();
1290 }
1291 }
1292 return ModuleAddresses[id];
1293 }
1294
1295 static void *get_address_from_dll(const unsigned int id)
1296 {
1297 assert(id < (unsigned int)NumFunction);
1298 return get_proc_address(get_module(FunctionModules[id]), FunctionNames[id]);
1299 }
1300
1301 public:
1302 static void *get(const unsigned int id)
1303 {
1304 assert(id < (unsigned int)NumFunction);
1305 while(FunctionStates[id] < 2){
1306 if(interlocked_compare_exchange(&FunctionStates[id], 1, 0) == 0){
1307 FunctionAddresses[id] = get_address_from_dll(id);
1308 interlocked_increment(&FunctionStates[id]);
1309 break;
1310 }
1311 else{
1312 sched_yield();
1313 }
1314 }
1315 return FunctionAddresses[id];
1316 }
1317};
1318
1319template<int Dummy>
1320const char *function_address_holder<Dummy>::FunctionNames[function_address_holder<Dummy>::NumFunction] =
1321{
1322 "NtSetInformationFile",
1323 "NtQuerySystemInformation",
1324 "NtQueryObject",
1325 "NtQuerySemaphore",
1326 "NtQuerySection",
1327 "NtOpenFile",
1328 "NtClose"
1329};
1330
1331template<int Dummy>
1332unsigned int function_address_holder<Dummy>::FunctionModules[function_address_holder<Dummy>::NumFunction] =
1333{
1334 NtDll_dll,
1335 NtDll_dll,
1336 NtDll_dll,
1337 NtDll_dll,
1338 NtDll_dll,
1339 NtDll_dll,
1340 NtDll_dll
1341};
1342
1343template<int Dummy>
1344const char *function_address_holder<Dummy>::ModuleNames[function_address_holder<Dummy>::NumModule] =
1345{
1346 "ntdll.dll"
1347};
1348
1349
1350template<int Dummy>
1351void *function_address_holder<Dummy>::FunctionAddresses[function_address_holder<Dummy>::NumFunction];
1352
1353template<int Dummy>
1354volatile long function_address_holder<Dummy>::FunctionStates[function_address_holder<Dummy>::NumFunction];
1355
1356template<int Dummy>
1357void *function_address_holder<Dummy>::ModuleAddresses[function_address_holder<Dummy>::NumModule];
1358
1359template<int Dummy>
1360volatile long function_address_holder<Dummy>::ModuleStates[function_address_holder<Dummy>::NumModule];
1361
1362
1363struct dll_func
1364 : public function_address_holder<0>
1365{};
1366
1367//Complex winapi based functions...
1368struct library_unloader
1369{
1370 void *lib_;
1371 library_unloader(void *module) : lib_(module){}
1372 ~library_unloader(){ free_library(lib_); }
1373};
1374
1375//pszFilename must have room for at least MaxPath+1 characters
1376inline bool get_file_name_from_handle_function
1377 (void * hFile, wchar_t *pszFilename, std::size_t length, std::size_t &out_length)
1378{
1379 if(length <= MaxPath){
1380 return false;
1381 }
1382
1383// void *hiPSAPI = load_library("PSAPI.DLL");
1384// if (0 == hiPSAPI)
1385// return 0;
1386// library_unloader unloader(hiPSAPI);
1387
1388// Pointer to function getMappedFileName() in PSAPI.DLL
1389// GetMappedFileName_t pfGMFN =
1390// (GetMappedFileName_t)get_proc_address(hiPSAPI, "GetMappedFileNameW");
1391// if (! pfGMFN){
1392// return 0; // Failed: unexpected error
1393// }
1394
1395 bool bSuccess = false;
1396
1397 // Create a file mapping object.
1398 void * hFileMap = create_file_mapping(hFile, page_readonly, 1, 0, 0);
1399 if(hFileMap){
1400 // Create a file mapping to get the file name.
1401 void* pMem = map_view_of_file_ex(hFileMap, file_map_read, 0, 1, 0);
1402
1403 if (pMem){
1404 //out_length = pfGMFN(get_current_process(), pMem, pszFilename, MaxPath);
1405 out_length = get_mapped_file_name(get_current_process(), pMem, pszFilename, MaxPath);
1406 if(out_length){
1407 bSuccess = true;
1408 }
1409 unmap_view_of_file(pMem);
1410 }
1411 close_handle(hFileMap);
1412 }
1413
1414 return(bSuccess);
1415}
1416
1417inline bool get_system_time_of_day_information(system_timeofday_information &info)
1418{
1419 NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t)
1420 dll_func::get(dll_func::NtQuerySystemInformation);
1421 unsigned long res;
1422 long status = pNtQuerySystemInformation(system_time_of_day_information, &info, sizeof(info), &res);
1423 if(status){
1424 return false;
1425 }
1426 return true;
1427}
1428
1429inline bool get_boot_time(unsigned char (&bootstamp) [BootstampLength])
1430{
1431 system_timeofday_information info;
1432 bool ret = get_system_time_of_day_information(info);
1433 if(!ret){
1434 return false;
1435 }
1436 std::memcpy(&bootstamp[0], &info.Reserved1, sizeof(bootstamp));
1437 return true;
1438}
1439
1440inline bool get_boot_and_system_time(unsigned char (&bootsystemstamp) [BootAndSystemstampLength])
1441{
1442 system_timeofday_information info;
1443 bool ret = get_system_time_of_day_information(info);
1444 if(!ret){
1445 return false;
1446 }
1447 std::memcpy(&bootsystemstamp[0], &info.Reserved1, sizeof(bootsystemstamp));
1448 return true;
1449}
1450
1451inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s) //will write BootstampLength chars
1452{
1453 if(s < (BootstampLength*2))
1454 return false;
1455 system_timeofday_information info;
1456 bool ret = get_system_time_of_day_information(info);
1457 if(!ret){
1458 return false;
1459 }
1460 const char Characters [] =
1461 { '0', '1', '2', '3', '4', '5', '6', '7'
1462 , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1463 std::size_t char_counter = 0;
1464 for(std::size_t i = 0; i != static_cast<std::size_t>(BootstampLength); ++i){
1465 bootstamp_str[char_counter++] = Characters[(info.Reserved1[i]&0xF0)>>4];
1466 bootstamp_str[char_counter++] = Characters[(info.Reserved1[i]&0x0F)];
1467 }
1468 s = BootstampLength*2;
1469 return true;
1470}
1471
1472//Writes the hexadecimal value of the buffer, in the wide character string.
1473//str must be twice length
1474inline void buffer_to_wide_str(const void *buf, std::size_t length, wchar_t *str)
1475{
1476 const wchar_t Characters [] =
1477 { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7'
1478 , L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
1479 std::size_t char_counter = 0;
1480 const char *chbuf = static_cast<const char *>(buf);
1481 for(std::size_t i = 0; i != length; ++i){
1482 str[char_counter++] = Characters[(chbuf[i]&0xF0)>>4];
1483 str[char_counter++] = Characters[(chbuf[i]&0x0F)];
1484 }
1485}
1486
1487inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp, std::size_t &s) //will write BootAndSystemstampLength chars
1488{
1489 if(s < (BootAndSystemstampLength*2))
1490 return false;
1491 system_timeofday_information info;
1492 bool ret = get_system_time_of_day_information(info);
1493 if(!ret){
1494 return false;
1495 }
1496
1497 buffer_to_wide_str(&info.Reserved1[0], BootAndSystemstampLength, bootsystemstamp);
1498 s = BootAndSystemstampLength*2;
1499 return true;
1500}
1501
1502class handle_closer
1503{
1504 void *handle_;
1505 handle_closer(const handle_closer &);
1506 handle_closer& operator=(const handle_closer &);
1507 public:
1508 explicit handle_closer(void *handle) : handle_(handle){}
1509 ~handle_closer()
1510 { close_handle(handle_); }
1511};
1512
1513union ntquery_mem_t
1514{
1515 object_name_information_t name;
1516 struct ren_t
1517 {
1518 file_rename_information_t info;
1519 wchar_t buf[1];
1520 } ren;
1521};
1522
1523class nt_query_mem_deleter
1524{
1525 static const std::size_t rename_offset = offsetof(ntquery_mem_t, ren.info.FileName) -
1526 offsetof(ntquery_mem_t, name.Name.Buffer);
1527 // Timestamp process id atomic count
1528 static const std::size_t rename_suffix = (SystemTimeOfDayInfoLength + sizeof(unsigned long) + sizeof(boost::uint32_t))*2;
1529
1530 public:
1531 nt_query_mem_deleter(std::size_t object_name_information_size)
1532 : m_size(object_name_information_size + rename_offset + rename_suffix)
1533 , m_buf(new char [m_size])
1534 {}
1535
1536 ~nt_query_mem_deleter()
1537 {
1538 delete[]m_buf;
1539 }
1540
1541 void realloc(std::size_t num_bytes)
1542 {
1543 num_bytes += rename_suffix + rename_offset;
1544 char *buf = m_buf;
1545 m_buf = new char[num_bytes];
1546 delete[]buf;
1547 m_size = num_bytes;
1548 }
1549
1550 ntquery_mem_t *query_mem() const
1551 { return static_cast<ntquery_mem_t *>(static_cast<void*>(m_buf)); }
1552
1553 unsigned long object_name_information_size() const
1554 { return static_cast<unsigned long>(m_size - rename_offset - SystemTimeOfDayInfoLength*2); }
1555
1556 std::size_t file_rename_information_size() const
1557 { return static_cast<unsigned long>(m_size); }
1558
1559 private:
1560 std::size_t m_size;
1561 char *m_buf;
1562};
1563
1564inline bool unlink_file(const char *filename)
1565{
1566 //Don't try to optimize doing a DeleteFile first
1567 //as there are interactions with permissions and
1568 //in-use files.
1569 //
1570 //if(!delete_file(filename)){
1571 // (...)
1572 //
1573
1574 //This functions tries to emulate UNIX unlink semantics in windows.
1575 //
1576 //- Open the file and mark the handle as delete-on-close
1577 //- Rename the file to an arbitrary name based on a random number
1578 //- Close the handle. If there are no file users, it will be deleted.
1579 // Otherwise it will be used by already connected handles but the
1580 // file name can't be used to open this file again
1581 try{
1582 NtSetInformationFile_t pNtSetInformationFile =
1583 (NtSetInformationFile_t)dll_func::get(dll_func::NtSetInformationFile);
1584
1585 NtQueryObject_t pNtQueryObject = (NtQueryObject_t)dll_func::get(dll_func::NtQueryObject);
1586
1587 //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
1588 void *fh = create_file(filename, generic_read | delete_access, open_existing, 0, 0);
1589 if(fh == invalid_handle_value){
1590 return false;
1591 }
1592
1593 handle_closer h_closer(fh);
1594 {
1595 //Obtain name length
1596 unsigned long size;
1597 const std::size_t initial_string_mem = 512u;
1598
1599 nt_query_mem_deleter nt_query_mem(sizeof(ntquery_mem_t)+initial_string_mem);
1600 //Obtain file name with guessed length
1601 if(pNtQueryObject(fh, object_name_information, nt_query_mem.query_mem(), nt_query_mem.object_name_information_size(), &size)){
1602 //Obtain file name with exact length buffer
1603 nt_query_mem.realloc(size);
1604 if(pNtQueryObject(fh, object_name_information, nt_query_mem.query_mem(), nt_query_mem.object_name_information_size(), &size)){
1605 return false;
1606 }
1607 }
1608 ntquery_mem_t *pmem = nt_query_mem.query_mem();
1609 file_rename_information_t *pfri = &pmem->ren.info;
1610 const std::size_t RenMaxNumChars =
1611 (((char*)(pmem) + nt_query_mem.file_rename_information_size()) - (char*)&pmem->ren.info.FileName[0])/sizeof(wchar_t);
1612
1613 //Copy filename to the rename member
1614 std::memmove(pmem->ren.info.FileName, pmem->name.Name.Buffer, pmem->name.Name.Length);
1615 std::size_t filename_string_length = pmem->name.Name.Length/sizeof(wchar_t);
1616
1617 //Search '\\' character to replace from it
1618 for(std::size_t i = filename_string_length; i != 0; --filename_string_length){
1619 if(pmem->ren.info.FileName[--i] == L'\\')
1620 break;
1621 }
1622
1623 //Add random number
1624 std::size_t s = RenMaxNumChars - filename_string_length;
1625 if(!get_boot_and_system_time_wstr(&pfri->FileName[filename_string_length], s)){
1626 return false;
1627 }
1628 filename_string_length += s;
1629
1630 //Sometimes the precission of the timestamp is not enough and we need to add another random number.
1631 //The process id (to exclude concurrent processes) and an atomic count (to exclude concurrent threads).
1632 //should be enough
1633 const unsigned long pid = get_current_process_id();
1634 buffer_to_wide_str(&pid, sizeof(pid), &pfri->FileName[filename_string_length]);
1635 filename_string_length += sizeof(pid)*2;
1636
1637 static volatile boost::uint32_t u32_count = 0;
1638 interlocked_decrement(reinterpret_cast<volatile long*>(&u32_count));
1639 buffer_to_wide_str(const_cast<const boost::uint32_t *>(&u32_count), sizeof(boost::uint32_t), &pfri->FileName[filename_string_length]);
1640 filename_string_length += sizeof(boost::uint32_t)*2;
1641
1642 //Fill rename information (FileNameLength is in bytes)
1643 pfri->FileNameLength = static_cast<unsigned long>(sizeof(wchar_t)*(filename_string_length));
1644 pfri->Replace = 1;
1645 pfri->RootDir = 0;
1646
1647 //Cange the name of the in-use file...
1648 io_status_block_t io;
1649 if(0 != pNtSetInformationFile(fh, &io, pfri, nt_query_mem.file_rename_information_size(), file_rename_information)){
1650 return false;
1651 }
1652 }
1653 //...and mark it as delete-on-close
1654 {
1655 //Don't use pNtSetInformationFile with file_disposition_information as it can return STATUS_CANNOT_DELETE
1656 //if the file is still mapped. Reopen it with NtOpenFile and file_delete_on_close
1657 NtOpenFile_t pNtOpenFile = (NtOpenFile_t)dll_func::get(dll_func::NtOpenFile);
1658 NtClose_t pNtClose = (NtClose_t)dll_func::get(dll_func::NtClose);
1659 const wchar_t empty_str [] = L"";
1660 unicode_string_t ustring = { sizeof(empty_str) - sizeof (wchar_t) //length in bytes without null
1661 , sizeof(empty_str) //total size in bytes of memory allocated for Buffer.
1662 , const_cast<wchar_t*>(empty_str)
1663 };
1664 object_attributes_t object_attr;
1665 initialize_object_attributes(&object_attr, &ustring, 0, fh, 0);
1666 void* fh2 = 0;
1667 io_status_block_t io;
1668 pNtOpenFile( &fh2, delete_flag, &object_attr, &io
1669 , file_share_read | file_share_write | file_share_delete, file_delete_on_close);
1670 pNtClose(fh2);
1671 //Even if NtOpenFile fails, the file was renamed and the original no longer exists, so return a success status
1672 return true;
1673 }
1674 }
1675 catch(...){
1676 return false;
1677 }
1678 return true;
1679}
1680
1681struct reg_closer
1682{
1683 //reg_closer(RegCloseKey_t func, void *key) : func_(func), key_(key){}
1684 //~reg_closer(){ (*func_)(key_); }
1685 //RegCloseKey_t func_;
1686 void *key_;
1687 reg_closer(void *key) : key_(key){}
1688 ~reg_closer(){ reg_close_key(key_); }
1689};
1690
1691inline void get_shared_documents_folder(std::string &s)
1692{
1693 s.clear();
1694 void *key;
1695 if (reg_open_key_ex( hkey_local_machine
1696 , "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
1697 , 0
1698 , key_query_value
1699 , &key) == 0){
1700 reg_closer key_closer(key);
1701
1702 //Obtain the value
1703 unsigned long size;
1704 unsigned long type;
1705 const char *const reg_value = "Common AppData";
1706 //long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
1707 long err = reg_query_value_ex( key, reg_value, 0, &type, 0, &size);
1708 if(!err){
1709 //Size includes terminating NULL
1710 s.resize(size);
1711 //err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
1712 err = reg_query_value_ex( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
1713 if(!err)
1714 s.erase(s.end()-1);
1715 (void)err;
1716 }
1717 }
1718}
1719
1720inline void get_registry_value(const char *folder, const char *value_key, std::vector<unsigned char> &s)
1721{
1722 s.clear();
1723 void *key;
1724 if (reg_open_key_ex( hkey_local_machine
1725 , folder
1726 , 0
1727 , key_query_value
1728 , &key) == 0){
1729 reg_closer key_closer(key);
1730
1731 //Obtain the value
1732 unsigned long size;
1733 unsigned long type;
1734 const char *const reg_value = value_key;
1735 //long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
1736 long err = reg_query_value_ex( key, reg_value, 0, &type, 0, &size);
1737 if(!err){
1738 //Size includes terminating NULL
1739 s.resize(size);
1740 //err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
1741 err = reg_query_value_ex( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
1742 if(!err)
1743 s.erase(s.end()-1);
1744 (void)err;
1745 }
1746 }
1747}
1748
1749struct co_uninitializer
1750{
1751 co_uninitializer(bool b_uninitialize)
1752 : m_b_uninitialize(b_uninitialize)
1753 {}
1754
1755 ~co_uninitializer()
1756 {
1757 if(m_b_uninitialize){
1758 CoUninitialize();
1759 }
1760 }
1761
1762 private:
1763 const bool m_b_uninitialize;
1764};
1765
1766template<class Object>
1767struct com_releaser
1768{
1769 Object *&object_;
1770 com_releaser(Object *&object) : object_(object) {}
1771 ~com_releaser() { object_->Release(); object_ = 0; }
1772};
1773
1774inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_class, const wchar_t *wmi_class_var)
1775{
1776 //See example http://msdn.microsoft.com/en-us/library/aa390423%28v=VS.85%29.aspx
1777 //
1778 //See BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL definition if you need to change the
1779 //default value of this macro in your application
1780 long co_init_ret = CoInitializeEx(0, BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL);
1781 if(co_init_ret != S_OK_BIPC && co_init_ret != S_FALSE_BIPC && co_init_ret != RPC_E_CHANGED_MODE_BIPC)
1782 return false;
1783 co_uninitializer co_initialize_end(co_init_ret != RPC_E_CHANGED_MODE_BIPC);
1784 (void)co_initialize_end;
1785
1786 bool bRet = false;
1787 long sec_init_ret = CoInitializeSecurity
1788 ( 0 //pVoid
1789 ,-1 //cAuthSvc
1790 , 0 //asAuthSvc
1791 , 0 //pReserved1
1792 , RPC_C_AUTHN_LEVEL_PKT_BIPC //dwAuthnLevel
1793 , RPC_C_IMP_LEVEL_IMPERSONATE_BIPC //dwImpLevel
1794 , 0 //pAuthList
1795 , EOAC_NONE_BIPC //dwCapabilities
1796 , 0 //pReserved3
1797 );
1798 if( 0 == sec_init_ret || RPC_E_TOO_LATE_BIPC == sec_init_ret)
1799 {
1800 IWbemLocator_BIPC * pIWbemLocator = 0;
1801 const wchar_t * bstrNamespace = L"root\\cimv2";
1802
1803 if( 0 != CoCreateInstance(
1804 CLSID_WbemAdministrativeLocator,
1805 0,
1806 CLSCTX_INPROC_SERVER_BIPC | CLSCTX_LOCAL_SERVER_BIPC,
1807 IID_IUnknown, (void **)&pIWbemLocator)){
1808 return false;
1809 }
1810
1811 com_releaser<IWbemLocator_BIPC> IWbemLocator_releaser(pIWbemLocator);
1812
1813 IWbemServices_BIPC *pWbemServices = 0;
1814
1815 if( 0 != pIWbemLocator->ConnectServer(
1816 bstrNamespace, // Namespace
1817 0, // Userid
1818 0, // PW
1819 0, // Locale
1820 0, // flags
1821 0, // Authority
1822 0, // Context
1823 &pWbemServices
1824 )
1825 ){
1826 return false;
1827 }
1828
1829 if( S_OK_BIPC != CoSetProxyBlanket(
1830 pWbemServices,
1831 RPC_C_AUTHN_DEFAULT_BIPC,
1832 RPC_C_AUTHZ_DEFAULT_BIPC,
1833 0,
1834 RPC_C_AUTHN_LEVEL_PKT_BIPC,
1835 RPC_C_IMP_LEVEL_IMPERSONATE_BIPC,
1836 0,
1837 EOAC_NONE_BIPC
1838 )
1839 ){
1840 return false;
1841 }
1842
1843 com_releaser<IWbemServices_BIPC> IWbemServices_releaser(pWbemServices);
1844
1845 strValue.clear();
1846 strValue += L"Select ";
1847 strValue += wmi_class_var;
1848 strValue += L" from ";
1849 strValue += wmi_class;
1850
1851 IEnumWbemClassObject_BIPC * pEnumObject = 0;
1852
1853 if ( 0 != pWbemServices->ExecQuery(
1854 L"WQL",
1855 strValue.c_str(),
1856 //WBEM_FLAG_RETURN_IMMEDIATELY_BIPC,
1857 WBEM_FLAG_RETURN_WHEN_COMPLETE_BIPC | WBEM_FLAG_FORWARD_ONLY_BIPC,
1858 0,
1859 &pEnumObject
1860 )
1861 ){
1862 return false;
1863 }
1864
1865 com_releaser<IEnumWbemClassObject_BIPC> IEnumWbemClassObject_releaser(pEnumObject);
1866
1867 //WBEM_FLAG_FORWARD_ONLY_BIPC incompatible with Reset
1868 //if ( 0 != pEnumObject->Reset() ){
1869 //return false;
1870 //}
1871
1872 wchar_variant vwchar;
1873 unsigned long uCount = 1, uReturned;
1874 IWbemClassObject_BIPC * pClassObject = 0;
1875 while( 0 == pEnumObject->Next( WBEM_INFINITE_BIPC, uCount, &pClassObject, &uReturned ) )
1876 {
1877 com_releaser<IWbemClassObject_BIPC> IWbemClassObject_releaser(pClassObject);
1878 if ( 0 == pClassObject->Get( L"LastBootUpTime", 0, &vwchar, 0, 0 ) ){
1879 bRet = true;
1880 strValue = vwchar.value.pbstrVal;
1881 VariantClear(&vwchar );
1882 break;
1883 }
1884 }
1885 }
1886 return bRet;
1887}
1888
1889inline bool get_last_bootup_time( std::wstring& strValue )
1890{
1891 bool ret = get_wmi_class_attribute(strValue, L"Win32_OperatingSystem", L"LastBootUpTime");
1892 std::size_t timezone = strValue.find(L'+');
1893 if(timezone != std::wstring::npos){
1894 strValue.erase(timezone);
1895 }
1896 timezone = strValue.find(L'-');
1897 if(timezone != std::wstring::npos){
1898 strValue.erase(timezone);
1899 }
1900 return ret;
1901}
1902
1903inline bool get_last_bootup_time( std::string& str )
1904{
1905 std::wstring wstr;
1906 bool ret = get_last_bootup_time(wstr);
1907 str.resize(wstr.size());
1908 for(std::size_t i = 0, max = str.size(); i != max; ++i){
1909 str[i] = '0' + (wstr[i]-L'0');
1910 }
1911 return ret;
1912}
1913
1914inline bool is_directory(const char *path)
1915{
1916 unsigned long attrib = GetFileAttributesA(path);
1917
1918 return (attrib != invalid_file_attributes &&
1919 (attrib & file_attribute_directory));
1920}
1921
1922inline bool get_file_mapping_size(void *file_mapping_hnd, __int64 &size)
1923{
1924 NtQuerySection_t pNtQuerySection =
1925 (NtQuerySection_t)dll_func::get(dll_func::NtQuerySection);
1926 //Obtain file name
1927 interprocess_section_basic_information info;
1928 unsigned long ntstatus =
1929 pNtQuerySection(file_mapping_hnd, section_basic_information, &info, sizeof(info), 0);
1930 if(ntstatus){
1931 return false;
1932 }
1933 size = info.section_size;
1934 return true;
1935}
1936
1937inline bool get_semaphore_info(void *handle, long &count, long &limit)
1938{
1939 winapi::interprocess_semaphore_basic_information info;
1940 winapi::NtQuerySemaphore_t pNtQuerySemaphore =
1941 (winapi::NtQuerySemaphore_t)dll_func::get(winapi::dll_func::NtQuerySemaphore);
1942 unsigned int ret_len;
1943 long status = pNtQuerySemaphore(handle, winapi::semaphore_basic_information, &info, sizeof(info), &ret_len);
1944 if(status){
1945 return false;
1946 }
1947 count = info.count;
1948 limit = info.limit;
1949 return true;
1950}
1951
1952
1953} //namespace winapi
1954} //namespace interprocess
1955} //namespace boost
1956
1957#include <boost/interprocess/detail/config_end.hpp>
1958
1959#endif //#ifdef BOOST_INTERPROCESS_WIN32_PRIMITIVES_HPP