home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-12-16 | 8.7 KB | 491 lines | [TEXT/CWIE] |
- //
- // DLLENTRY.CPP
- //
- // Copyright (C) Microsoft Corporation, 1996
- //
-
- #include <stdio.h>
- #include "ocHeaders.h"
- #include "CBaseControl.h"
- #include "ResourceMap.h"
- #include "dllentry.h"
-
- #define INITGUID
- #include <initguid.h>
-
- #include "register.h"
-
- typedef struct
- {
- CFragInitBlock InitBlock;
- ResourceMapHandle TopMapHdl;
- unsigned long RefThisDll; // used to be g_cRefThisDll = 0;
- Boolean Inited;
- short ResRefNum;
- }
- dlldata;
-
- static dlldata DllData;
-
- static pascal void WriteToOleReg (char * strKey, char * strValue);
- static char * privstrcat(char * dest, const char * src);
-
- enum
- {
- uppDllInitRoutineProcInfo = kPascalStackBased
- | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
- | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(CFragInitBlockPtr)))
- };
-
- ProcInfoType __procinfo = uppDllInitRoutineProcInfo;
-
-
- extern "C"
- {
- OSErr pascal __initialize(CFragInitBlockPtr initBlkPtr);
- OSErr pascal DllInitializationRoutine(CFragInitBlockPtr initBlkPtr);
- OSErr pascal DllExecutionRoutine(CFragInitBlockPtr initBlkPtr);
- void pascal DllTerminationRoutine(CFragInitBlockPtr initBlkPtr);
- }
-
-
- short GetDllResRefNum(void)
- {
- return DllData.ResRefNum;
- }
-
- ResourceMapHandle GetDllTopMapHdl(void)
- {
- return DllData.TopMapHdl;
- }
-
-
- //
- // Class Factory
- //
- // Class for creating an instance of the control class
- //
-
- class CClassFactory:
- public IClassFactory
- {
- public:
- // *** Constructor/Destructor methods ***
- CClassFactory(void);
- ~CClassFactory(void);
-
- // *** IUnknown methods ***
- STDMETHOD(QueryInterface)(REFIID riid, void** ppv);
- STDMETHOD_(ULONG, AddRef)(void);
- STDMETHOD_(ULONG, Release)(void);
-
- // *** IClassFactory methods ***
- STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void**
- ppvObject);
- STDMETHOD(LockServer)(unsigned long fLock);
-
- protected:
- ULONG m_cRef;
-
- };
-
-
- //
- // CBaseClassFactory::CClassFactory
- //
- // Constructor
- //
-
- CClassFactory::CClassFactory()
- {
- m_cRef = 1;
- DLLAddRef();
-
- if (!DllData.Inited && DllData.InitBlock.fragLocator.where == kDataForkCFragLocator)
- {
- short InResFile = ::CurResFile();
- ResourceMapHandle InTopMapHdl = ResourceMapHandle( ::LMGetTopMapHndl() );
-
- DllData.Inited = true;
- // open up the resource fork of the dll and save it off
- DllData.ResRefNum = ::FSpOpenResFile(DllData.InitBlock.fragLocator.u.onDisk.fileSpec, fsRdPerm);
- DllData.TopMapHdl = ResourceMapHandle( ::LMGetTopMapHndl() );
- ::UseResFile(InResFile);
- ::LMSetTopMapHndl( Handle(InTopMapHdl) );
- }
- }
-
- //
- // CClassFactory::~CClassFactory
- //
- // Destructor
- //
-
- CClassFactory::~CClassFactory()
- {
- if (DllData.Inited)
- {
- if (DllData.TopMapHdl != NULL)
- ::LMSetTopMapHndl( Handle(DllData.TopMapHdl) );
-
- if (DllData.ResRefNum != -1)
- {
- ::FSClose(DllData.ResRefNum);
- DllData.ResRefNum = -1;
- }
- }
- DLLRelease();
- }
-
- //
- // CClassFactory::IUnknown::QueryInterface
- //
- // Returns a pointer to the specified interface on a component to which a
- // client currently holds an interface pointer.
- //
-
- STDMETHODIMP
- CClassFactory::QueryInterface(REFIID riid, void** ppv)
- {
- HRESULT rc = 0;
-
- void* pv;
-
- if (riid == IID_IUnknown || riid == IID_IClassFactory)
- pv = (void*)(LPCLASSFACTORY) this;
- else {
- *ppv = NULL;
- rc = E_NOINTERFACE;
- goto Done;
- }
-
- *ppv = pv;
- ((LPUNKNOWN) pv)->AddRef();
- rc = S_OK;
-
- Done:
- return rc;
- }
-
- //
- // CClassFactory::IUnknown::AddRef
- //
- // Increments the reference count for the calling interface.
- //
-
- STDMETHODIMP_(ULONG)
- CClassFactory::AddRef(void)
- {
- return ++m_cRef;
- }
-
- //
- // CClassFactory::IUnknown::Release
- //
- // Decrements the reference count for the calling interface on a object. If
- // the reference count on the object falls to zero, the object is freed.
- //
-
- STDMETHODIMP_(ULONG)
- CClassFactory::Release(void)
- {
- if (--m_cRef != 0)
- return m_cRef;
-
- delete this;
- return 0;
- }
-
- //
- // CClassFactory::IClassFactory::Release
- //
- // Decrements the reference count for the calling interface on a object. If
- // the reference count on the object falls to zero, the object is freed.
- //
-
- STDMETHODIMP
- CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObject)
- {
- #pragma unused (pUnkOuter)
- HRESULT hr;
- CControl* pControl;
-
- pControl = new CControl();
-
- if (pControl == NULL)
- {
- *ppvObject = NULL;
- return E_OUTOFMEMORY;
- }
-
- hr = pControl->QueryInterface(riid, ppvObject);
- ((IControl*)pControl)->Release();
-
- return hr;
- }
-
- //
- // CClassFactory::IClassFactory::LockServer
- //
- // Decrements the reference count for the calling interface on a object. If
- // the reference count on the object falls to zero, the object is freed.
- //
-
- STDMETHODIMP
- CClassFactory::LockServer(unsigned long fLock)
- {
- #pragma unused (fLock)
- return E_NOTIMPL;
- }
-
- #pragma export on
-
- //
- // DllGetClassObject
- //
- // Called by COM to create the class factory
- //
-
- STDAPI
- DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
- {
-
-
- HRESULT hr;
- CClassFactory* pcf;
-
- *ppv = NULL;
-
- if (IsEqualCLSID(rclsid, CLSID_ocx))
- {
- pcf = new CClassFactory();
- if (pcf != NULL)
- {
- hr = pcf->QueryInterface(riid, ppv);
- pcf->Release();
- }
- else
- {
- hr = E_OUTOFMEMORY;
- }
- }
- else
- {
- hr = CLASS_E_CLASSNOTAVAILABLE;
- }
-
- return hr;
- }
-
-
- //
- // DllCanUnloadNow
- //
- // Determines whether the dll can be unloaded yet
- //
-
- STDAPI
- DllCanUnloadNow(void)
- {
- return (DllData.RefThisDll == 0) ? S_OK : S_FALSE;
- }
-
- #define kCLSIDConst "CLSID\\"
- #define kINPROCSERVERConst "\\InprocServer"
- #define kALIASConst "\\Alias"
- #define kALS2Const "ALS2:"
-
- STDAPI
- DllRegisterServer(void)
- {
- HKEY hKey;
- char Key[256];
- char DataValue[256];
- SCODE sc;
- unsigned long AliasLength;
-
- DllUnregisterServer();
- Key[0] = '\0';
- privstrcat(Key, kCLSIDConst kOCXCLSID);
- if (RegOpenKey(HKEY_CLASSES_ROOT, Key, &hKey) == S_OK)
- RegCloseKey(hKey);
- else
- {
- AliasHandle AliasH;
- HKEY hkey = NULL;
-
- WriteToOleReg(Key, kOCXFullUserTypeName);
-
- Key[0] = '\0';
- privstrcat(Key, kCLSIDConst kOCXCLSID kINPROCSERVERConst);
- DataValue[0] = '\0';
- privstrcat(DataValue, kALS2Const kOCXProgID);
-
- WriteToOleReg(Key, DataValue);
-
- ::NewAlias (NULL, DllData.InitBlock.fragLocator.u.onDisk.fileSpec, &AliasH);
-
- if((AliasH) && (RegOpenKey(HKEY_CLASSES_ROOT, Key, &hkey) == ERROR_SUCCESS))
- {
- AliasLength = ::GetHandleSize(Handle(AliasH));
-
- Key[0] = '\0';
- privstrcat(Key, kCLSIDConst kOCXCLSID kINPROCSERVERConst kALIASConst);
-
- sc = RegSetValueEx(hkey, "Alias", 0, REG_BINARY,
- (char*)*AliasH, AliasLength);
-
- RegCloseKey(hkey);
- }
-
- if (AliasH)
- ::DisposeHandle( Handle(AliasH) );
- }
-
- return S_OK;
- }
-
- //
- // DllUnregisterServer
- //
- // Unregisters the server from the COM registry
- //
-
- STDAPI
- DllUnregisterServer(void)
- {
- HKEY hKey;
- char DataValue[256];
- char SubKey[256];
- long length;
-
- if (RegOpenKey(HKEY_CLASSES_ROOT, "CLSID", &hKey) == S_OK)
- {
- SubKey[0] = '\0';
- privstrcat(SubKey, kCLSIDConst kOCXCLSID);
- if (RegQueryValue(HKEY_CLASSES_ROOT, SubKey, DataValue, &length) == S_OK)
- {
- RegDeleteKey(HKEY_CLASSES_ROOT, SubKey);
- }
-
- RegCloseKey(hKey);
- }
-
- return S_OK;
- }
-
-
- //
- // DllInitializationRoutine
- //
- // Initialization routine called by COM
- //
-
- OSErr pascal
- DllInitializationRoutine(CFragInitBlockPtr initBlkPtr)
- {
- DllData.InitBlock = *initBlkPtr;
- DllData.TopMapHdl = NULL;
- DllData.Inited = false;
- DllData.ResRefNum = -1;
- DllData.RefThisDll = 0;
-
- __initialize(initBlkPtr);
- return noErr;
- }
-
-
- //
- // DllInitializationRoutine
- //
- // Initialization routine called by COM
- //
-
- OSErr pascal
- DllExecutionRoutine(CFragInitBlockPtr initBlkPtr)
- {
- #pragma unused (initBlkPtr)
- // this routine isn't getting called by anybody
- return noErr;
- }
-
-
- //
- // DllTerminationRoutine
- //
- // Termination routine called by COM
- //
-
- void pascal
- DllTerminationRoutine(CFragInitBlockPtr initBlkPtr)
- {
- #pragma unused (initBlkPtr)
- }
-
-
- //
- // WriteToOleReg
- //
- // Utility function for writing a CLASSID key to the COM registry
- //
-
- pascal void WriteToOleReg (char * strKey, char * strValue)
- {
- static Boolean fNoErr = true;
- SCODE sc;
-
- sc = RegSetValue(HKEY_CLASSES_ROOT, strKey, REG_SZ, strValue, 0);
- if (sc != S_OK)
- {
- fNoErr = false;
- }
- }
-
-
- //
- // privstrcat
- //
- // Utility function for concatenating strings
- //
-
- char * privstrcat(char * dst, const char * src)
- {
- #if !__POWERPC__
-
- const char * p = src;
- char * q = dst;
-
- while (*q++);
-
- q--;
-
- while (*q++ = *p++);
-
- #else
-
- const unsigned char * p = (unsigned char *) src - 1;
- unsigned char * q = (unsigned char *) dst - 1;
-
- while (*++q) ;
-
- q--;
-
- while ((*++q = *++p) != 0) ;
-
- #endif
-
- return(dst);
- }
-
- unsigned long DLLAddRef()
- {
- return ++DllData.RefThisDll;
- }
-
- unsigned long DLLRelease()
- {
- return --DllData.RefThisDll;
- }
-
- #pragma export off
-