Sync to Wine-20050628:
Robert Shearman <rob@codeweavers.com>
- Convert some registry helper functions to use unicode versions of
  CLSID & registry functions (untested).
- Add registry entries for local-only OLE interfaces.
- Change IUnknown to local interface.
- IUnknown isn't a remotable interface so the stub manager shouldn't
  need a marshaller for it.
- Change the RPC code to use the unicode versions of the CLSID &
  registry functions.
- Don't disconnect proxies flagged with SORFP_NOLIFETIMEMGMT. It makes
  no sense and only causes trouble for proxies that depend on these
  proxies being available.
- Change some of the registry helper functions to use the unicode
  versions of the CLSID & registry functions.
- Reindent CoGetClassObject and output an error message if the class
  isn't registered.
- Add tests for the touched functions.
Dmitry Timoshkov <dmitry@codeweavers.com>
- Make remaining OLE interface vtables const.
Richard Cohen <richard@daijobu.co.uk>
- Base FileMonikerImpl_Save() on XP.
- Correct handling of Unicode strings & multibyte locales.
- More error checking.
- Change ERR to WARN.
- Match Windows quick & dirty estimate for GetSizeMax().
Stefan Huehner <stefan@huehner.org>
- Fix some more -Wstrict-prototypes warnings.
Mike Hearn <mike@navi.cx>
- Add some tracing to the IRemUnknown RpcProxyBuffer implementation.
Eric Pouech <pouech-eric@wanadoo.fr>
- Const correctness fixes.
Richard Cohen <richard@daijobu.co.uk>
- IEnum::Clone shouldn't do a Reset.
Marcus Meissner <marcus@jet.franken.de>
- Removed CLSID_CompositeMoniker (conflicting with static definition).
Alexandre Julliard <julliard@winehq.org>
- Sort entry points alphabetically.
Modified: trunk/reactos/lib/ole32/antimoniker.c
Modified: trunk/reactos/lib/ole32/bindctx.c
Modified: trunk/reactos/lib/ole32/clipboard.c
Modified: trunk/reactos/lib/ole32/compobj.c
Modified: trunk/reactos/lib/ole32/compobj_private.h
Modified: trunk/reactos/lib/ole32/compositemoniker.c
Modified: trunk/reactos/lib/ole32/datacache.c
Modified: trunk/reactos/lib/ole32/defaulthandler.c
Modified: trunk/reactos/lib/ole32/errorinfo.c
Modified: trunk/reactos/lib/ole32/filemoniker.c
Modified: trunk/reactos/lib/ole32/ftmarshal.c
Modified: trunk/reactos/lib/ole32/git.c
Modified: trunk/reactos/lib/ole32/hglobalstream.c
Modified: trunk/reactos/lib/ole32/ifs.c
Modified: trunk/reactos/lib/ole32/itemmoniker.c
Modified: trunk/reactos/lib/ole32/marshal.c
Modified: trunk/reactos/lib/ole32/memlockbytes.c
Modified: trunk/reactos/lib/ole32/memlockbytes16.c
Modified: trunk/reactos/lib/ole32/moniker.c
Modified: trunk/reactos/lib/ole32/moniker.h
Modified: trunk/reactos/lib/ole32/ole16.c
Modified: trunk/reactos/lib/ole32/ole2.c
Modified: trunk/reactos/lib/ole32/ole32.spec
Modified: trunk/reactos/lib/ole32/oleobj.c
Modified: trunk/reactos/lib/ole32/oleproxy.c
Modified: trunk/reactos/lib/ole32/regsvr.c
Modified: trunk/reactos/lib/ole32/rpc.c
Modified: trunk/reactos/lib/ole32/stg_prop.c
Modified: trunk/reactos/lib/ole32/stg_stream.c
Modified: trunk/reactos/lib/ole32/storage.c
Modified: trunk/reactos/lib/ole32/storage32.c
Modified: trunk/reactos/lib/ole32/storage32.h
Modified: trunk/reactos/lib/ole32/stubmanager.c

Modified: trunk/reactos/lib/ole32/antimoniker.c
--- trunk/reactos/lib/ole32/antimoniker.c	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/antimoniker.c	2005-08-03 22:31:39 UTC (rev 17036)
@@ -42,12 +42,12 @@
 /* AntiMoniker data structure */
 typedef struct AntiMonikerImpl{
 
-    IMonikerVtbl*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/
+    const IMonikerVtbl*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/
 
     /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
      * two monikers are equal. That's whay IROTData interface is implemented by monikers.
      */
-    IROTDataVtbl*  lpvtbl2;  /* VTable relative to the IROTData interface.*/
+    const IROTDataVtbl*  lpvtbl2;  /* VTable relative to the IROTData interface.*/
 
     ULONG ref; /* reference counter for this object */
 
@@ -530,7 +530,7 @@
 /********************************************************************************/
 /* Virtual function table for the AntiMonikerImpl class which  include IPersist,*/
 /* IPersistStream and IMoniker functions.                                       */
-static IMonikerVtbl VT_AntiMonikerImpl =
+static const IMonikerVtbl VT_AntiMonikerImpl =
 {
     AntiMonikerImpl_QueryInterface,
     AntiMonikerImpl_AddRef,
@@ -559,7 +559,7 @@
 
 /********************************************************************************/
 /* Virtual function table for the IROTData class.                               */
-static IROTDataVtbl VT_ROTDataImpl =
+static const IROTDataVtbl VT_ROTDataImpl =
 {
     AntiMonikerROTDataImpl_QueryInterface,
     AntiMonikerROTDataImpl_AddRef,

Modified: trunk/reactos/lib/ole32/bindctx.c
--- trunk/reactos/lib/ole32/bindctx.c	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/bindctx.c	2005-08-03 22:31:39 UTC (rev 17036)
@@ -50,7 +50,7 @@
 /* BindCtx data strucrture */
 typedef struct BindCtxImpl{
 
-    IBindCtxVtbl *lpVtbl; /* VTable relative to the IBindCtx interface.*/
+    const IBindCtxVtbl *lpVtbl; /* VTable relative to the IBindCtx interface.*/
 
     ULONG ref; /* reference counter for this object */
 
@@ -474,7 +474,7 @@
 }
 
 /* Virtual function table for the BindCtx class. */
-static IBindCtxVtbl VT_BindCtxImpl =
+static const IBindCtxVtbl VT_BindCtxImpl =
 {
     BindCtxImpl_QueryInterface,
     BindCtxImpl_AddRef,

Modified: trunk/reactos/lib/ole32/clipboard.c
--- trunk/reactos/lib/ole32/clipboard.c	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/clipboard.c	2005-08-03 22:31:39 UTC (rev 17036)
@@ -96,7 +96,7 @@
   /*
    * List all interface VTables here
    */
-  IDataObjectVtbl*  lpvtbl1;  /* IDataObject VTable */
+  const IDataObjectVtbl*  lpvtbl1;  /* IDataObject VTable */
 
   /*
    * The hidden OLE clipboard window. This window is used as the bridge between the
@@ -135,7 +135,7 @@
 typedef struct
 {
   /* IEnumFORMATETC VTable */
-  IEnumFORMATETCVtbl          *lpVtbl;
+  const IEnumFORMATETCVtbl          *lpVtbl;
 
   /* IEnumFORMATETC fields */
   UINT                         posFmt;    /* current enumerator position */
@@ -250,7 +250,7 @@
 /*
  * Virtual function table for the OLEClipbrd's exposed IDataObject interface
  */
-static IDataObjectVtbl OLEClipbrd_IDataObject_VTable =
+static const IDataObjectVtbl OLEClipbrd_IDataObject_VTable =
 {
   OLEClipbrd_IDataObject_QueryInterface,
   OLEClipbrd_IDataObject_AddRef,
@@ -269,7 +269,7 @@
 /*
  * Virtual function table for IEnumFORMATETC interface
  */
-static struct IEnumFORMATETCVtbl efvt =
+static const IEnumFORMATETCVtbl efvt =
 {
   OLEClipbrd_IEnumFORMATETC_QueryInterface,
   OLEClipbrd_IEnumFORMATETC_AddRef,

Modified: trunk/reactos/lib/ole32/compobj.c
--- trunk/reactos/lib/ole32/compobj.c	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/compobj.c	2005-08-03 22:31:39 UTC (rev 17036)
@@ -76,6 +76,8 @@
 
 HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */
 
+#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
+
 /****************************************************************************
  * This section defines variables internal to the COM module.
  *
@@ -195,7 +197,7 @@
     UnregisterClassW(wszAptWinClass, OLE32_hInstance);
 }
 
-static void COM_TlsDestroy()
+static void COM_TlsDestroy(void)
 {
     struct oletls *info = NtCurrentTeb()->ReservedForOle;
     if (info)
@@ -981,6 +983,16 @@
   return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
 }
 
+/* open HKCR\\CLSID\\{string form of clsid} key */
+DWORD COM_OpenKeyForCLSID(REFCLSID clsid, REGSAM access, HKEY *key)
+{
+    static const WCHAR wszCLSIDSlash[] = {'C','L','S','I','D','\\',0};
+    WCHAR path[CHARS_IN_GUID + ARRAYSIZE(wszCLSIDSlash) - 1];
+    strcpyW(path, wszCLSIDSlash);
+    StringFromGUID2(clsid, path + strlenW(wszCLSIDSlash), CHARS_IN_GUID);
+    return RegOpenKeyExW(HKEY_CLASSES_ROOT, path, 0, access, key);
+}
+
 /******************************************************************************
  *               ProgIDFromCLSID [OLE32.@]
  *
@@ -997,43 +1009,42 @@
  */
 HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID)
 {
-  char     strCLSID[50], *buf, *buf2;
-  DWORD    buf2len;
-  HKEY     xhkey;
-  LPMALLOC mllc;
+  static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
+  HKEY     hkey = NULL;
+  HKEY     hkey_clsid;
   HRESULT  ret = S_OK;
 
-  WINE_StringFromCLSID(clsid, strCLSID);
-
-  buf = HeapAlloc(GetProcessHeap(), 0, strlen(strCLSID)+14);
-  sprintf(buf,"CLSID\\%s\\ProgID", strCLSID);
-  if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey))
+  if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsid, KEY_READ, &hkey_clsid))
     ret = REGDB_E_CLASSNOTREG;
 
-  HeapFree(GetProcessHeap(), 0, buf);
+  if (ret == S_OK)
+  {
+    if (RegOpenKeyExW(hkey_clsid, wszProgID, 0, KEY_READ, &hkey))
+      ret = REGDB_E_CLASSNOTREG;
+    RegCloseKey(hkey_clsid);
+  }
 
   if (ret == S_OK)
   {
-    buf2 = HeapAlloc(GetProcessHeap(), 0, 255);
-    buf2len = 255;
-    if (RegQueryValueA(xhkey, NULL, buf2, &buf2len))
+    DWORD progidlen = 0;
+
+    if (RegQueryValueW(hkey, NULL, NULL, &progidlen))
       ret = REGDB_E_CLASSNOTREG;
 
     if (ret == S_OK)
     {
-      if (CoGetMalloc(0,&mllc))
-        ret = E_OUTOFMEMORY;
-      else
+      *lplpszProgID = CoTaskMemAlloc(progidlen * sizeof(WCHAR));
+      if (*lplpszProgID)
       {
-          DWORD len = MultiByteToWideChar( CP_ACP, 0, buf2, -1, NULL, 0 );
-          *lplpszProgID = IMalloc_Alloc(mllc, len * sizeof(WCHAR) );
-          MultiByteToWideChar( CP_ACP, 0, buf2, -1, *lplpszProgID, len );
+        if (RegQueryValueW(hkey, NULL, *lplpszProgID, &progidlen))
+          ret = REGDB_E_CLASSNOTREG;
       }
+      else
+        ret = E_OUTOFMEMORY;
     }
-    HeapFree(GetProcessHeap(), 0, buf2);
-    RegCloseKey(xhkey);
   }
 
+  RegCloseKey(hkey);
   return ret;
 }
 
@@ -1089,7 +1100,7 @@
 HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid)
 {
     static const WCHAR clsidW[] = { '\\','C','L','S','I','D',0 };
-    char buf2[80];
+    WCHAR buf2[CHARS_IN_GUID];
     DWORD buf2len = sizeof(buf2);
     HKEY xhkey;
 
@@ -1103,13 +1114,13 @@
     }
     HeapFree(GetProcessHeap(),0,buf);
 
-    if (RegQueryValueA(xhkey,NULL,buf2,&buf2len))
+    if (RegQueryValueW(xhkey,NULL,buf2,&buf2len))
     {
         RegCloseKey(xhkey);
         return CO_E_CLASSSTRING;
     }
     RegCloseKey(xhkey);
-    return __CLSIDFromStringA(buf2,riid);
+    return CLSIDFromString(buf2,riid);
 }
 
 
@@ -1151,46 +1162,41 @@
  */
 HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
 {
-    char *buf, buf2[40];
-    DWORD buf2len;
-    HKEY xhkey;
+    static const WCHAR wszInterface[] = {'I','n','t','e','r','f','a','c','e','\\',0};
+    static const WCHAR wszPSC[] = {'\\','P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};
+    WCHAR path[ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1 + ARRAYSIZE(wszPSC)];
+    WCHAR value[CHARS_IN_GUID];
+    DWORD len;
+    HKEY hkey;
 
     TRACE("() riid=%s, pclsid=%p\n", debugstr_guid(riid), pclsid);
 
-    /* Get the input iid as a string */
-    WINE_StringFromCLSID(riid, buf2);
-    /* Allocate memory for the registry key we will construct.
-       (length of iid string plus constant length of static text */
-    buf = HeapAlloc(GetProcessHeap(), 0, strlen(buf2)+27);
-    if (buf == NULL)
-        return E_OUTOFMEMORY;
+    /* Interface\\{string form of riid}\\ProxyStubClsid32 */
+    strcpyW(path, wszInterface);
+    StringFromGUID2(riid, path + ARRAYSIZE(wszInterface) - 1, CHARS_IN_GUID);
+    strcpyW(path + ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1, wszPSC);
 
-    /* Construct the registry key we want */
-    sprintf(buf,"Interface\\%s\\ProxyStubClsid32", buf2);
-
     /* Open the key.. */
-    if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey))
+    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, path, 0, KEY_READ, &hkey))
     {
         WARN("No PSFactoryBuffer object is registered for IID %s\n", debugstr_guid(riid));
-        HeapFree(GetProcessHeap(),0,buf);
         return REGDB_E_IIDNOTREG;
     }
-    HeapFree(GetProcessHeap(),0,buf);
 
     /* ... Once we have the key, query the registry to get the
        value of CLSID as a string, and convert it into a
        proper CLSID structure to be passed back to the app */
-    buf2len = sizeof(buf2);
-    if ( (RegQueryValueA(xhkey,NULL,buf2,&buf2len)) )
+    len = sizeof(value);
+    if (ERROR_SUCCESS != RegQueryValueW(hkey, NULL, value, &len))
     {
-        RegCloseKey(xhkey);
+        RegCloseKey(hkey);
         return REGDB_E_IIDNOTREG;
     }
-    RegCloseKey(xhkey);
+    RegCloseKey(hkey);
 
     /* We have the CLSid we want back from the registry as a string, so
        lets convert it into a CLSID structure */
-    if ( (__CLSIDFromStringA(buf2,pclsid)) != NOERROR)
+    if (CLSIDFromString(value, pclsid) != NOERROR)
         return REGDB_E_IIDNOTREG;
 
     TRACE ("() Returning CLSID=%s\n", debugstr_guid(pclsid));
@@ -1528,25 +1534,24 @@
 }
 
 /***********************************************************************
- *	compobj_RegReadPath	[internal]
+ *	COM_RegReadPath	[internal]
  *
  *	Reads a registry value and expands it when necessary
  */
-static HRESULT
-compobj_RegReadPath(char * keyname, char * valuename, char * dst, DWORD dstlen)
+HRESULT COM_RegReadPath(HKEY hkeyroot, const WCHAR *keyname, const WCHAR *valuename, WCHAR * dst, DWORD dstlen)
 {
 	HRESULT hres;
 	HKEY key;
 	DWORD keytype;
-	char src[MAX_PATH];
-	DWORD dwLength = dstlen;
+	WCHAR src[MAX_PATH];
+	DWORD dwLength = dstlen * sizeof(WCHAR);
 
-	if((hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, keyname, 0, KEY_READ, &key)) == ERROR_SUCCESS) {
-          if( (hres = RegQueryValueExA(key, NULL, NULL, &keytype, (LPBYTE)src, &dwLength)) == ERROR_SUCCESS ) {
+	if((hres = RegOpenKeyExW(hkeyroot, keyname, 0, KEY_READ, &key)) == ERROR_SUCCESS) {
+          if( (hres = RegQueryValueExW(key, NULL, NULL, &keytype, (LPBYTE)src, &dwLength)) == ERROR_SUCCESS ) {
             if (keytype == REG_EXPAND_SZ) {
-              if (dstlen <= ExpandEnvironmentStringsA(src, dst, dstlen)) hres = ERROR_MORE_DATA;
+              if (dstlen <= ExpandEnvironmentStringsW(src, dst, dstlen)) hres = ERROR_MORE_DATA;
             } else {
-              lstrcpynA(dst, src, dstlen);
+              lstrcpynW(dst, src, dstlen);
             }
 	  }
           RegCloseKey (key);
@@ -1565,17 +1570,11 @@
  */
 HRESULT WINAPI CoGetClassObject(
     REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo,
-    REFIID iid, LPVOID *ppv
-) {
+    REFIID iid, LPVOID *ppv)
+{
     LPUNKNOWN	regClassObject;
     HRESULT	hres = E_UNEXPECTED;
-    char	xclsid[80];
-    HINSTANCE hLibrary;
-    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
-    DllGetClassObjectFunc DllGetClassObject;
 
-    WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
-
     TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
 
     if (pServerInfo) {
@@ -1589,9 +1588,7 @@
      */
     if (S_OK == COM_GetRegisteredClassObject(rclsid, dwClsContext, &regClassObject))
     {
-      /*
-       * Get the required interface from the retrieved pointer.
-       */
+      /* Get the required interface from the retrieved pointer. */
       hres = IUnknown_QueryInterface(regClassObject, iid, ppv);
 
       /*
@@ -1605,32 +1602,49 @@
     }
 
     /* first try: in-process */
-    if ((CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) & dwClsContext) {
-	char keyname[MAX_PATH];
-	char dllpath[MAX_PATH+1];
+    if ((CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) & dwClsContext)
+    {
+        static const WCHAR wszInprocServer32[] = {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
+        HINSTANCE hLibrary;
+        typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
+        DllGetClassObjectFunc DllGetClassObject;
+        WCHAR dllpath[MAX_PATH+1];
+        HKEY hkey;
 
-	sprintf(keyname,"CLSID\\%s\\InprocServer32",xclsid);
+        if (ERROR_SUCCESS != COM_OpenKeyForCLSID(rclsid, KEY_READ, &hkey))
+        {
+            ERR("class %s not registered\n", debugstr_guid(rclsid));
+            hres = REGDB_E_CLASSNOTREG;
+        }
 
-	if ( compobj_RegReadPath(keyname, NULL, dllpath, sizeof(dllpath)) != ERROR_SUCCESS) {
-	    /* failure: CLSID is not found in registry */
-           WARN("class %s not registered inproc\n", xclsid);
+        if (COM_RegReadPath(hkey, wszInprocServer32, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+        {
+            /* failure: CLSID is not found in registry */
+            WARN("class %s not registered inproc\n", debugstr_guid(rclsid));
             hres = REGDB_E_CLASSNOTREG;
-	} else {
-	  if ((hLibrary = LoadLibraryExA(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
-	    /* failure: DLL could not be loaded */
-	    ERR("couldn't load InprocServer32 dll %s\n", dllpath);
-	    hres = E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
-	  } else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) {
-	    /* failure: the dll did not export DllGetClassObject */
-	    ERR("couldn't find function DllGetClassObject in %s\n", dllpath);
-	    FreeLibrary( hLibrary );
-	    hres = CO_E_DLLNOTFOUND;
-	  } else {
-	    /* OK: get the ClassObject */
-	    COMPOBJ_DLLList_Add( hLibrary );
-	    return DllGetClassObject(rclsid, iid, ppv);
-	  }
-	}
+        }
+        else
+        {
+            if ((hLibrary = LoadLibraryExW(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0)
+            {
+                /* failure: DLL could not be loaded */
+                ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(dllpath));
+                hres = E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
+            }
+            else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject")))
+            {
+                /* failure: the dll did not export DllGetClassObject */
+                ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(dllpath));
+                FreeLibrary( hLibrary );
+                hres = CO_E_DLLNOTFOUND;
+            }
+            else
+            {
+                /* OK: get the ClassObject */
+                COMPOBJ_DLLList_Add( hLibrary );
+                return DllGetClassObject(rclsid, iid, ppv);
+            }
+        }
     }
 
     /* Next try out of process */
@@ -2154,28 +2168,27 @@
  */
 HRESULT WINAPI OleGetAutoConvert(REFCLSID clsidOld, LPCLSID pClsidNew)
 {
-    HKEY hkey = 0;
-    char buf[200];
-    WCHAR wbuf[200];
+    static const WCHAR wszAutoConvertTo[] = {'A','u','t','o','C','o','n','v','e','r','t','T','o',0};
+    HKEY hkey = NULL;
+    WCHAR buf[CHARS_IN_GUID];
     DWORD len;
     HRESULT res = S_OK;
 
-    sprintf(buf,"CLSID\\");WINE_StringFromCLSID(clsidOld,&buf[6]);
-    if (RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&hkey))
+    if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsidOld, KEY_READ, &hkey))
     {
         res = REGDB_E_CLASSNOTREG;
-	goto done;
+        goto done;
     }
-    len = 200;
+
+    len = sizeof(buf);
     /* we can just query for the default value of AutoConvertTo key like that,
        without opening the AutoConvertTo key and querying for NULL (default) */
-    if (RegQueryValueA(hkey,"AutoConvertTo",buf,&len))
+    if (RegQueryValueW(hkey, wszAutoConvertTo, buf, &len))
     {
         res = REGDB_E_KEYMISSING;
-	goto done;
+        goto done;
     }
-    MultiByteToWideChar( CP_ACP, 0, buf, -1, wbuf, sizeof(wbuf)/sizeof(WCHAR) );
-    CLSIDFromString(wbuf,pClsidNew);
+    res = CLSIDFromString(buf, pClsidNew);
 done:
     if (hkey) RegCloseKey(hkey);
     return res;
@@ -2199,27 +2212,26 @@
  */
 HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew)
 {
-    HKEY hkey = 0;
-    char buf[47];
-    char szClsidNew[39];
+    static const WCHAR wszAutoTreatAs[] = {'A','u','t','o','T','r','e','a','t','A','s',0};
+    static const WCHAR wszTreatAs[] = {'T','r','e','a','t','A','s',0};
+    HKEY hkey = NULL;
+    WCHAR szClsidNew[CHARS_IN_GUID];
     HRESULT res = S_OK;
-    char auto_treat_as[39];
+    WCHAR auto_treat_as[CHARS_IN_GUID];
     LONG auto_treat_as_size = sizeof(auto_treat_as);
     CLSID id;
 
-    sprintf(buf,"CLSID\\");WINE_StringFromCLSID(clsidOld,&buf[6]);
-    WINE_StringFromCLSID(clsidNew, szClsidNew);
-    if (RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&hkey))
+    if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsidOld, KEY_READ | KEY_WRITE, &hkey))
     {
         res = REGDB_E_CLASSNOTREG;
 	goto done;
     }
     if (!memcmp( clsidOld, clsidNew, sizeof(*clsidOld) ))
     {
-       if (!RegQueryValueA(hkey, "AutoTreatAs", auto_treat_as, &auto_treat_as_size) &&
-           !__CLSIDFromStringA(auto_treat_as, &id))
+       if (!RegQueryValueW(hkey, wszAutoTreatAs, auto_treat_as, &auto_treat_as_size) &&
+           !CLSIDFromString(auto_treat_as, &id))
        {
-           if (RegSetValueA(hkey, "TreatAs", REG_SZ, auto_treat_as, strlen(auto_treat_as)+1))
+           if (RegSetValueW(hkey, wszTreatAs, REG_SZ, auto_treat_as, sizeof(auto_treat_as)))
            {
                res = REGDB_E_WRITEREGDB;
                goto done;
@@ -2227,13 +2239,14 @@
        }
        else
        {
-           RegDeleteKeyA(hkey, "TreatAs");
+           RegDeleteKeyW(hkey, wszTreatAs);
            goto done;
        }
     }
-    else if (RegSetValueA(hkey, "TreatAs", REG_SZ, szClsidNew, strlen(szClsidNew)+1))
+    else if (!StringFromGUID2(clsidNew, szClsidNew, ARRAYSIZE(szClsidNew)) &&
+             !RegSetValueW(hkey, wszTreatAs, REG_SZ, szClsidNew, sizeof(szClsidNew)))
     {
-       res = REGDB_E_WRITEREGDB;
+        res = REGDB_E_WRITEREGDB;
 	goto done;
     }
 
@@ -2260,32 +2273,31 @@
  */
 HRESULT WINAPI CoGetTreatAsClass(REFCLSID clsidOld, LPCLSID clsidNew)
 {
-    HKEY hkey = 0;
-    char buf[200], szClsidNew[200];
+    static const WCHAR wszTreatAs[] = {'T','r','e','a','t','A','s',0};
+    HKEY hkey = NULL;
+    WCHAR szClsidNew[CHARS_IN_GUID];
     HRESULT res = S_OK;
     LONG len = sizeof(szClsidNew);
 
     FIXME("(%s,%p)\n", debugstr_guid(clsidOld), clsidNew);
-    sprintf(buf,"CLSID\\");WINE_StringFromCLSID(clsidOld,&buf[6]);
     memcpy(clsidNew,clsidOld,sizeof(CLSID)); /* copy over old value */
 
-    if (RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&hkey))
+    if (COM_OpenKeyForCLSID(clsidOld, KEY_READ, &hkey))
     {
         res = REGDB_E_CLASSNOTREG;
 	goto done;
     }
-    if (RegQueryValueA(hkey, "TreatAs", szClsidNew, &len))
+    if (RegQueryValueW(hkey, wszTreatAs, szClsidNew, &len))
     {
         res = S_FALSE;
 	goto done;
     }
-    res = __CLSIDFromStringA(szClsidNew,clsidNew);
+    res = CLSIDFromString(szClsidNew,clsidNew);
     if (FAILED(res))
-    	FIXME("Failed CLSIDFromStringA(%s), hres %lx?\n",szClsidNew,res);
+        ERR("Failed CLSIDFromStringA(%s), hres 0x%08lx\n", debugstr_w(szClsidNew), res);
 done:
     if (hkey) RegCloseKey(hkey);
     return res;
-
 }
 
 /******************************************************************************

Modified: trunk/reactos/lib/ole32/compobj_private.h
--- trunk/reactos/lib/ole32/compobj_private.h	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/compobj_private.h	2005-08-03 22:31:39 UTC (rev 17036)
@@ -163,6 +163,7 @@
 extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
 HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
 
+DWORD COM_OpenKeyForCLSID(REFCLSID clsid, REGSAM access, HKEY *key);
 HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
 
 /* Stub Manager */
@@ -256,4 +257,6 @@
 
 extern HINSTANCE OLE32_hInstance; /* FIXME: make static */
 
+#define CHARS_IN_GUID 39 /* including NULL */
+
 #endif /* __WINE_OLE_COMPOBJ_H */

Modified: trunk/reactos/lib/ole32/compositemoniker.c
--- trunk/reactos/lib/ole32/compositemoniker.c	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/compositemoniker.c	2005-08-03 22:31:39 UTC (rev 17036)
@@ -37,7 +37,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
-const CLSID CLSID_CompositeMoniker = {
+static const CLSID CLSID_CompositeMoniker = {
   0x309, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
 };
 
@@ -46,13 +46,13 @@
 /* CompositeMoniker data structure */
 typedef struct CompositeMonikerImpl{
 
-    IMonikerVtbl*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/
+    const IMonikerVtbl*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/
 
     /* The ROT (RunningObjectTable implementation) uses the IROTData
      * interface to test whether two monikers are equal. That's why IROTData
      * interface is implemented by monikers.
      */
-    IROTDataVtbl*  lpvtbl2;  /* VTable relative to the IROTData interface.*/
+    const IROTDataVtbl*  lpvtbl2;  /* VTable relative to the IROTData interface.*/
 
     ULONG ref; /* reference counter for this object */
 
@@ -68,7 +68,7 @@
 /* EnumMoniker data structure */
 typedef struct EnumMonikerImpl{
 
-    IEnumMonikerVtbl *lpVtbl;  /* VTable relative to the IEnumMoniker interface.*/
+    const IEnumMonikerVtbl *lpVtbl;  /* VTable relative to the IEnumMoniker interface.*/
 
     ULONG ref; /* reference counter for this object */
 
@@ -1388,7 +1388,7 @@
 
 /********************************************************************************/
 /* Virtual function table for the IROTData class                                */
-static IEnumMonikerVtbl VT_EnumMonikerImpl =
+static const IEnumMonikerVtbl VT_EnumMonikerImpl =
 {
     EnumMonikerImpl_QueryInterface,
     EnumMonikerImpl_AddRef,
@@ -1453,7 +1453,7 @@
 /* Virtual function table for the CompositeMonikerImpl class which includes     */
 /* IPersist, IPersistStream and IMoniker functions.                             */
 
-static IMonikerVtbl VT_CompositeMonikerImpl =
+static const IMonikerVtbl VT_CompositeMonikerImpl =
 {
     CompositeMonikerImpl_QueryInterface,
     CompositeMonikerImpl_AddRef,
@@ -1482,7 +1482,7 @@
 
 /********************************************************************************/
 /* Virtual function table for the IROTData class.                               */
-static IROTDataVtbl VT_ROTDataImpl =
+static const IROTDataVtbl VT_ROTDataImpl =
 {
     CompositeMonikerROTDataImpl_QueryInterface,
     CompositeMonikerROTDataImpl_AddRef,

Modified: trunk/reactos/lib/ole32/datacache.c
--- trunk/reactos/lib/ole32/datacache.c	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/datacache.c	2005-08-03 22:31:39 UTC (rev 17036)
@@ -93,12 +93,12 @@
   /*
    * List all interface VTables here
    */
-  IDataObjectVtbl*      lpvtbl1;
-  IUnknownVtbl*         lpvtbl2;
-  IPersistStorageVtbl*  lpvtbl3;
-  IViewObject2Vtbl*     lpvtbl4;
-  IOleCache2Vtbl*       lpvtbl5;
-  IOleCacheControlVtbl* lpvtbl6;
+  const IDataObjectVtbl*      lpvtbl1;
+  const IUnknownVtbl*         lpvtbl2;
+  const IPersistStorageVtbl*  lpvtbl3;
+  const IViewObject2Vtbl*     lpvtbl4;
+  const IOleCache2Vtbl*       lpvtbl5;
+  const IOleCacheControlVtbl* lpvtbl6;
 
   /*
    * Reference count of this object
@@ -1617,14 +1617,14 @@
 /*
  * Virtual function tables for the DataCache class.
  */
-static IUnknownVtbl DataCache_NDIUnknown_VTable =
+static const IUnknownVtbl DataCache_NDIUnknown_VTable =
 {
   DataCache_NDIUnknown_QueryInterface,
   DataCache_NDIUnknown_AddRef,
   DataCache_NDIUnknown_Release
 };
 
-static IDataObjectVtbl DataCache_IDataObject_VTable =
+static const IDataObjectVtbl DataCache_IDataObject_VTable =
 {
   DataCache_IDataObject_QueryInterface,
   DataCache_IDataObject_AddRef,
@@ -1640,7 +1640,7 @@
   DataCache_EnumDAdvise
 };
 
-static IPersistStorageVtbl DataCache_IPersistStorage_VTable =
+static const IPersistStorageVtbl DataCache_IPersistStorage_VTable =
 {
   DataCache_IPersistStorage_QueryInterface,
   DataCache_IPersistStorage_AddRef,
@@ -1654,7 +1654,7 @@
   DataCache_HandsOffStorage
 };
 
-static IViewObject2Vtbl DataCache_IViewObject2_VTable =
+static const IViewObject2Vtbl DataCache_IViewObject2_VTable =
 {
   DataCache_IViewObject2_QueryInterface,
   DataCache_IViewObject2_AddRef,
@@ -1668,7 +1668,7 @@
   DataCache_GetExtent
 };
 
-static IOleCache2Vtbl DataCache_IOleCache2_VTable =
+static const IOleCache2Vtbl DataCache_IOleCache2_VTable =
 {
   DataCache_IOleCache2_QueryInterface,
   DataCache_IOleCache2_AddRef,
@@ -1682,7 +1682,7 @@
   DataCache_DiscardCache
 };
 
-static IOleCacheControlVtbl DataCache_IOleCacheControl_VTable =
+static const IOleCacheControlVtbl DataCache_IOleCacheControl_VTable =
 {
   DataCache_IOleCacheControl_QueryInterface,
   DataCache_IOleCacheControl_AddRef,

Modified: trunk/reactos/lib/ole32/defaulthandler.c
--- trunk/reactos/lib/ole32/defaulthandler.c	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/defaulthandler.c	2005-08-03 22:31:39 UTC (rev 17036)
@@ -70,10 +70,10 @@
   /*
    * List all interface VTables here
    */
-  IOleObjectVtbl*      lpvtbl1;
-  IUnknownVtbl*        lpvtbl2;
-  IDataObjectVtbl*     lpvtbl3;
-  IRunnableObjectVtbl* lpvtbl4;
+  const IOleObjectVtbl*      lpvtbl1;
+  const IUnknownVtbl*        lpvtbl2;
+  const IDataObjectVtbl*     lpvtbl3;
+  const IRunnableObjectVtbl* lpvtbl4;
 
   /*
    * Reference count of this object
@@ -325,7 +325,7 @@
 /*
  * Virtual function tables for the DefaultHandler class.
  */
-static IOleObjectVtbl DefaultHandler_IOleObject_VTable =
+static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
 {
   DefaultHandler_QueryInterface,
   DefaultHandler_AddRef,
@@ -353,14 +353,14 @@
   DefaultHandler_SetColorScheme
 };
 
-static IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
+static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
 {
   DefaultHandler_NDIUnknown_QueryInterface,
   DefaultHandler_NDIUnknown_AddRef,
   DefaultHandler_NDIUnknown_Release,
 };
 
-static IDataObjectVtbl DefaultHandler_IDataObject_VTable =
+static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
 {
   DefaultHandler_IDataObject_QueryInterface,
   DefaultHandler_IDataObject_AddRef,
@@ -376,7 +376,7 @@
   DefaultHandler_EnumDAdvise
 };
 
-static IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
+static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
 {
   DefaultHandler_IRunnableObject_QueryInterface,
   DefaultHandler_IRunnableObject_AddRef,

Modified: trunk/reactos/lib/ole32/errorinfo.c
--- trunk/reactos/lib/ole32/errorinfo.c	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/errorinfo.c	2005-08-03 22:31:39 UTC (rev 17036)
@@ -128,9 +128,9 @@
 
 typedef struct ErrorInfoImpl
 {
-	IErrorInfoVtbl		*lpvtei;
-	ICreateErrorInfoVtbl	*lpvtcei;
-	ISupportErrorInfoVtbl	*lpvtsei;
+	const IErrorInfoVtbl           *lpvtei;
+	const ICreateErrorInfoVtbl     *lpvtcei;
+	const ISupportErrorInfoVtbl    *lpvtsei;
 	DWORD				ref;
 
 	GUID m_Guid;
@@ -140,9 +140,9 @@
 	DWORD m_dwHelpContext;
 } ErrorInfoImpl;
 
-static IErrorInfoVtbl		IErrorInfoImpl_VTable;
-static ICreateErrorInfoVtbl	ICreateErrorInfoImpl_VTable;
-static ISupportErrorInfoVtbl	ISupportErrorInfoImpl_VTable;
+static const IErrorInfoVtbl        IErrorInfoImpl_VTable;
+static const ICreateErrorInfoVtbl  ICreateErrorInfoImpl_VTable;
+static const ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable;
 
 /*
  converts an object pointer to This
@@ -303,7 +303,7 @@
 	return S_OK;
 }
 
-static IErrorInfoVtbl IErrorInfoImpl_VTable =
+static const IErrorInfoVtbl IErrorInfoImpl_VTable =
 {
   IErrorInfoImpl_QueryInterface,
   IErrorInfoImpl_AddRef,
@@ -402,7 +402,7 @@
 	return S_OK;
 }
 
-static ICreateErrorInfoVtbl ICreateErrorInfoImpl_VTable =
+static const ICreateErrorInfoVtbl ICreateErrorInfoImpl_VTable =
 {
   ICreateErrorInfoImpl_QueryInterface,
   ICreateErrorInfoImpl_AddRef,
@@ -452,7 +452,7 @@
 	return (IsEqualIID(riid, &This->m_Guid)) ? S_OK : S_FALSE;
 }
 
-static ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable =
+static const ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable =
 {
   ISupportErrorInfoImpl_QueryInterface,
   ISupportErrorInfoImpl_AddRef,

Modified: trunk/reactos/lib/ole32/filemoniker.c
--- trunk/reactos/lib/ole32/filemoniker.c	2005-08-03 22:31:41 UTC (rev 17035)
+++ trunk/reactos/lib/ole32/filemoniker.c	2005-08-03 22:31:39 UTC (rev 17036)
@@ -46,12 +46,12 @@
 /* filemoniker data structure */
 typedef struct FileMonikerImpl{
 
-    IMonikerVtbl*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/
+    const IMonikerVtbl*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/
 
     /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether
      * two monikers are equal. That's whay IROTData interface is implemented by monikers.
      */
-    IROTDataVtbl*  lpvtbl2;  /* VTable relative to the IROTData interface.*/
+    const IROTDataVtbl*  lpvtbl2;  /* VTable relative to the IROTData interface.*/
 
     ULONG ref; /* reference counter for this object */
 
@@ -182,121 +182,155 @@
  * written by FileMonikerImpl_Save
  */
 static HRESULT WINAPI
-FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
+FileMonikerImpl_Load(IMoniker* iface, IStream* pStm)
 {
     HRESULT res;
-    CHAR* filePathA;
-    WCHAR* filePathW;
+    CHAR* filePathA = NULL;
+    WCHAR* filePathW = NULL;
     ULONG bread;
     WORD  wbuffer;
-    DWORD dwbuffer,length,i,doubleLenHex,doubleLenDec;
+    DWORD dwbuffer, bytesA, bytesW, len;
+    int i;
 
     FileMonikerImpl *This = (FileMonikerImpl *)iface;
 
     TRACE("(%p,%p)\n",iface,pStm);
 
-    /* first WORD is non significative */
+    /* first WORD must be 0 */
     res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
     if (bread!=sizeof(WORD) || wbuffer!=0)
     {
-        ERR("Couldn't read 0 word\n");
-        return E_FAIL;
+        WARN("Couldn't read 0 word\n");
+        goto fail;
     }
 
     /* read filePath string length (plus one) */
-    res=IStream_Read(pStm,&length,sizeof(DWORD),&bread);
+    res=IStream_Read(pStm,&bytesA,sizeof(DWORD),&bread);
     if (bread != sizeof(DWORD))
     {
-        ERR("Couldn't read file string length\n");
-        return E_FAIL;
+        WARN("Couldn't read file string length\n");
+        goto fail;
     }
 
     /* read filePath string */
-    filePathA=HeapAlloc(GetProcessHeap(),0,length);
-    res=IStream_Read(pStm,filePathA,length,&bread);
-    HeapFree(GetProcessHeap(),0,filePathA);
-    if (bread != length)
+    filePathA=HeapAlloc(GetProcessHeap(),0,bytesA);
+    if (!filePathA)
     {
-        ERR("Couldn't read file path string\n");
-        return E_FAIL;
+        res = E_OUTOFMEMORY;
+        goto fail;
     }
 
+    res=IStream_Read(pStm,filePathA,bytesA,&bread);
+    if (bread != bytesA)
+    {
+        WARN("Couldn't read file path string\n");
+        goto fail;
+    }
+
     /* read the first constant */
     IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
     if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
     {
-        ERR("Couldn't read 0xDEADFFFF constant\n");
-        return E_FAIL;
+        WARN("Couldn't read 0xDEADFFFF constant\n");
+        goto fail;
     }
 
-    length--;
-
-    for(i=0;i<10;i++){
-        res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
-        if (bread!=sizeof(WORD) || wbuffer!=0)
+    for(i=0;i<5;i++)
+    {
+        res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
+        if (bread!=sizeof(DWORD) || dwbuffer!=0)
         {
-            ERR("Couldn't read 0 padding\n");
-            return E_FAIL;
+            WARN("Couldn't read 0 padding\n");
+            goto fail;
         }
     }
 
-    if (length>8)
-        length=0;
+    res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
+    if (bread!=sizeof(DWORD))
+        goto fail;
 
-    doubleLenHex=doubleLenDec=2*length;
-    if (length > 5)
-        doubleLenDec+=6;
+    if (!dwbuffer) /* No W-string */
+    {        
+        bytesA--;
+        len=MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, filePathA, bytesA, NULL, 0);
+        if (!len)
+            goto fail;
 
-    res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
-    if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenDec)
-        return E_FAIL;
+        filePathW=HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
+        if (!filePathW)
+        {
+            res = E_OUTOFMEMORY;
+            goto fail;
+        }
+        MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, filePathA, -1, filePathW, len+1);
+        goto succeed;
+    }
 
-    if (length==0)
-        return res;
+    if (dwbuffer < 6)
+        goto fail;
 
+    bytesW=dwbuffer - 6;
+
     res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
-    if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenHex)
-        return E_FAIL;
+    if (bread!=sizeof(DWORD) || dwbuffer!=bytesW)
+        goto fail;
 
     res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
     if (bread!=sizeof(WORD) || wbuffer!=0x3)
-        return E_FAIL;
+        goto fail;
 
-    filePathW=HeapAlloc(GetProcessHeap(),0,(length+1)*sizeof(WCHAR));
-    filePathW[length]=0;
-    res=IStream_Read(pStm,filePathW,doubleLenHex,&bread);
-    if (bread!=doubleLenHex) {
-        HeapFree(GetProcessHeap(), 0, filePathW);
-        return E_FAIL;
+    len=bytesW/sizeof(WCHAR);
+    filePathW=HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
+    if(!filePathW)
[truncated at 1000 lines; 1370 more skipped]