home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- (C) Copyright 1995 - 1999 Microsoft Corporation. All rights reserved.
-
-
- --*/
-
-
- #pragma hdrstop
-
-
- #define INITGUID 1
-
- #include <windows.h>
- #include <stdio.h>
- #include <olectl.h> // to get the SELFREF_E_CLASS definition
-
-
- #include "debug\\Plotter.h" // IPlotter defn (generated from Plotter.odl).
-
-
-
- //=======================================================================
- // CPlotter
- //
- // This class implements our COM object which exposes only one interface
- // (IPlotter).
- //
- // Strictly speaking, it should also expose IMarshal by aggregating the
- // Ole free-threaded marshaler, since this dll marks itself "Both."
- // For such a simple sample, however, this will not matter.
- //=======================================================================
-
- class CPlotter : public IPlotter {
- private:
- ULONG m_ref; // Reference count.
-
- public:
- CPlotter() {
- m_ref = 0;
- }
-
- //-------------------------------------------------------
- // IUnknown methods.
- //-------------------------------------------------------
- STDMETHOD(QueryInterface) (REFIID riid, LPVOID *ppv) {
- __try {
- *ppv = NULL;
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- return E_POINTER;
- }
-
- if (riid == IID_IUnknown || riid == IID_IPlotter) {
- AddRef();
- *ppv = (IPlotter*)this;
- return S_OK;
- }
- return E_NOINTERFACE;
- }
-
- STDMETHOD_(ULONG, AddRef) () {
- InterlockedIncrement( (LONG*)&m_ref );
- return 1;
- }
-
- STDMETHOD_(ULONG, Release) () {
- LONG ulc;
-
- ulc = InterlockedDecrement( (LONG*)&m_ref );
- if (ulc < 0) {
- OutputDebugString("Too many releases on CPlotter object!\n");
- DebugBreak();
- }
- if (0 == ulc) {
- OutputDebugString("CPlotter: Destroy\n");
- delete this;
- return 0;
- }
- return 1;
- }
-
-
- //-------------------------------------------------------
- // IPlotter methods.
- //-------------------------------------------------------
- STDMETHOD(DrawLine)(POINT *start, POINT *end)
- {
- printf("DrawLine called: start = (%ld,%ld), end = (%ld,%ld)\n",
- start->x,
- start->y,
- end->x,
- end->y);
- return S_OK;
- }
-
- };
-
-
- //=======================================================================
- // J2CClassFactory
- //
- // This class implements the classfactory for our COM server. Since our
- // classfactory has no intrinsic state, we use a static class factory
- // to simplify our implementation.
- //
- //=======================================================================
- class J2CClassFactory : public IClassFactory
- {
- public:
-
- //-----------------------------------------------------------
- // IUnknown methods.
- //-----------------------------------------------------------
- STDMETHOD(QueryInterface) (REFIID riid, LPVOID *ppv)
- {
- __try {
- *ppv = NULL;
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- return E_POINTER;
- }
-
- if (riid == IID_IUnknown || riid == IID_IClassFactory) {
- AddRef();
- *ppv = (IClassFactory*)this;
- return S_OK;
- }
- return E_NOINTERFACE;
- }
-
- STDMETHOD_(ULONG, AddRef) () {
- return 1;
- }
-
- STDMETHOD_(ULONG, Release) () {
- return 1;
- }
-
- //-----------------------------------------------------------
- // IClassFactory methods.
- //-----------------------------------------------------------
- STDMETHOD(CreateInstance)(IUnknown *punkOuter, REFIID riid, LPVOID *ppv)
- {
- *ppv = NULL;
-
- if (punkOuter != NULL) {
- return CLASS_E_NOAGGREGATION;
- }
-
- CPlotter *pJ2CThing;
- HRESULT hr;
-
- pJ2CThing = new CPlotter();
- if (!pJ2CThing) {
- return E_OUTOFMEMORY;
- }
-
- pJ2CThing->AddRef();
- hr = pJ2CThing->QueryInterface(riid, ppv);
- pJ2CThing->Release();
- return hr;
- }
-
- STDMETHOD(LockServer)(BOOL fLock) {
- return S_OK;
- }
-
- };
-
-
- //===================================================================
- // Create our first (and only) classfactory.
- //===================================================================
- J2CClassFactory g_CF;
-
-
- // Rememeber our dll's module handle.
- HINSTANCE ghInstance;
-
-
-
-
- //===================================================================
- // Standard DLL entry point (called by Win32 loader.)
- //===================================================================
- BOOL WINAPI DllMain(HINSTANCE hmod, DWORD dwReason,
- PVOID pvReserved)
- {
- ghInstance = hmod;
-
- if (dwReason == DLL_PROCESS_ATTACH) {
- OutputDebugString("Plotter.dll has successfully loaded.\n");
- }
-
- return TRUE;
- }
-
-
-
-
-
-
- //===================================================================
- // Standard Ole export ("creates" a classfactory.)
- //===================================================================
- STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
- {
-
- HRESULT hr;
-
- __try {
- *ppv = NULL;
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- return E_POINTER;
- }
-
- if (rclsid != CLSID_CPlotter) {
- return CLASS_E_CLASSNOTAVAILABLE;
- }
-
- return g_CF.QueryInterface(riid, ppv);
-
-
- }
-
-
-
-
- //===================================================================
- // Simple GUID unparsing utility (for self-registering code).
- //===================================================================
-
-
- #define GUIDSTR_MAX (1+ 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1)
-
- static const CHAR szDigits[] = "0123456789ABCDEF";
- static const BYTE GuidMap[] = { 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
- 8, 9, '-', 10, 11, 12, 13, 14, 15 };
-
-
- //--------------------------------------------------------------------------
- //
- // Function: GUID2StringA
- //
- // Synopsis: Convert GUID to string form
- //
- // Arguments: [rguid] - the guid to convert
- // [lpszy] - buffer to hold the results
- //
- // Returns: nothing
- //
- // This code is massively plagiarized from the Ole sources.
- //--------------------------------------------------------------------------
-
- VOID
- GUID2StringA(REFGUID rguid, LPSTR lpsz)
- {
- int i;
- LPSTR p = lpsz;
-
- const BYTE * pBytes = (const BYTE *) &rguid;
-
- *p++ = '{';
-
- for (i = 0; i < sizeof(GuidMap); i++)
- {
- if (GuidMap[i] == '-')
- {
- *p++ = '-';
- }
- else
- {
- *p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
- *p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
- }
- }
- *p++ = '}';
- *p = '\0';
- }
-
-
-
- const char achTM[] = "Both";
- const char achDESC[] = "Sample Custom Marshaling Server.";
- const char achPROGID[] = "CPlotter";
-
-
- //===================================================================
- // Standard Ole export (for self-registration a la regsvr32.)
- //===================================================================
- __declspec(dllexport)
- STDAPI
- DllRegisterServer(VOID)
- {
- HKEY hKey = NULL;
- HKEY hKey2 = NULL;
- HKEY hKey3 = NULL;
- DWORD result;
- HRESULT hr = SELFREG_E_CLASS;
- CHAR achCLSID[GUIDSTR_MAX];
- TCHAR achModulePathName[MAX_PATH];
-
- // If we fail in the middle, the state of the registry entries
- // is indeterminate (as per Ole specs.)
-
-
- // Create HKEY_CLASSES_ROOT\progid\CLSID
- result = RegCreateKey(HKEY_CLASSES_ROOT, achPROGID, &hKey);
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
- result = RegSetValue(hKey, NULL, REG_SZ, achDESC, lstrlen(achDESC));
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
- result = RegCreateKey(hKey, TEXT("CLSID"), &hKey2);
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
- GUID2StringA(CLSID_CPlotter, achCLSID);
- result = RegSetValue(hKey2, NULL, REG_SZ, achCLSID, GUIDSTR_MAX-1);
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
-
- RegCloseKey(hKey);
- RegCloseKey(hKey2);
- hKey = NULL;
- hKey2 = NULL;
-
-
- // Create HKEY_CLASSES_ROOT\CLSID\...
- result = RegCreateKey(HKEY_CLASSES_ROOT, TEXT("CLSID"), &hKey);
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
-
- result = RegCreateKey(hKey, achCLSID, &hKey2);
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
-
- result = RegSetValue(hKey2, NULL, REG_SZ, achDESC, lstrlen(achDESC));
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
-
- result = RegCreateKey(hKey2, "InprocServer32", &hKey3);
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
-
- result = GetModuleFileName(ghInstance, achModulePathName, sizeof(achModulePathName)/sizeof(TCHAR));
- if (result == 0) { //No way to detect truncation from GetModuleFileName.
- goto lExit;
- }
-
- result = RegSetValue(hKey3, NULL, REG_SZ, achModulePathName, lstrlen(achModulePathName));
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
-
- result = RegSetValueEx(hKey3, "ThreadingModel", 0, REG_SZ, (BYTE*)achTM, sizeof(achTM));
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
-
- RegCloseKey(hKey3);
- hKey3 = NULL;
-
-
- result = RegCreateKey(hKey2, "ProgID", &hKey3);
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
- result = RegSetValue(hKey3, NULL, REG_SZ, achPROGID, lstrlen(achPROGID));
- if (result != ERROR_SUCCESS) {
- goto lExit;
- }
- RegCloseKey(hKey3);
- hKey3 = NULL;
-
-
-
- hr = S_OK;
-
- lExit:
- if (hKey) {
- RegCloseKey(hKey);
- }
- if (hKey2) {
- RegCloseKey(hKey2);
- }
- if (hKey3) {
- RegCloseKey(hKey3);
- }
- return hr;
-
- }
-
-
-
- //===================================================================
- // Standard Ole export (for self-unregistration a la regsvr32.)
- //===================================================================
- __declspec(dllexport)
- STDAPI
- DllUnregisterServer(VOID)
- {
- return S_OK;
- }
-
-
-
-
-
-
-