// 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 #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