home *** CD-ROM | disk | FTP | other *** search
- /*
- * stub.cpp
- *
- * Sample code.
- *
- * (C) Copyright 1996, Microsoft Corporation and it suppliers.
- */
-
- #pragma hdrstop
-
- #include "stub.h"
-
- // Macros
-
- #define WIN32_ERROR_TO_HRESULT(err) MAKE_SCODE(SEVERITY_ERROR, FACILITY_WIN32, (err))
- #define WIN32_RESULT_TO_HRESULT(err) ((err) == ERROR_SUCCESS ? S_OK : WIN32_ERROR_TO_HRESULT(err))
- #define LAST_WIN32_ERROR_TO_HRESULT() WIN32_RESULT_TO_HRESULT(GetLastError())
-
- // Resource IDs for the class resource data and the main class name data.
- // These are the IDs of the resources that jexegen will create when used
- // with the /bindto option.
-
- #define CLASSRESOURCEID 1000
- #define MAINCLASSNAMERESOURCEID 1001
-
- //------------------------------------------------------------------------------
- // CJView::CJView:
- // Constructor
- //------------------------------------------------------------------------------
-
- CJView::CJView (int ac, char **av) : m_ac (ac), m_av (av)
- {
- m_pszClassName = NULL;
- m_ppszArgs = NULL;
- m_iArgs = 0;
- m_pJE = NULL;
- }
-
- //------------------------------------------------------------------------------
- // CJView::~CJView:
- // Destructor
- //------------------------------------------------------------------------------
-
- CJView::~CJView ()
- {
- if (m_ppszArgs)
- {
- INT n = 0;
-
- while (m_ppszArgs[n] != NULL)
- delete [] m_ppszArgs[n++];
- delete [] m_ppszArgs;
- }
-
- if (m_pJE)
- {
- m_pJE->Release();
- CoUninitialize();
- }
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_FatalError:
- //
- // Print a formatted error message to stderr
- //
- // Returns: Nothing
- //------------------------------------------------------------------------------
-
- void CJView::m_FatalError
- (
- INT idString,
- ...
- )
- {
- CHAR szFmt[BUFSIZE];
- va_list va;
- va_start(va, idString);
-
- LoadString(NULL, IDS_ERROR, szFmt, sizeof(szFmt));
- fprintf(stderr, szFmt);
-
- if (idString)
- LoadString(NULL, idString, szFmt, sizeof(szFmt));
- else
- lstrcpy(szFmt, "%s");
-
- vfprintf(stderr, szFmt, va);
- va_end(va);
- fprintf(stderr, "\n");
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_FatalErrorHR:
- //
- // Print a formatted error followup by an hresult tp stderr
- //------------------------------------------------------------------------------
-
- void CJView::m_FatalErrorHR
- (
- HRESULT hr,
- INT idString,
- ...
- )
- {
- CHAR szFmt[BUFSIZE];
- CHAR buf[BUFSIZE];
- DWORD res;
- va_list va;
- va_start(va, idString);
-
- LoadString(NULL, IDS_ERROR, szFmt, sizeof(szFmt));
- fprintf(stderr, szFmt);
- LoadString(NULL, idString, szFmt, sizeof(szFmt));
- vfprintf(stderr, szFmt, va);
- va_end(va);
-
- res = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- (DWORD)hr,
- LOCALE_SYSTEM_DEFAULT,
- buf,
- sizeof(buf),
- NULL);
-
- CHAR szNoMain[BUFSIZE] = "";
-
- if (!res)
- {
- CHAR szSCODE[BUFSIZE];
-
- LoadString(NULL, IDS_SCODE, szSCODE, sizeof(szSCODE));
- sprintf(buf, szSCODE, (DWORD)hr);
- }
- else
- {
- // Now we check if the error is "Member not found", and if it is, we
- // will append some additional info to the error message letting
- // the user know it was main() that could not be found, since that
- // is the only time this message should be generated.
-
- if (hr == DISP_E_MEMBERNOTFOUND)
- {
- CHAR sz[BUFSIZE] = "";
-
- LoadString(NULL, IDS_NOMAIN, sz, sizeof(sz));
- sprintf(szNoMain, sz, m_pszClassName, m_pszClassName);
- }
- else
- *szNoMain = '\0';
- }
-
-
- fprintf(stderr, ": %s\n", buf);
- if (*szNoMain)
- fprintf(stderr, "%s", szNoMain);
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_InitComAndJava:
- //
- // Initializes COM and obtains the neccessary interfaces from the Java VM
- //
- // Returns: TRUE if successful, FALSE if not
- //------------------------------------------------------------------------------
-
- BOOL CJView::m_InitComAndJava ()
- {
- HRESULT hr = E_UNEXPECTED;
- IClassFactory *pcf = NULL;
-
- hr = CoInitialize(NULL);
-
- if (FAILED(hr))
- {
- m_FatalErrorHR(hr, IDS_COULDNOTINITOLE);
- }
- else
- {
- hr = CoGetClassObject(CLSID_JavaExecute,
- CLSCTX_INPROC_SERVER |
- CLSCTX_INPROC_HANDLER |
- CLSCTX_LOCAL_SERVER,
- NULL,
- IID_IClassFactory,
- (LPVOID*)(&pcf));
- if (FAILED(hr))
- {
- m_FatalErrorHR(hr, IDS_JAVAVM);
- }
- else
- {
- hr = pcf->CreateInstance(NULL, IID_IJavaExecute2, (LPVOID *)(&m_pJE));
- if (FAILED(hr))
- {
- m_pJE = NULL;
- m_FatalErrorHR(hr, IDS_CLASSLOADER);
- }
-
- pcf->Release();
- }
-
- if (NULL == m_pJE)
- CoUninitialize();
- }
-
- return (m_pJE != NULL);
- }
-
- //------------------------------------------------------------------------------
- // CJView::MB2WC:
- //
- // Converts the multibyte string to a UNICODE string, allocating space
- // for the destination string.
- //
- // Returns: Pointer to newly allocated and converted string, NULL if it fails
- //------------------------------------------------------------------------------
-
- LPWSTR CJView::m_MB2WC
- (
- LPCSTR szAnsi,
- int cchAnsi
- )
- {
- // First, determine size of converted string
- LPWSTR pwsz = NULL;
- int cchWide = MultiByteToWideChar(0, 0, szAnsi, cchAnsi, NULL, 0) + 1;
-
- if (cchWide > 0)
- {
- // Got size so allocate the space and convert the string
- if (pwsz = new WCHAR[cchWide])
- MultiByteToWideChar(0, 0, szAnsi, cchAnsi, pwsz, cchWide);
- }
-
- return pwsz;
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_WC2MB:
- //
- // Converts the given UNICODE string to a multibyte string, allocating space
- // for the destination string.
- //
- // Returns: Pointer to newly allocated and converted string, NULL if it fails
- //------------------------------------------------------------------------------
-
- LPSTR CJView::m_WC2MB
- (
- LPCWSTR pwsz,
- int cchWide
- )
- {
- // First, determine size of converted string
- LPSTR psz = NULL;
- int cchAnsi = WideCharToMultiByte(0, 0, pwsz, cchWide, NULL, 0, NULL, NULL);
-
- if (cchAnsi > 0)
- {
- // Got size so allocate the space and convert the string
- if (psz = new CHAR[cchAnsi])
- WideCharToMultiByte(0, 0, pwsz, cchWide, psz, cchAnsi, NULL, NULL);
- }
-
- return psz;
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_ParseParameters
- //
- // Parses off the command line arguments following the class simply
- // copying them into a list of OLESTRS
- //
- // Returns: TRUE if successful, FALSE if not
- //------------------------------------------------------------------------------
-
- BOOL CJView::m_ParseParameters()
- {
- m_iArgs = m_ac - 1;
-
- m_ppszArgs = new LPOLESTR[m_iArgs + 1];
- if (!m_ppszArgs)
- {
- m_FatalError(IDS_OUTOFMEMORY);
- return FALSE;
- }
-
- (m_ppszArgs)[0] = NULL; // Initially empty!
-
- // Now, run through the list of arguments and process
- int iNext = 1;
- int i;
-
- for (i = 0; i < m_iArgs; i++)
- {
- if (!((m_ppszArgs)[i] = m_MB2WC(m_av[iNext++])))
- break;
- }
-
- // If succesful, mark end of array
- if (i == m_iArgs)
- {
- (m_ppszArgs)[i] = NULL;
- }
- else
- {
- // Clean up if we fail
- int n;
-
- for (n = 0; n < i; n++)
- deleteSZ(m_ppszArgs[n]);
- deleteSZ(m_ppszArgs);
- }
-
- return (i == m_iArgs);
- }
-
- //------------------------------------------------------------------------------
-
- BOOL CJView::LoadDataResource( DWORD dwResID, BYTE *pBuffer, DWORD *pdwSize )
- {
- HMODULE hMod = GetModuleHandle(NULL);
- DWORD dwBufferSize;
- HRSRC hRes;
- HANDLE hLoadedRes;
- PVOID pData;
-
- if ( !pdwSize || !pBuffer )
- return FALSE;
-
- dwBufferSize = *pdwSize;
- *pdwSize = 0;
-
- hRes = FindResource( hMod, MAKEINTRESOURCE(dwResID), RT_RCDATA );
-
- if ( hRes == NULL )
- return FALSE;
-
- *pdwSize = SizeofResource( hMod, hRes );
-
- if ( dwBufferSize < *pdwSize )
- return FALSE;
-
- hLoadedRes = LoadResource( hMod, hRes );
-
- if ( !hLoadedRes )
- return FALSE;
-
- pData = LockResource( hLoadedRes );
-
- CopyMemory( pBuffer, pData, *pdwSize );
-
- FreeResource( hLoadedRes );
-
- return TRUE;
- }
-
- //------------------------------------------------------------------------------
- // CJView::Initialize:
- //
- // Performs initialization for CJView
- //
- // Returns: TRUE if successful, FALSE if not
- //------------------------------------------------------------------------------
-
- BOOL CJView::Initialize ()
- {
- // Load the name of the main class file to
- // execute.
-
- char szBuffer[1024];
- DWORD dwSize = sizeof(szBuffer);
-
- if ( !LoadDataResource( MAINCLASSNAMERESOURCEID, (BYTE *)szBuffer, &dwSize ) )
- {
- m_FatalError( IDS_NOCLASSGIVEN );
- return FALSE;
- }
-
- m_pszClassName = new char[ lstrlen(szBuffer) + 1];
-
- if ( !m_pszClassName )
- {
- m_FatalError( IDS_OUTOFMEMORY );
- return FALSE;
- }
-
- lstrcpy( m_pszClassName, szBuffer );
-
- return m_InitComAndJava();
- }
-
- //------------------------------------------------------------------------------
- // RunMessageLoop:
- // Message pump for OLE
- //------------------------------------------------------------------------------
-
- UINT RunMessageLoop(void)
- {
- MSG msg;
-
- // No accelerators to load. Get and dispatch messages until a WM_QUIT
- // message is received.
- ZeroMemory(&msg, sizeof(msg));
-
- msg.wParam = S_OK;
-
- while (GetMessage(&msg, NULL, 0, 0))
- //
- // Dispatch message to target window.
- //
- // We don't have any windows, so there are no window procedures that
- // require TranslateMessage(&msg).
- //
- DispatchMessage(&msg);
-
- return(msg.wParam);
- }
-
- //------------------------------------------------------------------------------
- // CJView::ExecuteClass:
- //
- // Executes the given class file
- //
- // Returns: 0 if successful, 1 if not
- //------------------------------------------------------------------------------
-
- DWORD _stdcall RunClassThread
- (
- PVOID pv
- )
- {
- CJView* pJV = (CJView*)pv;
- HRESULT hr;
- int iResult;
-
- if ( pJV->m_ParseParameters() )
- {
- // Tell the VM that it should look in the current module for
- // class files. The /bindto option of the jexegen tool will
- // place the resource data in the exe with a resource ID of
- // 1001 so we tell the VM that is where the data is.
-
- JAVACLASSRESOURCEINFO jcri;
- jcri.hModule = GetModuleHandle(NULL);
- jcri.dwResourceID = CLASSRESOURCEID; // Compatible with jexegen.
-
- hr = pJV->m_pJE->SetClassSource( CLASS_SOURCE_TYPE_MODULERESOURCES,
- &jcri,
- sizeof(JAVACLASSRESOURCEINFO) );
-
- if ( !SUCCEEDED(hr) )
- {
- pJV->m_FatalError( IDS_VMCANTFINDRESOURCE );
- return 0;
- }
-
- // Execute.
- LPOLESTR pszClassName = pJV->m_MB2WC(pJV->m_pszClassName);
- LPERRORINFO pIErrorInfo = NULL;
- JAVAEXECUTEINFO jei;
-
- jei.cbSize = sizeof(jei);
- jei.dwFlags = 0;
- jei.pszClassName = pszClassName;
- jei.rgszArgs = (LPCOLESTR *)(pJV->m_ppszArgs);
- jei.cArgs = pJV->m_iArgs;
- jei.pszClassPath = NULL;
-
- hr = pJV->m_pJE->Execute(&jei, &pIErrorInfo);
-
- if (!SUCCEEDED(hr))
- {
- // Most likely .class file did not exist
- pJV->m_FatalErrorHR (hr, IDS_EXECUTINGCLASS, pJV->m_pszClassName);
- iResult = 1;
- }
- else if (pIErrorInfo)
- {
- // VM threw an exception while running the .class file. We
- // get the info via the returned IErrorInfo interface
- BSTR bstrError = NULL;
-
- if (SUCCEEDED(pIErrorInfo->GetDescription(&bstrError)))
- {
- LPSTR pszError = pJV->m_WC2MB(bstrError);
-
- if (pszError)
- {
- pJV->m_FatalError (0, pszError);
- deleteSZ(pszError);
- }
- else
- pJV->m_FatalError (IDS_UNKNOWNERROR);
-
- SysFreeString(bstrError);
- }
- else
- pJV->m_FatalError(IDS_UNKNOWNERROR);
-
- iResult = 1;
-
- pIErrorInfo->Release();
- }
- else
- // Success.
- iResult = 0;
-
- deleteSZ(pszClassName);
- }
- else
- iResult = 1;
-
- // Terminate message pump
- PostThreadMessage(pJV->m_dwMsgLoopThreadID, WM_QUIT, 0, 0);
-
- return (DWORD)iResult;
- }
-
- //------------------------------------------------------------------------------
-
- int __cdecl main
- (
- int ac,
- char **av
- )
- {
- int iRet = 1;
- CJView* pJV = new CJView(ac, av);
-
- if ( !pJV )
- {
- CHAR szFmt[20];
-
- LoadString(NULL, IDS_ERROR, szFmt, sizeof(szFmt));
- fprintf(stderr, szFmt);
- LoadString(NULL, IDS_OUTOFMEMORY, szFmt, sizeof(szFmt));
- fprintf(stderr, szFmt);
- fprintf(stderr, "\n");
- return iRet;
- }
-
- if (pJV->Initialize())
- {
- // OK, we're ready, everything is done on the applet thread
- HANDLE hth;
- DWORD dwThreadID;
-
- pJV->m_dwMsgLoopThreadID = GetCurrentThreadId();
- hth = CreateThread(NULL, 0, &RunClassThread, pJV, 0, &dwThreadID);
-
- if (hth)
- {
- RunMessageLoop();
-
- // If we returned from RunMessageLoop() as a result of
- // RunClassThread() posting the WM_QUIT message, then the thread
- // will be exiting shortly (if not already). We wait for it to
- // terminate and grab its exit code. 1/2 second is plenty --
- // if the thread doesn't die by then, something is wrong (we
- // got a quit message from someone else, perhaps?) in which case
- // we return 1 for failure.
-
- if (WaitForSingleObject (hth, 500) == WAIT_OBJECT_0)
- {
- DWORD dwRetCode = 1;
-
- // Thread's dead, baby... thread's dead...
- GetExitCodeThread (hth, &dwRetCode);
- iRet = dwRetCode;
- }
- CloseHandle(hth);
- hth = NULL;
- }
- else
- {
- pJV->m_FatalErrorHR(LAST_WIN32_ERROR_TO_HRESULT(),
- IDS_NOJAVATHREAD);
- }
- }
-
- delete pJV;
- return iRet;
- }
-
-