Index: /trunk/src/VBox/Additions/WINNT/VBoxCredProv/VBoxCredProvCredential.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxCredProv/VBoxCredProvCredential.cpp	(revision 66108)
+++ /trunk/src/VBox/Additions/WINNT/VBoxCredProv/VBoxCredProvCredential.cpp	(revision 66109)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2012-2016 Oracle Corporation
+ * Copyright (C) 2012-2017 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -126,5 +126,5 @@
 {
     AssertPtrReturn(pUnicodeDest, E_POINTER);
-    AssertPtrReturn(pwszSource, E_POINTER);
+    AssertPtrReturn(pwszSource,   E_POINTER);
 
     size_t cbLen = RTUtf16Len(pwszSource) * sizeof(RTUTF16);
@@ -155,9 +155,72 @@
 
 
-HRESULT VBoxCredProvCredential::kerberosLogonInit(KERB_INTERACTIVE_LOGON *pLogonIn,
-                                                  CREDENTIAL_PROVIDER_USAGE_SCENARIO enmUsage,
-                                                  PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain)
-{
-    AssertPtrReturn(pLogonIn,     E_INVALIDARG);
+/**
+ * Copies an UTF16 string into a PUNICODE_STRING by allocating space for it.
+ *
+ * @return  HRESULT
+ * @param   pUnicodeDest        Where to store the copied (allocated) unicode string.
+ * @param   pwszSource          UTF16 string to copy.
+ */
+HRESULT VBoxCredProvCredential::RTUTF16ToUnicodeA(PUNICODE_STRING pUnicodeDest, PRTUTF16 pwszSource)
+{
+    AssertPtrReturn(pUnicodeDest, E_POINTER);
+    AssertPtrReturn(pwszSource,   E_POINTER);
+
+    size_t cbLen = (RTUtf16Len(pwszSource) + 1 /* Trailing zero */) * sizeof(WCHAR);
+
+    pUnicodeDest->Buffer = (LPWSTR)CoTaskMemAlloc(cbLen);
+
+    if (!pUnicodeDest->Buffer)
+        return E_OUTOFMEMORY;
+
+    pUnicodeDest->MaximumLength = (USHORT)cbLen;
+    pUnicodeDest->Length        = 0;
+
+    return RTUTF16ToUnicode(pUnicodeDest, pwszSource, true /* fCopy */);
+}
+
+
+/**
+ * Frees a formerly allocated PUNICODE_STRING.
+ *
+ * @param   pUnicode            String to free.
+ */
+void VBoxCredProvCredential::UnicodeStringFree(PUNICODE_STRING pUnicode)
+{
+    if (!pUnicode)
+        return;
+
+    if (pUnicode->Buffer)
+    {
+        Assert(pUnicode->MaximumLength);
+
+        /* Make sure to wipe contents before free'ing. */
+        RTMemWipeThoroughly(pUnicode->Buffer, pUnicode->MaximumLength * sizeof(WCHAR), 3 /* Passes */);
+
+        CoTaskMemFree(pUnicode->Buffer);
+        pUnicode->Buffer = NULL;
+    }
+
+    pUnicode->Length        = 0;
+    pUnicode->MaximumLength = 0;
+}
+
+
+/**
+ * Creates a KERB_INTERACTIVE_LOGON structure with the given parameters.
+ * Must be destroyed with kerberosLogonDestroy().
+ *
+ * @return  HRESULT
+ * @param   pLogon              Structure to create.
+ * @param   enmUsage            Intended usage of the structure.
+ * @param   pwszUser            User name to use.
+ * @param   pwszPassword        Password to use.
+ * @param   pwszDomain          Domain to use. Optional and can be NULL.
+ */
+HRESULT VBoxCredProvCredential::kerberosLogonCreate(KERB_INTERACTIVE_LOGON *pLogon,
+                                                    CREDENTIAL_PROVIDER_USAGE_SCENARIO enmUsage,
+                                                    PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain)
+{
+    AssertPtrReturn(pLogon,       E_INVALIDARG);
     AssertPtrReturn(pwszUser,     E_INVALIDARG);
     AssertPtrReturn(pwszPassword, E_INVALIDARG);
@@ -170,5 +233,5 @@
         && RTUtf16Len(pwszDomain))
     {
-        hr = RTUTF16ToUnicode(&pLogonIn->LogonDomainName, pwszDomain, true /* fCopy */);
+        hr = RTUTF16ToUnicodeA(&pLogon->LogonDomainName, pwszDomain);
     }
     else /* No domain (FQDN) given, try local computer name. */
@@ -179,5 +242,5 @@
         {
             /* Is a domain name missing? Then use the name of the local computer. */
-            hr = RTUTF16ToUnicode(&pLogonIn->LogonDomainName, wszComputerName, true /* fCopy */);
+            hr = RTUTF16ToUnicodeA(&pLogon->LogonDomainName, wszComputerName);
 
             VBoxCredProvVerbose(0, "VBoxCredProvCredential::kerberosLogonInit: Local computer name=%ls\n",
@@ -191,8 +254,8 @@
     if (SUCCEEDED(hr))
     {
-        hr = RTUTF16ToUnicode(&pLogonIn->UserName, pwszUser, true /* fCopy */);
+        hr = RTUTF16ToUnicodeA(&pLogon->UserName, pwszUser);
         if (SUCCEEDED(hr))
         {
-            hr = RTUTF16ToUnicode(&pLogonIn->Password, pwszPassword, true /* fCopy */);
+            hr = RTUTF16ToUnicodeA(&pLogon->Password, pwszPassword);
             if (SUCCEEDED(hr))
             {
@@ -201,13 +264,13 @@
                 {
                     case CPUS_UNLOCK_WORKSTATION:
-                        pLogonIn->MessageType = KerbWorkstationUnlockLogon;
+                        pLogon->MessageType = KerbWorkstationUnlockLogon;
                         break;
 
                     case CPUS_LOGON:
-                        pLogonIn->MessageType = KerbInteractiveLogon;
+                        pLogon->MessageType = KerbInteractiveLogon;
                         break;
 
                     case CPUS_CREDUI:
-                        pLogonIn->MessageType = (KERB_LOGON_SUBMIT_TYPE)0; /* No message type required here. */
+                        pLogon->MessageType = (KERB_LOGON_SUBMIT_TYPE)0; /* No message type required here. */
                         break;
 
@@ -223,4 +286,20 @@
 
     return hr;
+}
+
+
+/**
+ * Destroys a formerly created KERB_INTERACTIVE_LOGON structure.
+ *
+ * @param   pLogon              Structure to destroy.
+ */
+void VBoxCredProvCredential::kerberosLogonDestroy(KERB_INTERACTIVE_LOGON *pLogon)
+{
+    if (!pLogon)
+        return;
+
+    UnicodeStringFree(&pLogon->UserName);
+    UnicodeStringFree(&pLogon->Password);
+    UnicodeStringFree(&pLogon->LogonDomainName);
 }
 
@@ -908,5 +987,4 @@
     /* Save a pointer to the interactive logon struct. */
     KERB_INTERACTIVE_LOGON *pLogon = &KerberosUnlockLogon.Logon;
-    AssertPtr(pLogon);
 
 #ifdef DEBUG /* Note: NEVER print this in release mode! */
@@ -917,9 +995,9 @@
 #endif
 
-    HRESULT hr = kerberosLogonInit(pLogon,
-                                   m_enmUsageScenario,
-                                   m_apwszCredentials[VBOXCREDPROV_FIELDID_USERNAME],
-                                   m_apwszCredentials[VBOXCREDPROV_FIELDID_PASSWORD],
-                                   m_apwszCredentials[VBOXCREDPROV_FIELDID_DOMAINNAME]);
+    HRESULT hr = kerberosLogonCreate(pLogon,
+                                     m_enmUsageScenario,
+                                     m_apwszCredentials[VBOXCREDPROV_FIELDID_USERNAME],
+                                     m_apwszCredentials[VBOXCREDPROV_FIELDID_PASSWORD],
+                                     m_apwszCredentials[VBOXCREDPROV_FIELDID_DOMAINNAME]);
     if (SUCCEEDED(hr))
     {
@@ -973,7 +1051,10 @@
         else
             VBoxCredProvVerbose(1, "VBoxCredProvCredential::GetSerialization: kerberosLogonSerialize failed with hr=0x%08x\n", hr);
+
+        kerberosLogonDestroy(pLogon);
+        pLogon = NULL;
     }
     else
-        VBoxCredProvVerbose(1, "VBoxCredProvCredential::GetSerialization: kerberosLogonInit failed with hr=0x%08x\n", hr);
+        VBoxCredProvVerbose(1, "VBoxCredProvCredential::GetSerialization: kerberosLogonCreate failed with hr=0x%08x\n", hr);
 
     VBoxCredProvVerbose(0, "VBoxCredProvCredential::GetSerialization returned hr=0x%08x\n", hr);
Index: /trunk/src/VBox/Additions/WINNT/VBoxCredProv/VBoxCredProvCredential.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxCredProv/VBoxCredProvCredential.h	(revision 66108)
+++ /trunk/src/VBox/Additions/WINNT/VBoxCredProv/VBoxCredProvCredential.h	(revision 66109)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2012-2016 Oracle Corporation
+ * Copyright (C) 2012-2017 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -95,7 +95,11 @@
 protected:
     HRESULT RTUTF16ToUnicode(PUNICODE_STRING pUnicodeDest, PRTUTF16 pwszSource, bool fCopy);
-    HRESULT kerberosLogonInit(KERB_INTERACTIVE_LOGON *pLogonIn,
-                              CREDENTIAL_PROVIDER_USAGE_SCENARIO enmUsage,
-                              PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain);
+    HRESULT RTUTF16ToUnicodeA(PUNICODE_STRING pUnicodeDest, PRTUTF16 pwszSource);
+    void UnicodeStringFree(PUNICODE_STRING pUnicode);
+
+    HRESULT kerberosLogonCreate(KERB_INTERACTIVE_LOGON *pLogon,
+                                CREDENTIAL_PROVIDER_USAGE_SCENARIO enmUsage,
+                                PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain);
+    void    kerberosLogonDestroy(KERB_INTERACTIVE_LOGON *pLogon);
     HRESULT kerberosLogonSerialize(const KERB_INTERACTIVE_LOGON *pLogon, PBYTE *ppPackage, DWORD *pcbPackage);
 
