Index: /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/Makefile.kmk	(revision 82624)
+++ /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/Makefile.kmk	(revision 82625)
@@ -31,8 +31,8 @@
 VBoxGuestInstallHelper_INST     = repack/resources/VBoxGuestInstallHelper/
 ifdef VBOX_SIGN_ADDITIONS # (See the parent makefile.)
- VBoxGuestInstallHelper_INSTTYPE = stage
+ VBoxGuestInstallHelper_INSTTYPE       = stage
  VBoxGuestInstallHelper_DEBUG_INSTTYPE = both
 endif
-VBoxGuestInstallHelper_DEFS     = _WIN32_WINNT=0x0400 WIN32_LEAN_AND_MEAN=1
+VBoxGuestInstallHelper_DEFS         = _WIN32_WINNT=0x0400 WIN32_LEAN_AND_MEAN=1 UNICODE _UNICODE
 VBoxGuestInstallHelper_BLD_TRG_ARCH = x86
 VBoxGuestInstallHelper_SOURCES  = \
@@ -41,3 +41,2 @@
 
 include $(FILE_KBUILD_SUB_FOOTER)
-
Index: /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp	(revision 82624)
+++ /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp	(revision 82625)
@@ -30,5 +30,5 @@
 #pragma warning(pop)
 
-#include <iprt/errcore.h>
+#include <iprt/err.h>
 #include <iprt/initterm.h>
 #include <iprt/ldr.h>
@@ -37,4 +37,7 @@
 #include <iprt/process.h>
 #include <iprt/string.h>
+#ifdef UNICODE
+# include <iprt/utf16.h>
+#endif
 
 /* Required structures/defines of VBoxTray. */
@@ -70,53 +73,58 @@
  * overflows, use vboxPopString() instead!
  *
- * @return  HRESULT
+ * @return  VBox status code.
  * @param   pszDest     Pointer to pre-allocated string to store result.
  * @param   cchDest     Size (in characters) of pre-allocated string.
  */
-static HRESULT vboxPopString(TCHAR *pszDest, size_t cchDest)
-{
-    HRESULT hr = S_OK;
+static int vboxPopString(TCHAR *pszDest, size_t cchDest)
+{
+    int rc = VINF_SUCCESS;
+
     if (!g_stacktop || !*g_stacktop)
-        hr = __HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
+    {
+        rc = VERR_NO_DATA;
+    }
     else
     {
         stack_t *pStack = (*g_stacktop);
-        if (pStack)
-        {
-            hr = StringCchCopy(pszDest, cchDest, pStack->text);
-            if (SUCCEEDED(hr))
-            {
-                *g_stacktop = pStack->next;
-                GlobalFree((HGLOBAL)pStack);
-            }
-        }
-        else
-            hr = __HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
-    }
-    return hr;
-}
-
-static HRESULT vboxPopULong(PULONG pulValue)
-{
-    HRESULT hr = S_OK;
-    if (!g_stacktop || !*g_stacktop)
-        hr = __HRESULT_FROM_WIN32(ERROR_EMPTY);
-    else
-    {
-        stack_t *pStack = (*g_stacktop);
-        if (pStack)
-        {
-            *pulValue = strtoul(pStack->text, NULL, 10 /* Base */);
-
+        AssertPtr(pStack);
+
+        HRESULT hr = StringCchCopy(pszDest, cchDest, pStack->text);
+        if (SUCCEEDED(hr))
+        {
             *g_stacktop = pStack->next;
             GlobalFree((HGLOBAL)pStack);
         }
-    }
-    return hr;
-}
-
-static void vboxPushResultAsString(HRESULT hr)
-{
-    TCHAR szErr[MAX_PATH + 1];
+        else
+            rc = VERR_INVALID_PARAMETER;
+    }
+    return rc;
+}
+
+static int vboxPopULong(PULONG pulValue)
+{
+    int rc = VINF_SUCCESS;
+
+    if (!g_stacktop || !*g_stacktop)
+    {
+        rc = VERR_NO_DATA;
+    }
+    else
+    {
+        stack_t *pStack = (*g_stacktop);
+        AssertPtr(pStack);
+
+        *pulValue = _tcstoul(pStack->text, NULL, 10 /* Base */);
+
+        *g_stacktop = pStack->next;
+        GlobalFree((HGLOBAL)pStack);
+    }
+
+    return rc;
+}
+
+static void vboxPushHResultAsString(HRESULT hr)
+{
+    TCHAR szErr[NSIS_MAX_STRLEN];
     if (FAILED(hr))
     {
@@ -125,8 +133,35 @@
         else
             StringCchPrintf(szErr, sizeof(szErr),
-                            "FormatMessage failed! Error = %ld", GetLastError());
+                            _T("FormatMessage failed! Error = %ld"), GetLastError());
     }
     else
-        StringCchPrintf(szErr, sizeof(szErr), "0");
+        StringCchPrintf(szErr, sizeof(szErr), _T("0"));
+    pushstring(szErr);
+}
+
+static void vboxPushRcAsString(int rc)
+{
+    TCHAR szErr[NSIS_MAX_STRLEN];
+    if (RT_FAILURE(rc))
+    {
+
+#ifdef UNICODE
+        TCHAR *pszErrAsString;
+        int rc2 = RTStrToUtf16(RTErrGetDefine(rc), &pszErrAsString);
+        if (RT_SUCCESS(rc2))
+        {
+#else
+            TCHAR *pszErrAsString = RTErrGetDefine(rc);
+#endif
+            StringCchPrintf(szErr, sizeof(szErr), _T("Error: %s"), pszErrAsString);
+
+#ifdef UNICODE
+            RTUtf16Free(pszErrAsString);
+        }
+#endif
+    }
+    else
+        StringCchPrintf(szErr, sizeof(szErr), _T("0"));
+
     pushstring(szErr);
 }
@@ -152,4 +187,5 @@
 }
 
+#ifndef UNICODE
 static void vboxChar2WCharFree(PWCHAR pwString)
 {
@@ -158,26 +194,29 @@
 }
 
-static HRESULT vboxChar2WCharAlloc(const char *pszString, PWCHAR *ppwString)
-{
-    HRESULT hr;
-    int iLen = (int)strlen(pszString) + 2;
+static int vboxChar2WCharAlloc(const TCHAR *pszString, PWCHAR *ppwString)
+{
+    int rc = VINF_SUCCESS;
+
+    int iLen = (int)_tcslen(pszString) + 2;
     WCHAR *pwString = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, iLen * sizeof(WCHAR));
     if (!pwString)
-        hr = __HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
+    {
+        rc = VERR_NO_MEMORY;
+    }
     else
     {
         if (MultiByteToWideChar(CP_ACP, 0, pszString, -1, pwString, iLen) == 0)
         {
-            hr = HRESULT_FROM_WIN32(GetLastError());
+            rc = VERR_INVALID_PARAMETER;
             HeapFree(GetProcessHeap(), 0, pwString);
         }
         else
         {
-            hr = S_OK;
             *ppwString = pwString;
         }
     }
-    return hr;
-}
+    return rc;
+}
+#endif /* !UNICODE */
 
 /**
@@ -217,6 +256,6 @@
 
     TCHAR szFile[MAX_PATH + 1];
-    HRESULT hr = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR));
-    if (SUCCEEDED(hr))
+    int rc = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR));
+    if (RT_SUCCESS(rc))
     {
         HMODULE hSFC = loadSystemDll("sfc_os.dll"); /** @todo Replace this by RTLdr APIs. */
@@ -230,20 +269,26 @@
                 g_pfnSfcFileException = (PFNSFCFILEEXCEPTION)GetProcAddress(hSFC, (LPCSTR)5);
                 if (g_pfnSfcFileException == NULL)
-                    hr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
+                    rc = VERR_SYMBOL_NOT_FOUND;
             }
         }
         else
-            hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
-
-        if (SUCCEEDED(hr))
-        {
+            rc = VERR_FILE_NOT_FOUND;
+
+        if (RT_SUCCESS(rc))
+        {
+#ifndef UNICODE
             WCHAR *pwszFile;
-            hr = vboxChar2WCharAlloc(szFile, &pwszFile);
-            if (SUCCEEDED(hr))
+            rc = vboxChar2WCharAlloc(szFile, &pwszFile);
+            if (RT_SUCCESS(rc))
             {
+#else
+            TCHAR *pwszFile = szFile;
+#endif
                 if (g_pfnSfcFileException(0, pwszFile, UINT32_MAX) != 0)
-                    hr = HRESULT_FROM_WIN32(GetLastError());
+                    rc = VERR_ACCESS_DENIED; /** @todo Find a better rc. */
+#ifndef UNICODE
                 vboxChar2WCharFree(pwszFile);
             }
+#endif
         }
 
@@ -252,5 +297,5 @@
     }
 
-    vboxPushResultAsString(hr);
+    vboxPushRcAsString(rc);
 }
 
@@ -273,44 +318,51 @@
 
     TCHAR szFile[MAX_PATH + 1];
-    HRESULT hr = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR));
-    if (SUCCEEDED(hr))
-    {
-        RTLDRMOD hLdrMod;
-        int rc = RTLdrOpen(szFile, RTLDR_O_FOR_VALIDATION, RTLDRARCH_WHATEVER, &hLdrMod);
+    int rc = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR));
+    if (RT_SUCCESS(rc))
+    {
+#ifdef UNICODE
+        char *pszFileUtf8;
+        int rc = RTUtf16ToUtf8(szFile, &pszFileUtf8);
         if (RT_SUCCESS(rc))
         {
-            if (RTLdrGetFormat(hLdrMod) == RTLDRFMT_PE)
+#else
+            char *pszFileUtf8 = szFile;
+#endif
+            RTLDRMOD hLdrMod;
+            rc = RTLdrOpen(pszFileUtf8, RTLDR_O_FOR_VALIDATION, RTLDRARCH_WHATEVER, &hLdrMod);
+            if (RT_SUCCESS(rc))
             {
-                RTLDRARCH enmLdrArch = RTLdrGetArch(hLdrMod);
-                switch (enmLdrArch)
+                if (RTLdrGetFormat(hLdrMod) == RTLDRFMT_PE)
                 {
-                    case RTLDRARCH_X86_32:
-                        pushstring("x86");
-                        break;
-
-                    case RTLDRARCH_AMD64:
-                        pushstring("amd64");
-                        break;
-
-                    default:
-                        pushstring("Error: Unknown / invalid architecture");
-                        break;
+                    RTLDRARCH enmLdrArch = RTLdrGetArch(hLdrMod);
+                    switch (enmLdrArch)
+                    {
+                        case RTLDRARCH_X86_32:
+                            pushstring(_T("x86"));
+                            break;
+
+                        case RTLDRARCH_AMD64:
+                            pushstring(_T("amd64"));
+                            break;
+
+                        default:
+                            pushstring(_T("Error: Unknown / invalid architecture"));
+                            break;
+                    }
                 }
+                else
+                    pushstring(_T("Error: Unknown / invalid PE signature"));
+
+                RTLdrClose(hLdrMod);
             }
             else
-                pushstring("Error: Unknown / invalid PE signature");
-
-            RTLdrClose(hLdrMod);
-        }
-        else
-        {
-            char szMsg[64];
-            RTStrPrintf(szMsg, sizeof(szMsg), "Error: Could not open file: %Rrc", rc);
-
-            pushstring(szMsg);
-        }
+                pushstring(_T("Error: Could not open file"));
+#ifdef UNICODE
+            RTStrFree(pszFileUtf8);
+        }
+#endif
     }
     else
-        vboxPushResultAsString(hr);
+        pushstring(_T("Error: Could not retrieve file name"));
 }
 
@@ -333,6 +385,6 @@
 
     TCHAR szFile[MAX_PATH + 1];
-    HRESULT hr = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR));
-    if (SUCCEEDED(hr))
+    int rc = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR));
+    if (RT_SUCCESS(rc))
     {
         DWORD dwInfoSize = GetFileVersionInfoSize(szFile, NULL /* lpdwHandle */);
@@ -353,30 +405,29 @@
 
                         TCHAR szQuery[MAX_PATH];
-#pragma warning(suppress:4995) /* warning C4995: '_sntprintf': name was marked as #pragma deprecated */
-                        _sntprintf(szQuery, sizeof(szQuery), _T("StringFileInfo\\%04X%04X\\CompanyName"),
-                                   wCodePage,wLanguageID);
+                        StringCchPrintf(szQuery, sizeof(szQuery), _T("StringFileInfo\\%04X%04X\\CompanyName"),
+                                        wCodePage, wLanguageID);
 
                         LPCTSTR pcData;
-                        if (VerQueryValue(pFileInfo, szQuery,(void**)&pcData, &puInfoLen))
+                        if (VerQueryValue(pFileInfo, szQuery, (void**)&pcData, &puInfoLen))
                         {
                             pushstring(pcData);
                         }
                         else
-                            hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
+                            rc = VERR_NOT_FOUND;
                     }
                     else
-                        hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
+                        rc = VERR_NOT_FOUND;
                 }
                 GlobalFree(pFileInfo);
             }
             else
-                hr = __HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
+                rc = VERR_NO_MEMORY;
         }
         else
-            hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
-    }
-
-    if (FAILED(hr))
-        vboxPushResultAsString(hr);
+            rc = VERR_NOT_FOUND;
+    }
+
+    if (RT_FAILURE(rc))
+        vboxPushRcAsString(rc);
 }
 
@@ -398,9 +449,11 @@
     EXDLL_INIT();
 
-    char szMsg[256];
-    char szTitle[128];
-    HRESULT hr = vboxPopString(szMsg, sizeof(szMsg) / sizeof(char));
+    int rc = VINF_SUCCESS;
+
+    TCHAR szMsg[256];
+    TCHAR szTitle[128];
+    HRESULT hr = vboxPopString(szMsg, sizeof(szMsg) / sizeof(TCHAR));
     if (SUCCEEDED(hr))
-        hr = vboxPopString(szTitle, sizeof(szTitle) / sizeof(char));
+        hr = vboxPopString(szTitle, sizeof(szTitle) / sizeof(TCHAR));
 
     /** @todo Do we need to restore the stack on failure? */
@@ -410,52 +463,60 @@
         RTR3InitDll(0);
 
-        uint32_t cbMsg = sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG)
-                       + (uint32_t)strlen(szMsg)   + 1  /* Include terminating zero */
-                       + (uint32_t)strlen(szTitle) + 1; /* Ditto. */
-        Assert(cbMsg);
-        PVBOXTRAYIPCMSG_SHOWBALLOONMSG pIpcMsg =
-            (PVBOXTRAYIPCMSG_SHOWBALLOONMSG)RTMemAlloc(cbMsg);
-        if (pIpcMsg)
-        {
-            /* Stuff in the strings. */
-            memcpy(pIpcMsg->szMsgContent, szMsg, strlen(szMsg)   + 1);
-            memcpy(pIpcMsg->szMsgTitle, szTitle, strlen(szTitle) + 1);
-
-            /* Pop off the values in reverse order from the stack. */
-            if (SUCCEEDED(hr))
-                hr = vboxPopULong((ULONG*)&pIpcMsg->uType);
-            if (SUCCEEDED(hr))
-                hr = vboxPopULong((ULONG*)&pIpcMsg->uShowMS);
-
-            if (SUCCEEDED(hr))
+#ifdef UNICODE
+        char *pszMsgUtf8   = NULL;
+        char *pszTitleUtf8 = NULL;
+        rc = RTUtf16ToUtf8(szMsg, &pszMsgUtf8);
+        if (RT_SUCCESS(rc))
+            rc = RTUtf16ToUtf8(szTitle, &pszTitleUtf8);
+#else
+        char *pszMsgUtf8   = szMsg;
+        char *pszTitleUtf8 = szTitle;
+#endif
+        if (RT_SUCCESS(rc))
+        {
+            /* We use UTF-8 for the IPC data. */
+            uint32_t cbMsg = sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG)
+                           + (uint32_t)strlen(pszMsgUtf8)   + 1  /* Include terminating zero */
+                           + (uint32_t)strlen(pszTitleUtf8) + 1; /* Ditto. */
+            Assert(cbMsg);
+            PVBOXTRAYIPCMSG_SHOWBALLOONMSG pIpcMsg = (PVBOXTRAYIPCMSG_SHOWBALLOONMSG)RTMemAlloc(cbMsg);
+            if (pIpcMsg)
             {
-                RTLOCALIPCSESSION hSession = 0;
-                int rc = vboxConnectToVBoxTray(&hSession);
+                /* Stuff in the strings. */
+                memcpy(pIpcMsg->szMsgContent, pszMsgUtf8,   strlen(pszMsgUtf8)   + 1);
+                memcpy(pIpcMsg->szMsgTitle,   pszTitleUtf8, strlen(pszTitleUtf8) + 1);
+
+                /* Pop off the values in reverse order from the stack. */
+                rc = vboxPopULong((ULONG *)&pIpcMsg->uType);
+                if (RT_SUCCESS(rc))
+                    rc = vboxPopULong((ULONG *)&pIpcMsg->uShowMS);
+
                 if (RT_SUCCESS(rc))
                 {
-                    VBOXTRAYIPCHEADER ipcHdr = { VBOXTRAY_IPC_HDR_MAGIC, 0 /* Header version */,
-                                                 VBOXTRAYIPCMSGTYPE_SHOWBALLOONMSG, cbMsg };
-
-                    rc = RTLocalIpcSessionWrite(hSession, &ipcHdr, sizeof(ipcHdr));
+                    RTLOCALIPCSESSION hSession = 0;
+                    rc = vboxConnectToVBoxTray(&hSession);
                     if (RT_SUCCESS(rc))
-                        rc = RTLocalIpcSessionWrite(hSession, pIpcMsg, cbMsg);
-
-                    int rc2 = RTLocalIpcSessionClose(hSession);
-                    if (RT_SUCCESS(rc))
-                        rc = rc2;
+                    {
+                        VBOXTRAYIPCHEADER ipcHdr = { VBOXTRAY_IPC_HDR_MAGIC, 0 /* Header version */,
+                                                     VBOXTRAYIPCMSGTYPE_SHOWBALLOONMSG, cbMsg };
+
+                        rc = RTLocalIpcSessionWrite(hSession, &ipcHdr, sizeof(ipcHdr));
+                        if (RT_SUCCESS(rc))
+                            rc = RTLocalIpcSessionWrite(hSession, pIpcMsg, cbMsg);
+
+                        int rc2 = RTLocalIpcSessionClose(hSession);
+                        if (RT_SUCCESS(rc))
+                            rc = rc2;
+                    }
                 }
 
-                if (RT_FAILURE(rc))
-                    hr = __HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE);
+                RTMemFree(pIpcMsg);
             }
-
-            RTMemFree(pIpcMsg);
-        }
-        else
-            hr = __HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
-    }
-
-    /* Push simple return value on stack. */
-    SUCCEEDED(hr) ? pushstring("0") : pushstring("1");
+            else
+                rc = VERR_NO_MEMORY;
+        }
+    }
+
+    vboxPushRcAsString(rc);
 }
 
Index: /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/exdll.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/exdll.h	(revision 82624)
+++ /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/exdll.h	(revision 82625)
@@ -72,5 +72,5 @@
 {
     struct _stack_t *next;
-    char text[1]; // this should be the length of string_size
+    TCHAR text[1]; // this should be the length of string_size
 } stack_t;
 
@@ -106,10 +106,5 @@
 static unsigned int g_stringsize;
 static stack_t **g_stacktop;
-static char *g_variables;
-
-static int __stdcall popstring(char *str) UNUSED; // 0 on success, 1 on empty stack
-static void __stdcall pushstring(const char *str) UNUSED;
-static char * __stdcall getuservariable(const int varnum) UNUSED;
-static void __stdcall setuservariable(const int varnum, const char *var) UNUSED;
+static TCHAR *g_variables;
 
 enum
@@ -144,11 +139,10 @@
 
 // utility functions (not required but often useful)
-static int __stdcall popstring(char *str)
+int popstringn(TCHAR *str, int maxlen)
 {
   stack_t *th;
-  if (!g_stacktop || !*g_stacktop)
-      return 1;
+  if (!g_stacktop || !*g_stacktop) return 1;
   th=(*g_stacktop);
-  lstrcpyA(str,th->text);
+  if (str) lstrcpyn(str,th->text,maxlen?maxlen:g_stringsize);
   *g_stacktop = th->next;
   GlobalFree((HGLOBAL)th);
@@ -156,5 +150,5 @@
 }
 
-static void __stdcall pushstring(const char *str)
+static void __stdcall pushstring(const TCHAR *str)
 {
   stack_t *th;
@@ -162,10 +156,10 @@
       return;
   th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
-  lstrcpynA(th->text,str,g_stringsize);
+  lstrcpyn(th->text,str,g_stringsize);
   th->next=*g_stacktop;
   *g_stacktop=th;
 }
 
-static char * __stdcall getuservariable(const int varnum)
+static TCHAR* __stdcall getuservariable(const int varnum)
 {
   if (varnum < 0 || varnum >= __INST_LAST)
@@ -174,8 +168,8 @@
 }
 
-static void __stdcall setuservariable(const int varnum, const char *var)
+static void __stdcall setuservariable(const int varnum, const TCHAR *var)
 {
     if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
-        lstrcpyA(g_variables + varnum*g_stringsize, var);
+        lstrcpy(g_variables + varnum*g_stringsize, var);
 }
 #endif /* !GA_INCLUDED_SRC_WINNT_Installer_InstallHelper_exdll_h */
Index: /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/testcase/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/testcase/Makefile.kmk	(revision 82624)
+++ /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/testcase/Makefile.kmk	(revision 82625)
@@ -27,5 +27,5 @@
 tstWinAdditionsInstallHelper_TEMPLATE = VBoxGuestR3Exe
 tstWinAdditionsInstallHelper_SOURCES  = tstWinAdditionsInstallHelper.cpp
-tstWinAdditionsInstallHelper_DEFS     = _WIN32_WINNT=0x0400 WIN32_LEAN_AND_MEAN=1 TESTCASE
+tstWinAdditionsInstallHelper_DEFS     = _WIN32_WINNT=0x0400 WIN32_LEAN_AND_MEAN=1 UNICODE _UNICODE
 
 endif # VBOX_WITH_TESTCASES
Index: /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/testcase/tstWinAdditionsInstallHelper.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/testcase/tstWinAdditionsInstallHelper.cpp	(revision 82624)
+++ /trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/testcase/tstWinAdditionsInstallHelper.cpp	(revision 82625)
@@ -21,4 +21,7 @@
 *********************************************************************************************************************************/
 #include <iprt/win/windows.h>
+
+#include <tchar.h>
+
 #pragma warning(push)
 #pragma warning(disable: 4995) /* warning C4995: 'lstrcpyA': name was marked as #pragma deprecated */
@@ -33,4 +36,5 @@
 #include <iprt/string.h>
 #include <iprt/test.h>
+#include <iprt/utf16.h>
 
 
@@ -45,6 +49,7 @@
 
 /** Symbol names to test. */
-#define TST_FILEGETARCHITECTURE_NAME "FileGetArchitecture"
-#define TST_FILEGETVENDOR_NAME       "FileGetVendor"
+#define TST_FILEGETARCHITECTURE_NAME   "FileGetArchitecture"
+#define TST_FILEGETVENDOR_NAME         "FileGetVendor"
+#define TST_VBOXTRAYSHOWBALLONMSG_NAME "VBoxTrayShowBallonMsg"
 
 
@@ -71,15 +76,13 @@
  * @param   pcszString          String to push to the stack.
  */
-static int tstStackPushString(stack_t **ppStackTop, const char *pcszString)
-{
-    const size_t cchString = strlen(pcszString);
-    AssertReturn(cchString, NULL);
-
+static int tstStackPushString(stack_t **ppStackTop, const TCHAR *pcszString)
+{
     int rc = VINF_SUCCESS;
 
-    stack_t *pStack = (stack_t *)GlobalAlloc(GPTR, sizeof(stack_t) + cchString /* Termination space is part of stack_t */);
+    /* Termination space is part of stack_t. */
+    stack_t *pStack = (stack_t *)GlobalAlloc(GPTR, sizeof(stack_t) + g_stringsize);
     if (pStack)
     {
-        lstrcpynA(pStack->text, pcszString, (int)cchString + 1);
+        lstrcpyn(pStack->text, pcszString, (int)g_stringsize);
         pStack->next = ppStackTop ? *ppStackTop : NULL;
 
@@ -98,20 +101,12 @@
  * @param   ppStackTop          Stack to pop off string from.
  */
-static char *tstStackPopString(stack_t **ppStackTop)
-{
-    AssertPtrReturn(ppStackTop, NULL);
-    AssertPtrReturn(*ppStackTop, NULL);
-
+static int tstStackPopString(stack_t **ppStackTop, TCHAR *pszStr, size_t cchStr)
+{
     stack_t *pStack = *ppStackTop;
-
-    char *pszString = RTStrDup(pStack->text);
-    if (pszString)
-    {
-        *ppStackTop = pStack->next;
-        GlobalFree((HGLOBAL)pStack);
-    }
-
-    AssertPtr(pszString);
-    return pszString;
+    lstrcpyn(pszStr, pStack->text, cchStr);
+    *ppStackTop = pStack->next;
+    GlobalFree((HGLOBAL)pStack);
+
+    return VINF_SUCCESS;
 }
 
@@ -126,4 +121,7 @@
     char szGuestInstallHelperDll[RTPATH_MAX];
     RTProcGetExecutablePath(szGuestInstallHelperDll, sizeof(szGuestInstallHelperDll));
+
+    /* Set the default string size. */
+    g_stringsize = NSIS_MAX_STRLEN;
 
     /** @todo This ASSUMES that this testcase always is located in the separate "bin/additions" sub directory
@@ -136,10 +134,20 @@
         RTTestIPrintf(RTTESTLVL_ALWAYS, "Using DLL: %s\n", szGuestInstallHelperDll);
 
+#ifdef UNICODE
+        const bool fUnicode = true;
+#else
+        const bool fUnicode = false;
+#endif
+        RTTestIPrintf(RTTESTLVL_ALWAYS, "Running %s build\n", fUnicode ? "UNICODE" : "ANSI");
+
         RTLDRMOD hLdrMod;
         rc = RTLdrLoad(szGuestInstallHelperDll, &hLdrMod);
         if (RT_SUCCESS(rc))
         {
-            TCHAR szVars[NSIS_MAX_STRLEN] = { 0 };
-
+            TCHAR szVars[NSIS_MAX_STRLEN * sizeof(TCHAR)] = { 0 };
+
+            /*
+             * Tests FileGetArchitecture
+             */
             PNSIS_PLUGIN_FUNC pfnFileGetArchitecture = NULL;
             rc = RTLdrGetSymbol(hLdrMod, TST_FILEGETARCHITECTURE_NAME, (void**)&pfnFileGetArchitecture);
@@ -147,19 +155,29 @@
             {
                 stack_t *pStack = NULL;
-                tstStackPushString(&pStack, "c:\\windows\\system32\\kernel32.dll");
+                tstStackPushString(&pStack, _T("c:\\windows\\system32\\kernel32.dll"));
 
                 pfnFileGetArchitecture(NULL /* hWnd */, NSIS_MAX_STRLEN, szVars, &pStack, NULL /* extra */);
 
-                char *pszStack = tstStackPopString(&pStack);
-                if (pszStack)
-                    RTTestIPrintf(RTTESTLVL_ALWAYS, "Arch: %s\n", pszStack);
+                TCHAR szStack[NSIS_MAX_STRLEN];
+                rc = tstStackPopString(&pStack, szStack, sizeof(szStack));
+                if (   RT_SUCCESS(rc)
+                    && (   !_tcscmp(szStack, _T("x86"))
+                        || !_tcscmp(szStack, _T("amd64"))))
+                {
+                    if (fUnicode)
+                        RTTestIPrintf(RTTESTLVL_ALWAYS, "Arch: %ls\n", szStack);
+                    else
+                        RTTestIPrintf(RTTESTLVL_ALWAYS, "Arch: %s\n", szStack);
+                }
                 else
                     RTTestIFailed("Getting file arch failed (NSIS API changed?)\n");
-                RTStrFree(pszStack);
                 tstStackDestroy(pStack);
             }
             else
-                RTTestIFailed("Loading FileGetArchitecture failed: %Rrc", rc);
-
+                RTTestIFailed("Loading pfnFileGetArchitecture failed: %Rrc", rc);
+
+            /*
+             * Tests FileGetVendor
+             */
             PNSIS_PLUGIN_FUNC pfnFileGetVendor;
             rc = RTLdrGetSymbol(hLdrMod, TST_FILEGETVENDOR_NAME, (void**)&pfnFileGetVendor);
@@ -167,16 +185,56 @@
             {
                 stack_t *pStack = NULL;
-                tstStackPushString(&pStack, "c:\\windows\\system32\\kernel32.dll");
+                tstStackPushString(&pStack, _T("c:\\windows\\system32\\kernel32.dll"));
+
                 pfnFileGetVendor(NULL /* hWnd */, NSIS_MAX_STRLEN, szVars, &pStack, NULL /* extra */);
-                char *pszStack = tstStackPopString(&pStack);
-                if (pszStack)
-                    RTTestIPrintf(RTTESTLVL_ALWAYS, "Vendor: %s\n", pszStack);
+
+                TCHAR szStack[NSIS_MAX_STRLEN];
+                rc = tstStackPopString(&pStack, szStack, RT_ELEMENTS(szStack));
+                if (   RT_SUCCESS(rc)
+                    && !_tcscmp(szStack, _T("Microsoft Corporation")))
+                {
+                    if (fUnicode)
+                        RTTestIPrintf(RTTESTLVL_ALWAYS, "Vendor: %ls\n", szStack);
+                    else
+                        RTTestIPrintf(RTTESTLVL_ALWAYS, "Vendor: %s\n", szStack);
+                }
                 else
                     RTTestIFailed("Getting file vendor failed (NSIS API changed?)\n");
-                RTStrFree(pszStack);
                 tstStackDestroy(pStack);
             }
             else
-                RTTestIFailed("Loading FileGetVendor failed: %Rrc", rc);
+                RTTestIFailed("Loading pfnFileGetVendor failed: %Rrc", rc);
+
+            /*
+             * Tests VBoxTrayShowBallonMsg
+             */
+            PNSIS_PLUGIN_FUNC pfnVBoxTrayShowBallonMsg;
+            rc = RTLdrGetSymbol(hLdrMod, TST_VBOXTRAYSHOWBALLONMSG_NAME, (void **)&pfnVBoxTrayShowBallonMsg);
+            if (RT_SUCCESS(rc))
+            {
+                stack_t *pStack = NULL;
+                /* Push stuff in reverse order to the stack. */
+                tstStackPushString(&pStack, _T("5000") /* Time to show in ms */);
+                tstStackPushString(&pStack, _T("1") /* Type */);
+                tstStackPushString(&pStack, _T("This is a message from tstWinAdditionsInstallHelper!"));
+                tstStackPushString(&pStack, _T("This is a title from tstWinAdditionsInstallHelper!"));
+
+                pfnVBoxTrayShowBallonMsg(NULL /* hWnd */, NSIS_MAX_STRLEN, szVars, &pStack, NULL /* extra */);
+
+                TCHAR szStack[NSIS_MAX_STRLEN];
+                rc = tstStackPopString(&pStack, szStack, RT_ELEMENTS(szStack));
+                if (RT_SUCCESS(rc))
+                {
+                    if (fUnicode)
+                        RTTestIPrintf(RTTESTLVL_ALWAYS, "Reply: %ls\n", szStack);
+                    else
+                        RTTestIPrintf(RTTESTLVL_ALWAYS, "Reply: %s\n", szStack);
+                }
+                else
+                    RTTestIFailed("Sending message to VBoxTray failed (NSIS API changed?)\n");
+                tstStackDestroy(pStack);
+            }
+            else
+                RTTestIFailed("Loading pfnVBoxTrayShowBallonMsg failed: %Rrc", rc);
 
             RTLdrClose(hLdrMod);
Index: /trunk/src/VBox/Additions/WINNT/Installer/VBoxGuestAdditionsCommon.nsh
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Installer/VBoxGuestAdditionsCommon.nsh	(revision 82624)
+++ /trunk/src/VBox/Additions/WINNT/Installer/VBoxGuestAdditionsCommon.nsh	(revision 82625)
@@ -571,7 +571,13 @@
 found:
 
+  ${LogVerbose} "Getting architecture of file $\"$0$\" ..."
+
   VBoxGuestInstallHelper::FileGetArchitecture "$0"
+
   ; Stack: <architecture> $1 $0
   Pop  $0 ; Get architecture string
+
+  ${LogVerbose} "Architecture is: $0"
+
   Pop  $1 ; Restore $1
   Exch $0 ; Restore $0, push vendor on top of stack
