home *** CD-ROM | disk | FTP | other *** search
- /*
- * jview.cpp - JView front end, including command-line parsing logic.
- *
- * (C) Copyright 1996-1998, Microsoft Corporation and it suppliers.
- */
-
- #pragma hdrstop
-
- #include "jview.h"
- #include "javaprop.hpp"
-
- // 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"
-
- //------------------------------------------------------------------------------
- // LoadOemString
- //
- // Wrapper for the Win32 LoadString API that translates the string to the OEM
- // character set before returning it to the caller.
- //------------------------------------------------------------------------------
-
- BOOL LoadOemString(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int
- nBufferMax)
- {
- BOOL fResult;
-
- fResult = LoadString(hInstance, uID, lpBuffer, nBufferMax);
-
- if (fResult)
- CharToOem(lpBuffer, lpBuffer);
-
- return fResult;
- }
-
- //------------------------------------------------------------------------------
- // CJView::CJView:
- // Constructor
- //------------------------------------------------------------------------------
- CJView::CJView (int ac, char **av) : m_ac (ac), m_av (av)
- {
- m_fApplet = FALSE;
- m_fPause = FALSE;
- m_fVerify = FALSE;
- m_pszClassPath = NULL;
- m_pszAppend = NULL;
- m_pszPrepend = NULL;
- m_pszClassName = NULL;
- m_ppszArgs = NULL;
- m_iArgs = 0;
- m_pJE = NULL;
- m_pProperties = 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_pProperties)
- {
- m_pProperties->Release();
- delete(m_pProperties);
- }
-
- 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];
-
- LoadOemString(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);
-
-
- LoadOemString(NULL, IDS_ERROR, szFmt, sizeof(szFmt));
- fprintf(stderr, szFmt);
-
- if (idString)
- LoadOemString(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);
-
- LoadOemString(NULL, IDS_ERROR, szFmt, sizeof(szFmt));
- fprintf(stderr, szFmt);
- LoadOemString(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];
-
- LoadOemString(NULL, IDS_SCODE, szSCODE, sizeof(szSCODE));
- sprintf(buf, szSCODE, (DWORD)hr);
- }
- else
- {
- // Convert ANSI string returned by FormatMessage to OEM.
- CharToOem(buf, buf);
-
- // 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] = "";
-
- LoadOemString(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;
-
- m_DisplayBanner();
-
- while (TRUE)
- {
- LoadOemString(NULL, IDS_USAGE1 + (i++), sz, sizeof(sz));
- if (*sz == '~')
- break;
- printf(sz);
- }
- }
-
- //------------------------------------------------------------------------------
- // 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]);
-
- // Check for the -D switch prior to CharLowering the switch string.
-
- if ( (*psz == 'D' || *psz == 'd') && (*(psz+1)==':') )
- {
- char *pszPropStr = psz+2;
-
- if ( *pszPropStr == '\0' )
- {
- m_FatalError(IDS_INVALIDSWITCH, psz);
- fSuccess = FALSE;
- break;
- }
-
- // If we don't already have a properties object, create one.
- if ( !m_pProperties )
- {
- m_pProperties = new(CEnumJAVAPROPERTY);
-
- if (!m_pProperties)
- {
- m_FatalError(IDS_OUTOFMEMORY);
- fSuccess = FALSE;
- break;
- }
- }
-
- // Add the property to the property enumerator.
- m_pProperties->Add(psz+2);
- }
- else
- {
- // All other switches are case insensitive, so just knock 'em down to
- // lowercase here.
-
- 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 "verify all" switch, -v
- else if (lstrcmp(psz, "v") == 0)
- m_fVerify = TRUE;
- // Silently ignore the old "quiet" switch for compatibility with
- // existing scripts.
- else if (lstrcmp(psz, "q") == 0)
- ;
- 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] == '/'))
- {
- // We're about to exit, so we don't have to worry about
- // losing information in the ANSI to OEM conversion.
- CharToOem(m_av[*piArg - 1], m_av[*piArg - 1]);
-
- 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
- {
- // We're about to exit, so we don't have to worry about
- // losing information in the ANSI to OEM conversion.
- CharToOem(m_av[*piArg], m_av[*piArg]);
-
- // 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_DisplayUsage();
- 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];
-
- LoadOemString(NULL, IDS_BANNER1, sz, sizeof(sz));
- printf(sz, HIWORD(lpInfo->dwFileVersionMS),
- LOWORD(lpInfo->dwFileVersionMS),
- LOWORD(lpInfo->dwFileVersionLS));
- LoadOemString(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 ()
- {
- 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::SetSystemProperties:
- //
- // Will inform the VM of any additional system properties that we want to
- // set.
-
- HRESULT CJView::SetSystemProperties()
- {
- HRESULT hr;
- IJavaExecute2 *pije2;
-
- // If no properties defined, bail.
- if ( !m_pProperties )
- return S_OK;
-
- // Query for the IJavaExecute2 interface off of the existing
- // IJavaExecute interface.
- if (m_pJE->QueryInterface(IID_IJavaExecute2, (LPVOID*)&pije2) == S_OK)
- {
- // We found IJavaExecute2, set the system properties.
- hr = pije2->SetSystemProperties( (IEnumJAVAPROPERTY *)m_pProperties);
- pije2->Release();
- }
- else
- {
- // If the QI failed, this current VM does not support IJavaExecute2
- hr = E_FAIL;
- m_FatalError(IDS_PROPSNOTSUPPORTED);
- }
-
- return hr;
- }
-
- //------------------------------------------------------------------------------
- // CJView::ExecuteClass:
- //
- // Executes the given class file
- //
- // Returns: result of IJavaExecute::Execute
- //------------------------------------------------------------------------------
-
- HRESULT CJView::ExecuteClass (LPERRORINFO *ppIErrorInfo)
- {
- LPOLESTR pszClassName;
- LPOLESTR pszClassPath;
- JAVAEXECUTEINFO jei;
-
- pszClassName = m_MB2WC(m_pszClassName);
- pszClassPath = m_MB2WC(m_pszClassPath);
-
- jei.cbSize = sizeof(jei);
- jei.dwFlags = m_fVerify ? JEIF_VERIFYCLASSES : 0;
- jei.pszClassName = pszClassName;
- jei.rgszArgs = (LPCOLESTR *)(m_ppszArgs);
- jei.cArgs = m_iArgs;
- jei.pszClassPath = pszClassPath;
-
- HRESULT hr = m_pJE->Execute(&jei, ppIErrorInfo);
-
- deleteSZ(pszClassPath);
- deleteSZ(pszClassName);
- return hr;
- }
-
-
- //------------------------------------------------------------------------------
- // RunClassThread
- //
- // Executes the given class file. If not found, executes without .class
- // extension, if it has it.
- //
- // Returns: 0 if successful, 1 if not
- //------------------------------------------------------------------------------
-
- DWORD _stdcall RunClassThread
- (
- PVOID pv
- )
- {
- CJView* pJV = (CJView*)pv;
- int iResult = 1; // Assume failure.
-
- if (pJV->ParseCommandLine())
- {
- HRESULT hr;
- LPERRORINFO pIErrorInfo = NULL;
-
- // Check for prepended path
-
- int len = strlen(pJV->m_pszClassName);
-
- if (len > 2 && (pJV->m_pszClassName[1] == ':' || strchr(pJV->m_pszClassName,'\\') != NULL))
- {
- char *fullname = pJV->m_newSZ(MAX_PATH);
- char *endofpath;
-
- if (GetFullPathName(pJV->m_pszClassName, MAX_PATH+1, fullname, &endofpath))
- {
- // Convert to long filename, if needed
-
- WIN32_FIND_DATA findinfo;
- HANDLE hfind;
-
- hfind = FindFirstFile(fullname, &findinfo);
-
- if (hfind == INVALID_HANDLE_VALUE)
- {
- // Try appending a .class extension
-
- strcat(endofpath, ".class");
-
- hfind = FindFirstFile(fullname, &findinfo);
- }
-
- if (hfind != INVALID_HANDLE_VALUE)
- {
- // Split path from name
-
- *(endofpath-1) = '\0';
-
- // Create the real class name and update length
-
- deleteSZ(pJV->m_pszClassName);
- len = lstrlen(findinfo.cFileName);
- pJV->m_pszClassName = pJV->m_newSZ(len);
- lstrcpy(pJV->m_pszClassName, findinfo.cFileName);
-
- // Prepend to specified path
-
- if (*pJV->m_pszClassPath == '\0')
- {
- deleteSZ(pJV->m_pszClassPath);
- pJV->m_pszClassPath = fullname;
- }
- else
- {
- pJV->m_AppendPathString(&fullname, pJV->m_pszClassPath);
- deleteSZ(pJV->m_pszClassPath);
- pJV->m_pszClassPath = fullname;
- }
-
- FindClose(hfind);
- }
- }
-
- // else let the vm deal with whatever was specified.
- }
-
- // Check for .class extension.
-
- const char classext1[] = ".cla";
- const int classext1len = sizeof(classext1)-1;
- const char classext2[] = ".class";
- const int classext2len = sizeof(classext2)-1;
-
- char *classnameext = NULL;
-
- if (len > classext1len)
- {
- char *ext = pJV->m_pszClassName+len-classext1len;
-
- if (_stricmp(ext, classext1) == 0)
- {
- // Truncate at extension.
-
- *ext = '\0';
- classnameext = ext;
- }
- else
- {
- // Try the full extension.
-
- ext -= classext2len-classext1len;
-
- if (_stricmp(ext, classext2) == 0)
- {
- *ext = '\0';
- classnameext = ext;
- }
- }
- }
-
- // Set any user defined system properties.
- hr = pJV->SetSystemProperties();
-
- if ( hr == S_OK )
- {
- hr = pJV->ExecuteClass(&pIErrorInfo);
-
- if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) && classnameext != NULL)
- {
- // Try the 1 in a billion possibility that someone is trying
- // to execute some class named 'class' in a package. Of course,
- // if someone has a class with the same name as the package, we
- // hit it first above.
-
- *classnameext = '.';
-
- hr = pJV->ExecuteClass(&pIErrorInfo);
- }
-
- if (!SUCCEEDED(hr))
- {
- // We're about to exit, so we don't have to worry about
- // losing information in the ANSI to OEM conversion.
- CharToOem(pJV->m_pszClassName, pJV->m_pszClassName);
-
- // 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)
- {
- CharToOem(pszError, 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;
- }
- }
-
- // 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
- //------------------------------------------------------------------------------
-
- #ifdef NO_CONSOLE
- #define ENTRYPOINT int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
- #else
- #define ENTRYPOINT int __cdecl main( int, char ** )
- #endif
-
- ENTRYPOINT
- {
- int iRet = 1;
- CJView* pJV = new CJView(__argc,__argv);
-
- if (!pJV)
- {
- CHAR szFmt[64];
-
- LoadOemString(NULL, IDS_ERROR, szFmt, sizeof(szFmt));
- fprintf(stderr, szFmt);
- LoadOemString(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;
- }
-
-