windows-nt/Source/XPSP1/NT/net/layer2svc/wlsnp/ccompdta.cpp
2020-09-26 16:20:57 +08:00

1080 lines
37 KiB
C++

#include "stdafx.h"
#include "sceattch.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// polstore is not threadsafe: we have multiple threads so we wrap critical sections around our calls to polstore
CCriticalSection g_csPolStore;
///////////////////////////////////////////////////////////////////////////////
// IComponentData implementation
DEBUG_DECLARE_INSTANCE_COUNTER(CComponentDataImpl);
CComponentDataImpl::CComponentDataImpl()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
DEBUG_INCREMENT_INSTANCE_COUNTER(CComponentDataImpl);
// Initialize members
m_pConsoleNameSpace = NULL;
m_pPrshtProvider = NULL;
m_pConsole = NULL;
m_pRootFolderScopeItem = NULL;
m_bIsDirty = FALSE;
m_enumLocation = LOCATION_LOCAL;
m_bDontDisplayRootFolderProperties = FALSE;
m_bStorageWarningIssued = FALSE;
m_bLocationStorageWarningIssued = FALSE;
m_bAttemptReconnect = TRUE;
m_bNeedCleanUpWSA = FALSE;
m_hPolicyStore = NULL;
m_pScopeRootFolder = NULL;
m_pGPEInformation = NULL;
m_bRsop = FALSE;
m_pRSOPInformation = NULL;
#ifdef _DEBUG
m_cDataObjects = 0;
#endif
// create our initial folder
CComObject <CWirelessManagerFolder>::CreateInstance(&m_pScopeRootFolder);
if (m_pScopeRootFolder == NULL)
{
// note: we are in a seriously bad state(!)
// but this is ok, because we will now 'fail to initialize' and
// mmc deals ok
return;
}
// we are storing, and later using, m_pScopeRootFolder so AddRef it
m_pScopeRootFolder->AddRef();
m_pScopeRootFolder->SetDataObjectType( CCT_SCOPE );
m_pScopeRootFolder->Initialize (this, NULL, FOLDER_IMAGE_IDX, OPEN_FOLDER_IMAGE_IDX, FALSE);
m_pScopeRootFolder->GetScopeItem()->mask |= SDI_PARAM;
m_pScopeRootFolder->GetScopeItem()->lParam = (LPARAM)m_pScopeRootFolder;
#ifdef _DEBUG
m_pScopeRootFolder->SetComponentData(this);
#endif
}
CComponentDataImpl::~CComponentDataImpl()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
DEBUG_DECREMENT_INSTANCE_COUNTER(CComponentDataImpl);
// Some snap-in is hanging on to data objects.
// If they access, it will crash!!!
ASSERT(m_cDataObjects == 0);
// release our interfaces
SAFE_RELEASE(m_pScopeRootFolder); // triggers delete up sub folders
SAFE_RELEASE(m_pConsoleNameSpace);
SAFE_RELEASE(m_pConsole);
SAFE_RELEASE(m_pPrshtProvider);
SAFE_RELEASE(m_pGPEInformation);
// cleanup winsock if we got it
if (m_bNeedCleanUpWSA)
WSACleanup();
}
STDMETHODIMP CComponentDataImpl::Initialize(LPUNKNOWN pUnknown)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = E_UNEXPECTED;
// TODO: clean this up and add error checking!
ASSERT(pUnknown != NULL);
// MMC should only call ::Initialize once!
ASSERT(m_pConsoleNameSpace == NULL);
pUnknown->QueryInterface(IID_IConsoleNameSpace, reinterpret_cast<void**>(&m_pConsoleNameSpace));
pUnknown->QueryInterface(IID_IPropertySheetProvider, reinterpret_cast<void**>(&m_pPrshtProvider));
// add the images for the scope tree
CBitmap bmp16x16;
LPIMAGELIST lpScopeImage;
hr = pUnknown->QueryInterface(IID_IConsole, reinterpret_cast<void**>(&m_pConsole));
ASSERT(hr == S_OK);
hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
ASSERT(hr == S_OK);
// Load the bitmaps from the dll
bmp16x16.LoadBitmap(IDB_16x16);
// Set the images
lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmp16x16)),
reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmp16x16)), 0, RGB(255, 0, 255));
lpScopeImage->Release();
// attempt to start winsock
WORD wsaVersion = MAKEWORD(2,0);
DWORD dwRet;
dwRet = WSAStartup(wsaVersion, &wsaData);
ASSERT (0 == dwRet);
if (0 == dwRet)
{
// make sure we got a version we expected, but don't really
// bother with any other failures as all this will effect is the
// DNS lookup, which will just cram in a DNS name without looking
// it up first... shrug.
if ((LOBYTE(wsaData.wVersion) != LOBYTE(wsaVersion)) ||
(HIBYTE(wsaData.wVersion) != HIBYTE(wsaVersion))) {
WSACleanup();
}
else
{
m_bNeedCleanUpWSA = TRUE;
}
}
return S_OK;
}
DWORD
CComponentDataImpl::OpenPolicyStore(
)
{
DWORD dwError = 0;
HANDLE hPolicyStore = NULL;
if (m_hPolicyStore)
{
WirelessClosePolicyStore(m_hPolicyStore);
m_hPolicyStore = NULL;
}
DWORD dwProvider = WIRELESS_REGISTRY_PROVIDER;
CString strLocationName;
CString strDSGPOName;
switch(EnumLocation())
{
case LOCATION_REMOTE:
strLocationName = RemoteMachineName();
break;
case LOCATION_GLOBAL:
strLocationName = RemoteMachineName();
strDSGPOName = DomainGPOName();
dwProvider = WIRELESS_DIRECTORY_PROVIDER;
break;
case LOCATION_WMI:
strLocationName = RemoteMachineName(); //rsop namespace
dwProvider = WIRELESS_WMI_PROVIDER;
break;
case LOCATION_LOCAL:
default:
break;
}
/*
dwError = WirelessOpenPolicyStore(
(LPWSTR) (LPCWSTR) strLocationName,
dwProvider,
NULL,
&hPolicyStore
);
*/
dwError = WirelessGPOOpenPolicyStore(
(LPWSTR) (LPCWSTR) strLocationName,
dwProvider,
(LPWSTR) (LPCWSTR) strDSGPOName,
NULL,
&hPolicyStore
);
if (dwError) {
Destroy();
return(dwError);
}
m_hPolicyStore = hPolicyStore;
return dwError;
}
STDMETHODIMP CComponentDataImpl::CreateComponent(LPCOMPONENT* ppComponent)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(ppComponent != NULL);
CComObject<CComponentImpl>* pObject;
CComObject<CComponentImpl>::CreateInstance(&pObject);
ASSERT(pObject != NULL);
// Store IComponentData
pObject->SetIComponentData(this);
return pObject->QueryInterface(IID_IComponent, reinterpret_cast<void**>(ppComponent));
}
STDMETHODIMP CComponentDataImpl::Notify(LPDATAOBJECT pDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
{
OPT_TRACE( _T("CComponentDataImpl::Notify pDataObject-%p\n"), pDataObject );
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(m_pConsoleNameSpace != NULL);
HRESULT hr = S_FALSE;
// Need pDataObject unless the event is one of these:
// -MMCN_PROPERTY_CHANGE because this event is generated by a
// MMCPropertyChangeNotify() which does not take pDataObject as an argument.
//
// -MMCN_COLUMN_CLICK because it is defined as having a NULL pDataObject.
if (pDataObject == NULL && MMCN_PROPERTY_CHANGE != event && MMCN_COLUMN_CLICK != event)
{
TRACE(_T("CComponentDataImpl::Notify ERROR(?) called with pDataObject==NULL on event-%i\n"), event);
// Is this an event for which there should be no IDataObj? If so, add it to
// the if statement above.
ASSERT( FALSE );
return E_UNEXPECTED;
}
switch(event)
{
case MMCN_REMOVE_CHILDREN:
{
//
// In RSoP, we may get called to refresh the scope pane when the query
// is re-executed -- if this happens, current nodes will be removed and
// we must reset all of our cached information. We reset the relevant
// information below
//
if ( ((HSCOPEITEM)arg != NULL) && m_bRsop && (m_pRSOPInformation != NULL) )
{
m_pRSOPInformation->Release();
m_pRSOPInformation = NULL;
}
break;
}
case MMCN_EXPANDSYNC:
{
//this event is not supported
return S_FALSE;
break;
}
case MMCN_EXPAND:
{
if (pDataObject)
{
// if we are an extension snap-in, IDataObject is from the parent snap-in and so it
// won't know about the IID_IWirelessSnapInDataObject interface. Otherwise we created
// the root now (IDataObject) so it does respond to the query, and we don't want
// to do our extension snapin stuff
CComQIPtr <IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
if ( spData )
{
//should be internal format, as the external snapin does not know about our format
return spData->Notify( event, arg, param, TRUE, m_pConsole, NULL );
}
else
{
//we may be in extension sanpin now
UINT cfModeType = RegisterClipboardFormat(CCF_SCE_RSOP_UNKNOWN);
STGMEDIUM ObjMediumMode = { TYMED_HGLOBAL, NULL };
FORMATETC fmteMode = {(CLIPFORMAT)cfModeType, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
ObjMediumMode.hGlobal = GlobalAlloc(GMEM_SHARE|GMEM_ZEROINIT, sizeof(DWORD*));
if (NULL == ObjMediumMode.hGlobal)
{
DWORD dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
return hr;
}
hr = pDataObject->GetDataHere (&fmteMode, &ObjMediumMode);
LPUNKNOWN pUnkRSOP = *((LPUNKNOWN*) (ObjMediumMode.hGlobal));
ASSERT (pUnkRSOP);
if(pUnkRSOP) {
if ( m_pRSOPInformation )
{
m_pRSOPInformation->Release();
m_pRSOPInformation = NULL;
}
hr = pUnkRSOP->QueryInterface(IID_IRSOPInformation, (LPVOID *)&m_pRSOPInformation);
pUnkRSOP->Release();
}
GlobalFree(ObjMediumMode.hGlobal);
if(m_pRSOPInformation)
{
m_bRsop = TRUE;
}
if(m_pRSOPInformation)
{
////RSOP case
UINT cfModeType = RegisterClipboardFormat(CCF_SCE_MODE_TYPE);
STGMEDIUM ObjMediumMode = { TYMED_HGLOBAL, NULL };
FORMATETC fmteMode = {(CLIPFORMAT)cfModeType, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
ObjMediumMode.hGlobal = GlobalAlloc(GMEM_SHARE|GMEM_ZEROINIT, sizeof(DWORD*));
if (NULL == ObjMediumMode.hGlobal)
{
DWORD dwError = GetLastError();
m_pRSOPInformation->Release();
m_pRSOPInformation = NULL;
return HRESULT_FROM_WIN32(dwError);
}
DWORD dwSCEMode = SCE_MODE_UNKNOWN;
hr = pDataObject->GetDataHere (&fmteMode, &ObjMediumMode);
dwSCEMode = *(DWORD*)(ObjMediumMode.hGlobal);
GlobalFree(ObjMediumMode.hGlobal);
//Bug296532, Wireless shouldn't show up as an extention unless we are in
// the following SCE modes
if (!
(SCE_MODE_LOCAL_COMPUTER == dwSCEMode ||
SCE_MODE_DOMAIN_COMPUTER == dwSCEMode ||
SCE_MODE_OU_COMPUTER == dwSCEMode ||
SCE_MODE_REMOTE_COMPUTER == dwSCEMode ||
SCE_MODE_RSOP_COMPUTER == dwSCEMode)
)
{
m_pRSOPInformation->Release();
m_pRSOPInformation = NULL;
hr = S_FALSE;
return hr;
}
const int cchMaxLength = 512;
WCHAR szNameSpace[cchMaxLength];
if (m_pRSOPInformation->GetNamespace(GPO_SECTION_MACHINE, szNameSpace, cchMaxLength) == S_OK)
{
RemoteMachineName(szNameSpace);
}
else
{
RemoteMachineName (L"");
}
EnumLocation (LOCATION_WMI);
m_pScopeRootFolder->SetExtScopeObject( m_pScopeRootFolder );
} //if(m_pRSOPInformation)
else
{
// The GPT knows where we are loaded from (DS, Local, Remote)
// and will provide that information via its interface
UINT cfModeType = RegisterClipboardFormat(CCF_SCE_GPT_UNKNOWN);
STGMEDIUM ObjMediumMode = { TYMED_HGLOBAL, NULL };
FORMATETC fmteMode = {(CLIPFORMAT)cfModeType, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
ObjMediumMode.hGlobal = GlobalAlloc(GMEM_SHARE|GMEM_ZEROINIT, sizeof(DWORD*));
if (NULL == ObjMediumMode.hGlobal)
{
DWORD dwError = GetLastError();
hr = HRESULT_FROM_WIN32(dwError);
return hr;
}
hr = pDataObject->GetDataHere (&fmteMode, &ObjMediumMode);
// yes, CCF_SCE_GPT_UNKNOWN implies a GPT unknown, but what we actually
// get is an unknown for a GPE!!
LPUNKNOWN pUnkGPE = *((LPUNKNOWN*) (ObjMediumMode.hGlobal));
ASSERT (pUnkGPE);
// if we didn't get an IUNKNOWN something is serously wrong
if (pUnkGPE == NULL)
{
GlobalFree(ObjMediumMode.hGlobal);
hr = E_FAIL;
return hr;
}
// need to look for the GPE interface
if ( m_pGPEInformation )
{
m_pGPEInformation->Release();
m_pGPEInformation = NULL;
}
hr = pUnkGPE->QueryInterface(cGPEguid, (void**) &m_pGPEInformation);
// this is an alternative way of doing that QI if we wanted, I like the
// more direct approach
// CComQIPtr <IGPTInformation, &cGPTguid> spGPTInformation(pUnkGPT);
// since calling GetDataHere is equivalent (so to speak) to a CreateInstance call
// we need to release the IUnknown
pUnkGPE->Release();
GlobalFree(ObjMediumMode.hGlobal);
// check to see if we got it
if (m_pGPEInformation != NULL)
{
UINT cfModeType = RegisterClipboardFormat(CCF_SCE_MODE_TYPE);
STGMEDIUM ObjMediumMode = { TYMED_HGLOBAL, NULL };
FORMATETC fmteMode = {(CLIPFORMAT)cfModeType, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
ObjMediumMode.hGlobal = GlobalAlloc(GMEM_SHARE|GMEM_ZEROINIT, sizeof(DWORD*));
if (NULL == ObjMediumMode.hGlobal)
{
DWORD dwError = GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
DWORD dwSCEMode = SCE_MODE_UNKNOWN;
hr = pDataObject->GetDataHere (&fmteMode, &ObjMediumMode);
dwSCEMode = *(DWORD*)(ObjMediumMode.hGlobal);
GlobalFree(ObjMediumMode.hGlobal);
//Bug296532, Wireless shouldn't show up as an extention unless we are in
// the following SCE modes
if (!
(SCE_MODE_LOCAL_COMPUTER == dwSCEMode ||
SCE_MODE_DOMAIN_COMPUTER == dwSCEMode ||
SCE_MODE_OU_COMPUTER == dwSCEMode ||
SCE_MODE_REMOTE_COMPUTER == dwSCEMode ||
SCE_MODE_RSOP_COMPUTER == dwSCEMode)
)
{
m_pGPEInformation->Release();
m_pGPEInformation = NULL;
return S_FALSE;
}
CString strName;
m_pGPEInformation->GetName (strName.GetBuffer(MAX_PATH), MAX_PATH);
strName.ReleaseBuffer (-1);
GROUP_POLICY_OBJECT_TYPE gpoType;
m_pGPEInformation->GetType (&gpoType);
switch (gpoType)
{
case GPOTypeLocal:
{
// redirect to local machine
RemoteMachineName (L"");
EnumLocation (LOCATION_LOCAL);
hr = S_FALSE;
return(hr);
break;
}
case GPOTypeRemote:
// redirect to the GetName machine
RemoteMachineName (strName);
EnumLocation (LOCATION_REMOTE);
break;
case GPOTypeDS:
{
hr = GetDomainDnsName(strName);
if ( FAILED(hr) )
return hr;
RemoteMachineName (strName);
hr = GetDomainGPOName(strName);
if ( FAILED(hr) )
return hr;
DomainGPOName(strName);
EnumLocation (LOCATION_GLOBAL);
break;
}
}//switch (gpoType)
// we save the m_pGPEInformation interface for later use instead of:
// pGPEInformation->Release();
}//if (m_pGPEInformation != NULL)
// If we made it here we were loaded as an extension snap-in. Only do this once.
m_pScopeRootFolder->SetExtScopeObject( m_pScopeRootFolder );
} //else if(m_pRSOPInformation)
}
} //if (pDataObject)
break;
} //case MMCN_EXPAND
default:
break;
}//switch
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(pDataObject);
if (spData == NULL)
{
// Either we are loaded as an extension snapin (so it doesn't know about our
// internal interface), or pDataObject is NULL. In either case, we can pass
// the event on.
LPUNKNOWN pUnkScope;
if (NULL != m_pScopeRootFolder->GetExtScopeObject())
{
// We are loaded as an extension snapin, let the designated extension
// scope object handle the event.
pUnkScope = reinterpret_cast<LPUNKNOWN>(m_pScopeRootFolder->GetExtScopeObject());
}
else
{
// Let our static scope object handle the event.
pUnkScope = reinterpret_cast<LPUNKNOWN>(m_pScopeRootFolder);
}
// Pass on event
ASSERT( NULL != pUnkScope );
if (NULL != pUnkScope)
{
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject>
spExtData( pUnkScope );
if (spExtData != NULL)
{
return spExtData->Notify( event, arg, param, TRUE, m_pConsole, NULL );
}
ASSERT( FALSE );
}
TRACE(_T("CComponentDataImpl::Notify - QI for IWirelessSnapInDataObject failed\n"));
ASSERT( FALSE );
hr = E_UNEXPECTED;
}
else
{
return spData->Notify( event, arg, param, TRUE, m_pConsole, NULL );
}
return hr;
}
HRESULT CComponentDataImpl::GetDomainGPOName(CString & strName)
{
WCHAR szADsPathName[MAX_PATH];
HRESULT hr = S_OK;
CString szName;
CString szPrefixName;
hr = m_pGPEInformation->GetDSPath(
GPO_SECTION_MACHINE,
szADsPathName,
MAX_PATH
);
//Truncate the LDAP:// from the string
szName = _wcsninc( szADsPathName, 7);
//szPrefixName = L"CN=Windows,CN=Microsoft,";
//strName = szPrefixName+szName;
strName = szName;
return hr;
}
HRESULT CComponentDataImpl::GetDomainDnsName(CString & strName)
{
WCHAR szADsPathName[MAX_PATH];
WCHAR *szDnsName = NULL;
LPWSTR pszDirectoryName = NULL;
ULONG ulSize = 0;
HRESULT hr = S_OK;
m_pGPEInformation->GetDSPath(
GPO_SECTION_MACHINE,
szADsPathName,
MAX_PATH
);
pszDirectoryName = wcsstr(szADsPathName, L"DC");
TranslateName (
pszDirectoryName , // object name
NameFullyQualifiedDN, // name format
NameCanonical, // new name format
szDnsName, // name buffer
&ulSize // buffer size
);
szDnsName = (WCHAR *) LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)* (ulSize+1));
if ( szDnsName == NULL )
{
hr = E_OUTOFMEMORY;
return hr;
}
if ( !TranslateName (
pszDirectoryName , // object name
NameFullyQualifiedDN, // name format
NameCanonical, // new name format
szDnsName, // name buffer
&ulSize // buffer size
))
{
hr = HRESULT_FROM_WIN32(GetLastError());
LocalFree( szDnsName );
return hr;
}
if ( szDnsName[lstrlen(szDnsName) -1 ] == _T('/') )
{
szDnsName[lstrlen(szDnsName) -1 ] = _T('\0');
}
strName = szDnsName;
LocalFree( szDnsName );
return hr;
}
STDMETHODIMP CComponentDataImpl::Destroy()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// since they are shutting us down, we use our static node
// Use our member data object to handle call.
IUnknown* pUnk = (IUnknown*) NULL;
HRESULT hr = GetStaticScopeObject()->QueryInterface(IID_IUnknown, (void**)&pUnk);
ASSERT (hr == S_OK);
if (NULL == pUnk)
return E_UNEXPECTED;
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pUnk );
if (spData == NULL)
{
TRACE(_T("CComponentDataImpl::GetDisplayInfo QI for IWirelessSnapInDataObject FAILED\n"));
return E_UNEXPECTED;
}
spData->Destroy ();
// Used our member data object to handle call, release it.
pUnk->Release();
return hr;
}
STDMETHODIMP CComponentDataImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
{
OPT_TRACE( _T("CComponentDataImpl::QueryDataObject this-%p, cookie-%p\n"), this, cookie );
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// return failure since we weren't able to get up and running
// causes mmc to report 'snapin failed to initialize'
if (m_pScopeRootFolder == NULL)
{
return E_UNEXPECTED;
}
ASSERT( m_pScopeRootFolder->NodeName().GetLength() ); // we should know our own display name
if (NULL == ppDataObject)
{
TRACE(_T("CComponentDataImpl::QueryDataObject - ERROR ppDataObject is NULL\n"));
return E_UNEXPECTED;
}
*ppDataObject = NULL;
#ifdef _DEBUG
HRESULT hr;
if (cookie == NULL)
{
hr = m_pScopeRootFolder->QueryInterface( IID_IDataObject, (void**)(ppDataObject) );
OPT_TRACE(_T(" QI on m_pScopeRootFolder-%p -> pDataObj-%p\n"), m_pScopeRootFolder, *ppDataObject);
ASSERT(hr == S_OK);
ASSERT( NULL != *ppDataObject );
return hr;
}
IUnknown* pUnk = (IUnknown*) cookie;
hr = pUnk->QueryInterface( IID_IDataObject, (void**)(ppDataObject) );
OPT_TRACE(_T(" QI on cookie-%p -> pDataObj-%p\n"), cookie, *ppDataObject);
ASSERT(hr == S_OK);
return hr;
#else
if (cookie == NULL)
return m_pScopeRootFolder->QueryInterface( IID_IDataObject, (void**)(ppDataObject) );
IUnknown* pUnk = (IUnknown*) cookie;
return pUnk->QueryInterface( IID_IDataObject, (void**)(ppDataObject) );
#endif
}
///////////////////////////////////////////////////////////////////////////////
//// IPersistStream interface members
STDMETHODIMP CComponentDataImpl::GetClassID(CLSID *pClassID)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT (0);
// TODO: CComponentDataImpl::GetClassID and CComponentImpl::GetClassID are identical (?)
ASSERT(pClassID != NULL);
// Copy the CLSID for this snapin
*pClassID = CLSID_Snapin;
return S_OK;
}
STDMETHODIMP CComponentDataImpl::IsDirty()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// return dirty state
return InternalIsDirty() ? S_OK : S_FALSE;
}
STDMETHODIMP CComponentDataImpl::Load(IStream *pStm)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
unsigned long read;
// NOTE: it looks like there is a strange case were the MMC will
// attempt to load the properties for the root node a second (or more)
// time. To do so right click on an item in the results pane and then
// double click on the empty space in the results pane
m_bDontDisplayRootFolderProperties = TRUE;
// read the location enum
HRESULT hr = pStm->Read (&m_enumLocation, sizeof (enum STORAGE_LOCATION), &read);
if ((hr != S_OK) || (read != sizeof (enum STORAGE_LOCATION)))
{
// for debug purposes, we should assert here
ASSERT (0);
// make sure we have a valid (even if incorrect) value
m_enumLocation = LOCATION_LOCAL;
// TODO: look into better return value(s)
return E_UNEXPECTED;
}
// read the size of the location string
unsigned int iStrLen;
hr = pStm->Read (&iStrLen, sizeof (unsigned int), &read);
if ((hr == S_OK) && (read == sizeof (unsigned int)))
{
// read the string itself
LPCTSTR szStr = (LPCTSTR) malloc (iStrLen);
hr = pStm->Read ((void*) szStr, iStrLen, &read);
if ((hr == S_OK) && (read == iStrLen))
{
m_sRemoteMachineName = szStr;
free ((void*)szStr);
// we don't want to allow the location page to come up
if (m_pScopeRootFolder)
{
m_pScopeRootFolder->LocationPageDisplayEnable(FALSE);
}
return S_OK;
}
// need to delete here as well
free ((void*)szStr);
}
// we only get to here in an error situation
ASSERT (0);
// make sure we have a valid (even if incorrect) value
m_enumLocation = LOCATION_GLOBAL;
m_sRemoteMachineName = _T("");
// TODO: look into better return value(s)
return E_UNEXPECTED;
}
STDMETHODIMP CComponentDataImpl::Save(IStream *pStm, BOOL fClearDirty)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
unsigned long written;
// save the storage location
HRESULT hr = pStm->Write(&m_enumLocation, sizeof (enum STORAGE_LOCATION), &written);
if ((hr != S_OK) || (written != sizeof (enum STORAGE_LOCATION)))
{
ASSERT (0);
// TODO: look into better return value(s)
return E_UNEXPECTED;
}
// save the length of the location string
unsigned int iStrLen = m_sRemoteMachineName.GetLength()*sizeof(wchar_t)+sizeof(wchar_t);
hr = pStm->Write(&iStrLen, sizeof (unsigned int), &written);
if ((hr != S_OK) || (written != sizeof (unsigned int)))
{
ASSERT (0);
// TODO: look into better return value(s)
return E_UNEXPECTED;
}
// save the location string itself
hr = pStm->Write((LPCTSTR) m_sRemoteMachineName, iStrLen, &written);
if ((hr != S_OK) || (written != iStrLen))
{
ASSERT (0);
// TODO: look into better return value(s)
return E_UNEXPECTED;
}
// if fClearDirty we clear it out
if (fClearDirty == TRUE)
{
ClearDirty();
}
return S_OK;
}
STDMETHODIMP CComponentDataImpl::GetSizeMax(ULARGE_INTEGER *pcbSize)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Set the size of the string to be saved
ULISet32(*pcbSize, sizeof (enum STORAGE_LOCATION));
return S_OK;
}
STDMETHODIMP CComponentDataImpl::GetDisplayInfo(SCOPEDATAITEM* pScopeDataItem)
{
if (pScopeDataItem == NULL)
{
TRACE(_T("CComponentDataImpl::GetDisplayInfo called with pScopeDataItem == NULL\n"));
return E_UNEXPECTED;
}
IUnknown* pUnk = (IUnknown*) pScopeDataItem->lParam;
if (pUnk == NULL)
{
// Use our member data object to handle call.
HRESULT hr = GetStaticScopeObject()->QueryInterface(IID_IUnknown, (void**)&pUnk);
ASSERT (hr == S_OK);
if (NULL == pUnk)
return E_UNEXPECTED;
}
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pUnk );
if (spData == NULL)
{
TRACE(_T("CComponentDataImpl::GetDisplayInfo QI for IWirelessSnapInDataObject FAILED\n"));
return E_UNEXPECTED;
}
HRESULT hr = spData->GetScopeDisplayInfo( pScopeDataItem );
if (NULL == pScopeDataItem->lParam)
// Used our member data object to handle call, release it.
pUnk->Release();
return hr;
}
STDMETHODIMP CComponentDataImpl::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT (0);
return E_UNEXPECTED;
// NOTE: to implement look to CComponentImpl::CompareObjects
}
/////////////////////////////////////////////////////////////////////////////
// IExtendPropertySheet Implementation
STDMETHODIMP CComponentDataImpl::QueryPagesFor(LPDATAOBJECT lpDataObject)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (lpDataObject == NULL)
{
TRACE(_T("CComponentDataImpl::QueryPagesFor called with lpDataObject == NULL\n"));
return E_UNEXPECTED;
}
CComQIPtr <IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(lpDataObject);
if (spData == NULL)
{
TRACE(_T("CComponentDataImpl::QueryPagesFor - QI for IWirelessSnapInDataObject FAILED\n"));
ASSERT( FALSE );
return E_UNEXPECTED;
}
return spData->QueryPagesFor();
}
STDMETHODIMP CComponentDataImpl::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, LPDATAOBJECT lpDataObject)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (lpDataObject == NULL)
{
TRACE(_T("CComponentDataImpl::CreatePropertyPages called with lpDataObject==NULL\n"));
return E_UNEXPECTED;
}
CComQIPtr <IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(lpDataObject);
if (spData == NULL)
{
TRACE(_T("CComponentDataImpl::CreatePropertyPages QI for IWirelessSnapInDataObject FAILED\n"));
return E_UNEXPECTED;
}
return spData->CreatePropertyPages( lpProvider, handle );
}
#ifdef WIZ97WIZARDS
STDMETHODIMP CComponentDataImpl::GetWatermarks (LPDATAOBJECT lpDataObject, HBITMAP* lphWatermark, HBITMAP* lphHeader, HPALETTE* lphPalette, BOOL* bStretch)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CBitmap* pbmpWatermark = new CBitmap;
CBitmap* pbmpHeader = new CBitmap;
if ((pbmpWatermark == NULL) || (pbmpHeader == NULL))
return E_UNEXPECTED;
// Load the bitmaps
pbmpWatermark->LoadBitmap(IDB_WPOLICY);
pbmpHeader->LoadBitmap(IDB_BPOLICY);
*lphWatermark = static_cast<HBITMAP>(*pbmpWatermark);
*lphHeader = static_cast<HBITMAP>(*pbmpHeader);
*lphPalette = NULL;
*bStretch = TRUE;
return S_OK;
}
#endif
STDMETHODIMP CComponentDataImpl::AddMenuItems(LPDATAOBJECT lpDataObject, LPCONTEXTMENUCALLBACK pContextMenuCallback, long *pInsertionAllowed)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (lpDataObject == NULL)
{
TRACE(_T("CComponentDataImpl::AddMenuItems called with piDataObject==NULL\n"));
return E_UNEXPECTED;
}
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(lpDataObject);
if (spData == NULL)
{
TRACE(_T("CComponentDataImpl::AddMenuItems QI for IWirelessSnapInDataObject FAILED\n"));
return E_UNEXPECTED;
}
return spData->AddMenuItems( pContextMenuCallback, pInsertionAllowed );
}
STDMETHODIMP CComponentDataImpl::Command(long nCommandID, LPDATAOBJECT lpDataObject)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT( NULL != m_pConsoleNameSpace );
if (lpDataObject == NULL)
{
TRACE(_T("CComponentDataImpl::Command called with lpDataObject==NULL\n"));
return E_UNEXPECTED;
}
CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData(lpDataObject);
if (spData == NULL)
{
TRACE(_T("CComponentDataImpl::Command QI for IWirelessSnapInDataObject FAILED\n"));
return E_UNEXPECTED;
}
return spData->Command( nCommandID, m_pConsoleNameSpace );
}
STDMETHODIMP CComponentDataImpl::GetHelpTopic (LPOLESTR* lpCompiledHelpFile)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (lpCompiledHelpFile == NULL)
return E_POINTER;
// need to form a complete path to the .chm file
CString s, s2;
s.LoadString(IDS_HELPCONTENTSFILE);
DWORD dw = ExpandEnvironmentStrings (s, s2.GetBuffer (512), 512);
s2.ReleaseBuffer (-1);
if ((dw == 0) || (dw > 512))
{
return E_UNEXPECTED;
}
*lpCompiledHelpFile = reinterpret_cast<LPOLESTR>
(CoTaskMemAlloc((s2.GetLength() + 1)* sizeof(wchar_t)));
if (*lpCompiledHelpFile == NULL)
return E_OUTOFMEMORY;
USES_CONVERSION;
wcscpy(*lpCompiledHelpFile, T2OLE((LPTSTR)(LPCTSTR)s2));
return S_OK;
}
void CComponentDataImpl::EnumLocation (enum STORAGE_LOCATION enumLocation)
{
SetDirty();
m_enumLocation = enumLocation;
// our enumlocation changed, so we should change the nodename of our
// manager folder
if (m_pScopeRootFolder)
{
m_pScopeRootFolder->SetNodeNameByLocation();
}
}
///////////////////////////////////////////////////////////////////////////////
// class CComponentDataPrimaryImpl : IComponentData implementation
CComponentDataPrimaryImpl::CComponentDataPrimaryImpl() : CComponentDataImpl()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT( NULL != GetStaticScopeObject() );
// Store the coclass with the data object
// GetStaticScopeObject()->INTERNALclsid( GetCoClassID() );
GetStaticScopeObject()->clsid (GetCoClassID());
}