Index: /trunk/src/VBox/Main/glue/string.cpp
===================================================================
--- /trunk/src/VBox/Main/glue/string.cpp	(revision 85305)
+++ /trunk/src/VBox/Main/glue/string.cpp	(revision 85306)
@@ -185,4 +185,48 @@
     throw std::bad_alloc();
 }
+
+HRESULT Bstr::cleanupAndCopyFromNoThrow(const char *a_pszSrc, size_t a_cchMax) RT_NOEXCEPT
+{
+    /*
+     * Check for empty input (m_bstr == NULL means empty, there are no NULL strings).
+     */
+    cleanup();
+    if (!a_cchMax || !a_pszSrc || !*a_pszSrc)
+        return S_OK;
+
+    /*
+     * Calculate the length and allocate a BSTR string buffer of the right
+     * size, i.e. optimize heap usage.
+     */
+    HRESULT hrc;
+    size_t cwc;
+    int vrc = ::RTStrCalcUtf16LenEx(a_pszSrc, a_cchMax, &cwc);
+    if (RT_SUCCESS(vrc))
+    {
+        m_bstr = ::SysAllocStringByteLen(NULL, (unsigned)(cwc * sizeof(OLECHAR)));
+        if (RT_LIKELY(m_bstr))
+        {
+            PRTUTF16 pwsz = (PRTUTF16)m_bstr;
+            vrc = ::RTStrToUtf16Ex(a_pszSrc, a_cchMax, &pwsz, cwc + 1, NULL);
+            if (RT_SUCCESS(vrc))
+                return S_OK;
+
+            /* This should not happen! */
+            AssertRC(vrc);
+            cleanup();
+            hrc = E_UNEXPECTED;
+        }
+        else
+            hrc = E_OUTOFMEMORY;
+    }
+    else
+    {
+        /* Unexpected: Invalid UTF-8 input. */
+        AssertLogRelMsgFailed(("%Rrc %.*Rhxs\n", vrc, RTStrNLen(a_pszSrc, a_cchMax), a_pszSrc));
+        hrc = E_UNEXPECTED;
+    }
+    return hrc;
+}
+
 
 int Bstr::compareUtf8(const char *a_pszRight, CaseSensitivity a_enmCase /*= CaseSensitive*/) const
Index: /trunk/src/VBox/Main/idl/comimpl.xsl
===================================================================
--- /trunk/src/VBox/Main/idl/comimpl.xsl	(revision 85305)
+++ /trunk/src/VBox/Main/idl/comimpl.xsl	(revision 85306)
@@ -35,4 +35,5 @@
 <!-- $G_kind contains what kind of COM class implementation we generate -->
 <xsl:variable name="G_xsltFilename" select="'autogen.xsl'" />
+<xsl:variable name="G_generateBstrVariants" select="'yes'" />
 
 
@@ -102,4 +103,5 @@
   <xsl:param name="dir" />
   <xsl:param name="mod" />
+  <xsl:param name="utf8str" select="'no'" />
 
   <xsl:choose>
@@ -110,4 +112,5 @@
           <xsl:with-param name="safearray" select="''" />
           <xsl:with-param name="dir" select="'in'" />
+          <xsl:with-param name="utf8str" select="$utf8str" />
         </xsl:call-template>
       </xsl:variable>
@@ -131,9 +134,15 @@
         <xsl:when test="(($type='wstring') or ($type='uuid'))">
           <xsl:choose>
-            <xsl:when test="$param and ($dir='in')">
+            <xsl:when test="$param and ($dir='in') and ($utf8str!='yes')">
               <xsl:value-of select="'CBSTR'"/>
+            </xsl:when>
+            <xsl:when test="$param and ($dir='in') and ($utf8str='yes')">
+              <xsl:value-of select="'const Utf8Str &amp;'"/>
             </xsl:when>
             <xsl:when test="$param and ($dir='out')">
               <xsl:value-of select="'BSTR'"/>
+            </xsl:when>
+            <xsl:when test="$param and ($dir='out') and ($utf8str='yes')">
+              <xsl:value-of select="'Utf8Str &amp;'"/>
             </xsl:when>
             <xsl:otherwise>
@@ -194,4 +203,36 @@
   </xsl:choose>
 
+</xsl:template>
+
+<!-- Checks if interface $name has any string attributes, producing '1' for each string attrib.
+     No output if no string attributes -->
+<xsl:template name="hasStringAttributes">
+  <xsl:param name="name" />
+
+  <!-- Recurse into parent interfaces: -->
+  <xsl:variable name="extends">
+    <xsl:value-of select="key('G_keyInterfacesByName', $name)/@extends" />
+  </xsl:variable>
+  <xsl:choose>
+    <xsl:when test="$extends='IEvent'">
+    </xsl:when>
+    <xsl:when test="$extends='IReusableEvent'">
+    </xsl:when>
+    <xsl:when test="count(key('G_keyInterfacesByName', $extends)) > 0">
+      <xsl:call-template name="hasStringAttributes">
+        <xsl:with-param name="name" select="$extends" />
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:call-template name="fatalError">
+        <xsl:with-param name="msg" select="concat('No idea how to process it: ', $name)" />
+      </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>
+
+  <!-- Find immediate string and uuid attributes and output '1' for each one: -->
+  <xsl:for-each select="key('G_keyInterfacesByName', $name)/attribute[(@type = 'wstring' or @type = 'uuid') and (@name != 'midlDoesNotLikeEmptyInterfaces')]">
+    <xsl:text>1</xsl:text>
+  </xsl:for-each>
 </xsl:template>
 
@@ -264,4 +305,5 @@
 <xsl:template name="genFormalParams">
   <xsl:param name="name" />
+  <xsl:param name="utf8str" />
   <xsl:variable name="extends">
     <xsl:value-of select="key('G_keyInterfacesByName', $name)/@extends" />
@@ -276,4 +318,5 @@
       <xsl:call-template name="genFormalParams">
         <xsl:with-param name="name" select="$extends" />
+        <xsl:with-param name="utf8str" select="$utf8str" />
       </xsl:call-template>
     </xsl:when>
@@ -294,4 +337,5 @@
         <xsl:with-param name="dir" select="'in'" />
         <xsl:with-param name="mod" select="@mod" />
+        <xsl:with-param name="utf8str" select="$utf8str" />
       </xsl:call-template>
     </xsl:variable>
@@ -534,4 +578,12 @@
     </xsl:call-template>
     <xsl:value-of select="       '    }&#10;'" />
+
+    <xsl:if test="(@type='wstring') or (@type = 'uuid')">
+      <xsl:text>    inline HRESULT set_</xsl:text><xsl:value-of select="@name"/><xsl:text>(const Utf8Str &amp;a_rString)&#10;</xsl:text>
+      <xsl:text>    {&#10;</xsl:text>
+      <xsl:text>        return </xsl:text><xsl:value-of select="$mName"/><xsl:text>.assignEx(a_rString);&#10;</xsl:text>
+      <xsl:text>    }&#10;</xsl:text>
+    </xsl:if>
+
   </xsl:for-each>
 
@@ -559,4 +611,105 @@
     </xsl:otherwise>
   </xsl:choose>
+</xsl:template>
+
+<xsl:template name="genReinitFunction">
+  <xsl:param name="name"/>
+  <xsl:param name="evname"/>
+  <xsl:param name="ifname"/>
+  <xsl:param name="implName"/>
+  <xsl:param name="utf8str"/>
+
+  <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Reinit', $evname, '(IEvent *aEvent')"/>
+  <xsl:call-template name="genFormalParams">
+    <xsl:with-param name="name" select="$ifname" />
+    <xsl:with-param name="utf8str" select="'no'" />
+  </xsl:call-template>
+  <xsl:text>)&#10;</xsl:text>
+  <xsl:text>{&#10;</xsl:text>
+  <xsl:text>    </xsl:text><xsl:value-of select="$implName"/><xsl:text> *pEvtImpl = dynamic_cast&lt;</xsl:text>
+  <xsl:value-of select="$implName"/><xsl:text> *&gt;(aEvent);&#10;</xsl:text>
+  <xsl:text>    if (pEvtImpl)&#10;</xsl:text>
+  <xsl:text>    {&#10;</xsl:text>
+  <xsl:text>        pEvtImpl->Reuse();&#10;</xsl:text>
+  <xsl:text>        HRESULT hrc = S_OK;&#10;</xsl:text>
+  <xsl:call-template name="genAttrInitCode">
+    <xsl:with-param name="name" select="$name" />
+    <xsl:with-param name="obj" select="'pEvtImpl'" />
+  </xsl:call-template>
+  <xsl:text>        return hrc;&#10;</xsl:text>
+  <xsl:text>    }&#10;</xsl:text>
+  <xsl:text>    return E_INVALIDARG;&#10;</xsl:text>
+  <xsl:text>}&#10;</xsl:text>
+  <xsl:text>&#10;</xsl:text>
+</xsl:template>
+
+<xsl:template name="genCreateFunction">
+  <xsl:param name="name"/>
+  <xsl:param name="evname"/>
+  <xsl:param name="ifname"/>
+  <xsl:param name="implName"/>
+  <xsl:param name="waitable"/>
+  <xsl:param name="evid"/>
+  <xsl:param name="utf8str"/>
+
+  <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Create', $evname, '(IEvent **aEvent, IEventSource *aSource')"/>
+  <xsl:call-template name="genFormalParams">
+    <xsl:with-param name="name" select="$ifname" />
+    <xsl:with-param name="utf8str" select="$utf8str" />
+  </xsl:call-template>
+  <xsl:text>)&#10;</xsl:text>
+  <xsl:text>{&#10;</xsl:text>
+  <xsl:text>    ComObjPtr&lt;</xsl:text><xsl:value-of select="$implName"/><xsl:text>&gt; EvtObj;&#10;</xsl:text>
+  <xsl:text>    HRESULT hrc = EvtObj.createObject();&#10;</xsl:text>
+  <xsl:text>    if (SUCCEEDED(hrc))&#10;</xsl:text>
+  <xsl:text>    {&#10;</xsl:text>
+  <xsl:text>        hrc = EvtObj-&gt;init(aSource, VBoxEventType_</xsl:text><xsl:value-of select="$evid"/>
+  <xsl:text>, </xsl:text><xsl:value-of select="$waitable" /><xsl:text> /*waitable*/);&#10;</xsl:text>
+  <xsl:call-template name="genAttrInitCode">
+    <xsl:with-param name="name" select="$name" />
+    <xsl:with-param name="obj" select="'EvtObj'" />
+  </xsl:call-template>
+  <xsl:text>        if (SUCCEEDED(hrc))&#10;</xsl:text>
+  <xsl:text>        {&#10;</xsl:text>
+  <xsl:text>            hrc = EvtObj.queryInterfaceTo(aEvent);&#10;</xsl:text>
+  <xsl:text>            if (SUCCEEDED(hrc))&#10;</xsl:text>
+  <xsl:text>                return hrc;&#10;</xsl:text>
+  <xsl:text>        }&#10;</xsl:text>
+  <xsl:text>    }&#10;</xsl:text>
+  <xsl:text>    *aEvent = NULL;&#10;</xsl:text>
+  <xsl:text>    return hrc;&#10;</xsl:text>
+  <xsl:text>}&#10;</xsl:text>
+  <xsl:text>&#10;</xsl:text>
+</xsl:template>
+
+<xsl:template name="genFireFunction">
+  <xsl:param name="evname"/>
+  <xsl:param name="ifname"/>
+  <xsl:param name="utf8str"/>
+
+  <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Fire', $evname, '(IEventSource *aSource')"/>
+  <xsl:call-template name="genFormalParams">
+    <xsl:with-param name="name" select="$ifname" />
+    <xsl:with-param name="utf8str" select="$utf8str" />
+  </xsl:call-template>
+  <xsl:text>)&#10;</xsl:text>
+  <xsl:text>{&#10;</xsl:text>
+  <xsl:text>    AssertReturn(aSource, E_INVALIDARG);&#10;</xsl:text>
+  <xsl:text>    ComPtr&lt;IEvent&gt; ptrEvent;&#10;</xsl:text>
+  <xsl:text>    HRESULT hrc = </xsl:text>
+  <xsl:value-of select="concat('Create', $evname, '(ptrEvent.asOutParam(), aSource')"/>
+  <xsl:call-template name="genCallParams">
+    <xsl:with-param name="name" select="$ifname" />
+  </xsl:call-template>
+  <xsl:text>);&#10;</xsl:text>
+  <xsl:text>    if (SUCCEEDED(hrc))&#10;</xsl:text>
+  <xsl:text>    {&#10;</xsl:text>
+  <xsl:text>        BOOL fDeliveredIgnored = FALSE;&#10;</xsl:text>
+  <xsl:text>        hrc = aSource-&gt;FireEvent(ptrEvent, /* do not wait for delivery */ 0, &amp;fDeliveredIgnored);&#10;</xsl:text>
+  <xsl:text>        AssertComRC(hrc);&#10;</xsl:text>
+  <xsl:text>    }&#10;</xsl:text>
+  <xsl:text>    return hrc;&#10;</xsl:text>
+  <xsl:text>}&#10;</xsl:text>
+  <xsl:text>&#10;</xsl:text>
 </xsl:template>
 
@@ -716,5 +869,5 @@
   </xsl:call-template>
 
-  <!-- Split off the remainer into separate template? -->
+  <!-- Associate public functions. -->
   <xsl:variable name="evname">
     <xsl:value-of select="substring(@name, 2)" />
@@ -736,83 +889,68 @@
     </xsl:choose>
   </xsl:variable>
+  <xsl:variable name="hasStringAttribs">
+    <xsl:call-template name="hasStringAttributes">
+      <xsl:with-param name="name" select="@name"/>
+    </xsl:call-template>
+  </xsl:variable>
 
   <!-- Generate ReinitXxxxEvent functions if reusable. -->
   <xsl:if test="$isReusable='yes'">
-    <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Reinit', $evname, '(IEvent *aEvent')"/>
-    <xsl:call-template name="genFormalParams">
-      <xsl:with-param name="name" select="$ifname" />
+    <xsl:call-template name="genReinitFunction">
+      <xsl:with-param name="name" select="@name"/>
+      <xsl:with-param name="evname" select="$evname"/>
+      <xsl:with-param name="ifname" select="$ifname"/>
+      <xsl:with-param name="implName" select="$implName"/>
+      <xsl:with-param name="utf8str" select="'yes'"/>
     </xsl:call-template>
-    <xsl:text>)&#10;</xsl:text>
-    <xsl:text>{&#10;</xsl:text>
-    <xsl:text>    </xsl:text><xsl:value-of select="$implName"/><xsl:text> *pEvtImpl = dynamic_cast&lt;</xsl:text>
-    <xsl:value-of select="$implName"/><xsl:text> *&gt;(aEvent);&#10;</xsl:text>
-    <xsl:text>    if (pEvtImpl)&#10;</xsl:text>
-    <xsl:text>    {&#10;</xsl:text>
-    <xsl:text>        pEvtImpl->Reuse();&#10;</xsl:text>
-    <xsl:text>        HRESULT hrc = S_OK;&#10;</xsl:text>
-    <xsl:call-template name="genAttrInitCode">
-      <xsl:with-param name="name" select="@name" />
-      <xsl:with-param name="obj" select="'pEvtImpl'" />
+
+    <xsl:if test="($hasStringAttribs != '') and ($G_generateBstrVariants = 'yes')">
+      <xsl:call-template name="genReinitFunction">
+        <xsl:with-param name="name" select="@name"/>
+        <xsl:with-param name="evname" select="$evname"/>
+        <xsl:with-param name="ifname" select="$ifname"/>
+        <xsl:with-param name="implName" select="$implName"/>
+        <xsl:with-param name="utf8str" select="'no'"/>
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:if>
+
+  <!-- Generate the CreateXxxxEvent function. -->
+  <xsl:call-template name="genCreateFunction">
+    <xsl:with-param name="name" select="@name"/>
+    <xsl:with-param name="evname" select="$evname"/>
+    <xsl:with-param name="ifname" select="$ifname"/>
+    <xsl:with-param name="implName" select="$implName"/>
+    <xsl:with-param name="waitable" select="$waitable"/>
+    <xsl:with-param name="evid" select="$evid"/>
+    <xsl:with-param name="utf8str" select="'yes'"/>
+  </xsl:call-template>
+
+  <xsl:if test="($hasStringAttribs != '') and ($G_generateBstrVariants = 'yes')">
+    <xsl:call-template name="genCreateFunction">
+      <xsl:with-param name="name" select="@name"/>
+      <xsl:with-param name="evname" select="$evname"/>
+      <xsl:with-param name="ifname" select="$ifname"/>
+      <xsl:with-param name="implName" select="$implName"/>
+      <xsl:with-param name="waitable" select="$waitable"/>
+      <xsl:with-param name="evid" select="$evid"/>
+      <xsl:with-param name="utf8str" select="'no'"/>
     </xsl:call-template>
-    <xsl:text>        return hrc;&#10;</xsl:text>
-    <xsl:text>    }&#10;</xsl:text>
-    <xsl:text>    return E_INVALIDARG;&#10;</xsl:text>
-    <xsl:text>}&#10;</xsl:text>
-    <xsl:text>&#10;</xsl:text>
   </xsl:if>
 
-  <!-- Generate the CreateXxxxEvent function. -->
-  <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Create', $evname, '(IEvent **aEvent, IEventSource *aSource')"/>
-  <xsl:call-template name="genFormalParams">
-    <xsl:with-param name="name" select="$ifname" />
-  </xsl:call-template>
-  <xsl:text>)&#10;</xsl:text>
-  <xsl:text>{&#10;</xsl:text>
-  <xsl:text>    ComObjPtr&lt;</xsl:text><xsl:value-of select="$implName"/><xsl:text>&gt; EvtObj;&#10;</xsl:text>
-  <xsl:text>    HRESULT hrc = EvtObj.createObject();&#10;</xsl:text>
-  <xsl:text>    if (SUCCEEDED(hrc))&#10;</xsl:text>
-  <xsl:text>    {&#10;</xsl:text>
-  <xsl:text>        hrc = EvtObj-&gt;init(aSource, VBoxEventType_</xsl:text><xsl:value-of select="$evid"/>
-  <xsl:text>, </xsl:text><xsl:value-of select="$waitable" /><xsl:text> /*waitable*/);&#10;</xsl:text>
-  <xsl:call-template name="genAttrInitCode">
-    <xsl:with-param name="name" select="@name" />
-    <xsl:with-param name="obj" select="'EvtObj'" />
-  </xsl:call-template>
-  <xsl:text>        if (SUCCEEDED(hrc))&#10;</xsl:text>
-  <xsl:text>        {&#10;</xsl:text>
-  <xsl:text>            hrc = EvtObj.queryInterfaceTo(aEvent);&#10;</xsl:text>
-  <xsl:text>            if (SUCCEEDED(hrc))&#10;</xsl:text>
-  <xsl:text>                return hrc;&#10;</xsl:text>
-  <xsl:text>        }&#10;</xsl:text>
-  <xsl:text>    }&#10;</xsl:text>
-  <xsl:text>    *aEvent = NULL;&#10;</xsl:text>
-  <xsl:text>    return hrc;&#10;</xsl:text>
-  <xsl:text>}&#10;</xsl:text>
-  <xsl:text>&#10;</xsl:text>
-
   <!-- Generate the FireXxxxEvent function. -->
-  <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Fire', $evname, '(IEventSource *aSource')"/>
-  <xsl:call-template name="genFormalParams">
-    <xsl:with-param name="name" select="$ifname" />
-  </xsl:call-template>
-  <xsl:text>)&#10;</xsl:text>
-  <xsl:text>{&#10;</xsl:text>
-  <xsl:text>    AssertReturn(aSource, E_INVALIDARG);&#10;</xsl:text>
-  <xsl:text>    ComPtr&lt;IEvent&gt; ptrEvent;&#10;</xsl:text>
-  <xsl:text>    HRESULT hrc = </xsl:text>
-  <xsl:value-of select="concat('Create', $evname, '(ptrEvent.asOutParam(), aSource')"/>
-  <xsl:call-template name="genCallParams">
-    <xsl:with-param name="name" select="$ifname" />
-  </xsl:call-template>
-  <xsl:text>);&#10;</xsl:text>
-  <xsl:text>    if (SUCCEEDED(hrc))&#10;</xsl:text>
-  <xsl:text>    {&#10;</xsl:text>
-  <xsl:text>        BOOL fDeliveredIgnored = FALSE;&#10;</xsl:text>
-  <xsl:text>        hrc = aSource-&gt;FireEvent(ptrEvent, /* do not wait for delivery */ 0, &amp;fDeliveredIgnored);&#10;</xsl:text>
-  <xsl:text>        AssertComRC(hrc);&#10;</xsl:text>
-  <xsl:text>    }&#10;</xsl:text>
-  <xsl:text>    return hrc;&#10;</xsl:text>
-  <xsl:text>}&#10;</xsl:text>
-  <xsl:text>&#10;</xsl:text>
+  <xsl:call-template name="genFireFunction">
+    <xsl:with-param name="evname" select="$evname"/>
+    <xsl:with-param name="ifname" select="$ifname"/>
+    <xsl:with-param name="utf8str" select="'yes'"/>
+  </xsl:call-template>
+
+  <xsl:if test="($hasStringAttribs != '') and ($G_generateBstrVariants = 'yes')">
+    <xsl:call-template name="genFireFunction">
+      <xsl:with-param name="evname" select="$evname"/>
+      <xsl:with-param name="ifname" select="$ifname"/>
+      <xsl:with-param name="utf8str" select="'no'"/>
+    </xsl:call-template>
+  </xsl:if>
 
 </xsl:template>
@@ -892,10 +1030,25 @@
       <xsl:value-of select="@name" />
     </xsl:variable>
+    <xsl:variable name="hasStringAttribs">
+      <xsl:call-template name="hasStringAttributes">
+        <xsl:with-param name="name" select="@name"/>
+      </xsl:call-template>
+    </xsl:variable>
 
     <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Fire', $evname, '(IEventSource *aSource')"/>
     <xsl:call-template name="genFormalParams">
       <xsl:with-param name="name" select="$ifname" />
+      <xsl:with-param name="utf8str" select="'yes'" />
     </xsl:call-template>
     <xsl:text>);&#10;</xsl:text>
+
+    <xsl:if test="($hasStringAttribs != '') and ($G_generateBstrVariants = 'yes')">
+      <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Fire', $evname, '(IEventSource *aSource')"/>
+      <xsl:call-template name="genFormalParams">
+        <xsl:with-param name="name" select="$ifname" />
+        <xsl:with-param name="utf8str" select="'no'" />
+      </xsl:call-template>
+      <xsl:text>);&#10;</xsl:text>
+    </xsl:if>
   </xsl:for-each>
   <xsl:text>/** @} */&#10;&#10;</xsl:text>
@@ -912,10 +1065,25 @@
       <xsl:value-of select="@name" />
     </xsl:variable>
+    <xsl:variable name="hasStringAttribs">
+      <xsl:call-template name="hasStringAttributes">
+        <xsl:with-param name="name" select="@name"/>
+      </xsl:call-template>
+    </xsl:variable>
 
     <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Create', $evname, '(IEvent **aEvent, IEventSource *aSource')"/>
     <xsl:call-template name="genFormalParams">
       <xsl:with-param name="name" select="$ifname" />
+      <xsl:with-param name="utf8str" select="'yes'" />
     </xsl:call-template>
     <xsl:text>);&#10;</xsl:text>
+
+    <xsl:if test="($hasStringAttribs != '') and ($G_generateBstrVariants = 'yes')">
+      <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Create', $evname, '(IEvent **aEvent, IEventSource *aSource')"/>
+      <xsl:call-template name="genFormalParams">
+        <xsl:with-param name="name" select="$ifname" />
+        <xsl:with-param name="utf8str" select="'no'" />
+      </xsl:call-template>
+      <xsl:text>);&#10;</xsl:text>
+    </xsl:if>
   </xsl:for-each>
   <xsl:text>/** @} */&#10;</xsl:text>
@@ -934,10 +1102,25 @@
         <xsl:value-of select="@name" />
       </xsl:variable>
+      <xsl:variable name="hasStringAttribs">
+        <xsl:call-template name="hasStringAttributes">
+          <xsl:with-param name="name" select="@name"/>
+        </xsl:call-template>
+      </xsl:variable>
 
       <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Reinit', $evname, '(IEvent *aEvent')"/>
       <xsl:call-template name="genFormalParams">
         <xsl:with-param name="name" select="$ifname" />
+        <xsl:with-param name="utf8str" select="'yes'" />
       </xsl:call-template>
       <xsl:text>);&#10;</xsl:text>
+
+      <xsl:if test="($hasStringAttribs != '') and ($G_generateBstrVariants = 'yes')">
+        <xsl:value-of select="concat('DECLHIDDEN(HRESULT) Reinit', $evname, '(IEvent *aEvent')"/>
+        <xsl:call-template name="genFormalParams">
+          <xsl:with-param name="name" select="$ifname" />
+          <xsl:with-param name="utf8str" select="'no'" />
+        </xsl:call-template>
+        <xsl:text>);&#10;</xsl:text>
+      </xsl:if>
     </xsl:if>
   </xsl:for-each>
Index: /trunk/src/VBox/Main/include/VirtualBoxImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 85305)
+++ /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 85306)
@@ -169,7 +169,6 @@
     void i_onMachineStateChanged(const Guid &aId, MachineState_T aState);
     void i_onMachineDataChanged(const Guid &aId, BOOL aTemporary = FALSE);
-    BOOL i_onExtraDataCanChange(const Guid &aId, IN_BSTR aKey, IN_BSTR aValue,
-                                Bstr &aError);
-    void i_onExtraDataChanged(const Guid &aId, IN_BSTR aKey, IN_BSTR aValue);
+    BOOL i_onExtraDataCanChange(const Guid &aId, const Utf8Str &aKey, const Utf8Str &aValue, Bstr &aError);
+    void i_onExtraDataChanged(const Guid &aId, const Utf8Str &aKey, const Utf8Str &aValue);
     void i_onMachineRegistered(const Guid &aId, BOOL aRegistered);
     void i_onSessionStateChanged(const Guid &aId, SessionState_T aState);
@@ -192,5 +191,5 @@
 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
 
-    void i_onGuestPropertyChanged(const Guid &aMachineId, IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags);
+    void i_onGuestPropertyChanged(const Guid &aMachineId, const Utf8Str &aName, const Utf8Str &aValue, const Utf8Str &aFlags);
     void i_onNatRedirectChanged(const Guid &aMachineId, ULONG ulSlot, bool fRemove, IN_BSTR aName,
                                 NATProtocol_T aProto, IN_BSTR aHostIp, uint16_t aHostPort,
Index: /trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 85305)
+++ /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 85306)
@@ -4698,11 +4698,9 @@
         // i_onExtraDataCanChange() only briefly requests the VirtualBox
         // lock to copy the list of callbacks to invoke
-        Bstr error;
-        Bstr bstrValue(aValue);
-
-        if (!mParent->i_onExtraDataCanChange(mData->mUuid, Bstr(aKey).raw(), bstrValue.raw(), error))
-        {
-            const char *sep = error.isEmpty() ? "" : ": ";
-            Log1WarningFunc(("Someone vetoed! Change refused%s%ls\n", sep, error.raw()));
+        Bstr bstrError;
+        if (!mParent->i_onExtraDataCanChange(mData->mUuid, aKey, aValue, bstrError))
+        {
+            const char *sep = bstrError.isEmpty() ? "" : ": ";
+            Log1WarningFunc(("Someone vetoed! Change refused%s%ls\n", sep, bstrError.raw()));
             return setError(E_ACCESSDENIED,
                             tr("Could not set extra data because someone refused the requested change of '%s' to '%s'%s%ls"),
@@ -4710,5 +4708,5 @@
                             aValue.c_str(),
                             sep,
-                            error.raw());
+                            bstrError.raw());
         }
 
@@ -4739,5 +4737,5 @@
     // fire notification outside the lock
     if (fChanged)
-        mParent->i_onExtraDataChanged(mData->mUuid, Bstr(aKey).raw(), Bstr(aValue).raw());
+        mParent->i_onExtraDataChanged(mData->mUuid, aKey, aValue);
 
     return S_OK;
@@ -5523,5 +5521,5 @@
             alock.release();
 
-            mParent->i_onGuestPropertyChanged(mData->mUuid, Bstr(aName).raw(), Bstr(aValue).raw(), Bstr(aFlags).raw());
+            mParent->i_onGuestPropertyChanged(mData->mUuid, aName, aValue, aFlags);
         }
     }
@@ -13536,5 +13534,5 @@
         alock.release();
 
-        mParent->i_onGuestPropertyChanged(mData->mUuid, Bstr(aName).raw(), Bstr(aValue).raw(), Bstr(aFlags).raw());
+        mParent->i_onGuestPropertyChanged(mData->mUuid, aName, aValue, aFlags);
     }
     catch (...)
Index: /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 85305)
+++ /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 85306)
@@ -3246,5 +3246,5 @@
     ComPtr<IEvent> ptrEvent;
     HRESULT hrc = ::CreateMediumRegisteredEvent(ptrEvent.asOutParam(), m->pEventSource,
-                                                aMediumId.toUtf16().raw(), aDevType, aRegistered);
+                                                aMediumId.toString(), aDevType, aRegistered);
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3274,5 +3274,5 @@
     ComPtr<IEvent> ptrEvent;
     HRESULT hrc = ::CreateStorageControllerChangedEvent(ptrEvent.asOutParam(), m->pEventSource,
-                                                        aMachineId.toUtf16().raw(), Bstr(aControllerName).raw());
+                                                        aMachineId.toString(), aControllerName);
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3293,5 +3293,5 @@
 {
     ComPtr<IEvent> ptrEvent;
-    HRESULT hrc = ::CreateMachineStateChangedEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toUtf16().raw(), aState);
+    HRESULT hrc = ::CreateMachineStateChangedEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toString(), aState);
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3304,5 +3304,5 @@
 {
     ComPtr<IEvent> ptrEvent;
-    HRESULT hrc = ::CreateMachineDataChangedEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toUtf16().raw(), aTemporary);
+    HRESULT hrc = ::CreateMachineDataChangedEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toString(), aTemporary);
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3312,8 +3312,7 @@
  *  @note Locks this object for reading.
  */
-BOOL VirtualBox::i_onExtraDataCanChange(const Guid &aId, IN_BSTR aKey, IN_BSTR aValue,
-                                        Bstr &aError)
-{
-    LogFlowThisFunc(("machine={%RTuuid} aKey={%ls} aValue={%ls}\n", aId.raw(), aKey, aValue));
+BOOL VirtualBox::i_onExtraDataCanChange(const Guid &aId, const Utf8Str &aKey, const Utf8Str &aValue, Bstr &aError)
+{
+    LogFlowThisFunc(("machine={%RTuuid} aKey={%s} aValue={%s}\n", aId.raw(), aKey.c_str(), aValue.c_str()));
 
     AutoCaller autoCaller(this);
@@ -3321,5 +3320,5 @@
 
     ComPtr<IEvent> ptrEvent;
-    HRESULT hrc = ::CreateExtraDataCanChangeEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toUtf16().raw(), aKey, aValue);
+    HRESULT hrc = ::CreateExtraDataCanChangeEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toString(), aKey, aValue);
     AssertComRCReturn(hrc, TRUE);
 
@@ -3353,8 +3352,8 @@
  *  @note Doesn't lock any object.
  */
-void VirtualBox::i_onExtraDataChanged(const Guid &aId, IN_BSTR aKey, IN_BSTR aValue)
+void VirtualBox::i_onExtraDataChanged(const Guid &aId, const Utf8Str &aKey, const Utf8Str &aValue)
 {
     ComPtr<IEvent> ptrEvent;
-    HRESULT hrc = ::CreateExtraDataChangedEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toUtf16().raw(), aKey, aValue);
+    HRESULT hrc = ::CreateExtraDataChangedEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toString(), aKey, aValue);
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3367,5 +3366,5 @@
 {
     ComPtr<IEvent> ptrEvent;
-    HRESULT hrc = ::CreateMachineRegisteredEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toUtf16().raw(), aRegistered);
+    HRESULT hrc = ::CreateMachineRegisteredEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toString(), aRegistered);
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3378,5 +3377,5 @@
 {
     ComPtr<IEvent> ptrEvent;
-    HRESULT hrc = ::CreateSessionStateChangedEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toUtf16().raw(), aState);
+    HRESULT hrc = ::CreateSessionStateChangedEvent(ptrEvent.asOutParam(), m->pEventSource, aId.toString(), aState);
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3390,5 +3389,5 @@
     ComPtr<IEvent> ptrEvent;
     HRESULT hrc = ::CreateSnapshotTakenEvent(ptrEvent.asOutParam(), m->pEventSource,
-                                             aMachineId.toUtf16().raw(), aSnapshotId.toUtf16().raw());
+                                             aMachineId.toString(), aSnapshotId.toString());
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3402,5 +3401,5 @@
     ComPtr<IEvent> ptrEvent;
     HRESULT hrc = ::CreateSnapshotDeletedEvent(ptrEvent.asOutParam(), m->pEventSource,
-                                               aMachineId.toUtf16().raw(), aSnapshotId.toUtf16().raw());
+                                               aMachineId.toString(), aSnapshotId.toString());
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3414,5 +3413,5 @@
     ComPtr<IEvent> ptrEvent;
     HRESULT hrc = ::CreateSnapshotRestoredEvent(ptrEvent.asOutParam(), m->pEventSource,
-                                                aMachineId.toUtf16().raw(), aSnapshotId.toUtf16().raw());
+                                                aMachineId.toString(), aSnapshotId.toString());
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3426,5 +3425,5 @@
     ComPtr<IEvent> ptrEvent;
     HRESULT hrc = ::CreateSnapshotChangedEvent(ptrEvent.asOutParam(), m->pEventSource,
-                                               aMachineId.toUtf16().raw(), aSnapshotId.toUtf16().raw());
+                                               aMachineId.toString(), aSnapshotId.toString());
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
@@ -3711,9 +3710,10 @@
  *  @note Doesn't lock any object.
  */
-void VirtualBox::i_onGuestPropertyChanged(const Guid &aMachineId, IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags)
+void VirtualBox::i_onGuestPropertyChanged(const Guid &aMachineId, const Utf8Str &aName, const Utf8Str &aValue,
+                                          const Utf8Str &aFlags)
 {
     ComPtr<IEvent> ptrEvent;
     HRESULT hrc = ::CreateGuestPropertyChangedEvent(ptrEvent.asOutParam(), m->pEventSource,
-                                                    aMachineId.toUtf16().raw(), aName, aValue, aFlags);
+                                                    aMachineId.toString(), aName, aValue, aFlags);
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
