Back

// PSLPrivileges.cpp : Implementation of CPSLPrivileges

#include "stdafx.h"
#include "PSLPrivileges.h"


CPSLPrivileges::CPSLPrivileges()
{
}

HRESULT CPSLPrivileges::OnIndexOutOfRange()
{
   return MakeException(EX_INDEXOUTOFRANGE);
}

HRESULT CPSLPrivileges::FinalConstruct()
{
   PSL_BEGIN

   InternalUpdate();

   PSL_END
}

void CPSLPrivileges::FinalRelease()
{
}

void CPSLPrivileges::InternalUpdate()
{
   CCritSecLock cs(m_csCollection);

   m_coll.clear(); // Releases interfaces and clears the collection;
               // NOTE: .NET clients catch up interfaces, so takes
               // about 30 seconds before they are garbaged by .NET;

   HANDLE hToken = NULL;
   if(::OpenProcessToken(::GetCurrentProcess(), TOKEN_READ, &hToken))
   {
      DWORD dwLength = 0;
      ::GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwLength);
      LPBYTE pBuffer = new BYTE[dwLength];
      if(::GetTokenInformation(hToken, TokenPrivileges, pBuffer, dwLength, &dwLength))
      {
         TOKEN_PRIVILEGES * pPrivileges = (TOKEN_PRIVILEGES*)(LPVOID)pBuffer;
         LUID_AND_ATTRIBUTES * Privileges = pPrivileges->Privileges;
         DWORD dwCount = pPrivileges->PrivilegeCount;
         TCHAR PrivilegeName[64];
         for(DWORD i = 0;i < dwCount;i ++)
         {
            DWORD dwLength = 64;
            if(::LookupPrivilegeName(NULL, &Privileges[i].Luid, PrivilegeName, &dwLength))
            {
               CComObject<CPSLPrivilege> * pPrivilege = NULL;
               if(CComObject<CPSLPrivilege>::CreateInstance(&pPrivilege) == S_OK)
               {
                  pPrivilege->Initialize(Privileges[i], PrivilegeName);
                  // NOTE: Here the interface is also gets AddRef;
                  m_coll.push_back(CComPtr<IPSLPrivilege>(pPrivilege));
               }
            }
         }
      }
      delete []pBuffer;
      ::CloseHandle(hToken);
   }
}

////////////////////////////////////////////////////////////////////////
// Interface Implementation;
////////////////////////////////////////////////////////////////////////

STDMETHODIMP CPSLPrivileges::Update()
{
   PSL_BEGIN

   InternalUpdate();

   PSL_END
}

STDMETHODIMP CPSLPrivileges::Find(BSTR PrivilegeName, IPSLPrivilege ** ppValue)
{
   PSL_BEGIN

   *ppValue = NULL;
   _bstr_t sPrivilegeName(PrivilegeName);
   CCritSecLock cs(m_csCollection);

   for(PrivilegesType::iterator i = m_coll.begin();i != m_coll.end();i ++)
   {
      BSTR sName = NULL;
      if(i->m_T->get_Name(&sName) == S_OK)
      {
         _bstr_t s(sName);
         if(!::_tcsicmp(s, sPrivilegeName)) // Doing case-insensitive comparison;
         {
            IPSLPrivilege * pPrivilege = i->m_T;
            pPrivilege->AddRef();
            *ppValue = pPrivilege;
            break;
         }
      }
   }

   PSL_END
}

Top