You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2228 lines
56 KiB
2228 lines
56 KiB
/*++
|
|
|
|
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;
|
|
|
|
FILETIME tempTime;
|
|
|
|
hr = m_pIABase->EnumBackups(
|
|
io_wszMDBackupLocation,
|
|
o_pdwMDVersion,
|
|
&tempTime,
|
|
i_dwMDEnumIndex
|
|
);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
if (!FileTimeToLocalFileTime( &tempTime, o_pftMDBackupTime)){
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
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
|
|
)
|
|
{
|
|
int iLen = 0;
|
|
int iCounter = 0;
|
|
int iAdd = 0;
|
|
DWORD dwRet;
|
|
DWORD dwRetOld;
|
|
WCHAR *buffer = NULL;
|
|
WCHAR *bufferOld = NULL;
|
|
WCHAR *pwszBiggerBuffer = NULL;
|
|
HRESULT hr=0;
|
|
WCHAR *pBuffer = NULL;
|
|
WCHAR *pBigger = NULL;
|
|
|
|
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);
|
|
}
|
|
|
|
// need a special work-around case for MD_SECURE_BINDINGS
|
|
if ( MD_SECURE_BINDINGS == i_pmbp->dwMDIdentifier )
|
|
{
|
|
|
|
pBuffer = buffer;
|
|
while (iLen = wcslen(pBuffer))
|
|
{
|
|
if (pBuffer[iLen-1] != L':')
|
|
{
|
|
iAdd++;
|
|
}
|
|
|
|
iCounter += iLen+1;
|
|
|
|
if (iCounter < dwRet)
|
|
{
|
|
pBuffer = buffer + iCounter;
|
|
}
|
|
else
|
|
{
|
|
// the string wasn't double null terminated - BAD
|
|
hr = E_FAIL;
|
|
THROW_ON_ERROR(hr);
|
|
}
|
|
}
|
|
|
|
pwszBiggerBuffer = new WCHAR[dwRet + iAdd]; // iAdd = number of colons to be added
|
|
|
|
pBuffer = buffer;
|
|
pBigger = pwszBiggerBuffer;
|
|
|
|
while (iLen = wcslen(pBuffer))
|
|
{
|
|
wcscpy(pBigger, pBuffer);
|
|
|
|
if (pBuffer[iLen-1] != L':')
|
|
{
|
|
wcscat(pBigger, L":");
|
|
pBigger++;
|
|
}
|
|
|
|
// this is okay
|
|
// previously we guaranteed pBuffer was double null terminated
|
|
pBuffer += iLen+1;
|
|
pBigger += iLen+1;
|
|
}
|
|
|
|
// put on the final null
|
|
pwszBiggerBuffer[dwRet + iAdd - 1] = 0;
|
|
|
|
mr.pbMDData = (unsigned char*)pwszBiggerBuffer;
|
|
mr.dwMDDataLen = (dwRet + iAdd)*sizeof(WCHAR);
|
|
}
|
|
else
|
|
{
|
|
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;
|
|
|
|
if (pwszBiggerBuffer)
|
|
{
|
|
delete [] pwszBiggerBuffer;
|
|
pwszBiggerBuffer = NULL;
|
|
}
|
|
|
|
buffer = NULL;
|
|
THROW_E_ON_ERROR(hr,i_pmbp);
|
|
}
|
|
|
|
catch (...)
|
|
{
|
|
delete [] buffer;
|
|
delete [] bufferOld;
|
|
|
|
if (pwszBiggerBuffer)
|
|
{
|
|
delete [] pwszBiggerBuffer;
|
|
pwszBiggerBuffer = NULL;
|
|
}
|
|
|
|
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
|
|
);
|
|
|
|
// special case - throw on data not found if we're
|
|
// trying to delete an IIsIPSecuritySetting
|
|
|
|
if ((hr == MD_ERROR_DATA_NOT_FOUND && MD_IP_SEC != i_dwMDIdentifier) || 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, METADATA_VOLATILE);
|
|
if(FAILED(hr))
|
|
{
|
|
m_pIABase->CloseKey(hKey);
|
|
goto error;
|
|
}
|
|
hr = IISSetDword(hKey, MD_SERVER_COMMAND, dwControl, METADATA_VOLATILE);
|
|
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,
|
|
DWORD dwAttrib
|
|
)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD dwBufferSize = sizeof(DWORD);
|
|
METADATA_RECORD mdrMDData;
|
|
LPBYTE pBuffer = (LPBYTE)&dwValue;
|
|
|
|
MD_SET_DATA_RECORD(&mdrMDData,
|
|
dwPropId,
|
|
dwAttrib,
|
|
IIS_MD_UT_SERVER,
|
|
DWORD_METADATA,
|
|
dwBufferSize,
|
|
pBuffer);
|
|
|
|
hr = m_pIABase->SetData(
|
|
hKey,
|
|
L"",
|
|
&mdrMDData
|
|
);
|
|
if(FAILED(hr))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
error:
|
|
|
|
return(hr);
|
|
|
|
}
|