home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- (C) Copyright 1995 - 1999 Microsoft Corporation. All rights reserved.
-
- Module Name:
-
- jview.cpp
-
- Abstract:
-
- Front end to the Java virtual machine.
-
- --*/
-
- #pragma hdrstop
-
- #define INITGUID 1
-
- #include "jview.h"
- #include "cresprop.hpp"
- #include "version.h"
-
-
- #ifdef PROFILER_HOOK
-
- #include "jviewprf.h"
-
- DEFINE_GUID(CLSID_JVIEWEventMonitor, 0x68c267c0, 0xb042, 0x11d2, 0xb0, 0x81, 0x0, 0x60, 0x8, 0x3, 0x9b, 0xf0);
- #define CLSIDSTR_JVIEWEventMonitor "{68C267C0-B042-11d2-B081-006008039BF0}"
-
- #endif
-
-
- #define VER_LAST_COPYRIGHT_YEAR 1999
-
-
- // 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())
-
- // e.g., "D2029F40-8AB3-11CF-85FB-00401C608501"
- // (+ 1) for null terminator
- #define GUIDSTR_LEN (8 + 1 + 4 + 1 + 4 + 1 + 4 + 1 + 12 + 1)
-
- // e.g., "{D2029F40-8AB3-11CF-85FB-00401C608501}"
- // (+ 1) for leading bracket, (+ 1) for trailing bracket
- #define GUIDSTR_MAX (1 + GUIDSTR_LEN + 1)
-
- #define MAX_BUFFER 4096
-
- /* array element count */
-
- #define ARRAY_ELEMENTS(rg) (sizeof(rg) / sizeof((rg)[0]))
-
-
- #ifdef APPLETVIEWER
- #define APPLETVIEWER_CLASS L"com.ms.applet.Main"
- #else
- #define APPLETVIEWER_CLASS "com.ms.applet.Main"
- #endif
-
- RESOURCEJAVAPROPERTY g_AppletViewerProperties[] = {
- L"com.ms.tools.appletviewer.warn.noappletattrs", IDS_WARN_NOAPPLETATTRS,
- L"com.ms.tools.appletviewer.warn.noparamattrs", IDS_WARN_NOPARAMATTRS,
- L"com.ms.tools.appletviewer.warn.invalidparam", IDS_WARN_INVALIDPARAM,
- L"com.ms.tools.appletviewer.warn.nocode", IDS_WARN_NOCODE,
- L"com.ms.tools.appletviewer.warn.parseerror", IDS_WARN_PARSEERROR,
- L"com.ms.tools.appletviewer.warn.noapphtml", IDS_WARN_NOAPPLETTAGS,
- L"com.ms.tools.appletviewer.warn.urlerror", IDS_WARN_URLNOTFOUND,
- L"com.ms.tools.appletviewer.warn.fileerror", IDS_WARN_FILENOTFOUND,
-
- L"com.ms.tools.appletviewer.error.noapplets", IDS_ERROR_NOAPPLETS,
- L"com.ms.tools.appletviewer.error.unexpected", IDS_ERROR_UNEXPECTED,
-
- L"com.ms.tools.appletviewer.menu.applet", IDS_MENU_APPLET,
- L"com.ms.tools.appletviewer.menu.reload", IDS_MENU_RELOAD,
- L"com.ms.tools.appletviewer.menu.restart", IDS_MENU_RESTART,
- L"com.ms.tools.appletviewer.menu.stop", IDS_MENU_STOP,
- L"com.ms.tools.appletviewer.menu.start", IDS_MENU_START,
- L"com.ms.tools.appletviewer.menu.html", IDS_MENU_HTML,
- L"com.ms.tools.appletviewer.menu.info", IDS_MENU_INFO,
- L"com.ms.tools.appletviewer.menu.console", IDS_MENU_CONSOLE,
- L"com.ms.tools.appletviewer.menu.secreload", IDS_MENU_SECRELOAD,
- L"com.ms.tools.appletviewer.menu.quit", IDS_MENU_QUIT,
-
- L"com.ms.tools.appletviewer.usage", IDS_APPLETVIEWER_USAGE,
- L"com.ms.tools.appletviewer.title", IDS_APPLETVIEWER_TITLE,
- L"com.ms.tools.appletviewer.loading", IDS_APPLETVIEWER_LOADING,
- L"com.ms.tools.appletviewer.htmltitle", IDS_APPLETVIEWER_HTMLTITLE,
- L"com.ms.tools.appletviewer.infotitle", IDS_APPLETVIEWER_INFOTITLE,
- L"com.ms.tools.appletviewer.noinfo", IDS_APPLETVIEWER_NOINFO,
- };
-
- // Globals
-
- BOOL g_fPause = FALSE;
- LPSTR g_pszMainClass = NULL;
-
-
- typedef int __cdecl snprintfProc (char *str, size_t count, const char *fmt, ...);
- typedef int __cdecl vsnprintfProc (char *str, size_t count, const char *fmt, va_list args);
-
- int __cdecl unsafe_snprintf (char *str, size_t count, const char *fmt, ...)
- {
- va_list va;
- va_start(va, fmt);
- int len = wvsprintf(str, fmt, va);
- va_end(va);
- return len;
- }
-
- int __cdecl unsafe_vsnprintf (char *str, size_t count, const char *fmt, va_list args)
- {
- return wvsprintf(str, fmt, args);
- }
-
- // Start with the unbounded versions in user32. When msjava is loaded, we'll
- // switch to its bounded versions (jio_snprintf and jio_vsnprintf).
- snprintfProc *g_pfnsnprintf = &unsafe_snprintf;
- vsnprintfProc *g_pfnvsnprintf = &unsafe_vsnprintf;
-
- #define JVIEWsnprintf (*g_pfnsnprintf)
- #define JVIEWvsnprintf (*g_pfnvsnprintf)
-
-
- //------------------------------------------------------------------------
-
-
- BOOL WriteConsoleBasic (DWORD nStdHandle, LPCSTR lpBuffer, DWORD nNumberOfCharsToWrite);
- int LoadStringX (HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int nBufferMax);
-
-
- //------------------------------------------------------------------------
- // Exported profiler functions
-
- #ifdef PROFILER_HOOK
-
- BOOL g_fMessageDisplayed = FALSE;
-
- class JVIEWProfilerUtils : public IJVIEWProfilerUtils
- {
- public:
-
- STDMETHODIMP QueryInterface (REFIID riid, LPVOID *ppvObj)
- {
- if ( riid == IID_IUnknown
- || riid == IID_IJVIEWProfilerUtils)
- {
- *ppvObj = (IJVIEWProfilerUtils*)this;
- }
- else
- {
- *ppvObj = NULL;
- return E_NOINTERFACE;
- }
-
- //AddRef();
- return S_OK;
- }
-
- STDMETHODIMP_(ULONG) AddRef ()
- {
- return 1;
- }
-
- STDMETHODIMP_(ULONG) Release ()
- {
- return 1;
- }
-
- STDMETHODIMP DisplayString (JVIEWDisplayClass cls, PCSTR pcsz)
- {
- BOOL ret;
-
- #ifndef NO_CONSOLE
- DWORD nhnd = STD_OUTPUT_HANDLE;
-
- if (cls == JDC_ERROR)
- nhnd = STD_ERROR_HANDLE;
-
- ret = WriteConsoleBasic(nhnd, pcsz, -1);
-
- if (ret && cls == JDC_ERROR && g_fPause)
- Pause();
- #else
- UINT mbtype = MB_OK;
-
- switch (cls)
- {
- case JDC_INFORMATION:
- mbtype |= MB_ICONINFORMATION;
- break;
-
- case JDC_WARNING:
- mbtype |= MB_ICONWARNING;
- break;
-
- case JDC_ERROR:
- mbtype |= MB_ICONERROR;
- break;
- }
-
- CHAR szTitle[MAX_BUFFER];
- LoadStringX(NULL, IDS_WJVIEW_PROFTITLE, szTitle, sizeof(szTitle));
-
- ret = (MessageBox(NULL, pcsz, szTitle, mbtype) == IDOK);
- #endif
-
- if (ret)
- g_fMessageDisplayed = TRUE;
-
- return ret ? S_OK : E_FAIL;
- }
-
- STDMETHODIMP DisplayResourceString (JVIEWDisplayClass cls, HINSTANCE hinst, UINT id)
- {
- CHAR szText[BUFSIZE];
- DWORD nChars;
-
- nChars = LoadStringX(hinst, id, szText, sizeof(szText));
-
- if (nChars)
- return DisplayString(cls, szText);
- else
- return E_FAIL;
- }
-
- STDMETHODIMP_(int) LoadResourceString (HINSTANCE hinst, UINT id, PSTR buf, int bufsize)
- {
- return LoadStringX(hinst, id, buf, bufsize);
- }
-
- STDMETHODIMP_(int) snprintf (char *str, size_t count, const char *fmt, ...)
- {
- va_list va;
- va_start(va, fmt);
- int len = JVIEWvsnprintf(str, count, fmt, va);
- va_end(va);
- return len;
- }
-
- STDMETHODIMP_(int) vsnprintf (char *str, size_t count, const char *fmt, va_list args)
- {
- return JVIEWvsnprintf(str, count, fmt, args);
- }
- };
-
- #endif // PROFILER_HOOK
-
-
- //------------------------------------------------------------------------
-
-
- #ifndef NO_CONSOLE
-
- //------------------------------------------------------------------------------
- // WaitConsoleKeypress
- //
- // Waits for a keypress on the console. Lightweight version of the CRT _getch
- // function, which this function is heavily based on.
- //------------------------------------------------------------------------------
-
- VOID WaitConsoleKeypress()
- {
- HANDLE hConsole;
- DWORD OldConsoleMode;
- INPUT_RECORD InputRecord;
- DWORD NumberOfEventsRead;
-
- hConsole = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
-
- if (hConsole != INVALID_HANDLE_VALUE) {
-
- // Switch console to raw mode (no line input, no echo input).
- GetConsoleMode(hConsole, &OldConsoleMode);
- SetConsoleMode(hConsole, 0);
-
- while (TRUE) {
-
- if (!ReadConsoleInput(hConsole, &InputRecord, 1,
- &NumberOfEventsRead) || NumberOfEventsRead == 0)
- break;
-
- if (InputRecord.EventType == KEY_EVENT &&
- InputRecord.Event.KeyEvent.bKeyDown)
- {
- switch (InputRecord.Event.KeyEvent.wVirtualKeyCode)
- {
- case VK_CONTROL:
- case VK_MENU:
- continue;
-
- case 'c':
- case 'C':
- {
- DWORD dwCtrlKeysMask = (InputRecord.Event.KeyEvent.dwControlKeyState & ( LEFT_CTRL_PRESSED
- | RIGHT_CTRL_PRESSED
- | LEFT_ALT_PRESSED
- | RIGHT_ALT_PRESSED
- | SHIFT_PRESSED));
- if ( (dwCtrlKeysMask & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
- && !(dwCtrlKeysMask & ~(LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))
- {
- ExitProcess(-1);
- }
- }
- break;
- }
-
- break;
- }
- }
-
- SetConsoleMode(hConsole, OldConsoleMode);
- CloseHandle(hConsole);
- }
- }
-
- //------------------------------------------------------------------------------
- // WriteConsoleBasic
- //
- // Wrapper for the Win32 WriteConsole API.
- //------------------------------------------------------------------------------
-
- BOOL WriteConsoleBasic(DWORD nStdHandle, LPCSTR lpBuffer, DWORD
- nNumberOfCharsToWrite)
- {
- DWORD NumberOfCharsWritten;
-
- if (nNumberOfCharsToWrite == (DWORD) -1)
- nNumberOfCharsToWrite = lstrlen(lpBuffer);
-
- // Don't call WriteConsoleA, because that won't handle the case of
- // redirected file handles on NT properly (jview does.not.exist >x 2>&1).
- return WriteFile(GetStdHandle(nStdHandle), (LPSTR) lpBuffer,
- nNumberOfCharsToWrite, &NumberOfCharsWritten, NULL);
- }
-
- //------------------------------------------------------------------------------
- // WriteConsoleVprintf
- //
- // Wrapper for the Win32 WriteConsole API.
- //------------------------------------------------------------------------------
-
- BOOL WriteConsoleVprintf(DWORD nStdHandle, LPCSTR lpFormat, va_list arglist)
- {
- CHAR buffer[4096];
- DWORD nChars;
-
- nChars = JVIEWvsnprintf(buffer, sizeof(buffer), lpFormat, arglist);
-
- return WriteConsoleBasic(nStdHandle, buffer, nChars);
- }
-
- //------------------------------------------------------------------------------
- // WriteConsolePrintf
- //
- // Wrapper for the Win32 WriteConsole API.
- //------------------------------------------------------------------------------
-
- BOOL WriteConsolePrintf(DWORD nStdHandle, LPCSTR lpFormat, ...)
- {
- BOOL fResult;
- va_list va;
-
- va_start(va, lpFormat);
- fResult = WriteConsoleVprintf(nStdHandle, lpFormat, va);
- va_end(va);
-
- return fResult;
- }
-
- #endif // !NO_CONSOLE
-
-
- INT VMLoadString(
- HINSTANCE hModule,
- UINT wStringID,
- LPSTR pszBuffer,
- int cchBufferMax,
- WORD wLanguage);
-
- //------------------------------------------------------------------------------
- // LoadStringX
- //
- // Wrapper around VMLoadString that will use the default user language
- // to load strings. For the console mode jview.exe, this wrapper will
- // also perform the converstion to the OEM character set.
- //------------------------------------------------------------------------------
-
- int LoadStringX(
- HINSTANCE hInstance,
- UINT uID,
- LPSTR lpBuffer,
- int nBufferMax)
- {
- int nChars;
-
- nChars = VMLoadString(hInstance,uID,lpBuffer,nBufferMax,LANG_USER_DEFAULT);
-
- #ifndef NO_CONSOLE
-
- if (nChars > 0)
- CharToOem(lpBuffer, lpBuffer);
-
- #endif
-
- return nChars;
- }
-
- #ifdef NO_CONSOLE
- #define CharToOemX(args) ((void) 0)
- #else
- #define CharToOemX(args) CharToOem args
- #endif
-
- //------------------------------------------------------------------------------
- // FatalError:
- //
- // Print a formatted error message to stderr
- //
- // Returns: Nothing
- //------------------------------------------------------------------------------
-
- void FatalError
- (
- INT idString,
- ...
- )
- {
- CHAR szError[MAX_BUFFER];
-
- CHAR *pch;
- CHAR szFmt[BUFSIZE];
- va_list va;
-
- // Load the prefix string into our buffer.
- LoadStringX(NULL,IDS_ERROR,szError,sizeof(szError));
-
- // If an resource ID was specified load it up into a
- // temp buffer so that we can use it from the printf
- // operation.
- if (idString)
- LoadStringX(NULL, idString, szFmt, sizeof(szFmt));
- else
- lstrcpy(szFmt, "%s");
-
- // Get a pointer into our error buffer just past the
- // prefix string.
- pch = szError + lstrlen(szError);
-
- // Copy the remainder of the error message. Reserve space for the '\n'
- // we'll add below.
- va_start(va, idString);
- JVIEWvsnprintf(pch, sizeof(szError) - (pch-szError) - 1, szFmt, va);
- va_end(va);
-
- // Terminate it.
- lstrcat(szError,"\n");
-
- // If building for WJVIEW, display the error string in a
- // MessageBox, otherwise dump it to the console.
-
- #ifdef NO_CONSOLE
- // Load up the caption title. Reuse the printf format buffer.
- LoadStringX(NULL,IDS_WJVIEW_TITLE_ERROR,szFmt,sizeof(szFmt));
-
- MessageBox(NULL,szError,szFmt,MB_OK|MB_ICONHAND);
- #else
- WriteConsoleBasic(STD_ERROR_HANDLE,szError,lstrlen(szError));
-
- if (g_fPause)
- Pause();
- #endif
-
- }
-
- //------------------------------------------------------------------------------
- // FatalErrorHR:
- //
- // Print a formatted error followup by an hresult tp stderr
- //------------------------------------------------------------------------------
-
- void FatalErrorHR
- (
- HRESULT hr,
- INT idString,
- ...
- )
- {
- CHAR szError[MAX_BUFFER] = "\0";
- CHAR *pch = NULL;;
- DWORD cRemaining = sizeof(szError);
-
- CHAR szFmt[BUFSIZE];
- DWORD nChars;
- DWORD res;
- va_list va;
-
- // Load the error prefix string.
- nChars = LoadStringX(NULL,IDS_ERROR,szError, sizeof(szError));
-
- // Keep track of our current position in the error string buffer.
- cRemaining -= nChars;
- pch = szError + nChars;
-
- // Load next portion of the error string based upon the specified
- // resource ID, and then do a printf operation into the error
- // buffer using the resource string and the specified params.
- nChars = LoadStringX(NULL, idString, szFmt, sizeof(szFmt));
-
- // Reserve 4 chars for the " : " and "\n" we may add below.
- cRemaining = sizeof(szError) - nChars - 4;
-
- va_start(va, idString);
- JVIEWvsnprintf(pch, cRemaining, szFmt, va);
- va_end(va);
-
- // Add a seperator to the message.
- lstrcat( szError, " : " );
-
- // Keep track of our current position in the error string buffer.
- pch = szError + lstrlen(szError);
- cRemaining = MAX_BUFFER - (DWORD) (pch - szError);
-
- // Add more text to the error buffer based upon the specified
- // HRESULT.
- res = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- (DWORD)hr,
- LOCALE_SYSTEM_DEFAULT,
- pch,
- cRemaining,
- NULL);
-
- if (!res)
- {
- // If not system error message was found for the specified
- // HRESULT, use a generic error.
-
- CHAR szSCODE[BUFSIZE];
-
- LoadStringX(NULL, IDS_SCODE, szSCODE, sizeof(szSCODE));
- JVIEWsnprintf(pch, cRemaining, szSCODE, (DWORD)hr);
- }
- else
- {
- // Convert ANSI string returned by FormatMessage to OEM.
- CharToOemX((pch,pch));
-
- // 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)
- {
- lstrcat(szError,"\n");
-
- // Move pointer to the end of the buffer.
- pch = szError + lstrlen(szError);
-
- LoadStringX(NULL,IDS_NOMAIN,szFmt,sizeof(szFmt));
-
- cRemaining = MAX_BUFFER - (DWORD) (pch - szError);
- JVIEWsnprintf(pch, cRemaining, szFmt, g_pszMainClass, g_pszMainClass);
- }
- }
-
- // If building for WJVIEW, display the error string in a
- // MessageBox, otherwise dump it to the console.
- #ifdef NO_CONSOLE
- // Load up the caption title. Reuse the printf format buffer.
- LoadStringX(NULL,IDS_WJVIEW_TITLE_ERROR,szFmt,sizeof(szFmt));
-
- MessageBox(NULL,szError,szFmt,MB_OK|MB_ICONHAND);
- #else
- WriteConsoleBasic(STD_ERROR_HANDLE,szError,lstrlen(szError));
-
- if (g_fPause)
- Pause();
- #endif
- }
-
-
- #ifndef NO_CONSOLE
-
- //------------------------------------------------------------------------------
- // 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 Pause()
- {
- CHAR szText[BUFSIZE];
- DWORD nChars;
-
- nChars = LoadStringX(NULL, IDS_PRESSANYKEY, szText, sizeof(szText));
- WriteConsoleBasic(STD_ERROR_HANDLE, szText, nChars);
- WaitConsoleKeypress();
- WriteConsoleBasic(STD_ERROR_HANDLE, "\n", 1);
- }
-
- #endif
-
-
- //------------------------------------------------------------------------------
- // CJView::CJView:
- // Constructor
- //------------------------------------------------------------------------------
- CJView::CJView (int ac, char **av) : m_ac (ac), m_av (av)
- {
- m_fVerify = FALSE;
- m_fVerboseStackTraces = FALSE;
- m_pszClassPath = NULL;
- m_pszAppend = NULL;
- m_pszPrepend = NULL;
- m_pszClassName = NULL;
- m_ppszArgs = NULL;
- m_iArgs = 0;
- m_pJE = NULL;
- m_pszNamespace = NULL;
- #ifdef APPLETVIEWER
- m_fApplet = TRUE;
- #else
- m_pProperties = NULL;
- m_fApplet = FALSE;
- #endif
-
- #ifdef PROFILER_HOOK
- m_pProfiler = NULL;
- m_fAttemptedLoadProfiler = FALSE;
- m_fEnableProfiling = FALSE;
- #endif
- }
-
- //------------------------------------------------------------------------------
- // CJView::~CJView:
- // Destructor
- //------------------------------------------------------------------------------
- CJView::~CJView ()
- {
- deleteSZ(m_pszClassPath);
- deleteSZ(m_pszClassName);
- deleteSZ(m_pszAppend);
- deleteSZ(m_pszPrepend);
- deleteSZ(m_pszNamespace);
-
- g_pszMainClass = NULL;
-
- if (m_ppszArgs)
- {
- INT n = 0;
-
- while (m_ppszArgs[n] != NULL)
- delete [] m_ppszArgs[n++];
- delete [] m_ppszArgs;
- }
-
- #ifndef APPLETVIEWER
-
- if (m_pProperties)
- {
- m_pProperties->Release();
- m_pProperties = NULL;
- }
-
- #endif
-
- #ifdef PROFILER_HOOK
- if (m_pProfiler)
- m_pProfiler->Release();
- #endif
-
- if (m_pJE)
- {
- m_pJE->Release();
- CoUninitialize();
- }
- }
-
-
- #ifdef PROFILER_HOOK
-
- IJVIEWProfiler *CreateProfilerFromLibrary (PCSTR pcszProfilerLibFilename)
- {
- IJVIEWProfiler *pProfiler = NULL;
-
- HMODULE hmodProfiler = LoadLibrary(pcszProfilerLibFilename);
- if (hmodProfiler)
- {
- JVIEWPRF_CreateProfilerProc *pfnCreateProfiler = (JVIEWPRF_CreateProfilerProc*)GetProcAddress(
- hmodProfiler, JVIEWPRF_CreateProfilerProcNameStr);
- if (pfnCreateProfiler)
- {
- pProfiler = (*pfnCreateProfiler)();
- }
-
- if (!pProfiler)
- {
- LPFNGETCLASSOBJECT pfnDllGetClassObject = (LPFNGETCLASSOBJECT)GetProcAddress(
- hmodProfiler, "DllGetClassObject");
- if (pfnDllGetClassObject)
- {
- IClassFactory *pProfilerFactory;
- if (SUCCEEDED((*pfnDllGetClassObject)(CLSID_DefaultJVIEWProfiler, IID_IClassFactory, (PVOID*)&pProfilerFactory)))
- {
- pProfilerFactory->CreateInstance(NULL, IID_IJVIEWProfiler, (PVOID*)&pProfiler);
-
- pProfilerFactory->Release();
- }
- }
- }
-
- if (!pProfiler)
- {
- FreeLibrary(hmodProfiler);
- }
- }
-
- return pProfiler;
- }
-
-
- IJVIEWProfiler *CJView::LoadProfiler (BOOL fSilent)
- {
- IJVIEWProfiler *pProfiler = m_pProfiler;
-
- if (!pProfiler && !m_fAttemptedLoadProfiler)
- {
- UINT idError = fSilent ? 0 : IDS_COULDNOTLOADPROF;
-
- CHAR szProfilerCLSID[GUIDSTR_MAX];
- if (GetEnvironmentVariable(JVIEWPRF_ENV_VAR_CLSID_STR, szProfilerCLSID, sizeof(szProfilerCLSID)))
- {
- WCHAR wszProfilerCLSID[GUIDSTR_MAX*2];
- for (unsigned i = 0; i < sizeof(szProfilerCLSID); i++)
- wszProfilerCLSID[i] = szProfilerCLSID[i];
-
- CLSID ProfilerCLSID;
- if (SUCCEEDED(CLSIDFromString(wszProfilerCLSID, &ProfilerCLSID)))
- {
- CoCreateInstance(ProfilerCLSID, NULL, CLSCTX_INPROC_SERVER, IID_IJVIEWProfiler, (PVOID*)&pProfiler);
- }
- }
-
- if (!pProfiler)
- {
- CHAR szProfilerLibFilename[MAX_PATH];
- if (GetEnvironmentVariable(JVIEWPRF_ENV_VAR_LIB_STR, szProfilerLibFilename, sizeof(szProfilerLibFilename)))
- {
- pProfiler = CreateProfilerFromLibrary(szProfilerLibFilename);
- }
- }
-
- if (!pProfiler)
- {
- pProfiler = CreateProfilerFromLibrary(JVIEWPRF_DEFAULT_LIB_FILENAME_STR);
- }
-
- if (!pProfiler)
- {
- CoCreateInstance(CLSID_DefaultJVIEWProfiler, NULL, CLSCTX_INPROC_SERVER, IID_IJVIEWProfiler, (PVOID*)&pProfiler);
- }
-
- if (pProfiler)
- {
- JVIEWProfilerUtils *pUtils = new JVIEWProfilerUtils();
- if (pUtils)
- {
- if (FAILED(pProfiler->JVIEWInitialize(pUtils)))
- {
- if (g_fMessageDisplayed)
- idError = 0;
- else
- idError = IDS_COULDNOTINITPROF;
-
- pProfiler->Release();
- pProfiler = NULL;
- }
-
- //pUtils->Release();
- }
-
- }
-
- if (!pProfiler && idError)
- FatalError(idError);
-
- m_pProfiler = pProfiler;
- m_fAttemptedLoadProfiler = TRUE;
- }
-
- return pProfiler;
- }
-
-
- BOOL CJView::ParseProfilingParams (PCSTR pcszParams)
- {
- BOOL ret = FALSE;
-
- IJVIEWProfiler *pProfiler = LoadProfiler();
- if (pProfiler)
- {
- if (pcszParams[0] == '\0')
- {
- ret = TRUE;
- }
- else
- {
- pcszParams++;
-
- ret = SUCCEEDED(pProfiler->ParseParameters(pcszParams));
-
- if (!ret && !g_fMessageDisplayed)
- {
- FatalError(IDS_BADPROFPARAMS);
- }
- }
- }
-
- return ret;
- }
-
- #endif // PROFILER_HOOK
-
-
- //------------------------------------------------------------------------------
- // 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))
- {
- 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))
- {
- FatalErrorHR(hr, IDS_JAVAVM);
- }
- else
- {
- // Getting the class factory should have loaded msjava. Link its
- // size-bounded sprintf functions. If they're not there for some
- // bizarre reason, we'll fall back on user's wsprintf.
-
- HMODULE hmodMSJAVA = GetModuleHandle("MSJAVA.DLL");
- if (hmodMSJAVA)
- {
- snprintfProc *pfnsnprintf = (snprintfProc *)GetProcAddress(hmodMSJAVA, "jio_snprintf");
- vsnprintfProc *pfnvsnprintf = (vsnprintfProc*)GetProcAddress(hmodMSJAVA, "jio_vsnprintf");
-
- if (pfnsnprintf) g_pfnsnprintf = pfnsnprintf;
- if (pfnvsnprintf) g_pfnvsnprintf = pfnvsnprintf;
- }
-
- hr = pcf->CreateInstance(NULL, IID_IJavaExecute, (LPVOID *)(&m_pJE));
- if (FAILED(hr))
- {
- m_pJE = NULL;
- 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)
- FatalError(IDS_OUTOFMEMORY);
-
- return psz;
- }
-
-
-
- BOOL CJView::m_SetNamespace
- (
- LPSTR pszNamespace
- )
- {
- m_pszNamespace = m_MB2WC((LPCSTR) pszNamespace);
-
- if (m_pszNamespace == NULL)
- return FALSE;
- else
- return TRUE;
- }
-
-
- //------------------------------------------------------------------------------
- // 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
- //------------------------------------------------------------------------------
-
- #ifdef NO_CONSOLE
-
- VOID CJView::m_DisplayUsage()
- {
- CHAR *pszBuffer;
- CHAR *pchDest;
- CHAR *pchSrc;
- DWORD dwCurBufferSize;
- DWORD dwMaxBufferSize;
- CHAR szTmp[BUFSIZE];
- INT i = 0;
- DWORD nChars;
-
- dwCurBufferSize = 0;
- dwMaxBufferSize = MAX_BUFFER;
- pszBuffer = new(CHAR[dwMaxBufferSize]);
-
- if (!pszBuffer)
- return;
-
- // Pick up the copyright banner text.
-
- LoadStringX(NULL, IDS_BANNER1, szTmp, sizeof(szTmp));
-
- JVIEWsnprintf(pszBuffer, dwMaxBufferSize, szTmp,
- HIBYTE(HIWORD(VER_PRODUCTVERSION_DW)),
- LOBYTE(HIWORD(VER_PRODUCTVERSION_DW)),
- LOWORD(VER_PRODUCTVERSION_DW));
-
- dwCurBufferSize = lstrlen(pszBuffer);
- pchDest = pszBuffer + dwCurBufferSize;
-
- LoadStringX(NULL, IDS_BANNER2, szTmp, sizeof(szTmp));
- JVIEWsnprintf(pchDest, dwMaxBufferSize - dwCurBufferSize, szTmp, VER_LAST_COPYRIGHT_YEAR);
-
- dwCurBufferSize = lstrlen(pszBuffer);
-
- // Get the actual help text.
-
- while (TRUE)
- {
- nChars = LoadStringX(NULL, IDS_USAGE1 + (i++), szTmp, sizeof(szTmp));
-
- if (*szTmp == '~')
- break;
-
- pchSrc = szTmp;
-
- if ( dwCurBufferSize + nChars > dwMaxBufferSize )
- {
- DWORD dwNewMax = dwMaxBufferSize + MAX_BUFFER;
- CHAR *pszTmpBuffer = new( CHAR[dwNewMax] );
-
- if (!pszTmpBuffer)
- break;
-
- CopyMemory(pszTmpBuffer,pszBuffer,dwCurBufferSize);
- delete(pszBuffer);
-
- pszBuffer = pszTmpBuffer;
- dwMaxBufferSize = dwNewMax;
- }
-
- pchDest = pszBuffer + dwCurBufferSize;
-
- CopyMemory(pchDest, pchSrc, nChars);
-
- dwCurBufferSize += nChars;
- }
-
- // Load up the caption title. Reuse the printf format buffer.
- LoadStringX(NULL,IDS_WJVIEW_TITLE_HELP,szTmp,sizeof(szTmp));
-
- MessageBox(NULL,pszBuffer,"WJView Help",MB_OK);
- }
-
- #else
-
- VOID CJView::m_DisplayUsage ()
- {
- // NOTE: All usage lines must be sequential String
- // IDS starting with IDS_USAGE1
- CHAR sz[BUFSIZE];
- INT i = 0;
- DWORD nChars;
-
- m_DisplayBanner();
-
- while (TRUE)
- {
- nChars = LoadStringX(NULL, IDS_USAGE1 + (i++), sz, sizeof(sz));
-
- if (*sz == '~')
- break;
-
- CHAR *pchSrc = sz;
-
- WriteConsoleBasic(STD_OUTPUT_HANDLE, pchSrc, nChars);
- }
- }
-
- #endif
-
- //------------------------------------------------------------------------------
- // 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;
-
- #ifndef APPLETVIEWER
-
- 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' )
- {
- 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)
- {
- FatalError(IDS_OUTOFMEMORY);
- fSuccess = FALSE;
- break;
- }
- }
-
- // Add the property to the property enumerator.
- m_pProperties->Add(psz+2);
- }
- else
- {
- // Check for usage switch first. This is only valid as first switch
- //----------------------------------------------------------------------
- if (*piArg == 1 && lstrcmp(psz, "?") == 0)
- {
- m_DisplayUsage();
- fSuccess = FALSE;
- break;
- }
-
- #ifdef PROFILER_HOOK
- CHAR buf[5];
- *(DWORD*)buf = *(DWORD*)psz;
- buf[4] = '\0';
- if (lstrcmpi(buf, "prof") == 0 && (psz[4] == ':' || psz[4] == '\0'))
- {
- *(DWORD*)psz = *(DWORD*)"prof";
- }
- else
- #endif
- {
- // All other switches are case insensitive, so just knock 'em down to
- // lowercase here.
-
- CharLower(psz);
- }
-
- // 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)
- g_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)
- ;
- // check for "verbose stack traces" switch
- else if( lstrcmp( psz, "vst" ) == 0 )
- m_fVerboseStackTraces = TRUE;
- #ifdef PROFILER_HOOK
- else if ( *(DWORD*)psz == *(DWORD*)"prof"
- && (psz[4] == ':' || psz[4] == '\0'))
- {
- if (!ParseProfilingParams(psz+4))
- {
- // ParseProfilingParams has already displayed an error message.
- fSuccess = FALSE;
- break;
- }
-
- m_fEnableProfiling = TRUE;
- }
- #endif
- #ifndef NO_CONSOLE
- // Internal switches to control process affinity.
- else if ((lstrcmp(psz, "x:pa1") == 0) ||
- (lstrcmp(psz, "x:pa2") == 0) ||
- (lstrcmp(psz, "x:pa3") == 0) ||
- (lstrcmp(psz, "x:pa4") == 0))
- {
- typedef BOOL (WINAPI *PFNSETPROCESSAFFINITYMASK)(HANDLE, DWORD);
- HMODULE hmodKernel = GetModuleHandle("KERNEL32");
- PFNSETPROCESSAFFINITYMASK pfnSetProcessAffinityMask =
- (PFNSETPROCESSAFFINITYMASK) GetProcAddress(hmodKernel,
- "SetProcessAffinityMask");
-
- if (pfnSetProcessAffinityMask != NULL)
- {
- pfnSetProcessAffinityMask(GetCurrentProcess(),
- (1 << (psz[4] - '0')) - 1);
- }
- }
- #endif
- 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.
- CharToOemX((m_av[*piArg - 1], m_av[*piArg - 1]));
-
- 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 if (!lstrcmp(psz, "n"))
- {
- // 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.
- CharToOemX((m_av[*piArg - 1], m_av[*piArg - 1]));
-
- FatalError(IDS_NONAMESPACEGIVEN, m_av[*piArg - 1]);
- fSuccess = FALSE;
- break;
- }
-
- (void) m_SetNamespace(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.
- CharToOemX((m_av[*piArg], m_av[*piArg]));
-
- // Bogus switch!
- FatalError(IDS_INVALIDSWITCH, m_av[*piArg]);
- fSuccess = FALSE;
- break;
- }
- }
- }
-
- (*piArg)++;
- }
-
- #endif
-
- 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)
- {
- 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 ()
- {
- #ifdef APPLETVIEWER
-
- return m_ac > 1 ? m_ParseParameters(1) : TRUE;
-
- #else
-
- // 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)
- {
- FatalError(IDS_NOCLASSGIVEN);
- fSuccess = FALSE;
- }
- else
- {
- INT len;
- // 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(len = lstrlen(m_fApplet ? APPLETVIEWER_CLASS : m_av[i])))
- {
- lstrcpy(m_pszClassName, m_fApplet ? APPLETVIEWER_CLASS : m_av[i++]);
-
- // Keep track of the class name in a global. Note that we alias the
- // real m_pszClassName here. Need to be careful about lifetimes.
- g_pszMainClass = m_pszClassName;
-
- OSVERSIONINFO osvi;
- osvi.dwOSVersionInfoSize = sizeof(osvi);
-
- if (len && GetVersionEx(&osvi) && (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT))
- {
- INT j = i;
-
- // compute of length of title
-
- len += lstrlen("JVIEW ") + 1; // +1 for \0
- while (j < m_ac)
- {
- len += lstrlen(m_av[j++]) + 1; // +1 for ' '
- }
-
-
- LPSTR title = new CHAR[len]; // +1 for \0
- if (title)
- {
- lstrcpy(title, "JVIEW ");
- lstrcat(title,g_pszMainClass);
- j = i;
-
- while (j < m_ac)
- {
- lstrcat(title, " ");
- lstrcat(title, m_av[j++]);
- }
-
- SetConsoleTitle(title);
- delete title;
- }
- }
-
-
- // 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;
-
- #endif
- }
-
-
- #ifndef NO_CONSOLE
-
- //------------------------------------------------------------------------------
- // CJView::m_DisplayBanner:
- //
- // Displays the banner for JView.exe
- //
- // Returns: Nothing
- //------------------------------------------------------------------------------
- VOID CJView::m_DisplayBanner ()
- {
- CHAR sz[BUFSIZE];
-
- LoadStringX(NULL, IDS_BANNER1, sz, sizeof(sz));
- WriteConsolePrintf(STD_OUTPUT_HANDLE, sz,
- HIBYTE(HIWORD(VER_PRODUCTVERSION_DW)),
- LOBYTE(HIWORD(VER_PRODUCTVERSION_DW)),
- LOWORD(VER_PRODUCTVERSION_DW));
- LoadStringX(NULL, IDS_BANNER2, sz, sizeof(sz));
- WriteConsolePrintf(STD_OUTPUT_HANDLE, sz, VER_LAST_COPYRIGHT_YEAR);
- }
-
- #endif
-
-
- //------------------------------------------------------------------------------
- // 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.
- //
- // To host activex controls, this is required.
- //
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return (UINT) (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;
-
- #ifndef APPLETVIEWER
- // If no properties defined or not running the applet viewer, bail.
- if ( !m_pProperties && !m_fApplet )
- return S_OK;
- #endif
-
- // Query for the IJavaExecute2 interface off of the existing
- // IJavaExecute interface.
- if (m_pJE->QueryInterface(IID_IJavaExecute2, (LPVOID*)&pije2) == S_OK)
- {
- if (m_fApplet)
- {
- CEnumResourceJAVAPROPERTY *perjp =
- new CEnumResourceJAVAPROPERTY(g_AppletViewerProperties,
- ARRAY_ELEMENTS(g_AppletViewerProperties));
-
- hr = pije2->SetSystemProperties((IEnumJAVAPROPERTY *) perjp);
- perjp->Release();
- }
- else
- {
- hr = S_OK;
- }
-
- #ifndef APPLETVIEWER
- if (hr == S_OK && m_pProperties)
- {
- // We found IJavaExecute2, set the system properties.
- hr = pije2->SetSystemProperties( (IEnumJAVAPROPERTY *)m_pProperties);
- }
- #endif
-
- pije2->Release();
- }
- else
- {
- // If the QI failed, this current VM does not support IJavaExecute2
- hr = E_FAIL;
- 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 = (JEIF_ACTIVEXDEBUG |
- JEIF_DEBUGGEE_SHUTDOWN_ON_RELEASE |
- #if !defined(NO_CONSOLE) && !defined(APPLETVIEWER)
- JEIF_PRINTUNHANDLEDSTACKTRACE |
- #endif
- (m_fVerify ? JEIF_VERIFYCLASSES : 0) |
- (m_fApplet ? JEIF_INSTALLSTANDARDSECURITY : 0) |
- (m_fVerboseStackTraces ? JEIF_VERBOSESTACKTRACES : 0)
- );
- #ifdef APPLETVIEWER
- jei.pszClassName = APPLETVIEWER_CLASS;
- #else
- jei.pszClassName = pszClassName;
- #endif
-
- if ( m_fApplet )
- jei.dwFlags = jei.dwFlags | JEIF_APPLETVIEWER;
-
- jei.rgszArgs = (LPCOLESTR *)(m_ppszArgs);
- jei.cArgs = m_iArgs;
- jei.pszClassPath = pszClassPath;
- jei.pszNamespace = m_pszNamespace;
-
- if (jei.pszNamespace != NULL)
- jei.dwFlags |= JEIF_NAMESPACE_SPECIFIED;
-
- HRESULT hr = m_pJE->Execute(&jei, ppIErrorInfo);
-
- deleteSZ(pszClassPath);
- deleteSZ(pszClassName);
- return hr;
- }
-
-
- //------------------------------------------------------------------------
-
- #ifdef PROFILER_HOOK
-
- class ProfilerFactory : public IClassFactory
- {
- IJVIEWProfiler *m_pProfiler;
- ULONG m_refcount;
-
- public:
-
- ProfilerFactory (IJVIEWProfiler *pProfiler)
- {
- (m_pProfiler = pProfiler)->AddRef();
- m_refcount = 1;
- }
-
- ~ProfilerFactory ()
- {
- m_pProfiler->Release();
- }
-
-
- // IUnknown methods
-
- STDMETHODIMP QueryInterface (REFIID riid, void **ppv)
- {
- if ( riid == IID_IClassFactory
- || riid == IID_IUnknown)
- {
- *ppv = (IClassFactory*)this;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- AddRef();
- return S_OK;
- }
-
- STDMETHODIMP_(ULONG) AddRef ()
- {
- return InterlockedIncrement((LONG*)&m_refcount);
- }
-
- STDMETHODIMP_(ULONG) Release ()
- {
- ULONG refcount = (ULONG)InterlockedIncrement((LONG*)&m_refcount);
- if (!refcount)
- delete this;
- return refcount;
- }
-
-
- // IClassFactory methods
-
- STDMETHODIMP CreateInstance (LPUNKNOWN punkOuter, REFIID riid, void **ppv)
- {
- return !punkOuter ? m_pProfiler->QueryInterface(riid, ppv) : CLASS_E_NOAGGREGATION;
- }
-
- STDMETHODIMP LockServer (BOOL)
- {
- return E_NOTIMPL;
- }
- };
-
-
- HRESULT AppendEnvironmentVariable (PCSTR varname, PCSTR delim, PCSTR cat)
- {
- CHAR buf[256];
- PSTR pbuf = &buf[0];
- unsigned bufsize = sizeof(buf);
- DWORD len;
- unsigned delimlen = strlen(delim);
- unsigned catlen = strlen(cat);
- unsigned extraneeded = delimlen+catlen+1;
-
- while (1)
- {
- len = GetEnvironmentVariable(varname, pbuf, bufsize);
- if (len < bufsize)
- break;
- mkbuf:
- bufsize = len+extraneeded;
- pbuf = new CHAR[bufsize];
- if (pbuf == NULL)
- return E_OUTOFMEMORY;
- }
-
- if (len+extraneeded > bufsize)
- goto mkbuf;
-
- if (len == 0)
- delimlen = 0;
-
- CopyMemory(pbuf+len, delim, delimlen);
- CopyMemory(pbuf+len+delimlen, cat, catlen+1);
-
- BOOL result = SetEnvironmentVariable(varname, pbuf);
-
- if (pbuf != &buf[0])
- delete pbuf;
-
- return result ? S_OK : E_FAIL;
- }
-
- #endif // PROFILER_HOOK
-
-
- //------------------------------------------------------------------------------
- // 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 (FAILED(CoInitialize(NULL)))
- return iResult;
-
- if (pJV->ParseCommandLine())
- {
- HRESULT hr = S_OK;
- LPERRORINFO pIErrorInfo = NULL;
- char *classnameext = NULL;
-
- #ifndef APPLETVIEWER
-
- // 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))
- {
- if ( 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;
-
- if (len > classext1len)
- {
- char *ext = pJV->m_pszClassName+len-classext1len;
-
- if (lstrcmpi(ext, classext1) == 0)
- {
- // Truncate at extension.
-
- *ext = '\0';
- classnameext = ext;
- }
- else
- {
- // Try the full extension.
-
- ext -= classext2len-classext1len;
-
- if (lstrcmpi(ext, classext2) == 0)
- {
- *ext = '\0';
- classnameext = ext;
- }
- }
- }
-
- #endif
-
- #ifdef PROFILER_HOOK
- if (pJV->m_fEnableProfiling)
- {
- hr = AppendEnvironmentVariable("MSJAVA_EVENT_MONITORS", ";", CLSIDSTR_JVIEWEventMonitor);
-
- if (hr == S_OK)
- {
- hr = SetEnvironmentVariable("MSJAVA_ENABLE_MONITORS", "1") ? S_OK : E_FAIL;
- }
-
- if (hr == S_OK)
- {
- ProfilerFactory *pfact = new ProfilerFactory(pJV->m_pProfiler);
- if (pfact)
- {
- IUnknown *punkfact;
- if (pfact->QueryInterface(IID_IUnknown, (PVOID*)&punkfact) == S_OK)
- {
- DWORD dwRegister;
-
- hr = CoRegisterClassObject(
- CLSID_JVIEWEventMonitor,
- punkfact,
- CLSCTX_INPROC_SERVER,
- REGCLS_MULTIPLEUSE,
- &dwRegister);
-
- punkfact->Release();
- }
-
- pfact->Release();
- }
- else
- {
- hr = E_OUTOFMEMORY;
- }
- }
-
- if (hr != S_OK)
- FatalError(IDS_COULDNOTREGPROF);
- }
- #endif
-
- if (hr == S_OK)
- {
- // 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 (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)
- {
- CharToOemX((pszError, pszError));
- FatalError (0, pszError);
- deleteSZ(pszError);
- }
- else
- FatalError (IDS_UNKNOWNERROR);
-
- SysFreeString(bstrError);
- }
- else
- FatalError(IDS_UNKNOWNERROR);
-
- iResult = 1;
-
- pIErrorInfo->Release();
- }
- else if (!SUCCEEDED(hr))
- {
- // We're about to exit, so we don't have to worry about
- // losing information in the ANSI to OEM conversion.
- CharToOemX((pJV->m_pszClassName, pJV->m_pszClassName));
-
- // Most likely .class file did not exist
- FatalErrorHR (hr, IDS_EXECUTINGCLASS, pJV->m_pszClassName);
- iResult = 1;
- }
- else
- // Success.
- iResult = 0;
- }
- }
-
- #ifdef PROFILER_HOOK
- if (pJV->m_pProfiler)
- {
- pJV->m_pProfiler->Shutdown();
- }
- #endif
-
- // Terminate message pump
- PostThreadMessage(pJV->m_dwMsgLoopThreadID, WM_QUIT, 0, 0);
-
- CoUninitialize();
-
- return (DWORD)iResult;
- }
-
- //------------------------------------------------------------------------------
- // main - Entry point for JView
- //
- // Returns: 0 if successful, 1 if not
- //------------------------------------------------------------------------------
-
-
- #ifdef NO_CONSOLE
- int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
- {
- int argc = __argc;
- char **argv = __argv;
- #else
- int __cdecl main (int argc, char *argv[])
- {
- #endif
- int iRet = 1;
- CJView* pJV;
-
- pJV = new CJView(argc, argv);
-
- if (!pJV)
- {
- FatalError(IDS_OUTOFMEMORY);
- goto exit;
- }
-
- 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
- {
- FatalErrorHR(LAST_WIN32_ERROR_TO_HRESULT(),
- IDS_NOJAVATHREAD);
- }
- }
-
- delete pJV;
-
- exit:
- ExitProcess(iRet);
- return iRet;
- }
-
- //
- // Loads a resource and returns a pointer to the raw resource data.
- // We add some additional language search order semantics on top
- // of the standard FindResourceEx behavior:
- //
- // I've seen different behavior between NT and Win9x when the
- // specified language is LANG_SYSTEM_DEFAULT or LANG_USER_DEFAULT.
- // We manually expand either of these language specifiers to
- // the current system values from either GetXDefaultLangID.
- //
- // If we don't find a resource with the specified language, we
- // explicitly fall back to US/English and reattempt the search.
- //
-
- LPVOID VMGetResource(
- HINSTANCE hModule,
- LPCTSTR lpType,
- LPCTSTR lpName,
- LANGID wLanguage)
- {
- HRSRC hResource = NULL;
- HGLOBAL hLoadedResource = NULL;
-
- if ( wLanguage == LANG_SYSTEM_DEFAULT )
- wLanguage = GetSystemDefaultLangID();
- else if ( wLanguage == LANG_USER_DEFAULT )
- wLanguage = GetUserDefaultLangID();
-
- hResource = FindResourceEx(hModule,lpType,lpName,wLanguage);
-
- if ( hResource )
- hLoadedResource = LoadResource(hModule,hResource);
-
- if ( !hLoadedResource )
- {
- wLanguage = MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US);
-
- hResource = FindResourceEx(hModule,lpType,lpName,wLanguage);
-
- if ( hResource )
- hLoadedResource = LoadResource(hModule,hResource);
- }
-
- return (LPVOID)hLoadedResource;
- }
-
- //
- // LoadString variation with better control over which language
- // will be selected.
- //
- // The language search order is not consistent between Win95 and
- // NT with the LoadString API, and neither of them really give us
- // the control that we want. The language search order that this
- // function will use is roughly:
- //
- // 1. An exact primary/sub language match.
- // 2. A primary language match.
- // 3. English.
- //
- // We manually grok the resource table resources here. Each
- // resource table contains 16 entries, some of which may contain
- // empty strings. All strings are Unicode, are length prefixed
- // with a WORD containing the number of Unicode characters in the
- // string, and are NOT null terminated.
- //
- // Note that this is mostly a copy of the real LoadString from the
- // Win95 kernel.
- //
-
- INT VMLoadString(
- HINSTANCE hModule,
- UINT wStringID,
- LPSTR pszBuffer,
- int cchBufferMax,
- WORD wLanguage)
- {
- LPWSTR pwsz = NULL;
- int cb = 0;
- int cch;
-
- if ( !pszBuffer || (cchBufferMax-- == 0) )
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- // Transform the string ID into the corresponding
- // StringTable ID.
-
- LPCSTR TableID = (LPCTSTR)((LONG)(((USHORT)(wStringID) >> 4) + 1));
-
- cch = 0;
- pwsz = (LPWSTR)VMGetResource(hModule,RT_STRING,TableID,wLanguage);
-
- if ( pwsz )
- {
- __try
- {
- wStringID &= 0x0F;
-
- while ( TRUE )
- {
- cch = *(pwsz++);
-
- if ( wStringID-- == 0 )
- break;
-
- pwsz += cch;
- }
-
- if ( cch > cchBufferMax )
- cch = cchBufferMax;
-
- cb = WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,pwsz,cch,
- pszBuffer,cchBufferMax,NULL,NULL);
- }
- __except( EXCEPTION_EXECUTE_HANDLER )
- {
- SetLastError(ERROR_BAD_FORMAT);
- }
- }
-
- pszBuffer[cb] = '\0';
-
- return cb;
- }
-
-
-