windows-nt/Source/XPSP1/NT/base/remoteboot/admin/dataobj.cpp
2020-09-26 16:20:57 +08:00

378 lines
7.7 KiB
C++

//
// Copyright 1997 - Microsoft
//
//
// DATAOBJ.CPP - A data object
//
#include "pch.h"
#include "dataobj.h"
DEFINE_MODULE("IMADMUI")
DEFINE_THISCLASS("CDsPropDataObj")
#define THISCLASS CDsPropDataObj
#define LPTHISCLASS CDsPropDataObj*
//
// CreateInstance( )
//
LPVOID
CDsPropDataObj_CreateInstance(
HWND hwndParent,
IDataObject * pido,
GUID * pClassGUID,
BOOL fReadOnly,
LPWSTR pszObjPath,
LPWSTR bstrClass )
{
TraceFunc( "CDsPropDataObj_CreateInstance( ... )\n" );
LPTHISCLASS lpcc = new THISCLASS( hwndParent, pido, pClassGUID, fReadOnly);
if (!lpcc)
RETURN(lpcc);
HRESULT hr = THR( lpcc->Init( pszObjPath, bstrClass ) );
if ( hr )
{
delete lpcc;
RETURN(NULL);
}
RETURN((LPVOID) lpcc);
}
//
// Constructor
//
THISCLASS::THISCLASS(
HWND hwndParent,
IDataObject * pido,
GUID * pClassGUID,
BOOL fReadOnly) :
m_fReadOnly(fReadOnly),
m_pwszObjName(NULL),
m_pwszObjClass(NULL),
m_hwnd(hwndParent),
m_pPage(pido),
m_ClassGUID(*pClassGUID),
_cRef(0)
{
TraceClsFunc( "CDsPropDataObj( )\n" );
if (m_pPage) {
m_pPage->AddRef();
}
TraceFuncExit( );
}
//
// Destructor
//
THISCLASS::~THISCLASS(void)
{
TraceClsFunc( "~CDsPropDataObj( )\n" );
if (m_pPage) {
m_pPage->Release();
}
if (m_pwszObjName) {
TraceFree(m_pwszObjName);
}
if (m_pwszObjClass) {
TraceFree(m_pwszObjClass);
}
TraceFuncExit( );
}
//
// Init( )
//
HRESULT
THISCLASS::Init(
LPWSTR pwszObjName,
LPWSTR pwszClass )
{
TraceClsFunc( "Init( ... )\n" );
HRESULT hr = S_OK;
// IUnknown stuff
BEGIN_QITABLE_IMP( CDsPropDataObj, IDataObject );
QITABLE_IMP( IDataObject );
END_QITABLE_IMP( CDsPropDataObj );
Assert( _cRef == 0);
AddRef( );
if (!pwszObjName || *pwszObjName == L'\0')
{
HRETURN(E_INVALIDARG);
}
if (!pwszClass || *pwszClass == L'\0')
{
HRETURN(E_INVALIDARG);
}
m_pwszObjName = (LPWSTR) TraceStrDup( pwszObjName );
if ( !m_pwszObjName ) {
hr = THR(E_OUTOFMEMORY);
goto Error;
}
m_pwszObjClass = (LPWSTR) TraceStrDup( pwszClass );
if ( !m_pwszObjClass ) {
hr = THR(E_OUTOFMEMORY);
goto Error;
}
Cleanup:
HRETURN(S_OK);
Error:
if ( m_pwszObjName ) {
TraceFree( m_pwszObjName );
m_pwszObjName = NULL;
}
if ( m_pwszObjClass ) {
TraceFree( m_pwszObjClass );
m_pwszObjClass = NULL;
}
switch (hr) {
case S_OK:
break;
default:
MessageBoxFromHResult( m_hwnd, IDC_ERROR_CREATINGACCOUNT_TITLE, hr );
break;
}
goto Cleanup;
}
// ************************************************************************
//
// IUnknown
//
// ************************************************************************
//
// QueryInterface()
//
STDMETHODIMP
THISCLASS::QueryInterface(
REFIID riid,
LPVOID *ppv )
{
TraceClsFunc( "" );
HRESULT hr = ::QueryInterface( this, _QITable, riid, ppv );
QIRETURN( hr, riid );
}
//
// AddRef()
//
STDMETHODIMP_(ULONG)
THISCLASS::AddRef( void )
{
TraceClsFunc( "[IUnknown] AddRef( )\n" );
InterlockIncrement( _cRef );
RETURN(_cRef);
}
//
// Release()
//
STDMETHODIMP_(ULONG)
THISCLASS::Release( void )
{
TraceClsFunc( "[IUnknown] Release( )\n" );
InterlockDecrement( _cRef );
if ( _cRef )
RETURN(_cRef);
TraceDo( delete this );
RETURN(0);
}
// ************************************************************************
//
// IDataObject
//
// ************************************************************************
//
// GetData( )
//
STDMETHODIMP
THISCLASS::GetData(
FORMATETC * pFormatEtc,
STGMEDIUM * pMedium)
{
TraceClsFunc( "[IDataObject] GetData( ... )\n" );
if (IsBadWritePtr(pMedium, sizeof(STGMEDIUM))) {
HRETURN(E_INVALIDARG);
}
if (!(pFormatEtc->tymed & TYMED_HGLOBAL)) {
HRETURN(DV_E_TYMED);
}
HRESULT hr = S_OK;
if (pFormatEtc->cfFormat == g_cfDsObjectNames)
{
// return the object name and class.
//
INT cbPath = sizeof(WCHAR) * (wcslen(m_pwszObjName) + 1);
INT cbClass = sizeof(WCHAR) * (wcslen(m_pwszObjClass) + 1);
INT cbStruct = sizeof(DSOBJECTNAMES);
LPDSOBJECTNAMES pDSObj;
pDSObj = (LPDSOBJECTNAMES)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
cbStruct + cbPath + cbClass);
if (pDSObj == NULL) {
hr = THR(STG_E_MEDIUMFULL);
goto Error;
}
pDSObj->clsidNamespace = CLSID_MicrosoftDS;
pDSObj->cItems = 1;
pDSObj->aObjects[0].offsetName = cbStruct;
pDSObj->aObjects[0].offsetClass = cbStruct + cbPath;
if (m_fReadOnly)
{
pDSObj->aObjects[0].dwFlags = DSOBJECT_READONLYPAGES;
}
wcscpy((PWSTR)((BYTE *)pDSObj + cbStruct), m_pwszObjName);
wcscpy((PWSTR)((BYTE *)pDSObj + cbStruct + cbPath), m_pwszObjClass);
pMedium->hGlobal = (HGLOBAL)pDSObj;
}
else if (pFormatEtc->cfFormat == g_cfDsPropCfg)
{
// return the property sheet notification info. In this case, it is
// the invokding sheet's hwnd.
//
PPROPSHEETCFG pSheetCfg;
pSheetCfg = (PPROPSHEETCFG)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
sizeof(PROPSHEETCFG));
if (pSheetCfg == NULL) {
hr = THR(STG_E_MEDIUMFULL);
goto Error;
}
ZeroMemory(pSheetCfg, sizeof(PROPSHEETCFG));
pSheetCfg->hwndParentSheet = m_hwnd;
pMedium->hGlobal = (HGLOBAL)pSheetCfg;
}
else
{
// Pass call on to "parent" object's data obj.
if (m_pPage ) {
hr = m_pPage->GetData( pFormatEtc, pMedium );
#ifdef DEBUG
if (hr != DV_E_FORMATETC )
THR(hr);
#endif
goto Error; // not really, but we don't want to clean up
} else {
hr = THR(E_FAIL);
goto Error;
}
}
pMedium->tymed = TYMED_HGLOBAL;
pMedium->pUnkForRelease = NULL;
Error:
HRETURN(hr);
}
//
// GetDataHere( )
//
STDMETHODIMP
THISCLASS::GetDataHere(
LPFORMATETC pFormatEtc,
LPSTGMEDIUM pMedium)
{
TraceClsFunc( "[IDataObject] GetDataHere( ... )\n" );
HRESULT hr;
if (IsBadWritePtr(pMedium, sizeof(STGMEDIUM))) {
HRETURN(E_INVALIDARG);
}
if (pFormatEtc->cfFormat == g_cfMMCGetNodeType)
{
if (!(pFormatEtc->tymed & TYMED_HGLOBAL)) {
hr = THR(DV_E_TYMED);
goto Error;
}
LPSTREAM lpStream;
ULONG written;
// Create the stream on the hGlobal passed in.
//
hr = CreateStreamOnHGlobal(pMedium->hGlobal, FALSE, &lpStream);
if (hr)
goto Error;
hr = lpStream->Write(&m_ClassGUID, sizeof(m_ClassGUID), &written);
// Because we told CreateStreamOnHGlobal with 'FALSE', only the
// stream is released here.
lpStream->Release();
} else if (m_pPage ) {
// Pass call on to "parent" object's data obj.
hr = THR( m_pPage->GetDataHere( pFormatEtc, pMedium ) );
} else {
hr = THR(E_FAIL);
}
Cleanup:
HRETURN(hr);
Error:
goto Cleanup;
}
//
// EnumFormatEtc( )
//
STDMETHODIMP
THISCLASS::EnumFormatEtc(
DWORD dwDirection,
LPENUMFORMATETC * ppEnumFormatEtc)
{
TraceClsFunc( "[IDataObject] EnumFormatEtc( ... )\n" );
//
// Pass call on to "parent" object's data obj.
//
if (m_pPage )
{
HRETURN(m_pPage->EnumFormatEtc(dwDirection, ppEnumFormatEtc));
}
else
{
HRETURN(E_FAIL);
}
}