|
|
// SnapIn.cpp : Defines the initialization routines for the DLL.
//
// Copyright (c) 2000 Microsoft Corporation
//
//
// 03-14-00 v-marfin bug 58675 : Disable the "server busy.. retry, switch, etc" dialog.
// 03-23-00 v-marfin bug 61680 : Added escape and unescape special chars functions.
// 03/31/00 v-marfin no bug : Call AfxSetResourceHandle on resource dll handle to
// enable early calls to LoadString() etc to work.
// Use AfxFreeLibrary instead of FreeLibrary to use thread
// protected version of function.
#include "stdafx.h"
#include "SnapIn.h"
#include <atlbase.h>
#include "WbemClassObject.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
//
// Note!
//
// If this DLL is dynamically linked against the MFC
// DLLs, any functions exported from this DLL which
// call into MFC must have the AFX_MANAGE_STATE macro
// added at the very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
//
// It is very important that this macro appear in each
// function, prior to any calls into MFC. This means that
// it must appear as the first statement within the
// function, even before any object variable declarations
// as their constructors may generate calls into the MFC
// DLL.
//
// Please see MFC Technical Notes 33 and 58 for additional
// details.
//
CStringArray CSnapInApp::m_arrsNamespaces;
/////////////////////////////////////////////////////////////////////////////
// CSnapInApp
BEGIN_MESSAGE_MAP(CSnapInApp, CWinApp) //{{AFX_MSG_MAP(CSnapInApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSnapInApp construction
CSnapInApp::CSnapInApp() { // TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// Resource Dll Members
inline bool CSnapInApp::LoadDefaultResourceDll() { TRACEX(_T("CSnapInApp::LoadDefaultResourceDll\n"));
// first attempt to load resources for the current locale
m_hDefaultResourceDll = AfxLoadLibrary(GetDefaultResDllPath());
// if that fails then load resources for english
if( m_hDefaultResourceDll == NULL ) { m_hDefaultResourceDll = AfxLoadLibrary(GetEnglishResDllPath()); }
// v-marfin
AfxSetResourceHandle(m_hDefaultResourceDll);
return m_hDefaultResourceDll != NULL; }
inline void CSnapInApp::UnloadDefaultResourceDll() { TRACEX(_T("CSnapInApp::UnloadDefaultResourceDll\n"));
if( m_hDefaultResourceDll ) { // v-marfin (no bug)
AfxFreeLibrary(m_hDefaultResourceDll); } }
HINSTANCE CSnapInApp::LoadResourceDll(const CString& sFileName) { HINSTANCE hDllInst = NULL; if( m_ResourceDllMap.Lookup(sFileName,hDllInst) ) { return hDllInst; }
hDllInst = AfxLoadLibrary(GetDefaultResDllDirectory() + sFileName); if( !hDllInst ) { //AfxMessageBox(IDS_STRING_RESOURCE_DLL_MISSING);
return NULL; }
m_ResourceDllMap.SetAt(sFileName,hDllInst);
return hDllInst; }
bool CSnapInApp::LoadString(const CString& sFileName, UINT uiResId, CString& sResString) { HINSTANCE hInst = LoadResourceDll(sFileName); if( ! hInst ) { return false; }
int iResult = ::LoadString(hInst,uiResId,sResString.GetBuffer(2048),2048); sResString.ReleaseBuffer();
if( iResult == 0 || sResString.IsEmpty() ) { return false; }
return true; }
void CSnapInApp::UnloadResourceDlls() { POSITION pos = m_ResourceDllMap.GetStartPosition(); LPCTSTR lpszKey; HINSTANCE hInst;
while (pos != NULL) { m_ResourceDllMap.GetNextAssoc( pos, lpszKey, hInst );
AfxFreeLibrary(hInst); } }
/////////////////////////////////////////////////////////////////////////////
// Help System Members
inline void CSnapInApp::SetHelpFilePath() { TRACEX(_T("CSnapInApp::SetHelpFilePath\n"));
TCHAR szWinDir[_MAX_PATH]; GetWindowsDirectory(szWinDir,_MAX_PATH);
CString sHelpFilePath; sHelpFilePath.Format(IDS_STRING_HELP_FORMAT,szWinDir);
if( m_pszHelpFilePath ) { free((LPVOID)m_pszHelpFilePath); }
m_pszHelpFilePath = _tcsdup(sHelpFilePath); }
/////////////////////////////////////////////////////////////////////////////
// Directory Assistance Members
CString CSnapInApp::GetSnapinDllDirectory() { TCHAR szModule[_MAX_PATH]; TCHAR szDrive[_MAX_PATH]; TCHAR szDir[_MAX_PATH]; GetModuleFileName(AfxGetInstanceHandle(), szModule, _MAX_PATH); _tsplitpath(szModule,szDrive,szDir,NULL,NULL); CString sPath; sPath += szDrive; sPath += szDir; return sPath; }
CString CSnapInApp::GetDefaultResDllDirectory() { LCID lcid = GetUserDefaultLCID(); CString sLocaleID; sLocaleID.Format(_T("%08x\\"),lcid); return GetSnapinDllDirectory() + sLocaleID; }
CString CSnapInApp::GetDefaultResDllPath() { return GetDefaultResDllDirectory() + _T("HMSnapinRes.dll"); }
CString CSnapInApp::GetEnglishResDllPath() { return GetSnapinDllDirectory() + _T("00000409\\HMSnapinRes.dll"); }
/////////////////////////////////////////////////////////////////////////////
// The one and only CSnapInApp object
CSnapInApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CSnapInApp initialization
BOOL CSnapInApp::InitInstance() { SetRegistryKey(_T("Microsoft"));
// Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications.
COleObjectFactory::RegisterAll();
// set the help path up
SetHelpFilePath();
// load the resource dll
if( ! LoadDefaultResourceDll() ) { AfxMessageBox(IDS_STRING_RESOURCE_DLL_MISSING); return FALSE; }
//-------------------------------------------------------------------------------
// v-marfin : bug 58675 : Disable the "server busy.. retry, switch, etc" dialog.
//
if (!AfxOleInit()) { AfxMessageBox(IDS_ERR_OLE_INIT_FAILED); return FALSE; }
// If an OLE message filter is already in place, remove it
COleMessageFilter *pOldFilter = AfxOleGetMessageFilter(); if (pOldFilter) { pOldFilter->Revoke(); }
// Disable the "busy" dialogs
m_mfMyMessageFilter.EnableNotRespondingDialog(FALSE); m_mfMyMessageFilter.EnableBusyDialog(FALSE);
if (!m_mfMyMessageFilter.Register()) { AfxMessageBox(IDS_ERR_MSGFILTER_REG_FAILED); } //-------------------------------------------------------------------------------
return TRUE; }
int CSnapInApp::ExitInstance() { UnloadDefaultResourceDll();
UnloadResourceDlls(); //-------------------------------------------------------------------------------
// v-marfin : bug 58675 : Disable the "server busy.. retry, switch, etc" dialog.
m_mfMyMessageFilter.Revoke();
return CWinApp::ExitInstance(); }
/////////////////////////////////////////////////////////////////////////////
// Special entry points required for inproc servers
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return AfxDllGetClassObject(rclsid, riid, ppv); }
STDAPI DllCanUnloadNow(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return AfxDllCanUnloadNow(); }
HRESULT UpdateRegistryFromResource(LPCOLESTR lpszRes,BOOL bRegister) { HRESULT hRes = S_OK; IRegistrar* p;
hRes = CoCreateInstance(CLSID_Registrar, NULL, CLSCTX_INPROC_SERVER, IID_IRegistrar, (void**)&p); if( ! CHECKHRESULT(hRes) ) { AfxMessageBox(_T("Could not create CLSID_Registrar ! Updated version of ATL.DLL is needed !")); return hRes; } else { TCHAR szModule[_MAX_PATH]; GetModuleFileName(AfxGetInstanceHandle(), szModule, _MAX_PATH); BSTR szTemp = CString(szModule).AllocSysString(); p->AddReplacement(OLESTR("Module"), szTemp );
LPCOLESTR szType = OLESTR("REGISTRY"); if( HIWORD(lpszRes) == 0 ) { #ifndef IA64
if (bRegister) hRes = p->ResourceRegister(szModule, ((UINT)LOWORD((DWORD)lpszRes)), szType); else hRes = p->ResourceRegister(szModule, ((UINT)LOWORD((DWORD)lpszRes)), szType); #endif // IA64
} else { if (bRegister) hRes = p->ResourceRegisterSz(szModule, lpszRes, szType); else hRes = p->ResourceUnregisterSz(szModule, lpszRes, szType);
} ::SysFreeString(szTemp); p->Release(); } return hRes; }
// by exporting DllRegisterServer, you can use regsvr.exe
STDAPI DllRegisterServer(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE)) return ResultFromScode(SELFREG_E_CLASS);
HRESULT hRes = UpdateRegistryFromResource((LPCOLESTR)MAKEINTRESOURCE(IDR_REGISTRY),TRUE); if( hRes != S_OK ) { return hRes; }
return S_OK; }
STDAPI DllUnregisterServer(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE)) return ResultFromScode(SELFREG_E_CLASS);
HRESULT hRes = UpdateRegistryFromResource((LPCOLESTR)MAKEINTRESOURCE(IDR_REGISTRY_UNREG),TRUE); if( hRes != S_OK ) { return hRes; }
// delete the HMSnapin.ini file
CString sPath; GetWindowsDirectory(sPath.GetBuffer(_MAX_PATH+1),_MAX_PATH); sPath.ReleaseBuffer();
sPath += _T("\\HMSnapin.ini");
try { CFile::Remove(sPath); } catch(CException* pE) { pE->Delete(); }
return S_OK; }
//*********************************************************
// EscapeSpecialChars v-marfin bug 60233
//*********************************************************
CString CSnapInApp::EscapeSpecialChars(CString &refString) { // Convert any single backslashes to double backslashes.
// Setup our return var.
CString sRet;
// get size of string so we don't call GetLength repeatedly
int nSize=refString.GetLength(); int x=0;
// for each char in passed string, inspect and convert into ret val
for (x=0; x<nSize; x++) { // Does this position have a backslash?
if (refString.GetAt(x) == _T('\\')) { // Yes - Add 1 more backslash to the ret string before copying the
// original
sRet += _T('\\'); }
sRet += refString.GetAt(x); }
return sRet; } //*********************************************************
// UnEscapeSpecialChars v-marfin bug 60233
//*********************************************************
CString CSnapInApp::UnEscapeSpecialChars(CString &refString) { // Convert any double backslashes read from WMI into single
// Setup our return var.
CString sRet;
// get size of string so we don't call GetLength repeatedly
int nSize=refString.GetLength(); int x=0;
// for each char in passed string, inspect and convert into ret val
while (x < nSize) { // Does this position have a double backslash?
if (refString.Mid(x,2) == _T("\\\\")) { // Yes - only write 1 to the return string and increment our index by 2
sRet += _T('\\'); x += 2; } else { // No, just copy the char to the return string and increment index.
sRet += refString.GetAt(x++); } }
return sRet; }
//****************************************************
// ValidNamespace
//****************************************************
BOOL CSnapInApp::ValidNamespace(const CString &refNamespace, const CString& sMachine) { // If namespaces are empty, load.
if (m_arrsNamespaces.GetSize() < 1) { // loads only once since it is static.
CWaitCursor w; LoadNamespaceArray(_T("ROOT"),sMachine); }
// scan namespace array
int nSize = (int)m_arrsNamespaces.GetSize(); for (int x=0; x<nSize; x++) { if (m_arrsNamespaces.GetAt(x).CompareNoCase(refNamespace)==0) return TRUE; }
return FALSE; // not found. invalid.
}
//********************************************************************
// LoadNamespaceArray
//********************************************************************
void CSnapInApp::LoadNamespaceArray(const CString& sNamespace, const CString& sMachine) { ULONG ulReturned = 0L; int i = 0;
CWbemClassObject Namespaces; Namespaces.Create(sMachine);
Namespaces.SetNamespace(sNamespace);
CString sTemp = IDS_STRING_MOF_NAMESPACE; BSTR bsTemp = sTemp.AllocSysString(); if( ! CHECKHRESULT(Namespaces.CreateEnumerator(bsTemp)) ) { ::SysFreeString(bsTemp); return; } ::SysFreeString(bsTemp);
// for each namespace
while( Namespaces.GetNextObject(ulReturned) == S_OK && ulReturned ) { CString sName; Namespaces.GetProperty(IDS_STRING_MOF_NAME,sName);
CString sTemp2; Namespaces.GetProperty(IDS_STRING_MOF_NAMESPACE,sTemp2);
// build namespace string
CString sNamespaceFound = sTemp2 + _T("\\") + sName;
// Add the namespace to the array
m_arrsNamespaces.Add(sNamespaceFound); // call ourself recursively
LoadNamespaceArray(sNamespaceFound,sMachine); }
}
|