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

  1. #define INITGUID 1
  2.  
  3. #include <windows.h>
  4. #include <olectl.h>
  5.  
  6. #include "comsamp.h"
  7.  
  8. TCHAR achSampleProgID[]        = "comntv";
  9. TCHAR achInprocServer32[]      = "InprocServer32";
  10. TCHAR achProgID[]              = "ProgID";
  11. TCHAR achThreadingModel[]      = "ThreadingModel";
  12. TCHAR achBoth[]                = "Both";
  13.  
  14.  
  15. DWORD g_ObjectCount = 0;
  16. HINSTANCE ghInstance = 0;
  17.  
  18.  
  19.  
  20. VOID ObjectCreated(VOID)
  21. {
  22.     InterlockedIncrement( (LONG*)&g_ObjectCount );
  23. }
  24.  
  25.  
  26.  
  27. VOID ObjectDestroyed(VOID)
  28. {
  29.     InterlockedDecrement( (LONG*)&g_ObjectCount );
  30. }
  31.  
  32.  
  33. HRESULT CheckJavaWriteAccess (BSTR pwszFilename)
  34. {
  35.     // If there is no vm in the process, then we could not have
  36.     // been called directly from java code, and remote calls are
  37.     // implicitly trusted.
  38.     if (GetModuleHandle("MSJAVA") == NULL)
  39.         return S_OK;
  40.  
  41.     HRESULT hr;
  42.  
  43.     IMyCOMObjectSecurity *psecurity;
  44.  
  45.     hr = CoCreateInstance(
  46.             CLSID_CMyCOMObjectSecurity,
  47.             NULL,
  48.             CLSCTX_ALL,
  49.             IID_IMyCOMObjectSecurity,
  50.             (PVOID*)&psecurity
  51.             );
  52.     if (SUCCEEDED(hr))
  53.     {
  54.         hr = psecurity->CheckRead(pwszFilename);
  55.         psecurity->Release();
  56.  
  57.         // The VM does not convert SecurityException to a useful HRESULT, so do it here.
  58.         if (hr == E_FAIL)
  59.             hr = HRESULT_FROM_WIN32(ERROR_PRIVILEGE_NOT_HELD);
  60.     }
  61.  
  62.     return hr;
  63. }
  64.  
  65.  
  66. class CMyCOMObject : public IMyInterface
  67. {
  68.     ULONG refcount;
  69.  
  70. public:
  71.  
  72.     CMyCOMObject ()
  73.     {
  74.         refcount = 1;
  75.     }
  76.     
  77.  
  78.     // IUnknown methods
  79.     
  80.     HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, LPVOID* ppv)
  81.     {
  82.         *ppv = NULL;
  83.         
  84.         if (riid == IID_IUnknown)
  85.         {
  86.             *ppv = (IUnknown*)this;
  87.         }
  88.         else if (riid == IID_IMyInterface)
  89.         {
  90.             *ppv = (IMyInterface*)this;
  91.         }
  92.         
  93.         if (*ppv)
  94.         {
  95.             ((IUnknown*)(*ppv))->AddRef();
  96.             return S_OK;
  97.         }
  98.         
  99.         return E_NOINTERFACE;
  100.     }
  101.  
  102.     ULONG STDMETHODCALLTYPE AddRef ()
  103.     {
  104.         InterlockedIncrement((LONG*)&refcount);
  105.         return 0xcccccccc;
  106.     }
  107.  
  108.     ULONG STDMETHODCALLTYPE Release ()
  109.     {
  110.         if (!InterlockedDecrement((LONG*)&refcount))
  111.         {
  112.             delete this;
  113.             return 0;
  114.         }
  115.         
  116.         return 0xcccccccc;
  117.     }
  118.  
  119.  
  120.     // IMyInterface methods
  121.  
  122.     HRESULT STDMETHODCALLTYPE COMCheckedLoad (BSTR pwszFilename, BYTE buffer[], int *bufsize)
  123.     {
  124.         HRESULT hr = CheckJavaWriteAccess(pwszFilename);
  125.         if (SUCCEEDED(hr))
  126.         {
  127.             hr = JavaCheckedLoad(pwszFilename, buffer, bufsize);
  128.         }
  129.         
  130.         return hr;
  131.     }
  132.     
  133.     HRESULT STDMETHODCALLTYPE JavaCheckedLoad (BSTR pwszFilename, BYTE buffer[], int *bufsize)
  134.     {
  135.         if (pwszFilename == NULL || buffer == NULL || bufsize == NULL)
  136.             return E_POINTER;
  137.  
  138.         if (*bufsize < 0)
  139.             return E_INVALIDARG;
  140.  
  141.         HRESULT hr = E_FAIL;
  142.  
  143.         CHAR filename[MAX_PATH];
  144.         int filenamelen = WideCharToMultiByte(
  145.                 CP_ACP,
  146.                 0,
  147.                 pwszFilename,
  148.                 -1,
  149.                 filename,
  150.                 sizeof(filename)-1,
  151.                 NULL,
  152.                 NULL);
  153.         if (filenamelen != 0)
  154.         {
  155.             filename[filenamelen] = '\0';
  156.  
  157.             HANDLE file = CreateFile(
  158.                     filename,
  159.                     GENERIC_READ,
  160.                     FILE_SHARE_READ,
  161.                     NULL,
  162.                     OPEN_EXISTING,
  163.                     FILE_FLAG_SEQUENTIAL_SCAN,
  164.                     NULL
  165.                     );
  166.             if (file != INVALID_HANDLE_VALUE)
  167.             {
  168.                 DWORD size = GetFileSize(file, NULL);
  169.                 if (size != 0xffffffff)
  170.                 {
  171.                     DWORD toread = size;
  172.                     if (toread > *bufsize)
  173.                         toread = *bufsize;
  174.  
  175.                     DWORD read;
  176.                     if (ReadFile(
  177.                             file,
  178.                             buffer,
  179.                             toread,
  180.                             &read,
  181.                             NULL
  182.                             )
  183.                           && read == size
  184.                           )
  185.                     {
  186.                         *bufsize = read;
  187.                         hr = S_OK;
  188.                     }
  189.                 }
  190.  
  191.                 CloseHandle(file);
  192.             }
  193.         }
  194.  
  195.         if (hr == E_FAIL)
  196.             hr = HRESULT_FROM_WIN32(GetLastError());
  197.  
  198.         return hr;
  199.     }
  200. };
  201.  
  202.  
  203.  
  204. class CMyComObjectClassFactory : public IClassFactory
  205. {
  206. public:
  207.  
  208.     CMyComObjectClassFactory ()
  209.     {
  210.         ObjectCreated();
  211.     }
  212.  
  213.     ~CMyComObjectClassFactory ()
  214.     {
  215.         ObjectDestroyed();
  216.     }
  217.     
  218.  
  219.     // IUnknown methods
  220.     
  221.     HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppv)
  222.     {
  223.         *ppv = NULL;
  224.         if (riid == IID_IUnknown)
  225.         {
  226.             *ppv = (IUnknown*)this;
  227.         }
  228.         else if (riid == IID_IClassFactory)
  229.         {
  230.             *ppv = (IClassFactory*)this;
  231.         }
  232.         if (*ppv)
  233.         {
  234.             ((IUnknown*)(*ppv))->AddRef();
  235.             return S_OK;
  236.         }
  237.         return E_NOINTERFACE;
  238.  
  239.     }
  240.  
  241.     ULONG STDMETHODCALLTYPE AddRef ()
  242.     {
  243.         return 0xcccccccc;
  244.     }
  245.  
  246.     ULONG STDMETHODCALLTYPE Release ()
  247.     {
  248.         return 0xcccccccc;
  249.     }
  250.  
  251.  
  252.     // IClassFactory methods
  253.     
  254.     HRESULT STDMETHODCALLTYPE CreateInstance (IUnknown *punkOuter, REFIID riid, VOID **ppv)
  255.     {
  256.         HRESULT hr;
  257.         *ppv = NULL;
  258.         
  259.         if (punkOuter)
  260.         {
  261.             return CLASS_E_NOAGGREGATION;
  262.         }
  263.         
  264.         CMyCOMObject *obj = new CMyCOMObject();
  265.         if (obj == NULL)
  266.         {
  267.             return E_OUTOFMEMORY;
  268.         }
  269.         
  270.         hr = obj->QueryInterface(riid, ppv);
  271.         obj->Release();
  272.         return hr;
  273.     }
  274.  
  275.     HRESULT STDMETHODCALLTYPE LockServer (BOOL fLock)
  276.     {
  277.         if (fLock)
  278.             ObjectCreated();
  279.         else
  280.             ObjectDestroyed();
  281.         return S_OK;
  282.     }
  283. };
  284.  
  285.  
  286. CMyComObjectClassFactory g_CMyCOMObjectFactory;
  287.  
  288.  
  289. extern "C"
  290. BOOL WINAPI DllMain (HINSTANCE hmod, DWORD dwReason, PVOID pvReserved)
  291. {
  292.     ghInstance = hmod;
  293.     return TRUE;
  294. }
  295.  
  296.  
  297. STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID *ppv)
  298. {
  299.     *ppv = NULL;
  300.     if (rclsid == CLSID_CMyCOMObject)
  301.     {
  302.         return g_CMyCOMObjectFactory.QueryInterface(riid, ppv);
  303.     }
  304.     else
  305.     {
  306.         return CLASS_E_CLASSNOTAVAILABLE;
  307.     }
  308. }
  309.  
  310.  
  311. STDAPI DllCanUnloadNow ()
  312. {
  313.     return g_ObjectCount;
  314. }
  315.  
  316.  
  317.  
  318.  
  319. // Plagiarized from comsamp.
  320.  
  321.  
  322.  
  323.  
  324. #define GUIDSTR_MAX (1+ 8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1 + 1)
  325.  
  326. static const CHAR szDigits[] = "0123456789ABCDEF";
  327. static const BYTE GuidMap[] = { 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
  328.                                 8, 9, '-', 10, 11, 12, 13, 14, 15 };
  329.  
  330.  
  331. //--------------------------------------------------------------------------
  332. //
  333. //  Function:   GUID2StringA
  334. //
  335. //  Synopsis:   Convert GUID to string form
  336. //
  337. //  Arguments:  [rguid] - the guid to convert
  338. //              [lpszy] - buffer to hold the results
  339. //
  340. //  Returns:    nothing
  341. //
  342. //  This code is massively plagiarized from the Ole sources.
  343. //--------------------------------------------------------------------------
  344.  
  345. VOID
  346. GUID2StringA(REFGUID rguid, LPSTR lpsz)
  347. {
  348.     int i;
  349.     LPSTR p = lpsz;
  350.  
  351.     const BYTE * pBytes = (const BYTE *) &rguid;
  352.  
  353.     *p++ = '{';
  354.  
  355.     for (i = 0; i < sizeof(GuidMap); i++)
  356.     {
  357.         if (GuidMap[i] == '-')
  358.         {
  359.             *p++ = '-';
  360.         }
  361.         else
  362.         {
  363.             *p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
  364.             *p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
  365.         }
  366.     }
  367.     *p++ = '}';
  368.     *p   = '\0';
  369. }
  370.  
  371.  
  372.  
  373.  
  374. //--------------------------------------------------------------------------
  375. //
  376. //  NTCompatibleRegDeleteKey
  377. //
  378. //--------------------------------------------------------------------------
  379. LONG
  380. NTCompatibleRegDeleteKey(HKEY hKey, LPCTSTR szSubKey)
  381. {
  382.    TCHAR achName[MAX_PATH+1];
  383.    HKEY  hSubkey;
  384.  
  385.    if (ERROR_SUCCESS != RegOpenKey(hKey, szSubKey, &hSubkey)) {
  386.       return REGDB_E_INVALIDVALUE;
  387.    }
  388.  
  389.    if (ERROR_SUCCESS == RegEnumKey(hSubkey, 0, achName, sizeof(achName)/sizeof(TCHAR))) {
  390.       RegCloseKey(hSubkey);
  391.       // There's still one subkey: fail the call.
  392.       return REGDB_E_INVALIDVALUE;
  393.    }
  394.    RegCloseKey(hSubkey);
  395.    return RegDeleteKey(hKey, szSubKey);
  396. }
  397.  
  398.  
  399.  
  400. STDAPI DllRegisterServer ()
  401. {
  402.    HKEY    hKey  = NULL;
  403.    HKEY    hKey2 = NULL;
  404.    HKEY    hKey3 = NULL;
  405.    DWORD   result;
  406.    HRESULT hr = SELFREG_E_CLASS;
  407.    CHAR    achCLSID[GUIDSTR_MAX];
  408.    TCHAR   achModulePathName[MAX_PATH];
  409.  
  410.    // If we fail in the middle, the state of the registry entries
  411.    // is indeterminate (as per Ole specs.)
  412.  
  413.  
  414.    // Create HKEY_CLASSES_ROOT\progid\CLSID
  415.    result = RegCreateKey(HKEY_CLASSES_ROOT, achSampleProgID, &hKey);
  416.    if (result != ERROR_SUCCESS) {
  417.       goto lExit;
  418.    }
  419.    result = RegCreateKey(hKey, TEXT("CLSID"), &hKey2);
  420.    if (result != ERROR_SUCCESS) {
  421.       goto lExit;
  422.    }
  423.    GUID2StringA(CLSID_CMyCOMObject, achCLSID);
  424.    result = RegSetValue(hKey2, NULL, REG_SZ, achCLSID, GUIDSTR_MAX-1);
  425.    if (result != ERROR_SUCCESS) {
  426.       goto lExit;
  427.    }
  428.  
  429.    RegCloseKey(hKey);
  430.    RegCloseKey(hKey2);
  431.    hKey = NULL;
  432.    hKey2 = NULL;
  433.  
  434.  
  435.    // Create HKEY_CLASSES_ROOT\CLSID\...
  436.    result = RegCreateKey(HKEY_CLASSES_ROOT, TEXT("CLSID"), &hKey);
  437.    if (result != ERROR_SUCCESS) {
  438.       goto lExit;
  439.    }
  440.  
  441.    result = RegCreateKey(hKey, achCLSID, &hKey2);
  442.    if (result != ERROR_SUCCESS) {
  443.       goto lExit;
  444.    }
  445.  
  446.    result = RegCreateKey(hKey2, achInprocServer32, &hKey3);
  447.    if (result != ERROR_SUCCESS) {
  448.       goto lExit;
  449.    }
  450.  
  451.    result = GetModuleFileName(ghInstance, achModulePathName, sizeof(achModulePathName)/sizeof(TCHAR));
  452.    if (result == 0) {  //No way to detect truncation from GetModuleFileName. 
  453.       goto lExit;
  454.    }
  455.  
  456.    result = RegSetValue(hKey3, NULL, REG_SZ, achModulePathName, lstrlen(achModulePathName));
  457.    if (result != ERROR_SUCCESS) {
  458.       goto lExit;
  459.    }
  460.  
  461.    result = RegSetValueEx(hKey3, achThreadingModel, 0, REG_SZ, (BYTE*)achBoth, sizeof(achBoth));
  462.    if (result != ERROR_SUCCESS) {
  463.       goto lExit;
  464.    }
  465.  
  466.    RegCloseKey(hKey3);
  467.    hKey3 = NULL;
  468.  
  469.  
  470.    result = RegCreateKey(hKey2, achProgID, &hKey3);
  471.    if (result != ERROR_SUCCESS) {
  472.       goto lExit;
  473.    }
  474.    result = RegSetValue(hKey3, NULL, REG_SZ, achSampleProgID, lstrlen(achSampleProgID));
  475.    if (result != ERROR_SUCCESS) {
  476.       goto lExit;
  477.    }
  478.    RegCloseKey(hKey3);
  479.    hKey3 = NULL;
  480.  
  481.  
  482.  
  483.    hr = S_OK;
  484.  
  485.  lExit:
  486.    if (hKey) {
  487.       RegCloseKey(hKey);
  488.    }
  489.    if (hKey2) {
  490.       RegCloseKey(hKey2);
  491.    }
  492.    if (hKey3) {
  493.       RegCloseKey(hKey3);
  494.    }
  495.    return hr;
  496.  
  497. }
  498.  
  499.  
  500.  
  501. //----------------------------------------------------------------------
  502. // DllUnregisterServer(): Called by OLE.
  503. //----------------------------------------------------------------------
  504. STDAPI DllUnregisterServer(VOID)
  505. {
  506.    HKEY    hKey  = NULL;
  507.    HKEY    hKey2 = NULL;
  508.    DWORD   result;
  509.    HRESULT hr = SELFREG_E_CLASS;
  510.    CHAR    achCLSID[GUIDSTR_MAX];
  511.  
  512.    // If we fail in the middle, the state of the registry entries
  513.    // is indeterminate (as per Ole specs.)
  514.    GUID2StringA(CLSID_CMyCOMObject, achCLSID);
  515.  
  516.  
  517.    result = RegOpenKey(HKEY_CLASSES_ROOT, achSampleProgID, &hKey);
  518.    if (result == ERROR_SUCCESS) {
  519.       NTCompatibleRegDeleteKey(hKey, TEXT("CLSID"));
  520.       RegCloseKey(hKey);
  521.       hKey = NULL;
  522.       NTCompatibleRegDeleteKey(HKEY_CLASSES_ROOT, achSampleProgID);
  523.    }
  524.    // If this fails, it means somebody else added a subkey to this tree.
  525.    // We're not allowed to touch it so ignore the failure.
  526.  
  527.  
  528.    result = RegOpenKey(HKEY_CLASSES_ROOT, TEXT("CLSID"), &hKey);
  529.    if (result == ERROR_SUCCESS) {
  530.  
  531.       result = RegOpenKey(hKey, achCLSID, &hKey2);
  532.       if (result == ERROR_SUCCESS) {
  533.          NTCompatibleRegDeleteKey(hKey2, achInprocServer32);
  534.          NTCompatibleRegDeleteKey(hKey2, achProgID);
  535.          RegCloseKey(hKey2);
  536.          hKey2 = NULL;
  537.          NTCompatibleRegDeleteKey(hKey, achCLSID);
  538.       }
  539.  
  540.       // If this fails, it means somebody else added a subkey to this tree.
  541.       // We're not allowed to touch it so ignore the failure.
  542.  
  543.       RegCloseKey(hKey);
  544.       hKey = NULL;
  545.    }
  546.  
  547.  
  548.    hr = S_OK;
  549.  
  550.    return hr;
  551.  
  552. }
  553.  
  554.