/*============================================================================ * * File Name: DLLMain.cpp * * Description: Main File that is responsible for registering a Tribble * with COM. * * Author: * * Date: * * *==============================================================================*/ // $history: $ //============================================================================== #include "stdafx.h" #include "dllmain.h" #include "TribbleInterface.h" #include "tribbleclass.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //=== External References =================================================== extern CTribbleClass g_TribbleClass; //=== Global Variables ====================================================== // NOTE:This variable gets initialized to contain the current // file name for this module. TCHAR g_szFileName[MAX_PATH]; ///////////////////////////////////////////////////////////////////////////// // The one and only CTribbleApp object CTribbleApp theApp; LONG g_ModuleLock = 0L; // Locks the server in memory // CTribbleApp BEGIN_MESSAGE_MAP(CTribbleApp, CWinApp) //{{AFX_MSG_MAP(CTribbleApp) // 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() ///////////////////////////////////////////////////////////////////////////// // CTribbleApp construction CTribbleApp::CTribbleApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } //--------------------------------------------------------------------------- // Method: CTribbleApp::InitInstance // Purpose: Init the DLL //--------------------------------------------------------------------------- BOOL CTribbleApp::InitInstance() { CWinApp::InitInstance(); // Get the file name GetModuleFileName(AfxGetInstanceHandle(), g_szFileName, MAX_PATH); return TRUE; } /// Helper Functions /////// /// Used to lock the server in memory void LockModule() { ::InterlockedIncrement(&g_ModuleLock); } /// Used to lower the lock count - making it more // likely that the tribble is released. void UnlockModule() { ::InterlockedDecrement(&g_ModuleLock); } extern "C" { /*============================================================================ * Start of Registry Entry Data. ==============================================================================*/ /* * We have defined a class of "FurryAnimals" to which tribbles belong */ // NOTE:This structure represents the static data that will be // used to create/delete this server's registry keys and values. struct REG_DATA { const TCHAR *pszKeyName; const TCHAR *pszValueName; const TCHAR *pszValue; BOOL bDeleteOnUnregister; }; // NOTE:This table has all of the keys and values used to // self register this server. const REG_DATA g_rgEntries[] = { // Uses Class ID of 384D1ED2,0x635E,0x11d2,{0xAD,0x73,0x00,0x00,0x00,0x00,0x00,0x00 // Which is : // // 384D1ED2-635E-11d2-AD73-000000000000 { __TEXT("CLSID\\{384D1ED2-635E-11d2-AD73-000000000000}"), 0, __TEXT("Tribble Class"), TRUE }, { __TEXT("CLSID\\{384D1ED2-635E-11d2-AD73-000000000000}"), __TEXT("ThreadingModel"), __TEXT("Apartment"), TRUE }, { __TEXT("CLSID\\{384D1ED2-635E-11d2-AD73-000000000000}\\InprocServer32"), 0, g_szFileName, TRUE }, { __TEXT("CLSID\\{384D1ED2-635E-11d2-AD73-000000000000}\\ProgID"), 0, __TEXT("FurryAnimals.Tribble.1"), TRUE }, { __TEXT("CLSID\\{384D1ED2-635E-11d2-AD73-000000000000}\\VersionIndependentProgID"), 0, __TEXT("FurryAnimals.Tribble"), TRUE }, { __TEXT("FurryAnimals.Tribble.1"), 0, __TEXT("Tribble"), TRUE }, { __TEXT("FurryAnimals.Tribble.1\\CLSID"), 0, __TEXT("{384D1ED2-635E-11d2-AD73-000000000000}"), TRUE }, { __TEXT("FurryAnimals.Tribble"), 0, __TEXT("Tribble"), TRUE }, { __TEXT("FurryAnimals.Tribble\\CLSID"), 0, __TEXT("{384D1ED2-635E-11d2-AD73-000000000000}"), TRUE }, { __TEXT("FurryAnimals.Tribble\\CurVer"), 0, __TEXT("FurryAnimals.Tribble.1"), TRUE }, }; const int g_cEntries = sizeof(g_rgEntries)/sizeof(*g_rgEntries); /*============================================================================ * End of Registry Entry Data ==============================================================================*/ //------------------------------------------------------------------------------ // Method: Unregister // Purpose: This is the actual unregister code. Called from separate places //------------------------------------------------------------------------------ static HRESULT Unregister(const REG_DATA *rgEntries, int cEntries) { HRESULT hr; hr = UnRegisterTypeLib (LIBID_TribbleLib, 1, 0, 0, SYS_WIN32); BOOL bSuccess = true; for (int i = cEntries - 1; i >= 0; i--) if (rgEntries[i].bDeleteOnUnregister) { LONG err = RegDeleteKey(HKEY_CLASSES_ROOT, rgEntries[i].pszKeyName); if (err != ERROR_SUCCESS) bSuccess = FALSE; } return bSuccess ? S_OK : S_FALSE; } // Unregister //--------------------------------------------------------------------------- // Method: DllGetClassObject // Purpose: Return the Class Object to the caller if IClassFactory is req'd //--------------------------------------------------------------------------- STDAPI DllGetClassObject(REFCLSID rclsid,REFIID riid, void **pvObject) { HRESULT hr = S_OK; if (rclsid == CLSID_Tribble) hr = g_TribbleClass.QueryInterface (riid, pvObject); else hr = CLASS_E_CLASSNOTAVAILABLE; return hr; } // DllGetClassObject //--------------------------------------------------------------------------- // Method: DllCanUnloadNow // Purpose: Tells the caller if they can unload this DLL //--------------------------------------------------------------------------- STDAPI DllCanUnloadNow() { HRESULT hr; if(!g_ModuleLock) hr = S_OK; // can unload the library else hr = S_FALSE; // can't unload yet return hr; } // DllCanUnloadNow //--------------------------------------------------------------------------- // Method: DllRegisterServer // Purpose: Register the server by first using the type lib and then the // boiler plate code for the rest. //--------------------------------------------------------------------------- STDAPI DllRegisterServer(void) { ITypeLib *pITLB = 0; HRESULT hr; /* * note this code registers the type lib * it has to be wide char because that's what COM * takes */ WCHAR wszFullPath [MAX_PATH]; MultiByteToWideChar (CP_ACP, 0, g_szFileName, -1, wszFullPath, MAX_PATH); // ACTUALLY DO THE REGISTREATION hr = LoadTypeLib (wszFullPath, &pITLB); if (SUCCEEDED (hr)) { hr = RegisterTypeLib (pITLB, wszFullPath, NULL); if(FAILED(hr)) MessageBox(NULL,"Registration failed","DEBUG",MB_OK); pITLB->Release (); } else MessageBox(NULL,"Load failed","DEBUG",MB_OK); // this bit registers all the interfaces, // class ids and other baloney BOOL bSuccess = TRUE; const REG_DATA *pEntry = g_rgEntries; while (pEntry < g_rgEntries + g_cEntries) { HKEY hkey; LONG err = RegCreateKey(HKEY_CLASSES_ROOT, pEntry->pszKeyName, &hkey); if (err == ERROR_SUCCESS) { if (pEntry->pszValue) err = RegSetValueEx(hkey, pEntry->pszValueName, 0, REG_SZ, (const BYTE*)pEntry->pszValue, (lstrlen(pEntry->pszValue) + 1) * sizeof(TCHAR)); if (err != ERROR_SUCCESS) { bSuccess = FALSE; } RegCloseKey(hkey); } if (err != ERROR_SUCCESS) { bSuccess = FALSE; } pEntry++; } return bSuccess ? S_OK : E_FAIL; } // DllRegisterServer //--------------------------------------------------------------------------- // Method: DllUnregisterServer // Purpose: Delete the server from the registry //--------------------------------------------------------------------------- STDAPI DllUnregisterServer(void) { return Unregister(g_rgEntries,g_cEntries); } // DllUnregisterServer } // extern "C" /*============================================================================ * End of File: DLLMain.cpp ==============================================================================*/