home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 39 / IOPROG_39.ISO / SOFT / sdkjava40.exe / data1.cab / fg_Samples / Samples / COM / CustomMarshal / plotter / Plotter.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-04  |  10.6 KB  |  417 lines

  1. /*++
  2.  
  3. (C) Copyright 1995 - 1999 Microsoft Corporation.  All rights reserved.
  4.  
  5.  
  6. --*/
  7.  
  8.  
  9. #pragma hdrstop
  10.  
  11.  
  12. #define INITGUID 1
  13.  
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <olectl.h>          // to get the SELFREF_E_CLASS definition
  17.  
  18.  
  19. #include "debug\\Plotter.h"  // IPlotter defn (generated from Plotter.odl).
  20.  
  21.  
  22.  
  23. //=======================================================================
  24. // CPlotter
  25. //
  26. //   This class implements our COM object which exposes only one interface
  27. //   (IPlotter).
  28. //
  29. //   Strictly speaking, it should also expose IMarshal by aggregating the
  30. //   Ole free-threaded marshaler, since this dll marks itself "Both."
  31. //   For such a simple sample, however, this will not matter.
  32. //=======================================================================
  33.  
  34. class CPlotter : public IPlotter {
  35.     private:
  36.         ULONG       m_ref;          // Reference count.
  37.  
  38.     public:
  39.         CPlotter() {
  40.             m_ref = 0;
  41.         }
  42.  
  43.         //-------------------------------------------------------
  44.         // IUnknown methods.
  45.         //-------------------------------------------------------
  46.         STDMETHOD(QueryInterface) (REFIID riid, LPVOID *ppv) {
  47.             __try {
  48.                 *ppv = NULL;
  49.             } __except (EXCEPTION_EXECUTE_HANDLER) {
  50.                 return E_POINTER;
  51.             }
  52.  
  53.             if (riid == IID_IUnknown || riid == IID_IPlotter) {
  54.                 AddRef();
  55.                 *ppv = (IPlotter*)this;
  56.                 return S_OK;
  57.             }
  58.             return E_NOINTERFACE;
  59.         }
  60.  
  61.         STDMETHOD_(ULONG, AddRef) () {
  62.             InterlockedIncrement( (LONG*)&m_ref );
  63.             return 1;
  64.         }
  65.  
  66.         STDMETHOD_(ULONG, Release) () {
  67.             LONG ulc;
  68.  
  69.             ulc = InterlockedDecrement( (LONG*)&m_ref );
  70.             if (ulc < 0) {
  71.                 OutputDebugString("Too many releases on CPlotter object!\n");
  72.                 DebugBreak();
  73.             }
  74.             if (0 == ulc) {
  75.                 OutputDebugString("CPlotter: Destroy\n");
  76.                 delete this;
  77.                 return 0;
  78.             }
  79.             return 1;
  80.         }
  81.  
  82.  
  83.         //-------------------------------------------------------
  84.         // IPlotter methods.
  85.         //-------------------------------------------------------
  86.         STDMETHOD(DrawLine)(POINT *start, POINT *end)
  87.         {
  88.             printf("DrawLine called: start = (%ld,%ld), end = (%ld,%ld)\n",
  89.                    start->x,
  90.                    start->y,
  91.                    end->x,
  92.                    end->y);
  93.             return S_OK;
  94.         }
  95.  
  96. };
  97.  
  98.  
  99. //=======================================================================
  100. // J2CClassFactory
  101. //
  102. //   This class implements the classfactory for our COM server. Since our
  103. //   classfactory has no intrinsic state, we use a static class factory
  104. //   to simplify our implementation.
  105. //   
  106. //=======================================================================
  107. class J2CClassFactory : public IClassFactory
  108. {
  109.     public:
  110.  
  111.         //-----------------------------------------------------------
  112.         // IUnknown methods.
  113.         //-----------------------------------------------------------
  114.         STDMETHOD(QueryInterface) (REFIID riid, LPVOID *ppv)
  115.         {
  116.             __try {
  117.                 *ppv = NULL;
  118.             } __except (EXCEPTION_EXECUTE_HANDLER) {
  119.                 return E_POINTER;
  120.             }
  121.  
  122.             if (riid == IID_IUnknown || riid == IID_IClassFactory) {
  123.                 AddRef();
  124.                 *ppv = (IClassFactory*)this;
  125.                 return S_OK;
  126.             }
  127.             return E_NOINTERFACE;
  128.         }
  129.  
  130.         STDMETHOD_(ULONG, AddRef) () {
  131.             return 1;
  132.         }
  133.  
  134.         STDMETHOD_(ULONG, Release) () {
  135.             return 1;
  136.         }
  137.  
  138.         //-----------------------------------------------------------
  139.         // IClassFactory methods.
  140.         //-----------------------------------------------------------
  141.         STDMETHOD(CreateInstance)(IUnknown *punkOuter, REFIID riid, LPVOID *ppv)
  142.         {
  143.             *ppv = NULL;
  144.  
  145.             if (punkOuter != NULL) {
  146.                 return CLASS_E_NOAGGREGATION;
  147.             }
  148.  
  149.             CPlotter *pJ2CThing;
  150.             HRESULT hr;
  151.  
  152.             pJ2CThing = new CPlotter();
  153.             if (!pJ2CThing) {
  154.                 return E_OUTOFMEMORY;
  155.             }
  156.         
  157.             pJ2CThing->AddRef();
  158.             hr = pJ2CThing->QueryInterface(riid, ppv);
  159.             pJ2CThing->Release();
  160.             return hr;
  161.         }
  162.  
  163.         STDMETHOD(LockServer)(BOOL fLock) {
  164.             return S_OK;
  165.             }
  166.  
  167. };
  168.  
  169.  
  170. //===================================================================
  171. // Create our first (and only) classfactory.
  172. //===================================================================
  173. J2CClassFactory g_CF;
  174.  
  175.  
  176. // Rememeber our dll's module handle.
  177. HINSTANCE ghInstance;
  178.  
  179.  
  180.  
  181.  
  182. //===================================================================
  183. // Standard DLL entry point (called by Win32 loader.)
  184. //===================================================================
  185. BOOL WINAPI DllMain(HINSTANCE hmod, DWORD dwReason,
  186.                                 PVOID pvReserved)
  187. {
  188.    ghInstance = hmod;
  189.  
  190.    if (dwReason == DLL_PROCESS_ATTACH) {
  191.         OutputDebugString("Plotter.dll has successfully loaded.\n");
  192.    }
  193.  
  194.    return TRUE;
  195. }
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202. //===================================================================
  203. // Standard Ole export ("creates" a classfactory.)
  204. //===================================================================
  205. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
  206. {
  207.  
  208.     HRESULT hr;
  209.  
  210.     __try {
  211.         *ppv = NULL;
  212.     } __except (EXCEPTION_EXECUTE_HANDLER) {
  213.         return E_POINTER;
  214.     }
  215.  
  216.     if (rclsid != CLSID_CPlotter) {
  217.         return CLASS_E_CLASSNOTAVAILABLE;
  218.     }
  219.  
  220.     return g_CF.QueryInterface(riid, ppv);
  221.  
  222.  
  223. }
  224.  
  225.  
  226.  
  227.  
  228. //===================================================================
  229. // Simple GUID unparsing utility (for self-registering code).
  230. //===================================================================
  231.  
  232.  
  233. #define GUIDSTR_MAX (1+ 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1)
  234.  
  235. static const CHAR szDigits[] = "0123456789ABCDEF";
  236. static const BYTE GuidMap[] = { 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
  237.                                 8, 9, '-', 10, 11, 12, 13, 14, 15 };
  238.  
  239.  
  240. //--------------------------------------------------------------------------
  241. //
  242. //  Function:   GUID2StringA
  243. //
  244. //  Synopsis:   Convert GUID to string form
  245. //
  246. //  Arguments:  [rguid] - the guid to convert
  247. //              [lpszy] - buffer to hold the results
  248. //
  249. //  Returns:    nothing
  250. //
  251. //  This code is massively plagiarized from the Ole sources.
  252. //--------------------------------------------------------------------------
  253.  
  254. VOID
  255. GUID2StringA(REFGUID rguid, LPSTR lpsz)
  256. {
  257.     int i;
  258.     LPSTR p = lpsz;
  259.  
  260.     const BYTE * pBytes = (const BYTE *) &rguid;
  261.  
  262.     *p++ = '{';
  263.  
  264.     for (i = 0; i < sizeof(GuidMap); i++)
  265.     {
  266.         if (GuidMap[i] == '-')
  267.         {
  268.             *p++ = '-';
  269.         }
  270.         else
  271.         {
  272.             *p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
  273.             *p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
  274.         }
  275.     }
  276.     *p++ = '}';
  277.     *p   = '\0';
  278. }
  279.  
  280.  
  281.  
  282. const char achTM[] = "Both";
  283. const char achDESC[] = "Sample Custom Marshaling Server.";
  284. const char achPROGID[] = "CPlotter";
  285.  
  286.  
  287. //===================================================================
  288. // Standard Ole export (for self-registration a la regsvr32.)
  289. //===================================================================
  290. __declspec(dllexport)
  291. STDAPI
  292. DllRegisterServer(VOID)
  293. {
  294.    HKEY    hKey  = NULL;
  295.    HKEY    hKey2 = NULL;
  296.    HKEY    hKey3 = NULL;
  297.    DWORD   result;
  298.    HRESULT hr = SELFREG_E_CLASS;
  299.    CHAR    achCLSID[GUIDSTR_MAX];
  300.    TCHAR   achModulePathName[MAX_PATH];
  301.  
  302.    // If we fail in the middle, the state of the registry entries
  303.    // is indeterminate (as per Ole specs.)
  304.  
  305.  
  306.    // Create HKEY_CLASSES_ROOT\progid\CLSID
  307.    result = RegCreateKey(HKEY_CLASSES_ROOT, achPROGID, &hKey);
  308.    if (result != ERROR_SUCCESS) {
  309.       goto lExit;
  310.    }
  311.    result = RegSetValue(hKey, NULL, REG_SZ, achDESC, lstrlen(achDESC));
  312.    if (result != ERROR_SUCCESS) {
  313.       goto lExit;
  314.    }
  315.    result = RegCreateKey(hKey, TEXT("CLSID"), &hKey2);
  316.    if (result != ERROR_SUCCESS) {
  317.       goto lExit;
  318.    }
  319.    GUID2StringA(CLSID_CPlotter, achCLSID);
  320.    result = RegSetValue(hKey2, NULL, REG_SZ, achCLSID, GUIDSTR_MAX-1);
  321.    if (result != ERROR_SUCCESS) {
  322.       goto lExit;
  323.    }
  324.  
  325.    RegCloseKey(hKey);
  326.    RegCloseKey(hKey2);
  327.    hKey = NULL;
  328.    hKey2 = NULL;
  329.  
  330.  
  331.    // Create HKEY_CLASSES_ROOT\CLSID\...
  332.    result = RegCreateKey(HKEY_CLASSES_ROOT, TEXT("CLSID"), &hKey);
  333.    if (result != ERROR_SUCCESS) {
  334.       goto lExit;
  335.    }
  336.  
  337.    result = RegCreateKey(hKey, achCLSID, &hKey2);
  338.    if (result != ERROR_SUCCESS) {
  339.       goto lExit;
  340.    }
  341.  
  342.    result = RegSetValue(hKey2, NULL, REG_SZ, achDESC, lstrlen(achDESC));
  343.    if (result != ERROR_SUCCESS) {
  344.       goto lExit;
  345.    }
  346.  
  347.    result = RegCreateKey(hKey2, "InprocServer32", &hKey3);
  348.    if (result != ERROR_SUCCESS) {
  349.       goto lExit;
  350.    }
  351.  
  352.    result = GetModuleFileName(ghInstance, achModulePathName, sizeof(achModulePathName)/sizeof(TCHAR));
  353.    if (result == 0) {  //No way to detect truncation from GetModuleFileName. 
  354.       goto lExit;
  355.    }
  356.  
  357.    result = RegSetValue(hKey3, NULL, REG_SZ, achModulePathName, lstrlen(achModulePathName));
  358.    if (result != ERROR_SUCCESS) {
  359.       goto lExit;
  360.    }
  361.  
  362.    result = RegSetValueEx(hKey3, "ThreadingModel", 0, REG_SZ, (BYTE*)achTM, sizeof(achTM));
  363.    if (result != ERROR_SUCCESS) {
  364.       goto lExit;
  365.    }
  366.  
  367.    RegCloseKey(hKey3);
  368.    hKey3 = NULL;
  369.  
  370.  
  371.    result = RegCreateKey(hKey2, "ProgID", &hKey3);
  372.    if (result != ERROR_SUCCESS) {
  373.       goto lExit;
  374.    }
  375.    result = RegSetValue(hKey3, NULL, REG_SZ, achPROGID, lstrlen(achPROGID));
  376.    if (result != ERROR_SUCCESS) {
  377.       goto lExit;
  378.    }
  379.    RegCloseKey(hKey3);
  380.    hKey3 = NULL;
  381.  
  382.  
  383.  
  384.    hr = S_OK;
  385.  
  386.  lExit:
  387.    if (hKey) {
  388.       RegCloseKey(hKey);
  389.    }
  390.    if (hKey2) {
  391.       RegCloseKey(hKey2);
  392.    }
  393.    if (hKey3) {
  394.       RegCloseKey(hKey3);
  395.    }
  396.    return hr;
  397.  
  398. }
  399.  
  400.  
  401.  
  402. //===================================================================
  403. // Standard Ole export (for self-unregistration a la regsvr32.)
  404. //===================================================================
  405. __declspec(dllexport)
  406. STDAPI
  407. DllUnregisterServer(VOID)
  408. {
  409.     return S_OK;
  410. }
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.