Listing 6 WinSTL's token_information helper template
/* ///////////////////////////////////////////////////////////// * ... * * Extract from winstl_token_information.h * * Copyright (C) 2003, Synesis Software Pty Ltd. * (Licensed under the Synesis Software Standard Source License: * http://www.synesis.com.au/licenses/ssssl.html) * * ... * ////////////////////////////////////////////////////////// */ namespace winstl { template <TOKEN_INFORMATION_CLASS C> struct token_information_traits; template <> struct token_information_traits<TokenUser> { typedef TOKEN_USER data_type; }; ... // More specialisations of token_information_traits template< TOKEN_INFORMATION_CLASS C , ws_typename_param_k X = stlsoft::null_exception , ws_typename_param_k D = token_information_traits<C>::data_type , ws_typename_param_k A = processheap_allocator<ss_byte_t> > class token_information { public: typedef token_information<C, X, D, A> class_type; typedef token_information_traits<C> traits_type; typedef X exception_thrower_type; typedef D data_type; typedef A allocator_type; // Construction public: /// Constructs an instance from the given access token ws_explicit_k token_information(HANDLE hToken) : m_data(0) { DWORD cbRequired; DWORD dwError; ::GetTokenInformation(hToken, C, NULL, 0, &cbRequired); dwError = ::GetLastError(); if(ERROR_INSUFFICIENT_BUFFER != dwError) { // Report error exception_thrower_type()(dwError); } else { data_type *data = (data_type*)allocator_type().allocate(cbRequired); if(NULL == data) { // Report error exception_thrower_type()(ERROR_NOT_ENOUGH_MEMORY); // Set the last error, in case the client code is not // using exception reporting ::SetLastError(ERROR_NOT_ENOUGH_MEMORY); } else { if(!::GetTokenInformation(hToken, C, data, cbRequired, &cbRequired)) { // Scope the last error, in case the client code is not // using exception reporting dwError = ::GetLastError(); allocator_type().deallocate((ss_byte_t*)data); // Report error ::SetLastError(dwError); exception_thrower_type()(dwError); } else { // Success m_data = data; ::SetLastError(ERROR_SUCCESS); } } } } ~token_information() { allocator_type().deallocate((ss_byte_t*)m_data); } // Conversion public: operator data_type *(); operator data_type const *() const; data_type *operator ->(); data_type const *operator ->() const; ws_bool_t operator !() const; /// Members private: data_type *m_data; /// Not to be implemented private: token_information(token_information const &); token_information &operator =(token_information const &); }; } // namespace winstl