00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00049 #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SEARCHPATH_SEQUENCE
00050 #define WINSTL_INCL_WINSTL_SYSTEM_HPP_SEARCHPATH_SEQUENCE
00051
00052 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00053 # define WINSTL_VER_SYSTEM_HPP_SEARCHPATH_SEQUENCE_MAJOR 4
00054 # define WINSTL_VER_SYSTEM_HPP_SEARCHPATH_SEQUENCE_MINOR 2
00055 # define WINSTL_VER_SYSTEM_HPP_SEARCHPATH_SEQUENCE_REVISION 3
00056 # define WINSTL_VER_SYSTEM_HPP_SEARCHPATH_SEQUENCE_EDIT 96
00057 #endif
00058
00059
00060
00061
00062
00063 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00064 # include <winstl/winstl.h>
00065 #endif
00066 #ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
00067 # include <winstl/filesystem/filesystem_traits.hpp>
00068 #endif
00069 #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
00070 # include <winstl/memory/processheap_allocator.hpp>
00071 #endif
00072 #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_VERSION
00073 # include <winstl/system/system_version.hpp>
00074 #endif
00075 #ifndef WINSTL_INCL_WINSTL_SYNCH_HPP_SPIN_MUTEX
00076 # include <winstl/synch/spin_mutex.hpp>
00077 #endif
00078 #ifndef WINSTL_INCL_WINSTL_HPP_REGISTRY_FUNCTIONS
00079
00080 #endif
00081 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00082 # include <stlsoft/memory/auto_buffer.hpp>
00083 #endif
00084 #ifndef STLSOFT_INCL_STLSOFT_SYNCH_HPP_LOCK_SCOPE
00085 # include <stlsoft/synch/lock_scope.hpp>
00086 #endif
00087 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00088 # include <stlsoft/util/std/iterator_helper.hpp>
00089 #endif
00090 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00091 # include <stlsoft/collections/util/collections.hpp>
00092 #endif
00093
00094
00095
00096
00097
00098 #ifndef _WINSTL_NO_NAMESPACE
00099 # if defined(_STLSOFT_NO_NAMESPACE) || \
00100 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00101
00102 namespace winstl
00103 {
00104 # else
00105
00106
00107 namespace stlsoft
00108 {
00109
00110 namespace winstl_project
00111 {
00112
00113 # endif
00114 #endif
00115
00116
00117
00118
00119
00120
00128 template< ss_typename_param_k C
00129 #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00130 , ss_typename_param_k T = filesystem_traits<C>
00131 #else
00132 , ss_typename_param_k T
00133 #endif
00134 >
00135 class basic_searchpath_sequence
00136 : public stlsoft_ns_qual(stl_collection_tag)
00137 {
00138 public:
00140 typedef C char_type;
00142 typedef T traits_type;
00144 typedef basic_searchpath_sequence<C, T> class_type;
00146 typedef char_type const* value_type;
00148 typedef value_type* pointer;
00150 typedef value_type const* const_pointer;
00152 typedef value_type& reference;
00154 typedef value_type const& const_reference;
00156 typedef ws_size_t size_type;
00158 typedef ws_ptrdiff_t difference_type;
00160 #if defined(STLSOFT_COMPILER_IS_BORLAND)
00161 typedef stlsoft_ns_qual(pointer_iterator)<
00162 #else
00163 typedef ss_typename_type_k stlsoft_ns_qual(pointer_iterator)<
00164 #endif
00165 value_type
00166 , const_pointer
00167 , const_reference
00168 >::type const_iterator;
00169 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00171 typedef stlsoft_ns_qual(const_reverse_iterator_base)<
00172 const_iterator
00173 , value_type
00174 , const_reference
00175 , const_pointer
00176 , difference_type
00177 > const_reverse_iterator;
00178 #endif
00179
00180
00181 public:
00185 basic_searchpath_sequence();
00191 basic_searchpath_sequence(
00192 ws_bool_t bIncludeApplicationDirectory
00193 , ws_bool_t bIncludeCurrentDirectory
00194 , ws_bool_t bApplicationDirectoryFirst = true
00195 );
00197 ~basic_searchpath_sequence() stlsoft_throw_0();
00198
00199
00200 public:
00204 const_iterator begin() const;
00208 const_iterator end() const;
00209
00210 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00214 const_reverse_iterator rbegin() const;
00218 const_reverse_iterator rend() const;
00219 #endif
00220
00221
00222 public:
00224 size_type size() const;
00226 ws_bool_t empty() const;
00228 static size_type max_size();
00229
00230
00231 public:
00233 value_type operator [](size_type index) const;
00234
00235
00236 private:
00237
00238
00239
00240
00241
00242
00243
00244 typedef processheap_allocator<char_type> main_allocator_type_;
00245 typedef processheap_allocator<value_type> value_allocator_type_;
00246 typedef stlsoft_ns_qual(auto_buffer_old)<
00247 char_type
00248 , main_allocator_type_
00249 , 1024
00250 > main_buffer_type_;
00251 typedef stlsoft_ns_qual(auto_buffer_old)<
00252 value_type
00253 , value_allocator_type_
00254 , 24
00255 > value_buffer_type_;
00256
00257 main_buffer_type_ m_buffer;
00258 value_buffer_type_ m_values;
00259 const_iterator m_end;
00260
00261
00262 private:
00263 void construct_(
00264 ws_bool_t bIncludeApplicationDirectory
00265 , ws_bool_t bIncludeCurrentDirectory
00266 , ws_bool_t bApplicationDirectoryFirst
00267 );
00268
00269
00270 #ifdef STLSOFT_COMPILER_IS_BORLAND
00271 typedef ws_int_t init_type;
00272 #else
00273 typedef ws_bool_t init_type;
00274 #endif
00275
00276 static char_type const* get_application_directory()
00277 {
00278 static char_type s_application_directory[WINSTL_CONST_MAX_PATH + 1];
00279 static sint32_t s_mx;
00280 spin_mutex mx(&s_mx);
00281 stlsoft_ns_qual(lock_scope)<spin_mutex> lock(mx);
00282 static init_type s_init = ws_false_v;
00283
00284 if(!s_init)
00285 {
00286 char_type dummy[WINSTL_CONST_MAX_PATH + 1];
00287 char_type* file_part;
00288
00289 traits_type::get_module_filename(NULL, s_application_directory, STLSOFT_NUM_ELEMENTS(s_application_directory));
00290 traits_type::get_full_path_name(s_application_directory, STLSOFT_NUM_ELEMENTS(dummy), dummy, &file_part);
00291 s_application_directory[file_part - &dummy[0] - 1] = '\0';
00292 s_init = ws_true_v;
00293 }
00294
00295 return s_application_directory;
00296 }
00297
00298 static char_type const* get_system_directory()
00299 {
00300 static char_type s_system_directory[WINSTL_CONST_MAX_PATH + 1];
00301 static sint32_t s_mx;
00302 spin_mutex mx(&s_mx);
00303 stlsoft_ns_qual(lock_scope)<spin_mutex> lock(mx);
00304 static init_type s_init = (traits_type::get_system_directory(s_system_directory, STLSOFT_NUM_ELEMENTS(s_system_directory)), ws_true_v);
00305
00306 return s_system_directory;
00307 }
00308
00309 static char_type const* get_windows_directory()
00310 {
00311 static char_type s_windows_directory[WINSTL_CONST_MAX_PATH + 1];
00312 static sint32_t s_mx;
00313 spin_mutex mx(&s_mx);
00314 stlsoft_ns_qual(lock_scope)<spin_mutex> lock(mx);
00315 static init_type s_init = (traits_type::get_windows_directory(s_windows_directory, STLSOFT_NUM_ELEMENTS(s_windows_directory)), ws_true_v);
00316
00317 return s_windows_directory;
00318 }
00319
00320 static char_type const* get_system16_directory()
00321 {
00322 static char_type s_system16_directory[WINSTL_CONST_MAX_PATH + 1];
00323 static sint32_t s_mx;
00324 spin_mutex mx(&s_mx);
00325 stlsoft_ns_qual(lock_scope)<spin_mutex> lock(mx);
00326 static init_type s_init = ws_false_v;
00327
00328 if(!s_init)
00329 {
00330 if(system_version::winnt())
00331 {
00332 char_type* file_part;
00333
00334 traits_type::get_full_path_name(get_system_directory(), STLSOFT_NUM_ELEMENTS(s_system16_directory), s_system16_directory, &file_part);
00335 traits_type::char_copy(file_part, disgusting_hack_("SYSTEM", L"SYSTEM"), 7);
00336 }
00337 else
00338 {
00339 s_system16_directory[0] = '\0';
00340 }
00341
00342 s_init = ws_true_v;
00343 }
00344
00345 return s_system16_directory;
00346 }
00347
00348 static ws_size_t directories_total()
00349 {
00350 ws_size_t cch = 0;
00351
00352 cch += 1 + traits_type::str_len(get_application_directory());
00353 cch += 1 + traits_type::get_current_directory(static_cast<char*>(NULL), 0);
00354 cch += 1 + traits_type::str_len(get_system_directory());
00355 cch += 1 + traits_type::str_len(get_system16_directory());
00356 cch += 1 + traits_type::str_len(get_windows_directory());
00357 cch += 1 + traits_type::get_environment_variable(disgusting_hack_("PATH", L"PATH"), NULL, 0);
00358
00359 return cch;
00360 }
00361
00362 static ws_size_t num_paths()
00363 {
00364 ws_size_t cPaths = 0;
00365 ws_size_t cch = traits_type::get_environment_variable(disgusting_hack_("PATH", L"PATH"), NULL, 0);
00366 main_buffer_type_ buffer(1 + cch);
00367 char_type const* begin = &buffer[0];
00368 char_type const* end = begin + cch;
00369 char_type const* last;
00370
00371 traits_type::get_environment_variable(disgusting_hack_("PATH", L"PATH"), &buffer[0], buffer.size());
00372
00373 for(; begin != end; ++begin)
00374 {
00375 if(*begin != ';')
00376 {
00377 break;
00378 }
00379 }
00380
00381 for(last = begin; begin != end; ++begin)
00382 {
00383 if(*begin == ';')
00384 {
00385 if(1 < begin - last)
00386 {
00387 ++cPaths;
00388 }
00389
00390 last = begin + 1;
00391 }
00392 }
00393
00394 if(1 < begin - last)
00395 {
00396 ++cPaths;
00397 }
00398
00399 return cPaths;
00400 }
00401
00402 static ws_bool_t is_curr_dir_last_()
00403 {
00404 if( system_version::winnt() &&
00405 system_version::major() >= 5 &&
00406 system_version::minor() == 1)
00407 {
00408 ws_bool_t res = false;
00409 HKEY hkey;
00410 LRESULT lRes = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE
00411 , L"SYSTEM\\CurrentControlSet\\Control\\Session Manager"
00412 , 0
00413 , KEY_QUERY_VALUE
00414 , &hkey);
00415
00416 if(ERROR_SUCCESS == lRes)
00417 {
00418 DWORD type;
00419 DWORD data;
00420 DWORD cbData = sizeof(data);
00421
00422 lRes = ::RegQueryValueExW(hkey, L"SafeDllSearchMode", NULL, &type, reinterpret_cast<LPBYTE>(&data), &cbData);
00423 if(ERROR_SUCCESS == lRes)
00424 {
00425 if(1 == data)
00426 {
00427 res = true;
00428 }
00429 }
00430
00431 ::RegCloseKey(hkey);
00432 }
00433
00434 return res;
00435 }
00436 else
00437 {
00438 return false;
00439 }
00440 }
00441
00442
00443 static char_type const* disgusting_hack_(ws_char_a_t* literal_a, ws_char_w_t* literal_w)
00444 {
00445 #if defined(STLSOFT_COMPILER_IS_DMC)
00446 if(sizeof(char_type) == sizeof(ws_char_w_t))
00447 {
00448 return static_cast<char_type*>(static_cast<void*>(literal_w));
00449 }
00450 else
00451 {
00452 return static_cast<char_type*>(static_cast<void*>(literal_a));
00453 }
00454 #else
00455 return static_cast<char_type*>((sizeof(char_type) == sizeof(ws_char_w_t)) ? static_cast<void*>(literal_w) : static_cast<void*>(literal_a));
00456 #endif
00457 }
00458
00459
00460 private:
00461 basic_searchpath_sequence(class_type const&);
00462 basic_searchpath_sequence const& operator =(class_type const&);
00463 };
00464
00465
00466
00467
00468
00473 typedef basic_searchpath_sequence<ws_char_a_t, filesystem_traits<ws_char_a_t> > searchpath_sequence_a;
00478 typedef basic_searchpath_sequence<ws_char_w_t, filesystem_traits<ws_char_w_t> > searchpath_sequence_w;
00483 typedef basic_searchpath_sequence<TCHAR, filesystem_traits<TCHAR> > searchpath_sequence;
00484
00486
00487
00488 #ifdef STLSOFT_UNITTEST
00489 #include "./unittest/searchpath_sequence_unittest_.h"
00490 #endif
00491
00493
00494
00495 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00496
00497
00498
00499 template< ss_typename_param_k C
00500 , ss_typename_param_k T
00501 >
00502 inline basic_searchpath_sequence<C, T>::basic_searchpath_sequence()
00503 : m_buffer(directories_total())
00504 , m_values(num_paths() + (system_version::winnt() ? 5 : 4))
00505 {
00506 construct_(true, true, true);
00507 }
00508
00509 template< ss_typename_param_k C
00510 , ss_typename_param_k T
00511 >
00512 inline basic_searchpath_sequence<C, T>::basic_searchpath_sequence(
00513 ws_bool_t bIncludeApplicationDirectory
00514 , ws_bool_t bIncludeCurrentDirectory
00515 , ws_bool_t bApplicationDirectoryFirst
00516 )
00517
00518 : m_buffer(directories_total())
00519 , m_values(num_paths() + (system_version::winnt() ? 5 : 4) - (!bIncludeApplicationDirectory + !bIncludeCurrentDirectory))
00520 {
00521 construct_(bIncludeApplicationDirectory, bIncludeCurrentDirectory, bApplicationDirectoryFirst);
00522 }
00523
00524 template< ss_typename_param_k C
00525 , ss_typename_param_k T
00526 >
00527 inline void basic_searchpath_sequence<C, T>::construct_(
00528 ws_bool_t bIncludeApplicationDirectory
00529 , ws_bool_t bIncludeCurrentDirectory
00530 , ws_bool_t bApplicationDirectoryFirst
00531 )
00532 {
00533
00534 ws_bool_t bIncludeCurrentDirectoryLast = bIncludeCurrentDirectory && is_curr_dir_last_();
00535
00536
00537
00538 char_type* psz = &m_buffer[0];
00539 char_type const** it = &m_values[0];
00540 char_type const* cwd = NULL;
00541
00542 psz[0] = '\0';
00543
00544 { for(int i = 0; i < 2; ++i) {
00545
00546 if((i & 1) != static_cast<int>(bApplicationDirectoryFirst))
00547 {
00548 if(bIncludeApplicationDirectory)
00549 {
00550 *it++ = psz;
00551
00552
00553 size_t n = traits_type::str_len(get_application_directory());
00554 traits_type::char_copy(psz, get_application_directory(), n + 1);
00555 psz += n;
00556 }
00557 }
00558 else
00559 {
00560 if(bIncludeCurrentDirectory)
00561 {
00562 cwd = psz;
00563
00564
00565 psz += traits_type::get_current_directory(WINSTL_CONST_MAX_PATH + 1, psz);
00566
00567 if(!bIncludeCurrentDirectoryLast)
00568 {
00569 *it++ = cwd;
00570 }
00571 }
00572 }
00573
00574 ++psz;
00575 }}
00576
00577 size_t n;
00578
00579
00580 *it++ = psz;
00581 n = traits_type::str_len(get_system_directory());
00582 traits_type::char_copy(psz, get_system_directory(), n + 1);
00583 psz += n;
00584 ++psz;
00585
00586
00587 if(system_version::winnt())
00588 {
00589 *it++ = psz;
00590 n = traits_type::str_len(get_system16_directory());
00591 traits_type::char_copy(psz, get_system16_directory(), n + 1);
00592 psz += n;
00593 ++psz;
00594 }
00595
00596
00597 *it++ = psz;
00598 n = traits_type::str_len(get_windows_directory());
00599 traits_type::char_copy(psz, get_windows_directory(), n + 1);
00600 psz += n;
00601 ++psz;
00602
00603
00604 if( bIncludeCurrentDirectory &&
00605 bIncludeCurrentDirectoryLast)
00606 {
00607 *it++ = cwd;
00608 }
00609
00610
00611 char_type const* begin = psz;
00612 char_type const* const end = begin + traits_type::get_environment_variable(disgusting_hack_("PATH", L"PATH"), psz, static_cast<DWORD>(m_buffer.end() - psz));
00613 char_type const* last;
00614
00615
00616 for(; begin != end; ++begin)
00617 {
00618 if(*begin != ';')
00619 {
00620 break;
00621 }
00622 }
00623
00624 for(last = begin; begin != end; ++begin)
00625 {
00626 if(*begin == ';')
00627 {
00628 if(1 < begin - last)
00629 {
00630 *it++ = last;
00631 }
00632
00633 *const_cast<char_type*>(begin) = '\0';
00634
00635 last = begin + 1;
00636 }
00637 }
00638
00639 if(1 < begin - last)
00640 {
00641 *it++ = last;
00642 }
00643
00644 m_end = it;
00645 }
00646
00647 template< ss_typename_param_k C
00648 , ss_typename_param_k T
00649 >
00650 inline basic_searchpath_sequence<C, T>::~basic_searchpath_sequence() stlsoft_throw_0()
00651 {}
00652
00653 template< ss_typename_param_k C
00654 , ss_typename_param_k T
00655 >
00656 inline ss_typename_type_ret_k basic_searchpath_sequence<C, T>::const_iterator basic_searchpath_sequence<C, T>::begin() const
00657 {
00658 return &m_values[0];
00659 }
00660
00661 template< ss_typename_param_k C
00662 , ss_typename_param_k T
00663 >
00664 inline ss_typename_type_ret_k basic_searchpath_sequence<C, T>::const_iterator basic_searchpath_sequence<C, T>::end() const
00665 {
00666 return m_end;
00667 }
00668
00669 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00670 template< ss_typename_param_k C
00671 , ss_typename_param_k T
00672 >
00673 inline ss_typename_type_ret_k basic_searchpath_sequence<C, T>::const_reverse_iterator basic_searchpath_sequence<C, T>::rbegin() const
00674 {
00675 return const_reverse_iterator(end());
00676 }
00677
00678 template< ss_typename_param_k C
00679 , ss_typename_param_k T
00680 >
00681 inline ss_typename_type_ret_k basic_searchpath_sequence<C, T>::const_reverse_iterator basic_searchpath_sequence<C, T>::rend() const
00682 {
00683 return const_reverse_iterator(begin());
00684 }
00685 #endif
00686
00687 template< ss_typename_param_k C
00688 , ss_typename_param_k T
00689 >
00690 inline ss_typename_type_ret_k basic_searchpath_sequence<C, T>::size_type basic_searchpath_sequence<C, T>::size() const
00691 {
00692 return static_cast<size_type>(end() - begin());
00693 }
00694
00695 template< ss_typename_param_k C
00696 , ss_typename_param_k T
00697 >
00698 inline ws_bool_t basic_searchpath_sequence<C, T>::empty() const
00699 {
00700 return begin() == end();
00701 }
00702
00703 template< ss_typename_param_k C
00704 , ss_typename_param_k T
00705 >
00706 inline ss_typename_type_ret_k basic_searchpath_sequence<C, T>::size_type basic_searchpath_sequence<C, T>::max_size()
00707 {
00708
00709 return static_cast<size_type>(-1) / WINSTL_CONST_MAX_PATH;
00710 }
00711
00712 template< ss_typename_param_k C
00713 , ss_typename_param_k T
00714 >
00715 inline ss_typename_type_ret_k basic_searchpath_sequence<C, T>::value_type basic_searchpath_sequence<C, T>::operator [](ss_typename_type_k basic_searchpath_sequence<C, T>::size_type index) const
00716 {
00717 WINSTL_MESSAGE_ASSERT("Invalid index in search path sequence", !(size() < index));
00718
00719 return begin()[index];
00720 }
00721
00722 #endif
00723
00724
00725
00726 #ifndef _WINSTL_NO_NAMESPACE
00727 # if defined(_STLSOFT_NO_NAMESPACE) || \
00728 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00729 }
00730 # else
00731 }
00732 }
00733 # endif
00734 #endif
00735
00736
00737
00738 #endif
00739
00740