windows-nt/Source/XPSP1/NT/inetsrv/iis/setup/osrc/mdkey.cpp

1477 lines
42 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
// MdKey.cpp
#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"
#include "iwamreg.h"
#include "strfn.h"
#define TIMEOUT_VALUE 5000
INT_PTR CALLBACK pSecureRetryIgnoreAllDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
extern BOOL g_bGlobalWriteUnSecuredIfFailed_All;
CMDKey::CMDKey():
m_cCoInits(0)
{
m_pcCom = NULL;
m_hKey = NULL;
_tcscpy(m_szCurrentNodeName, _T(""));
}
CMDKey::~CMDKey()
{
this->Close();
// while there are outstanding coinits, close them
while ( m_cCoInits > 0 && !(m_cCoInits < 0) )
DoCoUnInit();
}
HRESULT CMDKey::DoCoInitEx()
{
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
// track our calls to coinit
if ( SUCCEEDED(hRes) )
{
m_cCoInits++;
}
return hRes;
}
void CMDKey::DoCoUnInit()
{
HRESULT hRes = NOERROR;
// if there are outstanding coinits, uninit one
if ( m_cCoInits > 0 )
{
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().Start.")));
CoUninitialize();
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().End.")));
m_cCoInits--;
}
// we shouldn't ever have a negative count. But just in case...
ASSERT( m_cCoInits >= 0 );
if ( m_cCoInits < 0 )
{
// something is seriously wrong here. Prevent looping
// by going straight to zero, and write an error to the log.
m_cCoInits = 0;
iisDebugOut((LOG_TYPE_WARN, _T("WARNING: CoInits in mdkey have gone negative")));
}
}
HRESULT CMDKey::OpenNode(LPCTSTR pchSubKeyPath)
{
HRESULT hRes = ERROR_SUCCESS;
IClassFactory * pcsfFactory = NULL;
BOOL b = FALSE;
m_pcCom = NULL;
m_hKey = NULL;
WCHAR szSubKeyPath[_MAX_PATH];
pszFailedAPI = NULL;
_tcscpy(m_szCurrentNodeName, pchSubKeyPath);
if ( !pchSubKeyPath || !(*pchSubKeyPath) )
{
*szSubKeyPath = L'\0';
}
else
{
#if defined(UNICODE) || defined(_UNICODE)
_tcscpy(szSubKeyPath, pchSubKeyPath);
#else
MultiByteToWideChar( CP_ACP, 0, pchSubKeyPath, -1, szSubKeyPath, _MAX_PATH);
#endif
}
hRes = DoCoInitEx();
if (FAILED(hRes))
{
iisDebugOut((LOG_TYPE_ERROR, _T("CoInitializeEx() failed, hRes=%x\n"), hRes));
}
hRes = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
if (FAILED(hRes))
{
MyMessageBox(NULL, _T("CoGetClassObject"), hRes, MB_OK | MB_SETFOREGROUND);
}
else
{
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &m_pcCom);
pcsfFactory->Release();
if (FAILED(hRes))
{
MyMessageBox(NULL, _T("CoCreateInstance"), hRes, MB_OK | MB_SETFOREGROUND);
}
else
{
_tcscpy(m_szCurrentNodeName, pchSubKeyPath);
hRes = m_pcCom->OpenKey(METADATA_MASTER_ROOT_HANDLE,szSubKeyPath,METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,TIMEOUT_VALUE,&m_hKey);
if (FAILED(hRes))
{
if (hRes != RETURNCODETOHRESULT(ERROR_PATH_NOT_FOUND))
{
MyMessageBox(NULL, _T("OpenKey"), hRes, MB_OK | MB_SETFOREGROUND);
}
}
else
{
b = TRUE;
}
} // end of CoCreateInstance
} // end of CoGetClassObject
if (!b) {this->Close();}
return hRes;
}
HRESULT CMDKey::CreateNode(METADATA_HANDLE hKeyBase, LPCTSTR pchSubKeyPath)
{
HRESULT hRes = ERROR_SUCCESS;
IClassFactory * pcsfFactory = NULL;
BOOL b = FALSE;
m_pcCom = NULL;
m_hKey = NULL;
WCHAR szSubKeyPath[_MAX_PATH];
_tcscpy(m_szCurrentNodeName, pchSubKeyPath);
pszFailedAPI = NULL;
if ( !pchSubKeyPath || !(*pchSubKeyPath) )
{
*szSubKeyPath = L'\0';
}
else
{
#if defined(UNICODE) || defined(_UNICODE)
_tcscpy(szSubKeyPath, pchSubKeyPath);
#else
MultiByteToWideChar( CP_ACP, 0, pchSubKeyPath, -1, szSubKeyPath, _MAX_PATH);
#endif
}
hRes = DoCoInitEx();
if (FAILED(hRes))
{
iisDebugOut((LOG_TYPE_ERROR, _T("CoInitializeEx() failed, hRes=%x\n"), hRes));
}
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoGetClassObject().Start.")));
hRes = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoGetClassObject().End.")));
if (FAILED(hRes))
{
MyMessageBox(NULL, _T("CoGetClassObject"), hRes, MB_OK | MB_SETFOREGROUND);
}
else
{
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &m_pcCom);
pcsfFactory->Release();
if (FAILED(hRes))
{
MyMessageBox(NULL, _T("CreateInstance"), hRes, MB_OK | MB_SETFOREGROUND);
}
else
{
_tcscpy(m_szCurrentNodeName, pchSubKeyPath);
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;
_tcscpy(m_szCurrentNodeName, pchSubKeyPath);
hRes = m_pcCom->OpenKey(hKeyBase,L"",METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,TIMEOUT_VALUE,&RootHandle);
hRes = m_pcCom->AddKey(RootHandle, szSubKeyPath);
if (FAILED(hRes))
{
MyMessageBox(NULL, _T("AddKey"), hRes, MB_OK | MB_SETFOREGROUND);
}
hRes = m_pcCom->CloseKey(RootHandle);
if (FAILED(hRes))
{
MyMessageBox(NULL, _T("CloseKey of the AddKey"), hRes, MB_OK | MB_SETFOREGROUND);
}
else
{
// open it again to set m_hKey
_tcscpy(m_szCurrentNodeName, pchSubKeyPath);
hRes = m_pcCom->OpenKey(hKeyBase,szSubKeyPath,METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,TIMEOUT_VALUE,&m_hKey);
if (FAILED(hRes))
{
MyMessageBox(NULL, _T("OpenKey"), hRes, MB_OK | MB_SETFOREGROUND);
}
else
{
b = TRUE;
}
}
}
else
{
iisDebugOut((LOG_TYPE_ERROR, _T("calling OpenKey()...failed....something other than ERROR_PATH_NOT_FOUND\n")));
MyMessageBox(NULL, _T("OpenKey"), hRes, MB_OK | MB_SETFOREGROUND);
}
}
else
{
b = TRUE;
} // end of OpenKey
} // end of CoCreateInstance
} // end of CoGetClassObject
if (!b) {this->Close();}
return hRes;
}
HRESULT CMDKey::ForceWriteMetabaseToDisk()
{
HRESULT hRes = ERROR_SUCCESS;
IClassFactory * pcsfFactory = NULL;
m_pcCom = NULL;
hRes = DoCoInitEx();
if (FAILED(hRes))
{
iisDebugOut((LOG_TYPE_ERROR, _T("CoInitializeEx() failed, hRes=%x\n"), hRes));
}
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoGetClassObject().Start.")));
hRes = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoGetClassObject().End.")));
if (FAILED(hRes))
{
MyMessageBox(NULL, _T("CoGetClassObject"), hRes, MB_OK | MB_SETFOREGROUND);
}
else
{
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &m_pcCom);
pcsfFactory->Release();
if (FAILED(hRes))
{
MyMessageBox(NULL, _T("CoCreateInstance"), hRes, MB_OK | MB_SETFOREGROUND);
}
else
{
if (m_pcCom)
{
hRes = m_pcCom->SaveData();
iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::ForceWriteMetabaseToDisk():Return=0x%x.\n"),hRes));
}
} // end of CoCreateInstance
} // end of CoGetClassObject
return hRes;
}
HRESULT CMDKey::Close()
{
HRESULT hRes = ERROR_SUCCESS;
if (m_pcCom)
{
if (m_hKey){hRes = m_pcCom->CloseKey(m_hKey);}
hRes = m_pcCom->Release();
}
DoCoUnInit();
m_pcCom = NULL;
m_hKey = NULL;
_tcscpy(m_szCurrentNodeName, _T(""));
return hRes;
}
BOOL CMDKey::IsEmpty( PWCHAR pszSubString )
{
int ReturnIndex;
METADATA_RECORD mdrData;
DWORD dwRequiredDataLen = 0;
HRESULT hRes = ERROR_SUCCESS;
UCHAR ReturnBuf[256];
for(ReturnIndex=0;ReturnIndex<sizeof(ReturnBuf);ReturnIndex++)ReturnBuf[ReturnIndex]=0xff;
MD_SET_DATA_RECORD(&mdrData, 0, METADATA_NO_ATTRIBUTES, 0, 0, sizeof(ReturnBuf), (PBYTE) ReturnBuf)
hRes = m_pcCom->EnumData(m_hKey, pszSubString, &mdrData, 0, &dwRequiredDataLen);
if (FAILED(hRes))
{
if(hRes == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS) || hRes == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER) )
{
return TRUE;
}
else
{
MyMessageBox(NULL, _T("EnumData"), hRes, MB_OK | MB_SETFOREGROUND);
}
}
return (hRes != ERROR_SUCCESS);
}
int CMDKey::GetNumberOfSubKeys( PWCHAR pszSubString )
{
int i=0;
HRESULT hRes = ERROR_SUCCESS;
WCHAR NameBuf[METADATA_MAX_NAME_LEN];
while (hRes == ERROR_SUCCESS)
{
hRes = m_pcCom->EnumKeys(m_hKey, pszSubString, NameBuf, i++);
}
if (hRes == RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS))
{
return (--i);
}
else
{
MyMessageBox(NULL, _T("EnumKeys"), hRes, MB_OK | MB_SETFOREGROUND);
return (0);
}
}
#if !defined(UNICODE) && !defined(_UNICODE)
void MyMultiByteToWideChar( char *sData, WCHAR *wData, int cbBufSize, BOOL fMultiSZ)
{
MultiByteToWideChar( CP_ACP, 0, sData, -1, wData, cbBufSize );
while (fMultiSZ)
{
sData = _tcsninc( sData, _tcslen(sData)) + 1;
while (*wData++);
if (*sData)
{
MultiByteToWideChar( CP_ACP, 0, sData, -1, wData, cbBufSize );
}
else
{
*wData = L'\0';
break;
}
}
return;
}
void MyWideCharToMultiByte( WCHAR *wData, char *sData, int cbBufSize, BOOL fMultiSZ)
{
WideCharToMultiByte( CP_ACP, 0, wData, -1, sData, cbBufSize, NULL, NULL );
while (fMultiSZ)
{
while (*wData++);
sData = _tcsninc( sData, _tcslen(sData)) + 1;
if (*wData)
{
WideCharToMultiByte( CP_ACP, 0, wData, -1, sData, cbBufSize, NULL, NULL );
}
else
{
*sData = '\0';
break;
}
}
return;
}
#endif // not unicode
HRESULT CMDKey::SetData(DWORD id,DWORD attr,DWORD uType,DWORD dType,DWORD cbLen, LPBYTE pbData,PWCHAR pszSubString )
{
HRESULT hRes = ERROR_SUCCESS;
METADATA_RECORD mdrData;
BUFFER bufData;
WCHAR *pData = (WCHAR *)pbData;
int iPlsDoNoEncryption = FALSE;
switch (dType)
{
case STRING_METADATA:
case EXPANDSZ_METADATA:
#if defined(UNICODE) || defined(_UNICODE)
pData = (WCHAR *)pbData;
#else
if ( ! (bufData.Resize(cbLen * sizeof(WCHAR))) )
{
// insufficient memory
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetData() failed to allocate memory.\n")));
hRes = RETURNCODETOHRESULT(GetLastError());
goto SetData_Exit;
}
pData = (WCHAR *)(bufData.QueryPtr());
MyMultiByteToWideChar( (LPTSTR)pbData, pData, cbLen, FALSE);
cbLen = cbLen * sizeof(WCHAR);
#endif
break;
case MULTISZ_METADATA:
#if defined(UNICODE) || defined(_UNICODE)
pData = (WCHAR *)pbData;
#else
if ( ! (bufData.Resize(cbLen * sizeof(WCHAR))) )
{
// insufficient memory
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetData() failed to allocate memory.\n")));
hRes = RETURNCODETOHRESULT(GetLastError());
goto SetData_Exit;
}
pData = (WCHAR *)(bufData.QueryPtr());
MyMultiByteToWideChar( (LPTSTR)pbData, pData, cbLen, TRUE );
cbLen = cbLen * sizeof(WCHAR);
#endif
break;
default:
break;
}
//DisplayStringForMetabaseID(id);
//_tcscpy(m_szCurrentNodeName, _T(""));
TCHAR lpReturnString[50];
ReturnStringForMetabaseID(id, lpReturnString);
iisDebugOut((LOG_TYPE_PROGRAM_FLOW, _T("CMDKey::SetData[%s:%d:%s].\n"), m_szCurrentNodeName, id, lpReturnString));
MD_SET_DATA_RECORD(&mdrData, id, attr, uType, dType, cbLen, (LPBYTE)pData);
hRes = m_pcCom->SetData(m_hKey, pszSubString, &mdrData);
if (FAILED(hRes))
{
// Check if it failed...
// if it failed and the METADATA_SECURE flag is set, then
// check if we can retry without the METADATA_SECURE flag!
if ( attr & METADATA_SECURE )
{
if (TRUE == g_bGlobalWriteUnSecuredIfFailed_All)
{
iPlsDoNoEncryption = TRUE;
}
else
{
if (TRUE == DialogBoxParam((HINSTANCE) g_MyModuleHandle, MAKEINTRESOURCE(IDD_ENCRYPTED_WRITE_ERROR_DIALOG), NULL, pSecureRetryIgnoreAllDlgProc, (LPARAM)hRes))
{
iPlsDoNoEncryption = TRUE;
}
}
if (TRUE == iPlsDoNoEncryption)
{
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetData() failed on a encrypt entry. try to write it out unencrypted.\n")));
attr &= ~METADATA_SECURE;
MD_SET_DATA_RECORD(&mdrData, id, attr, uType, dType, cbLen, (LPBYTE)pData);
hRes = m_pcCom->SetData(m_hKey, pszSubString, &mdrData);
if (FAILED(hRes))
{
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetData() failed on write on encrypt entry as unencrypted.\n")));
}
else
{
iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::SetData() success on write on encrypt entry as unencrypted.\n")));
}
// set the attr back to what it was
attr &= ~METADATA_SECURE;
}
}
}
goto SetData_Exit;
SetData_Exit:
if (FAILED(hRes))
{
MyMessageBox(NULL, IDS_SETDATA_ERROR, (int) hRes, MB_OK | MB_SETFOREGROUND);
}
return hRes;
}
BOOL CMDKey::GetData(DWORD id,DWORD *pdwAttr,DWORD *pdwUType,DWORD *pdwDType,DWORD *pcbLen,LPBYTE pbData,DWORD BufSize,PWCHAR pszSubString )
{
return GetData(id,pdwAttr,pdwUType,pdwDType,pcbLen,pbData,BufSize,0,0,0,pszSubString);
}
BOOL
CMDKey::GetData(CMDValue &Value, DWORD dwId, PWCHAR pszSubString )
{
DWORD dwAttr;
DWORD dwUType;
DWORD dwDType;
DWORD cbLen;
BUFFER bufData;
if (!GetData(dwId,&dwAttr,&dwUType,&dwDType,&cbLen,(LPBYTE) bufData.QueryPtr(),bufData.QuerySize(),0,0,0,pszSubString))
{
// Resize to Accomodate the big value
if (!bufData.Resize(cbLen))
{
return FALSE;
}
if (!GetData(dwId,&dwAttr,&dwUType,&dwDType,&cbLen,(LPBYTE) bufData.QueryPtr(),bufData.QuerySize(),0,0,0,pszSubString))
{
// Even with the new size buffer we could not retrieve the value
return FALSE;
}
}
return ( Value.SetValue(dwId,dwAttr,dwUType,dwDType,cbLen,(LPVOID) bufData.QueryPtr()) );
}
BOOL
CMDKey::SetData(CMDValue &Value, DWORD dwId, PWCHAR pszSubString )
{
return SUCCEEDED( SetData(dwId,
Value.GetAttributes(),
Value.GetUserType(),
Value.GetDataType(),
Value.GetDataLen(),
(LPBYTE) Value.GetData(),
pszSubString ) );
}
// Note: only use to access the AnonyName and AnonyPassword,
// buffer size 256 is big enough here
BOOL CMDKey::GetData(DWORD id,DWORD *pdwAttr,DWORD *pdwUType,DWORD *pdwDType,DWORD *pcbLen,LPBYTE pbData,DWORD BufSize,DWORD dwAttributes,DWORD dwUType,DWORD dwDType,PWCHAR pszSubString )
{
int ReturnIndex;
BOOL fReturn = FALSE;
HRESULT hRes = ERROR_SUCCESS;
METADATA_RECORD mdrData;
DWORD dwRequiredDataLen = 0;
LPBYTE ReturnBuf=NULL;
int ReturnBufSize;
// if we are just trying to get the size of the field, just do that.
if ( !pbData || (BufSize == 0) )
{
MD_SET_DATA_RECORD(&mdrData, id, dwAttributes, dwUType, dwDType, 0, NULL);
hRes = m_pcCom->GetData(m_hKey, pszSubString, &mdrData, &dwRequiredDataLen);
*pcbLen = dwRequiredDataLen;
fReturn = (hRes == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER));
goto GetData_Exit;
}
#if defined(UNICODE) || defined(_UNICODE)
ReturnBufSize = BufSize;
#else
ReturnBufSize = 2 * BufSize;
#endif
ReturnBuf = (LPBYTE)LocalAlloc(LPTR, ReturnBufSize);
if (!ReturnBuf)
{
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetData() failed to allocate memory.\n")));
ReturnBuf = NULL;
goto GetData_Exit;
}
//DisplayStringForMetabaseID(id);
TCHAR lpReturnString[50];
ReturnStringForMetabaseID(id, lpReturnString);
iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::GetData[%s:%d:%s].\n"), m_szCurrentNodeName, id, lpReturnString));
MD_SET_DATA_RECORD(&mdrData, id, dwAttributes, dwUType, dwDType, ReturnBufSize, (PBYTE) ReturnBuf);
hRes = m_pcCom->GetData(m_hKey, pszSubString, &mdrData, &dwRequiredDataLen);
if (FAILED(hRes))
{
if (hRes == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER))
{
#if defined(UNICODE) || defined(_UNICODE)
*pcbLen = dwRequiredDataLen;
#else
*pcbLen = dwRequiredDataLen / 2;
#endif
}
else
{
*pcbLen = 0;
if (hRes != MD_ERROR_DATA_NOT_FOUND)
{
MyMessageBox(NULL, IDS_GETDATA_ERROR, (int) hRes, MB_OK | MB_SETFOREGROUND);
}
}
goto GetData_Exit;
}
// --------
// We have successfully retrieved the data at this point
// --------
*pdwAttr = mdrData.dwMDAttributes;
*pdwUType = mdrData.dwMDUserType;
*pdwDType = mdrData.dwMDDataType;
*pcbLen = mdrData.dwMDDataLen; // number of SBCS chars + ending \0
switch (*pdwDType)
{
case STRING_METADATA:
case EXPANDSZ_METADATA:
#if defined(UNICODE) || defined(_UNICODE)
memcpy(pbData, mdrData.pbMDData, *pcbLen);
#else
*pcbLen = (*pcbLen) / sizeof(WCHAR);
WideCharToMultiByte(CP_ACP,0,(WCHAR *)(mdrData.pbMDData),-1,(LPSTR)pbData,*pcbLen, NULL, NULL);
#endif
fReturn = TRUE;
break;
case MULTISZ_METADATA:
#if defined(UNICODE) || defined(_UNICODE)
memcpy(pbData, mdrData.pbMDData, *pcbLen);
#else
*pcbLen = (*pcbLen) / sizeof(WCHAR);
MyWideCharToMultiByte((WCHAR *)(mdrData.pbMDData),(LPSTR)pbData, *pcbLen, TRUE);
#endif
fReturn = TRUE;
break;
default:
memcpy(pbData, mdrData.pbMDData, *pcbLen);
fReturn = TRUE;
break;
}
GetData_Exit:
if(ReturnBuf) {LocalFree(ReturnBuf);}
return fReturn;
}
HRESULT CMDKey::DeleteData(DWORD id, DWORD dType, PWCHAR pszSubString)
{
HRESULT hRes = ERROR_SUCCESS;
TCHAR lpReturnString[50];
ReturnStringForMetabaseID(id, lpReturnString);
iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::DeleteData[%s:%d:%s].\n"), m_szCurrentNodeName, id, lpReturnString));
hRes = m_pcCom->DeleteData(m_hKey, pszSubString, id, dType);
return hRes;
}
HRESULT CMDKey::DeleteNode(LPCTSTR pchSubKeyPath)
{
HRESULT hRes = ERROR_SUCCESS;
WCHAR szSubKeyPath[_MAX_PATH];
if ( pchSubKeyPath && (*pchSubKeyPath) )
{
#if defined(UNICODE) || defined(_UNICODE)
_tcscpy(szSubKeyPath, pchSubKeyPath);
#else
MultiByteToWideChar( CP_ACP, 0, pchSubKeyPath, -1, szSubKeyPath, _MAX_PATH );
#endif
iisDebugOut((LOG_TYPE_TRACE, _T("CMDKey::DeleteNode[%s:%s].\n"), m_szCurrentNodeName, szSubKeyPath));
hRes = m_pcCom->DeleteKey(m_hKey, szSubKeyPath);
}
return hRes;
}
CMDKeyIter::CMDKeyIter(CMDKey &cmdKey)
{
m_hKey = cmdKey.GetMDKeyHandle();
m_pcCom = cmdKey.GetMDKeyICOM();
m_dwBuffer = _MAX_PATH;
Reset();
m_pBuffer = new WCHAR [m_dwBuffer];
}
CMDKeyIter::~CMDKeyIter()
{
delete [] m_pBuffer;
}
LONG CMDKeyIter::Next(CString *pcsName, PWCHAR pwcsSubString)
{
TCHAR tchData[_MAX_PATH];
HRESULT hRes = ERROR_SUCCESS;
hRes = m_pcCom->EnumKeys(m_hKey, pwcsSubString, m_pBuffer, m_index);
if (FAILED(hRes))
{
return 1;
}
else
{
#if defined(UNICODE) || defined(_UNICODE)
_tcscpy(tchData, m_pBuffer);
#else
WideCharToMultiByte(CP_ACP,0,m_pBuffer,-1,(LPSTR)tchData,_MAX_PATH, NULL, NULL);
#endif
*pcsName = tchData;
m_index++;
return 0;
}
}
int CreateInProc(LPCTSTR lpszPath, int iUseOOPPool)
{
int iReturn = FALSE;
TCHAR lpszKeyPath[_MAX_PATH];
WCHAR wchKeyPath[_MAX_PATH];
HRESULT hr = NOERROR;
IWamAdmin2* pIWamAdmin = NULL;
DWORD dwAppMode = eAppRunInProc;
if (iUseOOPPool) {dwAppMode = eAppRunOutProcInDefaultPool;}
if (lpszPath[0] == _T('/'))
{
_tcscpy(lpszKeyPath, lpszPath);
}
else
{
lpszKeyPath[0] = _T('/');
_tcscpy(_tcsinc(lpszKeyPath), lpszPath);
}
if (lpszKeyPath[(_tcslen(lpszKeyPath)-1)] != _T('/')) {_tcscat(lpszKeyPath, _T("/"));}
#if defined(UNICODE) || defined(_UNICODE)
_tcscpy(wchKeyPath, lpszKeyPath);
#else
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpszKeyPath, -1, (LPWSTR)wchKeyPath, _MAX_PATH);
#endif
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoInitializeEx().Start.")));
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoInitializeEx().End.")));
if (FAILED(hr))
{
iisDebugOut((LOG_TYPE_ERROR, _T("CreateInProc: CoInitializeEx() failed, hr=%x\n"), hr));
MesssageBoxErrors_MTS(IDS_MTS_DOING_CREATEINPROC,hr);
}
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoCreateInstance().Start.")));
hr = CoCreateInstance(CLSID_WamAdmin,NULL,CLSCTX_SERVER,IID_IWamAdmin2,(void **)&pIWamAdmin);
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoCreateInstance().End.")));
if (SUCCEEDED(hr))
{
hr = pIWamAdmin->AppCreate2(wchKeyPath, dwAppMode);
pIWamAdmin->Release();
if (FAILED(hr))
{
iisDebugOut((LOG_TYPE_ERROR, _T("Create in-proc(type=%d) app on path %s failed, err=%x.\n"), dwAppMode, lpszKeyPath, hr));
MyMessageBox(NULL, _T("CreateInProc:Error Creating Transaction Server InProc App."), hr, MB_OK | MB_SETFOREGROUND);
MesssageBoxErrors_MTS(IDS_MTS_DOING_CREATEINPROC,hr);
}
else
{
iReturn = TRUE;
}
}
else
{
iisDebugOut((LOG_TYPE_ERROR, _T("Failed to CoCreateInstance of WamAdmin object. err=%x.\n"), hr));
MyMessageBox(NULL, _T("CreateInProc:CoCreateInstance"), hr, MB_OK | MB_SETFOREGROUND);
MesssageBoxErrors_MTS(IDS_MTS_DOING_CREATEINPROC,hr);
}
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().Start.")));
CoUninitialize();
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().End.")));
return iReturn;
}
void CreateInProc_Wrap(LPCTSTR lpszPath, int iUseOOPPool)
{
BOOL bDisplayMsgOnErrFlag = TRUE;
int iReturn = FALSE;
int bFinishedFlag = FALSE;
UINT iMsg = NULL;
do
{
iisDebugOut((LOG_TYPE_TRACE, _T("CreateInProc_Wrap(): %s\n"), lpszPath));
iReturn = CreateInProc(lpszPath, iUseOOPPool);
if (iReturn == TRUE)
{
break;
}
else
{
if (bDisplayMsgOnErrFlag == TRUE)
{
iMsg = MyMessageBox( NULL, IDS_RETRY, MB_ABORTRETRYIGNORE | MB_SETFOREGROUND );
switch ( iMsg )
{
case IDIGNORE:
iReturn = TRUE;
goto CreateInProc_Wrap_Exit;
case IDABORT:
iReturn = FALSE;
goto CreateInProc_Wrap_Exit;
case IDRETRY:
break;
default:
break;
}
}
else
{
// return whatever err happened
goto CreateInProc_Wrap_Exit;
}
}
} while (iReturn != TRUE);
CreateInProc_Wrap_Exit:
return;
}
void DeleteInProc(LPCTSTR lpszPath)
{
TCHAR lpszKeyPath[_MAX_PATH];
WCHAR wchKeyPath[_MAX_PATH];
HRESULT hr = NOERROR;
IWamAdmin* pIWamAdmin = NULL;
iisDebugOut((LOG_TYPE_TRACE, _T("DeleteInProc():Start.%s\n"), lpszPath));
if (lpszPath[0] == _T('/'))
{
_tcscpy(lpszKeyPath, lpszPath);
}
else
{
lpszKeyPath[0] = _T('/');
_tcscpy(_tcsinc(lpszKeyPath), lpszPath);
}
#if defined(UNICODE) || defined(_UNICODE)
_tcscpy(wchKeyPath, lpszKeyPath);
#else
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpszKeyPath, -1, (LPWSTR)wchKeyPath, _MAX_PATH);
#endif
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoInitializeEx().Start.")));
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoInitializeEx().End.")));
if (FAILED(hr))
{
iisDebugOut((LOG_TYPE_ERROR, _T("DeleteInProc: CoInitializeEx() failed, hr=%x\n"), hr));
}
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoCreateInstance().Start.")));
hr = CoCreateInstance(CLSID_WamAdmin,NULL,CLSCTX_SERVER,IID_IWamAdmin,(void **)&pIWamAdmin);
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoCreateInstance().End.")));
if (SUCCEEDED(hr))
{
iisDebugOut((LOG_TYPE_TRACE, _T("DeleteInProc():Calling AppDelete now.%s\n"), lpszKeyPath));
hr = pIWamAdmin->AppDelete(wchKeyPath, TRUE);
pIWamAdmin->Release();
if (FAILED(hr))
{
iisDebugOut((LOG_TYPE_ERROR, _T("Delete in-proc app on path %s failed, err=%x.\n"), lpszKeyPath, hr));
}
}
else
{
iisDebugOut((LOG_TYPE_ERROR, _T("DeleteInProc:CoCreateInstance() failed. err=%x.\n"), hr));
}
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().Start.")));
CoUninitialize();
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ole32:CoUninitialize().End.")));
iisDebugOut_End1(_T("DeleteInProc"),(LPTSTR) lpszPath,LOG_TYPE_TRACE);
return;
}
INT_PTR CALLBACK pSecureRetryIgnoreAllDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND hTextWording = NULL;
CString csErrMsg;
HRESULT hErrorCode;
TCHAR pMsg[_MAX_PATH] = _T("");
HRESULT nNetErr;
DWORD dwFormatReturn = 0;
switch (msg)
{
case WM_INITDIALOG:
uiCenterDialog(hDlg);
hTextWording = GetDlgItem(hDlg, IDC_STATIC2);
hErrorCode = (HRESULT) lParam;
nNetErr = (HRESULT) hErrorCode;
dwFormatReturn = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,NULL, hErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),pMsg, _MAX_PATH, NULL);
if ( dwFormatReturn == 0)
{
if (nNetErr >= NERR_BASE)
{
HMODULE hDll = (HMODULE)LoadLibrary(_T("netmsg.dll"));
if (hDll)
{
dwFormatReturn = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE,hDll, hErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),pMsg, _MAX_PATH, NULL);
FreeLibrary(hDll);
}
}
}
if (dwFormatReturn) {csErrMsg.Format(_T("0x%x=%s"), hErrorCode, pMsg);}
else{csErrMsg.Format(_T("%s\n\nErrorCode=0x%x."), hErrorCode);}
SetWindowText(hTextWording, csErrMsg);
UpdateWindow(hDlg);
break;
case WM_COMMAND:
switch (wParam)
{
case IDCANCEL:
EndDialog(hDlg, (int)wParam);
return FALSE;
case IDRETRY:
EndDialog(hDlg, (int)wParam);
return FALSE;
break;
case IDWRITEUNENCRYPTED:
EndDialog(hDlg, (int)wParam);
return TRUE;
break;
case IDWRITEUNENCRYPTEDALL:
g_bGlobalWriteUnSecuredIfFailed_All = TRUE;
EndDialog(hDlg, (int)wParam);
return TRUE;
break;
}
break;
}
return FALSE;
}
//-----------------------------------------------------------------------------
// get a multi-sz data block and immediately parse it into a CStringList
HRESULT CMDKey::GetMultiSzAsStringList (
DWORD dwMDIdentifier,
DWORD *uType,
DWORD *attributes,
CStringList& szStrList,
PWCHAR pszSubString OPTIONAL )
{
HRESULT hRes = ERROR_SUCCESS;
METADATA_RECORD mdrData;
DWORD cbBuffer;
// make sure the key is open
if ( NULL == m_hKey )
{
iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: GetMultiSzAsStringList on unopened node.%s\n"), _T("")));
return -1;
}
// get the paths. The loop accounts for a buffer that is too small...
DWORD dwMDBufferSize = 1024;
PWCHAR pwchBuffer = NULL;
do
{
if ( pwchBuffer )
{
delete pwchBuffer;
pwchBuffer = NULL;
}
pwchBuffer = new WCHAR[dwMDBufferSize];
if (pwchBuffer == NULL)
{
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
}
// prepare the metadata parameter block
MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, *attributes,
*uType, MULTISZ_METADATA, dwMDBufferSize, pwchBuffer);
// make the call to get the data
// If the buffer is too small, the correct size will be put into dwMDBufferSize
hRes = m_pcCom->GetData(
m_hKey,
pszSubString,
&mdrData,
&dwMDBufferSize
);
// Set the attributes return.
*attributes = mdrData.dwMDAttributes;
*uType = mdrData.dwMDUserType;
}
while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
// if there were any failures, go to the cleanup code now...
if ( SUCCEEDED(hRes) )
{
// at this point, we have the data we want. Time to convert it into a CString list.
if (pwchBuffer)
{
// to make prefix stop yelling at me
if (pwchBuffer[0])
{
ConvertWDoubleNullListToStringList(pwchBuffer, szStrList);
}
}
}
// clean up
if ( pwchBuffer )
delete pwchBuffer;
if ( FAILED(hRes) )
{
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetMultiSzAsStringList() failed. err=%x.\n"), hRes));
}
return hRes;
}
//-----------------------------------------------------------------------------
// take a CStringList and set it into metadata as a multi-sz
HRESULT CMDKey::SetMultiSzAsStringList (
DWORD dwMDIdentifier,
DWORD uType,
DWORD attributes,
CStringList& szStrList,
PWCHAR pszSubString OPTIONAL )
{
HRESULT hRes = ERROR_SUCCESS;
METADATA_RECORD mdrData;
DWORD cbBuffer;
// make sure the key is open
if ( NULL == m_hKey )
{
iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: SetMultiSzAsStringList on unopened node.%s\n"), _T("")));
return -1;
}
DWORD dwMDBufferSize = 0;
PWCHAR pwchBuffer = NULL;
// convert the cstringlist into a wide multisz data block.
hRes = ConvertStringListToWDoubleNullList(
szStrList,
dwMDBufferSize,
pwchBuffer
);
if ( FAILED(hRes) )
{
iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: SetMultiSzAsStringList Convert to null list.%x\n"), hRes));
return hRes;
}
// the buffer is expressed in wide characters. Change it to bytes...
dwMDBufferSize *= sizeof(WCHAR);
// prepare the metadata parameter block
MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, attributes,
uType, MULTISZ_METADATA, dwMDBufferSize, pwchBuffer);
// make the call to get the data
hRes = m_pcCom->SetData(
m_hKey,
pszSubString,
&mdrData
);
// clean up
FreeMem( pwchBuffer );
if ( FAILED(hRes) )
{
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetMultiSzAsStringList()-SetData failed. err=%x.\n"), hRes));
}
return hRes;
}
//-----------------------------------------------------------------------------
// get all the sub keys that have a certain property on them and return the
// sub-paths in a cstring list object. The cstring list should be instantiated
// by the caller and deleted by the same.
HRESULT CMDKey::GetDataPaths(
DWORD dwMDIdentifier,
DWORD dwMDDataType,
CStringList& szPathList,
PWCHAR pszSubString )
{
HRESULT hRes = ERROR_SUCCESS;
DWORD cbBuffer;
// make sure the key is open
if ( NULL == m_hKey )
{
iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: GetDataPaths on unopened node.%s\n"), _T("")));
return -1;
}
// get the paths. The loop accounts for a buffer that is too small...
DWORD dwMDBufferSize = 512;
PWCHAR pwchBuffer = NULL;
do
{
if ( pwchBuffer )
{
delete pwchBuffer;
pwchBuffer = NULL;
}
pwchBuffer = new WCHAR[dwMDBufferSize];
if (pwchBuffer == NULL)
{
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
}
// If the buffer is too small, the correct size will be put into dwMDBufferSize
hRes = m_pcCom->GetDataPaths(
m_hKey,
pszSubString,
dwMDIdentifier,
dwMDDataType,
dwMDBufferSize,
pwchBuffer,
&dwMDBufferSize
);
}
while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
// if there were any failures, go to the cleanup code now...
if ( SUCCEEDED(hRes) )
{
// at this point, we have the data we want. Time to convert it into a CString list.
ConvertWDoubleNullListToStringList(pwchBuffer, szPathList);
}
// clean up
if ( pwchBuffer )
delete pwchBuffer;
if ( FAILED(hRes) )
{
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetDataPaths() failed. err=%x.\n"), hRes));
}
return hRes;
}
//-----------------------------------------------------------------------------
// get a multi-sz data block and immediately parse it into a CStringList
HRESULT CMDKey::GetStringAsCString (
DWORD dwMDIdentifier,
DWORD uType,
DWORD attributes,
CString& szStr,
PWCHAR pszSubString OPTIONAL,
int iStringType OPTIONAL)
{
HRESULT hRes = ERROR_SUCCESS;
METADATA_RECORD mdrData;
DWORD cbBuffer;
// make sure the key is open
if ( NULL == m_hKey )
{
iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: GetStringAsCString on unopened node.%s\n"), _T("")));
return -1;
}
// get the string. The loop accounts for a buffer that is too small...
DWORD dwMDBufferSize = 255;
PWCHAR pwchBuffer = NULL;
do
{
if ( pwchBuffer )
{
delete pwchBuffer;
pwchBuffer = NULL;
}
pwchBuffer = new WCHAR[dwMDBufferSize + 1];
ZeroMemory( pwchBuffer, (dwMDBufferSize + 1) * sizeof(WCHAR) );
if (pwchBuffer == NULL)
{
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
}
// prepare the metadata parameter block
MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, attributes,
uType, STRING_METADATA, dwMDBufferSize, pwchBuffer);
// make the call to get the data
// If the buffer is too small, the correct size will be put into dwMDBufferSize
hRes = m_pcCom->GetData(
m_hKey,
pszSubString,
&mdrData,
&dwMDBufferSize
);
}
while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
// if there were any failures, go to the cleanup code now...
if ( SUCCEEDED(hRes) )
{
// at this point, we have the data we want. Time to convert it into a CString.
szStr = pwchBuffer;
}
// clean up
if ( pwchBuffer )
delete pwchBuffer;
if ( FAILED(hRes) && !MD_ERROR_DATA_NOT_FOUND)
{
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetStringAsCString() failed. err=%x.\n"), hRes));
}
return hRes;
}
//-----------------------------------------------------------------------------
// take a CStringList and set it into metadata as a multi-sz
HRESULT CMDKey::SetCStringAsString (
DWORD dwMDIdentifier,
DWORD uType,
DWORD attributes,
CString& szStr,
PWCHAR pszSubString OPTIONAL,
int iStringType OPTIONAL)
{
HRESULT hRes = ERROR_SUCCESS;
METADATA_RECORD mdrData;
DWORD cbBuffer;
// make sure the key is open
if ( NULL == m_hKey )
{
iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: SetCStringAsString on unopened node.%s\n"), _T("")));
return -1;
}
DWORD dwMDBufferSize = 0;
PWCHAR pwchBuffer = NULL;
// convert the cstring into a wide string data block.
pwchBuffer = AllocWideString( (LPCTSTR)szStr );
// Calculate the size of the buffer in bytes, not wide characters....
dwMDBufferSize = (szStr.GetLength() + 1) * sizeof(WCHAR);
// prepare the metadata parameter block
MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, attributes,
uType, STRING_METADATA, dwMDBufferSize, pwchBuffer);
// make the call to get the data
hRes = m_pcCom->SetData(
m_hKey,
pszSubString,
&mdrData
);
// clean up
FreeMem( pwchBuffer );
if ( FAILED(hRes) )
{
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::SetCStringAsString()-SetData failed. err=%x.\n"), hRes));
}
return hRes;
}
HRESULT CMDKey::GetDword(
DWORD dwMDIdentifier,
DWORD uType,
DWORD attributes,
DWORD& MyDword,
PWCHAR pszSubString OPTIONAL
)
{
HRESULT hRes = ERROR_SUCCESS;
METADATA_RECORD mdrData;
DWORD cbBuffer;
DWORD dwMDBufferSize = 255;
LPBYTE Buffer = NULL;
// make sure the key is open
if ( NULL == m_hKey )
{
iisDebugOut((LOG_TYPE_ERROR, _T("FAILED: GetDword on unopened node.\n")));
return -1;
}
// get the data. The loop accounts for a buffer that is too small...
do
{
if ( Buffer )
{
delete Buffer;
Buffer = NULL;
}
Buffer = (LPBYTE)LocalAlloc(LPTR, dwMDBufferSize);
if (Buffer == NULL)
{
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
}
// prepare the metadata parameter block
MD_SET_DATA_RECORD(&mdrData, dwMDIdentifier, attributes, uType, DWORD_METADATA, dwMDBufferSize, Buffer);
// make the call to get the data
// If the buffer is too small, the correct size will be put into dwMDBufferSize
hRes = m_pcCom->GetData(m_hKey,pszSubString,&mdrData,&dwMDBufferSize);
}
while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
// if there were any failures, go to the cleanup code now...
if ( SUCCEEDED(hRes) )
{
// at this point, we have the data we want. Time to convert it into a dword.
MyDword = (DWORD) *mdrData.pbMDData;
}
// clean up
if ( Buffer )
delete Buffer;
if ( FAILED(hRes) && !MD_ERROR_DATA_NOT_FOUND)
{
iisDebugOut((LOG_TYPE_ERROR, _T("CMDKey::GetDword() failed. err=%x.\n"), hRes));
}
return hRes;
}
HRESULT CMDKey::RenameNode(LPCTSTR pszMDPath,LPCTSTR pszMDNewName)
{
HRESULT hRes = ERROR_SUCCESS;
if (m_pcCom)
{
WCHAR wszPath1[_MAX_PATH];
WCHAR wszPath2[_MAX_PATH];
#if defined(UNICODE) || defined(_UNICODE)
_tcscpy(wszPath1, pszMDPath);
_tcscpy(wszPath2, pszMDNewName);
#else
MultiByteToWideChar( CP_ACP, 0, pszMDPath, -1, wszPath1, _MAX_PATH);
MultiByteToWideChar( CP_ACP, 0, pszMDNewName, -1, wszPath2, _MAX_PATH);
#endif
hRes = m_pcCom->RenameKey(m_hKey,wszPath1,wszPath2);
if ( FAILED(hRes) && !MD_ERROR_DATA_NOT_FOUND)
{
iisDebugOut((LOG_TYPE_WARN, _T("CMDKey::RenameNode(%s,%s) failed. err=%x.\n"), pszMDPath,pszMDNewName,hRes));
}
}
return hRes;
};
CMDValue::CMDValue()
:
m_dwId(0),
m_dwAttributes(0),
m_dwUserType(0),
m_dwDataType(0),
m_cbDataLen(0)
{
}
CMDValue::~CMDValue()
{
}
// function: CMDValue::SetValue
//
// Set the value of the class to what the pointer points to
//
DWORD
CMDValue::SetValue(DWORD dwId,
DWORD dwAttributes,
DWORD dwUserType,
DWORD dwDataType,
DWORD cbDataLen,
LPVOID pbData)
{
if ( cbDataLen > m_bufData.QuerySize() )
{
if (!m_bufData.Resize(cbDataLen))
{
// Failed to Resize Data
return FALSE;
}
}
memcpy( m_bufData.QueryPtr(), pbData, cbDataLen );
m_dwId = dwId;
m_dwAttributes = dwAttributes;
m_dwUserType = dwUserType;
m_dwDataType = dwDataType;
m_cbDataLen = cbDataLen;
return TRUE;
}
// function: CMDValue::SetValue
//
// Set the value of the class the value of the string. So if
// dwDataType is DWORD, we must first convert to DWORD before
// Setting the value
//
DWORD
CMDValue::SetValue(DWORD dwId,
DWORD dwAttributes,
DWORD dwUserType,
DWORD dwDataType,
DWORD cbDataLen,
LPTSTR szDataString)
{
if (dwDataType == DWORD_METADATA)
{
DWORD dwValue;
dwValue = _ttoi(szDataString);
return SetValue(dwId, dwAttributes, dwUserType, dwDataType, sizeof(DWORD), (LPVOID) &dwValue);
}
return SetValue(dwId, dwAttributes, dwUserType, dwDataType, cbDataLen, (LPVOID) szDataString);
}
BOOL
CMDValue::IsEqual(DWORD dwDataType, DWORD cbDataLen, LPVOID pbData)
{
if ( (dwDataType != m_dwDataType) ||
( cbDataLen != m_cbDataLen )
)
{
return FALSE;
}
return ( memcmp(pbData,m_bufData.QueryPtr(),cbDataLen) == 0 );
}
BOOL
CMDValue::IsEqual(DWORD dwDataType, DWORD cbDataLen, DWORD dwData)
{
return IsEqual(dwDataType,cbDataLen,(LPVOID) &dwData);
}