[OLEAUT32]
authorAleksey Bragin <aleksey@reactos.org>
Thu, 11 Mar 2010 10:28:34 +0000 (10:28 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Thu, 11 Mar 2010 10:28:34 +0000 (10:28 +0000)
- Sync to Wine-1.1.40.

svn path=/trunk/; revision=46093

43 files changed:
reactos/dll/win32/oleaut32/dispatch.c
reactos/dll/win32/oleaut32/oleaut.c
reactos/dll/win32/oleaut32/oleaut32.rbuild
reactos/dll/win32/oleaut32/oleaut32.rc
reactos/dll/win32/oleaut32/oleaut32_Bg.rc
reactos/dll/win32/oleaut32/oleaut32_Cz.rc
reactos/dll/win32/oleaut32/oleaut32_Da.rc
reactos/dll/win32/oleaut32/oleaut32_De.rc
reactos/dll/win32/oleaut32/oleaut32_El.rc
reactos/dll/win32/oleaut32/oleaut32_En.rc
reactos/dll/win32/oleaut32/oleaut32_Eo.rc
reactos/dll/win32/oleaut32/oleaut32_Es.rc
reactos/dll/win32/oleaut32/oleaut32_Fr.rc
reactos/dll/win32/oleaut32/oleaut32_Hu.rc
reactos/dll/win32/oleaut32/oleaut32_It.rc
reactos/dll/win32/oleaut32/oleaut32_Ko.rc
reactos/dll/win32/oleaut32/oleaut32_Lt.rc [new file with mode: 0644]
reactos/dll/win32/oleaut32/oleaut32_Nl.rc
reactos/dll/win32/oleaut32/oleaut32_No.rc
reactos/dll/win32/oleaut32/oleaut32_Pl.rc
reactos/dll/win32/oleaut32/oleaut32_Pt.rc
reactos/dll/win32/oleaut32/oleaut32_Ro.rc
reactos/dll/win32/oleaut32/oleaut32_Ru.rc
reactos/dll/win32/oleaut32/oleaut32_Si.rc
reactos/dll/win32/oleaut32/oleaut32_Sv.rc
reactos/dll/win32/oleaut32/oleaut32_Th.rc
reactos/dll/win32/oleaut32/oleaut32_Tr.rc
reactos/dll/win32/oleaut32/oleaut32_Uk.rc
reactos/dll/win32/oleaut32/oleaut32_Zh.rc
reactos/dll/win32/oleaut32/oleaut32_ros.diff [deleted file]
reactos/dll/win32/oleaut32/olefont.c
reactos/dll/win32/oleaut32/olepicture.c
reactos/dll/win32/oleaut32/regsvr.c
reactos/dll/win32/oleaut32/tmarshal.c
reactos/dll/win32/oleaut32/typelib.c
reactos/dll/win32/oleaut32/typelib.h
reactos/dll/win32/oleaut32/typelib2.c
reactos/dll/win32/oleaut32/usrmarshal.c
reactos/dll/win32/oleaut32/varformat.c
reactos/dll/win32/oleaut32/variant.c
reactos/dll/win32/oleaut32/variant.h
reactos/dll/win32/oleaut32/vartype.c
reactos/media/doc/README.WINE

index 2fd8bb4..ed3fad4 100644 (file)
@@ -130,10 +130,14 @@ HRESULT WINAPI DispGetParam(
 
     TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n",
           position, pdispparams->cArgs, pdispparams->cNamedArgs);
-    if (position < pdispparams->cArgs) {
+
+    if (position < pdispparams->cArgs)
+    {
       /* positional arg? */
       pos = pdispparams->cArgs - position - 1;
-    } else {
+    }
+    else
+    {
       /* FIXME: is this how to handle named args? */
       for (pos=0; pos<pdispparams->cNamedArgs; pos++)
         if (pdispparams->rgdispidNamedArgs[pos] == position) break;
@@ -141,10 +145,27 @@ HRESULT WINAPI DispGetParam(
       if (pos==pdispparams->cNamedArgs)
         return DISP_E_PARAMNOTFOUND;
     }
+
+    if (pdispparams->cArgs > 0 && !pdispparams->rgvarg)
+    {
+        hr = E_INVALIDARG;
+        goto done;
+    }
+
+    if (!pvarResult)
+    {
+        hr = E_INVALIDARG;
+        goto done;
+    }
+
     hr = VariantChangeType(pvarResult,
                            &pdispparams->rgvarg[pos],
                            0, vtTarg);
-    if (hr == DISP_E_TYPEMISMATCH) *puArgErr = pos;
+
+done:
+    if (FAILED(hr))
+        *puArgErr = pos;
+
     return hr;
 }
 
@@ -234,8 +255,8 @@ static HRESULT WINAPI StdDispatch_QueryInterface(
         IsEqualIID(riid, &IID_IUnknown))
     {
         *ppvObject = This;
-       IUnknown_AddRef((LPUNKNOWN)*ppvObject);
-       return S_OK;
+        IUnknown_AddRef((LPUNKNOWN)*ppvObject);
+        return S_OK;
     }
     return E_NOINTERFACE;
 }
index 0eaddb1..89e1ab9 100644 (file)
@@ -294,19 +294,17 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
        return 0;
 
     if (*old!=NULL) {
+      BSTR old_copy = *old;
       DWORD newbytelen = len*sizeof(WCHAR);
       DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD));
       *old = (BSTR)(ptr+1);
       *ptr = newbytelen;
-      if (str) {
-        memmove(*old, str, newbytelen);
-        (*old)[len] = 0;
-      } else {
-       /* Subtle hidden feature: The old string data is still there
-        * when 'in' is NULL!
-        * Some Microsoft program needs it.
-        */
-      }
+      /* Subtle hidden feature: The old string data is still there
+       * when 'in' is NULL!
+       * Some Microsoft program needs it.
+       */
+      if (str && old_copy!=str) memmove(*old, str, newbytelen);
+      (*old)[len] = 0;
     } else {
       /*
        * Allocate the new string
@@ -696,6 +694,7 @@ HRESULT WINAPI OleTranslateColor(
 
 extern HRESULT WINAPI OLEAUTPS_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLSPEC_HIDDEN;
 extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
+extern GUID const CLSID_PSFactoryBuffer DECLSPEC_HIDDEN;
 
 extern void _get_STDFONT_CF(LPVOID *);
 extern void _get_STDPIC_CF(LPVOID *);
@@ -728,7 +727,7 @@ static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface, IUnk
     HRESULT hr;
 
     if (IsEqualIID(riid, &IID_IDispatch))
-        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, &IID_IPSFactoryBuffer, (void **)&pPSFB);
+        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB);
     else
         hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB);
 
@@ -746,7 +745,7 @@ static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface, REFII
     HRESULT hr;
 
     if (IsEqualIID(riid, &IID_IDispatch))
-        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, &IID_IPSFactoryBuffer, (void **)&pPSFB);
+        hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB);
     else
         hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB);
 
@@ -790,11 +789,6 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
            return S_OK;
        }
     }
-    if (IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
-        IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
-        IsEqualCLSID(rclsid, &CLSID_PSEnumVariant)) {
-        return OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, iid, ppv);
-    }
     if (IsEqualCLSID(rclsid, &CLSID_PSDispatch) && IsEqualIID(iid, &IID_IPSFactoryBuffer)) {
         *ppv = &pPSDispatchFacBuf;
         IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv);
@@ -805,6 +799,12 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
            return S_OK;
        /*FALLTHROUGH*/
     }
+    if (IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
+        IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
+        IsEqualCLSID(rclsid, &CLSID_PSDispatch) ||
+        IsEqualCLSID(rclsid, &CLSID_PSEnumVariant))
+        return OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, iid, ppv);
+
     return OLEAUTPS_DllGetClassObject(rclsid, iid, ppv);
 }
 
index 8b117b9..1873cad 100644 (file)
@@ -9,7 +9,7 @@
        <include base="ReactOS">include/reactos/wine</include>
        <define name="__WINESRC__" />
        <redefine name="_WIN32_WINNT">0x600</redefine>
-       <define name="PROXY_CLSID">CLSID_PSDispatch</define>
+       <define name="PROXY_CLSID_IS">{0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}}</define>
        <define name="COM_NO_WINDOWS_H"/>
        <define name="_OLEAUT32_"/>
        <define name="PROXY_DELEGATION"/>
@@ -54,7 +54,7 @@
 </module>
 <module name="oleaut32_proxy" type="rpcproxy" allowwarnings="true">
        <define name="COM_NO_WINDOWS_H"/>
-       <define name="PROXY_CLSID">CLSID_PSDispatch</define>
+       <define name="PROXY_CLSID_IS">{0xb196b286,0xbab4,0x101a,{0xb6,0x9c,0x00,0xaa,0x00,0x34,0x1d,0x07}}</define>
        <define name="_OLEAUT32_"/>
        <define name="PROXY_DELEGATION"/>
        <define name="REGISTER_PROXY_DLL"/>
index e05528e..847da8b 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "oleaut32_Bg.rc"
 #include "oleaut32_Da.rc"
-#include "oleaut32_De.rc"
 #include "oleaut32_El.rc"
 #include "oleaut32_En.rc"
 #include "oleaut32_Eo.rc"
 #include "oleaut32_No.rc"
 #include "oleaut32_Pl.rc"
 #include "oleaut32_Pt.rc"
-#include "oleaut32_Ro.rc"
-#include "oleaut32_Ru.rc"
-#include "oleaut32_Si.rc"
 #include "oleaut32_Sv.rc"
 #include "oleaut32_Th.rc"
 #include "oleaut32_Tr.rc"
-#include "oleaut32_Zh.rc"
+
+#include "oleaut32_De.rc"
+#include "oleaut32_Lt.rc"
+#include "oleaut32_Ro.rc"
+#include "oleaut32_Ru.rc"
+#include "oleaut32_Si.rc"
 #include "oleaut32_Uk.rc"
+#include "oleaut32_Zh.rc"
 
 /*
  * FIXME:
index 7e930f4..7f0180b 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
index 7075b43..48be0b7 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
index 6f1dcbc..e28922f 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
index 9fb786c..1dbee3e 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
+#pragma code_page(65001)
+
 LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
 
 STRINGTABLE DISCARDABLE
index 145c1a1..a033795 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_GREEK, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
index e56eb11..6a98642 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
index c00e2fd..ae67139 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
index 5cc25ca..5c187db 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
 
 STRINGTABLE DISCARDABLE
index 40e392e..d6136ef 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
 
 STRINGTABLE DISCARDABLE
index 35283c8..ec3b982 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
index 0dee161..69fa31a 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
 
 STRINGTABLE DISCARDABLE
index 0134c7a..5413805 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
diff --git a/reactos/dll/win32/oleaut32/oleaut32_Lt.rc b/reactos/dll/win32/oleaut32/oleaut32_Lt.rc
new file mode 100644 (file)
index 0000000..c568d93
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Lithuanian resources for oleaut32
+ *
+ * Copyright 2009 Aurimas Fišeras <aurimas@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+{
+  IDS_TRUE  "Tiesa"
+  IDS_FALSE "Netiesa"
+  IDS_YES   "Taip"
+  IDS_NO    "Ne"
+  IDS_ON    "Įjungta"
+  IDS_OFF   "Išjungta"
+}
index 6affb2d..e2ae3de 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
 
 STRINGTABLE DISCARDABLE
index 7ca883c..1f99f7b 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
 
 STRINGTABLE DISCARDABLE
index 8c250cb..7d34796 100644 (file)
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_POLISH, SUBLANG_DEFAULT 
 
 STRINGTABLE DISCARDABLE
index 1cbd389..de008bb 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
 
 STRINGTABLE DISCARDABLE
index 52421a8..3a37a69 100644 (file)
@@ -17,6 +17,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
 
 #pragma code_page(65001)
@@ -30,5 +32,3 @@ STRINGTABLE DISCARDABLE
   IDS_ON    "Activat"
   IDS_OFF   "Dezactivat"
 }
-
-#pragma code_page(default)
index 194ca9e..e7c3107 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
 LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
 {
-  IDS_TRUE  "Ïðàâäà"
-  IDS_FALSE "Ëîæü"
-  IDS_YES   "Äà"
-  IDS_NO    "Íåò"
-  IDS_ON    "Âêëþ÷åíî"
-  IDS_OFF   "Âûêëþ÷åíî"
+  IDS_TRUE  "Правда"
+  IDS_FALSE "Ложь"
+  IDS_YES   "Да"
+  IDS_NO    "Нет"
+  IDS_ON    "Включено"
+  IDS_OFF   "Выключено"
 }
index 365d877..32a80ad 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 #pragma code_page(65001)
 
 LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
@@ -31,5 +33,3 @@ STRINGTABLE DISCARDABLE
   IDS_ON    "Vključeno"
   IDS_OFF   "Izključeno"
 }
-
-#pragma code_page(default)
index 387b25e..4362a06 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
 
 STRINGTABLE DISCARDABLE
index 22f01f7..8fcf212 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_THAI, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
index cc2f3e6..08d841a 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
index 557b4ec..d51b06e 100644 (file)
@@ -1,7 +1,9 @@
 /*
  * Ukrainian resources for oleaut32
  *
- * Copyright 2006 Artem Reznikov
+ * Copyright 2003 Jon Griffiths
+ *
+ * Copyright 2007 Artem Reznikov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
+/* UTF-8 */
+#pragma code_page(65001)
+
 LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
 
 STRINGTABLE DISCARDABLE
 {
-  IDS_TRUE  "²ñòèíà"
-  IDS_FALSE "Íåïðàâäà"
-  IDS_YES   "Òàê"
-  IDS_NO    "ͳ"
-  IDS_ON    "Ââ³ìêíåíî"
-  IDS_OFF   "Âèìêíåíî"
+  IDS_TRUE  "Істина"
+  IDS_FALSE "Неправда"
+  IDS_YES   "Так"
+  IDS_NO    "Ні"
+  IDS_ON    "Ввімкнено"
+  IDS_OFF   "Вимкнено"
 }
index 320c40f..bbb9e06 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include "resource.h"
+
 /* Chinese text is encoded in UTF-8 */
 #pragma code_page(65001)
 
@@ -44,5 +46,3 @@ STRINGTABLE DISCARDABLE
   IDS_ON    "開"
   IDS_OFF   "關"
 }
-
-#pragma code_page(default)
diff --git a/reactos/dll/win32/oleaut32/oleaut32_ros.diff b/reactos/dll/win32/oleaut32/oleaut32_ros.diff
deleted file mode 100644 (file)
index 81c42a6..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-Index: oleaut32_Ja.rc
-===================================================================
---- oleaut32_Ja.rc     (revision 23782)
-+++ oleaut32_Ja.rc     (working copy)
-@@ -0,0 +1,11 @@
-+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
-+
-+STRINGTABLE DISCARDABLE
-+{
-+  IDS_TRUE  "True"
-+  IDS_FALSE "False"
-+  IDS_YES   "\82Í\82¢"
-+  IDS_NO    "\82¢\82¢\82¦"
-+  IDS_ON    "\83I\83\93"
-+  IDS_OFF   "\83I\83t"
-+}
-Index: oleaut32_Uk.rc
-===================================================================
---- oleaut32_Uk.rc     (revision 23782)
-+++ oleaut32_Uk.rc     (working copy)
-@@ -0,0 +1,31 @@
-+/*
-+ * Ukrainian resources for oleaut32
-+ *
-+ * Copyright 2006 Artem Reznikov
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2.1 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
-+
-+STRINGTABLE DISCARDABLE
-+{
-+  IDS_TRUE  "²ñòèíà"
-+  IDS_FALSE "Íåïðàâäà"
-+  IDS_YES   "Òàê"
-+  IDS_NO    "ͳ"
-+  IDS_ON    "Ââ³ìêíåíî"
-+  IDS_OFF   "Âèìêíåíî"
-+}
-Index: oleaut32.rc
-===================================================================
---- oleaut32.rc        (revision 23782)
-+++ oleaut32.rc        (working copy)
-@@ -32,8 +32,9 @@
- #include "oleaut32_Es.rc"
- #include "oleaut32_Cz.rc"
- #include "oleaut32_Fr.rc"
- #include "oleaut32_Hu.rc"
- #include "oleaut32_It.rc"
-+#include "oleaut32_Ja.rc"
- #include "oleaut32_Ko.rc"
- #include "oleaut32_Nl.rc"
- #include "oleaut32_No.rc"
-@@ -43,6 +45,7 @@
- #include "oleaut32_Sv.rc"
- #include "oleaut32_Th.rc"
- #include "oleaut32_Tr.rc"
-+#include "oleaut32_Uk.rc"
- /*
-  * FIXME:
index a9b2c04..df7de87 100644 (file)
@@ -53,6 +53,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
 #define FONTPERSIST_UNDERLINE     0x04
 #define FONTPERSIST_STRIKETHROUGH 0x08
 
+static HDC olefont_hdc;
 
 /***********************************************************************
  * List of the HFONTs it has given out, with each one having a separate
@@ -62,10 +63,13 @@ typedef struct _HFONTItem
 {
   struct list entry;
 
-  /* Reference count for that instance of the class. */
-  LONG ref;
+  /* Reference count of any IFont objects that own this hfont */
+  LONG int_refs;
+
+  /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */
+  LONG total_refs;
 
-  /* Contain the font associated with this object. */
+  /* The font associated with this object. */
   HFONT gdiFont;
 
 } HFONTItem, *PHFONTItem;
@@ -88,6 +92,28 @@ static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug =
 };
 static CRITICAL_SECTION OLEFontImpl_csHFONTLIST = { &OLEFontImpl_csHFONTLIST_debug, -1, 0, 0, 0, 0 };
 
+static HDC get_dc(void)
+{
+    HDC hdc;
+    EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+    if(!olefont_hdc)
+        olefont_hdc = CreateCompatibleDC(NULL);
+    hdc = olefont_hdc;
+    LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+    return hdc;
+}
+
+static void delete_dc(void)
+{
+    EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+    if(olefont_hdc)
+    {
+        DeleteDC(olefont_hdc);
+        olefont_hdc = NULL;
+    }
+    LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+}
+
 static void HFONTItem_Delete(PHFONTItem item)
 {
   DeleteObject(item->gdiFont);
@@ -95,6 +121,123 @@ static void HFONTItem_Delete(PHFONTItem item)
   HeapFree(GetProcessHeap(), 0, item);
 }
 
+/* Find hfont item entry in the list.  Should be called while holding the crit sect */
+static HFONTItem *find_hfontitem(HFONT hfont)
+{
+    HFONTItem *item;
+
+    LIST_FOR_EACH_ENTRY(item, &OLEFontImpl_hFontList, HFONTItem, entry)
+    {
+        if (item->gdiFont == hfont)
+            return item;
+    }
+    return NULL;
+}
+
+/* Add an item to the list with one internal reference */
+static HRESULT add_hfontitem(HFONT hfont)
+{
+    HFONTItem *new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item));
+
+    if(!new_item) return E_OUTOFMEMORY;
+
+    new_item->int_refs = 1;
+    new_item->total_refs = 1;
+    new_item->gdiFont = hfont;
+    EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+    list_add_tail(&OLEFontImpl_hFontList,&new_item->entry);
+    LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+    return S_OK;
+}
+
+static HRESULT inc_int_ref(HFONT hfont)
+{
+    HFONTItem *item;
+    HRESULT hr = S_FALSE;
+
+    EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+    item = find_hfontitem(hfont);
+
+    if(item)
+    {
+        item->int_refs++;
+        item->total_refs++;
+        hr = S_OK;
+    }
+    LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+    return hr;
+}
+
+/* decrements the internal ref of a hfont item.  If both refs are zero it'll
+   remove the item from the list and delete the hfont */
+static HRESULT dec_int_ref(HFONT hfont)
+{
+    HFONTItem *item;
+    HRESULT hr = S_FALSE;
+
+    EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+    item = find_hfontitem(hfont);
+
+    if(item)
+    {
+        item->int_refs--;
+        item->total_refs--;
+        if(item->int_refs == 0 && item->total_refs == 0)
+            HFONTItem_Delete(item);
+        hr = S_OK;
+    }
+    LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+    return hr;
+}
+
+static HRESULT inc_ext_ref(HFONT hfont)
+{
+    HFONTItem *item;
+    HRESULT hr = S_FALSE;
+
+    EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+    item = find_hfontitem(hfont);
+    if(item)
+    {
+        item->total_refs++;
+        hr = S_OK;
+    }
+    LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+    return hr;
+}
+
+static HRESULT dec_ext_ref(HFONT hfont)
+{
+    HFONTItem *item;
+    HRESULT hr = S_FALSE;
+
+    EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+    item = find_hfontitem(hfont);
+    if(item)
+    {
+        if(--item->total_refs >= 0) hr = S_OK;
+    }
+    LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+
+    return hr;
+}
+
+static WCHAR *strdupW(const WCHAR* str)
+{
+    WCHAR *ret;
+    DWORD size = (strlenW(str) + 1) * sizeof(WCHAR);
+
+    ret = HeapAlloc(GetProcessHeap(), 0, size);
+    if(ret)
+        memcpy(ret, str, size);
+    return ret;
+}
+
 /***********************************************************************
  * Declaration of the implementation class for the IFont interface
  */
@@ -128,7 +271,7 @@ struct OLEFontImpl
    * Contain the font associated with this object.
    */
   HFONT gdiFont;
-
+  BOOL dirty;
   /*
    * Size ratio
    */
@@ -277,7 +420,8 @@ static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
   CONNECTDATA CD;
   HRESULT hres;
 
-  this->gdiFont = 0;
+  this->dirty = TRUE;
+
   hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum);
   if (SUCCEEDED(hres))
   {
@@ -402,7 +546,6 @@ static ULONG WINAPI OLEFontImpl_Release(
 {
   OLEFontImpl *this = (OLEFontImpl *)iface;
   ULONG ret;
-  PHFONTItem ptr, next;
   TRACE("(%p)->(ref=%d)\n", this, this->ref);
 
   /* Decrease the reference count for current interface */
@@ -412,13 +555,21 @@ static ULONG WINAPI OLEFontImpl_Release(
   if (ret == 0)
   {
     ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt);
-    /* Check if all HFONT list refs are zero */
+
+    /* Final IFont object so destroy font cache */
     if (fontlist_refs == 0)
     {
+      HFONTItem *item, *cursor2;
+
       EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
-      LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry)
-        HFONTItem_Delete(ptr);
+      LIST_FOR_EACH_ENTRY_SAFE(item, cursor2, &OLEFontImpl_hFontList, HFONTItem, entry)
+        HFONTItem_Delete(item);
       LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+      delete_dc();
+    }
+    else
+    {
+      dec_int_ref(this->gdiFont);
     }
     OLEFontImpl_Destroy(this);
   }
@@ -426,6 +577,109 @@ static ULONG WINAPI OLEFontImpl_Release(
   return ret;
 }
 
+typedef struct
+{
+    short orig_cs;
+    short avail_cs;
+} enum_data;
+
+static int CALLBACK font_enum_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm, DWORD type, LPARAM lp)
+{
+    enum_data *data = (enum_data*)lp;
+
+    if(elf->lfCharSet == data->orig_cs)
+    {
+        data->avail_cs = data->orig_cs;
+        return 0;
+    }
+    if(data->avail_cs == -1) data->avail_cs = elf->lfCharSet;
+    return 1;
+}
+
+static void realize_font(OLEFontImpl *This)
+{
+    if (This->dirty)
+    {
+        LOGFONTW logFont;
+        INT fontHeight;
+        WCHAR text_face[LF_FACESIZE];
+        HDC hdc = get_dc();
+        HFONT old_font;
+        TEXTMETRICW tm;
+
+        text_face[0] = 0;
+
+        if(This->gdiFont)
+        {
+            old_font = SelectObject(hdc, This->gdiFont);
+            GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+            SelectObject(hdc, old_font);
+            dec_int_ref(This->gdiFont);
+            This->gdiFont = 0;
+        }
+
+        memset(&logFont, 0, sizeof(LOGFONTW));
+
+        lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE);
+        logFont.lfCharSet         = This->description.sCharset;
+
+        /* If the font name has been changed then enumerate all charsets
+           and pick one that'll result in the font specified being selected */
+        if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName))
+        {
+            enum_data data;
+            data.orig_cs = This->description.sCharset;
+            data.avail_cs = -1;
+            logFont.lfCharSet = DEFAULT_CHARSET;
+            EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0);
+            if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs;
+        }
+
+
+        /*
+         * The height of the font returned by the get_Size property is the
+         * height of the font in points multiplied by 10000... Using some
+         * simple conversions and the ratio given by the application, it can
+         * be converted to a height in pixels.
+         *
+         * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms.
+         * Ratio is applied here relative to the standard.
+         */
+
+        fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 );
+
+
+        logFont.lfHeight          = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 :
+                                                                  (-fontHeight/10000L);
+        logFont.lfItalic          = This->description.fItalic;
+        logFont.lfUnderline       = This->description.fUnderline;
+        logFont.lfStrikeOut       = This->description.fStrikethrough;
+        logFont.lfWeight          = This->description.sWeight;
+        logFont.lfOutPrecision    = OUT_CHARACTER_PRECIS;
+        logFont.lfClipPrecision   = CLIP_DEFAULT_PRECIS;
+        logFont.lfQuality         = DEFAULT_QUALITY;
+        logFont.lfPitchAndFamily  = DEFAULT_PITCH;
+
+        This->gdiFont = CreateFontIndirectW(&logFont);
+        This->dirty = FALSE;
+
+        add_hfontitem(This->gdiFont);
+
+        /* Fixup the name and charset properties so that they match the
+           selected font */
+        old_font = SelectObject(get_dc(), This->gdiFont);
+        GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
+        if(lstrcmpiW(text_face, This->description.lpstrName))
+        {
+            HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
+            This->description.lpstrName = strdupW(text_face);
+        }
+        GetTextMetricsW(hdc, &tm);
+        This->description.sCharset = tm.tmCharSet;
+        SelectObject(hdc, old_font);
+    }
+}
+
 /************************************************************************
  * OLEFontImpl_get_Name (IFont)
  *
@@ -443,6 +697,8 @@ static HRESULT WINAPI OLEFontImpl_get_Name(
   if (pname==0)
     return E_POINTER;
 
+  if(this->dirty) realize_font(this);
+
   if (this->description.lpstrName!=0)
     *pname = SysAllocString(this->description.lpstrName);
   else
@@ -463,6 +719,9 @@ static HRESULT WINAPI OLEFontImpl_put_Name(
   OLEFontImpl *this = (OLEFontImpl *)iface;
   TRACE("(%p)->(%p)\n", this, name);
 
+  if (!name)
+    return CTL_E_INVALIDPROPERTYVALUE;
+
   if (this->description.lpstrName==0)
   {
     this->description.lpstrName = HeapAlloc(GetProcessHeap(),
@@ -504,6 +763,8 @@ static HRESULT WINAPI OLEFontImpl_get_Size(
   if (psize==0)
     return E_POINTER;
 
+  if(this->dirty) realize_font(this);
+
   psize->s.Hi = 0;
   psize->s.Lo = this->description.cySize.s.Lo;
 
@@ -545,6 +806,8 @@ static HRESULT WINAPI OLEFontImpl_get_Bold(
   if (pbold==0)
     return E_POINTER;
 
+  if(this->dirty) realize_font(this);
+
   *pbold = this->description.sWeight > 550;
 
   return S_OK;
@@ -584,6 +847,8 @@ static HRESULT WINAPI OLEFontImpl_get_Italic(
   if (pitalic==0)
     return E_POINTER;
 
+  if(this->dirty) realize_font(this);
+
   *pitalic = this->description.fItalic;
 
   return S_OK;
@@ -625,6 +890,8 @@ static HRESULT WINAPI OLEFontImpl_get_Underline(
   if (punderline==0)
     return E_POINTER;
 
+  if(this->dirty) realize_font(this);
+
   *punderline = this->description.fUnderline;
 
   return S_OK;
@@ -666,6 +933,8 @@ static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
   if (pstrikethrough==0)
     return E_POINTER;
 
+  if(this->dirty) realize_font(this);
+
   *pstrikethrough = this->description.fStrikethrough;
 
   return S_OK;
@@ -707,6 +976,8 @@ static HRESULT WINAPI OLEFontImpl_get_Weight(
   if (pweight==0)
     return E_POINTER;
 
+  if(this->dirty) realize_font(this);
+
   *pweight = this->description.sWeight;
 
   return S_OK;
@@ -748,6 +1019,8 @@ static HRESULT WINAPI OLEFontImpl_get_Charset(
   if (pcharset==0)
     return E_POINTER;
 
+  if(this->dirty) realize_font(this);
+
   *pcharset = this->description.sCharset;
 
   return S_OK;
@@ -785,53 +1058,7 @@ static HRESULT WINAPI OLEFontImpl_get_hFont(
   if (phfont==NULL)
     return E_POINTER;
 
-  /*
-   * Realize the font if necessary
- */
-  if (this->gdiFont==0)
-{
-    LOGFONTW logFont;
-    INT      fontHeight;
-    CY       cySize;
-    PHFONTItem newEntry;
-
-    /*
-     * The height of the font returned by the get_Size property is the
-     * height of the font in points multiplied by 10000... Using some
-     * simple conversions and the ratio given by the application, it can
-     * be converted to a height in pixels.
-     */
-    IFont_get_Size(iface, &cySize);
-
-    /* Standard ratio is 72 / 2540, or 18 / 635 in lowest terms. */
-    /* Ratio is applied here relative to the standard. */
-    fontHeight = MulDiv( cySize.s.Lo, this->cyLogical*635, this->cyHimetric*18 );
-
-    memset(&logFont, 0, sizeof(LOGFONTW));
-
-    logFont.lfHeight          = ((fontHeight%10000L)>5000L) ?  (-fontHeight/10000L)-1 :
-                                                               (-fontHeight/10000L);
-    logFont.lfItalic          = this->description.fItalic;
-    logFont.lfUnderline       = this->description.fUnderline;
-    logFont.lfStrikeOut       = this->description.fStrikethrough;
-    logFont.lfWeight          = this->description.sWeight;
-    logFont.lfCharSet         = this->description.sCharset;
-    logFont.lfOutPrecision    = OUT_CHARACTER_PRECIS;
-    logFont.lfClipPrecision   = CLIP_DEFAULT_PRECIS;
-    logFont.lfQuality         = DEFAULT_QUALITY;
-    logFont.lfPitchAndFamily  = DEFAULT_PITCH;
-    strcpyW(logFont.lfFaceName,this->description.lpstrName);
-
-    this->gdiFont = CreateFontIndirectW(&logFont);
-
-    /* Add font to the cache */
-    newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(HFONTItem));
-    newEntry->ref = 1;
-    newEntry->gdiFont = this->gdiFont;
-    EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
-    list_add_tail(&OLEFontImpl_hFontList,&newEntry->entry);
-    LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
-  }
+  if(this->dirty) realize_font(this);
 
   *phfont = this->gdiFont;
   TRACE("Returning %p\n", *phfont);
@@ -848,12 +1075,8 @@ static HRESULT WINAPI OLEFontImpl_Clone(
   IFont** ppfont)
 {
   OLEFontImpl* newObject = 0;
-  LOGFONTW logFont;
-  INT      fontHeight;
-  CY       cySize;
-  PHFONTItem newEntry;
-
   OLEFontImpl *this = (OLEFontImpl *)iface;
+
   TRACE("(%p)->(%p)\n", this, ppfont);
 
   if (ppfont == NULL)
@@ -879,36 +1102,12 @@ static HRESULT WINAPI OLEFontImpl_Clone(
        (1+strlenW(this->description.lpstrName))*2
   );
   strcpyW(newObject->description.lpstrName, this->description.lpstrName);
-  /* We need to clone the HFONT too. This is just cut & paste from above */
-  IFont_get_Size(iface, &cySize);
-
-  fontHeight = MulDiv(cySize.s.Lo, this->cyLogical*635,this->cyHimetric*18);
-
-  memset(&logFont, 0, sizeof(LOGFONTW));
 
-  logFont.lfHeight          = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
-                                                           (-fontHeight/10000L);
-  logFont.lfItalic          = this->description.fItalic;
-  logFont.lfUnderline       = this->description.fUnderline;
-  logFont.lfStrikeOut       = this->description.fStrikethrough;
-  logFont.lfWeight          = this->description.sWeight;
-  logFont.lfCharSet         = this->description.sCharset;
-  logFont.lfOutPrecision    = OUT_CHARACTER_PRECIS;
-  logFont.lfClipPrecision   = CLIP_DEFAULT_PRECIS;
-  logFont.lfQuality         = DEFAULT_QUALITY;
-  logFont.lfPitchAndFamily  = DEFAULT_PITCH;
-  strcpyW(logFont.lfFaceName,this->description.lpstrName);
 
-  newObject->gdiFont = CreateFontIndirectW(&logFont);
+  /* Increment internal ref in hfont item list */
+  if(newObject->gdiFont) inc_int_ref(newObject->gdiFont);
 
-  /* Add font to the cache */
   InterlockedIncrement(&ifont_cnt);
-  newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(HFONTItem));
-  newEntry->ref = 1;
-  newEntry->gdiFont = newObject->gdiFont;
-  EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
-  list_add_tail(&OLEFontImpl_hFontList,&newEntry->entry);
-  LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
 
   /* create new connection points */
   newObject->pPropertyNotifyCP = NULL;
@@ -1021,29 +1220,13 @@ static HRESULT WINAPI OLEFontImpl_AddRefHfont(
   IFont*  iface,
   HFONT hfont)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
-  PHFONTItem ptr, next;
-  HRESULT hres = S_FALSE; /* assume not present */
+    OLEFontImpl *this = (OLEFontImpl *)iface;
 
-  TRACE("(%p)->(%p)\n", this, hfont);
+    TRACE("(%p)->(%p)\n", this, hfont);
 
-  if (!hfont)
-    return E_INVALIDARG;
+    if (!hfont) return E_INVALIDARG;
 
-  /* Check of the hFont is already in the list */
-  EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
-  LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry)
-  {
-    if (ptr->gdiFont == hfont)
-    {
-      ptr->ref++;
-      hres = S_OK;
-      break;
-    }
-  }
-  LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
-
-  return hres;
+    return inc_ext_ref(hfont);
 }
 
 /************************************************************************
@@ -1055,34 +1238,13 @@ static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
   IFont*  iface,
   HFONT hfont)
 {
-  OLEFontImpl *this = (OLEFontImpl *)iface;
-  PHFONTItem ptr, next;
-  HRESULT hres = S_FALSE; /* assume not present */
+    OLEFontImpl *this = (OLEFontImpl *)iface;
 
-  TRACE("(%p)->(%p)\n", this, hfont);
+    TRACE("(%p)->(%p)\n", this, hfont);
 
-  if (!hfont)
-    return E_INVALIDARG;
-
-  /* Check of the hFont is already in the list */
-  EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
-  LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &OLEFontImpl_hFontList, HFONTItem, entry)
-  {
-    if ((ptr->gdiFont == hfont) && ptr->ref)
-    {
-      /* Remove from cache and delete object if not referenced */
-      if (!--ptr->ref)
-      {
-        if (ptr->gdiFont == this->gdiFont)
-          this->gdiFont = NULL;
-      }
-      hres = S_OK;
-      break;
-    }
-  }
-  LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
+    if (!hfont) return E_INVALIDARG;
 
-  return hres;
+    return dec_ext_ref(hfont);
 }
 
 /************************************************************************
@@ -1675,7 +1837,7 @@ static HRESULT WINAPI OLEFontImpl_Load(
   this->description.lpstrName[len] = 0;
 
   /* Ensure use of this font causes a new one to be created @@@@ */
-  DeleteObject(this->gdiFont);
+  dec_int_ref(this->gdiFont);
   this->gdiFont = 0;
 
   return S_OK;
@@ -2247,6 +2409,7 @@ static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
    * Initializing all the other members.
    */
   newObject->gdiFont  = 0;
+  newObject->dirty = TRUE;
   newObject->cyLogical  = 72L;
   newObject->cyHimetric = 2540L;
   newObject->pPropertyNotifyCP = NULL;
@@ -2280,9 +2443,6 @@ static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
 
   HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
 
-  if (fontDesc->gdiFont!=0)
-    DeleteObject(fontDesc->gdiFont);
-
   if (fontDesc->pPropertyNotifyCP)
       IConnectionPoint_Release(fontDesc->pPropertyNotifyCP);
   if (fontDesc->pFontEventsCP)
index 052aa9a..7a5bc29 100644 (file)
@@ -684,7 +684,7 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
     break;
   case PICTYPE_ICON:
     FIXME("Not quite correct implementation of rendering icons...\n");
-    DrawIcon(hdc,x,y,This->desc.u.icon.hicon);
+    DrawIconEx(hdc, x, y, This->desc.u.icon.hicon, cx, cy, 0, NULL, DI_NORMAL);
     break;
 
   case PICTYPE_METAFILE:
index 3c5fabc..12f64fa 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdarg.h>
 #include <string.h>
 
+#define COBJMACROS
 #include "windef.h"
 #include "winbase.h"
 #include "winuser.h"
@@ -377,6 +378,32 @@ static LONG register_key_defvalueA(
     return res;
 }
 
+/***********************************************************************
+ *             register_typelib
+ */
+static HRESULT register_typelib( const WCHAR *name )
+{
+    static const WCHAR backslash[] = {'\\',0};
+    HRESULT hr;
+    ITypeLib *typelib;
+    WCHAR *path;
+    DWORD len;
+
+    len = GetSystemDirectoryW( NULL, 0 ) + strlenW( name ) + 1;
+    if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
+    GetSystemDirectoryW( path, len );
+    strcatW( path, backslash );
+    strcatW( path, name );
+    hr = LoadTypeLib( path, &typelib );
+    if (SUCCEEDED(hr))
+    {
+        hr = RegisterTypeLib( typelib, path, NULL );
+        ITypeLib_Release( typelib );
+    }
+    HeapFree( GetProcessHeap(), 0, path );
+    return hr;
+}
+
 /***********************************************************************
  *             coclass list
  */
@@ -386,9 +413,6 @@ static GUID const CLSID_RecordInfo = {
 static GUID const CLSID_OldFont = {
     0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} };
 
-static GUID const CLSID_PSFactoryBuffer = {
-    0xB196B286, 0xBAB4, 0x101A, {0xB6,0x9C,0x00,0xAA,0x00,0x34,0x1D,0x07} };
-
 static struct regsvr_coclass const coclass_list[] = {
     {   &CLSID_RecordInfo,
        "CLSID_RecordInfo",
@@ -456,12 +480,6 @@ static struct regsvr_coclass const coclass_list[] = {
        "Obsolete Font",
        "OldFont"
     },
-    {   &CLSID_PSFactoryBuffer,
-       "PSFactoryBuffer",
-       NULL,
-       "oleaut32.dll",
-       "Both"
-    },
     { NULL }                   /* list terminator */
 };
 
@@ -470,7 +488,6 @@ static struct regsvr_coclass const coclass_list[] = {
  */
 #define INTERFACE_ENTRY(interface, clsid16, clsid32) { &IID_##interface, #interface, NULL, sizeof(interface##Vtbl)/sizeof(void*), clsid16, clsid32 }
 #define LCL_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, NULL)
-#define PSFAC_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, &CLSID_PSFactoryBuffer)
 #define CLSID_INTERFACE_ENTRY(interface,clsid) INTERFACE_ENTRY(interface, clsid, clsid)
 
 static struct regsvr_interface const interface_list[] = {
@@ -481,43 +498,10 @@ static struct regsvr_interface const interface_list[] = {
     CLSID_INTERFACE_ENTRY(ITypeComp,&CLSID_PSTypeComp),
     CLSID_INTERFACE_ENTRY(ITypeInfo,&CLSID_PSTypeInfo),
     CLSID_INTERFACE_ENTRY(ITypeLib,&CLSID_PSTypeLib),
-    PSFAC_INTERFACE_ENTRY(IAdviseSinkEx),
-    PSFAC_INTERFACE_ENTRY(IClassFactory2),
-    PSFAC_INTERFACE_ENTRY(IConnectionPoint),
-    PSFAC_INTERFACE_ENTRY(IConnectionPointContainer),
-    PSFAC_INTERFACE_ENTRY(ICreateErrorInfo),
-    PSFAC_INTERFACE_ENTRY(IEnumConnectionPoints),
-    PSFAC_INTERFACE_ENTRY(IEnumConnections),
-    PSFAC_INTERFACE_ENTRY(IEnumOleUndoUnits),
-    PSFAC_INTERFACE_ENTRY(IErrorInfo),
-    PSFAC_INTERFACE_ENTRY(IErrorLog),
-    PSFAC_INTERFACE_ENTRY(IFont),
-    PSFAC_INTERFACE_ENTRY(IObjectWithSite),
-    PSFAC_INTERFACE_ENTRY(IOleControl),
-    PSFAC_INTERFACE_ENTRY(IOleControlSite),
-    PSFAC_INTERFACE_ENTRY(IOleInPlaceSiteEx),
-    PSFAC_INTERFACE_ENTRY(IOleParentUndoUnit),
-    PSFAC_INTERFACE_ENTRY(IOleUndoManager),
-    PSFAC_INTERFACE_ENTRY(IOleUndoUnit),
-    PSFAC_INTERFACE_ENTRY(IPerPropertyBrowsing),
-    PSFAC_INTERFACE_ENTRY(IPersistMemory),
-    PSFAC_INTERFACE_ENTRY(IPersistPropertyBag),
-    PSFAC_INTERFACE_ENTRY(IPersistPropertyBag2),
-    PSFAC_INTERFACE_ENTRY(IPersistStreamInit),
-    PSFAC_INTERFACE_ENTRY(IPicture),
-    PSFAC_INTERFACE_ENTRY(IPointerInactive),
-    PSFAC_INTERFACE_ENTRY(IPropertyBag),
-    PSFAC_INTERFACE_ENTRY(IPropertyBag2),
-    PSFAC_INTERFACE_ENTRY(IPropertyNotifySink),
-    PSFAC_INTERFACE_ENTRY(IPropertyPage),
-    PSFAC_INTERFACE_ENTRY(IPropertyPage2),
-    PSFAC_INTERFACE_ENTRY(IPropertyPageSite),
-    PSFAC_INTERFACE_ENTRY(IProvideClassInfo),
-    PSFAC_INTERFACE_ENTRY(IProvideClassInfo2),
-    PSFAC_INTERFACE_ENTRY(IProvideMultipleClassInfo),
-    PSFAC_INTERFACE_ENTRY(IQuickActivate),
-    PSFAC_INTERFACE_ENTRY(ISimpleFrameSite),
-    PSFAC_INTERFACE_ENTRY(ISpecifyPropertyPages),
+    INTERFACE_ENTRY(ISupportErrorInfo,NULL,&CLSID_PSDispatch),
+    INTERFACE_ENTRY(ITypeFactory,NULL,&CLSID_PSDispatch),
+    INTERFACE_ENTRY(ITypeInfo2,NULL,&CLSID_PSDispatch),
+    INTERFACE_ENTRY(ITypeLib2,NULL,&CLSID_PSDispatch),
     { NULL }                   /* list terminator */
 };
 
@@ -538,6 +522,13 @@ HRESULT WINAPI DllRegisterServer(void)
         hr = register_coclasses(coclass_list);
     if (SUCCEEDED(hr))
        hr = register_interfaces(interface_list);
+    if (SUCCEEDED(hr))
+    {
+        const WCHAR stdole32W[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0};
+        const WCHAR stdole2W[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
+        hr = register_typelib( stdole2W );
+        if (SUCCEEDED(hr)) hr = register_typelib( stdole32W );
+    }
     return hr;
 }
 
index 7235850..26babdb 100644 (file)
@@ -615,8 +615,6 @@ serialize_param(
         vartype = VT_SAFEARRAY;
 
     switch (vartype) {
-    case VT_EMPTY: /* nothing. empty variant for instance */
-       return S_OK;
     case VT_I8:
     case VT_UI8:
     case VT_R8:
@@ -652,56 +650,23 @@ serialize_param(
        if (writeit)
            hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
        return hres;
-    case VT_I4|VT_BYREF:
-       hres = S_OK;
-       if (debugout) TRACE_(olerelay)("&0x%x\n",*arg);
-       if (writeit)
-           hres = xbuf_add(buf,(LPBYTE)(DWORD*)*arg,sizeof(DWORD));
-       /* do not dealloc at this time */
-       return hres;
     case VT_VARIANT: {
-       TYPEDESC        tdesc2;
-       VARIANT         *vt = (VARIANT*)arg;
-       DWORD           vttype = V_VT(vt);
-
-       if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(vttype),debugstr_vf(vttype));
-       tdesc2.vt = vttype;
-       if (writeit) {
-           hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype));
-           if (hres) return hres;
-       }
-       /* need to recurse since we need to free the stuff */
-       hres = serialize_param(tinfo,writeit,debugout,dealloc,&tdesc2,(DWORD*)&(V_I4(vt)),buf);
-       if (debugout) TRACE_(olerelay)(")");
-       return hres;
-    }
-    case VT_BSTR|VT_BYREF: {
-       if (debugout) TRACE_(olerelay)("[byref]'%s'", *(BSTR*)*arg ? relaystr(*((BSTR*)*arg)) : "<bstr NULL>");
-        if (writeit) {
-            /* ptr to ptr to magic widestring, basically */
-            BSTR *bstr = (BSTR *) *arg;
-            DWORD len;
-            if (!*bstr) {
-                /* -1 means "null string" which is equivalent to empty string */
-                len = -1;     
-                hres = xbuf_add(buf, (LPBYTE)&len,sizeof(DWORD));
-               if (hres) return hres;
-            } else {
-               len = *((DWORD*)*bstr-1)/sizeof(WCHAR);
-               hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
-               if (hres) return hres;
-               hres = xbuf_add(buf,(LPBYTE)*bstr,len * sizeof(WCHAR));
-               if (hres) return hres;
-            }
+        if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(V_VT((VARIANT *)arg)),debugstr_vf(V_VT((VARIANT *)arg)));
+        if (writeit)
+        {
+            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+            ULONG size = VARIANT_UserSize(&flags, buf->curoff, (VARIANT *)arg);
+            xbuf_resize(buf, size);
+            VARIANT_UserMarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg);
+            buf->curoff = size;
         }
-
-        if (dealloc && arg) {
-            BSTR *str = *((BSTR **)arg);
-            SysFreeString(*str);
+        if (dealloc)
+        {
+            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+            VARIANT_UserFree(&flags, (VARIANT *)arg);
         }
         return S_OK;
     }
-    
     case VT_BSTR: {
        if (debugout) {
            if (*arg)
@@ -709,25 +674,20 @@ serialize_param(
            else
                    TRACE_(olerelay)("<bstr NULL>");
        }
-       if (writeit) {
-            BSTR bstr = (BSTR)*arg;
-            DWORD len;
-           if (!bstr) {
-               len = -1;
-               hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
-               if (hres) return hres;
-           } else {
-               len = *((DWORD*)bstr-1)/sizeof(WCHAR);
-               hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
-               if (hres) return hres;
-               hres = xbuf_add(buf,(LPBYTE)bstr,len * sizeof(WCHAR));
-               if (hres) return hres;
-           }
-       }
-
-       if (dealloc && arg)
-           SysFreeString((BSTR)*arg);
-       return S_OK;
+        if (writeit)
+        {
+            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+            ULONG size = BSTR_UserSize(&flags, buf->curoff, (BSTR *)arg);
+            xbuf_resize(buf, size);
+            BSTR_UserMarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
+            buf->curoff = size;
+        }
+        if (dealloc)
+        {
+            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+            BSTR_UserFree(&flags, (BSTR *)arg);
+        }
+        return S_OK;
     }
     case VT_PTR: {
        DWORD cookie;
@@ -888,12 +848,14 @@ serialize_param(
        if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt));
        if (debugout) TRACE_(olerelay)("[");
        for (i=0;i<arrsize;i++) {
-           hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)arg+i*_xsize(&adesc->tdescElem, tinfo)), buf);
+           hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)), buf);
            if (hres)
                return hres;
            if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
        }
        if (debugout) TRACE_(olerelay)("]");
+       if (dealloc)
+           HeapFree(GetProcessHeap(), 0, *(void **)arg);
        return S_OK;
     }
     case VT_SAFEARRAY: {
@@ -905,6 +867,11 @@ serialize_param(
             LPSAFEARRAY_UserMarshal(&flags, buf->base + buf->curoff, (LPSAFEARRAY *)arg);
             buf->curoff = size;
         }
+        if (dealloc)
+        {
+            ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+            LPSAFEARRAY_UserFree(&flags, (LPSAFEARRAY *)arg);
+        }
         return S_OK;
     }
     default:
@@ -934,34 +901,15 @@ deserialize_param(
 
     while (1) {
        switch (vartype) {
-       case VT_EMPTY:
-           if (debugout) TRACE_(olerelay)("<empty>\n");
-           return S_OK;
-       case VT_NULL:
-           if (debugout) TRACE_(olerelay)("<null>\n");
-           return S_OK;
        case VT_VARIANT: {
-           VARIANT     *vt = (VARIANT*)arg;
-
-           if (readit) {
-               DWORD   vttype;
-               TYPEDESC        tdesc2;
-               hres = xbuf_get(buf,(LPBYTE)&vttype,sizeof(vttype));
-               if (hres) {
-                   FIXME("vt type not read?\n");
-                   return hres;
-               }
-               memset(&tdesc2,0,sizeof(tdesc2));
-               tdesc2.vt = vttype;
-               V_VT(vt)  = vttype;
-               if (debugout) TRACE_(olerelay)("Vt(%s%s)(",debugstr_vt(vttype),debugstr_vf(vttype));
-               hres = deserialize_param(tinfo, readit, debugout, alloc, &tdesc2, (DWORD*)&(V_I4(vt)), buf);
-               TRACE_(olerelay)(")");
-               return hres;
-           } else {
-               VariantInit(vt);
-               return S_OK;
+           if (readit)
+           {
+               ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+               unsigned char *buffer;
+               buffer = VARIANT_UserUnmarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg);
+               buf->curoff = buffer - buf->base;
            }
+           return S_OK;
        }
         case VT_I8:
         case VT_UI8:
@@ -1006,76 +954,14 @@ deserialize_param(
            }
            if (debugout) TRACE_(olerelay)("%02x",*arg & 0xff);
            return hres;
-        case VT_I4|VT_BYREF:
-           hres = S_OK;
-           if (alloc)
-               *arg = (DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD));
-           if (readit) {
-               hres = xbuf_get(buf,(LPBYTE)*arg,sizeof(DWORD));
-               if (hres) ERR("Failed to read integer 4 byte\n");
-           }
-           if (debugout) TRACE_(olerelay)("&0x%x",*(DWORD*)*arg);
-           return hres;
-       case VT_BSTR|VT_BYREF: {
-           BSTR **bstr = (BSTR **)arg;
-           WCHAR       *str;
-           DWORD       len;
-
-           if (readit) {
-               hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD));
-               if (hres) {
-                   ERR("failed to read bstr klen\n");
-                   return hres;
-               }
-               if (len == -1) {
-                    *bstr = CoTaskMemAlloc(sizeof(BSTR *));
-                   **bstr = NULL;
-                   if (debugout) TRACE_(olerelay)("<bstr NULL>");
-               } else {
-                   str  = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
-                   hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
-                   if (hres) {
-                       ERR("Failed to read BSTR.\n");
-                       HeapFree(GetProcessHeap(),0,str);
-                       return hres;
-                   }
-                    *bstr = CoTaskMemAlloc(sizeof(BSTR *));
-                   **bstr = SysAllocStringLen(str,len);
-                   if (debugout) TRACE_(olerelay)("%s",relaystr(str));
-                   HeapFree(GetProcessHeap(),0,str);
-               }
-           } else {
-               *bstr = NULL;
-           }
-           return S_OK;
-       }
        case VT_BSTR: {
-           WCHAR       *str;
-           DWORD       len;
-
-           if (readit) {
-               hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD));
-               if (hres) {
-                   ERR("failed to read bstr klen\n");
-                   return hres;
-               }
-               if (len == -1) {
-                   *arg = 0;
-                   if (debugout) TRACE_(olerelay)("<bstr NULL>");
-               } else {
-                   str  = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
-                   hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
-                   if (hres) {
-                       ERR("Failed to read BSTR.\n");
-                       HeapFree(GetProcessHeap(),0,str);
-                       return hres;
-                   }
-                   *arg = (DWORD)SysAllocStringLen(str,len);
-                   if (debugout) TRACE_(olerelay)("%s",relaystr(str));
-                   HeapFree(GetProcessHeap(),0,str);
-               }
-           } else {
-               *arg = 0;
+           if (readit)
+           {
+               ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION);
+               unsigned char *buffer;
+               buffer = BSTR_UserUnmarshal(&flags, buf->base + buf->curoff, (BSTR *)arg);
+               buf->curoff = buffer - buf->base;
+               if (debugout) TRACE_(olerelay)("%s",debugstr_w(*(BSTR *)arg));
            }
            return S_OK;
        }
@@ -1247,6 +1133,7 @@ deserialize_param(
            if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n");
            for (i=0;i<adesc->cDims;i++)
                arrsize *= adesc->rgbounds[i].cElements;
+           *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize);
            for (i=0;i<arrsize;i++)
                deserialize_param(
                    tinfo,
@@ -1254,7 +1141,7 @@ deserialize_param(
                    debugout,
                    alloc,
                    &adesc->tdescElem,
-                   (DWORD*)((LPBYTE)(arg)+i*_xsize(&adesc->tdescElem, tinfo)),
+                   (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)),
                    buf
                );
            return S_OK;
@@ -2037,6 +1924,7 @@ static HRESULT WINAPI
 TMStubImpl_Invoke(
     LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf)
 {
+#ifdef __i386__
     int                i;
     const FUNCDESC *fdesc;
     TMStubImpl *This = (TMStubImpl *)iface;
@@ -2103,7 +1991,7 @@ TMStubImpl_Invoke(
     nrofargs = 0;
     for (i=0;i<fdesc->cParams;i++)
        nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo);
-    args = HeapAlloc(GetProcessHeap(),0,(nrofargs+1)*sizeof(DWORD));
+    args = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(nrofargs+1)*sizeof(DWORD));
     if (!args)
     {
         hres = E_OUTOFMEMORY;
@@ -2201,6 +2089,10 @@ exit:
 
     TRACE("returning\n");
     return hres;
+#else
+    FIXME( "not implemented on non-i386\n" );
+    return E_FAIL;
+#endif
 }
 
 static LPRPCSTUBBUFFER WINAPI
index 887c6be..445eac5 100644 (file)
@@ -552,7 +552,9 @@ HRESULT WINAPI RegisterTypeLib(
         LPOLESTR doc;
 
         /* Set the human-readable name of the typelib */
-        if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
+        if (FAILED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
+            res = E_FAIL;
+        else if (doc)
         {
             if (RegSetValueExW(key, NULL, 0, REG_SZ,
                 (BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
@@ -560,8 +562,6 @@ HRESULT WINAPI RegisterTypeLib(
 
             SysFreeString(doc);
         }
-        else
-            res = E_FAIL;
 
         /* Make up the name of the typelib path subkey */
         if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL;
@@ -1013,7 +1013,7 @@ typedef struct tagTLBFuncDesc
     int helpcontext;
     int HelpStringContext;
     BSTR HelpString;
-    BSTR Entry;            /* if its Hiword==0, it numeric; -1 is not present*/
+    BSTR Entry;            /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */
     int ctCustData;
     TLBCustData * pCustData;        /* linked list to cust data; */
     struct tagTLBFuncDesc * next;
@@ -1048,7 +1048,7 @@ typedef struct tagITypeInfoImpl
     const ITypeInfo2Vtbl *lpVtbl;
     const ITypeCompVtbl  *lpVtblTypeComp;
     LONG ref;
-    BOOL no_free_data; /* don't free data structures */
+    BOOL not_attached_to_typelib;
     TYPEATTR TypeAttr ;         /* _lots_ of type information. */
     ITypeLibImpl * pTypeLib;        /* back pointer to typelib */
     int index;                  /* index in this typelib; */
@@ -1085,6 +1085,7 @@ static const ITypeInfo2Vtbl tinfvt;
 static const ITypeCompVtbl  tcompvt;
 
 static ITypeInfo2 * ITypeInfo_Constructor(void);
+static void ITypeInfo_fnDestroy(ITypeInfoImpl *This);
 
 typedef struct tagTLBContext
 {
@@ -1898,8 +1899,8 @@ MSFT_DoFuncs(TLBContext*     pcx,
                 {
                     if ( pFuncRec->FKCCIC & 0x2000 )
                     {
-                       if (HIWORD(pFuncRec->OptAttr[2]) != 0)
-                           ERR("ordinal 0x%08x invalid, HIWORD != 0\n", pFuncRec->OptAttr[2]);
+                       if (!IS_INTRESOURCE(pFuncRec->OptAttr[2]))
+                           ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->OptAttr[2]);
                        (*pptfd)->Entry = (BSTR)pFuncRec->OptAttr[2];
                     }
                     else
@@ -2492,7 +2493,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
     /* Find resource */
     typeInfo = (NE_TYPEINFO *)(resTab + 2);
 
-    if (HIWORD(typeid) != 0)  /* named type */
+    if (!IS_INTRESOURCE(typeid))  /* named type */
     {
         BYTE len = strlen( typeid );
         while (typeInfo->type_id)
@@ -2523,7 +2524,7 @@ static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
  found_type:
     nameInfo = (NE_NAMEINFO *)(typeInfo + 1);
 
-    if (HIWORD(resid) != 0)  /* named resource */
+    if (!IS_INTRESOURCE(resid))  /* named resource */
     {
         BYTE len = strlen( resid );
         for (count = typeInfo->count; count > 0; count--, nameInfo++)
@@ -2947,7 +2948,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
                 if(td[1]<0)
                     pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK;
                 else
-                    pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = stndTypeDesc[td[0]/8];
+                    pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = cx.pLibInfo->pTypeDesc[td[0]/(2*sizeof(INT))];
 
                 pTypeLibImpl->pTypeDesc[i].u.lpadesc->cDims = td[2];
 
@@ -2991,6 +2992,7 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
             name = TLB_Alloc(size+1);
             MSFT_Read(name, size, &cx, DO_NOT_SEEK);
             (*ppImpLib)->name = TLB_MultiByteToBSTR(name);
+            TLB_Free(name);
 
             MSFT_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
             offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3;
@@ -3676,6 +3678,9 @@ static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
   if (pTITail->funcs_off != 0xffff)
     SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
 
+  if (pTITail->impls_off != 0xffff)
+    SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup);
+
   /* this is necessary to cope with MSFT typelibs that set cFuncs to the number
    * of dispinterface functions including the IDispatch ones, so
    * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */
@@ -3935,6 +3940,9 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
       (*ppTypeInfoImpl)->TypeAttr.wTypeFlags =
        (pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5);
 
+      if((*ppTypeInfoImpl)->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)
+       (*ppTypeInfoImpl)->TypeAttr.typekind = TKIND_DISPATCH;
+
       if((pTIHeader->typeflags1 & 7) != 2)
        FIXME_(typelib)("typeflags1 = %02x\n", pTIHeader->typeflags1);
       if(pTIHeader->typeflags3 != 2)
@@ -4083,6 +4091,7 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
       TLBRefType *ref_type;
       void *cursor2;
       int i;
+      ITypeInfoImpl *pTI, *pTINext;
 
       /* remove cache entry */
       if(This->path)
@@ -4139,8 +4148,11 @@ static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
           TLB_Free(ref_type);
       }
 
-      if (This->pTypeInfo) /* can be NULL */
-         ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
+      for (pTI = This->pTypeInfo; pTI; pTI = pTINext)
+      {
+          pTINext = pTI->next;
+          ITypeInfo_fnDestroy(pTI);
+      }
       HeapFree(GetProcessHeap(),0,This);
       return 0;
     }
@@ -4835,8 +4847,29 @@ static HRESULT WINAPI ITypeLibComp_fnBindType(
     ITypeInfo ** ppTInfo,
     ITypeComp ** ppTComp)
 {
-    FIXME("(%s, %x, %p, %p): stub\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
-    return E_NOTIMPL;
+    ITypeLibImpl *This = impl_from_ITypeComp(iface);
+    ITypeInfoImpl *pTypeInfo;
+
+    TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
+
+    for (pTypeInfo = This->pTypeInfo; pTypeInfo; pTypeInfo = pTypeInfo->next)
+    {
+        /* FIXME: should use lHash to do the search */
+        if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name, szName))
+        {
+            TRACE("returning %p\n", pTypeInfo);
+            *ppTInfo = (ITypeInfo *)&pTypeInfo->lpVtbl;
+            ITypeInfo_AddRef(*ppTInfo);
+            *ppTComp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp;
+            ITypeComp_AddRef(*ppTComp);
+            return S_OK;
+        }
+    }
+
+    TRACE("not found\n");
+    *ppTInfo = NULL;
+    *ppTComp = NULL;
+    return S_OK;
 }
 
 static const ITypeCompVtbl tlbtcvt =
@@ -4860,7 +4893,7 @@ static ITypeInfo2 * ITypeInfo_Constructor(void)
     {
       pTypeInfoImpl->lpVtbl = &tinfvt;
       pTypeInfoImpl->lpVtblTypeComp = &tcompvt;
-      pTypeInfoImpl->ref=1;
+      pTypeInfoImpl->ref = 0;
       pTypeInfoImpl->hreftype = -1;
       pTypeInfoImpl->TypeAttr.memidConstructor = MEMBERID_NIL;
       pTypeInfoImpl->TypeAttr.memidDestructor = MEMBERID_NIL;
@@ -4902,97 +4935,96 @@ static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
     ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
     ULONG ref = InterlockedIncrement(&This->ref);
 
-    ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib);
-
     TRACE("(%p)->ref is %u\n",This, ref);
+
+    if (ref == 1 /* incremented from 0 */)
+        ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib);
+
     return ref;
 }
 
-/* ITypeInfo::Release
- */
-static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
+static void ITypeInfo_fnDestroy(ITypeInfoImpl *This)
 {
-    ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
-    ULONG ref = InterlockedDecrement(&This->ref);
+    TLBFuncDesc *pFInfo, *pFInfoNext;
+    TLBVarDesc *pVInfo, *pVInfoNext;
+    TLBImplType *pImpl, *pImplNext;
 
-    TRACE("(%p)->(%u)\n",This, ref);
+    TRACE("destroying ITypeInfo(%p)\n",This);
 
-    if (ref)   {
-      /* We don't release ITypeLib when ref=0 because
-         it means that function is called by ITypeLib2_Release */
-      ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
-    } else   {
-      TLBFuncDesc *pFInfo, *pFInfoNext;
-      TLBVarDesc *pVInfo, *pVInfoNext;
-      TLBImplType *pImpl, *pImplNext;
+    SysFreeString(This->Name);
+    This->Name = NULL;
 
-      TRACE("destroying ITypeInfo(%p)\n",This);
+    SysFreeString(This->DocString);
+    This->DocString = NULL;
 
-      if (This->no_free_data)
-          goto finish_free;
+    SysFreeString(This->DllName);
+    This->DllName = NULL;
 
-      SysFreeString(This->Name);
-      This->Name = NULL;
-
-      SysFreeString(This->DocString);
-      This->DocString = NULL;
+    for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext)
+    {
+        INT i;
+        for(i = 0;i < pFInfo->funcdesc.cParams; i++)
+        {
+            ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i];
+            if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
+            {
+                VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
+                TLB_Free(elemdesc->u.paramdesc.pparamdescex);
+            }
+            SysFreeString(pFInfo->pParamDesc[i].Name);
+        }
+        TLB_Free(pFInfo->funcdesc.lprgelemdescParam);
+        TLB_Free(pFInfo->pParamDesc);
+        TLB_FreeCustData(pFInfo->pCustData);
+        if (!IS_INTRESOURCE(pFInfo->Entry) && pFInfo->Entry != (BSTR)-1)
+            SysFreeString(pFInfo->Entry);
+        SysFreeString(pFInfo->HelpString);
+        SysFreeString(pFInfo->Name);
+
+        pFInfoNext = pFInfo->next;
+        TLB_Free(pFInfo);
+    }
+    for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext)
+    {
+        if (pVInfo->vardesc.varkind == VAR_CONST)
+        {
+            VariantClear(pVInfo->vardesc.u.lpvarValue);
+            TLB_Free(pVInfo->vardesc.u.lpvarValue);
+        }
+        TLB_FreeCustData(pVInfo->pCustData);
+        SysFreeString(pVInfo->Name);
+        pVInfoNext = pVInfo->next;
+        TLB_Free(pVInfo);
+    }
+    for (pImpl = This->impltypelist; pImpl; pImpl = pImplNext)
+    {
+        TLB_FreeCustData(pImpl->pCustData);
+        pImplNext = pImpl->next;
+        TLB_Free(pImpl);
+    }
+    TLB_FreeCustData(This->pCustData);
 
-      SysFreeString(This->DllName);
-      This->DllName = NULL;
+    HeapFree(GetProcessHeap(), 0, This);
+}
 
-      for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext)
-      {
-          INT i;
-          for(i = 0;i < pFInfo->funcdesc.cParams; i++)
-          {
-              ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i];
-              if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
-              {
-                  VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
-                  TLB_Free(elemdesc->u.paramdesc.pparamdescex);
-              }
-              SysFreeString(pFInfo->pParamDesc[i].Name);
-          }
-          TLB_Free(pFInfo->funcdesc.lprgelemdescParam);
-          TLB_Free(pFInfo->pParamDesc);
-          TLB_FreeCustData(pFInfo->pCustData);
-          if (HIWORD(pFInfo->Entry) != 0 && pFInfo->Entry != (BSTR)-1) 
-              SysFreeString(pFInfo->Entry);
-          SysFreeString(pFInfo->HelpString);
-          SysFreeString(pFInfo->Name);
-
-          pFInfoNext = pFInfo->next;
-          TLB_Free(pFInfo);
-      }
-      for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext)
-      {
-          if (pVInfo->vardesc.varkind == VAR_CONST)
-          {
-              VariantClear(pVInfo->vardesc.u.lpvarValue);
-              TLB_Free(pVInfo->vardesc.u.lpvarValue);
-          }
-          TLB_FreeCustData(pVInfo->pCustData);
-          SysFreeString(pVInfo->Name);
-          pVInfoNext = pVInfo->next;
-          TLB_Free(pVInfo);
-      }
-      for(pImpl = This->impltypelist; pImpl; pImpl = pImplNext)
-      {
-          TLB_FreeCustData(pImpl->pCustData);
-          pImplNext = pImpl->next;
-          TLB_Free(pImpl);
-      }
-      TLB_FreeCustData(This->pCustData);
+/* ITypeInfo::Release
+ */
+static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
+{
+    ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
 
-finish_free:
-      if (This->next)
-      {
-        ITypeInfo_Release((ITypeInfo*)This->next);
-      }
+    TRACE("(%p)->(%u)\n",This, ref);
 
-      HeapFree(GetProcessHeap(),0,This);
-      return 0;
+    if (!ref)
+    {
+        BOOL not_attached_to_typelib = This->not_attached_to_typelib;
+        ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
+        if (not_attached_to_typelib)
+            HeapFree(GetProcessHeap(), 0, This);
+        /* otherwise This will be freed when typelib is freed */
     }
+
     return ref;
 }
 
@@ -5345,7 +5377,7 @@ static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr )
         hr = VariantCopy(dest->u.lpvarValue, src->u.lpvarValue);
         if (FAILED(hr))
         {
-            SysFreeString((BSTR)dest_ptr);
+            SysFreeString((BSTR)dest);
             return hr;
         }
     }
@@ -5476,8 +5508,7 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
       */
       if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
 
-      if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDISPATCHABLE &&
-          This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL )
+      if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)
       {
         *pRefType = -1;
       }
@@ -5600,6 +5631,41 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
     return DISP_E_UNKNOWNNAME;
 }
 
+
+#ifdef __i386__
+
+extern DWORD CDECL call_method( void *func, int nb_args, const DWORD *args );
+__ASM_GLOBAL_FUNC( call_method,
+                   "pushl %ebp\n\t"
+                   __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+                   __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+                   "movl %esp,%ebp\n\t"
+                   __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+                   "pushl %esi\n\t"
+                  __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
+                   "pushl %edi\n\t"
+                  __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
+                   "movl 12(%ebp),%edx\n\t"
+                   "shll $2,%edx\n\t"
+                   "jz 1f\n\t"
+                   "subl %edx,%esp\n\t"
+                   "andl $~15,%esp\n\t"
+                   "movl 12(%ebp),%ecx\n\t"
+                   "movl 16(%ebp),%esi\n\t"
+                   "movl %esp,%edi\n\t"
+                   "cld\n\t"
+                   "rep; movsl\n"
+                   "1:\tcall *8(%ebp)\n\t"
+                   "leal -8(%ebp),%esp\n\t"
+                   "popl %edi\n\t"
+                   __ASM_CFI(".cfi_same_value %edi\n\t")
+                   "popl %esi\n\t"
+                   __ASM_CFI(".cfi_same_value %esi\n\t")
+                   "popl %ebp\n\t"
+                   __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+                   __ASM_CFI(".cfi_same_value %ebp\n\t")
+                   "ret" )
+
 /* ITypeInfo::Invoke
  *
  * Invokes a method, or accesses a property of an object, that implements the
@@ -5618,106 +5684,8 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) {
 
     switch (callconv) {
     case CC_STDCALL:
-
-       switch (nrargs) {
-       case 0:
-               res = func();
-               break;
-       case 1:
-               res = func(args[0]);
-               break;
-       case 2:
-               res = func(args[0],args[1]);
-               break;
-       case 3:
-               res = func(args[0],args[1],args[2]);
-               break;
-       case 4:
-               res = func(args[0],args[1],args[2],args[3]);
-               break;
-       case 5:
-               res = func(args[0],args[1],args[2],args[3],args[4]);
-               break;
-       case 6:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5]);
-               break;
-       case 7:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
-               break;
-       case 8:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
-               break;
-       case 9:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
-               break;
-       case 10:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]);
-               break;
-       case 11:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]);
-               break;
-       case 12:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]);
-               break;
-       case 13:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12]);
-               break;
-       case 14:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13]);
-               break;
-       case 15:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14]);
-               break;
-       case 16:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15]);
-               break;
-       case 17:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16]);
-               break;
-       case 18:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17]);
-               break;
-       case 19:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18]);
-               break;
-       case 20:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19]);
-               break;
-       case 21:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20]);
-               break;
-       case 22:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21]);
-               break;
-       case 23:
-               res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22]);
-               break;
-       case 24:
-                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23]);
-                break;
-       case 25:
-                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24]);
-                break;
-       case 26:
-                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25]);
-                break;
-       case 27:
-                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26]);
-                break;
-       case 28:
-                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27]);
-                break;
-       case 29:
-                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28]);
-                break;
-       case 30:
-                res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28],args[29]);
-                break;
-       default:
-               FIXME("unsupported number of arguments %d in stdcall\n",nrargs);
-               res = -1;
-               break;
-       }
+    case CC_CDECL:
+        res = call_method( func, nrargs, args );
        break;
     default:
        FIXME("unsupported calling convention %d\n",callconv);
@@ -5754,6 +5722,7 @@ static int _dispargsize(VARTYPE vt)
        return 1;
     }
 }
+#endif /* __i386__ */
 
 static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
 {
@@ -5933,6 +5902,7 @@ DispCallFunc(
     void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals,
     VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
 {
+#ifdef __i386__
     int argsize, argspos;
     UINT i;
     DWORD *args;
@@ -5988,9 +5958,13 @@ DispCallFunc(
         V_VT(pvargResult) = vtReturn;
         V_UI4(pvargResult) = hres;
     }
-
     HeapFree(GetProcessHeap(),0,args);
     return S_OK;
+#else
+    FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n",
+           pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
+    return E_NOTIMPL;
+#endif
 }
 
 #define INVBUF_ELEMENT_SIZE \
@@ -6177,7 +6151,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                         else
                         {
                             VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
-                            hres = VariantCopy(&missing_arg[i], src_arg);
+                            if (wParamFlags & PARAMFLAG_FIN)
+                                hres = VariantCopy(&missing_arg[i], src_arg);
                             V_VARIANTREF(&rgvarg[i]) = &missing_arg[i];
                         }
                         V_VT(&rgvarg[i]) = rgvt[i];
@@ -6215,8 +6190,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                     else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
                     {
                         VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
-                        V_VT(&missing_arg[i]) = V_VT(src_arg);
-                        hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
+                        if (wParamFlags & PARAMFLAG_FIN)
+                            hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
+                        else
+                            V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF;
                         V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]);
                         V_VT(&rgvarg[i]) = rgvt[i];
                     }
@@ -6299,6 +6276,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
             for (i = 0; i < func_desc->cParams; i++)
             {
                 USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
+                VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
 
                 if (wParamFlags & PARAMFLAG_FLCID)
                     continue;
@@ -6317,33 +6295,23 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                         hres = VariantCopyInd(pVarResult, prgpvarg[i]);
                     }
 
-                    /* free data stored in varresult. Note that
-                     * VariantClear doesn't do what we want because we are
-                     * working with byref types. */
-                    /* FIXME: clear safearrays, bstrs, records and
-                     * variants here too */
-                    if ((V_VT(prgpvarg[i]) == (VT_UNKNOWN | VT_BYREF)) ||
-                         (V_VT(prgpvarg[i]) == (VT_DISPATCH | VT_BYREF)))
-                    {
-                        if(*V_UNKNOWNREF(prgpvarg[i]))
-                            IUnknown_Release(*V_UNKNOWNREF(prgpvarg[i]));
-                    }
-                    break;
+                    VARIANT_ClearInd(prgpvarg[i]);
                 }
                 else if (vargs_converted < pDispParams->cArgs)
                 {
+                    VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
                     if (wParamFlags & PARAMFLAG_FOUT)
                     {
-                        VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
-
-                        if ((rgvt[i] == VT_BYREF) && (V_VT(arg) != VT_BYREF))
+                        if ((rgvt[i] & VT_BYREF) && !(V_VT(arg) & VT_BYREF))
+                        {
                             hres = VariantChangeType(arg, &rgvarg[i], 0, V_VT(arg));
 
-                        if (FAILED(hres))
-                        {
-                            ERR("failed to convert param %d to vt %d\n", i,
-                                V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
-                            break;
+                            if (FAILED(hres))
+                            {
+                                ERR("failed to convert param %d to vt %d\n", i,
+                                    V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
+                                break;
+                            }
                         }
                     }
                     else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
@@ -6382,6 +6350,8 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                     if (wParamFlags & PARAMFLAG_FHASDEFAULT)
                         VariantClear(&rgvarg[i]);
                 }
+
+                VariantClear(&missing_arg[i]);
             }
 
             if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult)))
@@ -6601,7 +6571,7 @@ static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid
            if (pBstrDllName)
                *pBstrDllName = SysAllocString(This->DllName);
 
-           if (HIWORD(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
+            if (!IS_INTRESOURCE(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
                if (pBstrName)
                    *pBstrName = SysAllocString(pFDesc->Entry);
                if (pwOrdinal)
@@ -6689,20 +6659,18 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
 
          *ppTInfo = (ITypeInfo*) pTypeInfoImpl;
 
-         /* we use data structures from This, so we need to keep a reference
-          * to it to stop it being destroyed and signal to the new instance to
+         /* the AddRef implicitly adds a reference to the parent typelib, which
+          * stops the copied data from being destroyed until the new typeinfo's
+          * refcount goes to zero, but we need to signal to the new instance to
           * not free its data structures when it is destroyed */
-         pTypeInfoImpl->no_free_data = TRUE;
-         pTypeInfoImpl->next = This;
-         ITypeInfo_AddRef((ITypeInfo*) This);
+         pTypeInfoImpl->not_attached_to_typelib = TRUE;
 
          ITypeInfo_AddRef(*ppTInfo);
 
          result = S_OK;
 
     } else if ((hRefType != -1) && (hRefType & DISPATCH_HREF_MASK) &&
-        (This->TypeAttr.typekind   == TKIND_DISPATCH) &&
-       (This->TypeAttr.wTypeFlags &  TYPEFLAG_FDUAL))
+        (This->TypeAttr.typekind   == TKIND_DISPATCH))
     {
         HREFTYPE href_dispatch = hRefType;
         result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo);
index 1fe8ecf..058c6a2 100644 (file)
@@ -155,6 +155,7 @@ typedef struct tagMSFT_TypeInfoBase {
         INT     datatype2;      /* if 0x8000, entry above is valid */
                                 /* actually dunno */
                                 /* else it is zero? */
+                                /* if interface: inheritance level | no of inherited funcs */
         INT     res18;          /* always? 0 */
 /*060*/ INT     res19;          /* always? -1 */
 } MSFT_TypeInfoBase;
@@ -413,7 +414,7 @@ typedef struct {
 /*0e*/ DWORD res0e;            /* 0xffffffff */
 /*12*/ WORD major_version;     /* major version number */
 /*14*/  WORD minor_version;    /* minor version number */
-/*16*/ DWORD res16;    /* 0xfffe0000 */
+/*16*/ DWORD res16;    /* 0xfffe0000 or 0xfffc0000 (on dual interfaces?) */
 /*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */
 /*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */
 /*1c*/ BYTE typeflags3;/* 0x02*/
index 0f641d4..4544317 100644 (file)
@@ -43,6 +43,7 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
+#include "winreg.h"
 #include "winuser.h"
 
 #include "wine/unicode.h"
@@ -116,6 +117,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(typelib2);
 
 /*================== Implementation Structures ===================================*/
 
+/* Used for storing cyclic list. Tail address is kept */
+typedef struct tagCyclicList {
+    struct tagCyclicList *next;
+    int indice;
+    int name;
+
+    union {
+        int val;
+        int *data;
+    }u;
+} CyclicList;
+
 enum MSFT_segment_index {
     MSFT_SEG_TYPEINFO = 0,  /* type information */
     MSFT_SEG_IMPORTINFO,    /* import information */
@@ -157,6 +170,9 @@ typedef struct tagICreateTypeLib2Impl
     char *typelib_segment_data[MSFT_SEG_MAX];
     int typelib_segment_block_length[MSFT_SEG_MAX];
 
+    int typelib_guids; /* Number of defined typelib guids */
+    int typeinfo_guids; /* Number of defined typeinfo guids */
+
     INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */
 
     INT *typelib_namehash_segment;
@@ -181,13 +197,7 @@ typedef struct tagICreateTypeInfo2Impl
     ICreateTypeLib2Impl *typelib;
     MSFT_TypeInfoBase *typeinfo;
 
-    INT *typedata;
-    int typedata_allocated;
-    int typedata_length;
-
-    int indices[42];
-    int names[42];
-    int offsets[42];
+    struct tagCyclicList *typedata; /* tail of cyclic list */
 
     int datawidth;
 
@@ -388,6 +398,27 @@ static int ctl2_encode_name(
     return (length + 7) & ~3;
 }
 
+/****************************************************************************
+ *      ctl2_decode_name
+ *
+ * Converts string stored in typelib data to unicode.
+ */
+static void ctl2_decode_name(
+        char *data,         /* [I] String to be decoded */
+        WCHAR **string)     /* [O] Decoded string */
+{
+    int i, length;
+    static WCHAR converted_string[0x104];
+
+    length = data[0];
+
+    for(i=0; i<length; i++)
+        converted_string[i] = data[i+4];
+    converted_string[length] = '\0';
+
+    *string = converted_string;
+}
+
 /****************************************************************************
  *     ctl2_encode_string
  *
@@ -423,6 +454,29 @@ static int ctl2_encode_string(
     return (length + 5) & ~3;
 }
 
+/****************************************************************************
+ *      ctl2_decode_string
+ *
+ * Converts string stored in typelib data to unicode.
+ */
+static void ctl2_decode_string(
+        char *data,         /* [I] String to be decoded */
+        WCHAR **string)     /* [O] Decoded string */
+{
+    int i, length;
+    static WCHAR converted_string[0x104];
+
+    length = data[0] + (data[1]<<8);
+    if((length&0x3) == 1)
+        length >>= 2;
+
+    for(i=0; i<length; i++)
+        converted_string[i] = data[i+2];
+    converted_string[length] = '\0';
+
+    *string = converted_string;
+}
+
 /****************************************************************************
  *     ctl2_alloc_segment
  *
@@ -508,7 +562,7 @@ static int ctl2_alloc_typeinfo(
     typeinfo->typekind = (This->typelib_header.nrtypeinfos - 1) << 16;
     typeinfo->memoffset = -1; /* should be EOF if no elements */
     typeinfo->res2 = 0;
-    typeinfo->res3 = -1;
+    typeinfo->res3 = 0;
     typeinfo->res4 = 3;
     typeinfo->res5 = 0;
     typeinfo->cElement = 0;
@@ -662,19 +716,20 @@ static int ctl2_alloc_string(
  *  Failure: -1 (this is invariably an out of memory condition).
  */
 static int ctl2_alloc_importinfo(
-       ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
-       MSFT_ImpInfo *impinfo)     /* [I] The import information to store. */
+        ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
+        MSFT_ImpInfo *impinfo)     /* [I] The import information to store. */
 {
     int offset;
     MSFT_ImpInfo *impinfo_space;
 
-    for (offset = 0;
-        offset < This->typelib_segdir[MSFT_SEG_IMPORTINFO].length;
-        offset += sizeof(MSFT_ImpInfo)) {
-       if (!memcmp(&(This->typelib_segment_data[MSFT_SEG_IMPORTINFO][offset]),
-                   impinfo, sizeof(MSFT_ImpInfo))) {
-           return offset;
-       }
+    impinfo_space = (MSFT_ImpInfo*)&This->typelib_segment_data[MSFT_SEG_IMPORTINFO][0];
+    for (offset=0; offset<This->typelib_segdir[MSFT_SEG_IMPORTINFO].length;
+            offset+=sizeof(MSFT_ImpInfo)) {
+        if(impinfo_space->oImpFile == impinfo->oImpFile
+                && impinfo_space->oGuid == impinfo->oGuid)
+            return offset;
+
+        impinfo_space += 1;
     }
 
     impinfo->flags |= This->typelib_header.nimpinfos++;
@@ -701,6 +756,7 @@ static int ctl2_alloc_importinfo(
 static int ctl2_alloc_importfile(
        ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
        int guidoffset,            /* [I] The offset to the GUID for the imported library. */
+        LCID lcid,                 /* [I] The LCID of imported library. */
        int major_version,         /* [I] The major version number of the imported library. */
        int minor_version,         /* [I] The minor version number of the imported library. */
        const WCHAR *filename)     /* [I] The filename of the imported library. */
@@ -726,7 +782,7 @@ static int ctl2_alloc_importfile(
 
     importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset];
     importfile->guid = guidoffset;
-    importfile->lcid = This->typelib_header.lcid2;
+    importfile->lcid = lcid;
     importfile->version = major_version | (minor_version << 16);
     memcpy(importfile->filename, encoded_string, length);
 
@@ -1103,6 +1159,131 @@ static HRESULT ctl2_find_typeinfo_from_offset(
     return TYPE_E_ELEMENTNOTFOUND;
 }
 
+/****************************************************************************
+ *      ctl2_add_default_value
+ *
+ *  Adds default value of an argument
+ *
+ * RETURNS
+ *
+ *  Success: S_OK
+ *  Failure: Error code from winerror.h
+ */
+static HRESULT ctl2_add_default_value(
+        ICreateTypeLib2Impl *This, /* [I] The typelib to allocate data in */
+        int *encoded_value,        /* [O] The encoded default value or data offset */
+        VARIANT *value,            /* [I] Default value to be encoded */
+        VARTYPE arg_type)          /* [I] Argument type */
+{
+    VARIANT v;
+    HRESULT hres;
+
+    TRACE("%p %d %d\n", This, V_VT(value), arg_type);
+
+    if(arg_type == VT_INT)
+        arg_type = VT_I4;
+    if(arg_type == VT_UINT)
+        arg_type = VT_UI4;
+
+    v = *value;
+    if(V_VT(value) != arg_type) {
+        hres = VariantChangeType(&v, value, 0, arg_type);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    /* Check if default value can be stored in encoded_value */
+    switch(arg_type) {
+    int mask = 0;
+    case VT_I4:
+    case VT_UI4:
+        mask = 0x3ffffff;
+        if(V_UI4(&v)>0x3ffffff)
+            break;
+    case VT_I1:
+    case VT_UI1:
+    case VT_BOOL:
+         if(!mask)
+             mask = 0xff;
+    case VT_I2:
+    case VT_UI2:
+        if(!mask)
+            mask = 0xffff;
+        *encoded_value = (V_UI4(&v)&mask) | ((0x80+0x4*arg_type)<<24);
+        return S_OK;
+    }
+
+    switch(arg_type) {
+    case VT_I4:
+    case VT_R4:
+    case VT_UI4:
+    case VT_INT:
+    case VT_UINT:
+    case VT_HRESULT:
+    case VT_PTR: {
+        /* Construct the data to be allocated */
+        int data[2];
+        data[0] = arg_type + (V_UI4(&v)<<16);
+        data[1] = (V_UI4(&v)>>16) + 0x57570000;
+
+        /* Check if the data was already allocated */
+        /* Currently the structures doesn't allow to do it in a nice way */
+        for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-8; *encoded_value+=4)
+            if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8))
+                return S_OK;
+
+        /* Allocate the data */
+        *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, 8, 0);
+        if(*encoded_value == -1)
+            return E_OUTOFMEMORY;
+
+        memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8);
+        return S_OK;
+    }
+    case VT_BSTR: {
+        /* Construct the data */
+        int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3;
+        char *data = HeapAlloc(GetProcessHeap(), 0, len);
+
+        if(!data)
+            return E_OUTOFMEMORY;
+
+        *((unsigned short*)data) = arg_type;
+        *((unsigned*)(data+2)) = SysStringLen(V_BSTR(&v));
+        for(i=0; i<SysStringLen(V_BSTR(&v)); i++) {
+            if(V_BSTR(&v)[i] <= 0x7f)
+                data[i+6] = V_BSTR(&v)[i];
+            else
+                data[i+6] = '?';
+        }
+        WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), SysStringLen(V_BSTR(&v)), &data[6], len-6, NULL, NULL);
+        for(i=6+SysStringLen(V_BSTR(&v)); i<len; i++)
+            data[i] = 0x57;
+
+        /* Check if the data was already allocated */
+        for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-len; *encoded_value+=4)
+            if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len)) {
+                HeapFree(GetProcessHeap(), 0, data);
+                return S_OK;
+            }
+
+        /* Allocate the data */
+        *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, len, 0);
+        if(*encoded_value == -1) {
+            HeapFree(GetProcessHeap(), 0, data);
+            return E_OUTOFMEMORY;
+        }
+
+        memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len);
+        HeapFree(GetProcessHeap(), 0, data);
+        return S_OK;
+    }
+    default:
+        FIXME("Argument type not yet handled\n");
+        return E_NOTIMPL;
+    }
+}
+
 /*================== ICreateTypeInfo2 Implementation ===================================*/
 
 /******************************************************************************
@@ -1170,7 +1351,8 @@ static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
     if (!ref) {
        if (This->typelib) {
            ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib);
-           This->typelib = NULL;
+            /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */
+            /* This->typelib = NULL; */
        }
 
        /* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */
@@ -1239,7 +1421,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U
        guidoffset = ctl2_alloc_guid(This->typelib, &foo);
        if (guidoffset == -1) return E_OUTOFMEMORY;
 
-       fileoffset =  ctl2_alloc_importfile(This->typelib, guidoffset, 2, 0, stdole2tlb);
+       fileoffset =  ctl2_alloc_importfile(This->typelib, guidoffset,
+                This->typelib->typelib_header.lcid2, 2, 0, stdole2tlb);
        if (fileoffset == -1) return E_OUTOFMEMORY;
 
        foo.guid = IID_IDispatch;
@@ -1340,10 +1523,10 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(
 
     TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType);
 
+    if(!pTInfo || !phRefType)
+        return E_INVALIDARG;
+
     /*
-     * If this is one of ours, we set *phRefType to the TYPEINFO offset of
-     * the referred TypeInfo. Otherwise, we presumably have more magic to do.
-     *
      * Unfortunately, we can't rely on the passed-in TypeInfo even having the
      * same internal structure as one of ours. It could be from another
      * implementation of ITypeInfo. So we need to do the following...
@@ -1355,9 +1538,94 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(
     }
 
     if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) {
+        /* Process locally defined TypeInfo */
        *phRefType = This->typelib->typelib_typeinfo_offsets[index];
     } else {
-       FIXME("(%p,%p,%p), pTInfo from different typelib.\n", iface, pTInfo, phRefType);
+        static const WCHAR regkey[] = {'T','y','p','e','L','i','b','\\','{',
+            '%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%',
+            '0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x',
+            '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',
+            '}','\\','%','d','.','%','d','\\','0','\\','w','i','n','3','2',0};
+
+        WCHAR name[MAX_PATH], *p;
+        TLIBATTR *tlibattr;
+        TYPEATTR *typeattr;
+        MSFT_GuidEntry guid, *check_guid;
+        MSFT_ImpInfo impinfo;
+        int guid_offset, import_offset;
+        DWORD len;
+        HRESULT hres;
+
+        /* Allocate container GUID */
+        hres = ITypeLib_GetLibAttr(container, &tlibattr);
+        if(FAILED(hres))
+            return hres;
+
+        guid.guid = tlibattr->guid;
+        guid.hreftype = This->typelib->typelib_guids*12+2;
+        guid.next_hash = -1;
+
+        guid_offset = ctl2_alloc_guid(This->typelib, &guid);
+        if(guid_offset == -1) {
+            ITypeLib_ReleaseTLibAttr(container, tlibattr);
+            return E_OUTOFMEMORY;
+        }
+
+        check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
+        if(check_guid->hreftype == guid.hreftype)
+            This->typelib->typelib_guids++;
+
+        /* Get import file name */
+        /* Check HKEY_CLASSES_ROOT\TypeLib\{GUID}\{Ver}\0\win32 */
+        len = MAX_PATH;
+        sprintfW(name, regkey, guid.guid.Data1, guid.guid.Data2,
+                guid.guid.Data3, guid.guid.Data4[0], guid.guid.Data4[1],
+                guid.guid.Data4[2], guid.guid.Data4[3], guid.guid.Data4[4],
+                guid.guid.Data4[5], guid.guid.Data4[6], guid.guid.Data4[7],
+                tlibattr->wMajorVerNum, tlibattr->wMinorVerNum);
+
+        if(RegGetValueW(HKEY_CLASSES_ROOT, name, NULL, RRF_RT_REG_SZ, NULL, name, &len)!=ERROR_SUCCESS
+            || (p=strrchrW(name, '\\'))==NULL) {
+            ERR("Error guessing typelib filename\n");
+            ITypeLib_ReleaseTLibAttr(container, tlibattr);
+            return E_NOTIMPL;
+        }
+        memmove(name, p+1, strlenW(p)*sizeof(WCHAR));
+
+        /* Import file */
+        import_offset = ctl2_alloc_importfile(This->typelib, guid_offset,
+                tlibattr->lcid, tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, name);
+        ITypeLib_ReleaseTLibAttr(container, tlibattr);
+
+        if(import_offset == -1)
+            return E_OUTOFMEMORY;
+
+        /* Allocate referenced guid */
+        hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr);
+        if(FAILED(hres))
+            return hres;
+
+        guid.guid = typeattr->guid;
+        guid.hreftype = This->typelib->typeinfo_guids*12+1;
+        guid.next_hash = -1;
+        ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr);
+
+        guid_offset = ctl2_alloc_guid(This->typelib, &guid);
+        if(guid_offset == -1)
+            return E_OUTOFMEMORY;
+
+        check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
+        if(check_guid->hreftype == guid.hreftype)
+            This->typelib->typeinfo_guids++;
+
+        /* Allocate importinfo */
+        impinfo.flags = ((This->typeinfo->typekind&0xf)<<24) | MSFT_IMPINFO_OFFSET_IS_GUID;
+        impinfo.oImpFile = import_offset;
+        impinfo.oGuid = guid_offset;
+        *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1;
+
+        if(!memcmp(&guid.guid, &IID_IDispatch, sizeof(GUID)))
+            This->typelib->typelib_header.dispatchpos = *phRefType;
     }
 
     ITypeLib_Release(container);
@@ -1376,71 +1644,131 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
 {
     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
 
-    int offset;
+    CyclicList *iter, *insert;
     int *typedata;
-    int i;
+    int i, num_defaults = 0;
     int decoded_size;
+    HRESULT hres;
+
+    TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc);
+
+    if(!pFuncDesc || (pFuncDesc->memid>0x7fffffff && pFuncDesc->memid!=MEMBERID_NIL))
+        return E_INVALIDARG;
+
+    TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid,
+            pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind,
+            pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams,
+            pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes,
+            pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
+
+    switch(This->typeinfo->typekind&0xf) {
+    case TKIND_MODULE:
+        if(pFuncDesc->funckind != FUNC_STATIC)
+            return TYPE_E_BADMODULEKIND;
+        break;
+    case TKIND_DISPATCH:
+        if(pFuncDesc->funckind != FUNC_DISPATCH)
+            return TYPE_E_BADMODULEKIND;
+        break;
+    default:
+        if(pFuncDesc->funckind != FUNC_PUREVIRTUAL)
+            return TYPE_E_BADMODULEKIND;
+    }
+
+    if(This->typeinfo->cElement<index)
+        return TYPE_E_ELEMENTNOTFOUND;
+
+    if((pFuncDesc->invkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) &&
+        !pFuncDesc->cParams)
+        return TYPE_E_INCONSISTENTPROPFUNCS;
+
+    /* get number of arguments with default values specified */
+    for (i = 0; i < pFuncDesc->cParams; i++)
+        if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
+            num_defaults++;
 
-    FIXME("(%p,%d,%p), stub!\n", iface, index, pFuncDesc);
-    FIXME("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind, pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams, pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
-/*     FIXME("{%d, %d}\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt, pFuncDesc->lprgelemdescParam[1].tdesc.vt); */
-/*     return E_OUTOFMEMORY; */
-    
     if (!This->typedata) {
-       This->typedata = HeapAlloc(GetProcessHeap(), 0, 0x2000);
-       This->typedata[0] = 0;
+       This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
+        if(!This->typedata)
+            return E_OUTOFMEMORY;
+
+        This->typedata->next = This->typedata;
+       This->typedata->u.val = 0;
     }
 
     /* allocate type data space for us */
-    offset = This->typedata[0];
-    This->typedata[0] += 0x18 + (pFuncDesc->cParams * 12);
-    typedata = This->typedata + (offset >> 2) + 1;
+    insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
+    if(!insert)
+        return E_OUTOFMEMORY;
+    insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[6])+sizeof(int[(num_defaults?4:3)])*pFuncDesc->cParams);
+    if(!insert->u.data) {
+        HeapFree(GetProcessHeap(), 0, insert);
+        return E_OUTOFMEMORY;
+    }
 
     /* fill out the basic type information */
-    typedata[0] = (0x18 + (pFuncDesc->cParams * 12)) | (index << 16);
+    typedata = insert->u.data;
+    typedata[0] = 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
     ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size);
     typedata[2] = pFuncDesc->wFuncFlags;
     typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | This->typeinfo->cbSizeVft;
-    typedata[4] = (index << 16) | (pFuncDesc->callconv << 8) | 9;
+    typedata[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind;
+    if(num_defaults) typedata[4] |= 0x1000;
     typedata[5] = pFuncDesc->cParams;
 
     /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */
     /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */
     typedata[3] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16;
+    typedata[3] += (sizeof(PARAMDESCEX) * num_defaults) << 16;
+
+    /* add default values */
+    if(num_defaults) {
+        for (i = 0; i < pFuncDesc->cParams; i++)
+            if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
+                hres = ctl2_add_default_value(This->typelib, typedata+6+i,
+                        &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue,
+                        pFuncDesc->lprgelemdescParam[i].tdesc.vt);
+
+                if(FAILED(hres)) {
+                    HeapFree(GetProcessHeap(), 0, insert->u.data);
+                    HeapFree(GetProcessHeap(), 0, insert);
+                    return hres;
+                }
+            } else
+                typedata[6+i] = 0xffffffff;
+
+        num_defaults = pFuncDesc->cParams;
+    }
 
+    /* add arguments */
     for (i = 0; i < pFuncDesc->cParams; i++) {
-       ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc, &typedata[6+(i*3)], NULL, NULL, &decoded_size);
-       typedata[7+(i*3)] = -1;
-       typedata[8+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
+       ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc,
+                &typedata[6+num_defaults+(i*3)], NULL, NULL, &decoded_size);
+       typedata[7+num_defaults+(i*3)] = -1;
+       typedata[8+num_defaults+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
        typedata[3] += decoded_size << 16;
-
-#if 0
-       /* FIXME: Doesn't work. Doesn't even come up with usable VTs for varDefaultValue. */
-       if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
-           ctl2_alloc_custdata(This->typelib, &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
-       }
-#endif
     }
 
     /* update the index data */
-    This->indices[index] = ((0x6000 | This->typeinfo->cImplTypes) << 16) | index;
-    This->names[index] = -1;
-    This->offsets[index] = offset;
-
-    /* ??? */
-    if (!This->typeinfo->res2) This->typeinfo->res2 = 0x20;
-    This->typeinfo->res2 <<= 1;
-
-    /* ??? */
-    if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0;
-    This->typeinfo->res3 += 0x38;
+    insert->indice = pFuncDesc->memid;
+    insert->name = -1;
+
+    /* insert type data to list */
+    if(index == This->typeinfo->cElement) {
+        insert->next = This->typedata->next;
+        This->typedata->next = insert;
+        This->typedata = insert;
+    } else {
+        iter = This->typedata->next;
+        for(i=0; i<index; i++)
+            iter = iter->next;
 
-    /* ??? */
-    if (index < 2) This->typeinfo->res2 += pFuncDesc->cParams << 4;
-    This->typeinfo->res3 += pFuncDesc->cParams << 4;
+        insert->next = iter->next;
+        iter->next = insert;
+    }
 
-    /* adjust size of VTBL */
-    This->typeinfo->cbSizeVft += 4;
+    /* update type data size */
+    This->typedata->next->u.val += 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
 
     /* Increment the number of function elements */
     This->typeinfo->cElement += 1;
@@ -1497,23 +1825,18 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(
     } else if ((This->typeinfo->typekind & 15) == TKIND_DISPATCH) {
        FIXME("dispatch case unhandled.\n");
     } else if ((This->typeinfo->typekind & 15) == TKIND_INTERFACE) {
-       if (This->typeinfo->cImplTypes) {
-           return (index == 1)? TYPE_E_BADMODULEKIND: TYPE_E_ELEMENTNOTFOUND;
-       }
-
-       if (index != 0)  return TYPE_E_ELEMENTNOTFOUND;
+        if (This->typeinfo->cImplTypes && index==1)
+            return TYPE_E_BADMODULEKIND;
 
-       This->typeinfo->cImplTypes++;
+        if( index != 0)  return TYPE_E_ELEMENTNOTFOUND;
 
-       /* hacked values for IDispatch only, and maybe only for stdole. */
-       This->typeinfo->cbSizeVft += 0x0c; /* hack */
-       This->typeinfo->datatype1 = hRefType;
-       This->typeinfo->datatype2 = (3 << 16) | 1; /* ? */
+        This->typeinfo->datatype1 = hRefType;
     } else {
        FIXME("AddImplType unsupported on typekind %d\n", This->typeinfo->typekind & 15);
        return E_OUTOFMEMORY;
     }
 
+    This->typeinfo->cImplTypes++;
     return S_OK;
 }
 
@@ -1614,7 +1937,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(
         VARDESC* pVarDesc)
 {
     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
-    int offset;
+
+    CyclicList *insert;
     INT *typedata;
     int var_datawidth;
     int var_alignment;
@@ -1633,14 +1957,30 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(
     }
 
     if (!This->typedata) {
-       This->typedata = HeapAlloc(GetProcessHeap(), 0, 0x2000);
-       This->typedata[0] = 0;
+        This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
+        if(!This->typedata)
+            return E_OUTOFMEMORY;
+
+        This->typedata->next = This->typedata;
+        This->typedata->u.val = 0;
     }
 
     /* allocate type data space for us */
-    offset = This->typedata[0];
-    This->typedata[0] += 0x14;
-    typedata = This->typedata + (offset >> 2) + 1;
+    insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
+    if(!insert)
+        return E_OUTOFMEMORY;
+    insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[5]));
+    if(!insert->u.data) {
+        HeapFree(GetProcessHeap(), 0, insert);
+        return E_OUTOFMEMORY;
+    }
+
+    insert->next = This->typedata->next;
+    This->typedata->next = insert;
+    This->typedata = insert;
+
+    This->typedata->next->u.val += 0x14;
+    typedata = This->typedata->u.data;
 
     /* fill out the basic type information */
     typedata[0] = 0x14 | (index << 16);
@@ -1648,9 +1988,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(
     typedata[3] = (sizeof(VARDESC) << 16) | 0;
 
     /* update the index data */
-    This->indices[index] = 0x40000000 + index;
-    This->names[index] = -1;
-    This->offsets[index] = offset;
+    insert->indice = 0x40000000 + index;
+    insert->name = -1;
 
     /* figure out type widths and whatnot */
     ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc,
@@ -1707,28 +2046,50 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(
         UINT cNames)
 {
     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
-
-    UINT i;
-    int offset;
+    CyclicList *iter = NULL, *iter2;
+    int offset, len, i=0;
     char *namedata;
 
-    FIXME("(%p,%d,%s,%d), stub!\n", iface, index, debugstr_w(*rgszNames), cNames);
+    TRACE("(%p %d %p %d)\n", iface, index, rgszNames, cNames);
+
+    if(!rgszNames)
+        return E_INVALIDARG;
+
+    if(index >= This->typeinfo->cElement || !cNames)
+        return TYPE_E_ELEMENTNOTFOUND;
+
+    len = ctl2_encode_name(This->typelib, rgszNames[0], &namedata);
+    for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
+        if(i == index)
+            iter = iter2;
+        else if(iter2->name!=-1 && !memcmp(namedata,
+                    This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len))
+            return TYPE_E_AMBIGUOUSNAME;
+
+        i++;
+    }
+
+    /* cNames == cParams for put or putref accessor, cParams+1 otherwise */
+    if(cNames != iter->u.data[5] + ((iter->u.data[4]>>3)&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1))
+        return TYPE_E_ELEMENTNOTFOUND;
 
     offset = ctl2_alloc_name(This->typelib, rgszNames[0]);
-    This->names[index] = offset;
+    if(offset == -1)
+        return E_OUTOFMEMORY;
+
+    iter->name = offset;
 
     namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
-    namedata[9] &= ~0x10;
-    if (*((INT *)namedata) == -1) {
-       *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
-    }
+    *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
 
-    for (i = 1; i < cNames; i++) {
-       /* FIXME: Almost certainly easy to break */
-       int *paramdata = &This->typedata[This->offsets[index] >> 2];
+    if(iter->u.data[4]&0x1000)
+        len = iter->u.data[5];
+    else
+        len = 0;
 
+    for (i = 1; i < cNames; i++) {
        offset = ctl2_alloc_name(This->typelib, rgszNames[i]);
-       paramdata[(i * 3) + 5] = offset;
+       iter->u.data[(i*3) + 4 + len] = offset;
     }
 
     return S_OK;
@@ -1745,7 +2106,8 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(
         LPOLESTR szName)
 {
     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
-    int offset;
+    CyclicList *iter;
+    int offset, i;
     char *namedata;
 
     TRACE("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szName));
@@ -1766,8 +2128,12 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(
     if ((This->typeinfo->typekind & 15) == TKIND_ENUM) {
        namedata[9] |= 0x20;
     }
-    This->names[index] = offset;
 
+    iter = This->typedata->next->next;
+    for(i=0; i<index; i++)
+        iter = iter->next;
+
+    iter->name = offset;
     return S_OK;
 }
 
@@ -1912,8 +2278,161 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc(
 static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
        ICreateTypeInfo2* iface)
 {
-    TRACE("(%p), stub!\n", iface);
-/*     return E_OUTOFMEMORY; */
+    ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
+    CyclicList *iter, *iter2, **typedata;
+    HREFTYPE hreftype;
+    HRESULT hres;
+    int i;
+
+    TRACE("(%p)\n", iface);
+
+    if((This->typeinfo->typekind&0xf) == TKIND_COCLASS)
+        return S_OK;
+
+    /* Validate inheritance */
+    This->typeinfo->datatype2 = 0;
+    hreftype = This->typeinfo->datatype1;
+
+    /* Process internally defined interfaces */
+    for(i=0; i<This->typelib->typelib_header.nrtypeinfos; i++) {
+        MSFT_TypeInfoBase *header;
+
+        if(hreftype&1)
+            break;
+
+        header = (MSFT_TypeInfoBase*)&(This->typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][hreftype]);
+        This->typeinfo->datatype2 += (header->cElement<<16) + 1;
+        hreftype = header->datatype1;
+    }
+    if(i == This->typelib->typelib_header.nrtypeinfos)
+        return TYPE_E_CIRCULARTYPE;
+
+    /* Process externally defined interfaces */
+    if(hreftype != -1) {
+        ITypeInfo *cur, *next;
+        TYPEATTR *typeattr;
+
+        hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&next);
+        if(FAILED(hres))
+            return hres;
+
+        hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur);
+        if(FAILED(hres))
+            return hres;
+
+        ITypeInfo_Release(next);
+
+        while(1) {
+            hres = ITypeInfo_GetTypeAttr(cur, &typeattr);
+            if(FAILED(hres))
+                return hres;
+
+            if(!memcmp(&typeattr->guid, &IID_IDispatch, sizeof(IDispatch)))
+                This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;
+
+            This->typeinfo->datatype2 += (typeattr->cFuncs<<16) + 1;
+            ITypeInfo_ReleaseTypeAttr(cur, typeattr);
+
+            hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype);
+            if(hres == TYPE_E_ELEMENTNOTFOUND)
+                break;
+            if(FAILED(hres))
+                return hres;
+
+            hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next);
+            if(FAILED(hres))
+                return hres;
+
+            ITypeInfo_Release(cur);
+            cur = next;
+        }
+    }
+
+    This->typeinfo->cbSizeVft = (This->typeinfo->datatype2>>16) * 4;
+    if(!This->typedata)
+        return S_OK;
+
+    typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*(This->typeinfo->cElement&0xffff));
+    if(!typedata)
+        return E_OUTOFMEMORY;
+
+    /* Assign IDs and VTBL entries */
+    i = 0;
+    for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
+        /* Assign MEMBERID if MEMBERID_NIL was specified */
+        if(iter->indice == MEMBERID_NIL) {
+            iter->indice = 0x60000000 + i + (This->typeinfo->datatype2<<16);
+
+            for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
+                if(iter == iter2) continue;
+                if(iter2->indice == iter->indice) {
+                    iter->indice = 0x5fffffff + This->typeinfo->cElement + i + (This->typeinfo->datatype2<<16);
+
+                    for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
+                        if(iter == iter2) continue;
+                        if(iter2->indice == iter->indice)
+                            return E_ACCESSDENIED;
+                    }
+
+                    break;
+                }
+            }
+        }
+
+        typedata[i] = iter;
+
+        iter->u.data[0] = (iter->u.data[0]&0xffff) | (i<<16);
+
+        if((This->typeinfo->typekind&0xf) != TKIND_MODULE) {
+            iter->u.data[3] = (iter->u.data[3]&0xffff0000) | This->typeinfo->cbSizeVft;
+            This->typeinfo->cbSizeVft += 4;
+        }
+
+        /* Construct a list of elements with the same memberid */
+        iter->u.data[4] = (iter->u.data[4]&0xffff) | (i<<16);
+        for(iter2=This->typedata->next->next; iter2!=iter; iter2=iter2->next) {
+            if(iter->indice == iter2->indice) {
+                int v1, v2;
+
+                v1 = iter->u.data[4] >> 16;
+                v2 = iter2->u.data[4] >> 16;
+
+                iter->u.data[4] = (iter->u.data[4]&0xffff) | (v2<<16);
+                iter2->u.data[4] = (iter2->u.data[4]&0xffff) | (v1<<16);
+                break;
+            }
+        }
+
+        i++;
+    }
+
+    for(i=0; i<(This->typeinfo->cElement&0xffff); i++) {
+        if(typedata[i]->u.data[4]>>16 > i) {
+            int inv;
+
+            inv = (typedata[i]->u.data[4]>>3) & 0xf;
+            i = typedata[i]->u.data[4] >> 16;
+
+            while(i > typedata[i]->u.data[4]>>16) {
+                int invkind = (typedata[i]->u.data[4]>>3) & 0xf;
+
+                if(inv & invkind) {
+                    HeapFree(GetProcessHeap(), 0, typedata);
+                    return TYPE_E_DUPLICATEID;
+                }
+
+                i = typedata[i]->u.data[4] >> 16;
+                inv |= invkind;
+            }
+
+            if(inv & INVOKE_FUNC) {
+                HeapFree(GetProcessHeap(), 0, typedata);
+                return TYPE_E_INCONSISTENTPROPFUNCS;
+            }
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, typedata);
     return S_OK;
 }
 
@@ -2243,8 +2762,45 @@ static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr(
         ITypeInfo2* iface,
         TYPEATTR** ppTypeAttr)
 {
-    FIXME("(%p,%p), stub!\n", iface, ppTypeAttr);
-    return E_OUTOFMEMORY;
+    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+    HRESULT hres;
+
+    TRACE("(%p,%p)\n", iface, ppTypeAttr);
+
+    if(!ppTypeAttr)
+        return E_INVALIDARG;
+
+    hres = ICreateTypeInfo_LayOut((ICreateTypeInfo*)This);
+    if(FAILED(hres))
+        return hres;
+
+    *ppTypeAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPEATTR));
+    if(!*ppTypeAttr)
+        return E_OUTOFMEMORY;
+
+    if(This->typeinfo->posguid != -1) {
+        MSFT_GuidEntry *guid;
+
+        guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][This->typeinfo->posguid];
+        (*ppTypeAttr)->guid = guid->guid;
+    }
+
+    (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid;
+    (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size;
+    (*ppTypeAttr)->typekind = This->typeinfo->typekind&0xf;
+    (*ppTypeAttr)->cFuncs = This->typeinfo->cElement&0xffff;
+    (*ppTypeAttr)->cVars = This->typeinfo->cElement>>16;
+    (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes;
+    (*ppTypeAttr)->cbSizeVft = This->typeinfo->cbSizeVft;
+    (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f;
+    (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags;
+    (*ppTypeAttr)->wMajorVerNum = This->typeinfo->version&0xffff;
+    (*ppTypeAttr)->wMinorVerNum = This->typeinfo->version>>16;
+
+    if((*ppTypeAttr)->typekind == TKIND_ALIAS)
+        FIXME("TKIND_ALIAS handling not implemented\n");
+
+    return S_OK;
 }
 
 /******************************************************************************
@@ -2314,8 +2870,35 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType(
         UINT index,
         HREFTYPE* pRefType)
 {
-    FIXME("(%p,%d,%p), stub!\n", iface, index, pRefType);
-    return E_OUTOFMEMORY;
+    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+    MSFT_RefRecord *ref;
+    int offset;
+
+    TRACE("(%p,%d,%p)\n", iface, index, pRefType);
+
+    if(!pRefType)
+        return E_INVALIDARG;
+
+    if(index == -1) {
+        FIXME("Dual interfaces not handled yet\n");
+        return E_NOTIMPL;
+    }
+
+    if(index >= This->typeinfo->cImplTypes)
+        return TYPE_E_ELEMENTNOTFOUND;
+
+    if((This->typeinfo->typekind&0xf) == TKIND_INTERFACE) {
+        *pRefType = This->typeinfo->datatype1 + 2;
+        return S_OK;
+    }
+
+    offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
+    if(offset == -1)
+        return TYPE_E_ELEMENTNOTFOUND;
+
+    ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
+    *pRefType = ref->reftype;
+    return S_OK;
 }
 
 /******************************************************************************
@@ -2328,8 +2911,30 @@ static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags(
         UINT index,
         INT* pImplTypeFlags)
 {
-    FIXME("(%p,%d,%p), stub!\n", iface, index, pImplTypeFlags);
-    return E_OUTOFMEMORY;
+    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+    int offset;
+    MSFT_RefRecord *ref;
+
+    TRACE("(%p,%d,%p)\n", iface, index, pImplTypeFlags);
+
+    if(!pImplTypeFlags)
+        return E_INVALIDARG;
+
+    if(index >= This->typeinfo->cImplTypes)
+        return TYPE_E_ELEMENTNOTFOUND;
+
+    if((This->typeinfo->typekind&0xf) != TKIND_COCLASS) {
+        *pImplTypeFlags = 0;
+        return S_OK;
+    }
+
+    offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
+    if(offset == -1)
+        return TYPE_E_ELEMENTNOTFOUND;
+
+    ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
+    *pImplTypeFlags = ref->flags;
+    return S_OK;
 }
 
 /******************************************************************************
@@ -2410,8 +3015,54 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo(
         HREFTYPE hRefType,
         ITypeInfo** ppTInfo)
 {
-    FIXME("(%p,%d,%p), stub!\n", iface, hRefType, ppTInfo);
-    return E_OUTOFMEMORY;
+    ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
+
+    TRACE("(%p,%d,%p)\n", iface, hRefType, ppTInfo);
+
+    if(!ppTInfo)
+        return E_INVALIDARG;
+
+    if(hRefType&1) {
+        ITypeLib *tl;
+        MSFT_ImpInfo *impinfo;
+        MSFT_ImpFile *impfile;
+        MSFT_GuidEntry *guid;
+        WCHAR *filename;
+        HRESULT hres;
+
+        if((hRefType&(~0x3)) >= This->typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length)
+            return E_FAIL;
+
+        impinfo = (MSFT_ImpInfo*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][hRefType&(~0x3)];
+        impfile = (MSFT_ImpFile*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][impinfo->oImpFile];
+        guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo->oGuid];
+
+        ctl2_decode_string(impfile->filename, &filename);
+
+        hres = LoadTypeLib(filename, &tl);
+        if(FAILED(hres))
+            return hres;
+
+        hres = ITypeLib_GetTypeInfoOfGuid(tl, &guid->guid, ppTInfo);
+
+        ITypeLib_Release(tl);
+        return hres;
+    } else {
+        ICreateTypeInfo2Impl *iter;
+        int i = 0;
+
+        for(iter=This->typelib->typeinfos; iter; iter=iter->next_typeinfo) {
+            if(This->typelib->typelib_typeinfo_offsets[i] == (hRefType&(~0x3))) {
+                *ppTInfo = (ITypeInfo*)&iter->lpVtblTypeInfo2;
+
+                ITypeLib_AddRef(*ppTInfo);
+                return S_OK;
+            }
+            i++;
+        }
+    }
+
+    return E_FAIL;
 }
 
 /******************************************************************************
@@ -2488,7 +3139,9 @@ static void WINAPI ITypeInfo2_fnReleaseTypeAttr(
         ITypeInfo2* iface,
         TYPEATTR* pTypeAttr)
 {
-    FIXME("(%p,%p), stub!\n", iface, pTypeAttr);
+    TRACE("(%p,%p)\n", iface, pTypeAttr);
+
+    HeapFree(GetProcessHeap(), 0, pTypeAttr);
 }
 
 /******************************************************************************
@@ -3049,7 +3702,21 @@ static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
        while (This->typeinfos) {
            ICreateTypeInfo2Impl *typeinfo = This->typeinfos;
            This->typeinfos = typeinfo->next_typeinfo;
-            HeapFree(GetProcessHeap(), 0, typeinfo->typedata);
+            if(typeinfo->typedata) {
+                CyclicList *iter, *rem;
+
+                rem = typeinfo->typedata->next;
+                typeinfo->typedata->next = NULL;
+                iter = rem->next;
+                HeapFree(GetProcessHeap(), 0, rem);
+
+                while(iter) {
+                    rem = iter;
+                    iter = iter->next;
+                    HeapFree(GetProcessHeap(), 0, rem->u.data);
+                    HeapFree(GetProcessHeap(), 0, rem);
+                }
+            }
            HeapFree(GetProcessHeap(), 0, typeinfo);
        }
 
@@ -3073,9 +3740,14 @@ static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(
        ICreateTypeInfo **ppCTInfo)
 {
     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
+    char *name;
 
     TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, ppCTInfo);
 
+    ctl2_encode_name(This, szName, &name);
+    if(ctl2_find_name(This, name) != -1)
+        return TYPE_E_NAMECONFLICT;
+
     *ppCTInfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind);
 
     if (!*ppCTInfo) return E_OUTOFMEMORY;
@@ -3260,17 +3932,25 @@ static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segme
     return -1;
 }
 
-static void ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
+static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
 {
     ICreateTypeInfo2Impl *typeinfo;
+    HRESULT hres;
 
     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
-       typeinfo->typeinfo->memoffset = filesize;
-       if (typeinfo->typedata) {
-           ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
-           filesize += typeinfo->typedata[0] + ((typeinfo->typeinfo->cElement >> 16) * 12) + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
-       }
+        typeinfo->typeinfo->memoffset = filesize;
+
+        hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
+        if(FAILED(hres))
+            return hres;
+
+       if (typeinfo->typedata)
+           filesize += typeinfo->typedata->next->u.val
+                + ((typeinfo->typeinfo->cElement >> 16) * 12)
+                + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
     }
+
+    return S_OK;
 }
 
 static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment)
@@ -3289,12 +3969,26 @@ static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile)
     ICreateTypeInfo2Impl *typeinfo;
 
     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
+        CyclicList *iter;
+        int offset = 0;
+
        if (!typeinfo->typedata) continue;
 
-       ctl2_write_chunk(hFile, typeinfo->typedata, typeinfo->typedata[0] + 4);
-       ctl2_write_chunk(hFile, typeinfo->indices, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4);
-       ctl2_write_chunk(hFile, typeinfo->names, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4);
-       ctl2_write_chunk(hFile, typeinfo->offsets, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4);
+        iter = typeinfo->typedata->next;
+        ctl2_write_chunk(hFile, &iter->u.val, sizeof(int));
+        for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next)
+            ctl2_write_chunk(hFile, iter->u.data, iter->u.data[0] & 0xffff);
+
+        for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
+            ctl2_write_chunk(hFile, &iter->indice, sizeof(int));
+
+        for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
+            ctl2_write_chunk(hFile, &iter->name, sizeof(int));
+
+        for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) {
+            ctl2_write_chunk(hFile, &offset, sizeof(int));
+            offset += iter->u.data[0] & 0xffff;
+        }
     }
 }
 
@@ -3310,6 +4004,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
     int retval;
     int filepos;
     HANDLE hFile;
+    HRESULT hres;
 
     TRACE("(%p)\n", iface);
 
@@ -3324,9 +4019,9 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO);
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH);
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID);
+    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES);
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO);
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES);
-    filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES);
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH);
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME);
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING);
@@ -3335,7 +4030,11 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA);
     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID);
 
-    ctl2_finalize_typeinfos(This, filepos);
+    hres = ctl2_finalize_typeinfos(This, filepos);
+    if(FAILED(hres)) {
+        CloseHandle(hFile);
+        return hres;
+    }
 
     if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval;
     if (This->typelib_header.varflags & HELPDLLFLAG)
@@ -3345,9 +4044,9 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
     if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO    )) return retval;
     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH    )) return retval;
     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID        )) return retval;
+    if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES  )) return retval;
     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO  )) return retval;
     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval;
-    if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES  )) return retval;
     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH    )) return retval;
     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME        )) return retval;
     if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING      )) return retval;
@@ -3360,8 +4059,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
 
     if (!CloseHandle(hFile)) return retval;
 
-    retval = S_OK;
-    return retval;
+    return S_OK;
 }
 
 
@@ -3596,9 +4294,28 @@ static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
 {
     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
 
-    FIXME("(%p,%p), stub!\n", This, ppTLibAttr);
+    TRACE("(%p,%p)\n", This, ppTLibAttr);
 
-    return E_OUTOFMEMORY;
+    if(!ppTLibAttr)
+        return E_INVALIDARG;
+
+    *ppTLibAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TLIBATTR));
+    if(!*ppTLibAttr)
+        return E_OUTOFMEMORY;
+
+    if(This->typelib_header.posguid != -1) {
+        MSFT_GuidEntry *guid;
+
+        guid = (MSFT_GuidEntry*)&This->typelib_segment_data[MSFT_SEG_GUID][This->typelib_header.posguid];
+        (*ppTLibAttr)->guid = guid->guid;
+    }
+
+    (*ppTLibAttr)->lcid = This->typelib_header.lcid;
+    (*ppTLibAttr)->syskind = This->typelib_header.varflags&0x3;
+    (*ppTLibAttr)->wMajorVerNum = This->typelib_header.version&0xffff;
+    (*ppTLibAttr)->wMinorVerNum = This->typelib_header.version>>16;
+    (*ppTLibAttr)->wLibFlags = This->typelib_header.flags;
+    return S_OK;
 }
 
 /******************************************************************************
@@ -3631,10 +4348,71 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
         BSTR* pBstrHelpFile)
 {
     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
+    WCHAR *string;
 
-    FIXME("(%p,%d,%p,%p,%p,%p), stub!\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
+    TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
 
-    return E_OUTOFMEMORY;
+    if(index != -1) {
+        ICreateTypeInfo2Impl *iter;
+
+        for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo)
+            index--;
+
+        if(!iter)
+            return TYPE_E_ELEMENTNOTFOUND;
+
+        return ITypeInfo_GetDocumentation((ITypeInfo*)iter->lpVtblTypeInfo2,
+                -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
+    }
+
+    if(pBstrName) {
+        if(This->typelib_header.NameOffset == -1)
+            *pBstrName = NULL;
+        else {
+            MSFT_NameIntro *name = (MSFT_NameIntro*)&This->
+                typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset];
+
+            ctl2_decode_name((char*)&name->namelen, &string);
+
+            *pBstrName = SysAllocString(string);
+            if(!*pBstrName)
+                return E_OUTOFMEMORY;
+        }
+    }
+
+    if(pBstrDocString) {
+        if(This->typelib_header.helpstring == -1)
+            *pBstrDocString = NULL;
+        else {
+            ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string);
+
+            *pBstrDocString = SysAllocString(string);
+            if(!*pBstrDocString) {
+                if(pBstrName) SysFreeString(*pBstrName);
+                return E_OUTOFMEMORY;
+            }
+        }
+    }
+
+    if(pdwHelpContext)
+        *pdwHelpContext = This->typelib_header.helpcontext;
+
+    if(pBstrHelpFile) {
+        if(This->typelib_header.helpfile == -1)
+            *pBstrHelpFile = NULL;
+        else {
+            ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string);
+
+            *pBstrHelpFile = SysAllocString(string);
+            if(!*pBstrHelpFile) {
+                if(pBstrName) SysFreeString(*pBstrName);
+                if(pBstrDocString) SysFreeString(*pBstrDocString);
+                return E_OUTOFMEMORY;
+            }
+        }
+    }
+
+    return S_OK;
 }
 
 /******************************************************************************
@@ -3702,9 +4480,9 @@ static void WINAPI ITypeLib2_fnReleaseTLibAttr(
         ITypeLib2 * iface,
         TLIBATTR* pTLibAttr)
 {
-    ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
+    TRACE("(%p,%p)\n", iface, pTLibAttr);
 
-    FIXME("(%p,%p), stub!\n", This, pTLibAttr);
+    HeapFree(GetProcessHeap(), 0, pTLibAttr);
 }
 
 /******************************************************************************
index 3172eba..402794c 100644 (file)
@@ -256,20 +256,21 @@ static unsigned int get_type_alignment(ULONG *pFlags, VARTYPE vt)
 
 static unsigned interface_variant_size(const ULONG *pFlags, REFIID riid, IUnknown *punk)
 {
-  ULONG size;
-  HRESULT hr;
-  /* find the buffer size of the marshalled dispatch interface */
-  hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
-  if (FAILED(hr)) {
-    if (!punk)
-      WARN("NULL dispatch pointer\n");
-    else
-      ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%x\n", hr);
-    return 0;
-  }
-  size += sizeof(ULONG); /* we have to store the buffersize in the stream */
-  TRACE("wire-size extra of dispatch variant is %d\n", size);
-  return size;
+    ULONG size = 0;
+    HRESULT hr;
+
+    if (punk)
+    {
+        hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
+        if (FAILED(hr))
+        {
+            ERR("interface variant buffer size calculation failed, HRESULT=0x%x\n", hr);
+            return 0;
+        }
+    }
+    size += sizeof(ULONG); /* we have to store the buffersize in the stream */
+    TRACE("wire-size extra of interface variant is %d\n", size);
+    return size;
 }
 
 static ULONG wire_extra_user_size(ULONG *pFlags, ULONG Start, VARIANT *pvar)
@@ -322,6 +323,12 @@ static unsigned char* interface_variant_marshal(const ULONG *pFlags, unsigned ch
   
   TRACE("pFlags=%d, Buffer=%p, pUnk=%p\n", *pFlags, Buffer, punk);
 
+  if(!punk)
+  {
+      memset(Buffer, 0, sizeof(ULONG));
+      return Buffer + sizeof(ULONG);
+  }
+
   oldpos = Buffer;
   
   /* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers.
@@ -378,6 +385,12 @@ static unsigned char *interface_variant_unmarshal(const ULONG *pFlags, unsigned
   memcpy(&size, Buffer, sizeof(ULONG));
   TRACE("buffersize=%d\n", size);
 
+  if(!size)
+  {
+      *ppunk = NULL;
+      return Buffer + sizeof(ULONG);
+  }
+
   working_mem = GlobalAlloc(0, size);
   if (!working_mem) return oldpos;
 
@@ -552,14 +565,29 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
 
     if(header->vt & VT_BYREF)
     {
+        ULONG mem_size;
         Pos += 4;
+
+        switch (header->vt & ~VT_BYREF)
+        {
+        /* these types have a different memory size compared to wire size */
+        case VT_UNKNOWN:
+        case VT_DISPATCH:
+        case VT_BSTR:
+            mem_size = sizeof(void *);
+            break;
+        default:
+            mem_size = type_size;
+            break;
+        }
+
         if (V_VT(pvar) != header->vt)
         {
             VariantClear(pvar);
-            V_BYREF(pvar) = CoTaskMemAlloc(type_size);
+            V_BYREF(pvar) = CoTaskMemAlloc(mem_size);
         }
         else if (!V_BYREF(pvar))
-            V_BYREF(pvar) = CoTaskMemAlloc(type_size);
+            V_BYREF(pvar) = CoTaskMemAlloc(mem_size);
         memcpy(V_BYREF(pvar), Pos, type_size);
         if((header->vt & VT_TYPEMASK) != VT_VARIANT)
             Pos += type_size;
@@ -748,6 +776,26 @@ static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa)
     }
 }
 
+static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype)
+{
+    if (sftype == SF_BSTR)
+        return sizeof(DWORD);
+    else if (sftype == SF_VARIANT)
+        return sizeof(variant_wire_t) - sizeof(DWORD);
+    else
+        return lpsa->cbElements;
+}
+
+static DWORD elem_mem_size(wireSAFEARRAY wiresa, SF_TYPE sftype)
+{
+    if (sftype == SF_BSTR)
+        return sizeof(BSTR);
+    else if (sftype == SF_VARIANT)
+        return sizeof(VARIANT);
+    else
+        return wiresa->cbElements;
+}
+
 ULONG WINAPI LPSAFEARRAY_UserSize(ULONG *pFlags, ULONG StartingSize, LPSAFEARRAY *ppsa)
 {
     ULONG size = StartingSize;
@@ -853,13 +901,15 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf
         SF_TYPE sftype;
         GUID guid;
 
+        sftype = SAFEARRAY_GetUnionType(psa);
+
         *(ULONG *)Buffer = psa->cDims;
         Buffer += sizeof(ULONG);
         *(USHORT *)Buffer = psa->cDims;
         Buffer += sizeof(USHORT);
         *(USHORT *)Buffer = psa->fFeatures;
         Buffer += sizeof(USHORT);
-        *(ULONG *)Buffer = psa->cbElements;
+        *(ULONG *)Buffer = elem_wire_size(psa, sftype);
         Buffer += sizeof(ULONG);
 
         hr = SafeArrayGetVartype(psa, &vt);
@@ -868,7 +918,6 @@ unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buf
         *(ULONG *)Buffer = (USHORT)psa->cLocks | (vt << 16);
         Buffer += sizeof(ULONG);
 
-        sftype = SAFEARRAY_GetUnionType(psa);
         *(ULONG *)Buffer = sftype;
         Buffer += sizeof(ULONG);
 
@@ -1028,7 +1077,7 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
     (*ppsa)->fFeatures &= FADF_AUTOSETFLAGS;
     (*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS));
     /* FIXME: there should be a limit on how large wiresa->cbElements can be */
-    (*ppsa)->cbElements = wiresa->cbElements;
+    (*ppsa)->cbElements = elem_mem_size(wiresa, sftype);
     (*ppsa)->cLocks = LOWORD(wiresa->cLocks);
 
     /* SafeArrayCreateEx allocates the data for us, but
@@ -1180,6 +1229,8 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
       if (V_ISBYREF(arg)) {
        rgVarRefIdx[cVarRef] = u;
        VariantInit(&rgVarRef[cVarRef]);
+       VariantCopy(&rgVarRef[cVarRef], arg);
+       VariantClear(arg);
        cVarRef++;
       }
     }
@@ -1265,6 +1316,12 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
   }
 
   if (SUCCEEDED(hr)) {
+    /* copy ref args to arg array */
+    for (u=0; u<cVarRef; u++) {
+      unsigned i = rgVarRefIdx[u];
+      VariantCopy(&arg[i], &rgVarRef[u]);
+    }
+
     pDispParams->rgvarg = arg;
 
     hr = IDispatch_Invoke(This,
@@ -1277,14 +1334,10 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
                          pExcepInfo,
                          pArgErr);
 
-    /* copy ref args to out list */
+    /* copy ref args from arg array */
     for (u=0; u<cVarRef; u++) {
       unsigned i = rgVarRefIdx[u];
-      VariantInit(&rgVarRef[u]);
       VariantCopy(&rgVarRef[u], &arg[i]);
-      /* clear original if equal, to avoid double-free */
-      if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
-        VariantClear(&rgvarg[i]);
     }
   }
 
index f6c142d..10f5038 100644 (file)
@@ -1264,13 +1264,11 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
       /* Exponent format: length of the integral number part is fixed and
          specified by the format. */
       pad = need_int - have_int;
-      if (pad >= 0)
-        exponent -= pad;
-      else
+      exponent -= pad;
+      if (pad < 0)
       {
         have_int = need_int;
         have_frac -= pad;
-        exponent -= pad;
         pad = 0;
       }
     }
@@ -1285,6 +1283,14 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
         have_frac = -pad;
         pad = 0;
       }
+      if(exponent < 0 && exponent > (-256 + have_int + have_frac))
+      {
+        /* Remove exponent notation */
+        memmove(rgbDig - exponent, rgbDig, have_int + have_frac);
+        ZeroMemory(rgbDig, -exponent);
+        have_frac -= exponent;
+        exponent = 0;
+      }
     }
 
     /* Rounding the number */
@@ -1313,10 +1319,10 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
         }
         else
           (*prgbDig)++;
-        /* We converted trailing digits to zeroes => have_frac has changed */
-        while (have_frac > 0 && rgbDig[have_int + have_frac - 1] == 0)
-          have_frac--;
       }
+      /* We converted trailing digits to zeroes => have_frac has changed */
+      while (have_frac > 0 && rgbDig[have_int + have_frac - 1] == 0)
+        have_frac--;
     }
     TRACE("have_int=%d,need_int=%d,have_frac=%d,need_frac=%d,pad=%d,exp=%d\n",
           have_int, need_int, have_frac, need_frac, pad, exponent);
@@ -1957,7 +1963,7 @@ static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat,
     if (FAILED(hRes))
       return hRes;
 
-    if (V_BSTR(pVarIn)[0] == '\0')
+    if (V_BSTR(&vStr)[0] == '\0')
       strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetNegative(header));
     else
       strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetPositive(header));
index e92a63d..450856f 100644 (file)
@@ -578,6 +578,66 @@ void WINAPI VariantInit(VARIANTARG* pVarg)
   V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */
 }
 
+HRESULT VARIANT_ClearInd(VARIANTARG *pVarg)
+{
+    HRESULT hres;
+
+    TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
+
+    hres = VARIANT_ValidateType(V_VT(pVarg));
+    if (FAILED(hres))
+        return hres;
+
+    switch (V_VT(pVarg))
+    {
+    case VT_DISPATCH:
+    case VT_UNKNOWN:
+        if (V_UNKNOWN(pVarg))
+            IUnknown_Release(V_UNKNOWN(pVarg));
+        break;
+    case VT_UNKNOWN | VT_BYREF:
+    case VT_DISPATCH | VT_BYREF:
+        if(*V_UNKNOWNREF(pVarg))
+            IUnknown_Release(*V_UNKNOWNREF(pVarg));
+        break;
+    case VT_BSTR:
+        SysFreeString(V_BSTR(pVarg));
+        break;
+    case VT_BSTR | VT_BYREF:
+        SysFreeString(*V_BSTRREF(pVarg));
+        break;
+    case VT_VARIANT | VT_BYREF:
+        VariantClear(V_VARIANTREF(pVarg));
+        break;
+    case VT_RECORD:
+    case VT_RECORD | VT_BYREF:
+    {
+        struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal);
+        if (pBr->pRecInfo)
+        {
+            IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord);
+            IRecordInfo_Release(pBr->pRecInfo);
+        }
+        break;
+    }
+    default:
+        if (V_ISARRAY(pVarg) || (V_VT(pVarg) & ~VT_BYREF) == VT_SAFEARRAY)
+        {
+            if (V_ISBYREF(pVarg))
+            {
+                if (*V_ARRAYREF(pVarg))
+                    hres = SafeArrayDestroy(*V_ARRAYREF(pVarg));
+            }
+            else if (V_ARRAY(pVarg))
+                hres = SafeArrayDestroy(V_ARRAY(pVarg));
+        }
+        break;
+    }
+
+    V_VT(pVarg) = VT_EMPTY;
+    return hres;
+}
+
 /******************************************************************************
  *             VariantClear    [OLEAUT32.9]
  *
@@ -1069,71 +1129,66 @@ static inline double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day
 static HRESULT VARIANT_RollUdate(UDATE *lpUd)
 {
   static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+  short iYear, iMonth, iDay, iHour, iMinute, iSecond;
 
-  TRACE("Raw date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
-        lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
+  /* interpret values signed */
+  iYear   = lpUd->st.wYear;
+  iMonth  = lpUd->st.wMonth;
+  iDay    = lpUd->st.wDay;
+  iHour   = lpUd->st.wHour;
+  iMinute = lpUd->st.wMinute;
+  iSecond = lpUd->st.wSecond;
 
-  /* Years < 100 are treated as 1900 + year */
-  if (lpUd->st.wYear < 100)
-    lpUd->st.wYear += 1900;
+  TRACE("Raw date: %d/%d/%d %d:%d:%d\n", iDay, iMonth,
+        iYear, iHour, iMinute, iSecond);
 
-  if (!lpUd->st.wMonth)
+  if (iYear > 9999 || iYear < -9999)
+    return E_INVALIDARG; /* Invalid value */
+  /* Years < 100 are treated as 1900 + year */
+  if (iYear > 0 && iYear < 100)
+    iYear += 1900;
+
+  iMinute += iSecond / 60;
+  iSecond  = iSecond % 60;
+  iHour   += iMinute / 60;
+  iMinute  = iMinute % 60;
+  iDay    += iHour / 24;
+  iHour    = iHour % 24;
+  iYear   += iMonth / 12;
+  iMonth   = iMonth % 12;
+  if (iMonth<=0) {iMonth+=12; iYear--;}
+  while (iDay > days[iMonth])
   {
-    /* Roll back to December of the previous year */
-    lpUd->st.wMonth = 12;
-    lpUd->st.wYear--;
+    if (iMonth == 2 && IsLeapYear(iYear))
+      iDay -= 29;
+    else
+      iDay -= days[iMonth];
+    iMonth++;
+    iYear += iMonth / 12;
+    iMonth = iMonth % 12;
   }
-  else while (lpUd->st.wMonth > 12)
+  while (iDay <= 0)
   {
-    /* Roll forward the correct number of months */
-    lpUd->st.wYear++;
-    lpUd->st.wMonth -= 12;
-  }
-
-  if (lpUd->st.wYear > 9999 || lpUd->st.wHour > 23 ||
-      lpUd->st.wMinute > 59 || lpUd->st.wSecond > 59)
-    return E_INVALIDARG; /* Invalid values */
-
-  if (!lpUd->st.wDay)
-  {
-    /* Roll back the date one day */
-    if (lpUd->st.wMonth == 1)
-    {
-      /* Roll back to December 31 of the previous year */
-      lpUd->st.wDay   = 31;
-      lpUd->st.wMonth = 12;
-      lpUd->st.wYear--;
-    }
+    iMonth--;
+    if (iMonth<=0) {iMonth+=12; iYear--;}
+    if (iMonth == 2 && IsLeapYear(iYear))
+      iDay += 29;
     else
-    {
-      lpUd->st.wMonth--; /* Previous month */
-      if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
-        lpUd->st.wDay = 29; /* February has 29 days on leap years */
-      else
-        lpUd->st.wDay = days[lpUd->st.wMonth]; /* Last day of the month */
-    }
+      iDay += days[iMonth];
   }
-  else if (lpUd->st.wDay > 28)
-  {
-    int rollForward = 0;
 
-    /* Possibly need to roll the date forward */
-    if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
-      rollForward = lpUd->st.wDay - 29; /* February has 29 days on leap years */
-    else
-      rollForward = lpUd->st.wDay - days[lpUd->st.wMonth];
+  if (iSecond<0){iSecond+=60; iMinute--;}
+  if (iMinute<0){iMinute+=60; iHour--;}
+  if (iHour<0)  {iHour+=24; iDay--;}
+  if (iYear<=0)  iYear+=2000;
+
+  lpUd->st.wYear   = iYear;
+  lpUd->st.wMonth  = iMonth;
+  lpUd->st.wDay    = iDay;
+  lpUd->st.wHour   = iHour;
+  lpUd->st.wMinute = iMinute;
+  lpUd->st.wSecond = iSecond;
 
-    if (rollForward > 0)
-    {
-      lpUd->st.wDay = rollForward;
-      lpUd->st.wMonth++;
-      if (lpUd->st.wMonth > 12)
-      {
-        lpUd->st.wMonth = 1; /* Roll forward into January of the next year */
-        lpUd->st.wYear++;
-      }
-    }
-  }
   TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
         lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
   return S_OK;
@@ -1190,6 +1245,8 @@ INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime,
   ud.st.wMinute = DOS_MINUTE(wDosTime);
   ud.st.wSecond = DOS_SECOND(wDosTime);
   ud.st.wDayOfWeek = ud.st.wMilliseconds = 0;
+  if (ud.st.wHour > 23 || ud.st.wMinute > 59 || ud.st.wSecond > 59)
+    return FALSE; /* Invalid values in Dos*/
 
   return VarDateFromUdate(&ud, 0, pDateOut) == S_OK;
 }
@@ -1328,7 +1385,6 @@ HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DAT
   dateVal += ud.st.wHour / 24.0;
   dateVal += ud.st.wMinute / 1440.0;
   dateVal += ud.st.wSecond / 86400.0;
-  dateVal += ud.st.wMilliseconds / 86400000.0;
 
   TRACE("Returning %g\n", dateVal);
   *pDateOut = dateVal;
@@ -2795,6 +2851,7 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
                 if (FAILED(rc))
                     return rc;
                 rc = VarBstrCmp(V_BSTR(bstrv), V_BSTR(&rv), lcid, flags);
+                VariantClear(&rv);
             } else if (V_BSTR(bstrv) && *V_BSTR(bstrv)) {
             /* Non NULL nor empty BSTR */
                 /* If the BSTR is not a number the BSTR is greater */
@@ -2810,8 +2867,8 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
                     /* Numeric comparison, will be handled below.
                        VARCMP_NULL used only to break out. */
                     rc = VARCMP_NULL;
-            VariantClear(&lv);
-            VariantClear(&rv);
+                VariantClear(&lv);
+                VariantClear(&rv);
             } else
                 /* Empty or NULL BSTR */
                 rc = VARCMP_GT;
index c881b24..265fcc8 100644 (file)
@@ -126,3 +126,4 @@ typedef struct tagVARIANT_NUMBER_CHARS
 
 
 BOOL VARIANT_GetLocalisedText(LANGID, DWORD, WCHAR *);
+HRESULT VARIANT_ClearInd(VARIANTARG *);
index 7f53259..da1288d 100644 (file)
@@ -3420,7 +3420,8 @@ static const int CY_Divisors[5] = { CY_MULTIPLIER/10000, CY_MULTIPLIER/1000,
  */
 HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut)
 {
-  return VarCyFromR8(bIn, pCyOut);
+    pCyOut->int64 = (ULONG64)bIn * CY_MULTIPLIER;
+    return S_OK;
 }
 
 /************************************************************************
@@ -3440,7 +3441,8 @@ HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut)
  */
 HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut)
 {
-  return VarCyFromR8(sIn, pCyOut);
+    pCyOut->int64 = (LONG64)sIn * CY_MULTIPLIER;
+    return S_OK;
 }
 
 /************************************************************************
@@ -3460,7 +3462,8 @@ HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut)
  */
 HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pCyOut)
 {
-  return VarCyFromR8(lIn, pCyOut);
+    pCyOut->int64 = (LONG64)lIn * CY_MULTIPLIER;
+    return S_OK;
 }
 
 /************************************************************************
@@ -3617,7 +3620,8 @@ HRESULT WINAPI VarCyFromDisp(IDispatch* pdispIn, LCID lcid, CY* pCyOut)
  */
 HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut)
 {
-  return VarCyFromR8(boolIn, pCyOut);
+    pCyOut->int64 = (LONG64)boolIn * CY_MULTIPLIER;
+    return S_OK;
 }
 
 /************************************************************************
@@ -3637,7 +3641,8 @@ HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut)
  */
 HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut)
 {
-  return VarCyFromR8(cIn, pCyOut);
+    pCyOut->int64 = (LONG64)cIn * CY_MULTIPLIER;
+    return S_OK;
 }
 
 /************************************************************************
@@ -3657,7 +3662,8 @@ HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut)
  */
 HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut)
 {
-  return VarCyFromR8(usIn, pCyOut);
+    pCyOut->int64 = (ULONG64)usIn * CY_MULTIPLIER;
+    return S_OK;
 }
 
 /************************************************************************
@@ -3677,7 +3683,8 @@ HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut)
  */
 HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pCyOut)
 {
-  return VarCyFromR8(ulIn, pCyOut);
+    pCyOut->int64 = (ULONG64)ulIn * CY_MULTIPLIER;
+    return S_OK;
 }
 
 /************************************************************************
@@ -3757,7 +3764,9 @@ HRESULT WINAPI VarCyFromI8(LONG64 llIn, CY* pCyOut)
  */
 HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut)
 {
-  return VarCyFromR8(ullIn, pCyOut);
+    if (ullIn >= (I8_MAX/CY_MULTIPLIER)) return DISP_E_OVERFLOW;
+    pCyOut->int64 = ullIn * CY_MULTIPLIER;
+    return S_OK;
 }
 
 /************************************************************************
@@ -7598,6 +7607,14 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
       break;
 
     case 0x3: /* TTT TTTDD TTTDDD */
+      if (iDate && dp.dwCount == 3)
+        {
+          /* DDD */
+          if ((dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)) ||
+              (dp.dwFlags[2] & (DP_AM|DP_PM)))
+            hRet = DISP_E_TYPEMISMATCH;
+          break;
+        }
       if (dp.dwCount > 4 &&
           ((dp.dwFlags[3] & (DP_AM|DP_PM)) || (dp.dwFlags[4] & (DP_AM|DP_PM)) ||
           (dp.dwFlags[5] & (DP_AM|DP_PM))))
@@ -7690,6 +7707,13 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd
       dp.dwCount -= 3;
       break;
 
+    case 0x1B: /* localized DDDTTT */
+      if (!iDate)
+        {
+          hRet = DISP_E_TYPEMISMATCH;
+          break;
+        }
+      /* .. fall through .. */
     case 0x18: /* DDDTTT */
       if ((dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)) ||
           (dp.dwFlags[2] & (DP_AM|DP_PM)))
index d8eb71f..7cd927d 100644 (file)
@@ -123,7 +123,7 @@ reactos/dll/win32/odbc32          # Out of sync. Depends on port of Linux ODBC.
 reactos/dll/win32/odbccp32        # Autosync
 reactos/dll/win32/ole32           # Autosync
 reactos/dll/win32/oleacc          # Autosync
-reactos/dll/win32/oleaut32        # Autosync ??
+reactos/dll/win32/oleaut32        # Autosync
 reactos/dll/win32/olecli32        # Autosync
 reactos/dll/win32/oledlg          # Autosync
 reactos/dll/win32/olepro32        # Autosync