home *** CD-ROM | disk | FTP | other *** search
- /*
- * jview.cpp - JView front end, including command-line parsing logic.
- *
- * (C) Copyright 1996, Microsoft Corporation and it suppliers.
- */
-
- #pragma hdrstop
-
- #include "jview.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())
-
- #define APPLETVIEWER "sun.applet.AppletViewer"
-
- //------------------------------------------------------------------------------
- // CJView::CJView:
- // Constructor
- //------------------------------------------------------------------------------
- CJView::CJView (int ac, char **av) : m_ac (ac), m_av (av)
- {
- m_fQuiet = FALSE;
- m_fApplet = FALSE;
- m_fPause = FALSE;
- m_pszClassPath = NULL;
- m_pszAppend = NULL;
- m_pszPrepend = NULL;
- m_pszClassName = NULL;
- m_ppszArgs = NULL;
- m_iArgs = 0;
- m_pJE = NULL;
- }
-
- //------------------------------------------------------------------------------
- // CJView::~CJView:
- // Destructor
- //------------------------------------------------------------------------------
- CJView::~CJView ()
- {
- deleteSZ(m_pszClassPath);
- deleteSZ(m_pszClassName);
- deleteSZ(m_pszAppend);
- deleteSZ(m_pszPrepend);
-
- 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_Pause:
- //
- // -p was given on the command line, and we have an error, thus we display
- // amessage to the user to press a key to terminate JView, thus allowing enough
- // time to read the message before JView termnates and the console it was
- // running in goes away if being executed from the IDE
- //
- // Returns: Nothing
- //------------------------------------------------------------------------------
- void CJView::m_Pause()
- {
- CHAR szText[BUFSIZE];
-
- LoadString(NULL, IDS_PRESSANYKEY, szText, sizeof(szText));
- fprintf(stderr, "%s", szText);
- _getch();
- }
-
- //------------------------------------------------------------------------------
- // 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");
-
- if (m_fPause)
- m_Pause();
- }
-
- //------------------------------------------------------------------------------
- // 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.
- //LoadString(NULL, IDS_MEMBERNOTFOUND, szNoMain, sizeof(szNoMain));
- //if (lstrcmp(buf, szNoMain) == 0)
- 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);
-
- if (m_fPause)
- m_Pause();
- }
-
- //------------------------------------------------------------------------------
- // 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_IJavaExecute, (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_newSZ:
- //
- // Allocates the given string, generating OUT OF MEMORY if it fails
- //
- // Returns: LPSTR to allocated buffer if successful, NULL if not
- //------------------------------------------------------------------------------
- LPSTR CJView::m_newSZ
- (
- int cBytes
- )
- {
- LPSTR psz = new CHAR[cBytes + 1]; // +1 for \0
-
- if (!psz)
- m_FatalError(IDS_OUTOFMEMORY);
-
- return psz;
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_AppendPathString
- //
- // Appends the given path the the other given path, allocating and freeing
- // as neccessary
- //
- // Returns: TRUE if successful, FALSE if not
- //------------------------------------------------------------------------------
- BOOL CJView::m_AppendPathString
- (
- LPSTR *ppszPath,
- LPSTR pszAppend
- )
- {
- LPSTR psz = NULL;
- BOOL fSemi2 = *CharPrev(pszAppend, pszAppend + lstrlen(pszAppend)) != ';';
-
- if (*ppszPath)
- {
- // Been here before, so we append the given string to the given path
- //----------------------------------------------------------------------
- if (!(psz = m_newSZ(lstrlen(*ppszPath))))
- return FALSE;
-
- lstrcpy(psz, *ppszPath);
- deleteSZ(*ppszPath);
-
- BOOL fSemi1 = *CharPrev(psz, psz + lstrlen(psz)) != ';';
-
- if (!(*ppszPath = m_newSZ(lstrlen(psz) + lstrlen(pszAppend) + fSemi1 + fSemi2)))
- {
- deleteSZ(psz);
- return FALSE;
- }
-
- lstrcpy(*ppszPath, psz);
-
- // Add semi-colon between paths if original path did not have one
- //----------------------------------------------------------------------
- if (fSemi1)
- lstrcat(*ppszPath, ";");
-
- lstrcat(*ppszPath, pszAppend);
- deleteSZ(psz);
- }
- else
- {
- // First time here, so copy Append string into Path
- //----------------------------------------------------------------------
- if (!(*ppszPath = m_newSZ(lstrlen(pszAppend) + fSemi2)))
- return FALSE;
-
- lstrcpy(*ppszPath , pszAppend);
- }
-
- // Append final semi-colon if string being append does not have one
- //--------------------------------------------------------------------------
- if (fSemi2)
- lstrcat(*ppszPath, ";");
-
- return TRUE;
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_DisplayUsage:
- //
- // Displays the usage text for JView.exe
- //
- // Returns: Nothing
- //------------------------------------------------------------------------------
- VOID CJView::m_DisplayUsage ()
- {
- // NOTE: All usage lines must be sequential String
- // IDS starting with IDS_USAGE1
- CHAR sz[BUFSIZE];
- INT i = 0;
-
- while (TRUE)
- {
- LoadString(NULL, IDS_USAGE1 + (i++), sz, sizeof(sz));
- if (*sz == '~')
- break;
- printf(sz);
- }
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_PreParseSwitches:
- //
- // Does an initial scan of the command line looking for the -q switch
- //
- //------------------------------------------------------------------------------
- VOID CJView::m_PreParseSwitches
- (
- )
- {
- LPSTR psz;
- int piArg;
-
- piArg = 1;
-
- // We support both '-' and '/' switch designators
- //--------------------------------------------------------------------------
- while ((piArg < m_ac) && ((m_av[piArg][0] == '-') || (m_av[piArg][0] == '/')))
- {
- psz = CharNext(m_av[piArg]);
- CharLower(psz);
-
- // Check for "Quiet" switch , -q
- if (lstrcmp(psz, "q") == 0)
- {
- m_fQuiet = TRUE;
- }
-
- (piArg)++;
- }
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_ParseSwitches:
- //
- // Parses off the switches portion of the command line
- //
- // Returns: TRUE if successful, FALSE if not
- //------------------------------------------------------------------------------
- BOOL CJView::m_ParseSwitches
- (
- int *piArg
- )
- {
- BOOL fSuccess = TRUE;
- BOOL fReplace = m_pszClassPath != NULL;
- LPSTR *ppsz;
- LPSTR psz;
-
- *piArg = 1;
-
- // We support both '-' and '/' switch designators
- //--------------------------------------------------------------------------
- while ((*piArg < m_ac) && ((m_av[*piArg][0] == '-') || (m_av[*piArg][0] == '/')))
- {
- psz = CharNext(m_av[*piArg]);
- CharLower(psz);
-
- // Check for usage switch first. This is only valid as first switch
- //----------------------------------------------------------------------
- if (*piArg == 1 && lstrcmp(psz, "?") == 0)
- {
- m_DisplayUsage();
- fSuccess = FALSE;
- break;
- }
-
- // Check for "run in sun.applet.AppletViewer switch" , -a
- if (lstrcmp(psz, "a") == 0)
- m_fApplet = TRUE;
- // Check for "pause after error switch" , -p
- else if (lstrcmp(psz, "p") == 0)
- m_fPause = TRUE;
- // Check for "Quiet" switch (ignore it), -q
- // NOTE: This is actually parsed/set in m_PreParseSwitches
- else if (lstrcmp(psz, "q") == 0)
- m_fQuiet = TRUE;
- else
- {
- // Check for classpath switches -cp, -cp:p, or -cp:a
- //------------------------------------------------------------------
- BOOL fAppend = FALSE;
- BOOL fPrepend = FALSE;
-
- if ( !lstrcmp(psz, "cp") ||
- (fPrepend = !lstrcmp(psz, "cp:p")) ||
- (fAppend = !lstrcmp(psz, "cp:a")))
- {
- // We have classpath switch, so check for path. If not given,
- // i.e, we're out of arguments, it's a bogus command line
- //--------------------------------------------------------------
- if (++(*piArg) == m_ac ||
- (m_av[*piArg][0] == '-' || m_av[*piArg][0] == '/'))
- {
- m_FatalError(IDS_NOPATHGIVEN, m_av[*piArg - 1]);
- fSuccess = FALSE;
- break;
- }
-
- // If we are given a class path on the command line and we also
- // have a classpath from the environment variable CLASSPATH,
- // the one given on the command line instructs us to ignore the
- // environment variable, and we instead append/prepend other
- // paths to this one instead
- //--------------------------------------------------------------
- if (fReplace && !(fPrepend || fAppend))
- {
- deleteSZ(m_pszClassPath);
- fReplace = FALSE;
- }
-
- ppsz = fPrepend ? &m_pszPrepend : (fAppend ? &m_pszAppend :
- &m_pszClassPath);
- m_AppendPathString(ppsz, m_av[*piArg]);
- }
- else
- {
- // Bogus switch!
- m_FatalError(IDS_INVALIDSWITCH, m_av[*piArg]);
- fSuccess = FALSE;
- break;
- }
- }
-
- (*piArg)++;
- }
-
- return fSuccess;
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_ParseParameters
- //
- // Parses off the remaining 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
- (
- int iNext
- )
- {
- // If applet or stand-alone, we need a values array
- //--------------------------------------------------------------------------
- m_iArgs = m_ac - iNext;
-
- 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 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);
- }
-
- //------------------------------------------------------------------------------
- // CJView::ParseCommandLine:
- //
- // Parses the command line, which must be in the format:
- //
- // JView [switches] ClassName [Parameters]
- //
- // switches: None : Invoke main()
- // -a : Run as Applet
- // -cp <path> : Set CLASSPATH to <path.
- // -cp:p <path> : Prepend <path> to CLASSPATH
- // -cp:a <path> : Append <path> to CLASSPATH
- //
- // Classname: Class file to run. Valid previously compiled .JAVA file(s)
- //
- // Parameters: Name=Value
- //
- // if value contains spaces, value must be contained in double
- // quotes
- //
- // Name="Value contains spaces"
- //
- // Returns: TRUE if successful, FALSE if not
- //------------------------------------------------------------------------------
- BOOL CJView::ParseCommandLine ()
- {
- // Must have at least one command line arguement of class name
- // Argument 0 is JVIEW itself
- //--------------------------------------------------------------------------
- if (m_ac == 1)
- {
- m_FatalError(IDS_NOCLASSGIVEN);
- return FALSE;
- }
-
- // Get current CLASSPATH from VM. We start with this, and append, prepend,
- // or replace it with what we find on the command line
- //--------------------------------------------------------------------------
- LPOLESTR psz = NULL;
-
- if (m_pszClassPath = new CHAR[1])
- *m_pszClassPath = 0;
-
- // First thing we check for are switches, processing all arguments that
- // begin with "-".
- // NOTE: All switches must come before class name and parameters
- //--------------------------------------------------------------------------
- INT i;
-
- if (!m_ParseSwitches(&i))
- return FALSE;
-
- // Next on the command line should be the class file to execute. If no more
- // arguments, it's a bogus command line
- //--------------------------------------------------------------------------
- BOOL fSuccess = TRUE;
-
- if (i == m_ac)
- {
- m_FatalError(IDS_NOCLASSGIVEN);
- fSuccess = FALSE;
- }
- else
- {
- // OK, we have another argument, so whatever it is we simply treat it as
- // the class file name and let the VM deal with verifying it.
- //----------------------------------------------------------------------
- if (m_pszClassName = m_newSZ(lstrlen(m_fApplet ? APPLETVIEWER : m_av[i])))
- {
- lstrcpy(m_pszClassName, m_fApplet ? APPLETVIEWER : m_av[i++]);
-
- // Finally, if we have any more arguments, they are all treated as
- // parameters to be used by the class
- //------------------------------------------------------------------
- if (i < m_ac)
- fSuccess = m_ParseParameters(i);
- }
- }
-
- if (fSuccess)
- {
- // Build final path string
- //----------------------------------------------------------------------
- if (m_pszPrepend)
- {
- if (m_pszClassPath)
- m_AppendPathString(&m_pszPrepend, m_pszClassPath);
- deleteSZ(m_pszClassPath);
- m_pszClassPath = m_pszPrepend;
- m_pszPrepend = NULL;
- }
-
- if (m_pszAppend)
- {
- if (m_pszClassPath)
- {
- m_AppendPathString(&m_pszClassPath, m_pszAppend);
- deleteSZ(m_pszAppend);
- }
- else
- {
- m_pszClassPath = m_pszAppend;
- m_pszAppend = NULL;
- }
- }
- }
-
- return fSuccess;
- }
-
- //------------------------------------------------------------------------------
- // CJView::m_DisplayBanner:
- //
- // Displays the banner for JView.exe
- //
- // Returns: Nothing
- //------------------------------------------------------------------------------
- VOID CJView::m_DisplayBanner ()
- {
- // Get FileVersion info
- //--------------------------------------------------------------------------
- DWORD dwVer = 0;
-
- CHAR szFile[MAX_PATH];
-
- GetModuleFileName(NULL, szFile, sizeof(szFile));
-
- VS_FIXEDFILEINFO *lpInfo;
- DWORD dw;
- DWORD dwSize = GetFileVersionInfoSize(szFile, &dw);
- LPVOID lpData = (LPVOID)new CHAR[dwSize];
-
- GetFileVersionInfo(szFile, 0, dwSize, lpData);
-
- // Get File Version and File Description
- //--------------------------------------------------------------------------
- UINT ui;
- VerQueryValue (lpData, "\\", (LPVOID*)&lpInfo, &ui);
-
- CHAR sz[BUFSIZE];
-
- LoadString(NULL, IDS_BANNER1, sz, sizeof(sz));
- printf(sz, HIWORD(lpInfo->dwFileVersionMS),
- LOWORD(lpInfo->dwFileVersionMS),
- LOWORD(lpInfo->dwFileVersionLS));
- LoadString(NULL, IDS_BANNER2, sz, sizeof(sz));
- printf(sz);
-
- delete lpData;
- }
-
- //------------------------------------------------------------------------------
- // CJView::Initialize:
- //
- // Performs initialization for CJView
- //
- // Returns: TRUE if successful, FALSE if not
- //------------------------------------------------------------------------------
- BOOL CJView::Initialize ()
- {
- m_PreParseSwitches();
- if (!m_fQuiet)
- m_DisplayBanner();
- 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;
- int iResult;
-
- if (pJV->ParseCommandLine())
- {
- LPOLESTR pszClassName;
- LPOLESTR pszClassPath;
- LPERRORINFO pIErrorInfo = NULL;
- JAVAEXECUTEINFO jei;
-
- pszClassName = pJV->m_MB2WC(pJV->m_pszClassName);
- pszClassPath = pJV->m_MB2WC(pJV->m_pszClassPath);
-
- jei.cbSize = sizeof(jei);
- jei.dwFlags = 0;
- jei.pszClassName = pszClassName;
- jei.rgszArgs = (LPCOLESTR *)(pJV->m_ppszArgs);
- jei.cArgs = pJV->m_iArgs;
- jei.pszClassPath = pszClassPath;
-
- HRESULT 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);
- deleteSZ(pszClassPath);
- }
- else
- iResult = 1;
-
- // Terminate message pump
- PostThreadMessage(pJV->m_dwMsgLoopThreadID, WM_QUIT, 0, 0);
-
- return (DWORD)iResult;
- }
-
- //------------------------------------------------------------------------------
- // main() - Entry point for JView
- //
- // Returns: 0 if successful, 1 if not
- //------------------------------------------------------------------------------
- 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;
- }
-
-