mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
@@ -315,13 +315,13 @@ class private_node_pool_impl
|
||||
|
||||
private:
|
||||
//!Returns a reference to the block hook placed in the end of the block
|
||||
static inline node_t & get_block_hook (void *block, std::size_t blocksize)
|
||||
static node_t & get_block_hook (void *block, std::size_t blocksize)
|
||||
{
|
||||
return *reinterpret_cast<node_t*>(reinterpret_cast<char*>(block) + blocksize);
|
||||
}
|
||||
|
||||
//!Returns the starting address of the block reference to the block hook placed in the end of the block
|
||||
inline void *get_block_from_hook (node_t *hook, std::size_t blocksize)
|
||||
void *get_block_from_hook (node_t *hook, std::size_t blocksize)
|
||||
{
|
||||
return (reinterpret_cast<char*>(hook) - blocksize);
|
||||
}
|
||||
|
||||
@@ -90,6 +90,8 @@ class clear_on_destroy
|
||||
}
|
||||
|
||||
private:
|
||||
clear_on_destroy(const clear_on_destroy &);
|
||||
clear_on_destroy &operator=(const clear_on_destroy &);
|
||||
C &c_;
|
||||
bool do_clear_;
|
||||
};
|
||||
@@ -530,6 +532,15 @@ class stable_vector
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
}
|
||||
|
||||
explicit stable_vector(size_type n)
|
||||
: internal_data(Allocator()),impl(Allocator())
|
||||
{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
this->resize(n);
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
cod.release();
|
||||
}
|
||||
|
||||
stable_vector(size_type n,const T& t=T(),const Allocator& al=Allocator())
|
||||
: internal_data(al),impl(al)
|
||||
{
|
||||
|
||||
@@ -477,7 +477,7 @@ class vector : private containers_detail::vector_alloc_holder<A>
|
||||
//! throws or T's default or copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
vector(size_type n)
|
||||
explicit vector(size_type n)
|
||||
: base_t(allocator_type())
|
||||
{ this->resize(n); }
|
||||
|
||||
@@ -1723,6 +1723,10 @@ class vector : private containers_detail::vector_alloc_holder<A>
|
||||
void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
|
||||
{
|
||||
size_type n = std::distance(first, last);
|
||||
if(!n){
|
||||
this->prot_destroy_all();
|
||||
return;
|
||||
}
|
||||
//Check if we have enough memory or try to expand current memory
|
||||
size_type remaining = this->members_.m_capacity - this->members_.m_size;
|
||||
bool same_buffer_start;
|
||||
@@ -1749,7 +1753,7 @@ class vector : private containers_detail::vector_alloc_holder<A>
|
||||
if (this->size() >= n){
|
||||
//There is memory, but there are more old elements than new ones
|
||||
//Overwrite old elements with new ones
|
||||
// iG std::copy(first, last, start);
|
||||
assert(start);
|
||||
std::copy(first, last, start);
|
||||
//Destroy remaining old elements
|
||||
this->destroy_n(start + n, this->members_.m_size - n);
|
||||
|
||||
@@ -461,6 +461,98 @@ inline boost::uint32_t atomic_cas32(
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
#elif defined(__IBMCPP__) && (__IBMCPP__ >= 800) && defined(_AIX)
|
||||
|
||||
#include <builtins.h>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail{
|
||||
|
||||
//first define boost::uint32_t versions of __lwarx and __stwcx to avoid poluting
|
||||
//all the functions with casts
|
||||
|
||||
//! From XLC documenation :
|
||||
//! This function can be used with a subsequent stwcxu call to implement a
|
||||
//! read-modify-write on a specified memory location. The two functions work
|
||||
//! together to ensure that if the store is successfully performed, no other
|
||||
//! processor or mechanism can modify the target doubleword between the time
|
||||
//! lwarxu function is executed and the time the stwcxu functio ncompletes.
|
||||
//! "mem" : pointer to the object
|
||||
//! Returns the value at pointed to by mem
|
||||
inline boost::uint32_t lwarxu(volatile boost::uint32_t *mem)
|
||||
{
|
||||
return static_cast<boost::uint32_t>(__lwarx(reinterpret_cast<volatile int*>(mem)));
|
||||
}
|
||||
|
||||
//! "mem" : pointer to the object
|
||||
//! "val" : the value to store
|
||||
//! Returns true if the update of mem is successful and false if it is
|
||||
//!unsuccessful
|
||||
inline bool stwcxu(volatile boost::uint32_t* mem, boost::uint32_t val)
|
||||
{
|
||||
return (__stwcx(reinterpret_cast<volatile int*>(mem), static_cast<int>(val)) != 0);
|
||||
}
|
||||
|
||||
//! "mem": pointer to the object
|
||||
//! "val": amount to add
|
||||
//! Returns the old value pointed to by mem
|
||||
inline boost::uint32_t atomic_add32
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{
|
||||
boost::uint32_t oldValue;
|
||||
do
|
||||
{
|
||||
oldValue = lwarxu(mem);
|
||||
}while (!stwcxu(mem, oldValue+val));
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
//! Atomically increment an apr_uint32_t by 1
|
||||
//! "mem": pointer to the object
|
||||
//! Returns the old value pointed to by mem
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
|
||||
{ return atomic_add32(mem, 1); }
|
||||
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
||||
//! "mem": pointer to the atomic value
|
||||
//! Returns the old value pointed to by mem
|
||||
inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
|
||||
{ return atomic_add32(mem, (boost::uint32_t)-1); }
|
||||
|
||||
//! Atomically read an boost::uint32_t from memory
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
|
||||
{ return *mem; }
|
||||
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
||||
//! If they are the same swap the value with "with"
|
||||
//! "mem": pointer to the value
|
||||
//! "with" what to swap it with
|
||||
//! "cmp": the value to compare it to
|
||||
//! Returns the old value of *mem
|
||||
inline boost::uint32_t atomic_cas32
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
|
||||
{
|
||||
boost::uint32_t oldValue;
|
||||
boost::uint32_t valueToStore;
|
||||
do
|
||||
{
|
||||
oldValue = lwarxu(mem);
|
||||
} while (!stwcxu(mem, (oldValue == with) ? cmp : oldValue));
|
||||
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
//! Atomically set an boost::uint32_t in memory
|
||||
//! "mem": pointer to the object
|
||||
//! "param": val value that the object will assume
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ *mem = val; }
|
||||
|
||||
} //namespace detail
|
||||
} //namespace interprocess
|
||||
} //namespace boost
|
||||
|
||||
#else
|
||||
|
||||
#error No atomic operations implemented for this platform, sorry!
|
||||
|
||||
@@ -84,6 +84,7 @@ inline bool create_directory(const char *path)
|
||||
inline const char *get_temporary_path()
|
||||
{ return std::getenv("TMP"); }
|
||||
|
||||
|
||||
inline file_handle_t create_new_file
|
||||
(const char *name, mode_t mode = read_write, bool temporary = false)
|
||||
{
|
||||
@@ -311,12 +312,13 @@ inline bool create_directory(const char *path)
|
||||
|
||||
inline const char *get_temporary_path()
|
||||
{
|
||||
struct stat data;
|
||||
const char *dir = std::getenv("TMPDIR");
|
||||
if(!dir){
|
||||
if(!dir || ::stat(dir, &data) != 0){
|
||||
dir = std::getenv("TMP");
|
||||
if(!dir){
|
||||
if(!dir || ::stat(dir, &data) != 0){
|
||||
dir = std::getenv("TEMP");
|
||||
if(!dir){
|
||||
if(!dir || ::stat(dir, &data) != 0){
|
||||
dir = "/tmp";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ inline OS_thread_id_t get_invalid_thread_id()
|
||||
}
|
||||
|
||||
inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
|
||||
{ return 0 != ::pthread_equal(id1, id2); }
|
||||
{ return 0 != pthread_equal(id1, id2); }
|
||||
|
||||
inline void thread_yield()
|
||||
{ ::sched_yield(); }
|
||||
@@ -152,7 +152,7 @@ inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
|
||||
|
||||
inline bool equal_systemwide_thread_id(const OS_systemwide_thread_id_t &id1, const OS_systemwide_thread_id_t &id2)
|
||||
{
|
||||
return (0 != ::pthread_equal(id1.tid, id2.tid)) && (id1.pid == id2.pid);
|
||||
return (0 != pthread_equal(id1.tid, id2.tid)) && (id1.pid == id2.pid);
|
||||
}
|
||||
|
||||
inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id()
|
||||
|
||||
@@ -84,18 +84,30 @@ inline void get_bootstamp(std::string &s, bool add = false)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
inline void tmp_filename(const char *filename, std::string &tmp_name)
|
||||
inline void get_tmp_base_dir(std::string &tmp_name)
|
||||
{
|
||||
const char *tmp_dir = get_temporary_path();
|
||||
if(!tmp_dir){
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
winapi::get_shared_documents_folder(tmp_name);
|
||||
if(tmp_name.empty()){
|
||||
tmp_name = get_temporary_path();
|
||||
}
|
||||
#else
|
||||
tmp_name = get_temporary_path();
|
||||
#endif
|
||||
if(tmp_name.empty()){
|
||||
error_info err = system_error_code();
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
tmp_name = tmp_dir;
|
||||
|
||||
//Remove final null.
|
||||
tmp_name += "/boost_interprocess/";
|
||||
tmp_name += "/boost_interprocess";
|
||||
}
|
||||
|
||||
|
||||
inline void tmp_filename(const char *filename, std::string &tmp_name)
|
||||
{
|
||||
get_tmp_base_dir(tmp_name);
|
||||
//Remove final null.
|
||||
tmp_name += "/";
|
||||
#ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
|
||||
get_bootstamp(tmp_name, true);
|
||||
tmp_name += '/';
|
||||
@@ -106,15 +118,7 @@ inline void tmp_filename(const char *filename, std::string &tmp_name)
|
||||
inline void create_tmp_dir_and_get_filename(const char *filename, std::string &tmp_name)
|
||||
{
|
||||
//First get the temp directory
|
||||
const char *tmp_path = get_temporary_path();
|
||||
if(!tmp_path){
|
||||
error_info err = system_error_code();
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
|
||||
//Create Boost.Interprocess dir
|
||||
tmp_name = tmp_path;
|
||||
tmp_name += "/boost_interprocess";
|
||||
get_tmp_base_dir(tmp_name);
|
||||
|
||||
//If fails, check that it's because already exists
|
||||
if(!create_directory(tmp_name.c_str())){
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
@@ -145,6 +146,9 @@ static const long BootAndSystemstampLength = 16;
|
||||
static const long BootstampLength = 8;
|
||||
static const unsigned long MaxPath = 260;
|
||||
|
||||
//Keys
|
||||
static void * const hkey_local_machine = (void*)(unsigned long*)(long)(0x80000002);
|
||||
static unsigned long key_query_value = 0x0001;
|
||||
|
||||
} //namespace winapi {
|
||||
} //namespace interprocess {
|
||||
@@ -440,6 +444,12 @@ typedef long (__stdcall *RtlAppendUnicodeToString_t)(unicode_string_t *Destinati
|
||||
typedef long (__stdcall * NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
|
||||
typedef long (__stdcall * NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
|
||||
typedef unsigned long (__stdcall * GetMappedFileName_t)(void *, void *, wchar_t *, unsigned long);
|
||||
typedef unsigned long (__stdcall * GetMappedFileName_t)(void *, void *, wchar_t *, unsigned long);
|
||||
typedef long (__stdcall * RegOpenKey_t)(void *, const char *, void **);
|
||||
typedef long (__stdcall * RegOpenKeyEx_t)(void *, const char *, unsigned long, unsigned long, void **);
|
||||
typedef long (__stdcall * RegQueryValue_t)(void *, const char *, char *, long*);
|
||||
typedef long (__stdcall * RegQueryValueEx_t)(void *, const char *, unsigned long*, unsigned long*, unsigned char *, unsigned long*);
|
||||
typedef long (__stdcall * RegCloseKey_t)(void *);
|
||||
|
||||
} //namespace winapi {
|
||||
} //namespace interprocess {
|
||||
@@ -453,7 +463,7 @@ namespace boost {
|
||||
namespace interprocess {
|
||||
namespace winapi {
|
||||
|
||||
static inline unsigned long format_message
|
||||
inline unsigned long format_message
|
||||
(unsigned long dwFlags, const void *lpSource,
|
||||
unsigned long dwMessageId, unsigned long dwLanguageId,
|
||||
char *lpBuffer, unsigned long nSize, std::va_list *Arguments)
|
||||
@@ -463,34 +473,34 @@ static inline unsigned long format_message
|
||||
}
|
||||
|
||||
//And now, wrapper functions
|
||||
static inline void * local_free(void *hmem)
|
||||
inline void * local_free(void *hmem)
|
||||
{ return LocalFree(hmem); }
|
||||
|
||||
static inline unsigned long make_lang_id(unsigned long p, unsigned long s)
|
||||
inline unsigned long make_lang_id(unsigned long p, unsigned long s)
|
||||
{ return ((((unsigned short)(s)) << 10) | (unsigned short)(p)); }
|
||||
|
||||
static inline void sched_yield()
|
||||
inline void sched_yield()
|
||||
{ Sleep(1); }
|
||||
|
||||
static inline unsigned long get_current_thread_id()
|
||||
inline unsigned long get_current_thread_id()
|
||||
{ return GetCurrentThreadId(); }
|
||||
|
||||
static inline unsigned long get_current_process_id()
|
||||
inline unsigned long get_current_process_id()
|
||||
{ return GetCurrentProcessId(); }
|
||||
|
||||
static inline unsigned int close_handle(void* handle)
|
||||
inline unsigned int close_handle(void* handle)
|
||||
{ return CloseHandle(handle); }
|
||||
|
||||
static inline void * find_first_file(const char *lpFileName, win32_find_data_t *lpFindFileData)
|
||||
inline void * find_first_file(const char *lpFileName, win32_find_data_t *lpFindFileData)
|
||||
{ return FindFirstFileA(lpFileName, lpFindFileData); }
|
||||
|
||||
static inline bool find_next_file(void *hFindFile, win32_find_data_t *lpFindFileData)
|
||||
inline bool find_next_file(void *hFindFile, win32_find_data_t *lpFindFileData)
|
||||
{ return FindNextFileA(hFindFile, lpFindFileData) != 0; }
|
||||
|
||||
static inline bool find_close(void *handle)
|
||||
inline bool find_close(void *handle)
|
||||
{ return FindClose(handle) != 0; }
|
||||
|
||||
static inline bool duplicate_current_process_handle
|
||||
inline bool duplicate_current_process_handle
|
||||
(void *hSourceHandle, void **lpTargetHandle)
|
||||
{
|
||||
return 0 != DuplicateHandle
|
||||
@@ -499,41 +509,41 @@ static inline bool duplicate_current_process_handle
|
||||
, duplicate_same_access);
|
||||
}
|
||||
|
||||
static inline unsigned long get_last_error()
|
||||
inline unsigned long get_last_error()
|
||||
{ return GetLastError(); }
|
||||
|
||||
static inline void get_system_time_as_file_time(interprocess_filetime *filetime)
|
||||
inline void get_system_time_as_file_time(interprocess_filetime *filetime)
|
||||
{ GetSystemTimeAsFileTime(filetime); }
|
||||
|
||||
static inline bool file_time_to_local_file_time
|
||||
inline bool file_time_to_local_file_time
|
||||
(const interprocess_filetime *in, const interprocess_filetime *out)
|
||||
{ return 0 != FileTimeToLocalFileTime(in, out); }
|
||||
|
||||
static inline void *create_mutex(const char *name)
|
||||
inline void *create_mutex(const char *name)
|
||||
{ return CreateMutexA(0, 0, name); }
|
||||
|
||||
static inline void *open_mutex(const char *name)
|
||||
inline void *open_mutex(const char *name)
|
||||
{ return OpenMutexA(mutex_all_access, 0, name); }
|
||||
|
||||
static inline unsigned long wait_for_single_object(void *handle, unsigned long time)
|
||||
inline unsigned long wait_for_single_object(void *handle, unsigned long time)
|
||||
{ return WaitForSingleObject(handle, time); }
|
||||
|
||||
static inline int release_mutex(void *handle)
|
||||
inline int release_mutex(void *handle)
|
||||
{ return ReleaseMutex(handle); }
|
||||
|
||||
static inline int unmap_view_of_file(void *address)
|
||||
inline int unmap_view_of_file(void *address)
|
||||
{ return UnmapViewOfFile(address); }
|
||||
|
||||
static inline void *create_semaphore(long initialCount, const char *name)
|
||||
inline void *create_semaphore(long initialCount, const char *name)
|
||||
{ return CreateSemaphoreA(0, initialCount, (long)(((unsigned long)(-1))>>1), name); }
|
||||
|
||||
static inline int release_semaphore(void *handle, long release_count, long *prev_count)
|
||||
inline int release_semaphore(void *handle, long release_count, long *prev_count)
|
||||
{ return ReleaseSemaphore(handle, release_count, prev_count); }
|
||||
|
||||
static inline void *open_semaphore(const char *name)
|
||||
inline void *open_semaphore(const char *name)
|
||||
{ return OpenSemaphoreA(semaphore_all_access, 1, name); }
|
||||
|
||||
static inline void * create_file_mapping (void * handle, unsigned long access, unsigned long high_size, unsigned long low_size, const char * name)
|
||||
inline void * create_file_mapping (void * handle, unsigned long access, unsigned long high_size, unsigned long low_size, const char * name)
|
||||
{
|
||||
interprocess_security_attributes sa;
|
||||
interprocess_security_descriptor sd;
|
||||
@@ -549,86 +559,86 @@ static inline void * create_file_mapping (void * handle, unsigned long access, u
|
||||
//return CreateFileMappingA (handle, 0, access, high_size, low_size, name);
|
||||
}
|
||||
|
||||
static inline void * open_file_mapping (unsigned long access, const char *name)
|
||||
inline void * open_file_mapping (unsigned long access, const char *name)
|
||||
{ return OpenFileMappingA (access, 0, name); }
|
||||
|
||||
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)
|
||||
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)
|
||||
{ return MapViewOfFileEx(handle, file_access, highoffset, lowoffset, numbytes, base_addr); }
|
||||
|
||||
static inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes = 0)
|
||||
inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes = 0)
|
||||
{ return CreateFileA(name, access, file_share_read | file_share_write | file_share_delete, 0, creation_flags, attributes, 0); }
|
||||
|
||||
static inline bool delete_file(const char *name)
|
||||
inline bool delete_file(const char *name)
|
||||
{ return 0 != DeleteFileA(name); }
|
||||
|
||||
static inline bool move_file_ex(const char *source_filename, const char *destination_filename, unsigned long flags)
|
||||
inline bool move_file_ex(const char *source_filename, const char *destination_filename, unsigned long flags)
|
||||
{ return 0 != MoveFileExA(source_filename, destination_filename, flags); }
|
||||
|
||||
static inline void get_system_info(system_info *info)
|
||||
inline void get_system_info(system_info *info)
|
||||
{ GetSystemInfo(info); }
|
||||
|
||||
static inline int flush_view_of_file(void *base_addr, std::size_t numbytes)
|
||||
inline int flush_view_of_file(void *base_addr, std::size_t numbytes)
|
||||
{ return FlushViewOfFile(base_addr, numbytes); }
|
||||
|
||||
static inline bool get_file_size(void *handle, __int64 &size)
|
||||
inline bool get_file_size(void *handle, __int64 &size)
|
||||
{ return 0 != GetFileSizeEx(handle, &size); }
|
||||
|
||||
static inline bool create_directory(const char *name, interprocess_security_attributes* security)
|
||||
inline bool create_directory(const char *name, interprocess_security_attributes* security)
|
||||
{ return 0 != CreateDirectoryA(name, security); }
|
||||
|
||||
static inline bool remove_directory(const char *lpPathName)
|
||||
inline bool remove_directory(const char *lpPathName)
|
||||
{ return 0 != RemoveDirectoryA(lpPathName); }
|
||||
|
||||
static inline unsigned long get_temp_path(unsigned long length, char *buffer)
|
||||
inline unsigned long get_temp_path(unsigned long length, char *buffer)
|
||||
{ return GetTempPathA(length, buffer); }
|
||||
|
||||
static inline int set_end_of_file(void *handle)
|
||||
inline int set_end_of_file(void *handle)
|
||||
{ return 0 != SetEndOfFile(handle); }
|
||||
|
||||
static inline bool set_file_pointer_ex(void *handle, __int64 distance, __int64 *new_file_pointer, unsigned long move_method)
|
||||
inline bool set_file_pointer_ex(void *handle, __int64 distance, __int64 *new_file_pointer, unsigned long move_method)
|
||||
{ return 0 != SetFilePointerEx(handle, distance, new_file_pointer, move_method); }
|
||||
|
||||
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)
|
||||
inline bool lock_file_ex(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped)
|
||||
{ return 0 != LockFileEx(hnd, flags, reserved, size_low, size_high, overlapped); }
|
||||
|
||||
static inline bool unlock_file_ex(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped)
|
||||
inline bool unlock_file_ex(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped)
|
||||
{ return 0 != UnlockFileEx(hnd, reserved, size_low, size_high, overlapped); }
|
||||
|
||||
static inline bool write_file(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped)
|
||||
inline bool write_file(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped)
|
||||
{ return 0 != WriteFile(hnd, buffer, bytes_to_write, bytes_written, overlapped); }
|
||||
|
||||
static inline long interlocked_increment(long volatile *addr)
|
||||
inline long interlocked_increment(long volatile *addr)
|
||||
{ return BOOST_INTERLOCKED_INCREMENT(addr); }
|
||||
|
||||
static inline long interlocked_decrement(long volatile *addr)
|
||||
inline long interlocked_decrement(long volatile *addr)
|
||||
{ return BOOST_INTERLOCKED_DECREMENT(addr); }
|
||||
|
||||
static inline long interlocked_compare_exchange(long volatile *addr, long val1, long val2)
|
||||
inline long interlocked_compare_exchange(long volatile *addr, long val1, long val2)
|
||||
{ return BOOST_INTERLOCKED_COMPARE_EXCHANGE(addr, val1, val2); }
|
||||
|
||||
static inline long interlocked_exchange_add(long volatile* addend, long value)
|
||||
inline long interlocked_exchange_add(long volatile* addend, long value)
|
||||
{ return BOOST_INTERLOCKED_EXCHANGE_ADD(const_cast<long*>(addend), value); }
|
||||
|
||||
static inline long interlocked_exchange(long volatile* addend, long value)
|
||||
inline long interlocked_exchange(long volatile* addend, long value)
|
||||
{ return BOOST_INTERLOCKED_EXCHANGE(const_cast<long*>(addend), value); }
|
||||
|
||||
//Forward functions
|
||||
static inline void *load_library(const char *name)
|
||||
inline void *load_library(const char *name)
|
||||
{ return LoadLibraryA(name); }
|
||||
|
||||
static inline bool free_library(void *module)
|
||||
inline bool free_library(void *module)
|
||||
{ return 0 != FreeLibrary(module); }
|
||||
|
||||
static inline void *get_proc_address(void *module, const char *name)
|
||||
inline void *get_proc_address(void *module, const char *name)
|
||||
{ return GetProcAddress(module, name); }
|
||||
|
||||
static inline void *get_current_process()
|
||||
inline void *get_current_process()
|
||||
{ return GetCurrentProcess(); }
|
||||
|
||||
static inline void *get_module_handle(const char *name)
|
||||
inline void *get_module_handle(const char *name)
|
||||
{ return GetModuleHandleA(name); }
|
||||
|
||||
static inline void initialize_object_attributes
|
||||
inline void initialize_object_attributes
|
||||
( object_attributes_t *pobject_attr, unicode_string_t *name
|
||||
, unsigned long attr, void *rootdir, void *security_descr)
|
||||
|
||||
@@ -641,7 +651,7 @@ static inline void initialize_object_attributes
|
||||
pobject_attr->SecurityQualityOfService = 0;
|
||||
}
|
||||
|
||||
static inline void rtl_init_empty_unicode_string(unicode_string_t *ucStr, wchar_t *buf, unsigned short bufSize)
|
||||
inline void rtl_init_empty_unicode_string(unicode_string_t *ucStr, wchar_t *buf, unsigned short bufSize)
|
||||
{
|
||||
ucStr->Buffer = buf;
|
||||
ucStr->Length = 0;
|
||||
@@ -649,9 +659,15 @@ static inline void rtl_init_empty_unicode_string(unicode_string_t *ucStr, wchar_
|
||||
}
|
||||
|
||||
//Complex winapi based functions...
|
||||
struct library_unloader
|
||||
{
|
||||
void *lib_;
|
||||
library_unloader(void *module) : lib_(module){}
|
||||
~library_unloader(){ free_library(lib_); }
|
||||
};
|
||||
|
||||
//pszFilename must have room for at least MaxPath+1 characters
|
||||
static inline bool get_file_name_from_handle_function
|
||||
inline bool get_file_name_from_handle_function
|
||||
(void * hFile, wchar_t *pszFilename, std::size_t length, std::size_t &out_length)
|
||||
{
|
||||
if(length <= MaxPath){
|
||||
@@ -662,14 +678,7 @@ static inline bool get_file_name_from_handle_function
|
||||
if (0 == hiPSAPI)
|
||||
return 0;
|
||||
|
||||
class library_unloader
|
||||
{
|
||||
void *lib_;
|
||||
|
||||
public:
|
||||
library_unloader(void *module) : lib_(module){}
|
||||
~library_unloader(){ free_library(lib_); }
|
||||
} unloader(hiPSAPI);
|
||||
library_unloader unloader(hiPSAPI);
|
||||
|
||||
// Pointer to function getMappedFileName() in PSAPI.DLL
|
||||
GetMappedFileName_t pfGMFN =
|
||||
@@ -700,7 +709,7 @@ static inline bool get_file_name_from_handle_function
|
||||
return(bSuccess);
|
||||
}
|
||||
|
||||
static inline bool get_system_time_of_day_information(system_timeofday_information &info)
|
||||
inline bool get_system_time_of_day_information(system_timeofday_information &info)
|
||||
{
|
||||
NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t)
|
||||
get_proc_address(get_module_handle("ntdll.dll"), "NtQuerySystemInformation");
|
||||
@@ -712,7 +721,7 @@ static inline bool get_system_time_of_day_information(system_timeofday_informati
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool get_boot_time(unsigned char (&bootstamp) [BootstampLength])
|
||||
inline bool get_boot_time(unsigned char (&bootstamp) [BootstampLength])
|
||||
{
|
||||
system_timeofday_information info;
|
||||
bool ret = get_system_time_of_day_information(info);
|
||||
@@ -723,7 +732,7 @@ static inline bool get_boot_time(unsigned char (&bootstamp) [BootstampLength])
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool get_boot_and_system_time(unsigned char (&bootsystemstamp) [BootAndSystemstampLength])
|
||||
inline bool get_boot_and_system_time(unsigned char (&bootsystemstamp) [BootAndSystemstampLength])
|
||||
{
|
||||
system_timeofday_information info;
|
||||
bool ret = get_system_time_of_day_information(info);
|
||||
@@ -734,7 +743,7 @@ static inline bool get_boot_and_system_time(unsigned char (&bootsystemstamp) [Bo
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s) //will write BootstampLength chars
|
||||
inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s) //will write BootstampLength chars
|
||||
{
|
||||
if(s < (BootstampLength*2))
|
||||
return false;
|
||||
@@ -755,7 +764,7 @@ static inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s) //will
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp, std::size_t &s) //will write BootAndSystemstampLength chars
|
||||
inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp, std::size_t &s) //will write BootAndSystemstampLength chars
|
||||
{
|
||||
if(s < (BootAndSystemstampLength*2))
|
||||
return false;
|
||||
@@ -776,7 +785,25 @@ static inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp, std::
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool unlink_file(const char *filename)
|
||||
class handle_closer
|
||||
{
|
||||
void *handle_;
|
||||
public:
|
||||
handle_closer(void *handle) : handle_(handle){}
|
||||
~handle_closer(){ close_handle(handle_); }
|
||||
};
|
||||
|
||||
union ntquery_mem_t
|
||||
{
|
||||
object_name_information_t name;
|
||||
struct ren_t
|
||||
{
|
||||
file_rename_information_t info;
|
||||
wchar_t buf[32767];
|
||||
} ren;
|
||||
};
|
||||
|
||||
inline bool unlink_file(const char *filename)
|
||||
{
|
||||
try{
|
||||
NtSetInformationFile_t pNtSetInformationFile =
|
||||
@@ -795,44 +822,16 @@ static inline bool unlink_file(const char *filename)
|
||||
return false;
|
||||
}
|
||||
|
||||
class handle_closer
|
||||
{
|
||||
void *handle_;
|
||||
public:
|
||||
handle_closer(void *handle) : handle_(handle){}
|
||||
~handle_closer(){ close_handle(handle_); }
|
||||
} handle_closer(fh);
|
||||
|
||||
const std::size_t CharArraySize = 32767; //Max name length
|
||||
|
||||
union mem_t
|
||||
{
|
||||
object_name_information_t name;
|
||||
struct ren_t
|
||||
{
|
||||
file_rename_information_t info;
|
||||
wchar_t buf[CharArraySize];
|
||||
} ren;
|
||||
};
|
||||
|
||||
class auto_ptr
|
||||
{
|
||||
public:
|
||||
explicit auto_ptr(mem_t *ptr) : ptr_(ptr){}
|
||||
~auto_ptr(){ delete ptr_; }
|
||||
mem_t *get() const{ return (ptr_); }
|
||||
mem_t *operator->() const{ return this->get(); }
|
||||
private:
|
||||
mem_t *ptr_;
|
||||
} pmem(new mem_t);
|
||||
handle_closer h_closer(fh);
|
||||
|
||||
std::auto_ptr<ntquery_mem_t> pmem(new ntquery_mem_t);
|
||||
file_rename_information_t *pfri = (file_rename_information_t*)&pmem->ren.info;
|
||||
const std::size_t RenMaxNumChars =
|
||||
((char*)pmem.get() - (char*)&pmem->ren.info.FileName[0])/sizeof(wchar_t);
|
||||
|
||||
//Obtain file name
|
||||
unsigned long size;
|
||||
if(pNtQueryObject(fh, object_name_information, pmem.get(), sizeof(mem_t), &size)){
|
||||
if(pNtQueryObject(fh, object_name_information, pmem.get(), sizeof(ntquery_mem_t), &size)){
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -870,7 +869,7 @@ static inline bool unlink_file(const char *filename)
|
||||
|
||||
//Final step: change the name of the in-use file:
|
||||
io_status_block_t io;
|
||||
if(0 != pNtSetInformationFile(fh, &io, pfri, sizeof(mem_t::ren_t), file_rename_information)){
|
||||
if(0 != pNtSetInformationFile(fh, &io, pfri, sizeof(ntquery_mem_t::ren_t), file_rename_information)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -880,6 +879,61 @@ static inline bool unlink_file(const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
struct reg_closer
|
||||
{
|
||||
RegCloseKey_t func_;
|
||||
void *key_;
|
||||
reg_closer(RegCloseKey_t func, void *key) : func_(func), key_(key){}
|
||||
~reg_closer(){ (*func_)(key_); }
|
||||
};
|
||||
|
||||
inline void get_shared_documents_folder(std::string &s)
|
||||
{
|
||||
s.clear();
|
||||
void *hAdvapi = load_library("Advapi32.dll");
|
||||
if (hAdvapi){
|
||||
library_unloader unloader(hAdvapi);
|
||||
// Pointer to function RegOpenKeyA
|
||||
RegOpenKeyEx_t pRegOpenKey =
|
||||
(RegOpenKeyEx_t)get_proc_address(hAdvapi, "RegOpenKeyExA");
|
||||
if (pRegOpenKey){
|
||||
// Pointer to function RegCloseKey
|
||||
RegCloseKey_t pRegCloseKey =
|
||||
(RegCloseKey_t)get_proc_address(hAdvapi, "RegCloseKey");
|
||||
if (pRegCloseKey){
|
||||
// Pointer to function RegQueryValueA
|
||||
RegQueryValueEx_t pRegQueryValue =
|
||||
(RegQueryValueEx_t)get_proc_address(hAdvapi, "RegQueryValueExA");
|
||||
if (pRegQueryValue){
|
||||
//Open the key
|
||||
void *key;
|
||||
if ((*pRegOpenKey)( hkey_local_machine
|
||||
, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
|
||||
, 0
|
||||
, key_query_value
|
||||
, &key) == 0){
|
||||
reg_closer key_closer(pRegCloseKey, key);
|
||||
|
||||
//Obtain the value
|
||||
unsigned long size;
|
||||
unsigned long type;
|
||||
const char *const reg_value = "Common AppData";
|
||||
long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
|
||||
if(!err){
|
||||
//Size includes terminating NULL
|
||||
s.resize(size);
|
||||
err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
|
||||
if(!err)
|
||||
s.erase(s.end()-1);
|
||||
(void)err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace winapi
|
||||
} //namespace interprocess
|
||||
} //namespace boost
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
/// @cond
|
||||
static inline int system_error_code() // artifact of POSIX and WINDOWS error reporting
|
||||
inline int system_error_code() // artifact of POSIX and WINDOWS error reporting
|
||||
{
|
||||
#if (defined BOOST_INTERPROCESS_WINDOWS)
|
||||
return winapi::get_last_error();
|
||||
@@ -82,7 +82,7 @@ inline void fill_system_message(int sys_err_code, std::string &str)
|
||||
str.erase( str.size()-1 );
|
||||
}
|
||||
# else
|
||||
static inline void fill_system_message( int system_error, std::string &str)
|
||||
inline void fill_system_message( int system_error, std::string &str)
|
||||
{ str = std::strerror(system_error); }
|
||||
# endif
|
||||
/// @endcond
|
||||
@@ -179,7 +179,7 @@ static const ec_xlate ec_table[] =
|
||||
#endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
|
||||
};
|
||||
|
||||
static inline error_code_t lookup_error(native_error_t err)
|
||||
inline error_code_t lookup_error(native_error_t err)
|
||||
{
|
||||
const ec_xlate *cur = &ec_table[0],
|
||||
*end = cur + sizeof(ec_table)/sizeof(ec_xlate);
|
||||
|
||||
Reference in New Issue
Block a user