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

  1. /*
  2.  * stub.cpp
  3.  *
  4.  * Sample code.
  5.  *  
  6.  * (C) Copyright 1995 - 1999 Microsoft Corporation.  All rights reserved.
  7.  */
  8.  
  9. #pragma hdrstop
  10.  
  11. #include "stub.h"
  12.  
  13. // Macros
  14.  
  15. #define WIN32_ERROR_TO_HRESULT(err)    MAKE_SCODE(SEVERITY_ERROR, FACILITY_WIN32, (err))
  16. #define WIN32_RESULT_TO_HRESULT(err)   ((err) == ERROR_SUCCESS ? S_OK : WIN32_ERROR_TO_HRESULT(err))
  17. #define LAST_WIN32_ERROR_TO_HRESULT()  WIN32_RESULT_TO_HRESULT(GetLastError())
  18.  
  19. // Resource IDs for the class resource data and the main class name data.
  20. // These are the IDs of the resources that jexegen will create when used
  21. // with the /bindto option.
  22.  
  23. #define CLASSRESOURCEID         1000
  24. #define MAINCLASSNAMERESOURCEID 1001
  25.  
  26. //------------------------------------------------------------------------------
  27. // CJView::CJView:
  28. //    Constructor
  29. //------------------------------------------------------------------------------
  30.  
  31. CJView::CJView (int ac, char **av) : m_ac (ac), m_av (av)
  32. {
  33.     m_pszClassName = NULL;
  34.     m_ppszArgs     = NULL;
  35.     m_iArgs        = 0;
  36.     m_pJE          = NULL;
  37. }
  38.  
  39. //------------------------------------------------------------------------------
  40. // CJView::~CJView:
  41. //    Destructor
  42. //------------------------------------------------------------------------------
  43.  
  44. CJView::~CJView ()
  45. {
  46.     if (m_ppszArgs)
  47.     {
  48.         INT n = 0;
  49.  
  50.         while (m_ppszArgs[n] != NULL)
  51.             delete [] m_ppszArgs[n++];
  52.         delete [] m_ppszArgs;
  53.     }
  54.  
  55.     if (m_pJE)
  56.     {
  57.         m_pJE->Release();
  58.         CoUninitialize();
  59.     }
  60. }
  61.  
  62. //------------------------------------------------------------------------------
  63. // CJView::m_FatalError:
  64. //
  65. // Print a formatted error message to stderr
  66. //
  67. // Returns: Nothing
  68. //------------------------------------------------------------------------------
  69.  
  70. void CJView::m_FatalError
  71. (
  72.     INT idString,
  73.     ...
  74. )
  75. {
  76.     CHAR szFmt[BUFSIZE];
  77.     va_list va;
  78.     va_start(va, idString);
  79.  
  80.     LoadString(NULL, IDS_ERROR, szFmt, sizeof(szFmt));
  81.     fprintf(stderr, szFmt);
  82.  
  83.     if (idString)
  84.         LoadString(NULL, idString, szFmt, sizeof(szFmt));
  85.     else
  86.         lstrcpy(szFmt, "%s");
  87.  
  88.     vfprintf(stderr, szFmt, va);
  89.     va_end(va);
  90.     fprintf(stderr, "\n");
  91. }
  92.  
  93. //------------------------------------------------------------------------------
  94. // CJView::m_FatalErrorHR:
  95. //
  96. //      Print a formatted error followup by an hresult tp stderr
  97. //------------------------------------------------------------------------------
  98.  
  99. void CJView::m_FatalErrorHR
  100. (
  101.     HRESULT hr,
  102.     INT     idString,
  103.     ...
  104. )
  105. {
  106.     CHAR  szFmt[BUFSIZE];
  107.     CHAR  buf[BUFSIZE];
  108.     DWORD res;
  109.     va_list va;
  110.     va_start(va, idString);
  111.  
  112.     LoadString(NULL, IDS_ERROR, szFmt, sizeof(szFmt));
  113.     fprintf(stderr, szFmt);
  114.     LoadString(NULL, idString, szFmt, sizeof(szFmt));
  115.     vfprintf(stderr, szFmt, va);
  116.     va_end(va);
  117.  
  118.     res = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  119.                         NULL,
  120.                         (DWORD)hr,
  121.                         LOCALE_SYSTEM_DEFAULT,
  122.                         buf,
  123.                         sizeof(buf),
  124.                         NULL);
  125.  
  126.     CHAR szNoMain[BUFSIZE] = "";
  127.  
  128.     if (!res)
  129.     {
  130.         CHAR szSCODE[BUFSIZE];
  131.  
  132.         LoadString(NULL, IDS_SCODE, szSCODE, sizeof(szSCODE));
  133.         sprintf(buf, szSCODE, (DWORD)hr);
  134.     }
  135.     else
  136.     {
  137.         // Now we check if the error is "Member not found", and if it is, we
  138.         // will append some additional info to the error message letting
  139.         // the user know it was main() that could not be found, since that
  140.         // is the only time this message should be generated.
  141.         
  142.         if (hr == DISP_E_MEMBERNOTFOUND)
  143.         {
  144.             CHAR sz[BUFSIZE] = "";
  145.  
  146.             LoadString(NULL, IDS_NOMAIN, sz, sizeof(sz));
  147.             sprintf(szNoMain, sz, m_pszClassName, m_pszClassName);
  148.         }
  149.         else
  150.             *szNoMain = '\0';
  151.     }
  152.  
  153.  
  154.     fprintf(stderr, ": %s\n", buf);
  155.     if (*szNoMain)
  156.         fprintf(stderr, "%s", szNoMain);
  157. }
  158.  
  159. //------------------------------------------------------------------------------
  160. // CJView::m_InitComAndJava:
  161. //
  162. // Initializes COM and obtains the neccessary interfaces from the Java VM
  163. //
  164. // Returns: TRUE if successful, FALSE if not
  165. //------------------------------------------------------------------------------
  166.  
  167. BOOL CJView::m_InitComAndJava ()
  168. {
  169.     HRESULT           hr   = E_UNEXPECTED;
  170.     IClassFactory    *pcf  = NULL;
  171.  
  172.     hr = CoInitialize(NULL);
  173.  
  174.     if (FAILED(hr))
  175.     {
  176.         m_FatalErrorHR(hr, IDS_COULDNOTINITOLE);
  177.     }
  178.     else
  179.     {
  180.         hr = CoGetClassObject(CLSID_JavaExecute,
  181.                               CLSCTX_INPROC_SERVER |
  182.                               CLSCTX_INPROC_HANDLER |
  183.                               CLSCTX_LOCAL_SERVER,
  184.                               NULL,
  185.                               IID_IClassFactory,
  186.                               (LPVOID*)(&pcf));
  187.         if (FAILED(hr))
  188.         {
  189.             m_FatalErrorHR(hr, IDS_JAVAVM);
  190.         }
  191.         else
  192.         {
  193.             hr = pcf->CreateInstance(NULL, IID_IJavaExecute2, (LPVOID *)(&m_pJE));
  194.             if (FAILED(hr))
  195.             {
  196.                 m_pJE = NULL;
  197.                 m_FatalErrorHR(hr, IDS_CLASSLOADER);
  198.             }
  199.  
  200.             pcf->Release();
  201.         }
  202.  
  203.         if (NULL == m_pJE)
  204.             CoUninitialize();
  205.     }
  206.  
  207.     return (m_pJE != NULL);
  208. }
  209.  
  210. //------------------------------------------------------------------------------
  211. // CJView::MB2WC:
  212. //
  213. //   Converts the multibyte string to a UNICODE string, allocating space
  214. // for the destination string.
  215. //
  216. // Returns: Pointer to newly allocated and converted string, NULL if it fails
  217. //------------------------------------------------------------------------------
  218.  
  219. LPWSTR CJView::m_MB2WC
  220. (
  221.     LPCSTR szAnsi,
  222.     int    cchAnsi
  223. )
  224. {
  225.    // First, determine size of converted string
  226.    LPWSTR pwsz    = NULL;
  227.    int    cchWide = MultiByteToWideChar(0, 0, szAnsi, cchAnsi, NULL, 0) + 1;
  228.  
  229.    if (cchWide > 0)
  230.    {
  231.        // Got size so allocate the space and convert the string
  232.        if (pwsz = new WCHAR[cchWide])
  233.           MultiByteToWideChar(0, 0, szAnsi, cchAnsi, pwsz, cchWide);
  234.     }
  235.  
  236.    return pwsz;
  237. }
  238.  
  239. //------------------------------------------------------------------------------
  240. // CJView::m_WC2MB:
  241. //
  242. //   Converts the given UNICODE string to a multibyte string, allocating space
  243. // for the destination string.
  244. //
  245. // Returns: Pointer to newly allocated and converted string, NULL if it fails
  246. //------------------------------------------------------------------------------
  247.  
  248. LPSTR CJView::m_WC2MB
  249. (
  250.    LPCWSTR pwsz,
  251.    int     cchWide
  252. )
  253. {
  254.    // First, determine size of converted string
  255.    LPSTR psz     = NULL;
  256.    int   cchAnsi = WideCharToMultiByte(0, 0, pwsz, cchWide, NULL, 0, NULL, NULL);
  257.  
  258.    if (cchAnsi > 0)
  259.    {
  260.        // Got size so allocate the space and convert the string
  261.       if (psz = new CHAR[cchAnsi])
  262.           WideCharToMultiByte(0, 0, pwsz, cchWide, psz, cchAnsi, NULL, NULL);
  263.     }
  264.  
  265.     return psz;
  266. }
  267.  
  268. //------------------------------------------------------------------------------
  269. // CJView::m_ParseParameters
  270. //
  271. // Parses off the command line arguments following the class simply
  272. // copying them into a list of OLESTRS
  273. //
  274. // Returns: TRUE if successful, FALSE if not
  275. //------------------------------------------------------------------------------
  276.  
  277. BOOL CJView::m_ParseParameters()
  278. {
  279.     m_iArgs = m_ac - 1;
  280.  
  281.     m_ppszArgs = new LPOLESTR[m_iArgs + 1];
  282.     if (!m_ppszArgs)
  283.     {
  284.         m_FatalError(IDS_OUTOFMEMORY);
  285.         return FALSE;
  286.     }
  287.  
  288.     (m_ppszArgs)[0] = NULL; // Initially empty!
  289.  
  290.     // Now, run through the list of arguments and process
  291.     int iNext = 1;
  292.     int i;
  293.  
  294.     for (i = 0; i < m_iArgs; i++)
  295.     {
  296.         if (!((m_ppszArgs)[i] = m_MB2WC(m_av[iNext++])))
  297.             break;
  298.     }
  299.  
  300.     // If succesful, mark end of array
  301.     if (i == m_iArgs)
  302.     {
  303.         (m_ppszArgs)[i] = NULL;
  304.     }
  305.     else
  306.     {
  307.         // Clean up if we fail
  308.         int n;
  309.  
  310.         for (n = 0; n < i; n++)
  311.             deleteSZ(m_ppszArgs[n]);
  312.         deleteSZ(m_ppszArgs);
  313.     }
  314.  
  315.     return (i == m_iArgs);
  316. }
  317.  
  318. //------------------------------------------------------------------------------
  319.  
  320. BOOL CJView::LoadDataResource( DWORD dwResID, BYTE *pBuffer, DWORD *pdwSize )
  321. {
  322.    HMODULE hMod = GetModuleHandle(NULL);
  323.    DWORD   dwBufferSize;
  324.    HRSRC   hRes;
  325.    HANDLE  hLoadedRes;
  326.    PVOID   pData;
  327.    
  328.    if ( !pdwSize || !pBuffer )
  329.       return FALSE;
  330.  
  331.    dwBufferSize = *pdwSize;
  332.    *pdwSize = 0;
  333.    
  334.    hRes = FindResource( hMod, MAKEINTRESOURCE(dwResID), RT_RCDATA );
  335.  
  336.    if ( hRes == NULL )
  337.       return FALSE;
  338.  
  339.    *pdwSize = SizeofResource( hMod, hRes );
  340.  
  341.    if ( dwBufferSize < *pdwSize )
  342.       return FALSE;
  343.  
  344.    hLoadedRes = LoadResource( hMod, hRes );
  345.  
  346.    if ( !hLoadedRes )
  347.       return FALSE;
  348.  
  349.    pData = LockResource( hLoadedRes );
  350.  
  351.    CopyMemory( pBuffer, pData, *pdwSize );
  352.  
  353.    FreeResource( hLoadedRes );
  354.    
  355.    return TRUE;
  356. }
  357.  
  358. //------------------------------------------------------------------------------
  359. // CJView::Initialize:
  360. //
  361. //  Performs initialization for CJView
  362. //
  363. // Returns: TRUE if successful, FALSE if not
  364. //------------------------------------------------------------------------------
  365.  
  366. BOOL CJView::Initialize ()
  367. {
  368.    // Load the name of the main class file to
  369.    // execute.
  370.    
  371.    char  szBuffer[1024];
  372.    DWORD dwSize = sizeof(szBuffer);
  373.  
  374.    if ( !LoadDataResource( MAINCLASSNAMERESOURCEID, (BYTE *)szBuffer, &dwSize ) )
  375.    {  
  376.       m_FatalError( IDS_NOCLASSGIVEN );
  377.       return FALSE;
  378.    }
  379.    
  380.    m_pszClassName = new char[ lstrlen(szBuffer) + 1];
  381.  
  382.    if ( !m_pszClassName )
  383.    {
  384.       m_FatalError( IDS_OUTOFMEMORY );
  385.       return FALSE;
  386.    }
  387.  
  388.    lstrcpy( m_pszClassName, szBuffer );
  389.  
  390.    return m_InitComAndJava();
  391. }
  392.  
  393. //------------------------------------------------------------------------------
  394. // RunMessageLoop:
  395. //      Message pump for OLE
  396. //------------------------------------------------------------------------------
  397.  
  398. UINT RunMessageLoop(void)
  399. {
  400.     MSG msg;
  401.  
  402.     // No accelerators to load.  Get and dispatch messages until a WM_QUIT
  403.     // message is received.
  404.     ZeroMemory(&msg, sizeof(msg));
  405.  
  406.     msg.wParam = S_OK;
  407.  
  408.     while (GetMessage(&msg, NULL, 0, 0))
  409.       //
  410.       // Dispatch message to target window.
  411.       //
  412.       // We don't have any windows, so there are no window procedures that
  413.       // require TranslateMessage(&msg).
  414.       //
  415.       DispatchMessage(&msg);
  416.  
  417.     return(msg.wParam);
  418. }
  419.  
  420. //------------------------------------------------------------------------------
  421. // CJView::ExecuteClass:
  422. //
  423. //  Executes the given class file
  424. //
  425. // Returns: 0 if successful, 1 if not
  426. //------------------------------------------------------------------------------
  427.  
  428. DWORD _stdcall RunClassThread
  429. (
  430.     PVOID pv
  431. )
  432. {
  433.     CJView* pJV     = (CJView*)pv;
  434.     HRESULT hr;
  435.     int     iResult;
  436.  
  437.     if ( SUCCEEDED(CoInitialize(NULL)) )
  438.     {
  439.         if ( pJV->m_ParseParameters() )
  440.         {
  441.             // Tell the VM that it should look in the current module for
  442.             // class files.  The /bindto option of the jexegen tool will
  443.             // place the resource data in the exe with a resource ID of
  444.             // 1001 so we tell the VM that is where the data is.
  445.  
  446.             JAVACLASSRESOURCEINFO jcri;
  447.             jcri.hModule      = GetModuleHandle(NULL);
  448.             jcri.dwResourceID = CLASSRESOURCEID;     // Compatible with jexegen.
  449.  
  450.             hr = pJV->m_pJE->SetClassSource( CLASS_SOURCE_TYPE_MODULERESOURCES,
  451.                                              &jcri,
  452.                                              sizeof(JAVACLASSRESOURCEINFO) );
  453.  
  454.             if ( !SUCCEEDED(hr) )
  455.             {
  456.                pJV->m_FatalError( IDS_VMCANTFINDRESOURCE );
  457.                return 0;
  458.             }
  459.  
  460.             // Execute.
  461.             LPOLESTR        pszClassName = pJV->m_MB2WC(pJV->m_pszClassName);
  462.             LPERRORINFO     pIErrorInfo = NULL;
  463.             JAVAEXECUTEINFO jei;
  464.  
  465.             jei.cbSize       = sizeof(jei);
  466.             jei.dwFlags      = 0;
  467.             jei.pszClassName = pszClassName;
  468.             jei.rgszArgs     = (LPCOLESTR *)(pJV->m_ppszArgs);
  469.             jei.cArgs        = pJV->m_iArgs;
  470.             jei.pszClassPath = NULL;
  471.  
  472.             hr = pJV->m_pJE->Execute(&jei, &pIErrorInfo);
  473.  
  474.             if (!SUCCEEDED(hr))
  475.             {
  476.                 // Most likely .class file did not exist
  477.                 pJV->m_FatalErrorHR (hr, IDS_EXECUTINGCLASS, pJV->m_pszClassName);
  478.                 iResult = 1;
  479.             }
  480.             else if (pIErrorInfo)
  481.             {
  482.                 // VM threw an exception while running the .class file.  We
  483.                 // get the info via the returned IErrorInfo interface
  484.                 BSTR bstrError = NULL;
  485.  
  486.                 if (SUCCEEDED(pIErrorInfo->GetDescription(&bstrError)))
  487.                 {
  488.                     LPSTR pszError = pJV->m_WC2MB(bstrError);
  489.  
  490.                     if (pszError)
  491.                     {
  492.                         pJV->m_FatalError (0, pszError);
  493.                         deleteSZ(pszError);
  494.                     }
  495.                     else
  496.                         pJV->m_FatalError (IDS_UNKNOWNERROR);
  497.  
  498.                     SysFreeString(bstrError);
  499.                 }
  500.                 else
  501.                     pJV->m_FatalError(IDS_UNKNOWNERROR);
  502.  
  503.                 iResult = 1;
  504.  
  505.                 pIErrorInfo->Release();
  506.             }
  507.             else
  508.                 // Success.
  509.                 iResult = 0;
  510.  
  511.             deleteSZ(pszClassName);
  512.         }
  513.         else
  514.             iResult = 1;
  515.  
  516.         CoUninitialize();
  517.     }
  518.     else
  519.         iResult = 1;
  520.  
  521.     // Terminate message pump
  522.     PostThreadMessage(pJV->m_dwMsgLoopThreadID, WM_QUIT, 0, 0);
  523.  
  524.     return (DWORD)iResult;
  525. }
  526.  
  527. //------------------------------------------------------------------------------
  528.  
  529. int __cdecl main
  530. (
  531.     int    ac,
  532.     char **av
  533. )
  534. {
  535.     int     iRet = 1;
  536.     CJView* pJV  = new CJView(ac, av);
  537.  
  538.     if ( !pJV )
  539.     {
  540.         CHAR szFmt[20];
  541.  
  542.         LoadString(NULL, IDS_ERROR, szFmt, sizeof(szFmt));
  543.         fprintf(stderr, szFmt);
  544.         LoadString(NULL, IDS_OUTOFMEMORY, szFmt, sizeof(szFmt));
  545.         fprintf(stderr, szFmt);
  546.         fprintf(stderr, "\n");
  547.         return iRet;
  548.     }
  549.  
  550.     if (pJV->Initialize())
  551.     {
  552.         // OK, we're ready, everything is done on the applet thread
  553.         HANDLE hth;
  554.         DWORD  dwThreadID;
  555.  
  556.         pJV->m_dwMsgLoopThreadID = GetCurrentThreadId();
  557.         hth = CreateThread(NULL, 0, &RunClassThread, pJV, 0, &dwThreadID);
  558.  
  559.         if (hth)
  560.         {
  561.             RunMessageLoop();
  562.  
  563.             // If we returned from RunMessageLoop() as a result of
  564.             // RunClassThread() posting the WM_QUIT message, then the thread
  565.             // will be exiting shortly (if not already).  We wait for it to
  566.             // terminate and grab its exit code.  1/2 second is plenty --
  567.             // if the thread doesn't die by then, something is wrong (we
  568.             // got a quit message from someone else, perhaps?) in which case
  569.             // we return 1 for failure.
  570.  
  571.             if (WaitForSingleObject (hth, 500) == WAIT_OBJECT_0)
  572.             {
  573.                 DWORD   dwRetCode = 1;
  574.  
  575.                 // Thread's dead, baby... thread's dead...
  576.                 GetExitCodeThread (hth, &dwRetCode);
  577.                 iRet = dwRetCode;
  578.             }
  579.             CloseHandle(hth);
  580.             hth = NULL;
  581.         }
  582.         else
  583.         {
  584.             pJV->m_FatalErrorHR(LAST_WIN32_ERROR_TO_HRESULT(),
  585.                                 IDS_NOJAVATHREAD);
  586.         }
  587.     }
  588.  
  589.     delete pJV;
  590.     return iRet;
  591. }
  592.  
  593.