//*************************************************************************** // // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved // //*************************************************************************** #include "wmicom.h" #include "wmimof.h" #include "wmimap.h" #include #include #include //////////////////////////////////////////////////////////////////////////////////////////////// //********************************************************************************************** // Global Utility Functions //********************************************************************************************** //////////////////////////////////////////////////////////////////////////////////////////////// BOOL IsBinaryMofResourceEvent(LPOLESTR pGuid, GUID gGuid) { HRESULT hr; GUID Guid; hr = CLSIDFromString(pGuid,&Guid); if( SUCCEEDED(hr) ) { if( gGuid == Guid) { return TRUE; } } return FALSE; } ///////////////////////////////////////////////////////////////////// BOOL GetParsedPropertiesAndClass( BSTR Query,WCHAR * wcsClass ) { ParsedObjectPath * pParsedPath = NULL; // stdlibrary API CObjectPathParser Parser; BOOL fRc = FALSE; if( CObjectPathParser::NoError == Parser.Parse(Query, &pParsedPath)) { try { // NTRaid:136400 // 07/12/00 if(pParsedPath && !IsBadReadPtr( pParsedPath, sizeof(ParsedObjectPath))) { KeyRef * pKeyRef = NULL; pKeyRef = *(pParsedPath->m_paKeys); if(!IsBadReadPtr( pKeyRef, sizeof(KeyRef))) { wcscpy(wcsClass,pParsedPath->m_pClass); fRc = TRUE; } } Parser.Free(pParsedPath); } catch(...) { Parser.Free(pParsedPath); throw; } } return fRc; } //////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CheckIfThisIsAValidKeyProperty(WCHAR * wcsClass, WCHAR * wcsProperty, IWbemServices * p) { HRESULT hr = WBEM_E_FAILED; IWbemClassObject * pIHCO = NULL; IWbemQualifierSet * pIWbemQualifierSet = NULL; long lType = 0L; BSTR strPath = NULL; strPath = SysAllocString(wcsClass); if(strPath == NULL) { hr = E_OUTOFMEMORY; } else { hr = p->GetObject(strPath, 0,NULL, &pIHCO, NULL); SysFreeString(strPath); if (WBEM_S_NO_ERROR != hr) return WBEM_E_INVALID_CLASS; if(wcsProperty){ hr = pIHCO->GetPropertyQualifierSet(wcsProperty,&pIWbemQualifierSet); if( SUCCEEDED(hr) ){ CVARIANT v; hr = pIWbemQualifierSet->Get(L"key", 0, &v, 0); SAFE_RELEASE_PTR(pIWbemQualifierSet); } else{ hr = WBEM_E_INVALID_OBJECT_PATH; } } //============================================================ // Cleanup //============================================================ SAFE_RELEASE_PTR(pIHCO); } return hr; } //==================================================================== HRESULT GetParsedPath( BSTR ObjectPath,WCHAR * wcsClass, WCHAR * wcsInstance,IWbemServices * p ) { //============================================================ // Get the path and instance name and check to make sure it // is valid //============================================================ ParsedObjectPath * pParsedPath = NULL; // stdlibrary API CObjectPathParser Parser; HRESULT hr = WBEM_E_FAILED; if( 0 == Parser.Parse(ObjectPath, &pParsedPath)) { try { // NTRaid:136395 // 07/12/00 if(pParsedPath && !IsBadReadPtr( pParsedPath, sizeof(ParsedObjectPath))) { KeyRef * pKeyRef = NULL; pKeyRef = *(pParsedPath->m_paKeys); if( !IsBadReadPtr( pKeyRef, sizeof(KeyRef))) { hr = CheckIfThisIsAValidKeyProperty(pParsedPath->m_pClass, pKeyRef->m_pName,p ); if( SUCCEEDED(hr) ) { wcscpy(wcsClass,pParsedPath->m_pClass); wcscpy(wcsInstance,pKeyRef->m_vValue.bstrVal); } } } Parser.Free(pParsedPath); } catch(...) { hr = WBEM_E_UNEXPECTED; Parser.Free(pParsedPath); throw; } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL GetUserThreadToken(HANDLE * phThreadTok) { BOOL fRc = FALSE; HRESULT hRes = WbemCoImpersonateClient(); if (SUCCEEDED(hRes)) { // Now, let's check the impersonation level. First, get the thread token if (!OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, TRUE, phThreadTok)) { // If the CoImpersonate works, but the OpenThreadToken fails, we are running under the // process token (either local system, or if we are running with /exe, the rights of // the logged in user). In either case, impersonation rights don't apply. We have the // full rights of that user. if(GetLastError() == ERROR_NO_TOKEN) { // Try getting the thread token. If it fails it's because we're a system thread and // we don't yet have a thread token, so just impersonate self and try again. if( ImpersonateSelf(SecurityImpersonation) ) { if (!OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, TRUE, phThreadTok)) { fRc = FALSE; } else { fRc = TRUE; } } else { ERRORTRACE((THISPROVIDER,"ImpersonateSelf(SecurityImpersonation)failed")); } } } else { fRc = TRUE; } } if( !fRc ) { ERRORTRACE((THISPROVIDER,IDS_ImpersonationFailed)); } return fRc; } //////////////////////////////////////////////////////////////////////////////////////////////// SAFEARRAY * OMSSafeArrayCreate( IN VARTYPE vt, IN int iNumElements) { if(iNumElements < 1) { return NULL; } SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = iNumElements; return SafeArrayCreate(vt,1,rgsabound); } //////////////////////////////////////////////////////////////////////////////////////////////// void TranslateAndLog( WCHAR * wcsMsg ) { CAnsiUnicode XLate; char * pStr = NULL; if( SUCCEEDED(XLate.UnicodeToAnsi(wcsMsg,pStr))) { ERRORTRACE((THISPROVIDER,pStr)); ERRORTRACE((THISPROVIDER,"\n")); SAFE_DELETE_ARRAY(pStr); } } ///////////////////////////////////////////////////////////////////////////////////////////////// bool IsNT(void) { OSVERSIONINFO os; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if(!GetVersionEx(&os)) return FALSE; // should never happen return os.dwPlatformId == VER_PLATFORM_WIN32_NT; } //////////////////////////////////////////////////////////////////// BOOL SetGuid(WCHAR * pwcsGuidString, CLSID & Guid) { BOOL fRc = FALSE; CAutoWChar wcsGuid(MAX_PATH+2); if( wcsGuid.Valid() ) { fRc = TRUE; swprintf(wcsGuid,L"{%s}",pwcsGuidString ); if(FAILED(CLSIDFromString(wcsGuid, &Guid))) { if( FAILED(CLSIDFromString(pwcsGuidString, &Guid))) { fRc = FALSE; } } } return fRc; } //////////////////////////////////////////////////////////////////// HRESULT AllocAndCopy(WCHAR * wcsSource, WCHAR ** pwcsDest ) { HRESULT hr = WBEM_E_FAILED; int nLen = wcslen(wcsSource); if( nLen > 0 ) { *pwcsDest = new WCHAR[nLen + 2 ]; if( *pwcsDest ) { wcscpy(*pwcsDest,wcsSource); hr = S_OK; } } return hr; } //////////////////////////////////////////////////////////////////////////////////////////////// //********************************************************************************************** // Utility Classes //********************************************************************************************** //////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////// void _WMIHandleMap::AddRef() { InterlockedIncrement((long*)&RefCount); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// long _WMIHandleMap::Release() { ULONG cRef = InterlockedDecrement( (long*) &RefCount); if ( !cRef ){ WmiCloseBlock(WMIHandle); return 0; } return cRef; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// _WMIEventRequest::_WMIEventRequest() { pwcsClass = NULL ; pHandler = NULL; pServices = NULL; pCtx = NULL; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// _WMIEventRequest::~_WMIEventRequest() { SAFE_RELEASE_PTR(pServices); SAFE_RELEASE_PTR(pCtx); SAFE_DELETE_ARRAY(pwcsClass); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// void _WMIEventRequest::AddPtrs( IWbemObjectSink __RPC_FAR * Handler,IWbemServices __RPC_FAR * Services,IWbemContext __RPC_FAR * Ctx) { pHandler = Handler; pServices = Services; pCtx = Ctx; if( pServices ){ pServices->AddRef(); } if( pCtx ){ pCtx->AddRef(); } return; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// _AccessList::~_AccessList() { for( int i = 0; i < m_List.Size(); i++ ) { IWbemObjectAccess * pPtr = (IWbemObjectAccess *)m_List[i]; SAFE_RELEASE_PTR(pPtr); } m_List.Empty(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// _IdList::~_IdList() { for( int i = 0; i < m_List.Size(); i++ ) { ULONG_PTR* pPtr = (ULONG_PTR*)m_List[i]; SAFE_DELETE_PTR(pPtr); } m_List.Empty(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// _HandleList::~_HandleList() { for( int i = 0; i < m_List.Size(); i++ ) { HANDLE * pPtr = (HANDLE*)m_List[i]; SAFE_DELETE_PTR(pPtr); } m_List.Empty(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// _InstanceList::~_InstanceList() { for( int i = 0; i < m_List.Size(); i++ ) { WCHAR * p = (WCHAR*)m_List[i]; SAFE_DELETE_ARRAY(p); } m_List.Empty(); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// _OldClassInfo::~_OldClassInfo() { SAFE_DELETE_ARRAY(m_pClass); SAFE_DELETE_ARRAY(m_pPath); m_pClass = m_pPath = NULL; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// _OldClassList::~_OldClassList() { for( int i = 0; i < m_List.Size(); i++ ) { OldClassInfo * p = (OldClassInfo*)m_List[i]; SAFE_DELETE_PTR(p); } m_List.Empty(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// _WMIHiPerfHandleMap::_WMIHiPerfHandleMap(CWMIProcessClass * p, IWbemHiPerfEnum * pEnum) { m_pEnum = pEnum; if( pEnum ) { pEnum->AddRef(); } m_pClass = p; m_fEnumerator = FALSE; lHiPerfId = 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// _WMIHiPerfHandleMap::~_WMIHiPerfHandleMap() { SAFE_RELEASE_PTR(m_pEnum); lHiPerfId = 0; SAFE_DELETE_PTR(m_pClass); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// // Hi Perf Handle Map = Handles are addref'd and when released, then the block is closed // Critical Sections are handled elsewhere /////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CHiPerfHandleMap::Add( HANDLE hCurrent, ULONG_PTR lHiPerfId, CWMIProcessClass * p, IWbemHiPerfEnum * pEnum) { HRESULT hr = S_OK; WMIHiPerfHandleMap * pWMIMap = new WMIHiPerfHandleMap(p,pEnum); if( pWMIMap ) { try { pWMIMap->WMIHandle = hCurrent; pWMIMap->lHiPerfId = lHiPerfId; // 170635 if(CFlexArray::out_of_memory == m_List.Add(pWMIMap)) { SAFE_DELETE_PTR(pWMIMap); hr = E_OUTOFMEMORY; } } catch(...) { hr = WBEM_E_UNEXPECTED; SAFE_DELETE_PTR(pWMIMap); throw; } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CHiPerfHandleMap::FindHandleAndGetClassPtr( HANDLE & hCurrent, ULONG_PTR lHiPerfId,CWMIProcessClass *& p) { HRESULT hr = WBEM_E_NOT_FOUND; for( int i=0; ilHiPerfId == lHiPerfId ) { hCurrent = pMap->WMIHandle; p = pMap->m_pClass; hr = S_OK; } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CHiPerfHandleMap::GetFirstHandle(HANDLE & hCurrent,CWMIProcessClass *& p, IWbemHiPerfEnum *& pEnum) { m_nIndex=0; return GetNextHandle(hCurrent,p,pEnum); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CHiPerfHandleMap::GetNextHandle(HANDLE & hCurrent,CWMIProcessClass *& p, IWbemHiPerfEnum *& pEnum) { HRESULT hr = WBEM_S_NO_MORE_DATA; if( m_nIndex < m_List.Size() ) { WMIHiPerfHandleMap * pMap = (WMIHiPerfHandleMap *) m_List[m_nIndex]; hCurrent = pMap->WMIHandle; p = pMap->m_pClass; pEnum = pMap->m_pEnum; m_nIndex++; hr = S_OK; } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CHiPerfHandleMap::Delete( HANDLE & hCurrent, ULONG_PTR lHiPerfId ) { HRESULT hr = WBEM_E_NOT_FOUND; for( int i=0; ilHiPerfId == lHiPerfId ) { hCurrent = pMap->WMIHandle; SAFE_DELETE_PTR(pMap); m_List.RemoveAt(i); hr = S_OK; break; } } return hr; } //////////////////////////////////////////////////////////////////////////////////////////////// // When this function is called, release all the handles kept // THis function is called in the destructor of the class to release all teh WMIHiPerfHandleMap // classes allocated //////////////////////////////////////////////////////////////////////////////////////////////// void CHiPerfHandleMap::CloseAndReleaseHandles() { //=================================== // Go through the handles one at // a time and close them, then // delete the records from the // array //=================================== CAutoBlock((CCriticalSection *)&m_HandleCs); if( m_List.Size() > 0 ){ for(int i = 0; i < m_List.Size(); i++){ WMIHiPerfHandleMap * pWMIMap = (WMIHiPerfHandleMap *) m_List[i]; SAFE_DELETE_PTR(pWMIMap); } //================================================== // Remove it and deallocate memory //================================================== m_List.Empty(); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////// // Regular Handle Map = Expensize handles are always kept open - by default we, dont' know the lifetime // of these handles /////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CHandleMap::Add(CLSID Guid, HANDLE hCurrent, ULONG uDesiredAccess) { // Critical section is called elsewhere HRESULT hr = S_OK; WMIHandleMap * pWMIMap = new WMIHandleMap(); if( pWMIMap ) { try { pWMIMap->AddRef(); // Used for HiPerf counts, otherwise not referenced pWMIMap->WMIHandle = hCurrent; pWMIMap->Guid = Guid; pWMIMap->uDesiredAccess = uDesiredAccess; // 170635 if(CFlexArray::out_of_memory == m_List.Add(pWMIMap)) { hr = E_OUTOFMEMORY; SAFE_DELETE_PTR(pWMIMap); } } catch(...) { hr = WBEM_E_UNEXPECTED; SAFE_DELETE_PTR(pWMIMap); throw; } } return hr; } //////////////////////////////////////////////////////////////////////////////////////////////// int CHandleMap::ExistingHandleAlreadyExistsForThisGuidUseIt(CLSID Guid, HANDLE & hCurrentWMIHandle, BOOL & fCloseHandle, ULONG uDesiredAccess) { int nRc = ERROR_NOT_SUPPORTED; // Critical section is called elsewhere //===================================================== // Initialize stuff //===================================================== hCurrentWMIHandle = 0; fCloseHandle = TRUE; for(int i = 0; i < m_List.Size(); i++){ WMIHandleMap * pWMIMap = (WMIHandleMap*) m_List[i]; //================================================== // Compare and see if this guid already has a // handle assigned for it with the access permissions // that we want to use //================================================== if( pWMIMap->Guid == Guid ){ if( pWMIMap->uDesiredAccess == uDesiredAccess ){ hCurrentWMIHandle = pWMIMap->WMIHandle; pWMIMap->AddRef(); // Used for HiPerf Handles, otherwise not needed nRc = ERROR_SUCCESS; fCloseHandle = FALSE; break; } } } return nRc; } //////////////////////////////////////////////////////////////////////////////////////////////// // When this function is called, we need to close all of the handles that may have been kept // open for accumulation purposes //////////////////////////////////////////////////////////////////////////////////////////////// void CHandleMap::CloseAllOutstandingWMIHandles() { //=================================== // Go through the handles one at // a time and close them, then // delete the records from the // array //=================================== CAutoBlock((CCriticalSection *)&m_HandleCs); if( m_List.Size() > 0 ){ for(int i = 0; i < m_List.Size(); i++){ WMIHandleMap * pWMIMap = (WMIHandleMap*) m_List[i]; //================================================== // Inform WMI we are done with this guy //================================================== try { WmiCloseBlock(pWMIMap->WMIHandle); } catch(...) { // don't throw } SAFE_DELETE_PTR(pWMIMap); } //================================================== // Remove it and deallocate memory //================================================== m_List.Empty(); } } //////////////////////////////////////////////////////////////////////////////////////////////// // Used when we know the handles lifetimes //////////////////////////////////////////////////////////////////////////////////////////////// int CHandleMap::ReleaseHandle( HANDLE hCurrentWMIHandle ) { int nRc = ERROR_NOT_SUPPORTED; CAutoBlock((CCriticalSection *)&m_HandleCs); for(int i = 0; i < m_List.Size(); i++){ WMIHandleMap * pWMIMap = (WMIHandleMap*) m_List[i]; if( pWMIMap->WMIHandle == hCurrentWMIHandle ) { long RefCount = pWMIMap->Release(); // Used for HiPerf Handles, otherwise not needed if( !RefCount ) { // WmiCloseBlock(hCurrentWMIHandle); SAFE_DELETE_PTR( pWMIMap); m_List.RemoveAt(i); } nRc = ERROR_SUCCESS; break; } } return nRc; } //////////////////////////////////////////////////////////////////////////////////////////////// int CHandleMap::GetHandle(CLSID Guid, HANDLE & hCurrentWMIHandle ) { int nRc = ERROR_NOT_SUPPORTED; CAutoBlock((CCriticalSection *)&m_HandleCs); //===================================================== // Initialize stuff //===================================================== hCurrentWMIHandle = 0; for(int i = 0; i < m_List.Size(); i++){ WMIHandleMap * pWMIMap = (WMIHandleMap*) m_List[i]; if( pWMIMap->Guid == Guid ){ hCurrentWMIHandle = pWMIMap->WMIHandle; pWMIMap->AddRef(); // Used for HiPerf Handles, otherwise not needed nRc = ERROR_SUCCESS; break; } } return nRc; } //////////////////////////////////////////////////////////////////////////////////////////////// //********************************************************************************************** // Utility Classes: CANSIUNICODE //********************************************************************************************** //////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CAnsiUnicode::AllocateAndConvertAnsiToUnicode(char * pstr, WCHAR *& pszW) { HRESULT hr = WBEM_E_FAILED; pszW = NULL; int nSize = strlen(pstr); if (nSize != 0 ){ // Determine number of wide characters to be allocated for the // Unicode string. nSize++; pszW = new WCHAR[nSize * 2]; if (NULL != pszW){ try { // Covert to Unicode. MultiByteToWideChar(CP_ACP, 0, pstr, nSize,pszW,nSize); hr = S_OK; } catch(...) { SAFE_DELETE_ARRAY(pszW); hr = WBEM_E_UNEXPECTED; throw; } } } return hr; } //////////////////////////////////////////////////////////////////// HRESULT CAnsiUnicode::UnicodeToAnsi(WCHAR * pszW, char *& pAnsi) { ULONG cbAnsi, cCharacters; HRESULT hr = WBEM_E_FAILED; pAnsi = NULL; if (pszW != NULL){ cCharacters = wcslen(pszW)+1; // Determine number of bytes to be allocated for ANSI string. An // ANSI string can have at most 2 bytes per character (for Double // Byte Character Strings.) cbAnsi = cCharacters*2; pAnsi = new char[cbAnsi]; if (NULL != pAnsi) { try { // Convert to ANSI. if (0 != WideCharToMultiByte(CP_ACP, 0, pszW, cCharacters, pAnsi, cbAnsi, NULL, NULL)){ hr = S_OK; } } catch(...) { SAFE_DELETE_ARRAY(pAnsi); hr = WBEM_E_UNEXPECTED; throw; } } } return hr; } //************************************************************************************************************ ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // CWMIManagement // ////////////////////////////////////////////////////////////////////////////////////////////////////////////// //************************************************************************************************************ CWMIManagement::CWMIManagement( ) { m_pHandler = NULL; m_pServices = NULL; m_pCtx = NULL; m_pHandleMap = NULL; } ////////////////////////////////////////////////////////////////////////////////////// CWMIManagement::~CWMIManagement() { } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////// void CWMIManagement::SendPrivilegeExtendedErrorObject( HRESULT hrToReturn,WCHAR * wcsClass) { HRESULT hr,hRes; IWbemClassObject * pClass = NULL, *pInst=NULL; BOOL fSetStatus = FALSE; if( hrToReturn == WBEM_E_ACCESS_DENIED ){ TOKEN_PRIVILEGES * ptPriv = NULL; hr = GetListOfUserPrivileges(ptPriv); if( SUCCEEDED(hr ) ){ BSTR strPrivelegeStat = NULL; strPrivelegeStat = SysAllocString(L"Win32_PrivilegesStatus"); if(strPrivelegeStat != NULL) { hr = m_pServices->GetObject(strPrivelegeStat, 0,m_pCtx, &pClass, NULL); if( hr == S_OK){ //============================================================= // Get an instance of the extended class //============================================================= hr = pClass->SpawnInstance(0,&pInst); SAFE_RELEASE_PTR(pClass); if( pInst ){ CVARIANT varTmp; WCHAR * pwcsStr = NULL; CAnsiUnicode XLate; //========================================================= // Fill in description //========================================================= XLate.AllocateAndConvertAnsiToUnicode(IDS_ImpersonationFailed,pwcsStr); varTmp.SetStr(pwcsStr); hr = pInst->Put(L"Description", 0, &varTmp, NULL); SAFE_DELETE_ARRAY( pwcsStr ); //====================================================== // Initialize all of the necessary stuff and get the // definition of the class we are working with //====================================================== CWMIProcessClass ClassInfo(0); if( SUCCEEDED(ClassInfo.Initialize()) ) { ClassInfo.WMI()->SetWMIPointers(m_pHandleMap,m_pServices,m_pHandler,m_pCtx); ClassInfo.SetClass(wcsClass); SAFEARRAY *psaPrivNotHeld=NULL; SAFEARRAY *psaPrivReq=NULL; //========================================================= // Get PrivilegesRequired // The only place to get this, if possible, is from the // class //========================================================= hRes = ClassInfo.GetPrivilegesQualifer(&psaPrivReq); if( hRes == WBEM_S_NO_ERROR){ //========================================================= // Get PrivilegesNotHeld //========================================================= ProcessPrivileges(ptPriv,psaPrivNotHeld,psaPrivReq); //========================================================= // Send it off //========================================================= VARIANT v; if( psaPrivReq ){ VariantInit(&v); SAFEARRAY *pSafeArray = NULL; if ( SUCCEEDED ( SafeArrayCopy ((SAFEARRAY*)psaPrivReq , &pSafeArray ) ) ){ v.vt = VT_BSTR | VT_ARRAY; v.parray = pSafeArray; pInst->Put(L"PrivilegesRequired", 0, &v, NULL); VariantClear(&v); } } if( psaPrivNotHeld ){ VariantInit(&v); SAFEARRAY *pSafeArray = NULL; if ( SUCCEEDED ( SafeArrayCopy ((SAFEARRAY*)psaPrivNotHeld , &pSafeArray ) ) ){ v.vt = VT_BSTR | VT_ARRAY; v.parray = pSafeArray; pInst->Put(L"PrivilegesNotHeld", 0, &v, NULL); VariantClear(&v); } } } //========================================================= // Now, send this guy off... //========================================================= fSetStatus = TRUE; hr = m_pHandler->SetStatus(0,hrToReturn,NULL,pInst); if (psaPrivNotHeld) SafeArrayDestroy(psaPrivNotHeld); if (psaPrivReq) SafeArrayDestroy(psaPrivReq); } } SAFE_RELEASE_PTR(pInst); } SysFreeString(strPrivelegeStat); } } SAFE_DELETE_ARRAY(ptPriv); } if( !fSetStatus ){ hr = m_pHandler->SetStatus(0,hrToReturn,NULL,NULL); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CWMIManagement::SetErrorMessage(HRESULT hrToReturn,WCHAR * wcsClass,WCHAR * wcsMsg) { HRESULT hr; IWbemClassObject * pClass = NULL, *pInst=NULL; BOOL fSetStatus = FALSE; if( m_pHandler ) { BSTR strExtendedStat = NULL; switch( hrToReturn ){ case WBEM_E_ACCESS_DENIED: SendPrivilegeExtendedErrorObject(hrToReturn,wcsClass); break; case S_OK : hr = m_pHandler->SetStatus(0,hrToReturn,NULL,NULL); break; default: strExtendedStat = SysAllocString(L"__ExtendedStatus"); if(strExtendedStat != NULL) { hr = m_pServices->GetObject(strExtendedStat, 0,m_pCtx, &pClass, NULL); if( hr == S_OK){ hr = pClass->SpawnInstance(0,&pInst); if( pInst ){ CVARIANT varTmp; varTmp.SetStr(wcsMsg); hr = pInst->Put(L"Description", 0, &varTmp, NULL); hr = m_pHandler->SetStatus(0,hrToReturn,NULL,pInst); fSetStatus = TRUE; // Now log the error in the error log if( hrToReturn != S_OK ){ TranslateAndLog(varTmp.GetStr()); } } } if( !fSetStatus ){ hr = m_pHandler->SetStatus(0,hrToReturn,NULL,NULL); } SAFE_RELEASE_PTR(pClass); SAFE_RELEASE_PTR(pInst); SysFreeString(strExtendedStat); } else { hr = E_OUTOFMEMORY; } break; } } return hrToReturn; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CWMIManagement::GetListOfUserPrivileges(TOKEN_PRIVILEGES *& ptPriv) { HRESULT hr = WBEM_E_FAILED; // Get the privileges this user has DWORD dwTokenInfoLength = 0; DWORD dwSize = 0; HANDLE hThreadTok; if (IsNT()){ if( GetUserThreadToken(&hThreadTok) ){ // get information if (!GetTokenInformation(hThreadTok, TokenPrivileges, NULL, dwTokenInfoLength, &dwSize)){ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){ ptPriv = new TOKEN_PRIVILEGES[dwSize+2]; if( ptPriv ) { try { dwTokenInfoLength = dwSize; if(GetTokenInformation(hThreadTok, TokenPrivileges, (LPVOID)ptPriv, dwTokenInfoLength, &dwSize)) { hr = WBEM_NO_ERROR; } } catch(...) { SAFE_DELETE_ARRAY(ptPriv); hr = WBEM_E_UNEXPECTED; throw; } } } } // Done with this handle CloseHandle(hThreadTok); } } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// void CWMIManagement::ProcessPrivileges(TOKEN_PRIVILEGES *ptPriv, SAFEARRAY *& psaPrivNotHeld, SAFEARRAY * psaPrivReq ) { CAnsiUnicode XLate; BOOL fFound = FALSE; //============================================================== // Create a temporary working array, we know the MAX can be // the number of priv held + the number of priv req, so // allocate it for that //============================================================== CSAFEARRAY PrivReq( psaPrivReq ); long lMax = PrivReq.GetNumElements()+ptPriv->PrivilegeCount; psaPrivNotHeld = OMSSafeArrayCreate(VT_BSTR,lMax); long nCurrentIndex = 0; //============================================================== // Get how many privs are not held //============================================================== for( long n = 0; n < PrivReq.GetNumElements(); n++ ){ //============================================================== // Now, get the privileges held array ready to put stuff in //============================================================== TCHAR * pPrivReq = NULL; CBSTR bstr; if( S_OK != PrivReq.Get(n, &bstr)){ return; } fFound = FALSE; #ifndef UNICODE XLate.UnicodeToAnsi(bstr,pPrivReq); #else pPrivReq = (TCHAR *)bstr; #endif // NTRaid:136384 // 07/12/00 if(pPrivReq) { for(int i=0;i < (int)ptPriv->PrivilegeCount;i++){ DWORD dwPriv=128; TCHAR szPriv[NAME_SIZE*2]; if( LookupPrivilegeName( NULL, &ptPriv->Privileges[i].Luid, szPriv, &dwPriv)){ //============================================== // If we found the privilege, then the user has // it. break out //============================================== if( _tcscmp( pPrivReq,pPrivReq ) == 0 ){ fFound = TRUE; break; } } //================================================== // If we didn't find it, then we need to add it to // the list so we can notify the user //================================================== if( !fFound ){ if( S_OK == SafeArrayPutElement(psaPrivNotHeld, &nCurrentIndex, bstr)) { nCurrentIndex++; } } } } #ifndef UNICODE SAFE_DELETE_ARRAY(pPrivReq); #else pPrivReq = NULL; #endif } SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = nCurrentIndex; HRESULT hr = SafeArrayRedim(psaPrivNotHeld, rgsabound); PrivReq.Unbind(); }