1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2008. 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)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP
12 #define BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP
14 #include <boost/interprocess/detail/config_begin.hpp>
15 #include <boost/interprocess/detail/workaround.hpp>
20 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
22 # pragma comment( lib, "advapi32.lib" )
25 #if (defined BOOST_INTERPROCESS_WINDOWS)
27 # include <boost/detail/interlocked.hpp>
29 # error "This file can only be included in Windows OS"
32 //The structures used in Interprocess with the
33 //same binary interface as windows ones
35 namespace interprocess
{
39 static const unsigned long infinite_time
= 0xFFFFFFFF;
40 static const unsigned long error_already_exists
= 183L;
41 static const unsigned long error_file_not_found
= 2u;
42 static const unsigned long error_no_more_files
= 18u;
44 static const unsigned long semaphore_all_access
= (0x000F0000L
)|(0x00100000L
)|0x3;
45 static const unsigned long mutex_all_access
= (0x000F0000L
)|(0x00100000L
)|0x0001;
47 static const unsigned long page_readonly
= 0x02;
48 static const unsigned long page_readwrite
= 0x04;
49 static const unsigned long page_writecopy
= 0x08;
51 static const unsigned long standard_rights_required
= 0x000F0000L
;
52 static const unsigned long section_query
= 0x0001;
53 static const unsigned long section_map_write
= 0x0002;
54 static const unsigned long section_map_read
= 0x0004;
55 static const unsigned long section_map_execute
= 0x0008;
56 static const unsigned long section_extend_size
= 0x0010;
57 static const unsigned long section_all_access
= standard_rights_required
|
64 static const unsigned long file_map_copy
= section_query
;
65 static const unsigned long file_map_write
= section_map_write
;
66 static const unsigned long file_map_read
= section_map_read
;
67 static const unsigned long file_map_all_access
= section_all_access
;
68 static const unsigned long delete_access
= 0x00010000L
;
69 static const unsigned long file_flag_backup_semantics
= 0x02000000;
70 static const long file_flag_delete_on_close
= 0x04000000;
72 //Native API constants
73 static const unsigned long file_open_for_backup_intent
= 0x00004000;
74 static const int file_share_valid_flags
= 0x00000007;
75 static const long file_delete_on_close
= 0x00001000L
;
76 static const long obj_case_insensitive
= 0x00000040L
;
78 static const unsigned long movefile_copy_allowed
= 0x02;
79 static const unsigned long movefile_delay_until_reboot
= 0x04;
80 static const unsigned long movefile_replace_existing
= 0x01;
81 static const unsigned long movefile_write_through
= 0x08;
82 static const unsigned long movefile_create_hardlink
= 0x10;
83 static const unsigned long movefile_fail_if_not_trackable
= 0x20;
85 static const unsigned long file_share_read
= 0x00000001;
86 static const unsigned long file_share_write
= 0x00000002;
87 static const unsigned long file_share_delete
= 0x00000004;
89 static const unsigned long file_attribute_readonly
= 0x00000001;
90 static const unsigned long file_attribute_hidden
= 0x00000002;
91 static const unsigned long file_attribute_system
= 0x00000004;
92 static const unsigned long file_attribute_directory
= 0x00000010;
93 static const unsigned long file_attribute_archive
= 0x00000020;
94 static const unsigned long file_attribute_device
= 0x00000040;
95 static const unsigned long file_attribute_normal
= 0x00000080;
96 static const unsigned long file_attribute_temporary
= 0x00000100;
98 static const unsigned long generic_read
= 0x80000000L
;
99 static const unsigned long generic_write
= 0x40000000L
;
101 static const unsigned long wait_object_0
= 0;
102 static const unsigned long wait_abandoned
= 0x00000080L
;
103 static const unsigned long wait_timeout
= 258L;
104 static const unsigned long wait_failed
= (unsigned long)0xFFFFFFFF;
106 static const unsigned long duplicate_close_source
= (unsigned long)0x00000001;
107 static const unsigned long duplicate_same_access
= (unsigned long)0x00000002;
109 static const unsigned long format_message_allocate_buffer
110 = (unsigned long)0x00000100;
111 static const unsigned long format_message_ignore_inserts
112 = (unsigned long)0x00000200;
113 static const unsigned long format_message_from_string
114 = (unsigned long)0x00000400;
115 static const unsigned long format_message_from_hmodule
116 = (unsigned long)0x00000800;
117 static const unsigned long format_message_from_system
118 = (unsigned long)0x00001000;
119 static const unsigned long format_message_argument_array
120 = (unsigned long)0x00002000;
121 static const unsigned long format_message_max_width_mask
122 = (unsigned long)0x000000FF;
123 static const unsigned long lang_neutral
= (unsigned long)0x00;
124 static const unsigned long sublang_default
= (unsigned long)0x01;
125 static const unsigned long invalid_file_size
= (unsigned long)0xFFFFFFFF;
126 static void * const invalid_handle_value
= (void*)(long)(-1);
127 static const unsigned long create_new
= 1;
128 static const unsigned long create_always
= 2;
129 static const unsigned long open_existing
= 3;
130 static const unsigned long open_always
= 4;
131 static const unsigned long truncate_existing
= 5;
133 static const unsigned long file_begin
= 0;
134 static const unsigned long file_current
= 1;
135 static const unsigned long file_end
= 2;
137 static const unsigned long lockfile_fail_immediately
= 1;
138 static const unsigned long lockfile_exclusive_lock
= 2;
139 static const unsigned long error_lock_violation
= 33;
140 static const unsigned long security_descriptor_revision
= 1;
143 static const long SystemTimeOfDayInfoLength
= 48;
144 static const long BootAndSystemstampLength
= 16;
145 static const long BootstampLength
= 8;
146 static const unsigned long MaxPath
= 260;
149 } //namespace winapi {
150 } //namespace interprocess {
151 } //namespace boost {
153 #if !defined( BOOST_USE_WINDOWS_H )
156 namespace interprocess
{
159 struct interprocess_overlapped
161 unsigned long *internal
;
162 unsigned long *internal_high
;
165 unsigned long offset
;
166 unsigned long offset_high
;
174 struct interprocess_filetime
176 unsigned long dwLowDateTime
;
177 unsigned long dwHighDateTime
;
180 struct win32_find_data_t
182 unsigned long dwFileAttributes
;
183 interprocess_filetime ftCreationTime
;
184 interprocess_filetime ftLastAccessTime
;
185 interprocess_filetime ftLastWriteTime
;
186 unsigned long nFileSizeHigh
;
187 unsigned long nFileSizeLow
;
188 unsigned long dwReserved0
;
189 unsigned long dwReserved1
;
190 char cFileName
[MaxPath
];
191 char cAlternateFileName
[14];
194 struct interprocess_security_attributes
196 unsigned long nLength
;
197 void *lpSecurityDescriptor
;
203 unsigned long dwOemId
; // Obsolete field...do not use
205 unsigned short wProcessorArchitecture
;
206 unsigned short wReserved
;
209 unsigned long dwPageSize
;
210 void * lpMinimumApplicationAddress
;
211 void * lpMaximumApplicationAddress
;
212 unsigned long * dwActiveProcessorMask
;
213 unsigned long dwNumberOfProcessors
;
214 unsigned long dwProcessorType
;
215 unsigned long dwAllocationGranularity
;
216 unsigned short wProcessorLevel
;
217 unsigned short wProcessorRevision
;
220 struct interprocess_memory_basic_information
223 void * AllocationBase
;
224 unsigned long AllocationProtect
;
225 unsigned long RegionSize
;
227 unsigned long Protect
;
231 typedef struct _interprocess_acl
233 unsigned char AclRevision
;
235 unsigned short AclSize
;
236 unsigned short AceCount
;
240 typedef struct _interprocess_security_descriptor
242 unsigned char Revision
;
244 unsigned short Control
;
247 interprocess_acl
*Sacl
;
248 interprocess_acl
*Dacl
;
249 } interprocess_security_descriptor
;
251 enum file_information_class_t
{
252 file_directory_information
= 1,
253 file_full_directory_information
,
254 file_both_directory_information
,
255 file_basic_information
,
256 file_standard_information
,
257 file_internal_information
,
259 file_access_information
,
260 file_name_information
,
261 file_rename_information
,
262 file_link_information
,
263 file_names_information
,
264 file_disposition_information
,
265 file_position_information
,
266 file_full_ea_information
,
267 file_mode_information
,
268 file_alignment_information
,
269 file_all_information
,
270 file_allocation_information
,
271 file_end_of_file_information
,
272 file_alternate_name_information
,
273 file_stream_information
,
274 file_pipe_information
,
275 file_pipe_local_information
,
276 file_pipe_remote_information
,
277 file_mailslot_query_information
,
278 file_mailslot_set_information
,
279 file_compression_information
,
280 file_copy_on_write_information
,
281 file_completion_information
,
282 file_move_cluster_information
,
283 file_quota_information
,
284 file_reparse_point_information
,
285 file_network_open_information
,
286 file_object_id_information
,
287 file_tracking_information
,
288 file_ole_directory_information
,
289 file_content_index_information
,
290 file_inherit_content_index_information
,
291 file_ole_information
,
292 file_maximum_information
295 struct file_name_information_t
{
296 unsigned long FileNameLength
;
300 struct file_rename_information_t
{
303 unsigned long FileNameLength
;
307 struct unicode_string_t
{
308 unsigned short Length
;
309 unsigned short MaximumLength
;
313 struct object_attributes_t
{
314 unsigned long Length
;
315 void * RootDirectory
;
316 unicode_string_t
*ObjectName
;
317 unsigned long Attributes
;
318 void *SecurityDescriptor
;
319 void *SecurityQualityOfService
;
322 struct io_status_block_t
{
328 unsigned long *Information
;
331 union system_timeofday_information
335 __int64 liKeBootTime
;
336 __int64 liKeSystemTime
;
337 __int64 liExpTimeZoneBias
;
338 unsigned long uCurrentTimeZoneId
;
339 unsigned long dwReserved
;
341 unsigned char Reserved1
[SystemTimeOfDayInfoLength
];
344 enum system_information_class
{
345 system_basic_information
= 0,
346 system_performance_information
= 2,
347 system_time_of_day_information
= 3,
348 system_process_information
= 5,
349 system_processor_performance_information
= 8,
350 system_interrupt_information
= 23,
351 system_exception_information
= 33,
352 system_registry_quota_information
= 37,
353 system_lookaside_information
= 45
356 enum object_information_class
358 object_basic_information
,
359 object_name_information
,
360 object_type_information
,
361 object_all_information
,
362 object_data_information
365 struct object_name_information_t
367 unicode_string_t Name
;
368 wchar_t NameBuffer
[1];
371 //Some windows API declarations
372 extern "C" __declspec(dllimport
) unsigned long __stdcall
GetCurrentProcessId();
373 extern "C" __declspec(dllimport
) unsigned long __stdcall
GetCurrentThreadId();
374 extern "C" __declspec(dllimport
) void __stdcall
Sleep(unsigned long);
375 extern "C" __declspec(dllimport
) unsigned long __stdcall
GetLastError();
376 extern "C" __declspec(dllimport
) void * __stdcall
GetCurrentProcess();
377 extern "C" __declspec(dllimport
) int __stdcall
CloseHandle(void*);
378 extern "C" __declspec(dllimport
) int __stdcall DuplicateHandle
379 ( void *hSourceProcessHandle
, void *hSourceHandle
380 , void *hTargetProcessHandle
, void **lpTargetHandle
381 , unsigned long dwDesiredAccess
, int bInheritHandle
382 , unsigned long dwOptions
);
383 extern "C" __declspec(dllimport
) void *__stdcall
FindFirstFileA(const char *lpFileName
, win32_find_data_t
*lpFindFileData
);
384 extern "C" __declspec(dllimport
) int __stdcall
FindNextFileA(void *hFindFile
, win32_find_data_t
*lpFindFileData
);
385 extern "C" __declspec(dllimport
) int __stdcall
FindClose(void *hFindFile
);
386 extern "C" __declspec(dllimport
) void __stdcall
GetSystemTimeAsFileTime(interprocess_filetime
*);
387 extern "C" __declspec(dllimport
) int __stdcall
FileTimeToLocalFileTime(const interprocess_filetime
*in
, const interprocess_filetime
*out
);
388 extern "C" __declspec(dllimport
) void * __stdcall
CreateMutexA(interprocess_security_attributes
*, int, const char *);
389 extern "C" __declspec(dllimport
) void * __stdcall
OpenMutexA(unsigned long, int, const char *);
390 extern "C" __declspec(dllimport
) unsigned long __stdcall
WaitForSingleObject(void *, unsigned long);
391 extern "C" __declspec(dllimport
) int __stdcall
ReleaseMutex(void *);
392 extern "C" __declspec(dllimport
) int __stdcall
UnmapViewOfFile(void *);
393 extern "C" __declspec(dllimport
) void * __stdcall
CreateSemaphoreA(interprocess_security_attributes
*, long, long, const char *);
394 extern "C" __declspec(dllimport
) int __stdcall
ReleaseSemaphore(void *, long, long *);
395 extern "C" __declspec(dllimport
) void * __stdcall
OpenSemaphoreA(unsigned long, int, const char *);
396 extern "C" __declspec(dllimport
) void * __stdcall
CreateFileMappingA (void *, interprocess_security_attributes
*, unsigned long, unsigned long, unsigned long, const char *);
397 extern "C" __declspec(dllimport
) void * __stdcall
MapViewOfFileEx (void *, unsigned long, unsigned long, unsigned long, std::size_t, void*);
398 extern "C" __declspec(dllimport
) void * __stdcall
OpenFileMappingA (unsigned long, int, const char *);
399 extern "C" __declspec(dllimport
) void * __stdcall
CreateFileA (const char *, unsigned long, unsigned long, struct interprocess_security_attributes
*, unsigned long, unsigned long, void *);
400 extern "C" __declspec(dllimport
) int __stdcall
DeleteFileA (const char *);
401 extern "C" __declspec(dllimport
) int __stdcall
MoveFileExA (const char *, const char *, unsigned long);
402 extern "C" __declspec(dllimport
) void __stdcall
GetSystemInfo (struct system_info
*);
403 extern "C" __declspec(dllimport
) int __stdcall
FlushViewOfFile (void *, std::size_t);
404 extern "C" __declspec(dllimport
) int __stdcall
GetFileSizeEx (void *, __int64
*size
);
405 extern "C" __declspec(dllimport
) unsigned long __stdcall FormatMessageA
406 (unsigned long dwFlags
, const void *lpSource
, unsigned long dwMessageId
,
407 unsigned long dwLanguageId
, char *lpBuffer
, unsigned long nSize
,
408 std::va_list *Arguments
);
409 extern "C" __declspec(dllimport
) void *__stdcall
LocalFree (void *);
410 extern "C" __declspec(dllimport
) int __stdcall
CreateDirectoryA(const char *, interprocess_security_attributes
*);
411 extern "C" __declspec(dllimport
) int __stdcall
RemoveDirectoryA(const char *lpPathName
);
412 extern "C" __declspec(dllimport
) int __stdcall
GetTempPathA(unsigned long length
, char *buffer
);
413 extern "C" __declspec(dllimport
) int __stdcall
CreateDirectory(const char *, interprocess_security_attributes
*);
414 extern "C" __declspec(dllimport
) int __stdcall
SetFileValidData(void *, __int64 size
);
415 extern "C" __declspec(dllimport
) int __stdcall
SetEndOfFile(void *);
416 extern "C" __declspec(dllimport
) int __stdcall
SetFilePointerEx(void *, __int64 distance
, __int64
*new_file_pointer
, unsigned long move_method
);
417 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
);
418 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
);
419 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
);
420 extern "C" __declspec(dllimport
) int __stdcall
UnlockFileEx(void *hnd
, unsigned long reserved
, unsigned long size_low
, unsigned long size_high
, interprocess_overlapped
* overlapped
);
421 extern "C" __declspec(dllimport
) int __stdcall
WriteFile(void *hnd
, const void *buffer
, unsigned long bytes_to_write
, unsigned long *bytes_written
, interprocess_overlapped
* overlapped
);
422 extern "C" __declspec(dllimport
) int __stdcall
InitializeSecurityDescriptor(interprocess_security_descriptor
*pSecurityDescriptor
, unsigned long dwRevision
);
423 extern "C" __declspec(dllimport
) int __stdcall
SetSecurityDescriptorDacl(interprocess_security_descriptor
*pSecurityDescriptor
, int bDaclPresent
, interprocess_acl
*pDacl
, int bDaclDefaulted
);
424 extern "C" __declspec(dllimport
) void *__stdcall
LoadLibraryA(const char *);
425 extern "C" __declspec(dllimport
) int __stdcall
FreeLibrary(void *);
426 extern "C" __declspec(dllimport
) void *__stdcall
GetProcAddress(void *, const char*);
427 extern "C" __declspec(dllimport
) void *__stdcall
GetModuleHandleA(const char*);
429 //API function typedefs
430 //Pointer to functions
431 typedef long (__stdcall
*NtDeleteFile_t
)(object_attributes_t
*ObjectAttributes
);
432 typedef long (__stdcall
*NtSetInformationFile_t
)(void *FileHandle
, io_status_block_t
*IoStatusBlock
, void *FileInformation
, unsigned long Length
, int FileInformationClass
);
433 typedef long (__stdcall
*NtQueryInformationFile_t
)(void *,io_status_block_t
*,void *, long, int);
434 typedef long (__stdcall
*NtOpenFile_t
)(void*,unsigned long ,object_attributes_t
*,io_status_block_t
*,unsigned long,unsigned long);
435 typedef long (__stdcall
*NtClose_t
) (void*);
436 typedef long (__stdcall
*RtlCreateUnicodeStringFromAsciiz_t
)(unicode_string_t
*, const char *);
437 typedef void (__stdcall
*RtlFreeUnicodeString_t
)(unicode_string_t
*);
438 typedef void (__stdcall
*RtlInitUnicodeString_t
)( unicode_string_t
*, const wchar_t * );
439 typedef long (__stdcall
*RtlAppendUnicodeToString_t
)(unicode_string_t
*Destination
, const wchar_t *Source
);
440 typedef long (__stdcall
* NtQuerySystemInformation_t
)(int, void*, unsigned long, unsigned long *);
441 typedef long (__stdcall
* NtQueryObject_t
)(void*, object_information_class
, void *, unsigned long, unsigned long *);
442 typedef unsigned long (__stdcall
* GetMappedFileName_t
)(void *, void *, wchar_t *, unsigned long);
444 } //namespace winapi {
445 } //namespace interprocess {
446 } //namespace boost {
449 # include <windows.h>
450 #endif //#if !defined( BOOST_USE_WINDOWS_H )
453 namespace interprocess
{
456 static inline unsigned long format_message
457 (unsigned long dwFlags
, const void *lpSource
,
458 unsigned long dwMessageId
, unsigned long dwLanguageId
,
459 char *lpBuffer
, unsigned long nSize
, std::va_list *Arguments
)
461 return FormatMessageA
462 (dwFlags
, lpSource
, dwMessageId
, dwLanguageId
, lpBuffer
, nSize
, Arguments
);
465 //And now, wrapper functions
466 static inline void * local_free(void *hmem
)
467 { return LocalFree(hmem
); }
469 static inline unsigned long make_lang_id(unsigned long p
, unsigned long s
)
470 { return ((((unsigned short)(s
)) << 10) | (unsigned short)(p
)); }
472 static inline void sched_yield()
475 static inline unsigned long get_current_thread_id()
476 { return GetCurrentThreadId(); }
478 static inline unsigned long get_current_process_id()
479 { return GetCurrentProcessId(); }
481 static inline unsigned int close_handle(void* handle
)
482 { return CloseHandle(handle
); }
484 static inline void * find_first_file(const char *lpFileName
, win32_find_data_t
*lpFindFileData
)
485 { return FindFirstFileA(lpFileName
, lpFindFileData
); }
487 static inline bool find_next_file(void *hFindFile
, win32_find_data_t
*lpFindFileData
)
488 { return FindNextFileA(hFindFile
, lpFindFileData
) != 0; }
490 static inline bool find_close(void *handle
)
491 { return FindClose(handle
) != 0; }
493 static inline bool duplicate_current_process_handle
494 (void *hSourceHandle
, void **lpTargetHandle
)
496 return 0 != DuplicateHandle
497 ( GetCurrentProcess(), hSourceHandle
, GetCurrentProcess()
498 , lpTargetHandle
, 0, 0
499 , duplicate_same_access
);
502 static inline unsigned long get_last_error()
503 { return GetLastError(); }
505 static inline void get_system_time_as_file_time(interprocess_filetime
*filetime
)
506 { GetSystemTimeAsFileTime(filetime
); }
508 static inline bool file_time_to_local_file_time
509 (const interprocess_filetime
*in
, const interprocess_filetime
*out
)
510 { return 0 != FileTimeToLocalFileTime(in
, out
); }
512 static inline void *create_mutex(const char *name
)
513 { return CreateMutexA(0, 0, name
); }
515 static inline void *open_mutex(const char *name
)
516 { return OpenMutexA(mutex_all_access
, 0, name
); }
518 static inline unsigned long wait_for_single_object(void *handle
, unsigned long time
)
519 { return WaitForSingleObject(handle
, time
); }
521 static inline int release_mutex(void *handle
)
522 { return ReleaseMutex(handle
); }
524 static inline int unmap_view_of_file(void *address
)
525 { return UnmapViewOfFile(address
); }
527 static inline void *create_semaphore(long initialCount
, const char *name
)
528 { return CreateSemaphoreA(0, initialCount
, (long)(((unsigned long)(-1))>>1), name
); }
530 static inline int release_semaphore(void *handle
, long release_count
, long *prev_count
)
531 { return ReleaseSemaphore(handle
, release_count
, prev_count
); }
533 static inline void *open_semaphore(const char *name
)
534 { return OpenSemaphoreA(semaphore_all_access
, 1, name
); }
536 static inline void * create_file_mapping (void * handle
, unsigned long access
, unsigned long high_size
, unsigned long low_size
, const char * name
)
538 interprocess_security_attributes sa
;
539 interprocess_security_descriptor sd
;
541 if(!InitializeSecurityDescriptor(&sd
, security_descriptor_revision
))
543 if(!SetSecurityDescriptorDacl(&sd
, true, 0, false))
545 sa
.lpSecurityDescriptor
= &sd
;
546 sa
.nLength
= sizeof(interprocess_security_attributes
);
547 sa
.bInheritHandle
= false;
548 return CreateFileMappingA (handle
, &sa
, access
, high_size
, low_size
, name
);
549 //return CreateFileMappingA (handle, 0, access, high_size, low_size, name);
552 static inline void * open_file_mapping (unsigned long access
, const char *name
)
553 { return OpenFileMappingA (access
, 0, name
); }
555 static inline void *map_view_of_file_ex(void *handle
, unsigned long file_access
, unsigned long highoffset
, unsigned long lowoffset
, std::size_t numbytes
, void *base_addr
)
556 { return MapViewOfFileEx(handle
, file_access
, highoffset
, lowoffset
, numbytes
, base_addr
); }
558 static inline void *create_file(const char *name
, unsigned long access
, unsigned long creation_flags
, unsigned long attributes
= 0)
559 { return CreateFileA(name
, access
, file_share_read
| file_share_write
| file_share_delete
, 0, creation_flags
, attributes
, 0); }
561 static inline bool delete_file(const char *name
)
562 { return 0 != DeleteFileA(name
); }
564 static inline bool move_file_ex(const char *source_filename
, const char *destination_filename
, unsigned long flags
)
565 { return 0 != MoveFileExA(source_filename
, destination_filename
, flags
); }
567 static inline void get_system_info(system_info
*info
)
568 { GetSystemInfo(info
); }
570 static inline int flush_view_of_file(void *base_addr
, std::size_t numbytes
)
571 { return FlushViewOfFile(base_addr
, numbytes
); }
573 static inline bool get_file_size(void *handle
, __int64
&size
)
574 { return 0 != GetFileSizeEx(handle
, &size
); }
576 static inline bool create_directory(const char *name
, interprocess_security_attributes
* security
)
577 { return 0 != CreateDirectoryA(name
, security
); }
579 static inline bool remove_directory(const char *lpPathName
)
580 { return 0 != RemoveDirectoryA(lpPathName
); }
582 static inline unsigned long get_temp_path(unsigned long length
, char *buffer
)
583 { return GetTempPathA(length
, buffer
); }
585 static inline int set_end_of_file(void *handle
)
586 { return 0 != SetEndOfFile(handle
); }
588 static inline bool set_file_pointer_ex(void *handle
, __int64 distance
, __int64
*new_file_pointer
, unsigned long move_method
)
589 { return 0 != SetFilePointerEx(handle
, distance
, new_file_pointer
, move_method
); }
591 static inline bool lock_file_ex(void *hnd
, unsigned long flags
, unsigned long reserved
, unsigned long size_low
, unsigned long size_high
, interprocess_overlapped
*overlapped
)
592 { return 0 != LockFileEx(hnd
, flags
, reserved
, size_low
, size_high
, overlapped
); }
594 static inline bool unlock_file_ex(void *hnd
, unsigned long reserved
, unsigned long size_low
, unsigned long size_high
, interprocess_overlapped
*overlapped
)
595 { return 0 != UnlockFileEx(hnd
, reserved
, size_low
, size_high
, overlapped
); }
597 static inline bool write_file(void *hnd
, const void *buffer
, unsigned long bytes_to_write
, unsigned long *bytes_written
, interprocess_overlapped
* overlapped
)
598 { return 0 != WriteFile(hnd
, buffer
, bytes_to_write
, bytes_written
, overlapped
); }
600 static inline long interlocked_increment(long volatile *addr
)
601 { return BOOST_INTERLOCKED_INCREMENT(addr
); }
603 static inline long interlocked_decrement(long volatile *addr
)
604 { return BOOST_INTERLOCKED_DECREMENT(addr
); }
606 static inline long interlocked_compare_exchange(long volatile *addr
, long val1
, long val2
)
607 { return BOOST_INTERLOCKED_COMPARE_EXCHANGE(addr
, val1
, val2
); }
609 static inline long interlocked_exchange_add(long volatile* addend
, long value
)
610 { return BOOST_INTERLOCKED_EXCHANGE_ADD(const_cast<long*>(addend
), value
); }
612 static inline long interlocked_exchange(long volatile* addend
, long value
)
613 { return BOOST_INTERLOCKED_EXCHANGE(const_cast<long*>(addend
), value
); }
616 static inline void *load_library(const char *name
)
617 { return LoadLibraryA(name
); }
619 static inline bool free_library(void *module
)
620 { return 0 != FreeLibrary(module
); }
622 static inline void *get_proc_address(void *module
, const char *name
)
623 { return GetProcAddress(module
, name
); }
625 static inline void *get_current_process()
626 { return GetCurrentProcess(); }
628 static inline void *get_module_handle(const char *name
)
629 { return GetModuleHandleA(name
); }
631 static inline void initialize_object_attributes
632 ( object_attributes_t
*pobject_attr
, unicode_string_t
*name
633 , unsigned long attr
, void *rootdir
, void *security_descr
)
636 pobject_attr
->Length
= sizeof(object_attributes_t
);
637 pobject_attr
->RootDirectory
= rootdir
;
638 pobject_attr
->Attributes
= attr
;
639 pobject_attr
->ObjectName
= name
;
640 pobject_attr
->SecurityDescriptor
= security_descr
;
641 pobject_attr
->SecurityQualityOfService
= 0;
644 static inline void rtl_init_empty_unicode_string(unicode_string_t
*ucStr
, wchar_t *buf
, unsigned short bufSize
)
648 ucStr
->MaximumLength
= bufSize
;
651 //Complex winapi based functions...
653 //pszFilename must have room for at least MaxPath+1 characters
654 static inline bool get_file_name_from_handle_function
655 (void * hFile
, wchar_t *pszFilename
, std::size_t length
, std::size_t &out_length
)
657 if(length
<= MaxPath
){
661 void *hiPSAPI
= load_library("PSAPI.DLL");
665 class library_unloader
670 library_unloader(void *module
) : lib_(module
){}
671 ~library_unloader(){ free_library(lib_
); }
674 // Pointer to function getMappedFileName() in PSAPI.DLL
675 GetMappedFileName_t pfGMFN
=
676 (GetMappedFileName_t
)get_proc_address(hiPSAPI
, "GetMappedFileNameW");
678 return 0; // Failed: unexpected error
681 bool bSuccess
= false;
683 // Create a file mapping object.
684 void * hFileMap
= create_file_mapping(hFile
, page_readonly
, 0, 1, 0);
687 // Create a file mapping to get the file name.
688 void* pMem
= map_view_of_file_ex(hFileMap
, file_map_read
, 0, 0, 1, 0);
691 out_length
= pfGMFN(get_current_process(), pMem
, pszFilename
, MaxPath
);
695 unmap_view_of_file(pMem
);
697 close_handle(hFileMap
);
703 static inline bool get_system_time_of_day_information(system_timeofday_information
&info
)
705 NtQuerySystemInformation_t pNtQuerySystemInformation
= (NtQuerySystemInformation_t
)
706 get_proc_address(get_module_handle("ntdll.dll"), "NtQuerySystemInformation");
708 long status
= pNtQuerySystemInformation(system_time_of_day_information
, &info
, sizeof(info
), &res
);
715 static inline bool get_boot_time(unsigned char (&bootstamp
) [BootstampLength
])
717 system_timeofday_information info
;
718 bool ret
= get_system_time_of_day_information(info
);
722 std::memcpy(&bootstamp
[0], &info
.Reserved1
, sizeof(bootstamp
));
726 static inline bool get_boot_and_system_time(unsigned char (&bootsystemstamp
) [BootAndSystemstampLength
])
728 system_timeofday_information info
;
729 bool ret
= get_system_time_of_day_information(info
);
733 std::memcpy(&bootsystemstamp
[0], &info
.Reserved1
, sizeof(bootsystemstamp
));
737 static inline bool get_boot_time_str(char *bootstamp_str
, std::size_t &s
) //will write BootstampLength chars
739 if(s
< (BootstampLength
*2))
741 system_timeofday_information info
;
742 bool ret
= get_system_time_of_day_information(info
);
746 const char Characters
[] =
747 { '0', '1', '2', '3', '4', '5', '6', '7'
748 , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
749 std::size_t char_counter
= 0;
750 for(std::size_t i
= 0; i
!= static_cast<std::size_t>(BootstampLength
); ++i
){
751 bootstamp_str
[char_counter
++] = Characters
[(info
.Reserved1
[i
]&0xF0)>>4];
752 bootstamp_str
[char_counter
++] = Characters
[(info
.Reserved1
[i
]&0x0F)];
754 s
= BootstampLength
*2;
758 static inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp
, std::size_t &s
) //will write BootAndSystemstampLength chars
760 if(s
< (BootAndSystemstampLength
*2))
762 system_timeofday_information info
;
763 bool ret
= get_system_time_of_day_information(info
);
767 const wchar_t Characters
[] =
768 { L
'0', L
'1', L
'2', L
'3', L
'4', L
'5', L
'6', L
'7'
769 , L
'8', L
'9', L
'A', L
'B', L
'C', L
'D', L
'E', L
'F' };
770 std::size_t char_counter
= 0;
771 for(std::size_t i
= 0; i
!= static_cast<std::size_t>(BootAndSystemstampLength
); ++i
){
772 bootsystemstamp
[char_counter
++] = Characters
[(info
.Reserved1
[i
]&0xF0)>>4];
773 bootsystemstamp
[char_counter
++] = Characters
[(info
.Reserved1
[i
]&0x0F)];
775 s
= BootAndSystemstampLength
*2;
779 static inline bool unlink_file(const char *filename
)
782 NtSetInformationFile_t pNtSetInformationFile
=
783 (NtSetInformationFile_t
)get_proc_address(get_module_handle("ntdll.dll"), "NtSetInformationFile");
784 if(!pNtSetInformationFile
){
788 NtQueryObject_t pNtQueryObject
=
789 (NtQueryObject_t
)get_proc_address(get_module_handle("ntdll.dll"), "NtQueryObject");
791 //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
792 void *fh
= create_file(filename
, generic_read
| delete_access
, open_existing
,
793 file_flag_backup_semantics
| file_flag_delete_on_close
);
794 if(fh
== invalid_handle_value
){
802 handle_closer(void *handle
) : handle_(handle
){}
803 ~handle_closer(){ close_handle(handle_
); }
806 const std::size_t CharArraySize
= 32767; //Max name length
810 object_name_information_t name
;
813 file_rename_information_t info
;
814 wchar_t buf
[CharArraySize
];
821 explicit auto_ptr(mem_t
*ptr
) : ptr_(ptr
){}
822 ~auto_ptr(){ delete ptr_
; }
823 mem_t
*get() const{ return (ptr_
); }
824 mem_t
*operator->() const{ return this->get(); }
829 file_rename_information_t
*pfri
= (file_rename_information_t
*)&pmem
->ren
.info
;
830 const std::size_t RenMaxNumChars
=
831 ((char*)pmem
.get() - (char*)&pmem
->ren
.info
.FileName
[0])/sizeof(wchar_t);
835 if(pNtQueryObject(fh
, object_name_information
, pmem
.get(), sizeof(mem_t
), &size
)){
839 //Copy filename to the rename member
840 std::memmove(pmem
->ren
.info
.FileName
, pmem
->name
.Name
.Buffer
, pmem
->name
.Name
.Length
);
841 std::size_t filename_string_length
= pmem
->name
.Name
.Length
/sizeof(wchar_t);
843 //Second step: obtain the complete native-nt filename
844 //if(!get_file_name_from_handle_function(fh, pfri->FileName, RenMaxNumChars, filename_string_length)){
849 if((RenMaxNumChars
-filename_string_length
) < (SystemTimeOfDayInfoLength
*2)){
853 //Search '\\' character to replace it
854 for(std::size_t i
= filename_string_length
; i
!= 0; --filename_string_length
){
855 if(pmem
->ren
.info
.FileName
[--i
] == L
'\\')
860 std::size_t s
= RenMaxNumChars
- filename_string_length
;
861 if(!get_boot_and_system_time_wstr(&pfri
->FileName
[filename_string_length
], s
)){
864 filename_string_length
+= s
;
866 //Fill rename information (FileNameLength is in bytes)
867 pfri
->FileNameLength
= static_cast<unsigned long>(sizeof(wchar_t)*(filename_string_length
));
871 //Final step: change the name of the in-use file:
872 io_status_block_t io
;
873 if(0 != pNtSetInformationFile(fh
, &io
, pfri
, sizeof(mem_t::ren_t
), file_rename_information
)){
884 } //namespace interprocess
887 #include <boost/interprocess/detail/config_end.hpp>
889 #endif //#ifdef BOOST_INTERPROCESS_WIN32_SYNC_PRIMITIVES_HPP