Index: trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.cpp	(revision 95824)
+++ trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.cpp	(revision 95827)
@@ -21,4 +21,5 @@
 #include <iprt/alloca.h>
 #include <iprt/system.h>
+#include <iprt/utf16.h>
 #include <VBox/Log.h>
 #include <VBox/VBoxGuestLib.h>
@@ -331,2 +332,44 @@
 }
 
+/**
+ * Shows a message box with a printf() style formatted string.
+ *
+ * @param   pszTitle            Title of the message box.
+ * @param   uStyle              Style of message box to use (see MSDN, MB_ defines).
+ *                              When 0 is specified, MB_ICONINFORMATION will be used.
+ * @param   pszFmt              Printf-style format string to show in the message box body.
+ * @param   ...                 Arguments for format string.
+ */
+void hlpShowMessageBox(const char *pszTitle, UINT uStyle, const char *pszFmt, ...)
+{
+    if (!uStyle)
+        uStyle = MB_ICONINFORMATION;
+
+    char       *pszMsg;
+    va_list     va;
+    va_start(va, pszFmt);
+    int rc = RTStrAPrintfV(&pszMsg, pszFmt, va);
+    va_end(va);
+    if (rc >= 0)
+    {
+        PRTUTF16 pwszTitle;
+        rc = RTStrToUtf16(pszTitle, &pwszTitle);
+        if (RT_SUCCESS(rc))
+        {
+            PRTUTF16 pwszMsg;
+            rc = RTStrToUtf16(pszMsg, &pwszMsg);
+            if (RT_SUCCESS(rc))
+            {
+                MessageBoxW(GetDesktopWindow(), pwszMsg, pwszTitle, uStyle);
+                RTUtf16Free(pwszMsg);
+            }
+            else
+                MessageBoxA(GetDesktopWindow(), pszMsg, pszTitle, uStyle);
+            RTUtf16Free(pwszTitle);
+        }
+    }
+    else /* Should never happen! */
+        AssertMsgFailed(("Failed to format error text of format string: %s!\n", pszFmt));
+    RTStrFree(pszMsg);
+}
+
Index: trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.h	(revision 95824)
+++ trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHelpers.h	(revision 95827)
@@ -24,4 +24,5 @@
 // #define DEBUG_DISPLAY_CHANGE
 
+/** @todo r=andy WTF? Remove this!! */
 #ifdef DEBUG_DISPLAY_CHANGE
 #   define DDCLOG(a) Log(a)
@@ -30,8 +31,9 @@
 #endif /* !DEBUG_DISPLAY_CHANGE */
 
-extern int hlpReportStatus(VBoxGuestFacilityStatus statusCurrent);
+extern int  hlpReportStatus(VBoxGuestFacilityStatus statusCurrent);
 extern void hlpReloadCursor(void);
 extern void hlpResizeRect(RECTL *paRects, unsigned nRects, unsigned uPrimary, unsigned uResized, int iNewWidth, int iNewHeight, int iNewPosX, int iNewPosY);
-extern int hlpShowBalloonTip(HINSTANCE hInst, HWND hWnd, UINT uID, const char *pszMsg, const char *pszTitle, UINT uTimeout, DWORD dwInfoFlags);
+extern int  hlpShowBalloonTip(HINSTANCE hInst, HWND hWnd, UINT uID, const char *pszMsg, const char *pszTitle, UINT uTimeout, DWORD dwInfoFlags);
+extern void hlpShowMessageBox(const char *pszTitle, UINT uStyle, const char *pszFmt, ...);
 
 #endif /* !GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxHelpers_h */
Index: trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp	(revision 95824)
+++ trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp	(revision 95827)
@@ -42,9 +42,12 @@
 #include <iprt/asm.h>
 #include <iprt/buildconfig.h>
+#include <iprt/getopt.h>
 #include <iprt/ldr.h>
+#include <iprt/message.h>
 #include <iprt/path.h>
 #include <iprt/process.h>
 #include <iprt/system.h>
 #include <iprt/time.h>
+#include <iprt/utf16.h>
 
 #include <VBox/log.h>
@@ -132,4 +135,5 @@
 *   Global Variables                                                                                                             *
 *********************************************************************************************************************************/
+int                   g_cVerbosity             = 0;
 HANDLE                g_hStopSem;
 HANDLE                g_hSeamlessWtNotifyEvent = 0;
@@ -559,40 +563,53 @@
 /**
  * Creates the default release logger outputting to the specified file.
- * Pass NULL for disabled logging.
  *
  * @return  IPRT status code.
+ * @param   pszLogFile          Path to log file to use.
  */
-static int vboxTrayLogCreate(void)
+static int vboxTrayLogCreate(const char *pszLogFile)
 {
     /* Create release (or debug) logger (stdout + file). */
     static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
-#ifdef DEBUG /* See below, debug logger not release. */
-    static const char s_szEnvVarPfx[] = "VBOXTRAY_LOG";
-    static const char s_szGroupSettings[] = "all.e.l.f";
-#else
     static const char s_szEnvVarPfx[] = "VBOXTRAY_RELEASE_LOG";
-    static const char s_szGroupSettings[] = "all";
-#endif
+
     RTERRINFOSTATIC ErrInfo;
     int rc = RTLogCreateEx(&g_pLoggerRelease, s_szEnvVarPfx,
                            RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG | RTLOGFLAGS_USECRLF,
-                           s_szGroupSettings, RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX,
+                           "all.e", RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX,
                            0 /*cBufDescs*/, NULL /*paBufDescs*/, RTLOGDEST_STDOUT,
                            vboxTrayLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
                            NULL /*pOutputIf*/, NULL /*pvOutputIfUser*/,
-                           RTErrInfoInitStatic(&ErrInfo), NULL /*pszFilenameFmt*/);
+                           RTErrInfoInitStatic(&ErrInfo), "%s", pszLogFile ? pszLogFile : "");
     if (RT_SUCCESS(rc))
     {
-#ifdef DEBUG
-        /* Register this logger as the _debug_ logger.
-           Note! This means any Log() statement preceeding this may cause a
-                 20yy-*VBoxTray*.log file to have been created and it will stay
-                 open till the process quits as we don't destroy it when
-                 replacing it here. */
-        RTLogSetDefaultInstance(g_pLoggerRelease);
-#else
         /* Register this logger as the release logger. */
         RTLogRelSetDefaultInstance(g_pLoggerRelease);
-#endif
+
+        /* Register this logger as the _debug_ logger. */
+        RTLogSetDefaultInstance(g_pLoggerRelease);
+
+        switch (g_cVerbosity) /* Not very elegant, but has to do it for now. */
+        {
+            case 1:
+                rc = RTLogGroupSettings(g_pLoggerRelease, "all.e.l");
+                break;
+
+            case 2:
+                rc = RTLogGroupSettings(g_pLoggerRelease, "all.e.l.l2");
+                break;
+
+            case 3:
+                rc = RTLogGroupSettings(g_pLoggerRelease, "all.e.l.l2.l3");
+                break;
+
+            case 4:
+                RT_FALL_THROUGH();
+            default:
+                rc = RTLogGroupSettings(g_pLoggerRelease, "all.e.l.l2.l3.f");
+                break;
+        }
+        if (RT_FAILURE(rc))
+            RTMsgError("Setting debug logging failed, rc=%Rrc\n", rc);
+
         /* Explicitly flush the log in case of VBOXTRAY_RELEASE_LOG=buffered. */
         RTLogFlush(g_pLoggerRelease);
@@ -985,11 +1002,111 @@
 {
     RT_NOREF(hPrevInstance, lpCmdLine, nCmdShow);
-    int rc = RTR3InitExeNoArguments(0);
+
+    int rc = RTR3InitExe(__argc, &__argv, RTR3INIT_FLAGS_STANDALONE_APP);
     if (RT_FAILURE(rc))
-        return RTEXITCODE_INIT;
+        return RTMsgInitFailure(rc);
+
+    LPWSTR pwszCmdLine = GetCommandLineW();
+    if (!pwszCmdLine)
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "GetCommandLineW failed");
+
+    char *pszCmdLine;
+    rc = RTUtf16ToUtf8(pwszCmdLine, &pszCmdLine); /* leaked */
+    if (RT_FAILURE(rc))
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to convert the command line: %Rrc", rc);
+
+    char szLogFile[RTPATH_MAX] = {0};
+
+    int    cArgs;
+    char **papszArgs;
+    rc = RTGetOptArgvFromString(&papszArgs, &cArgs, pszCmdLine, RTGETOPTARGV_CNV_QUOTE_MS_CRT, NULL);
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Parse the top level arguments until we find a command.
+         */
+        static const RTGETOPTDEF s_aOptions[] =
+        {
+            { "--help",             'h',                         RTGETOPT_REQ_NOTHING },
+            { "-help",              'h',                         RTGETOPT_REQ_NOTHING },
+            { "/help",              'h',                         RTGETOPT_REQ_NOTHING },
+            { "/?",                 'h',                         RTGETOPT_REQ_NOTHING },
+            { "--logfile",          'l',                         RTGETOPT_REQ_STRING  },
+            { "-l",                 'l',                         RTGETOPT_REQ_STRING  },
+            { "/l",                 'l',                         RTGETOPT_REQ_STRING  },
+            { "--verbose",          'v',                         RTGETOPT_REQ_NOTHING },
+            { "-v",                 'v',                         RTGETOPT_REQ_NOTHING },
+            { "/v",                 'v',                         RTGETOPT_REQ_NOTHING },
+            { "--version",          'V',                         RTGETOPT_REQ_NOTHING },
+            { "-version",           'V',                         RTGETOPT_REQ_NOTHING },
+            { "/version",           'V',                         RTGETOPT_REQ_NOTHING },
+            { "/V",                 'V',                         RTGETOPT_REQ_NOTHING }
+        };
+
+        RTGETOPTSTATE GetState;
+        rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/);
+        if (RT_FAILURE(rc))
+            return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc\n", rc);
+
+        int ch;
+        RTGETOPTUNION ValueUnion;
+        while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0)
+        {
+            switch (ch)
+            {
+                case 'h':
+                    hlpShowMessageBox(VBOX_VBOXTRAY_TITLE, MB_ICONINFORMATION, "-- %s v%u.%u.%ur%u --\n"
+                         "\n"
+                         "Command Line Parameters:\n\n"
+                         "-l, --logfile <file>\n"
+                         "    Enables logging to a file\n"
+                         "-v, --verbose\n"
+                         "    Increases verbosity\n"
+                         "-V, --version\n"
+                         "   Displays version number and exit\n"
+                         "-?, -h, --help\n"
+                         "   Displays this help text and exit\n"
+                         "\n"
+                         "Examples:\n"
+                         "  %s -vvv\n",
+                         VBOX_VBOXTRAY_TITLE, VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD, VBOX_SVN_REV,
+                         papszArgs[0], papszArgs[0]);
+                    return RTEXITCODE_SUCCESS;
+
+                case 'l':
+                    if (*ValueUnion.psz == '\0')
+                        szLogFile[0] = '\0';
+                    else
+                    {
+                        rc = RTPathAbs(ValueUnion.psz, szLogFile, sizeof(szLogFile));
+                        if (RT_FAILURE(rc))
+                            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Log file path is too long (%Rrc)", rc);
+                    }
+                    break;
+
+                case 'v':
+                    g_cVerbosity++;
+                    break;
+
+                case 'V':
+                    hlpShowMessageBox(VBOX_VBOXTRAY_TITLE, MB_ICONINFORMATION,
+                                      "Version: %u.%u.%ur%u",
+                                      VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD, VBOX_SVN_REV);
+                    return RTEXITCODE_SUCCESS;
+
+                default:
+                    rc = RTGetOptPrintError(ch, &ValueUnion);
+                    break;
+            }
+        }
+
+        RTGetOptArgvFree(papszArgs);
+    }
+    else
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptArgvFromString failed: %Rrc", rc);
 
     /* Note: Do not use a global namespace ("Global\\") for mutex name here,
      * will blow up NT4 compatibility! */
-    HANDLE hMutexAppRunning = CreateMutex(NULL, FALSE, "VBoxTray");
+    HANDLE hMutexAppRunning = CreateMutex(NULL, FALSE, VBOX_VBOXTRAY_TITLE);
     if (   hMutexAppRunning != NULL
         && GetLastError() == ERROR_ALREADY_EXISTS)
@@ -998,12 +1115,12 @@
         CloseHandle (hMutexAppRunning);
         hMutexAppRunning = NULL;
-        return 0;
-    }
-
-    LogRel(("%s r%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()));
-
-    rc = vboxTrayLogCreate();
+        return RTEXITCODE_SUCCESS;
+    }
+
+    rc = vboxTrayLogCreate(szLogFile[0] ? szLogFile : NULL);
     if (RT_SUCCESS(rc))
     {
+        LogRel(("Verbosity level: %d\n", g_cVerbosity));
+
         rc = VbglR3Init();
         if (RT_SUCCESS(rc))
@@ -1154,7 +1271,9 @@
                 case WM_LBUTTONDBLCLK:
                     break;
-#ifdef DEBUG
                 case WM_RBUTTONDOWN:
                 {
+                    if (!g_cVerbosity) /* Don't show menu when running in non-verbose mode. */
+                        break;
+
                     POINT lpCursor;
                     if (GetCursorPos(&lpCursor))
@@ -1192,5 +1311,4 @@
                     break;
                 }
-#endif
             }
             return 0;
Index: trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.h	(revision 95824)
+++ trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.h	(revision 95827)
@@ -39,4 +39,12 @@
 #include "VBoxDispIf.h"
 
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+/** Title of the program to show. 
+ *  Also shown as part of message boxes. */
+#define VBOX_VBOXTRAY_TITLE                     "VBoxTray"
+
 /*
  * Windows messsages.
@@ -58,4 +66,9 @@
 #define TIMERID_VBOXTRAY_DT_TIMER               1002
 #define TIMERID_VBOXTRAY_ST_DELAYED_INIT_TIMER  1003
+
+
+/*********************************************************************************************************************************
+*   Common structures                                                                                                            *
+*********************************************************************************************************************************/
 
 /**
@@ -123,15 +136,4 @@
 } VBOXSERVICEDESC, *PVBOXSERVICEDESC;
 
-extern VBOXSERVICEDESC g_SvcDescDisplay;
-#ifdef VBOX_WITH_SHARED_CLIPBOARD
-extern VBOXSERVICEDESC g_SvcDescClipboard;
-#endif
-extern VBOXSERVICEDESC g_SvcDescSeamless;
-extern VBOXSERVICEDESC g_SvcDescVRDP;
-extern VBOXSERVICEDESC g_SvcDescIPC;
-extern VBOXSERVICEDESC g_SvcDescLA;
-#ifdef VBOX_WITH_DRAG_AND_DROP
-extern VBOXSERVICEDESC g_SvcDescDnD;
-#endif
 
 /**
@@ -174,4 +176,21 @@
 } VBOXGLOBALMESSAGE, *PVBOXGLOBALMESSAGE;
 
+
+/*********************************************************************************************************************************
+*   Externals                                                                                                                    *
+*********************************************************************************************************************************/
+extern VBOXSERVICEDESC g_SvcDescDisplay;
+#ifdef VBOX_WITH_SHARED_CLIPBOARD
+extern VBOXSERVICEDESC g_SvcDescClipboard;
+#endif
+extern VBOXSERVICEDESC g_SvcDescSeamless;
+extern VBOXSERVICEDESC g_SvcDescVRDP;
+extern VBOXSERVICEDESC g_SvcDescIPC;
+extern VBOXSERVICEDESC g_SvcDescLA;
+#ifdef VBOX_WITH_DRAG_AND_DROP
+extern VBOXSERVICEDESC g_SvcDescDnD;
+#endif
+
+extern int          g_cVerbosity;
 extern HINSTANCE    g_hInstance;
 extern HWND         g_hwndToolWindow;
