From d67f58b2fdba53ec46447f7bd37dd723289ca415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 28 May 2009 20:44:12 +0000 Subject: [PATCH] Bugs #3090, #3101, #2992, #2973, #2967 [SVN r53362] --- .../allocators/detail/node_pool.hpp | 4 +- .../containers/container/stable_vector.hpp | 11 + .../containers/container/vector.hpp | 8 +- include/boost/interprocess/detail/atomic.hpp | 92 +++++++ .../interprocess/detail/os_file_functions.hpp | 8 +- .../detail/os_thread_functions.hpp | 4 +- .../interprocess/detail/tmp_dir_helpers.hpp | 36 +-- .../boost/interprocess/detail/win32_api.hpp | 250 +++++++++++------- include/boost/interprocess/errors.hpp | 6 +- 9 files changed, 293 insertions(+), 126 deletions(-) diff --git a/include/boost/interprocess/allocators/detail/node_pool.hpp b/include/boost/interprocess/allocators/detail/node_pool.hpp index 7d7631b..1dd923c 100644 --- a/include/boost/interprocess/allocators/detail/node_pool.hpp +++ b/include/boost/interprocess/allocators/detail/node_pool.hpp @@ -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(reinterpret_cast(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(hook) - blocksize); } diff --git a/include/boost/interprocess/containers/container/stable_vector.hpp b/include/boost/interprocess/containers/container/stable_vector.hpp index 552b69c..471a979 100644 --- a/include/boost/interprocess/containers/container/stable_vector.hpp +++ b/include/boost/interprocess/containers/container/stable_vector.hpp @@ -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 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) { diff --git a/include/boost/interprocess/containers/container/vector.hpp b/include/boost/interprocess/containers/container/vector.hpp index 4c38e25..d6a51ff 100644 --- a/include/boost/interprocess/containers/container/vector.hpp +++ b/include/boost/interprocess/containers/container/vector.hpp @@ -477,7 +477,7 @@ class vector : private containers_detail::vector_alloc_holder //! throws or T's default or copy constructor throws. //! //! Complexity: 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 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 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); diff --git a/include/boost/interprocess/detail/atomic.hpp b/include/boost/interprocess/detail/atomic.hpp index b8a8086..98c2744 100644 --- a/include/boost/interprocess/detail/atomic.hpp +++ b/include/boost/interprocess/detail/atomic.hpp @@ -461,6 +461,98 @@ inline boost::uint32_t atomic_cas32( } //namespace interprocess{ } //namespace boost{ +#elif defined(__IBMCPP__) && (__IBMCPP__ >= 800) && defined(_AIX) + +#include + +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(__lwarx(reinterpret_cast(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(mem), static_cast(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! diff --git a/include/boost/interprocess/detail/os_file_functions.hpp b/include/boost/interprocess/detail/os_file_functions.hpp index 369d45b..5109aa8 100644 --- a/include/boost/interprocess/detail/os_file_functions.hpp +++ b/include/boost/interprocess/detail/os_file_functions.hpp @@ -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"; } } diff --git a/include/boost/interprocess/detail/os_thread_functions.hpp b/include/boost/interprocess/detail/os_thread_functions.hpp index 4d2e3dd..1274500 100644 --- a/include/boost/interprocess/detail/os_thread_functions.hpp +++ b/include/boost/interprocess/detail/os_thread_functions.hpp @@ -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() diff --git a/include/boost/interprocess/detail/tmp_dir_helpers.hpp b/include/boost/interprocess/detail/tmp_dir_helpers.hpp index ee755e4..82391ec 100644 --- a/include/boost/interprocess/detail/tmp_dir_helpers.hpp +++ b/include/boost/interprocess/detail/tmp_dir_helpers.hpp @@ -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())){ diff --git a/include/boost/interprocess/detail/win32_api.hpp b/include/boost/interprocess/detail/win32_api.hpp index cfe0afc..7386761 100644 --- a/include/boost/interprocess/detail/win32_api.hpp +++ b/include/boost/interprocess/detail/win32_api.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #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(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(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 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 diff --git a/include/boost/interprocess/errors.hpp b/include/boost/interprocess/errors.hpp index cdd4208..ebd39d9 100644 --- a/include/boost/interprocess/errors.hpp +++ b/include/boost/interprocess/errors.hpp @@ -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);