Leaked source code of windows server 2003
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.
 
 
 
 
 
 

414 lines
11 KiB

#include "stdafx.h"
#define INITGUID
#define _WIN32_DCOM
#undef DEFINE_GUID // Added for NT5 migration
#include <ole2.h>
#include <coguid.h>
#include "iadmw.h"
#include "iiscnfg.h"
#include "mdkey.h"
#define TIMEOUT_VALUE 5000
CMDKey::CMDKey()
{
m_pcCom = NULL;
m_hKey = NULL;
m_fNeedToClose = FALSE;
}
CMDKey::~CMDKey()
{
this->Close();
}
void SetErrMsg(LPTSTR szMsg, HRESULT hRes)
{
CString csMsg;
csMsg.Format(_T("%s, %x"), szMsg, hRes);
MyMessageBox(NULL, csMsg, _T("IMS/INS Metabase Error"),
MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
return;
}
void TraceErrMsg(LPTSTR szMsg, HRESULT hRes)
{
CString csMsg;
csMsg.Format(_T("%s, %x"), szMsg, hRes);
DebugOutput(csMsg);
return;
}
void CMDKey::OpenNode(LPCTSTR pchSubKeyPath)
{
BOOL fInitialized = FALSE;
HRESULT hRes;
IClassFactory * pcsfFactory = NULL;
BOOL b = FALSE;
m_pcCom = NULL;
m_hKey = NULL;
WCHAR szSubKeyPath[_MAX_PATH];
DWORD dwRetry = 0;
DebugOutput(_T("OpenNode(): pchSubKeyPath=%s"), pchSubKeyPath);
pszFailedAPI = NULL;
if ( !pchSubKeyPath || !(*pchSubKeyPath) ) {
*szSubKeyPath = L'\0';
} else {
lstrcpyn(szSubKeyPath, pchSubKeyPath, _MAX_PATH);
}
hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if ( SUCCEEDED(hRes) || hRes == E_INVALIDARG || hRes == RPC_E_CHANGED_MODE ) {
fInitialized = TRUE;
if ( SUCCEEDED(hRes) || hRes == E_INVALIDARG )
m_fNeedToClose = TRUE; // need to be closed later
}
if (!fInitialized) {
SetErrMsg(_T("CoInitializeEx"), hRes);
} else {
dwRetry = 0;
do
{
hRes = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
if (FAILED(hRes))
{
TraceErrMsg(_T("Retrying on OpenNode::CoGetClassObject"), hRes);
// Add a small delay
Sleep(100);
}
} while ((FAILED(hRes)) && (++dwRetry < 5));
if (FAILED(hRes)) {
SetErrMsg(_T("CoGetClassObject"), hRes);
} else {
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &m_pcCom);
pcsfFactory->Release();
if (FAILED(hRes)) {
SetErrMsg(_T("CoCreateInstance"), hRes);
} else {
dwRetry = 0;
do
{
hRes = m_pcCom->OpenKey(METADATA_MASTER_ROOT_HANDLE,
szSubKeyPath,
METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
TIMEOUT_VALUE,
&m_hKey);
if (FAILED(hRes))
{
TraceErrMsg(_T("Retrying on OpenNode::OpenKey"), hRes);
// Add a small delay
Sleep(100);
}
} while ((FAILED(hRes)) && (++dwRetry < 5));
if (FAILED(hRes)) {
if (hRes != RETURNCODETOHRESULT(ERROR_PATH_NOT_FOUND)) {
SetErrMsg(_T("OpenKey"), hRes);
}
} else {
b = TRUE;
}
} // end of CoCreateInstance
} // end of CoGetClassObject
}
if (!b) {
this->Close();
}
return;
}
void CMDKey::CreateNode(METADATA_HANDLE hKeyBase, LPCTSTR pchSubKeyPath)
{
BOOL fInitialized = FALSE;
HRESULT hRes;
IClassFactory * pcsfFactory = NULL;
BOOL b = FALSE;
m_pcCom = NULL;
m_hKey = NULL;
WCHAR szSubKeyPath[_MAX_PATH];
DWORD dwRetry = 0;
DebugOutput(_T("CreateNode(): hKeyBase=0x%x, pchSubKeyPath=%s"), hKeyBase, pchSubKeyPath);
pszFailedAPI = NULL;
if ( !pchSubKeyPath || !(*pchSubKeyPath) ) {
*szSubKeyPath = L'\0';
} else {
lstrcpyn(szSubKeyPath, pchSubKeyPath, _MAX_PATH);
}
hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if ( SUCCEEDED(hRes) || hRes == E_INVALIDARG || hRes == RPC_E_CHANGED_MODE ) {
fInitialized = TRUE;
if ( SUCCEEDED(hRes) || hRes == E_INVALIDARG )
m_fNeedToClose = TRUE; // need to be closed later
}
if (!fInitialized) {
SetErrMsg(_T("CoInitializeEx"), hRes);
} else {
hRes = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
if (FAILED(hRes)) {
SetErrMsg(_T("CoGetClassObject"), hRes);
} else {
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &m_pcCom);
pcsfFactory->Release();
if (FAILED(hRes)) {
SetErrMsg(_T("CoCreateInstance"), hRes);
} else {
hRes = m_pcCom->OpenKey(hKeyBase,
szSubKeyPath,
METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
TIMEOUT_VALUE,
&m_hKey);
if (FAILED(hRes))
{
if (hRes == RETURNCODETOHRESULT(ERROR_PATH_NOT_FOUND)) {
METADATA_HANDLE RootHandle;
hRes = m_pcCom->OpenKey(hKeyBase,
L"",
METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
TIMEOUT_VALUE,
&RootHandle);
hRes = m_pcCom->AddKey(RootHandle, szSubKeyPath);
if (FAILED(hRes)) {
SetErrMsg(_T("AddKey"), hRes);
}
hRes = m_pcCom->CloseKey(RootHandle);
if (FAILED(hRes)) {
SetErrMsg(_T("CloseKey of AddKey"), hRes);
}
else
{
dwRetry = 0;
do
{
// open it again to set m_hKey
hRes = m_pcCom->OpenKey(hKeyBase,
szSubKeyPath,
METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
TIMEOUT_VALUE,
&m_hKey);
if (FAILED(hRes))
{
TraceErrMsg(_T("Retrying on CreateNode::OpenKey"), hRes);
// Add a small delay
Sleep(100);
}
} while ((FAILED(hRes)) && (++dwRetry < 5));
if (FAILED(hRes)) {
SetErrMsg(_T("OpenKey"), hRes);
} else {
b = TRUE;
}
}
} else {
SetErrMsg(_T("OpenKey"), hRes);
}
} else {
b = TRUE;
} // end of OpenKey
} // end of CoCreateInstance
} // end of CoGetClassObject
} // end of CoInitializeEx
if (!b) {
this->Close();
}
return;
}
void CMDKey::Close()
{
HRESULT hRes;
if (m_pcCom) {
if (m_hKey)
hRes = m_pcCom->CloseKey(m_hKey);
// Call save data anyway for good measure
hRes = m_pcCom->SaveData();
hRes = m_pcCom->Release();
}
if (m_fNeedToClose)
CoUninitialize();
m_pcCom = NULL;
m_hKey = NULL;
m_fNeedToClose = FALSE;
return;
}
#define FILL_RETURN_BUFF for(ReturnIndex=0;ReturnIndex<sizeof(ReturnBuf);ReturnIndex++)ReturnBuf[ReturnIndex]=0xff;
BOOL CMDKey::IsEmpty()
{
int ReturnIndex;
METADATA_RECORD mdrData;
DWORD dwRequiredDataLen = 0;
HRESULT hRes;
UCHAR ReturnBuf[256];
FILL_RETURN_BUFF;
MD_SET_DATA_RECORD(&mdrData, 0, METADATA_NO_ATTRIBUTES, 0, 0, sizeof(ReturnBuf), (PBYTE) ReturnBuf)
hRes = m_pcCom->EnumData(m_hKey, L"", &mdrData, 0, &dwRequiredDataLen);
if (FAILED(hRes)) {
if(hRes == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS) ||
hRes == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER) ) {
return TRUE;
} else {
SetErrMsg(_T("EnumData"), hRes);
}
}
return (hRes != ERROR_SUCCESS);
}
int CMDKey::GetNumberOfSubKeys()
{
int i=0;
HRESULT hRes = ERROR_SUCCESS;
WCHAR NameBuf[METADATA_MAX_NAME_LEN];
while (hRes == ERROR_SUCCESS) {
hRes = m_pcCom->EnumKeys(m_hKey, L"", NameBuf, i++);
}
if (hRes == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS))
return (--i);
else {
SetErrMsg(_T("EnumKeys"), hRes);
return (0);
}
}
BOOL CMDKey::SetData(
DWORD id,
DWORD attr,
DWORD uType,
DWORD dType,
DWORD cbLen, // number of bytes
LPBYTE pbData)
{
HRESULT hRes;
METADATA_RECORD mdrData;
WCHAR *pData = NULL;
BOOL fRet = FALSE;
switch (dType)
{
case DWORD_METADATA:
pData = (WCHAR *)pbData;
break;
case BINARY_METADATA:
pData = (WCHAR *)pbData;
break;
case STRING_METADATA:
case EXPANDSZ_METADATA:
pData = (WCHAR *)pbData;
break;
case MULTISZ_METADATA:
pData = (WCHAR *)pbData;
break;
default:
break;
}
if (cbLen > 0)
{
MD_SET_DATA_RECORD(&mdrData, id, attr, uType, dType, cbLen, (LPBYTE)pData);
hRes = m_pcCom->SetData(m_hKey, L"", &mdrData);
if (FAILED(hRes))
SetErrMsg(_T("SetData"), hRes);
else
fRet = TRUE;
}
if (pData && (pData != (WCHAR *)pbData))
LocalFree(pData);
return(fRet);
}
// Note: only use to access the AnonyName and AnonyPassword,
// buffer size 256 is big enough here
// sneely: Now used to see if a key exists as well.
BOOL CMDKey::GetData(DWORD id,
DWORD *pdwAttr,
DWORD *pdwUType,
DWORD *pdwDType,
DWORD *pcbLen, // number of bytes
LPBYTE pbData)
{
int ReturnIndex;
BOOL fReturn = FALSE;
HRESULT hRes;
METADATA_RECORD mdrData;
DWORD dwRequiredDataLen = 0;
UCHAR ReturnBuf[256];
FILL_RETURN_BUFF;
MD_SET_DATA_RECORD(&mdrData, id, 0, 0, 0, sizeof(ReturnBuf), (PBYTE) ReturnBuf);
hRes = m_pcCom->GetData(m_hKey, L"", &mdrData, &dwRequiredDataLen);
if (FAILED(hRes)) {
// MCIS uses this to see if an MD value exists, so we don't
// complain if it's not found.
//SetErrMsg(_T("GetData"), hRes);
} else {
*pdwAttr = mdrData.dwMDAttributes;
*pdwUType = mdrData.dwMDUserType;
*pdwDType = mdrData.dwMDDataType;
*pcbLen = mdrData.dwMDDataLen; // number of SBCS chars + ending \0
fReturn = TRUE;
switch (*pdwDType) {
case STRING_METADATA:
case EXPANDSZ_METADATA:
memcpy(pbData, mdrData.pbMDData, *pcbLen);
break;
default:
memcpy(pbData, mdrData.pbMDData, *pcbLen);
break;
}
}
return fReturn;
}
void CMDKey::DeleteData(DWORD id, DWORD dType)
{
m_pcCom->DeleteData(m_hKey, L"", id, dType);
return;
}
void CMDKey::DeleteNode(LPCTSTR pchSubKeyPath)
{
HRESULT hRes;
WCHAR szSubKeyPath[_MAX_PATH];
if ( pchSubKeyPath && (*pchSubKeyPath) ) {
lstrcpyn(szSubKeyPath, pchSubKeyPath, _MAX_PATH);
hRes = m_pcCom->DeleteKey(m_hKey, szSubKeyPath);
}
return;
}