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
00042
00043
00044
00051 #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_PID_SEQUENCE
00052 #define WINSTL_INCL_WINSTL_SYSTEM_HPP_PID_SEQUENCE
00053
00054 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00055 # define WINSTL_VER_WINSTL_SYSTEM_HPP_PID_SEQUENCE_MAJOR 2
00056 # define WINSTL_VER_WINSTL_SYSTEM_HPP_PID_SEQUENCE_MINOR 2
00057 # define WINSTL_VER_WINSTL_SYSTEM_HPP_PID_SEQUENCE_REVISION 2
00058 # define WINSTL_VER_WINSTL_SYSTEM_HPP_PID_SEQUENCE_EDIT 51
00059 #endif
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00076 # include <winstl/winstl.h>
00077 #endif
00078 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00079 # ifndef WINSTL_INCL_WINSTL_ERROR_HPP_WINDOWS_EXCEPTIONS
00080 # include <winstl/error/exceptions.hpp>
00081 # endif
00082 #endif
00083 #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
00084 # include <winstl/memory/processheap_allocator.hpp>
00085 #endif
00086 #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_VERSION
00087 # include <winstl/system/system_version.hpp>
00088 #endif
00089 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00090 # include <stlsoft/memory/auto_buffer.hpp>
00091 #endif
00092 #ifndef STLSOFT_INCL_STLSOFT_ALGORITHMS_HPP_POD
00093 # include <stlsoft/algorithms/pod.hpp>
00094 #endif
00095 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00096 # include <stlsoft/util/std/iterator_helper.hpp>
00097 #endif
00098 #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
00099 # include <stlsoft/collections/util/collections.hpp>
00100 #endif
00101 #if !defined(_PSAPI_H_) && \
00102 !defined(_PSAPI_H)
00103 # ifndef WINSTL_INCL_WINSTL_DL_HPP_DL_CALL
00104 # include <winstl/dl/dl_call.hpp>
00105 # endif
00106 #endif
00107
00108 #if !defined(STLSOFT_UNITTEST)
00109 # include <algorithm>
00110 #endif
00111
00112
00113
00114
00115
00116 #ifndef _WINSTL_NO_NAMESPACE
00117 # if defined(_STLSOFT_NO_NAMESPACE) || \
00118 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00119
00120 namespace winstl
00121 {
00122 # else
00123
00124
00125 namespace stlsoft
00126 {
00127
00128 namespace winstl_project
00129 {
00130
00131 # endif
00132 #endif
00133
00134
00135
00136
00137
00142 class pid_sequence
00143 : public stlsoft_ns_qual(stl_collection_tag)
00144 {
00147 public:
00149 typedef DWORD value_type;
00151 typedef processheap_allocator<value_type> allocator_type;
00153 typedef pid_sequence class_type;
00155 typedef value_type const* const_pointer;
00157 typedef value_type const& const_reference;
00159 typedef stlsoft_ns_qual(pointer_iterator)< value_type
00160 , const_pointer
00161 , const_reference
00162 >::type const_iterator;
00164 typedef ws_size_t size_type;
00166 typedef ws_ptrdiff_t difference_type;
00167 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00169 typedef stlsoft_ns_qual(const_reverse_bidirectional_iterator_base)< const_iterator
00170 , value_type
00171 , const_reference
00172 , const_pointer
00173 , difference_type
00174 > const_reverse_iterator;
00175 #endif
00176
00177 enum
00178 {
00179 elideIdle = 0x0001
00180 , elideSystem = 0x0002
00181 , sort = 0x0004
00182 };
00184
00187 public:
00189 ss_explicit_k pid_sequence(ws_uint32_t flags = elideIdle | elideSystem);
00191 pid_sequence(class_type const& rhs);
00193 ~pid_sequence() stlsoft_throw_0();
00195
00198 public:
00202 const_iterator begin() const;
00206 const_iterator end() const;
00207
00208 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00212 const_reverse_iterator rbegin() const;
00216 const_reverse_iterator rend() const;
00217 #endif
00219
00222 public:
00226 const_reference operator [](size_type index) const;
00228
00231 public:
00233 ws_bool_t empty() const;
00235 size_type size() const;
00237
00240 public:
00245 static value_type idleProcessId()
00246 {
00247 return 0;
00248 }
00253 static value_type systemProcessId()
00254 {
00255 ws_uint32_t major = system_version::major();
00256 ws_uint32_t minor = system_version::minor();
00257
00258 if(4 == major)
00259 {
00260 return 2;
00261 }
00262 else
00263 {
00264 if( 5 == major &&
00265 0 == minor)
00266 {
00267 return 8;
00268 }
00269 else if(5 == major &&
00270 1 == minor)
00271 {
00272 return 4;
00273 }
00274 else
00275 {
00276 return 4;
00277 }
00278 }
00279 }
00281
00284 private:
00285 typedef stlsoft_ns_qual(auto_buffer_old)< value_type
00286 , allocator_type
00287 , 64
00288 > buffer_type_;
00289
00290 buffer_type_ m_pids;
00292
00295 private:
00296 class_type& operator =(class_type const&);
00298 };
00299
00301
00302
00303 #ifdef STLSOFT_UNITTEST
00304 # include "./unittest/pid_sequence_unittest_.h"
00305 #endif
00306
00307
00308
00309
00310
00311 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00312
00313 inline pid_sequence::pid_sequence(ws_uint32_t flags)
00314 : m_pids(buffer_type_::internal_size())
00315 {
00316 DWORD cbReturned;
00317
00318 for(;;)
00319 {
00320 #if defined(_PSAPI_H_) || \
00321 defined(_PSAPI_H)
00322 if(!::EnumProcesses(&m_pids[0], sizeof(value_type) * m_pids.size(), &cbReturned))
00323 #else
00324 if(!dl_call<BOOL>( "PSAPI.DLL"
00325 , WINSTL_DL_CALL_WINx_STDCALL_LITERAL("EnumProcesses")
00326 , &m_pids[0]
00327 , sizeof(value_type) * m_pids.size()
00328 , &cbReturned))
00329 #endif
00330 {
00331 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00332 STLSOFT_THROW_X(windows_exception("Failed to enumerate processes", ::GetLastError()));
00333 #else
00334 m_pids.resize(0);
00335
00336 break;
00337 #endif
00338 }
00339 else
00340 {
00341 const size_type n = cbReturned / sizeof(value_type);
00342
00343 if(n < m_pids.size())
00344 {
00345 m_pids.resize(n);
00346
00347 break;
00348 }
00349 else
00350 {
00351 const size_type size = m_pids.size();
00352
00353 m_pids.resize(1);
00354
00355 if(!m_pids.resize(2 * size))
00356 {
00357
00358
00359 m_pids.resize(0);
00360
00361 break;
00362 }
00363 }
00364 }
00365 }
00366
00367 if(flags & (elideIdle | elideSystem))
00368 {
00369 value_type* begin = &*m_pids.begin();
00370 value_type* end = &*m_pids.end();
00371 value_type* pIdle = (flags & elideIdle) ? stlsoft_ns_qual_std(find)(begin, end, idleProcessId()) : end;
00372 value_type* pSystem = (flags & elideSystem) ? stlsoft_ns_qual_std(find)(begin, end, systemProcessId()) : end;
00373
00374
00375 if( end != pIdle &&
00376 end != pSystem &&
00377 pSystem == pIdle + 1)
00378 {
00379 pod_move(pSystem + 1, end, begin);
00380 m_pids.resize(m_pids.size() - 2);
00381 }
00382 else
00383 {
00384 if(end != pIdle)
00385 {
00386 pod_move(pIdle + 1, end, pIdle);
00387 m_pids.resize(m_pids.size() - 1);
00388 }
00389 if(end != pSystem)
00390 {
00391 pod_move(pSystem + 1, end, pSystem);
00392 m_pids.resize(m_pids.size() - 1);
00393 }
00394 }
00395 }
00396
00397 if(flags & sort)
00398 {
00399 stlsoft_ns_qual_std(sort)(m_pids.begin(), m_pids.end());
00400 }
00401 }
00402
00403 inline pid_sequence::pid_sequence(pid_sequence const& rhs)
00404 : m_pids(rhs.m_pids.size())
00405 {
00406 stlsoft_ns_qual_std(copy)(rhs.m_pids.begin(), rhs.m_pids.end(), m_pids.begin());
00407 }
00408
00409 inline pid_sequence::~pid_sequence() stlsoft_throw_0()
00410 {}
00411
00412 inline pid_sequence::const_iterator pid_sequence::begin() const
00413 {
00414 return &*m_pids.begin();
00415 }
00416
00417 inline pid_sequence::const_iterator pid_sequence::end() const
00418 {
00419 return &*m_pids.end();
00420 }
00421
00422 #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00423 inline pid_sequence::const_reverse_iterator pid_sequence::rbegin() const
00424 {
00425 return const_reverse_iterator(end());
00426 }
00427
00428 inline pid_sequence::const_reverse_iterator pid_sequence::rend() const
00429 {
00430 return const_reverse_iterator(begin());
00431 }
00432 #endif
00433
00434 inline pid_sequence::const_reference pid_sequence::operator [](pid_sequence::size_type index) const
00435 {
00436 WINSTL_MESSAGE_ASSERT("Index out of range", index < size());
00437
00438 return m_pids[index];
00439 }
00440
00441 inline ws_bool_t pid_sequence::empty() const
00442 {
00443 return m_pids.empty();
00444 }
00445
00446 inline pid_sequence::size_type pid_sequence::size() const
00447 {
00448 return m_pids.size();
00449 }
00450
00451 #endif
00452
00453
00454
00455
00456
00457 #ifndef _WINSTL_NO_NAMESPACE
00458 # if defined(_STLSOFT_NO_NAMESPACE) || \
00459 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00460 }
00461 # else
00462 }
00463 }
00464 # endif
00465 #endif
00466
00467
00468
00469 #endif
00470
00471