|
|
/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name:
metabase.cpp
Abstract:
This file contains implementation of: CMetabase, CServerMethod
CMetabase encapsulates an IMSAdminBase pointer.
Author:
???
Revision History:
Mohit Srivastava 18-Dec-00
--*/
#include "iisprov.h"
#include "MultiSzHelper.h"
extern CDynSchema* g_pDynSch;
//
// CMetabaseCache
//
HRESULT CMetabaseCache::Populate( IMSAdminBase* i_pIABase, METADATA_HANDLE i_hKey) { DBG_ASSERT(i_pIABase); DBG_ASSERT(m_pBuf == NULL); // only call populate once
DWORD dwDataSetNumber = 0; DWORD dwRequiredBufSize = 0;
HRESULT hr = WBEM_S_NO_ERROR;
m_pBuf = m_pBufFixed; m_cbBuf = m_cbBufFixed; hr = i_pIABase->GetAllData( i_hKey, NULL, METADATA_INHERIT | METADATA_ISINHERITED, ALL_METADATA, ALL_METADATA, &m_dwNumEntries, &dwDataSetNumber, m_cbBuf, m_pBuf, &dwRequiredBufSize); if(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { m_pBufDynamic = new BYTE[dwRequiredBufSize]; if(m_pBufDynamic == NULL) { hr = WBEM_E_OUT_OF_MEMORY; goto exit; } m_pBuf = m_pBufDynamic; m_cbBuf = dwRequiredBufSize; hr = i_pIABase->GetAllData( i_hKey, NULL, METADATA_INHERIT | METADATA_ISINHERITED, ALL_METADATA, ALL_METADATA, &m_dwNumEntries, &dwDataSetNumber, m_cbBuf, m_pBuf, &dwRequiredBufSize); if(FAILED(hr)) { DBG_ASSERT(hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)); goto exit; } } else if(FAILED(hr)) { goto exit; }
//
// If we are here, we have a valid data buffer
//
m_hKey = i_hKey;
exit: if(FAILED(hr)) { m_pBuf = NULL; m_cbBuf = 0; } return hr; }
HRESULT CMetabaseCache::GetProp( DWORD i_dwId, DWORD i_dwUserType, DWORD i_dwDataType, LPBYTE* o_ppData, METADATA_GETALL_RECORD** o_ppmr) const { DBG_ASSERT(o_ppmr != NULL); DBG_ASSERT(o_ppData != NULL);
*o_ppmr = NULL; *o_ppData = NULL;
if(m_pBuf == NULL) { return MD_ERROR_DATA_NOT_FOUND; }
for(ULONG i = 0; i < m_dwNumEntries; i++) { METADATA_GETALL_RECORD* pmr = ((METADATA_GETALL_RECORD*)m_pBuf) + i; if( i_dwId == pmr->dwMDIdentifier && i_dwUserType == pmr->dwMDUserType && i_dwDataType == pmr->dwMDDataType) { *o_ppmr = pmr; *o_ppData = m_pBuf + pmr->dwMDDataOffset; return S_OK; } }
return MD_ERROR_DATA_NOT_FOUND; }
//
// CMetabase
//
CMetabase::CMetabase() { m_pNodeCache = NULL; HRESULT hr = CoCreateInstance( CLSID_MSAdminBase, NULL, CLSCTX_ALL, IID_IMSAdminBase2, (void**)&m_pIABase );
THROW_ON_ERROR(hr); }
CMetabase::~CMetabase() { CacheFree();
const LIST_ENTRY* ple = m_keyList.GetHead()->Flink; while(ple != m_keyList.GetHead()) { const CMetabaseKeyList::CKeyListNode* pNode = CONTAINING_RECORD(ple, CMetabaseKeyList::CKeyListNode, m_leEntry); DBG_ASSERT(pNode); ple = ple->Flink; CloseKey(pNode->hKey); }
if(m_pIABase) m_pIABase->Release(); }
HRESULT CMetabase::SaveData() { HRESULT hr = m_pIABase->SaveData(); return hr; }
HRESULT CMetabase::BackupWithPasswd( LPCWSTR i_wszMDBackupLocation, DWORD i_dwMDVersion, DWORD i_dwMDFlags, LPCWSTR i_wszPassword ) { HRESULT hr; hr = m_pIABase->BackupWithPasswd( i_wszMDBackupLocation, i_dwMDVersion, i_dwMDFlags, i_wszPassword); return hr; }
HRESULT CMetabase::DeleteBackup( LPCWSTR i_wszMDBackupLocation, DWORD i_dwMDVersion ) { HRESULT hr; hr = m_pIABase->DeleteBackup( i_wszMDBackupLocation, i_dwMDVersion );
return hr; }
HRESULT CMetabase::EnumBackups( LPWSTR io_wszMDBackupLocation, DWORD* o_pdwMDVersion, PFILETIME o_pftMDBackupTime, DWORD i_dwMDEnumIndex ) { HRESULT hr; hr = m_pIABase->EnumBackups( io_wszMDBackupLocation, o_pdwMDVersion, o_pftMDBackupTime, i_dwMDEnumIndex );
return hr; }
HRESULT CMetabase::RestoreWithPasswd( LPCWSTR i_wszMDBackupLocation, DWORD i_dwMDVersion, DWORD i_dwMDFlags, LPCWSTR i_wszPassword ) { HRESULT hr; hr = m_pIABase->RestoreWithPasswd( i_wszMDBackupLocation, i_dwMDVersion, i_dwMDFlags, i_wszPassword); return hr; }
HRESULT CMetabase::Export( LPCWSTR i_wszPasswd, LPCWSTR i_wszFileName, LPCWSTR i_wszSourcePath, DWORD i_dwMDFlags) { HRESULT hr; hr = m_pIABase->Export( i_wszPasswd, i_wszFileName, i_wszSourcePath, i_dwMDFlags); return hr; }
HRESULT CMetabase::Import( LPCWSTR i_wszPasswd, LPCWSTR i_wszFileName, LPCWSTR i_wszSourcePath, LPCWSTR i_wszDestPath, DWORD i_dwMDFlags) { HRESULT hr; hr = m_pIABase->Import( i_wszPasswd, i_wszFileName, i_wszSourcePath, i_wszDestPath, i_dwMDFlags); return hr; }
HRESULT CMetabase::RestoreHistory( LPCWSTR i_wszMDHistoryLocation, DWORD i_dwMDMajorVersion, DWORD i_dwMDMinorVersion, DWORD i_dwMDFlags) { HRESULT hr; hr = m_pIABase->RestoreHistory( i_wszMDHistoryLocation, i_dwMDMajorVersion, i_dwMDMinorVersion, i_dwMDFlags); return hr; }
HRESULT CMetabase::EnumHistory( LPWSTR io_wszMDHistoryLocation, DWORD* o_pdwMDMajorVersion, DWORD* o_pdwMDMinorVersion, PFILETIME o_pftMDHistoryTime, DWORD i_dwMDEnumIndex) { HRESULT hr; hr = m_pIABase->EnumHistory( io_wszMDHistoryLocation, o_pdwMDMajorVersion, o_pdwMDMinorVersion, o_pftMDHistoryTime, i_dwMDEnumIndex); return hr; } void CMetabase::CloseKey(METADATA_HANDLE i_hKey) { m_keyList.Remove(i_hKey); if(i_hKey && m_pIABase) { m_pIABase->CloseKey(i_hKey); DBGPRINTF((DBG_CONTEXT, "Close Key: %x\n", i_hKey)); } }
METADATA_HANDLE CMetabase::OpenKey(LPCWSTR i_wszKey, BOOL i_bWrite) { METADATA_HANDLE hKey = NULL;
DWORD dwMDAccessRequested; if(i_bWrite) dwMDAccessRequested = METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE; else dwMDAccessRequested = METADATA_PERMISSION_READ; HRESULT hr = m_pIABase->OpenKey( METADATA_MASTER_ROOT_HANDLE, i_wszKey, dwMDAccessRequested, DEFAULT_TIMEOUT_VALUE, // 30 seconds
&hKey );
THROW_ON_ERROR(hr);
hr = m_keyList.Add(hKey); if(FAILED(hr)) { m_pIABase->CloseKey(hKey); THROW_ON_ERROR(hr); }
DBGPRINTF((DBG_CONTEXT, "Open Key on %ws, returned handle %x\n", i_wszKey, hKey)); return hKey; }
//
// force to create or open a key by read/write permision
//
METADATA_HANDLE CMetabase::CreateKey(LPCWSTR i_wszKey) { HRESULT hr; METADATA_HANDLE hKey;
// open and return key if exists
hr = m_pIABase->OpenKey( METADATA_MASTER_ROOT_HANDLE, i_wszKey, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, DEFAULT_TIMEOUT_VALUE, // 30 seconds
&hKey );
if(FAILED(hr)) { // create key if not there
hr = m_pIABase->OpenKey( METADATA_MASTER_ROOT_HANDLE, NULL, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, DEFAULT_TIMEOUT_VALUE, // 30 seconds
&hKey ); THROW_ON_ERROR(hr);
// add key
hr = m_pIABase->AddKey(hKey, i_wszKey);
// close this root key first
m_pIABase->CloseKey(hKey); THROW_ON_ERROR(hr);
// now open the key just created
hr = m_pIABase->OpenKey( METADATA_MASTER_ROOT_HANDLE, i_wszKey, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, DEFAULT_TIMEOUT_VALUE, // 30 seconds
&hKey ); THROW_ON_ERROR(hr); }
hr = m_keyList.Add(hKey); if(FAILED(hr)) { m_pIABase->CloseKey(hKey); THROW_ON_ERROR(hr); }
DBGPRINTF((DBG_CONTEXT, "Create Key on %ws, returned handle %x\n", i_wszKey, hKey)); return hKey; }
//
// Check if the key is existed
//
bool CMetabase::CheckKey(LPCWSTR i_wszKey) { METADATA_HANDLE hKey = NULL;
HRESULT hr = m_pIABase->OpenKey( METADATA_MASTER_ROOT_HANDLE, i_wszKey, METADATA_PERMISSION_READ, DEFAULT_TIMEOUT_VALUE, // 30 seconds
&hKey ); if(hr == ERROR_SUCCESS) { DBGPRINTF((DBG_CONTEXT, "Open Key on %ws, returned handle %x\n", i_wszKey, hKey)); CloseKey(hKey); } return (hr == ERROR_PATH_BUSY) || (hr == ERROR_SUCCESS) ? true : false; }
//
// Check if the key is existed
//
HRESULT CMetabase::CheckKey( LPCWSTR i_wszKey, METABASE_KEYTYPE* i_pktSearchKeyType) { WCHAR wszBuf[MAX_BUF_SIZE]; METADATA_RECORD mr = { MD_KEY_TYPE, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, MAX_BUF_SIZE*sizeof(WCHAR), (unsigned char*)wszBuf, 0 };
DWORD dwLen; HRESULT hr = m_pIABase->GetData( METADATA_MASTER_ROOT_HANDLE, i_wszKey, &mr, &dwLen); if( hr == MD_ERROR_DATA_NOT_FOUND && METABASE_PROPERTY_DATA::s_KeyType.pDefaultValue ) { mr.pbMDData = (LPBYTE)METABASE_PROPERTY_DATA::s_KeyType.pDefaultValue; hr = S_OK; } else if(FAILED(hr)) { return hr; }
if( i_pktSearchKeyType && CUtils::CompareKeyType((LPCWSTR)mr.pbMDData, i_pktSearchKeyType) ) { return S_OK; }
return MD_ERROR_DATA_NOT_FOUND; }
HRESULT CMetabase::DeleteKey( METADATA_HANDLE i_hKey, LPCWSTR i_wszKeyPath) { return m_pIABase->DeleteKey( i_hKey, i_wszKeyPath ); }
void CMetabase::CacheInit( METADATA_HANDLE i_hKey) { HRESULT hr = S_OK; delete m_pNodeCache; m_pNodeCache = new CMetabaseCache(); if(m_pNodeCache == NULL) { THROW_ON_ERROR(WBEM_E_OUT_OF_MEMORY); } hr = m_pNodeCache->Populate( m_pIABase, i_hKey); THROW_ON_ERROR(hr); }
void CMetabase::CacheFree() { delete m_pNodeCache; m_pNodeCache = NULL; }
void CMetabase::Get( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, CWbemServices* i_pNamespace, _variant_t& io_vt, BOOL* io_pbIsInherited, BOOL* io_pbIsDefault ) { DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL);
switch (i_pmbp->dwMDDataType) { case DWORD_METADATA: GetDword(i_hKey, i_pmbp, io_vt, io_pbIsInherited, io_pbIsDefault); break;
case EXPANDSZ_METADATA: case STRING_METADATA: GetString(i_hKey, i_pmbp, io_vt, io_pbIsInherited, io_pbIsDefault); break;
case MULTISZ_METADATA: GetMultiSz(i_hKey, i_pmbp, i_pNamespace, io_vt, io_pbIsInherited, io_pbIsDefault); break;
case BINARY_METADATA: GetBinary(i_hKey, i_pmbp, io_vt, io_pbIsInherited, io_pbIsDefault); break;
default: DBGPRINTF((DBG_CONTEXT, "[CMetabase::Get] Cannot retrieve %ws because type %u is unknown\n", i_pmbp->pszPropName, i_pmbp->dwMDDataType)); break; } }
//
// GetDword
//
// A long or bool is returned in the VARIANT. The value is a bool if the
// METABASE_PROPERTY has a mask otherwise the DWORD is returned as a long.
// The METADATA_HANDLE is expected to be valid and open.
//
void CMetabase::GetDword( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, _variant_t& io_vt, BOOL* io_pbIsInherited, BOOL* io_pbIsDefault ) { DWORD dw = 0; DWORD dwRet = 0; HRESULT hr = WBEM_S_NO_ERROR;
BOOL bIsInherited = false; BOOL bIsDefault = false;
DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL);
METADATA_RECORD mr = { i_pmbp->dwMDIdentifier, i_pmbp->dwMDAttributes | METADATA_ISINHERITED, i_pmbp->dwMDUserType, i_pmbp->dwMDDataType, sizeof(DWORD), (unsigned char*)&dw, 0 };
if(m_pNodeCache && m_pNodeCache->GetHandle() == i_hKey) { METADATA_GETALL_RECORD* pmr = NULL; hr = m_pNodeCache->GetProp( i_pmbp->dwMDIdentifier, i_pmbp->dwMDUserType, i_pmbp->dwMDDataType, &mr.pbMDData, &pmr); if(SUCCEEDED(hr)) { DBG_ASSERT(pmr); mr.dwMDAttributes = pmr->dwMDAttributes; dw = *((DWORD*)mr.pbMDData); } } else { hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet); }
//
// Set out parameters
//
if (hr == MD_ERROR_DATA_NOT_FOUND) { bIsInherited = false; if(i_pmbp->pDefaultValue == NULL) { io_vt.vt = VT_NULL; bIsDefault = false; } else { if(i_pmbp->dwMDMask) { io_vt.vt = VT_BOOL; io_vt.boolVal = (i_pmbp->dwDefaultValue & i_pmbp->dwMDMask ? -1 : 0); } else { io_vt.vt = VT_I4; io_vt.lVal = i_pmbp->dwDefaultValue; } bIsDefault = true; } } else { THROW_E_ON_ERROR(hr,i_pmbp); if (i_pmbp->dwMDMask) { io_vt.vt = VT_BOOL; io_vt.boolVal = (dw & i_pmbp->dwMDMask? -1 : 0); } else { io_vt.vt = VT_I4; io_vt.lVal = dw; } bIsDefault = false; bIsInherited = mr.dwMDAttributes & METADATA_ISINHERITED; }
if(io_pbIsInherited != NULL) { *io_pbIsInherited = bIsInherited; } if(io_pbIsDefault != NULL) { *io_pbIsDefault = bIsDefault; } }
//
// GetStringFromMetabase
//
void CMetabase::GetString( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, _variant_t& io_vt, BOOL* io_pbIsInherited, BOOL* io_pbIsDefault ) { DWORD dwRet; HRESULT hr; WCHAR wszBufStack[MAX_BUF_SIZE];
BOOL bIsDefault = false; BOOL bIsInherited = false;
DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL);
METADATA_RECORD mr = { i_pmbp->dwMDIdentifier, i_pmbp->dwMDAttributes | METADATA_ISINHERITED, i_pmbp->dwMDUserType, i_pmbp->dwMDDataType, MAX_BUF_SIZE*sizeof(WCHAR), (LPBYTE)wszBufStack, 0 };
if(m_pNodeCache && m_pNodeCache->GetHandle() == i_hKey) { METADATA_GETALL_RECORD* pmr = NULL; hr = m_pNodeCache->GetProp( i_pmbp->dwMDIdentifier, i_pmbp->dwMDUserType, i_pmbp->dwMDDataType, &mr.pbMDData, &pmr); if(SUCCEEDED(hr)) { DBG_ASSERT(pmr); mr.dwMDAttributes = pmr->dwMDAttributes; } } else { hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet); }
//
// Set out parameters.
//
if (hr == MD_ERROR_DATA_NOT_FOUND) { bIsInherited = false; if(i_pmbp->pDefaultValue == NULL) { io_vt.vt = VT_NULL; bIsDefault = false; } else { io_vt = (LPWSTR)i_pmbp->pDefaultValue; bIsDefault = true; } } else { THROW_E_ON_ERROR(hr, i_pmbp);
io_vt = (LPWSTR)mr.pbMDData; bIsInherited = mr.dwMDAttributes & METADATA_ISINHERITED; bIsDefault = false; }
if(io_pbIsDefault) { *io_pbIsDefault = bIsDefault; } if(io_pbIsInherited) { *io_pbIsInherited = bIsInherited; } }
//
// GetMultiSz
//
void CMetabase::GetMultiSz( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, CWbemServices* i_pNamespace, _variant_t& io_vt, BOOL* io_pbIsInherited, BOOL* io_pbIsDefault ) { DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL);
DWORD dwRet; HRESULT hr; WCHAR *buffer = NULL;
BOOL bIsDefault = false; BOOL bIsInherited = false;
METADATA_RECORD mr; mr.dwMDIdentifier = i_pmbp->dwMDIdentifier; mr.dwMDAttributes = i_pmbp->dwMDAttributes | METADATA_ISINHERITED; mr.dwMDUserType = i_pmbp->dwMDUserType; mr.dwMDDataType = i_pmbp->dwMDDataType; mr.pbMDData = NULL; mr.dwMDDataLen = 0; mr.dwMDDataTag = 0;
try { if(m_pNodeCache && m_pNodeCache->GetHandle() == i_hKey) { METADATA_GETALL_RECORD* pmr = NULL; hr = m_pNodeCache->GetProp( i_pmbp->dwMDIdentifier, i_pmbp->dwMDUserType, i_pmbp->dwMDDataType, &mr.pbMDData, &pmr); if(SUCCEEDED(hr)) { DBG_ASSERT(pmr); mr.dwMDAttributes = pmr->dwMDAttributes; } } else { buffer = new WCHAR[10*MAX_BUF_SIZE]; if(buffer == NULL) { throw WBEM_E_OUT_OF_MEMORY; } buffer[0] = L'\0'; mr.pbMDData = (LPBYTE)buffer; mr.dwMDDataLen = 10*MAX_BUF_SIZE*sizeof(WCHAR);
hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet);
if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { delete [] buffer; buffer = new WCHAR[dwRet/sizeof(WCHAR) + 1]; if(buffer == NULL) { throw (HRESULT)WBEM_E_OUT_OF_MEMORY; } buffer[0] = L'\0'; mr.pbMDData = (LPBYTE)buffer; mr.dwMDDataLen = sizeof(WCHAR) + dwRet; hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet); } }
CMultiSz MultiSz(i_pmbp, i_pNamespace); if (hr == MD_ERROR_DATA_NOT_FOUND) { bIsInherited = false; if(i_pmbp->pDefaultValue == NULL) { io_vt.vt = VT_NULL; bIsDefault = false; } else { hr = MultiSz.ToWmiForm((LPWSTR)i_pmbp->pDefaultValue, &io_vt); THROW_E_ON_ERROR(hr,i_pmbp); bIsDefault = true; } } else { THROW_E_ON_ERROR(hr,i_pmbp); hr = MultiSz.ToWmiForm((LPWSTR)mr.pbMDData,&io_vt); THROW_E_ON_ERROR(hr,i_pmbp); bIsInherited = mr.dwMDAttributes & METADATA_ISINHERITED; bIsDefault = false; }
if(io_pbIsDefault) { *io_pbIsDefault = bIsDefault; } if(io_pbIsInherited) { *io_pbIsInherited = bIsInherited; }
//
// Cleanup
//
delete [] buffer; } catch (...) { delete [] buffer; throw; } }
void CMetabase::GetBinary( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, _variant_t& io_vt, BOOL* io_pbIsInherited, BOOL* io_pbIsDefault ) { DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL);
DWORD dwRet = 0; HRESULT hr = S_OK; CHAR* pszBuf = NULL; SAFEARRAY* safeArray = NULL;
BOOL bIsDefault = false; BOOL bIsInherited = false;
pszBuf = new CHAR[10*MAX_BUF_SIZE]; if(pszBuf == NULL) { throw (HRESULT)WBEM_E_OUT_OF_MEMORY; }
METADATA_RECORD mr = { i_pmbp->dwMDIdentifier, (i_pmbp->dwMDAttributes & !METADATA_REFERENCE) | METADATA_ISINHERITED, i_pmbp->dwMDUserType, i_pmbp->dwMDDataType, 10*MAX_BUF_SIZE*sizeof(CHAR), (unsigned char*)pszBuf, 0 };
hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet); if (hr == ERROR_INSUFFICIENT_BUFFER) { delete [] pszBuf; pszBuf = new CHAR[dwRet/sizeof(CHAR) + 1]; if(pszBuf == NULL) { hr = WBEM_E_OUT_OF_MEMORY; goto exit; } mr.pbMDData = (unsigned char*)pszBuf; mr.dwMDDataLen = dwRet/sizeof(CHAR) + 1; hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet); } if (hr == MD_ERROR_DATA_NOT_FOUND) { bIsInherited = false; if(i_pmbp->pDefaultValue == NULL) { io_vt.vt = VT_NULL; bIsDefault = false; hr = S_OK; } else { hr = CUtils::LoadSafeArrayFromByteArray( (LPBYTE)i_pmbp->pDefaultValue, i_pmbp->dwDefaultValue, io_vt); if(FAILED(hr)) { goto exit; } bIsDefault = true; } } else if(FAILED(hr)) { goto exit; } else { hr = CUtils::LoadSafeArrayFromByteArray((LPBYTE)pszBuf, mr.dwMDDataLen, io_vt); if(FAILED(hr)) { goto exit; } bIsInherited = mr.dwMDAttributes & METADATA_ISINHERITED; bIsDefault = false; }
//
// If everything succeeded, set out parameters.
//
if(io_pbIsInherited) { *io_pbIsInherited = bIsInherited; } if(io_pbIsDefault) { *io_pbIsDefault = bIsDefault; }
exit: delete [] pszBuf; if(FAILED(hr)) { throw (HRESULT)hr; } }
//
// Put
//
void CMetabase::Put( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, CWbemServices* i_pNamespace, _variant_t& i_vt, _variant_t* i_pvtOld, // can be NULL
DWORD i_dwQuals, // optional
BOOL i_bDoDiff // optional
) { DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL);
switch(i_pmbp->dwMDDataType) { case DWORD_METADATA: PutDword(i_hKey, i_pmbp, i_vt, i_pvtOld, i_dwQuals, i_bDoDiff); break;
case STRING_METADATA: case EXPANDSZ_METADATA: PutString(i_hKey, i_pmbp, i_vt, i_pvtOld, i_dwQuals, i_bDoDiff); break;
case MULTISZ_METADATA: PutMultiSz(i_hKey, i_pmbp, i_pNamespace, i_vt, i_pvtOld, i_dwQuals, i_bDoDiff); break;
case BINARY_METADATA: PutBinary(i_hKey, i_pmbp, i_vt, i_pvtOld, i_dwQuals, i_bDoDiff); break;
default: DBGPRINTF((DBG_CONTEXT, "[CMetabase::Put] Cannot set %ws because type %u is unknown\n", i_pmbp->pszPropName, i_pmbp->dwMDDataType)); break; } }
//
// PutDword
//
void CMetabase::PutDword( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, _variant_t& i_vt, _variant_t* i_pvtOld, // can be NULL
DWORD i_dwQuals, // optional
BOOL i_bDoDiff // optional
) { DWORD dw=0; DWORD dwOld=0; DWORD dwRet=0; HRESULT hr=0;
DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL);
METADATA_RECORD mr; mr.dwMDIdentifier = i_pmbp->dwMDIdentifier; mr.dwMDAttributes = i_pmbp->dwMDAttributes; mr.dwMDUserType = i_pmbp->dwMDUserType; mr.dwMDDataType = i_pmbp->dwMDDataType; mr.dwMDDataLen = sizeof(DWORD_METADATA); mr.pbMDData = (unsigned char*)&dwOld; mr.dwMDDataTag = 0;
// if it's the bit of a flag
if (i_vt.vt == VT_BOOL && i_pmbp->dwMDMask != 0) { // Read the entire flag from in the metabase so we can set the bit
hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet);
if(hr == MD_ERROR_DATA_NOT_FOUND) { if(i_pmbp->pDefaultValue != NULL) { dwOld = i_pmbp->dwDefaultValue; } else { dwOld = 0; } hr = ERROR_SUCCESS; }
if (hr == ERROR_SUCCESS) { if (i_vt.boolVal) dw = dwOld | i_pmbp->dwMDMask; else dw = dwOld & ~i_pmbp->dwMDMask; } else THROW_ON_ERROR(hr);
if(dw == -1) dw = 1; // true
} else if (i_vt.vt == VT_I4) { dw = i_vt.lVal; } else if (i_vt.vt == VT_BOOL) { DBG_ASSERT(false && "i_pmbp->dwMDMask should not be 0"); dw = i_vt.bVal; } else throw WBEM_E_INVALID_OBJECT; // Decide whether to write to metabase
bool bWriteToMb = true; if( (i_dwQuals & g_fForcePropertyOverwrite) == 0 && i_bDoDiff ) { bool bMatchOld = i_pvtOld != NULL && (i_pvtOld->vt == VT_I4 || i_pvtOld->vt == VT_BOOL) && *i_pvtOld == i_vt; bWriteToMb = !bMatchOld; }
if (bWriteToMb) { if( i_pmbp->fReadOnly ) { THROW_E_ON_ERROR(WBEM_E_READ_ONLY, i_pmbp); } mr.pbMDData = (unsigned char*)&dw; hr = m_pIABase->SetData(i_hKey, NULL, &mr); }
THROW_E_ON_ERROR(hr,i_pmbp); }
//
// PutString
//
void CMetabase::PutString( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, _variant_t& i_vt, _variant_t* i_pvtOld, // can be NULL
DWORD i_dwQuals, // optional
BOOL i_bDoDiff // optional
) { HRESULT hr=0;
DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL);
if(i_vt.vt != VT_BSTR) { throw (HRESULT)WBEM_E_INVALID_OBJECT; }
METADATA_RECORD mr; mr.dwMDIdentifier = i_pmbp->dwMDIdentifier; mr.dwMDAttributes = i_pmbp->dwMDAttributes; mr.dwMDUserType = i_pmbp->dwMDUserType; mr.dwMDDataType = i_pmbp->dwMDDataType; mr.dwMDDataTag = 0;
// Decide whether to write to metabase
bool bWriteToMb = true; if( (i_dwQuals & g_fForcePropertyOverwrite) == 0 && i_bDoDiff ) { bool bMatchOld = i_pvtOld != NULL && i_pvtOld->vt == VT_BSTR && _wcsicmp(i_pvtOld->bstrVal, i_vt.bstrVal) == 0; bWriteToMb = !bMatchOld; }
// Set the value, only if old and new values differ.
if(bWriteToMb) { if( i_pmbp->fReadOnly ) { THROW_E_ON_ERROR(WBEM_E_READ_ONLY, i_pmbp); } mr.dwMDDataLen = (wcslen(i_vt.bstrVal)+1)*sizeof(WCHAR); mr.pbMDData = (unsigned char*)i_vt.bstrVal;
hr = m_pIABase->SetData(i_hKey, NULL, &mr); }
THROW_E_ON_ERROR(hr,i_pmbp); }
//
// PutMultiSz
//
void CMetabase::PutMultiSz( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, CWbemServices* i_pNamespace, _variant_t& i_vt, _variant_t* i_pvtOld, // can be NULL
DWORD i_dwQuals, // optional
BOOL i_bDoDiff // optional
) { DWORD dwRet; DWORD dwRetOld; WCHAR *buffer = NULL; WCHAR *bufferOld = NULL; HRESULT hr=0;
DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL); DBG_ASSERT(i_pNamespace != NULL);
if(i_vt.vt != (VT_ARRAY | VT_BSTR) && i_vt.vt != (VT_ARRAY | VT_UNKNOWN)) { throw (HRESULT)WBEM_E_INVALID_OBJECT; }
METADATA_RECORD mr; mr.dwMDIdentifier = i_pmbp->dwMDIdentifier; mr.dwMDAttributes = i_pmbp->dwMDAttributes; mr.dwMDUserType = i_pmbp->dwMDUserType; mr.dwMDDataType = i_pmbp->dwMDDataType; mr.dwMDDataTag = 0;
try { CMultiSz MultiSz(i_pmbp, i_pNamespace); hr = MultiSz.ToMetabaseForm(&i_vt, &buffer, &dwRet); THROW_ON_ERROR(hr);
// Decide whether to write to metabase
bool bWriteToMb = true; if( (i_dwQuals & g_fForcePropertyOverwrite) == 0 && i_bDoDiff ) { bool bMatchOld = false; if(i_pvtOld != NULL && (i_pvtOld->vt == (VT_ARRAY | VT_BSTR) || i_pvtOld->vt == (VT_ARRAY | VT_UNKNOWN))) { hr = MultiSz.ToMetabaseForm(i_pvtOld, &bufferOld, &dwRetOld); THROW_ON_ERROR(hr); if(CUtils::CompareMultiSz(buffer, bufferOld)) { bMatchOld = true; } delete [] bufferOld; bufferOld = NULL; } bWriteToMb = !bMatchOld; }
if (bWriteToMb) { if( i_pmbp->fReadOnly ) { THROW_E_ON_ERROR(WBEM_E_READ_ONLY, i_pmbp); }
mr.pbMDData = (unsigned char*)buffer; mr.dwMDDataLen = dwRet*sizeof(WCHAR); if(buffer != NULL) { hr = m_pIABase->SetData(i_hKey, NULL, &mr); } else { //
// non-fatal if it fails
//
m_pIABase->DeleteData(i_hKey, NULL, i_pmbp->dwMDIdentifier, ALL_METADATA); }
} delete [] buffer; buffer = NULL; THROW_E_ON_ERROR(hr,i_pmbp); } catch (...) { delete [] buffer; delete [] bufferOld; throw; } }
//
// PutBinary
//
void CMetabase::PutBinary( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, _variant_t& i_vt, _variant_t* i_pvtOld, // can be NULL
DWORD i_dwQuals, // optional
BOOL i_bDoDiff // optional
) { DWORD dwRet; DWORD dwRetOld; LPBYTE buffer = NULL; LPBYTE bufferOld = NULL; HRESULT hr=0;
bool bWriteToMb = true;
DBG_ASSERT(i_hKey != NULL); DBG_ASSERT(i_pmbp != NULL);
if(i_vt.vt != (VT_ARRAY | VT_UI1)) { throw (HRESULT)WBEM_E_INVALID_OBJECT; }
METADATA_RECORD mr; mr.dwMDIdentifier = i_pmbp->dwMDIdentifier; mr.dwMDAttributes = i_pmbp->dwMDAttributes & !METADATA_REFERENCE; mr.dwMDUserType = i_pmbp->dwMDUserType; mr.dwMDDataType = i_pmbp->dwMDDataType; mr.dwMDDataTag = 0;
hr = CUtils::CreateByteArrayFromSafeArray(i_vt, &buffer, &dwRet); if(FAILED(hr)) { goto exit; }
// Decide whether to write to metabase
if( (i_dwQuals & g_fForcePropertyOverwrite) == 0 && i_bDoDiff ) { bool bMatchOld = false; if(i_pvtOld != NULL && i_pvtOld->vt == (VT_ARRAY | VT_UI1)) { hr = CUtils::CreateByteArrayFromSafeArray(*i_pvtOld, &bufferOld, &dwRetOld); if(FAILED(hr)) { goto exit; } if(CUtils::CompareByteArray(buffer, dwRet, bufferOld, dwRetOld)) { bMatchOld = true; } delete [] bufferOld; bufferOld = NULL; } bWriteToMb = !bMatchOld; }
if (bWriteToMb) { if( i_pmbp->fReadOnly ) { hr = WBEM_E_READ_ONLY; goto exit; }
mr.pbMDData = buffer; mr.dwMDDataLen = dwRet; if(buffer != NULL) { hr = m_pIABase->SetData(i_hKey, NULL, &mr); } else { //
// non-fatal if it fails
//
m_pIABase->DeleteData(i_hKey, NULL, i_pmbp->dwMDIdentifier, ALL_METADATA); }
} delete [] buffer; buffer = NULL; if(FAILED(hr)) { goto exit; }
exit: delete [] buffer; delete [] bufferOld; THROW_E_ON_ERROR(hr, i_pmbp); }
//
// DeleteData
//
void CMetabase::DeleteData( METADATA_HANDLE i_hKey, DWORD i_dwMDIdentifier, DWORD i_dwMDDataType) { HRESULT hr;
if(i_hKey == NULL) throw WBEM_E_INVALID_PARAMETER;
hr = m_pIABase->DeleteData( i_hKey, NULL, i_dwMDIdentifier, i_dwMDDataType );
if (hr == MD_ERROR_DATA_NOT_FOUND || hr == ERROR_SUCCESS) return;
THROW_ON_ERROR(hr); }
//
// DeleteData
//
void CMetabase::DeleteData( METADATA_HANDLE i_hKey, METABASE_PROPERTY* i_pmbp, bool i_bThrowOnRO) { HRESULT hr;
if(i_hKey == NULL || i_pmbp == NULL) throw WBEM_E_INVALID_PARAMETER;
if(i_pmbp->fReadOnly && i_bThrowOnRO) { THROW_E_ON_ERROR(WBEM_E_READ_ONLY, i_pmbp); }
hr = m_pIABase->DeleteData( i_hKey, NULL, i_pmbp->dwMDIdentifier, i_pmbp->dwMDDataType );
if (hr == MD_ERROR_DATA_NOT_FOUND || hr == ERROR_SUCCESS) return;
THROW_E_ON_ERROR(hr,i_pmbp); }
//
// Enumuerates all the subkeys of i_wszMDPath under i_hKey.
// If we hit a 'valid' subkey, set io_pktKeyTypeSearch to this subkey and return.
// A 'valid' subkey is one where io_pktKeyTypeSearch can be a (grand*)child.
//
HRESULT CMetabase::EnumKeys( METADATA_HANDLE i_hKey, LPCWSTR i_wszMDPath, //path to the key
LPWSTR io_wszMDName, //receives the name of the subkey --must be METADATA_MAX_NAME_LEN
DWORD* io_pdwMDEnumKeyIndex, //index of the subkey
METABASE_KEYTYPE*& io_pktKeyTypeSearch, bool i_bLookForMatchAtCurrentLevelOnly ) { HRESULT hr; DWORD dwRet; WCHAR wszBuf[MAX_BUF_SIZE];
// DBG_ASSERT(i_hKey != NULL);
// DBG_ASSERT(i_wszMDPath != NULL);
DBG_ASSERT(io_wszMDName != NULL); DBG_ASSERT(io_pdwMDEnumKeyIndex != NULL); DBG_ASSERT(io_pktKeyTypeSearch != NULL); while(1) { hr = m_pIABase->EnumKeys( i_hKey, i_wszMDPath, io_wszMDName, *io_pdwMDEnumKeyIndex); if(hr != ERROR_SUCCESS) { break; }
wszBuf[0] = L'\0';
METADATA_RECORD mr = { METABASE_PROPERTY_DATA::s_KeyType.dwMDIdentifier, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, MAX_BUF_SIZE*sizeof(WCHAR), (unsigned char*)wszBuf, 0 };
//
// Eg. blah/
//
_bstr_t bstrPath = L""; if(i_wszMDPath) { bstrPath += i_wszMDPath; bstrPath += L"/"; } //
// Eg. blah/1
//
bstrPath += io_wszMDName;
DBGPRINTF((DBG_CONTEXT, "CMetabase::EnumKeys::GetData (Key = 0x%x, bstrPath = %ws)\n", i_hKey, (LPWSTR)bstrPath)); hr = m_pIABase->GetData( i_hKey, bstrPath, &mr, &dwRet); if( hr == MD_ERROR_DATA_NOT_FOUND && METABASE_PROPERTY_DATA::s_KeyType.pDefaultValue ) { mr.pbMDData = (LPBYTE)METABASE_PROPERTY_DATA::s_KeyType.pDefaultValue; hr = S_OK; }
//
// If this is a 'valid' subkey, then set io_pktKeyTypeSearch and return.
//
if (hr == ERROR_SUCCESS) { if(i_bLookForMatchAtCurrentLevelOnly == false) { if(CheckKeyType((LPCWSTR)mr.pbMDData,io_pktKeyTypeSearch)) { break; } } else { if(CUtils::CompareKeyType((LPWSTR)mr.pbMDData,io_pktKeyTypeSearch)) { break; } } }
//
// Otherwise, go to next subkey.
//
(*io_pdwMDEnumKeyIndex) = (*io_pdwMDEnumKeyIndex)+1; }
return hr; }
void CMetabase::PutMethod( LPWSTR i_wszPath, DWORD i_id) { HRESULT hr = S_OK;
CServerMethod method; hr = method.Initialize(m_pIABase, i_wszPath); THROW_ON_ERROR(hr);
hr = method.ExecMethod(i_id); THROW_ON_ERROR(hr); }
//
// You are currently at i_wszKeyTypeCurrent in the metabase. You want to see
// if io_pktKeyTypeSearch can be contained somewhere further down the tree.
//
bool CMetabase::CheckKeyType( LPCWSTR i_wszKeyTypeCurrent, METABASE_KEYTYPE*& io_pktKeyTypeSearch ) { bool bRet = false; METABASE_KEYTYPE* pktKeyTypeCurrent = &METABASE_KEYTYPE_DATA::s_NO_TYPE;
if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_NO_TYPE) { return false; }
if(FAILED(g_pDynSch->GetHashKeyTypes()->Wmi_GetByKey(i_wszKeyTypeCurrent, &pktKeyTypeCurrent))) { return (io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsObject) ? true : false; }
if(pktKeyTypeCurrent == io_pktKeyTypeSearch) { return true; }
if( io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACL || io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACE || io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_IPSecurity ) { bRet = true; } else { bRet = g_pDynSch->IsContainedUnder(pktKeyTypeCurrent, io_pktKeyTypeSearch); }
if(bRet) { io_pktKeyTypeSearch = pktKeyTypeCurrent; }
return bRet;
/*if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsLogModule)
{ if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsLogModules ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFtpInfo) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFtpServer) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFtpVirtualDir) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpVirtualDir ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebInfo) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFilters) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFilter) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFilters ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsCompressionSchemes) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFilters ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsCompressionScheme) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFilters || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsCompressionSchemes) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebServer) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsCertMapper) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebFile) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACL || io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACE) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebFile || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpVirtualDir ) bRet = true; } else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_IPSecurity) { if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebFile || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpServer || pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpVirtualDir ) bRet = true; }*/ }
HRESULT CMetabase::WebAppCheck( METADATA_HANDLE a_hKey ) {
HRESULT hr = S_OK; DWORD dwBufferSize; METADATA_RECORD mdrMDData; WCHAR DataBuf[MAX_PATH]; DWORD dwState;
dwBufferSize = MAX_PATH; MD_SET_DATA_RECORD( &mdrMDData, MD_APP_ROOT, METADATA_INHERIT|METADATA_ISINHERITED, IIS_MD_UT_FILE, STRING_METADATA, dwBufferSize, &DataBuf );
hr = m_pIABase->GetData( a_hKey, NULL, &mdrMDData, &dwBufferSize ); THROW_ON_ERROR(hr);
if (mdrMDData.dwMDAttributes & METADATA_ISINHERITED) { hr = MD_ERROR_DATA_NOT_FOUND; THROW_ON_ERROR(hr); }
dwBufferSize = sizeof(DWORD); MD_SET_DATA_RECORD( &mdrMDData, MD_APP_ISOLATED, METADATA_INHERIT|METADATA_ISINHERITED, IIS_MD_UT_WAM, DWORD_METADATA, dwBufferSize, &dwState );
hr = m_pIABase->GetData( a_hKey, NULL, &mdrMDData, &dwBufferSize ); THROW_ON_ERROR(hr);
if (mdrMDData.dwMDAttributes & METADATA_ISINHERITED) { hr = MD_ERROR_DATA_NOT_FOUND; THROW_ON_ERROR(hr); }
return hr; }
HRESULT CMetabase::WebAppGetStatus( METADATA_HANDLE a_hKey, PDWORD pdwState) { HRESULT hr = S_OK; DWORD dwBufferSize = sizeof(DWORD); METADATA_RECORD mdrMDData;
MD_SET_DATA_RECORD( &mdrMDData, MD_ASP_ENABLEAPPLICATIONRESTART, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, dwBufferSize, pdwState );
hr = m_pIABase->GetData( a_hKey, NULL, &mdrMDData, &dwBufferSize );
return hr; }
HRESULT CMetabase::WebAppSetStatus( METADATA_HANDLE a_hKey, DWORD dwState ) { HRESULT hr = S_OK; DWORD dwBufferSize = sizeof(DWORD); METADATA_RECORD mdrMDData;
MD_SET_DATA_RECORD( &mdrMDData, MD_ASP_ENABLEAPPLICATIONRESTART, METADATA_INHERIT, ASP_MD_UT_APP, DWORD_METADATA, dwBufferSize, &dwState );
hr = m_pIABase->SetData( a_hKey, NULL, &mdrMDData );
return hr; }
HRESULT CServerMethod::ExecMethod( DWORD dwControl ) { DWORD dwTargetState; DWORD dwPendingState; DWORD dwState = 0; DWORD dwSleepTotal = 0L;
METADATA_HANDLE hKey = 0;
HRESULT hr = S_OK; HRESULT hrMbNode = S_OK;
switch(dwControl) { case MD_SERVER_COMMAND_STOP: dwTargetState = MD_SERVER_STATE_STOPPED; dwPendingState = MD_SERVER_STATE_STOPPING; break;
case MD_SERVER_COMMAND_START: dwTargetState = MD_SERVER_STATE_STARTED; dwPendingState = MD_SERVER_STATE_STARTING; break;
case MD_SERVER_COMMAND_CONTINUE: dwTargetState = MD_SERVER_STATE_STARTED; dwPendingState = MD_SERVER_STATE_CONTINUING; break;
case MD_SERVER_COMMAND_PAUSE: dwTargetState = MD_SERVER_STATE_PAUSED; dwPendingState = MD_SERVER_STATE_PAUSING; break;
default: hr = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER); if(FAILED(hr)) { goto error; } }
hr = IISGetServerState(METADATA_MASTER_ROOT_HANDLE, &dwState); if(FAILED(hr)) { goto error; } if (dwState == dwTargetState) { return (hr); }
//
// Write the command to the metabase
//
hr = m_pIABase->OpenKey( METADATA_MASTER_ROOT_HANDLE, m_wszPath, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, DEFAULT_TIMEOUT_VALUE, // 30 seconds
&hKey); if(FAILED(hr)) { goto error; }
hr = IISSetDword(hKey, MD_WIN32_ERROR, 0); if(FAILED(hr)) { m_pIABase->CloseKey(hKey); goto error; } hr = IISSetDword(hKey, MD_SERVER_COMMAND, dwControl); if(FAILED(hr)) { m_pIABase->CloseKey(hKey); goto error; } m_pIABase->CloseKey(hKey);
while (dwSleepTotal < MAX_SLEEP_INST) { hr = IISGetServerState(METADATA_MASTER_ROOT_HANDLE, &dwState); if(FAILED(hr)) { goto error; } hrMbNode = 0; hr = IISGetServerWin32Error(METADATA_MASTER_ROOT_HANDLE, &hrMbNode); if(FAILED(hr)) { goto error; }
//
// First check if we've hit target state
//
if (dwState != dwPendingState) { //
// Done one way or another
//
if (dwState == dwTargetState) { break; } } //
// If we haven't check the Win32 Error from the metabase
//
if(FAILED(hrMbNode)) { hr = hrMbNode; goto error; }
//
// Still pending...
//
::Sleep(SLEEP_INTERVAL);
dwSleepTotal += SLEEP_INTERVAL; }
if (dwSleepTotal >= MAX_SLEEP_INST) { //
// Timed out. If there is a real error in the metabase
// use it, otherwise use a generic timeout error
//
hr = HRESULT_FROM_WIN32(ERROR_SERVICE_REQUEST_TIMEOUT); }
error :
return (hr); }
//
// Helper routine for ExecMethod.
// Gets Win32 error from the metabase
//
HRESULT CServerMethod::IISGetServerWin32Error( METADATA_HANDLE hObjHandle, HRESULT* phrError) { DBG_ASSERT(phrError != NULL);
long lWin32Error = 0; DWORD dwLen;
METADATA_RECORD mr = { MD_WIN32_ERROR, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, sizeof(DWORD), (unsigned char*)&lWin32Error, 0 }; HRESULT hr = m_pIABase->GetData( hObjHandle, m_wszPath, &mr, &dwLen); if(hr == MD_ERROR_DATA_NOT_FOUND) { hr = S_FALSE; }
//
// Set out param
//
*phrError = HRESULT_FROM_WIN32(lWin32Error);
return hr; }
//
// Helper routine for ExecMethod.
// Gets server state from the metabase.
//
HRESULT CServerMethod::IISGetServerState( METADATA_HANDLE hObjHandle, PDWORD pdwState ) {
HRESULT hr = S_OK; DWORD dwBufferSize = sizeof(DWORD); METADATA_RECORD mdrMDData; LPBYTE pBuffer = (LPBYTE)pdwState;
MD_SET_DATA_RECORD(&mdrMDData, MD_SERVER_STATE, // server state
METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, dwBufferSize, pBuffer);
hr = m_pIABase->GetData( hObjHandle, m_wszPath, &mdrMDData, &dwBufferSize ); if( hr == MD_ERROR_DATA_NOT_FOUND ) { //
// If the data is not there, but the path exists, then the
// most likely cause is that the service is not running and
// this object was just created.
//
// Since MD_SERVER_STATE would be set as stopped if the
// service were running when the key is added, we'll just
// say that it's stopped.
//
// Note: starting the server or service will automatically set
// the MB value.
//
*pdwState = MD_SERVER_STATE_STOPPED; hr = S_FALSE; } else { if(FAILED(hr)) { goto error; } }
error:
return(hr); }
//
// Helper routine for ExecMethod.
// Used to sets the command or Win32Error in the metabase.
//
HRESULT CServerMethod::IISSetDword( METADATA_HANDLE hKey, DWORD dwPropId, DWORD dwValue ) {
HRESULT hr = S_OK; DWORD dwBufferSize = sizeof(DWORD); METADATA_RECORD mdrMDData; LPBYTE pBuffer = (LPBYTE)&dwValue;
MD_SET_DATA_RECORD(&mdrMDData, dwPropId, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, dwBufferSize, pBuffer);
hr = m_pIABase->SetData( hKey, L"", &mdrMDData ); if(FAILED(hr)) { goto error; }
error:
return(hr);
}
|