- Height is now calculated based on the number of rows, not on the
[wine] / dlls / ole32 / storage32.c
index f5b701e..a234ce3 100644 (file)
@@ -8,16 +8,47 @@
  * Copyright 1999 Francis Beaudet
  * Copyright 1999 Sylvain St-Germain
  * Copyright 1999 Thuy Nguyen
+ * Copyright 2005 Mike McCormack
+ *
+ * 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
+ *
+ * NOTES
+ *  The compound file implementation of IStorage used for create
+ *  and manage substorages and streams within a storage object
+ *  residing in a compound file object.
+ *
+ * MSDN
+ *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stg/stg/istorage_compound_file_implementation.asp
  */
 
 #include <assert.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "winbase.h" /* for lstrlenW() and the likes */
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "windef.h"
+#include "winbase.h"
 #include "winnls.h"
-#include "debugtools.h"
+#include "winuser.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
 
 #include "storage32.h"
 #include "ole2.h"      /* For Write/ReadClassStm */
 #include "winreg.h"
 #include "wine/wingdi16.h"
 
-DEFAULT_DEBUG_CHANNEL(storage)
+WINE_DEFAULT_DEBUG_CHANNEL(storage);
 
 #define FILE_BEGIN 0
 
-
 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */
 #define OLESTREAM_ID 0x501
 #define OLESTREAM_MAX_STR_LEN 255
@@ -39,7 +69,7 @@ static const char rootPropertyName[] = "Root Entry";
 
 /* OLESTREAM memory structure to use for Get and Put Routines */
 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */
-typedef struct 
+typedef struct
 {
     DWORD dwOleID;
     DWORD dwTypeID;
@@ -49,7 +79,7 @@ typedef struct
     DWORD dwOleObjFileNameLength;
     DWORD dwMetaFileWidth;
     DWORD dwMetaFileHeight;
-    CHAR  strUnknown[8]; //don't know what is this 8 byts information in OLE stream.
+    CHAR  strUnknown[8]; /* don't know what is this 8 byts information in OLE stream. */
     DWORD dwDataLength;
     BYTE *pData;
 }OLECONVERT_OLESTREAM_DATA;
@@ -77,7 +107,7 @@ typedef struct
     BYTE byUnknown1[28];
     DWORD dwExtentX;
     DWORD dwExtentY;
-    DWORD dwSize;  
+    DWORD dwSize;
     BYTE *pData;
 }OLECONVERT_ISTORAGE_OLEPRES;
 
@@ -102,7 +132,7 @@ static HRESULT findPlaceholder(
   ULONG         storagePropertyIndex,
   INT         typeOfRelation);
 
-static HRESULT adjustPropertyChain( 
+static HRESULT adjustPropertyChain(
   StorageImpl *This,
   StgProperty   propertyToDelete,
   StgProperty   parentProperty,
@@ -122,87 +152,20 @@ static void updatePropertyChain(
   StgProperty newProperty);
 
 static LONG propertyNameCmp(
-  OLECHAR *newProperty,
-  OLECHAR *currentProperty);
+    const OLECHAR *newProperty,
+    const OLECHAR *currentProperty);
 
 
 /***********************************************************************
  * Declaration of miscellaneous functions...
  */
-static HRESULT validateSTGM(DWORD stgmValue); 
+static HRESULT validateSTGM(DWORD stgmValue);
 
 static DWORD GetShareModeFromSTGM(DWORD stgm);
 static DWORD GetAccessModeFromSTGM(DWORD stgm);
 static DWORD GetCreationModeFromSTGM(DWORD stgm);
 
-/*
- * Virtual function table for the IStorage32Impl class.
- */
-static ICOM_VTABLE(IStorage) Storage32Impl_Vtbl =
-{
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    StorageBaseImpl_QueryInterface,
-    StorageBaseImpl_AddRef,
-    StorageBaseImpl_Release,
-    StorageBaseImpl_CreateStream,
-    StorageBaseImpl_OpenStream,
-    StorageImpl_CreateStorage,
-    StorageBaseImpl_OpenStorage,
-    StorageImpl_CopyTo,
-    StorageImpl_MoveElementTo,
-    StorageImpl_Commit,
-    StorageImpl_Revert,
-    StorageBaseImpl_EnumElements,
-    StorageImpl_DestroyElement,
-    StorageBaseImpl_RenameElement,
-    StorageImpl_SetElementTimes,
-    StorageBaseImpl_SetClass,
-    StorageImpl_SetStateBits,
-    StorageBaseImpl_Stat
-};
-
-/*
- * Virtual function table for the Storage32InternalImpl class.
- */
-static ICOM_VTABLE(IStorage) Storage32InternalImpl_Vtbl =
-  {
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    StorageBaseImpl_QueryInterface,
-    StorageBaseImpl_AddRef,
-    StorageBaseImpl_Release,
-    StorageBaseImpl_CreateStream,
-    StorageBaseImpl_OpenStream,
-    StorageImpl_CreateStorage,
-    StorageBaseImpl_OpenStorage,
-    StorageImpl_CopyTo,
-    StorageImpl_MoveElementTo,
-    StorageInternalImpl_Commit,
-    StorageInternalImpl_Revert,
-    StorageBaseImpl_EnumElements,
-    StorageImpl_DestroyElement,
-    StorageBaseImpl_RenameElement,
-    StorageImpl_SetElementTimes,
-    StorageBaseImpl_SetClass,
-    StorageImpl_SetStateBits,
-    StorageBaseImpl_Stat
-};
-
-/*
- * Virtual function table for the IEnumSTATSTGImpl class.
- */
-static ICOM_VTABLE(IEnumSTATSTG) IEnumSTATSTGImpl_Vtbl =
-{
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    IEnumSTATSTGImpl_QueryInterface,
-    IEnumSTATSTGImpl_AddRef,
-    IEnumSTATSTGImpl_Release,
-    IEnumSTATSTGImpl_Next,
-    IEnumSTATSTGImpl_Skip,
-    IEnumSTATSTGImpl_Reset,
-    IEnumSTATSTGImpl_Clone
-};
-
-
+extern const IPropertySetStorageVtbl IPropertySetStorage_Vtbl;
 
 
 
@@ -215,7 +178,7 @@ static ICOM_VTABLE(IEnumSTATSTG) IEnumSTATSTGImpl_Vtbl =
  *
  * This method implements the common QueryInterface for all IStorage32
  * implementations contained in this file.
- * 
+ *
  * See Windows documentation for more details on IUnknown methods.
  */
 HRESULT WINAPI StorageBaseImpl_QueryInterface(
@@ -223,95 +186,101 @@ HRESULT WINAPI StorageBaseImpl_QueryInterface(
   REFIID             riid,
   void**             ppvObject)
 {
-  ICOM_THIS(StorageBaseImpl,iface);
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
   /*
    * Perform a sanity check on the parameters.
    */
   if ( (This==0) || (ppvObject==0) )
     return E_INVALIDARG;
-  
+
   /*
    * Initialize the return parameter.
    */
   *ppvObject = 0;
-  
+
   /*
    * Compare the riid with the interface IDs implemented by this object.
    */
-  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 
+  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
   {
     *ppvObject = (IStorage*)This;
   }
-  else if (memcmp(&IID_IStorage, riid, sizeof(IID_IStorage)) == 0) 
+  else if (memcmp(&IID_IStorage, riid, sizeof(IID_IStorage)) == 0)
   {
     *ppvObject = (IStorage*)This;
   }
-  
+  else if (memcmp(&IID_IPropertySetStorage, riid, sizeof(IID_IPropertySetStorage)) == 0)
+  {
+    *ppvObject = (IStorage*)&This->pssVtbl;
+  }
+
   /*
    * Check that we obtained an interface.
    */
   if ((*ppvObject)==0)
     return E_NOINTERFACE;
-  
+
   /*
    * Query Interface always increases the reference count by one when it is
    * successful
    */
-  StorageBaseImpl_AddRef(iface);
+  IStorage_AddRef(iface);
 
   return S_OK;
 }
-        
+
 /************************************************************************
  * Storage32BaseImpl_AddRef (IUnknown)
  *
  * This method implements the common AddRef for all IStorage32
  * implementations contained in this file.
- * 
+ *
  * See Windows documentation for more details on IUnknown methods.
  */
-ULONG WINAPI StorageBaseImpl_AddRef( 
+ULONG WINAPI StorageBaseImpl_AddRef(
             IStorage* iface)
 {
-  ICOM_THIS(StorageBaseImpl,iface);
-  This->ref++;
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
+  ULONG ref = InterlockedIncrement(&This->ref);
+
+  TRACE("(%p) AddRef to %ld\n", This, ref);
 
-  return This->ref;
+  return ref;
 }
-        
+
 /************************************************************************
  * Storage32BaseImpl_Release (IUnknown)
  *
  * This method implements the common Release for all IStorage32
  * implementations contained in this file.
- * 
+ *
  * See Windows documentation for more details on IUnknown methods.
  */
-ULONG WINAPI StorageBaseImpl_Release( 
+ULONG WINAPI StorageBaseImpl_Release(
       IStorage* iface)
 {
-  ICOM_THIS(StorageBaseImpl,iface);
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
   /*
    * Decrease the reference count on this object.
    */
-  This->ref--;
+  ULONG ref = InterlockedDecrement(&This->ref);
+
+  TRACE("(%p) ReleaseRef to %ld\n", This, ref);
 
   /*
    * If the reference count goes down to 0, perform suicide.
    */
-  if (This->ref==0)
+  if (ref == 0)
   {
     /*
-     * Since we are using a system of base-classes, we want to call the 
-     * destructor of the appropriate derived class. To do this, we are 
+     * Since we are using a system of base-classes, we want to call the
+     * destructor of the appropriate derived class. To do this, we are
      * using virtual functions to implement the destructor.
      */
     This->v_destructor(This);
-
-    return 0;
   }
-  
-  return This->ref;
+
+  return ref;
 }
 
 /************************************************************************
@@ -321,55 +290,76 @@ ULONG WINAPI StorageBaseImpl_Release(
  *
  * See Windows documentation for more details on IStorage methods.
  */
-HRESULT WINAPI StorageBaseImpl_OpenStream( 
+HRESULT WINAPI StorageBaseImpl_OpenStream(
   IStorage*        iface,
   const OLECHAR*   pwcsName,  /* [string][in] */
   void*            reserved1, /* [unique][in] */
-  DWORD            grfMode,   /* [in]  */        
-  DWORD            reserved2, /* [in]  */        
-  IStream**        ppstm)     /* [out] */       
+  DWORD            grfMode,   /* [in]  */
+  DWORD            reserved2, /* [in]  */
+  IStream**        ppstm)     /* [out] */
 {
-  ICOM_THIS(StorageBaseImpl,iface);
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
   IEnumSTATSTGImpl* propertyEnumeration;
   StgStreamImpl*    newStream;
   StgProperty       currentProperty;
   ULONG             foundPropertyIndex;
+  HRESULT           res = STG_E_UNKNOWN;
+  DWORD             parent_grfMode;
 
-  TRACE("(%p, %s, %p, %lx, %ld, %p)\n", 
+  TRACE("(%p, %s, %p, %lx, %ld, %p)\n",
        iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm);
 
   /*
    * Perform a sanity check on the parameters.
    */
   if ( (pwcsName==NULL) || (ppstm==0) )
-    return E_INVALIDARG;
-  
+  {
+    res = E_INVALIDARG;
+    goto end;
+  }
+
   /*
    * Initialize the out parameter
    */
-  *ppstm = 0;
-  
+  *ppstm = NULL;
+
   /*
    * Validate the STGM flags
    */
   if ( FAILED( validateSTGM(grfMode) ))
-    return STG_E_INVALIDFLAG;
+  {
+    res = STG_E_INVALIDFLAG;
+    goto end;
+  }
 
   /*
    * As documented.
    */
-  if ( !(grfMode & STGM_SHARE_EXCLUSIVE) ||
+  if ( STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE ||
         (grfMode & STGM_DELETEONRELEASE) ||
         (grfMode & STGM_TRANSACTED) )
-    return STG_E_INVALIDFUNCTION;
+  {
+    res = STG_E_INVALIDFUNCTION;
+    goto end;
+  }
+
+  /*
+   * Check that we're compatible with the parent's storage mode
+   */
+  parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
+  if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
+  {
+    res = STG_E_ACCESSDENIED;
+    goto end;
+  }
 
   /*
    * Create a property enumeration to search the properties
    */
   propertyEnumeration = IEnumSTATSTGImpl_Construct(
-    This->ancestorStorage, 
+    This->ancestorStorage,
     This->rootPropertySetIndex);
-  
+
   /*
    * Search the enumeration for the property with the given name
    */
@@ -377,98 +367,134 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
     propertyEnumeration,
     pwcsName,
     &currentProperty);
-  
+
   /*
    * Delete the property enumeration since we don't need it anymore
    */
   IEnumSTATSTGImpl_Destroy(propertyEnumeration);
-  
+
   /*
    * If it was found, construct the stream object and return a pointer to it.
    */
-  if ( (foundPropertyIndex!=PROPERTY_NULL) && 
+  if ( (foundPropertyIndex!=PROPERTY_NULL) &&
        (currentProperty.propertyType==PROPTYPE_STREAM) )
   {
     newStream = StgStreamImpl_Construct(This, grfMode, foundPropertyIndex);
-    
+
     if (newStream!=0)
     {
       newStream->grfMode = grfMode;
       *ppstm = (IStream*)newStream;
 
       /*
-       * Since we are returning a pointer to the interface, we have to 
+       * Since we are returning a pointer to the interface, we have to
        * nail down the reference.
        */
-      StgStreamImpl_AddRef(*ppstm);
-      
-      return S_OK;
+      IStream_AddRef(*ppstm);
+
+      res = S_OK;
+      goto end;
     }
-    
-    return E_OUTOFMEMORY;
+
+    res = E_OUTOFMEMORY;
+    goto end;
   }
-  
-  return STG_E_FILENOTFOUND;
+
+  res = STG_E_FILENOTFOUND;
+
+end:
+  if (res == S_OK)
+    TRACE("<-- IStream %p\n", *ppstm);
+  TRACE("<-- %08lx\n", res);
+  return res;
 }
 
 /************************************************************************
  * Storage32BaseImpl_OpenStorage (IStorage)
  *
  * This method will open a new storage object from the current storage.
- * 
+ *
  * See Windows documentation for more details on IStorage methods.
- */        
-HRESULT WINAPI StorageBaseImpl_OpenStorage( 
+ */
+HRESULT WINAPI StorageBaseImpl_OpenStorage(
   IStorage*        iface,
-  const OLECHAR*   pwcsName,      /* [string][unique][in] */ 
-  IStorage*        pstgPriority,  /* [unique][in] */         
-  DWORD            grfMode,       /* [in] */                 
-  SNB              snbExclude,    /* [unique][in] */         
-  DWORD            reserved,      /* [in] */                 
-  IStorage**       ppstg)         /* [out] */                        
-{
-  ICOM_THIS(StorageBaseImpl,iface);
+  const OLECHAR*   pwcsName,      /* [string][unique][in] */
+  IStorage*        pstgPriority,  /* [unique][in] */
+  DWORD            grfMode,       /* [in] */
+  SNB              snbExclude,    /* [unique][in] */
+  DWORD            reserved,      /* [in] */
+  IStorage**       ppstg)         /* [out] */
+{
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
   StorageInternalImpl* newStorage;
   IEnumSTATSTGImpl*      propertyEnumeration;
   StgProperty            currentProperty;
   ULONG                  foundPropertyIndex;
+  HRESULT                res = STG_E_UNKNOWN;
+  DWORD                  parent_grfMode;
 
-  TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n", 
-       iface, debugstr_w(pwcsName), pstgPriority, 
+  TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n",
+       iface, debugstr_w(pwcsName), pstgPriority,
        grfMode, snbExclude, reserved, ppstg);
-  
+
   /*
    * Perform a sanity check on the parameters.
    */
   if ( (This==0) || (pwcsName==NULL) || (ppstg==0) )
-    return E_INVALIDARG;
-  
+  {
+    res = E_INVALIDARG;
+    goto end;
+  }
+
+  /* as documented */
+  if (snbExclude != NULL)
+  {
+    res = STG_E_INVALIDPARAMETER;
+    goto end;
+  }
+
   /*
    * Validate the STGM flags
    */
   if ( FAILED( validateSTGM(grfMode) ))
-    return STG_E_INVALIDFLAG;
+  {
+    res = STG_E_INVALIDFLAG;
+    goto end;
+  }
 
   /*
    * As documented.
    */
-  if ( !(grfMode & STGM_SHARE_EXCLUSIVE) || 
+  if ( STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE ||
         (grfMode & STGM_DELETEONRELEASE) ||
         (grfMode & STGM_PRIORITY) )
-    return STG_E_INVALIDFUNCTION;
+  {
+    res = STG_E_INVALIDFUNCTION;
+    goto end;
+  }
+
+  /*
+   * Check that we're compatible with the parent's storage mode
+   */
+  parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
+  if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
+  {
+    res = STG_E_ACCESSDENIED;
+    goto end;
+  }
 
   /*
    * Initialize the out parameter
    */
-  *ppstg = 0;
-  
+  *ppstg = NULL;
+
   /*
    * Create a property enumeration to search the properties
    */
   propertyEnumeration = IEnumSTATSTGImpl_Construct(
-                          This->ancestorStorage, 
+                          This->ancestorStorage,
                           This->rootPropertySetIndex);
-  
+
   /*
    * Search the enumeration for the property with the given name
    */
@@ -476,16 +502,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
                          propertyEnumeration,
                          pwcsName,
                          &currentProperty);
-  
+
   /*
    * Delete the property enumeration since we don't need it anymore
    */
   IEnumSTATSTGImpl_Destroy(propertyEnumeration);
-  
+
   /*
    * If it was found, construct the stream object and return a pointer to it.
    */
-  if ( (foundPropertyIndex!=PROPERTY_NULL) && 
+  if ( (foundPropertyIndex!=PROPERTY_NULL) &&
        (currentProperty.propertyType==PROPTYPE_STORAGE) )
   {
     /*
@@ -493,46 +519,53 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
      */
     newStorage = StorageInternalImpl_Construct(
                    This->ancestorStorage,
+                   grfMode,
                    foundPropertyIndex);
-    
+
     if (newStorage != 0)
     {
       *ppstg = (IStorage*)newStorage;
 
       /*
-       * Since we are returning a pointer to the interface, 
+       * Since we are returning a pointer to the interface,
        * we have to nail down the reference.
        */
       StorageBaseImpl_AddRef(*ppstg);
-      
-      return S_OK;
+
+      res = S_OK;
+      goto end;
     }
-    
-    return STG_E_INSUFFICIENTMEMORY;
+
+    res = STG_E_INSUFFICIENTMEMORY;
+    goto end;
   }
-  
-  return STG_E_FILENOTFOUND;
+
+  res = STG_E_FILENOTFOUND;
+
+end:
+  TRACE("<-- %08lx\n", res);
+  return res;
 }
 
 /************************************************************************
  * Storage32BaseImpl_EnumElements (IStorage)
  *
- * This method will create an enumerator object that can be used to 
+ * This method will create an enumerator object that can be used to
  * retrieve informatino about all the properties in the storage object.
- * 
+ *
  * See Windows documentation for more details on IStorage methods.
- */        
-HRESULT WINAPI StorageBaseImpl_EnumElements( 
+ */
+HRESULT WINAPI StorageBaseImpl_EnumElements(
   IStorage*       iface,
-  DWORD           reserved1, /* [in] */                  
-  void*           reserved2, /* [size_is][unique][in] */ 
-  DWORD           reserved3, /* [in] */                  
-  IEnumSTATSTG**  ppenum)    /* [out] */                 
+  DWORD           reserved1, /* [in] */
+  void*           reserved2, /* [size_is][unique][in] */
+  DWORD           reserved3, /* [in] */
+  IEnumSTATSTG**  ppenum)    /* [out] */
 {
-  ICOM_THIS(StorageBaseImpl,iface);
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
   IEnumSTATSTGImpl* newEnum;
 
-  TRACE("(%p, %ld, %p, %ld, %p)\n", 
+  TRACE("(%p, %ld, %p, %ld, %p)\n",
        iface, reserved1, reserved2, reserved3, ppenum);
 
   /*
@@ -540,7 +573,7 @@ HRESULT WINAPI StorageBaseImpl_EnumElements(
    */
   if ( (This==0) || (ppenum==0))
     return E_INVALIDARG;
-  
+
   /*
    * Construct the enumerator.
    */
@@ -556,8 +589,8 @@ HRESULT WINAPI StorageBaseImpl_EnumElements(
      * Don't forget to nail down a reference to the new object before
      * returning it.
      */
-    IEnumSTATSTGImpl_AddRef(*ppenum);
-    
+    IEnumSTATSTG_AddRef(*ppenum);
+
     return S_OK;
   }
 
@@ -568,26 +601,30 @@ HRESULT WINAPI StorageBaseImpl_EnumElements(
  * Storage32BaseImpl_Stat (IStorage)
  *
  * This method will retrieve information about this storage object.
- * 
+ *
  * See Windows documentation for more details on IStorage methods.
- */        
-HRESULT WINAPI StorageBaseImpl_Stat( 
+ */
+HRESULT WINAPI StorageBaseImpl_Stat(
   IStorage*        iface,
-  STATSTG*         pstatstg,     /* [out] */ 
-  DWORD            grfStatFlag)  /* [in] */  
+  STATSTG*         pstatstg,     /* [out] */
+  DWORD            grfStatFlag)  /* [in] */
 {
-  ICOM_THIS(StorageBaseImpl,iface);
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
   StgProperty    curProperty;
-  BOOL         readSuccessful;
+  BOOL           readSuccessful;
+  HRESULT        res = STG_E_UNKNOWN;
 
-  TRACE("(%p, %p, %lx)\n", 
+  TRACE("(%p, %p, %lx)\n",
        iface, pstatstg, grfStatFlag);
 
   /*
    * Perform a sanity check on the parameters.
    */
   if ( (This==0) || (pstatstg==0))
-    return E_INVALIDARG;
+  {
+    res = E_INVALIDARG;
+    goto end;
+  }
 
   /*
    * Read the information from the property.
@@ -600,25 +637,34 @@ HRESULT WINAPI StorageBaseImpl_Stat(
   if (readSuccessful)
   {
     StorageUtl_CopyPropertyToSTATSTG(
-      pstatstg, 
-      &curProperty, 
+      pstatstg,
+      &curProperty,
       grfStatFlag);
-    
-    return S_OK;
+
+    res = S_OK;
+    goto end;
+  }
+
+  res = E_FAIL;
+
+end:
+  if (res == S_OK)
+  {
+    TRACE("<-- STATSTG: pwcsName: %s, type: %ld, cbSize.Low/High: %ld/%ld, grfMode: %08lx, grfLocksSupported: %ld, grfStateBits: %08lx\n", debugstr_w(pstatstg->pwcsName), pstatstg->type, pstatstg->cbSize.u.LowPart, pstatstg->cbSize.u.HighPart, pstatstg->grfMode, pstatstg->grfLocksSupported, pstatstg->grfStateBits);
   }
-  
-  return E_FAIL;
+  TRACE("<-- %08lx\n", res);
+  return res;
 }
 
 /************************************************************************
  * Storage32BaseImpl_RenameElement (IStorage)
  *
- * This method will rename the specified element. 
+ * This method will rename the specified element.
  *
  * See Windows documentation for more details on IStorage methods.
- * 
- * Implementation notes: The method used to rename consists of creating a clone 
- *    of the deleted StgProperty object setting it with the new name and to 
+ *
+ * Implementation notes: The method used to rename consists of creating a clone
+ *    of the deleted StgProperty object setting it with the new name and to
  *    perform a DestroyElement of the old StgProperty.
  */
 HRESULT WINAPI StorageBaseImpl_RenameElement(
@@ -626,12 +672,12 @@ HRESULT WINAPI StorageBaseImpl_RenameElement(
             const OLECHAR*   pwcsOldName,  /* [in] */
             const OLECHAR*   pwcsNewName)  /* [in] */
 {
-  ICOM_THIS(StorageBaseImpl,iface);
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
   IEnumSTATSTGImpl* propertyEnumeration;
   StgProperty       currentProperty;
   ULONG             foundPropertyIndex;
 
-  TRACE("(%p, %s, %s)\n", 
+  TRACE("(%p, %s, %s)\n",
        iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName));
 
   /*
@@ -656,7 +702,7 @@ HRESULT WINAPI StorageBaseImpl_RenameElement(
     return STG_E_FILEALREADYEXISTS;
   }
 
-  IEnumSTATSTGImpl_Reset((IEnumSTATSTG*)propertyEnumeration);
+  IEnumSTATSTG_Reset((IEnumSTATSTG*)propertyEnumeration);
 
   /*
    * Search the enumeration for the old property name
@@ -678,65 +724,65 @@ HRESULT WINAPI StorageBaseImpl_RenameElement(
     /*
      * Setup a new property for the renamed property
      */
-    renamedProperty.sizeOfNameString = 
+    renamedProperty.sizeOfNameString =
       ( lstrlenW(pwcsNewName)+1 ) * sizeof(WCHAR);
-  
+
     if (renamedProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN)
       return STG_E_INVALIDNAME;
-  
-    lstrcpyW(renamedProperty.name, pwcsNewName);
+
+    strcpyW(renamedProperty.name, pwcsNewName);
+
     renamedProperty.propertyType  = currentProperty.propertyType;
     renamedProperty.startingBlock = currentProperty.startingBlock;
-    renamedProperty.size.s.LowPart  = currentProperty.size.s.LowPart;
-    renamedProperty.size.s.HighPart = currentProperty.size.s.HighPart;
-  
+    renamedProperty.size.u.LowPart  = currentProperty.size.u.LowPart;
+    renamedProperty.size.u.HighPart = currentProperty.size.u.HighPart;
+
     renamedProperty.previousProperty = PROPERTY_NULL;
     renamedProperty.nextProperty     = PROPERTY_NULL;
-  
+
     /*
      * Bring the dirProperty link in case it is a storage and in which
      * case the renamed storage elements don't require to be reorganized.
      */
     renamedProperty.dirProperty = currentProperty.dirProperty;
-  
-    /* call CoFileTime to get the current time 
+
+    /* call CoFileTime to get the current time
     renamedProperty.timeStampS1
     renamedProperty.timeStampD1
     renamedProperty.timeStampS2
     renamedProperty.timeStampD2
-    renamedProperty.propertyUniqueID 
+    renamedProperty.propertyUniqueID
     */
-  
-    /* 
+
+    /*
      * Obtain a free property in the property chain
      */
     renamedPropertyIndex = getFreeProperty(This->ancestorStorage);
-  
+
     /*
      * Save the new property into the new property spot
-     */  
+     */
     StorageImpl_WriteProperty(
       This->ancestorStorage,
-      renamedPropertyIndex, 
+      renamedPropertyIndex,
       &renamedProperty);
-  
-    /* 
+
+    /*
      * Find a spot in the property chain for our newly created property.
      */
     updatePropertyChain(
       (StorageImpl*)This,
-      renamedPropertyIndex, 
+      renamedPropertyIndex,
       renamedProperty);
 
     /*
-     * At this point the renamed property has been inserted in the tree, 
-     * now, before to Destroy the old property we must zeroed it's dirProperty 
-     * otherwise the DestroyProperty below will zap it all and we do not want 
+     * At this point the renamed property has been inserted in the tree,
+     * now, before to Destroy the old property we must zeroed it's dirProperty
+     * otherwise the DestroyProperty below will zap it all and we do not want
      * this to happen.
      * Also, we fake that the old property is a storage so the DestroyProperty
      * will not do a SetSize(0) on the stream data.
-     * 
+     *
      * This means that we need to tweek the StgProperty if it is a stream or a
      * non empty storage.
      */
@@ -748,14 +794,14 @@ HRESULT WINAPI StorageBaseImpl_RenameElement(
     currentProperty.propertyType = PROPTYPE_STORAGE;
     StorageImpl_WriteProperty(
       This->ancestorStorage,
-      foundPropertyIndex, 
+      foundPropertyIndex,
       &currentProperty);
 
-    /* 
-     * Invoke Destroy to get rid of the ole property and automatically redo 
-     * the linking of it's previous and next members... 
-     */ 
-    StorageImpl_DestroyElement((IStorage*)This->ancestorStorage, pwcsOldName); 
+    /*
+     * Invoke Destroy to get rid of the ole property and automatically redo
+     * the linking of it's previous and next members...
+     */
+    IStorage_DestroyElement((IStorage*)This->ancestorStorage, pwcsOldName);
 
   }
   else
@@ -772,7 +818,7 @@ HRESULT WINAPI StorageBaseImpl_RenameElement(
 /************************************************************************
  * Storage32BaseImpl_CreateStream (IStorage)
  *
- * This method will create a stream object within this storage 
+ * This method will create a stream object within this storage
  *
  * See Windows documentation for more details on IStorage methods.
  */
@@ -784,14 +830,15 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
             DWORD            reserved2, /* [in] */
             IStream**        ppstm)     /* [out] */
 {
-  ICOM_THIS(StorageBaseImpl,iface);
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
   IEnumSTATSTGImpl* propertyEnumeration;
   StgStreamImpl*    newStream;
   StgProperty       currentProperty, newStreamProperty;
   ULONG             foundPropertyIndex, newPropertyIndex;
+  DWORD             parent_grfMode;
 
-  TRACE("(%p, %s, %lx, %ld, %ld, %p)\n", 
-       iface, debugstr_w(pwcsName), grfMode, 
+  TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
+       iface, debugstr_w(pwcsName), grfMode,
        reserved1, reserved2, ppstm);
 
   /*
@@ -803,20 +850,32 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
   if (pwcsName == 0)
     return STG_E_INVALIDNAME;
 
+  if (reserved1 || reserved2)
+    return STG_E_INVALIDPARAMETER;
+
   /*
    * Validate the STGM flags
    */
   if ( FAILED( validateSTGM(grfMode) ))
     return STG_E_INVALIDFLAG;
 
+  if (STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE) 
+    return STG_E_INVALIDFLAG;
+
   /*
    * As documented.
    */
-  if ( !(grfMode & STGM_SHARE_EXCLUSIVE) ||
-        (grfMode & STGM_DELETEONRELEASE) ||
-        (grfMode & STGM_TRANSACTED) )
+  if ((grfMode & STGM_DELETEONRELEASE) ||
+      (grfMode & STGM_TRANSACTED))
     return STG_E_INVALIDFUNCTION;
 
+  /*
+   * Check that we're compatible with the parent's storage mode
+   */
+  parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
+  if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
+    return STG_E_ACCESSDENIED;
+
   /*
    * Initialize the out parameter
    */
@@ -837,18 +896,18 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
   if (foundPropertyIndex != PROPERTY_NULL)
   {
     /*
-     * An element with this name already exists 
+     * An element with this name already exists
      */
-    if (grfMode & STGM_CREATE)
+    if (STGM_CREATE_MODE(grfMode) == STGM_CREATE)
     {
-      IStorage_DestroyElement(iface, pwcsName); 
+      IStorage_DestroyElement(iface, pwcsName);
     }
-    else 
+    else
       return STG_E_FILEALREADYEXISTS;
   }
 
-  /* 
-   * memset the empty property 
+  /*
+   * memset the empty property
    */
   memset(&newStreamProperty, 0, sizeof(StgProperty));
 
@@ -858,18 +917,18 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
   if (newStreamProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN)
     return STG_E_INVALIDNAME;
 
-  lstrcpyW(newStreamProperty.name, pwcsName);
+  strcpyW(newStreamProperty.name, pwcsName);
 
   newStreamProperty.propertyType  = PROPTYPE_STREAM;
   newStreamProperty.startingBlock = BLOCK_END_OF_CHAIN;
-  newStreamProperty.size.s.LowPart  = 0;
-  newStreamProperty.size.s.HighPart = 0;
+  newStreamProperty.size.u.LowPart  = 0;
+  newStreamProperty.size.u.HighPart = 0;
 
   newStreamProperty.previousProperty = PROPERTY_NULL;
   newStreamProperty.nextProperty     = PROPERTY_NULL;
   newStreamProperty.dirProperty      = PROPERTY_NULL;
 
-  /* call CoFileTime to get the current time 
+  /* call CoFileTime to get the current time
   newStreamProperty.timeStampS1
   newStreamProperty.timeStampD1
   newStreamProperty.timeStampS2
@@ -879,27 +938,27 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
   /*  newStreamProperty.propertyUniqueID */
 
   /*
-   * Get a free property or create a new one 
+   * Get a free property or create a new one
    */
   newPropertyIndex = getFreeProperty(This->ancestorStorage);
 
   /*
    * Save the new property into the new property spot
-   */  
+   */
   StorageImpl_WriteProperty(
     This->ancestorStorage,
-    newPropertyIndex, 
+    newPropertyIndex,
     &newStreamProperty);
 
-  /* 
+  /*
    * Find a spot in the property chain for our newly created property.
    */
   updatePropertyChain(
     (StorageImpl*)This,
-    newPropertyIndex, 
+    newPropertyIndex,
     newStreamProperty);
 
-  /* 
+  /*
    * Open the stream to return it.
    */
   newStream = StgStreamImpl_Construct(This, grfMode, newPropertyIndex);
@@ -912,7 +971,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
      * Since we are returning a pointer to the interface, we have to nail down
      * the reference.
      */
-    StgStreamImpl_AddRef(*ppstm);
+    IStream_AddRef(*ppstm);
   }
   else
   {
@@ -925,7 +984,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
 /************************************************************************
  * Storage32BaseImpl_SetClass (IStorage)
  *
- * This method will write the specified CLSID in the property of this 
+ * This method will write the specified CLSID in the property of this
  * storage.
  *
  * See Windows documentation for more details on IStorage methods.
@@ -934,13 +993,13 @@ HRESULT WINAPI StorageBaseImpl_SetClass(
   IStorage*        iface,
   REFCLSID         clsid) /* [in] */
 {
-  ICOM_THIS(StorageBaseImpl,iface);
+  StorageBaseImpl *This = (StorageBaseImpl *)iface;
   HRESULT hRes = E_FAIL;
   StgProperty curProperty;
   BOOL success;
 
   TRACE("(%p, %p)\n", iface, clsid);
-  
+
   success = StorageImpl_ReadProperty(This->ancestorStorage,
                                        This->rootPropertySetIndex,
                                        &curProperty);
@@ -961,7 +1020,7 @@ HRESULT WINAPI StorageBaseImpl_SetClass(
 /************************************************************************
 ** Storage32Impl implementation
 */
-        
+
 /************************************************************************
  * Storage32Impl_CreateStorage (IStorage)
  *
@@ -969,13 +1028,13 @@ HRESULT WINAPI StorageBaseImpl_SetClass(
  *
  * See Windows documentation for more details on IStorage methods.
  */
-HRESULT WINAPI StorageImpl_CreateStorage( 
+HRESULT WINAPI StorageImpl_CreateStorage(
   IStorage*      iface,
-  const OLECHAR  *pwcsName, /* [string][in] */ 
-  DWORD            grfMode,   /* [in] */ 
-  DWORD            reserved1, /* [in] */ 
-  DWORD            reserved2, /* [in] */ 
-  IStorage       **ppstg)   /* [out] */ 
+  const OLECHAR  *pwcsName, /* [string][in] */
+  DWORD            grfMode,   /* [in] */
+  DWORD            reserved1, /* [in] */
+  DWORD            reserved2, /* [in] */
+  IStorage       **ppstg)   /* [out] */
 {
   StorageImpl* const This=(StorageImpl*)iface;
 
@@ -985,11 +1044,12 @@ HRESULT WINAPI StorageImpl_CreateStorage(
   ULONG            foundPropertyIndex;
   ULONG            newPropertyIndex;
   HRESULT          hr;
+  DWORD            parent_grfMode;
 
-  TRACE("(%p, %s, %lx, %ld, %ld, %p)\n", 
-       iface, debugstr_w(pwcsName), grfMode, 
+  TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
+       iface, debugstr_w(pwcsName), grfMode,
        reserved1, reserved2, ppstg);
-  
+
   /*
    * Validate parameters
    */
@@ -1006,6 +1066,13 @@ HRESULT WINAPI StorageImpl_CreateStorage(
        (grfMode & STGM_DELETEONRELEASE) )
     return STG_E_INVALIDFLAG;
 
+  /*
+   * Check that we're compatible with the parent's storage mode
+   */
+  parent_grfMode = STGM_ACCESS_MODE( This->base.ancestorStorage->base.openFlags );
+  if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
+    return STG_E_ACCESSDENIED;
+
   /*
    * Initialize the out parameter
    */
@@ -1014,8 +1081,8 @@ HRESULT WINAPI StorageImpl_CreateStorage(
   /*
    * Create a property enumeration and search the properties
    */
-  propertyEnumeration = IEnumSTATSTGImpl_Construct( This->ancestorStorage,
-                                                    This->rootPropertySetIndex);
+  propertyEnumeration = IEnumSTATSTGImpl_Construct( This->base.ancestorStorage,
+                                                    This->base.rootPropertySetIndex);
 
   foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration,
                                                      pwcsName,
@@ -1025,16 +1092,16 @@ HRESULT WINAPI StorageImpl_CreateStorage(
   if (foundPropertyIndex != PROPERTY_NULL)
   {
     /*
-     * An element with this name already exists 
+     * An element with this name already exists
      */
-    if (grfMode & STGM_CREATE)
-      IStorage_DestroyElement(iface, pwcsName); 
-    else 
+    if (STGM_CREATE_MODE(grfMode) == STGM_CREATE)
+      IStorage_DestroyElement(iface, pwcsName);
+    else
       return STG_E_FILEALREADYEXISTS;
   }
 
-  /* 
-   * memset the empty property 
+  /*
+   * memset the empty property
    */
   memset(&newProperty, 0, sizeof(StgProperty));
 
@@ -1043,18 +1110,18 @@ HRESULT WINAPI StorageImpl_CreateStorage(
   if (newProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN)
     return STG_E_INVALIDNAME;
 
-  lstrcpyW(newProperty.name, pwcsName);
+  strcpyW(newProperty.name, pwcsName);
 
   newProperty.propertyType  = PROPTYPE_STORAGE;
   newProperty.startingBlock = BLOCK_END_OF_CHAIN;
-  newProperty.size.s.LowPart  = 0;
-  newProperty.size.s.HighPart = 0;
+  newProperty.size.u.LowPart  = 0;
+  newProperty.size.u.HighPart = 0;
 
   newProperty.previousProperty = PROPERTY_NULL;
   newProperty.nextProperty     = PROPERTY_NULL;
   newProperty.dirProperty      = PROPERTY_NULL;
 
-  /* call CoFileTime to get the current time 
+  /* call CoFileTime to get the current time
   newProperty.timeStampS1
   newProperty.timeStampD1
   newProperty.timeStampS2
@@ -1063,33 +1130,33 @@ HRESULT WINAPI StorageImpl_CreateStorage(
 
   /*  newStorageProperty.propertyUniqueID */
 
-  /* 
+  /*
    * Obtain a free property in the property chain
    */
-  newPropertyIndex = getFreeProperty(This->ancestorStorage);
+  newPropertyIndex = getFreeProperty(This->base.ancestorStorage);
 
   /*
    * Save the new property into the new property spot
-   */  
+   */
   StorageImpl_WriteProperty(
-    This->ancestorStorage,
-    newPropertyIndex, 
+    This->base.ancestorStorage,
+    newPropertyIndex,
     &newProperty);
 
-  /* 
+  /*
    * Find a spot in the property chain for our newly created property.
    */
   updatePropertyChain(
     This,
-    newPropertyIndex, 
+    newPropertyIndex,
     newProperty);
 
-  /* 
+  /*
    * Open it to get a pointer to return.
    */
   hr = IStorage_OpenStorage(
          iface,
-         (OLECHAR*)pwcsName,
+         (const OLECHAR*)pwcsName,
          0,
          grfMode,
          0,
@@ -1101,7 +1168,7 @@ HRESULT WINAPI StorageImpl_CreateStorage(
     return hr;
   }
 
-  
+
   return S_OK;
 }
 
@@ -1125,14 +1192,14 @@ static ULONG getFreeProperty(
     /*
      * Start by reading the root property
      */
-    readSuccessful = StorageImpl_ReadProperty(storage->ancestorStorage,
+    readSuccessful = StorageImpl_ReadProperty(storage->base.ancestorStorage,
                                                currentPropertyIndex,
                                                &currentProperty);
     if (readSuccessful)
     {
       if (currentProperty.sizeOfNameString == 0)
       {
-        /* 
+        /*
          * The property existis and is available, we found it.
          */
         newPropertyIndex = currentPropertyIndex;
@@ -1149,8 +1216,8 @@ static ULONG getFreeProperty(
 
   } while (newPropertyIndex == PROPERTY_NULL);
 
-  /* 
-   * grow the property chain 
+  /*
+   * grow the property chain
    */
   if (! readSuccessful)
   {
@@ -1160,42 +1227,42 @@ static ULONG getFreeProperty(
     ULONG          lastProperty  = 0;
     ULONG          blockCount    = 0;
 
-    /* 
-     * obtain the new count of property blocks 
+    /*
+     * obtain the new count of property blocks
      */
     blockCount = BlockChainStream_GetCount(
-                   storage->ancestorStorage->rootBlockChain)+1;
+                   storage->base.ancestorStorage->rootBlockChain)+1;
 
-    /* 
-     * initialize the size used by the property stream 
+    /*
+     * initialize the size used by the property stream
      */
-    newSize.s.HighPart = 0;
-    newSize.s.LowPart  = storage->bigBlockSize * blockCount;
+    newSize.u.HighPart = 0;
+    newSize.u.LowPart  = storage->bigBlockSize * blockCount;
 
-    /* 
-     * add a property block to the property chain 
+    /*
+     * add a property block to the property chain
      */
-    BlockChainStream_SetSize(storage->ancestorStorage->rootBlockChain, newSize);
+    BlockChainStream_SetSize(storage->base.ancestorStorage->rootBlockChain, newSize);
 
-    /* 
-     * memset the empty property in order to initialize the unused newly 
+    /*
+     * memset the empty property in order to initialize the unused newly
      * created property
      */
     memset(&emptyProperty, 0, sizeof(StgProperty));
 
-    /* 
+    /*
      * initialize them
      */
-    lastProperty = storage->bigBlockSize / PROPSET_BLOCK_SIZE * blockCount; 
-    
+    lastProperty = storage->bigBlockSize / PROPSET_BLOCK_SIZE * blockCount;
+
     for(
       propertyIndex = newPropertyIndex;
       propertyIndex < lastProperty;
       propertyIndex++)
     {
       StorageImpl_WriteProperty(
-        storage->ancestorStorage,
-        propertyIndex, 
+        storage->base.ancestorStorage,
+        propertyIndex,
         &emptyProperty);
     }
   }
@@ -1207,7 +1274,7 @@ static ULONG getFreeProperty(
  *
  * Internal Method
  *
- * Case insensitive comparaison of StgProperty.name by first considering 
+ * Case insensitive comparaison of StgProperty.name by first considering
  * their size.
  *
  * Returns <0 when newPrpoerty < currentProperty
@@ -1215,20 +1282,20 @@ static ULONG getFreeProperty(
  *          0 when newPrpoerty == currentProperty
  */
 static LONG propertyNameCmp(
-  OLECHAR *newProperty,
-  OLECHAR *currentProperty)
+    const OLECHAR *newProperty,
+    const OLECHAR *currentProperty)
 {
   LONG diff      = lstrlenW(newProperty) - lstrlenW(currentProperty);
 
-  if (diff == 0) 
+  if (diff == 0)
   {
-    /* 
-     * We compare the string themselves only when they are of the same lenght
+    /*
+     * We compare the string themselves only when they are of the same length
      */
     diff = lstrcmpiW( newProperty, currentProperty);
   }
 
-  return diff;  
+  return diff;
 }
 
 /****************************************************************************
@@ -1240,20 +1307,20 @@ static LONG propertyNameCmp(
 static void updatePropertyChain(
   StorageImpl *storage,
   ULONG         newPropertyIndex,
-  StgProperty   newProperty) 
+  StgProperty   newProperty)
 {
   StgProperty currentProperty;
 
   /*
    * Read the root property
    */
-  StorageImpl_ReadProperty(storage->ancestorStorage,
-                             storage->rootPropertySetIndex,
+  StorageImpl_ReadProperty(storage->base.ancestorStorage,
+                             storage->base.rootPropertySetIndex,
                              &currentProperty);
 
   if (currentProperty.dirProperty != PROPERTY_NULL)
   {
-    /* 
+    /*
      * The root storage contains some element, therefore, start the research
      * for the appropriate location.
      */
@@ -1266,9 +1333,9 @@ static void updatePropertyChain(
     currentPropertyId = currentProperty.dirProperty;
 
     /*
-     * Read 
+     * Read
      */
-    StorageImpl_ReadProperty(storage->ancestorStorage,
+    StorageImpl_ReadProperty(storage->base.ancestorStorage,
                                currentProperty.dirProperty,
                                &currentProperty);
 
@@ -1279,12 +1346,12 @@ static void updatePropertyChain(
     while (found == 0)
     {
       LONG diff = propertyNameCmp( newProperty.name, currentProperty.name);
-  
+
       if (diff < 0)
       {
         if (previous != PROPERTY_NULL)
         {
-          StorageImpl_ReadProperty(storage->ancestorStorage,
+          StorageImpl_ReadProperty(storage->base.ancestorStorage,
                                      previous,
                                      &currentProperty);
           current = previous;
@@ -1292,7 +1359,7 @@ static void updatePropertyChain(
         else
         {
           currentProperty.previousProperty = newPropertyIndex;
-          StorageImpl_WriteProperty(storage->ancestorStorage,
+          StorageImpl_WriteProperty(storage->base.ancestorStorage,
                                       current,
                                       &currentProperty);
           found = 1;
@@ -1302,7 +1369,7 @@ static void updatePropertyChain(
       {
         if (next != PROPERTY_NULL)
         {
-          StorageImpl_ReadProperty(storage->ancestorStorage,
+          StorageImpl_ReadProperty(storage->base.ancestorStorage,
                                      next,
                                      &currentProperty);
           current = next;
@@ -1310,7 +1377,7 @@ static void updatePropertyChain(
         else
         {
           currentProperty.nextProperty = newPropertyIndex;
-          StorageImpl_WriteProperty(storage->ancestorStorage,
+          StorageImpl_WriteProperty(storage->base.ancestorStorage,
                                       current,
                                       &currentProperty);
           found = 1;
@@ -1331,26 +1398,26 @@ static void updatePropertyChain(
   }
   else
   {
-    /* 
+    /*
      * The root storage is empty, link the new property to it's dir property
      */
     currentProperty.dirProperty = newPropertyIndex;
-    StorageImpl_WriteProperty(storage->ancestorStorage,
-                                storage->rootPropertySetIndex,
+    StorageImpl_WriteProperty(storage->base.ancestorStorage,
+                                storage->base.rootPropertySetIndex,
                                 &currentProperty);
   }
 }
 
-      
+
 /*************************************************************************
  * CopyTo (IStorage)
  */
-HRESULT WINAPI StorageImpl_CopyTo( 
+HRESULT WINAPI StorageImpl_CopyTo(
   IStorage*   iface,
-  DWORD       ciidExclude,  /* [in] */ 
-  const IID*  rgiidExclude, /* [size_is][unique][in] */ 
-  SNB         snbExclude,   /* [unique][in] */ 
-  IStorage*   pstgDest)     /* [unique][in] */ 
+  DWORD       ciidExclude,  /* [in] */
+  const IID*  rgiidExclude, /* [size_is][unique][in] */
+  SNB         snbExclude,   /* [unique][in] */
+  IStorage*   pstgDest)     /* [unique][in] */
 {
   IEnumSTATSTG *elements     = 0;
   STATSTG      curElement, strStat;
@@ -1361,8 +1428,8 @@ HRESULT WINAPI StorageImpl_CopyTo(
   if ((ciidExclude != 0) || (rgiidExclude != NULL) || (snbExclude != NULL))
     FIXME("Exclude option not implemented\n");
 
-  TRACE("(%p, %ld, %p, %p, %p)\n", 
-       iface, ciidExclude, rgiidExclude, 
+  TRACE("(%p, %ld, %p, %p, %p)\n",
+       iface, ciidExclude, rgiidExclude,
        snbExclude, pstgDest);
 
   /*
@@ -1371,7 +1438,7 @@ HRESULT WINAPI StorageImpl_CopyTo(
   if ( pstgDest == 0 )
     return STG_E_INVALIDPOINTER;
 
-  /* 
+  /*
    * Enumerate the elements
    */
   hr = IStorage_EnumElements( iface, 0, 0, 0, &elements );
@@ -1384,7 +1451,7 @@ HRESULT WINAPI StorageImpl_CopyTo(
    */
   IStorage_Stat( iface, &curElement, STATFLAG_NONAME);
   IStorage_SetClass( pstgDest, &curElement.clsid );
-  
+
   do
   {
     /*
@@ -1420,7 +1487,7 @@ HRESULT WINAPI StorageImpl_CopyTo(
 
        return STG_E_ACCESSDENIED;
       }
-            
+
       /*
        * create a new storage in destination storage
        */
@@ -1437,17 +1504,17 @@ HRESULT WINAPI StorageImpl_CopyTo(
                                    STGM_WRITE|STGM_SHARE_EXCLUSIVE,
                                    NULL, 0, &pstgTmp );
       }
-        
+
       if (hr != S_OK)
         break;
 
-        
+
       /*
        * do the copy recursively
        */
       hr = IStorage_CopyTo( pstgChild, ciidExclude, rgiidExclude,
                                snbExclude, pstgTmp );
-                                
+
       IStorage_Release( pstgTmp );
       IStorage_Release( pstgChild );
     }
@@ -1483,13 +1550,13 @@ HRESULT WINAPI StorageImpl_CopyTo(
        * Set the size of the destination stream.
        */
       IStream_SetSize(pstrTmp, strStat.cbSize);
-      
+
       /*
        * do the copy
        */
       hr = IStream_CopyTo( pstrChild, pstrTmp, strStat.cbSize,
                            NULL, NULL );
-                                
+
       IStream_Release( pstrTmp );
       IStream_Release( pstrChild );
     }
@@ -1504,39 +1571,48 @@ HRESULT WINAPI StorageImpl_CopyTo(
    * Clean-up
    */
   IEnumSTATSTG_Release(elements);
-  
+
   return hr;
 }
-        
+
 /*************************************************************************
  * MoveElementTo (IStorage)
  */
-HRESULT WINAPI StorageImpl_MoveElementTo( 
+HRESULT WINAPI StorageImpl_MoveElementTo(
   IStorage*     iface,
-  const OLECHAR *pwcsName,   /* [string][in] */ 
-  IStorage      *pstgDest,   /* [unique][in] */ 
-  const OLECHAR *pwcsNewName,/* [string][in] */ 
-  DWORD           grfFlags)    /* [in] */ 
+  const OLECHAR *pwcsName,   /* [string][in] */
+  IStorage      *pstgDest,   /* [unique][in] */
+  const OLECHAR *pwcsNewName,/* [string][in] */
+  DWORD           grfFlags)    /* [in] */
 {
   FIXME("not implemented!\n");
   return E_NOTIMPL;
 }
-        
+
 /*************************************************************************
  * Commit (IStorage)
+ *
+ * Ensures that any changes made to a storage object open in transacted mode
+ * are reflected in the parent storage
+ *
+ * NOTES
+ *  Wine doesn't implement transacted mode, which seems to be a basic
+ *  optimization, so we can ignore this stub for now.
  */
-HRESULT WINAPI StorageImpl_Commit( 
+HRESULT WINAPI StorageImpl_Commit(
   IStorage*   iface,
-  DWORD         grfCommitFlags)/* [in] */ 
+  DWORD         grfCommitFlags)/* [in] */
 {
   FIXME("(%ld): stub!\n", grfCommitFlags);
   return S_OK;
 }
-        
+
 /*************************************************************************
  * Revert (IStorage)
+ *
+ * Discard all changes that have been made since the last commit operation
  */
-HRESULT WINAPI StorageImpl_Revert( 
+HRESULT WINAPI StorageImpl_Revert(
   IStorage* iface)
 {
   FIXME("not implemented!\n");
@@ -1546,17 +1622,17 @@ HRESULT WINAPI StorageImpl_Revert(
 /*************************************************************************
  * DestroyElement (IStorage)
  *
- * Stategy: This implementation is build this way for simplicity not for speed. 
+ * Stategy: This implementation is build this way for simplicity not for speed.
  *          I always delete the top most element of the enumeration and adjust
- *          the deleted element pointer all the time.  This takes longer to 
- *          do but allow to reinvoke DestroyElement whenever we encounter a 
+ *          the deleted element pointer all the time.  This takes longer to
+ *          do but allow to reinvoke DestroyElement whenever we encounter a
  *          storage object.  The optimisation reside in the usage of another
- *          enumeration stategy that would give all the leaves of a storage 
+ *          enumeration stategy that would give all the leaves of a storage
  *          first. (postfix order)
  */
-HRESULT WINAPI StorageImpl_DestroyElement( 
+HRESULT WINAPI StorageImpl_DestroyElement(
   IStorage*     iface,
-  const OLECHAR *pwcsName)/* [string][in] */ 
+  const OLECHAR *pwcsName)/* [string][in] */
 {
   StorageImpl* const This=(StorageImpl*)iface;
 
@@ -1569,22 +1645,22 @@ HRESULT WINAPI StorageImpl_DestroyElement(
   ULONG             typeOfRelation;
   ULONG             parentPropertyId;
 
-  TRACE("(%p, %s)\n", 
+  TRACE("(%p, %s)\n",
        iface, debugstr_w(pwcsName));
 
   /*
    * Perform a sanity check on the parameters.
    */
-  if (pwcsName==NULL) 
+  if (pwcsName==NULL)
     return STG_E_INVALIDPOINTER;
-  
+
   /*
    * Create a property enumeration to search the property with the given name
    */
   propertyEnumeration = IEnumSTATSTGImpl_Construct(
-    This->ancestorStorage, 
-    This->rootPropertySetIndex);
-  
+    This->base.ancestorStorage,
+    This->base.rootPropertySetIndex);
+
   foundPropertyIndexToDelete = IEnumSTATSTGImpl_FindProperty(
     propertyEnumeration,
     pwcsName,
@@ -1592,51 +1668,51 @@ HRESULT WINAPI StorageImpl_DestroyElement(
 
   IEnumSTATSTGImpl_Destroy(propertyEnumeration);
 
-  if ( foundPropertyIndexToDelete == PROPERTY_NULL )  
+  if ( foundPropertyIndexToDelete == PROPERTY_NULL )
   {
     return STG_E_FILENOTFOUND;
   }
 
-  /* 
-   * Find the parent property of the property to delete (the one that 
-   * link to it).  If This->dirProperty == foundPropertyIndexToDelete, 
+  /*
+   * Find the parent property of the property to delete (the one that
+   * link to it).  If This->dirProperty == foundPropertyIndexToDelete,
    * the parent is This. Otherwise, the parent is one of it's sibling...
    */
 
-  /* 
+  /*
    * First, read This's StgProperty..
    */
-  res = StorageImpl_ReadProperty( 
-          This->ancestorStorage,
-          This->rootPropertySetIndex,
+  res = StorageImpl_ReadProperty(
+          This->base.ancestorStorage,
+          This->base.rootPropertySetIndex,
           &parentProperty);
 
-  assert(res==TRUE);
+  assert(res);
 
-  /* 
+  /*
    * Second, check to see if by any chance the actual storage (This) is not
    * the parent of the property to delete... We never know...
    */
   if ( parentProperty.dirProperty == foundPropertyIndexToDelete )
   {
-    /* 
+    /*
      * Set data as it would have been done in the else part...
      */
     typeOfRelation   = PROPERTY_RELATION_DIR;
-    parentPropertyId = This->rootPropertySetIndex;
+    parentPropertyId = This->base.rootPropertySetIndex;
   }
-  else 
-  { 
+  else
+  {
     /*
-     * Create a property enumeration to search the parent properties, and 
+     * Create a property enumeration to search the parent properties, and
      * delete it once done.
      */
     IEnumSTATSTGImpl* propertyEnumeration2;
 
     propertyEnumeration2 = IEnumSTATSTGImpl_Construct(
-      This->ancestorStorage, 
-      This->rootPropertySetIndex);
-  
+      This->base.ancestorStorage,
+      This->base.rootPropertySetIndex);
+
     typeOfRelation = IEnumSTATSTGImpl_FindParentProperty(
       propertyEnumeration2,
       foundPropertyIndexToDelete,
@@ -1646,22 +1722,22 @@ HRESULT WINAPI StorageImpl_DestroyElement(
     IEnumSTATSTGImpl_Destroy(propertyEnumeration2);
   }
 
-  if ( propertyToDelete.propertyType == PROPTYPE_STORAGE ) 
+  if ( propertyToDelete.propertyType == PROPTYPE_STORAGE )
   {
     hr = deleteStorageProperty(
-           This, 
+           This,
            foundPropertyIndexToDelete,
            propertyToDelete);
-  } 
+  }
   else if ( propertyToDelete.propertyType == PROPTYPE_STREAM )
   {
     hr = deleteStreamProperty(
-           This, 
+           This,
            foundPropertyIndexToDelete,
            propertyToDelete);
   }
 
-  if (hr!=S_OK) 
+  if (hr!=S_OK)
     return hr;
 
   /*
@@ -1669,7 +1745,7 @@ HRESULT WINAPI StorageImpl_DestroyElement(
    */
   hr = adjustPropertyChain(
         This,
-        propertyToDelete, 
+        propertyToDelete,
         parentProperty,
         parentPropertyId,
         typeOfRelation);
@@ -1678,6 +1754,32 @@ HRESULT WINAPI StorageImpl_DestroyElement(
 }
 
 
+/************************************************************************
+ * StorageImpl_Stat (IStorage)
+ *
+ * This method will retrieve information about this storage object.
+ *
+ * See Windows documentation for more details on IStorage methods.
+ */
+HRESULT WINAPI StorageImpl_Stat( IStorage* iface,
+                                 STATSTG*  pstatstg,     /* [out] */
+                                 DWORD     grfStatFlag)  /* [in] */
+{
+  StorageImpl* const This = (StorageImpl*)iface;
+  HRESULT result = StorageBaseImpl_Stat( iface, pstatstg, grfStatFlag );
+
+  if ( !FAILED(result) && ((grfStatFlag & STATFLAG_NONAME) == 0) && This->pwcsName )
+  {
+      CoTaskMemFree(pstatstg->pwcsName);
+      pstatstg->pwcsName = CoTaskMemAlloc((lstrlenW(This->pwcsName)+1)*sizeof(WCHAR));
+      strcpyW(pstatstg->pwcsName, This->pwcsName);
+  }
+
+  return result;
+}
+
+
+
 /*********************************************************************
  *
  * Internal Method
@@ -1713,7 +1815,7 @@ static HRESULT deleteStorageProperty(
     return hr;
   }
 
-  /* 
+  /*
    * Enumerate the elements
    */
   IStorage_EnumElements( childStorage, 0, 0, 0, &elements);
@@ -1727,7 +1829,7 @@ static HRESULT deleteStorageProperty(
     if (hr==S_OK)
     {
       destroyHr = StorageImpl_DestroyElement(
-                    (IStorage*)childStorage, 
+                    (IStorage*)childStorage,
                     (OLECHAR*)currentElement.pwcsName);
 
       CoTaskMemFree(currentElement.pwcsName);
@@ -1746,13 +1848,13 @@ static HRESULT deleteStorageProperty(
    */
   propertyToDelete.sizeOfNameString = 0;
 
-  StorageImpl_WriteProperty(parentStorage->ancestorStorage,
+  StorageImpl_WriteProperty(parentStorage->base.ancestorStorage,
                             indexOfPropertyToDelete,
                             &propertyToDelete);
 
   IStorage_Release(childStorage);
   IEnumSTATSTG_Release(elements);
-    
+
   return destroyHr;
 }
 
@@ -1772,8 +1874,8 @@ static HRESULT deleteStreamProperty(
   HRESULT        hr;
   ULARGE_INTEGER size;
 
-  size.s.HighPart = 0;
-  size.s.LowPart = 0;
+  size.u.HighPart = 0;
+  size.u.LowPart = 0;
 
   hr = StorageBaseImpl_OpenStream(
          (IStorage*)parentStorage,
@@ -1782,16 +1884,16 @@ static HRESULT deleteStreamProperty(
          STGM_WRITE | STGM_SHARE_EXCLUSIVE,
          0,
          &pis);
-    
+
   if (hr!=S_OK)
   {
     return(hr);
   }
 
-  /* 
-   * Zap the stream 
-   */ 
-  hr = IStream_SetSize(pis, size); 
+  /*
+   * Zap the stream
+   */
+  hr = IStream_SetSize(pis, size);
 
   if(hr != S_OK)
   {
@@ -1803,17 +1905,17 @@ static HRESULT deleteStreamProperty(
    */
   IStream_Release(pis);
 
-  /* 
+  /*
    * Invalidate the property by zeroing it's name member.
    */
   propertyToDelete.sizeOfNameString = 0;
 
-  /* 
+  /*
    * Here we should re-read the property so we get the updated pointer
    * but since we are here to zap it, I don't do it...
    */
   StorageImpl_WriteProperty(
-    parentStorage->ancestorStorage, 
+    parentStorage->base.ancestorStorage,
     indexOfPropertyToDelete,
     &propertyToDelete);
 
@@ -1841,8 +1943,8 @@ static HRESULT findPlaceholder(
    * Read the storage property
    */
   res = StorageImpl_ReadProperty(
-          storage->ancestorStorage,
-          storePropertyIndex, 
+          storage->base.ancestorStorage,
+          storePropertyIndex,
           &storeProperty);
 
   if(! res)
@@ -1856,7 +1958,7 @@ static HRESULT findPlaceholder(
     {
       return findPlaceholder(
                storage,
-               propertyIndexToStore, 
+               propertyIndexToStore,
                storeProperty.previousProperty,
                typeOfRelation);
     }
@@ -1871,7 +1973,7 @@ static HRESULT findPlaceholder(
     {
       return findPlaceholder(
                storage,
-               propertyIndexToStore, 
+               propertyIndexToStore,
                storeProperty.nextProperty,
                typeOfRelation);
     }
@@ -1879,14 +1981,14 @@ static HRESULT findPlaceholder(
     {
       storeProperty.nextProperty = propertyIndexToStore;
     }
-  } 
+  }
   else if (typeOfRelation == PROPERTY_RELATION_DIR)
   {
     if (storeProperty.dirProperty != PROPERTY_NULL)
     {
       return findPlaceholder(
                storage,
-               propertyIndexToStore, 
+               propertyIndexToStore,
                storeProperty.dirProperty,
                typeOfRelation);
     }
@@ -1897,8 +1999,8 @@ static HRESULT findPlaceholder(
   }
 
   hr = StorageImpl_WriteProperty(
-         storage->ancestorStorage,
-         storePropertyIndex, 
+         storage->base.ancestorStorage,
+         storePropertyIndex,
          &storeProperty);
 
   if(! hr)
@@ -1913,10 +2015,10 @@ static HRESULT findPlaceholder(
  *
  * Internal Method
  *
- * This method takes the previous and the next property link of a property 
+ * This method takes the previous and the next property link of a property
  * to be deleted and find them a place in the Storage.
  */
-static HRESULT adjustPropertyChain( 
+static HRESULT adjustPropertyChain(
   StorageImpl *This,
   StgProperty   propertyToDelete,
   StgProperty   parentProperty,
@@ -1930,116 +2032,116 @@ static HRESULT adjustPropertyChain(
   INT   relationType           = 0;
   HRESULT hr                     = S_OK;
   BOOL  res                    = TRUE;
-  
-  if (typeOfRelation == PROPERTY_RELATION_PREVIOUS) 
+
+  if (typeOfRelation == PROPERTY_RELATION_PREVIOUS)
   {
-    if (propertyToDelete.previousProperty != PROPERTY_NULL)  
+    if (propertyToDelete.previousProperty != PROPERTY_NULL)
     {
-      /* 
+      /*
        * Set the parent previous to the property to delete previous
        */
       newLinkProperty = propertyToDelete.previousProperty;
 
-      if (propertyToDelete.nextProperty != PROPERTY_NULL)  
+      if (propertyToDelete.nextProperty != PROPERTY_NULL)
       {
         /*
-         * We also need to find a storage for the other link, setup variables 
+         * We also need to find a storage for the other link, setup variables
          * to do this at the end...
-         */      
+         */
         needToFindAPlaceholder = TRUE;
         storeNode              = propertyToDelete.previousProperty;
         toStoreNode            = propertyToDelete.nextProperty;
         relationType           = PROPERTY_RELATION_NEXT;
       }
-    } 
-    else if (propertyToDelete.nextProperty != PROPERTY_NULL)  
+    }
+    else if (propertyToDelete.nextProperty != PROPERTY_NULL)
     {
-      /* 
+      /*
        * Set the parent previous to the property to delete next
        */
       newLinkProperty = propertyToDelete.nextProperty;
     }
-   
-    /* 
+
+    /*
      * Link it for real...
-     */ 
+     */
     parentProperty.previousProperty = newLinkProperty;
-  
-  } 
-  else if (typeOfRelation == PROPERTY_RELATION_NEXT) 
+
+  }
+  else if (typeOfRelation == PROPERTY_RELATION_NEXT)
   {
-    if (propertyToDelete.previousProperty != PROPERTY_NULL)  
+    if (propertyToDelete.previousProperty != PROPERTY_NULL)
     {
-      /* 
+      /*
        * Set the parent next to the property to delete next previous
        */
       newLinkProperty = propertyToDelete.previousProperty;
-      
-      if (propertyToDelete.nextProperty != PROPERTY_NULL)  
+
+      if (propertyToDelete.nextProperty != PROPERTY_NULL)
       {
         /*
-         * We also need to find a storage for the other link, setup variables 
+         * We also need to find a storage for the other link, setup variables
          * to do this at the end...
-         */      
+         */
         needToFindAPlaceholder = TRUE;
         storeNode              = propertyToDelete.previousProperty;
         toStoreNode            = propertyToDelete.nextProperty;
         relationType           = PROPERTY_RELATION_NEXT;
       }
-    } 
-    else if (propertyToDelete.nextProperty != PROPERTY_NULL)  
+    }
+    else if (propertyToDelete.nextProperty != PROPERTY_NULL)
     {
-      /* 
+      /*
        * Set the parent next to the property to delete next
        */
       newLinkProperty = propertyToDelete.nextProperty;
     }
 
-    /* 
+    /*
      * Link it for real...
-     */ 
+     */
     parentProperty.nextProperty = newLinkProperty;
-  } 
+  }
   else /* (typeOfRelation == PROPERTY_RELATION_DIR) */
   {
-    if (propertyToDelete.previousProperty != PROPERTY_NULL) 
+    if (propertyToDelete.previousProperty != PROPERTY_NULL)
     {
-      /* 
+      /*
        * Set the parent dir to the property to delete previous
        */
       newLinkProperty = propertyToDelete.previousProperty;
 
-      if (propertyToDelete.nextProperty != PROPERTY_NULL)  
+      if (propertyToDelete.nextProperty != PROPERTY_NULL)
       {
         /*
-         * We also need to find a storage for the other link, setup variables 
+         * We also need to find a storage for the other link, setup variables
          * to do this at the end...
-         */      
+         */
         needToFindAPlaceholder = TRUE;
         storeNode              = propertyToDelete.previousProperty;
         toStoreNode            = propertyToDelete.nextProperty;
         relationType           = PROPERTY_RELATION_NEXT;
       }
-    } 
-    else if (propertyToDelete.nextProperty != PROPERTY_NULL)  
+    }
+    else if (propertyToDelete.nextProperty != PROPERTY_NULL)
     {
-      /* 
+      /*
        * Set the parent dir to the property to delete next
        */
       newLinkProperty = propertyToDelete.nextProperty;
     }
 
-    /* 
+    /*
      * Link it for real...
-     */ 
+     */
     parentProperty.dirProperty = newLinkProperty;
   }
 
-  /* 
-   * Write back the parent property    
+  /*
+   * Write back the parent property
    */
   res = StorageImpl_WriteProperty(
-          This->ancestorStorage, 
+          This->base.ancestorStorage,
           parentPropertyId,
           &parentProperty);
   if(! res)
@@ -2048,14 +2150,14 @@ static HRESULT adjustPropertyChain(
   }
 
   /*
-   * If a placeholder is required for the other link, then, find one and 
+   * If a placeholder is required for the other link, then, find one and
    * get out of here...
    */
-  if (needToFindAPlaceholder) 
+  if (needToFindAPlaceholder)
   {
     hr = findPlaceholder(
-           This, 
-           toStoreNode, 
+           This,
+           toStoreNode,
            storeNode,
            relationType);
   }
@@ -2067,32 +2169,58 @@ static HRESULT adjustPropertyChain(
 /******************************************************************************
  * SetElementTimes (IStorage)
  */
-HRESULT WINAPI StorageImpl_SetElementTimes( 
+HRESULT WINAPI StorageImpl_SetElementTimes(
   IStorage*     iface,
-  const OLECHAR *pwcsName,/* [string][in] */ 
-  const FILETIME  *pctime,  /* [in] */ 
-  const FILETIME  *patime,  /* [in] */ 
-  const FILETIME  *pmtime)  /* [in] */ 
+  const OLECHAR *pwcsName,/* [string][in] */
+  const FILETIME  *pctime,  /* [in] */
+  const FILETIME  *patime,  /* [in] */
+  const FILETIME  *pmtime)  /* [in] */
 {
-  FIXME("not implemented!\n");
-  return E_NOTIMPL;
+  FIXME("(%s,...), stub!\n",debugstr_w(pwcsName));
+  return S_OK;
 }
 
 /******************************************************************************
  * SetStateBits (IStorage)
  */
-HRESULT WINAPI StorageImpl_SetStateBits( 
+HRESULT WINAPI StorageImpl_SetStateBits(
   IStorage*   iface,
-  DWORD         grfStateBits,/* [in] */ 
-  DWORD         grfMask)     /* [in] */ 
+  DWORD         grfStateBits,/* [in] */
+  DWORD         grfMask)     /* [in] */
 {
   FIXME("not implemented!\n");
   return E_NOTIMPL;
 }
 
+/*
+ * Virtual function table for the IStorage32Impl class.
+ */
+static const IStorageVtbl Storage32Impl_Vtbl =
+{
+    StorageBaseImpl_QueryInterface,
+    StorageBaseImpl_AddRef,
+    StorageBaseImpl_Release,
+    StorageBaseImpl_CreateStream,
+    StorageBaseImpl_OpenStream,
+    StorageImpl_CreateStorage,
+    StorageBaseImpl_OpenStorage,
+    StorageImpl_CopyTo,
+    StorageImpl_MoveElementTo,
+    StorageImpl_Commit,
+    StorageImpl_Revert,
+    StorageBaseImpl_EnumElements,
+    StorageImpl_DestroyElement,
+    StorageBaseImpl_RenameElement,
+    StorageImpl_SetElementTimes,
+    StorageBaseImpl_SetClass,
+    StorageImpl_SetStateBits,
+    StorageImpl_Stat
+};
+
 HRESULT StorageImpl_Construct(
   StorageImpl* This,
   HANDLE       hFile,
+  LPCOLESTR    pwcsName,
   ILockBytes*  pLkbyt,
   DWORD        openFlags,
   BOOL         fileBased,
@@ -2102,29 +2230,42 @@ HRESULT StorageImpl_Construct(
   StgProperty currentProperty;
   BOOL      readSuccessful;
   ULONG       currentPropertyIndex;
-  
+
   if ( FAILED( validateSTGM(openFlags) ))
     return STG_E_INVALIDFLAG;
 
   memset(This, 0, sizeof(StorageImpl));
-  
+
   /*
-   * Initialize the virtual fgunction table.
+   * Initialize the virtual function table.
    */
-  ICOM_VTBL(This)    = &Storage32Impl_Vtbl;
-  This->v_destructor = &StorageImpl_Destroy;
-  
+  This->base.lpVtbl = &Storage32Impl_Vtbl;
+  This->base.pssVtbl = &IPropertySetStorage_Vtbl;
+  This->base.v_destructor = &StorageImpl_Destroy;
+  This->base.openFlags = openFlags;
+
   /*
-   * This is the top-level storage so initialize the ancester pointer
+   * This is the top-level storage so initialize the ancestor pointer
    * to this.
    */
-  This->ancestorStorage = This;
-  
+  This->base.ancestorStorage = This;
+
   /*
    * Initialize the physical support of the storage.
    */
   This->hFile = hFile;
-  
+
+  /*
+   * Store copy of file path.
+   */
+  if(pwcsName) {
+      This->pwcsName = HeapAlloc(GetProcessHeap(), 0,
+                                (lstrlenW(pwcsName)+1)*sizeof(WCHAR));
+      if (!This->pwcsName)
+         return STG_E_INSUFFICIENTMEMORY;
+      strcpyW(This->pwcsName, pwcsName);
+  }
+
   /*
    * Initialize the big block cache.
    */
@@ -2138,7 +2279,7 @@ HRESULT StorageImpl_Construct(
 
   if (This->bigBlockFile == 0)
     return E_FAIL;
+
   if (fileCreate)
   {
     ULARGE_INTEGER size;
@@ -2150,8 +2291,8 @@ HRESULT StorageImpl_Construct(
      * - The properties start at block 1
      * - There is no small block depot
      */
-    memset( This->bigBlockDepotStart,     
-            BLOCK_UNUSED, 
+    memset( This->bigBlockDepotStart,
+            BLOCK_UNUSED,
             sizeof(This->bigBlockDepotStart));
 
     This->bigBlockDepotCount    = 1;
@@ -2168,8 +2309,8 @@ HRESULT StorageImpl_Construct(
     /*
      * Add one block for the big block depot and one block for the properties
      */
-    size.s.HighPart = 0;
-    size.s.LowPart  = This->bigBlockSize * 3;
+    size.u.HighPart = 0;
+    size.u.LowPart  = This->bigBlockSize * 3;
     BIGBLOCKFILE_SetSize(This->bigBlockFile, size);
 
     /*
@@ -2205,20 +2346,21 @@ HRESULT StorageImpl_Construct(
    * Start searching for free blocks with block 0.
    */
   This->prevFreeBlock = 0;
-  
+
   /*
    * Create the block chain abstractions.
    */
-  This->rootBlockChain = 
-    BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL);
+  if(!(This->rootBlockChain =
+       BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL)))
+    return STG_E_READFAULT;
 
-  This->smallBlockDepotChain = BlockChainStream_Construct(
-                                 This, 
-                                 &This->smallBlockDepotStart, 
-                                 PROPERTY_NULL);
+  if(!(This->smallBlockDepotChain =
+       BlockChainStream_Construct(This, &This->smallBlockDepotStart,
+                                 PROPERTY_NULL)))
+    return STG_E_READFAULT;
 
   /*
-   * Write the root property 
+   * Write the root property
    */
   if (fileCreate)
   {
@@ -2227,73 +2369,74 @@ HRESULT StorageImpl_Construct(
      * Initialize the property chain
      */
     memset(&rootProp, 0, sizeof(rootProp));
-    lstrcpyAtoW(rootProp.name, rootPropertyName);
-
-    rootProp.sizeOfNameString = (lstrlenW(rootProp.name)+1) * sizeof(WCHAR);
+    MultiByteToWideChar( CP_ACP, 0, rootPropertyName, -1, rootProp.name,
+                         sizeof(rootProp.name)/sizeof(WCHAR) );
+    rootProp.sizeOfNameString = (strlenW(rootProp.name)+1) * sizeof(WCHAR);
     rootProp.propertyType     = PROPTYPE_ROOT;
     rootProp.previousProperty = PROPERTY_NULL;
     rootProp.nextProperty     = PROPERTY_NULL;
     rootProp.dirProperty      = PROPERTY_NULL;
     rootProp.startingBlock    = BLOCK_END_OF_CHAIN;
-    rootProp.size.s.HighPart    = 0;
-    rootProp.size.s.LowPart     = 0;
+    rootProp.size.u.HighPart    = 0;
+    rootProp.size.u.LowPart     = 0;
 
     StorageImpl_WriteProperty(This, 0, &rootProp);
   }
 
   /*
-   * Find the ID of the root inhe property sets.
+   * Find the ID of the root in the property sets.
    */
   currentPropertyIndex = 0;
-  
+
   do
   {
     readSuccessful = StorageImpl_ReadProperty(
-                      This, 
-                      currentPropertyIndex, 
+                      This,
+                      currentPropertyIndex,
                       &currentProperty);
-    
+
     if (readSuccessful)
     {
       if ( (currentProperty.sizeOfNameString != 0 ) &&
            (currentProperty.propertyType     == PROPTYPE_ROOT) )
       {
-        This->rootPropertySetIndex = currentPropertyIndex;
+        This->base.rootPropertySetIndex = currentPropertyIndex;
       }
     }
 
     currentPropertyIndex++;
-    
-  } while (readSuccessful && (This->rootPropertySetIndex == PROPERTY_NULL) );
-  
+
+  } while (readSuccessful && (This->base.rootPropertySetIndex == PROPERTY_NULL) );
+
   if (!readSuccessful)
   {
     /* TODO CLEANUP */
-    return E_FAIL;
+    return STG_E_READFAULT;
   }
 
   /*
    * Create the block chain abstraction for the small block root chain.
    */
-  This->smallBlockRootChain = BlockChainStream_Construct(
-                                This, 
-                                NULL, 
-                                This->rootPropertySetIndex);
-  
+  if(!(This->smallBlockRootChain =
+       BlockChainStream_Construct(This, NULL, This->base.rootPropertySetIndex)))
+    return STG_E_READFAULT;
+
   return hr;
 }
 
-void StorageImpl_Destroy(
-  StorageImpl* This)
+void StorageImpl_Destroy(StorageBaseImpl* iface)
 {
+  StorageImpl *This = (StorageImpl*) iface;
   TRACE("(%p)\n", This);
 
+  HeapFree(GetProcessHeap(), 0, This->pwcsName);
+
   BlockChainStream_Destroy(This->smallBlockRootChain);
   BlockChainStream_Destroy(This->rootBlockChain);
   BlockChainStream_Destroy(This->smallBlockDepotChain);
 
   BIGBLOCKFILE_Destructor(This->bigBlockFile);
-  return;
+  HeapFree(GetProcessHeap(), 0, This);
 }
 
 /******************************************************************************
@@ -2565,7 +2708,7 @@ ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This)
   }
   else
   {
-    int i;
+    unsigned int i;
     /*
      * Follow the chain to the last one.
      */
@@ -2616,6 +2759,7 @@ void  StorageImpl_FreeBigBlock(
  * Params:  This       - Pointer to the Storage object.
  *          blockIndex - Index of the block to retrieve the chain
  *                       for.
+ *          nextBlockIndex - receives the return value.
  *
  * Returns: This method returns the index of the next block in the chain.
  *          It will return the constants:
@@ -2630,18 +2774,26 @@ void  StorageImpl_FreeBigBlock(
  *
  * See Windows documentation for more details on IStorage methods.
  */
-ULONG StorageImpl_GetNextBlockInChain(
+HRESULT StorageImpl_GetNextBlockInChain(
   StorageImpl* This,
-  ULONG          blockIndex)
+  ULONG        blockIndex,
+  ULONG*       nextBlockIndex)
 {
   ULONG offsetInDepot    = blockIndex * sizeof (ULONG);
   ULONG depotBlockCount  = offsetInDepot / This->bigBlockSize;
   ULONG depotBlockOffset = offsetInDepot % This->bigBlockSize;
-  ULONG nextBlockIndex   = BLOCK_SPECIAL;
   void* depotBuffer;
   ULONG depotBlockIndexPos;
+  int index;
 
-  assert(depotBlockCount < This->bigBlockDepotCount);
+  *nextBlockIndex   = BLOCK_SPECIAL;
+
+  if(depotBlockCount >= This->bigBlockDepotCount)
+  {
+    WARN("depotBlockCount %ld, bigBlockDepotCount %ld\n", depotBlockCount,
+        This->bigBlockDepotCount);
+    return STG_E_READFAULT;
+  }
 
   /*
    * Cache the currently accessed depot block.
@@ -2664,23 +2816,20 @@ ULONG StorageImpl_GetNextBlockInChain(
 
     depotBuffer = StorageImpl_GetROBigBlock(This, depotBlockIndexPos);
 
-    if (depotBuffer!=0)
-    {
-      int index;
-
-      for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++)
-      {
-        StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), &nextBlockIndex);
-        This->blockDepotCached[index] = nextBlockIndex;
-      }
+    if (!depotBuffer)
+      return STG_E_READFAULT;
 
-      StorageImpl_ReleaseBigBlock(This, depotBuffer);
+    for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++)
+    {
+      StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), nextBlockIndex);
+      This->blockDepotCached[index] = *nextBlockIndex;
     }
+    StorageImpl_ReleaseBigBlock(This, depotBuffer);
   }
 
-  nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)];
+  *nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)];
 
-  return nextBlockIndex;
+  return S_OK;
 }
 
 /******************************************************************************
@@ -2812,48 +2961,48 @@ HRESULT StorageImpl_LoadFileHeader(
     }
 
     StorageUtl_ReadWord(
-      headerBigBlock, 
-      OFFSET_BIGBLOCKSIZEBITS,   
+      headerBigBlock,
+      OFFSET_BIGBLOCKSIZEBITS,
       &This->bigBlockSizeBits);
 
     StorageUtl_ReadWord(
-      headerBigBlock, 
-      OFFSET_SMALLBLOCKSIZEBITS, 
+      headerBigBlock,
+      OFFSET_SMALLBLOCKSIZEBITS,
       &This->smallBlockSizeBits);
 
     StorageUtl_ReadDWord(
-      headerBigBlock, 
-      OFFSET_BBDEPOTCOUNT,      
+      headerBigBlock,
+      OFFSET_BBDEPOTCOUNT,
       &This->bigBlockDepotCount);
 
     StorageUtl_ReadDWord(
-      headerBigBlock, 
-      OFFSET_ROOTSTARTBLOCK,    
+      headerBigBlock,
+      OFFSET_ROOTSTARTBLOCK,
       &This->rootStartBlock);
 
     StorageUtl_ReadDWord(
-      headerBigBlock, 
-      OFFSET_SBDEPOTSTART,      
+      headerBigBlock,
+      OFFSET_SBDEPOTSTART,
       &This->smallBlockDepotStart);
 
-    StorageUtl_ReadDWord( 
-      headerBigBlock, 
-      OFFSET_EXTBBDEPOTSTART,   
+    StorageUtl_ReadDWord(
+      headerBigBlock,
+      OFFSET_EXTBBDEPOTSTART,
       &This->extBigBlockDepotStart);
 
     StorageUtl_ReadDWord(
-      headerBigBlock, 
-      OFFSET_EXTBBDEPOTCOUNT,   
+      headerBigBlock,
+      OFFSET_EXTBBDEPOTCOUNT,
       &This->extBigBlockDepotCount);
-    
+
     for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++)
     {
       StorageUtl_ReadDWord(
-        headerBigBlock, 
+        headerBigBlock,
         OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index),
         &(This->bigBlockDepotStart[index]));
     }
-    
+
     /*
      * Make the bitwise arithmetic to get the size of the blocks in bytes.
      */
@@ -2867,22 +3016,26 @@ HRESULT StorageImpl_LoadFileHeader(
       This->bigBlockSize   = 0x000000001 >> (DWORD)This->bigBlockSizeBits;
       This->smallBlockSize = 0x000000001 >> (DWORD)This->smallBlockSizeBits;
     }
-    
+
     /*
-     * Right now, the code is making some assumptions about the size of the 
+     * Right now, the code is making some assumptions about the size of the
      * blocks, just make sure they are what we're expecting.
      */
-    assert( (This->bigBlockSize==DEF_BIG_BLOCK_SIZE) && 
-            (This->smallBlockSize==DEF_SMALL_BLOCK_SIZE));
-    
+    if (This->bigBlockSize != DEF_BIG_BLOCK_SIZE ||
+       This->smallBlockSize != DEF_SMALL_BLOCK_SIZE)
+    {
+       WARN("Broken OLE storage file\n");
+       hr = STG_E_INVALIDHEADER;
+    }
+    else
+       hr = S_OK;
+
     /*
      * Release the block.
      */
     StorageImpl_ReleaseBigBlock(This, headerBigBlock);
-
-    hr = S_OK;
   }
-  
+
   return hr;
 }
 
@@ -2902,7 +3055,7 @@ void StorageImpl_SaveFileHeader(
    * Get a pointer to the big block of data containing the header.
    */
   success = StorageImpl_ReadBigBlock(This, -1, headerBigBlock);
-  
+
   /*
    * If the block read failed, the file is probably new.
    */
@@ -2912,12 +3065,12 @@ void StorageImpl_SaveFileHeader(
      * Initialize for all unknown fields.
      */
     memset(headerBigBlock, 0, BIG_BLOCK_SIZE);
-    
+
     /*
      * Initialize the magic number.
      */
     memcpy(headerBigBlock, STORAGE_magic, sizeof(STORAGE_magic));
-    
+
     /*
      * And a bunch of things we don't know what they mean
      */
@@ -2925,58 +3078,60 @@ void StorageImpl_SaveFileHeader(
     StorageUtl_WriteWord(headerBigBlock,  0x1a, 0x3);
     StorageUtl_WriteWord(headerBigBlock,  0x1c, (WORD)-2);
     StorageUtl_WriteDWord(headerBigBlock, 0x38, (DWORD)0x1000);
-    StorageUtl_WriteDWord(headerBigBlock, 0x40, (DWORD)0x0001);
   }
-  
+
   /*
    * Write the information to the header.
    */
-  if (headerBigBlock!=0)
-  {
-    StorageUtl_WriteWord(
-      headerBigBlock, 
-      OFFSET_BIGBLOCKSIZEBITS,   
-      This->bigBlockSizeBits);
+  StorageUtl_WriteWord(
+    headerBigBlock,
+    OFFSET_BIGBLOCKSIZEBITS,
+    This->bigBlockSizeBits);
 
-    StorageUtl_WriteWord(
-      headerBigBlock, 
-      OFFSET_SMALLBLOCKSIZEBITS, 
-      This->smallBlockSizeBits);
+  StorageUtl_WriteWord(
+    headerBigBlock,
+    OFFSET_SMALLBLOCKSIZEBITS,
+    This->smallBlockSizeBits);
 
-    StorageUtl_WriteDWord(
-      headerBigBlock, 
-      OFFSET_BBDEPOTCOUNT,      
-      This->bigBlockDepotCount);
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_BBDEPOTCOUNT,
+    This->bigBlockDepotCount);
 
-    StorageUtl_WriteDWord(
-      headerBigBlock, 
-      OFFSET_ROOTSTARTBLOCK,    
-      This->rootStartBlock);
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_ROOTSTARTBLOCK,
+    This->rootStartBlock);
 
-    StorageUtl_WriteDWord(
-      headerBigBlock, 
-      OFFSET_SBDEPOTSTART,      
-      This->smallBlockDepotStart);
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_SBDEPOTSTART,
+    This->smallBlockDepotStart);
 
-    StorageUtl_WriteDWord(
-      headerBigBlock, 
-      OFFSET_EXTBBDEPOTSTART,   
-      This->extBigBlockDepotStart);
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_SBDEPOTCOUNT,
+    This->smallBlockDepotChain ?
+     BlockChainStream_GetCount(This->smallBlockDepotChain) : 0);
 
-    StorageUtl_WriteDWord(
-      headerBigBlock, 
-      OFFSET_EXTBBDEPOTCOUNT,   
-      This->extBigBlockDepotCount);
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_EXTBBDEPOTSTART,
+    This->extBigBlockDepotStart);
 
-    for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++)
-    {
-      StorageUtl_WriteDWord(
-        headerBigBlock, 
-        OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index),
-        (This->bigBlockDepotStart[index]));
-    }
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_EXTBBDEPOTCOUNT,
+    This->extBigBlockDepotCount);
+
+  for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++)
+  {
+    StorageUtl_WriteDWord(
+      headerBigBlock,
+      OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index),
+      (This->bigBlockDepotStart[index]));
   }
-  
+
   /*
    * Write the big block back to the file.
    */
@@ -2998,82 +3153,87 @@ BOOL StorageImpl_ReadProperty(
   BOOL         readSuccessful;
   ULONG          bytesRead;
 
-  offsetInPropSet.s.HighPart = 0;
-  offsetInPropSet.s.LowPart  = index * PROPSET_BLOCK_SIZE;
-  
+  offsetInPropSet.u.HighPart = 0;
+  offsetInPropSet.u.LowPart  = index * PROPSET_BLOCK_SIZE;
+
   readSuccessful = BlockChainStream_ReadAt(
                     This->rootBlockChain,
                     offsetInPropSet,
                     PROPSET_BLOCK_SIZE,
                     currentProperty,
                     &bytesRead);
-  
+
   if (readSuccessful)
   {
+    /* replace the name of root entry (often "Root Entry") by the file name */
+    WCHAR *propName = (index == This->base.rootPropertySetIndex) ?
+                       This->filename : (WCHAR *)currentProperty+OFFSET_PS_NAME;
+
     memset(buffer->name, 0, sizeof(buffer->name));
     memcpy(
-      buffer->name, 
-      currentProperty+OFFSET_PS_NAME, 
+      buffer->name,
+      propName,
       PROPERTY_NAME_BUFFER_LEN );
+    TRACE("storage name: %s\n", debugstr_w(buffer->name));
 
     memcpy(&buffer->propertyType, currentProperty + OFFSET_PS_PROPERTYTYPE, 1);
-    
+
     StorageUtl_ReadWord(
-      currentProperty,  
-      OFFSET_PS_NAMELENGTH,  
+      currentProperty,
+      OFFSET_PS_NAMELENGTH,
       &buffer->sizeOfNameString);
 
     StorageUtl_ReadDWord(
-      currentProperty, 
-      OFFSET_PS_PREVIOUSPROP, 
+      currentProperty,
+      OFFSET_PS_PREVIOUSPROP,
       &buffer->previousProperty);
 
     StorageUtl_ReadDWord(
-      currentProperty, 
-      OFFSET_PS_NEXTPROP,     
+      currentProperty,
+      OFFSET_PS_NEXTPROP,
       &buffer->nextProperty);
 
     StorageUtl_ReadDWord(
-      currentProperty, 
-      OFFSET_PS_DIRPROP,      
+      currentProperty,
+      OFFSET_PS_DIRPROP,
       &buffer->dirProperty);
 
     StorageUtl_ReadGUID(
-      currentProperty,  
-      OFFSET_PS_GUID,        
+      currentProperty,
+      OFFSET_PS_GUID,
       &buffer->propertyUniqueID);
 
     StorageUtl_ReadDWord(
-      currentProperty, 
-      OFFSET_PS_TSS1,         
+      currentProperty,
+      OFFSET_PS_TSS1,
       &buffer->timeStampS1);
 
     StorageUtl_ReadDWord(
-      currentProperty, 
-      OFFSET_PS_TSD1,         
+      currentProperty,
+      OFFSET_PS_TSD1,
       &buffer->timeStampD1);
 
     StorageUtl_ReadDWord(
-      currentProperty, 
-      OFFSET_PS_TSS2,         
+      currentProperty,
+      OFFSET_PS_TSS2,
       &buffer->timeStampS2);
 
     StorageUtl_ReadDWord(
-      currentProperty, 
-      OFFSET_PS_TSD2,         
+      currentProperty,
+      OFFSET_PS_TSD2,
       &buffer->timeStampD2);
 
     StorageUtl_ReadDWord(
-      currentProperty, 
-      OFFSET_PS_STARTBLOCK,   
+      currentProperty,
+      OFFSET_PS_STARTBLOCK,
       &buffer->startingBlock);
 
     StorageUtl_ReadDWord(
-      currentProperty, 
-      OFFSET_PS_SIZE,         
-      &buffer->size.s.LowPart);
+      currentProperty,
+      OFFSET_PS_SIZE,
+      &buffer->size.u.LowPart);
 
-    buffer->size.s.HighPart = 0;
+    buffer->size.u.HighPart = 0;
   }
 
   return readSuccessful;
@@ -3092,72 +3252,72 @@ BOOL StorageImpl_WriteProperty(
   BOOL         writeSuccessful;
   ULONG          bytesWritten;
 
-  offsetInPropSet.s.HighPart = 0;
-  offsetInPropSet.s.LowPart  = index * PROPSET_BLOCK_SIZE;
+  offsetInPropSet.u.HighPart = 0;
+  offsetInPropSet.u.LowPart  = index * PROPSET_BLOCK_SIZE;
 
   memset(currentProperty, 0, PROPSET_BLOCK_SIZE);
 
   memcpy(
-    currentProperty + OFFSET_PS_NAME, 
-    buffer->name, 
+    currentProperty + OFFSET_PS_NAME,
+    buffer->name,
     PROPERTY_NAME_BUFFER_LEN );
 
   memcpy(currentProperty + OFFSET_PS_PROPERTYTYPE, &buffer->propertyType, 1);
 
   StorageUtl_WriteWord(
-    currentProperty,  
-      OFFSET_PS_NAMELENGTH,   
+    currentProperty,
+      OFFSET_PS_NAMELENGTH,
       buffer->sizeOfNameString);
 
   StorageUtl_WriteDWord(
-    currentProperty, 
-      OFFSET_PS_PREVIOUSPROP, 
+    currentProperty,
+      OFFSET_PS_PREVIOUSPROP,
       buffer->previousProperty);
 
   StorageUtl_WriteDWord(
-    currentProperty, 
-      OFFSET_PS_NEXTPROP,     
+    currentProperty,
+      OFFSET_PS_NEXTPROP,
       buffer->nextProperty);
 
   StorageUtl_WriteDWord(
-    currentProperty, 
-      OFFSET_PS_DIRPROP,      
+    currentProperty,
+      OFFSET_PS_DIRPROP,
       buffer->dirProperty);
 
   StorageUtl_WriteGUID(
-    currentProperty,  
-      OFFSET_PS_GUID,        
+    currentProperty,
+      OFFSET_PS_GUID,
       &buffer->propertyUniqueID);
 
   StorageUtl_WriteDWord(
-    currentProperty, 
-      OFFSET_PS_TSS1,         
+    currentProperty,
+      OFFSET_PS_TSS1,
       buffer->timeStampS1);
 
   StorageUtl_WriteDWord(
-    currentProperty, 
-      OFFSET_PS_TSD1,         
+    currentProperty,
+      OFFSET_PS_TSD1,
       buffer->timeStampD1);
 
   StorageUtl_WriteDWord(
-    currentProperty, 
-      OFFSET_PS_TSS2,         
+    currentProperty,
+      OFFSET_PS_TSS2,
       buffer->timeStampS2);
 
   StorageUtl_WriteDWord(
-    currentProperty, 
-      OFFSET_PS_TSD2,         
+    currentProperty,
+      OFFSET_PS_TSD2,
       buffer->timeStampD2);
 
   StorageUtl_WriteDWord(
-    currentProperty, 
-      OFFSET_PS_STARTBLOCK,   
+    currentProperty,
+      OFFSET_PS_STARTBLOCK,
       buffer->startingBlock);
 
   StorageUtl_WriteDWord(
-    currentProperty, 
-      OFFSET_PS_SIZE,         
-      buffer->size.s.LowPart);
+    currentProperty,
+      OFFSET_PS_SIZE,
+      buffer->size.u.LowPart);
 
   writeSuccessful = BlockChainStream_WriteAt(This->rootBlockChain,
                                             offsetInPropSet,
@@ -3202,10 +3362,10 @@ BOOL StorageImpl_WriteBigBlock(
     memcpy(bigBlockBuffer, buffer, This->bigBlockSize);
 
     StorageImpl_ReleaseBigBlock(This, bigBlockBuffer);
-    
+
     return TRUE;
   }
-  
+
   return FALSE;
 }
 
@@ -3258,7 +3418,7 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
   bbTempChain = BlockChainStream_Construct(This,
                                            &bbHeadOfChain,
                                            PROPERTY_NULL);
-
+  if(!bbTempChain) return NULL;
   /*
    * Grow the big block chain.
    */
@@ -3269,12 +3429,12 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
    * Copy the contents of the small block chain to the big block chain
    * by small block size increments.
    */
-  offset.s.LowPart = 0;
-  offset.s.HighPart = 0;
+  offset.u.LowPart = 0;
+  offset.u.HighPart = 0;
   cbTotalRead = 0;
   cbTotalWritten = 0;
 
-  buffer = (BYTE *) HeapAlloc(GetProcessHeap(),0,DEF_SMALL_BLOCK_SIZE);
+  buffer = HeapAlloc(GetProcessHeap(),0,DEF_SMALL_BLOCK_SIZE);
   do
   {
     successRead = SmallBlockChainStream_ReadAt(*ppsbChain,
@@ -3291,7 +3451,7 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
                                             &cbWritten);
     cbTotalWritten += cbWritten;
 
-    offset.s.LowPart += This->smallBlockSize;
+    offset.u.LowPart += This->smallBlockSize;
 
   } while (successRead && successWrite);
   HeapFree(GetProcessHeap(),0,buffer);
@@ -3302,8 +3462,8 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
    * Destroy the small block chain.
    */
   propertyIndex = (*ppsbChain)->ownerPropertyIndex;
-  size.s.HighPart = 0;
-  size.s.LowPart  = 0;
+  size.u.HighPart = 0;
+  size.u.LowPart  = 0;
   SmallBlockChainStream_SetSize(*ppsbChain, size);
   SmallBlockChainStream_Destroy(*ppsbChain);
   *ppsbChain = 0;
@@ -3330,52 +3490,11 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
   return bigBlockChain;
 }
 
-/******************************************************************************
-** Storage32InternalImpl implementation
-*/
-
-StorageInternalImpl* StorageInternalImpl_Construct(
-  StorageImpl* ancestorStorage,  
-  ULONG          rootPropertyIndex)
+void StorageInternalImpl_Destroy( StorageBaseImpl *iface)
 {
-  StorageInternalImpl* newStorage;
-
-  /*
-   * Allocate space for the new storage object
-   */
-  newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageInternalImpl));
-
-  if (newStorage!=0)
-  {
-    memset(newStorage, 0, sizeof(StorageInternalImpl));
-
-    /*
-     * Initialize the virtual function table.
-     */
-    ICOM_VTBL(newStorage)    = &Storage32InternalImpl_Vtbl;
-    newStorage->v_destructor = &StorageInternalImpl_Destroy;
-
-    /*
-     * Keep the ancestor storage pointer and nail a reference to it.
-     */
-    newStorage->ancestorStorage = ancestorStorage;
-    StorageBaseImpl_AddRef((IStorage*)(newStorage->ancestorStorage));
-
-    /*
-     * Keep the index of the root property set for this storage,
-     */
-    newStorage->rootPropertySetIndex = rootPropertyIndex;
-
-    return newStorage;
-  }
+  StorageInternalImpl* This = (StorageInternalImpl*) iface;
 
-  return 0;
-}
-
-void StorageInternalImpl_Destroy(
-  StorageInternalImpl* This)
-{
-  StorageBaseImpl_Release((IStorage*)This->ancestorStorage);
+  StorageBaseImpl_Release((IStorage*)This->base.ancestorStorage);
   HeapFree(GetProcessHeap(), 0, This);
 }
 
@@ -3386,13 +3505,13 @@ void StorageInternalImpl_Destroy(
 ** The non-root storages cannot be opened in transacted mode thus this function
 ** does nothing.
 */
-HRESULT WINAPI StorageInternalImpl_Commit( 
+HRESULT WINAPI StorageInternalImpl_Commit(
   IStorage*            iface,
-  DWORD                  grfCommitFlags)  /* [in] */ 
+  DWORD                  grfCommitFlags)  /* [in] */
 {
   return S_OK;
 }
-        
+
 /******************************************************************************
 **
 ** Storage32InternalImpl_Revert
@@ -3400,58 +3519,12 @@ HRESULT WINAPI StorageInternalImpl_Commit(
 ** The non-root storages cannot be opened in transacted mode thus this function
 ** does nothing.
 */
-HRESULT WINAPI StorageInternalImpl_Revert( 
+HRESULT WINAPI StorageInternalImpl_Revert(
   IStorage*            iface)
 {
   return S_OK;
 }
 
-/******************************************************************************
-** IEnumSTATSTGImpl implementation
-*/
-
-IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(
-  StorageImpl* parentStorage,
-  ULONG          firstPropertyNode)
-{
-  IEnumSTATSTGImpl* newEnumeration;
-
-  newEnumeration = HeapAlloc(GetProcessHeap(), 0, sizeof(IEnumSTATSTGImpl));
-  
-  if (newEnumeration!=0)
-  {
-    /*
-     * Set-up the virtual function table and reference count.
-     */
-    ICOM_VTBL(newEnumeration) = &IEnumSTATSTGImpl_Vtbl;
-    newEnumeration->ref       = 0;
-    
-    /*
-     * We want to nail-down the reference to the storage in case the
-     * enumeration out-lives the storage in the client application.
-     */
-    newEnumeration->parentStorage = parentStorage;
-    IStorage_AddRef((IStorage*)newEnumeration->parentStorage);
-    
-    newEnumeration->firstPropertyNode   = firstPropertyNode;
-    
-    /*
-     * Initialize the search stack
-     */
-    newEnumeration->stackSize    = 0;
-    newEnumeration->stackMaxSize = ENUMSTATSGT_SIZE_INCREMENT;
-    newEnumeration->stackToVisit = 
-      HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG)*ENUMSTATSGT_SIZE_INCREMENT);
-    
-    /*
-     * Make sure the current node of the iterator is the first one.
-     */
-    IEnumSTATSTGImpl_Reset((IEnumSTATSTG*)newEnumeration);
-  }
-  
-  return newEnumeration;
-}
-
 void IEnumSTATSTGImpl_Destroy(IEnumSTATSTGImpl* This)
 {
   IStorage_Release((IStorage*)This->parentStorage);
@@ -3480,39 +3553,24 @@ HRESULT WINAPI IEnumSTATSTGImpl_QueryInterface(
   /*
    * Compare the riid with the interface IDs implemented by this object.
    */
-  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 
-  {
-    *ppvObject = (IEnumSTATSTG*)This;
-  }
-  else if (memcmp(&IID_IStorage, riid, sizeof(IID_IEnumSTATSTG)) == 0) 
+  if (IsEqualGUID(&IID_IUnknown, riid) ||
+      IsEqualGUID(&IID_IStorage, riid))
   {
     *ppvObject = (IEnumSTATSTG*)This;
+    IEnumSTATSTG_AddRef((IEnumSTATSTG*)This);
+    return S_OK;
   }
 
-  /*
-   * Check that we obtained an interface.
-   */
-  if ((*ppvObject)==0)
-    return E_NOINTERFACE;
-
-  /*
-   * Query Interface always increases the reference count by one when it is
-   * successful
-   */
-  IEnumSTATSTGImpl_AddRef((IEnumSTATSTG*)This);
-
-  return S_OK;
+  return E_NOINTERFACE;
 }
-        
+
 ULONG   WINAPI IEnumSTATSTGImpl_AddRef(
   IEnumSTATSTG* iface)
 {
   IEnumSTATSTGImpl* const This=(IEnumSTATSTGImpl*)iface;
-
-  This->ref++;
-  return This->ref;
+  return InterlockedIncrement(&This->ref);
 }
-        
+
 ULONG   WINAPI IEnumSTATSTGImpl_Release(
   IEnumSTATSTG* iface)
 {
@@ -3520,8 +3578,7 @@ ULONG   WINAPI IEnumSTATSTGImpl_Release(
 
   ULONG newRef;
 
-  This->ref--;
-  newRef = This->ref;
+  newRef = InterlockedDecrement(&This->ref);
 
   /*
    * If the reference count goes down to 0, perform suicide.
@@ -3531,7 +3588,7 @@ ULONG   WINAPI IEnumSTATSTGImpl_Release(
     IEnumSTATSTGImpl_Destroy(This);
   }
 
-  return newRef;;
+  return newRef;
 }
 
 HRESULT WINAPI IEnumSTATSTGImpl_Next(
@@ -3551,15 +3608,15 @@ HRESULT WINAPI IEnumSTATSTGImpl_Next(
    * Perform a sanity check on the parameters.
    */
   if ( (rgelt==0) || ( (celt!=1) && (pceltFetched==0) ) )
-    return E_INVALIDARG;  
-  
+    return E_INVALIDARG;
+
   /*
    * To avoid the special case, get another pointer to a ULONG value if
    * the caller didn't supply one.
    */
   if (pceltFetched==0)
     pceltFetched = &objectFetched;
-  
+
   /*
    * Start the iteration, we will iterate until we hit the end of the
    * linked list or until we hit the number of items to iterate through
@@ -3571,10 +3628,10 @@ HRESULT WINAPI IEnumSTATSTGImpl_Next(
    */
   currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE);
 
-  while ( ( *pceltFetched < celt) && 
+  while ( ( *pceltFetched < celt) &&
           ( currentSearchNode!=PROPERTY_NULL) )
   {
-    /* 
+    /*
      * Remove the top node from the stack
      */
     IEnumSTATSTGImpl_PopSearchNode(This, TRUE);
@@ -3583,7 +3640,7 @@ HRESULT WINAPI IEnumSTATSTGImpl_Next(
      * Read the property from the storage.
      */
     StorageImpl_ReadProperty(This->parentStorage,
-      currentSearchNode, 
+      currentSearchNode,
       &currentProperty);
 
     /*
@@ -3592,7 +3649,7 @@ HRESULT WINAPI IEnumSTATSTGImpl_Next(
     StorageUtl_CopyPropertyToSTATSTG(currentReturnStruct,
       &currentProperty,
       STATFLAG_DEFAULT);
-        
+
     /*
      * Step to the next item in the iteration
      */
@@ -3616,7 +3673,7 @@ HRESULT WINAPI IEnumSTATSTGImpl_Next(
   return S_FALSE;
 }
 
-        
+
 HRESULT WINAPI IEnumSTATSTGImpl_Skip(
   IEnumSTATSTG* iface,
   ULONG             celt)
@@ -3632,10 +3689,10 @@ HRESULT WINAPI IEnumSTATSTGImpl_Skip(
    */
   currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE);
 
-  while ( (objectFetched < celt) && 
+  while ( (objectFetched < celt) &&
           (currentSearchNode!=PROPERTY_NULL) )
   {
-    /* 
+    /*
      * Remove the top node from the stack
      */
     IEnumSTATSTGImpl_PopSearchNode(This, TRUE);
@@ -3644,9 +3701,9 @@ HRESULT WINAPI IEnumSTATSTGImpl_Skip(
      * Read the property from the storage.
      */
     StorageImpl_ReadProperty(This->parentStorage,
-      currentSearchNode, 
+      currentSearchNode,
       &currentProperty);
-    
+
     /*
      * Step to the next item in the iteration
      */
@@ -3668,7 +3725,7 @@ HRESULT WINAPI IEnumSTATSTGImpl_Skip(
 
   return S_FALSE;
 }
-        
+
 HRESULT WINAPI IEnumSTATSTGImpl_Reset(
   IEnumSTATSTG* iface)
 {
@@ -3687,7 +3744,7 @@ HRESULT WINAPI IEnumSTATSTGImpl_Reset(
    */
   readSuccessful = StorageImpl_ReadProperty(
                     This->parentStorage,
-                    This->firstPropertyNode, 
+                    This->firstPropertyNode,
                     &rootProperty);
 
   if (readSuccessful)
@@ -3702,7 +3759,7 @@ HRESULT WINAPI IEnumSTATSTGImpl_Reset(
 
   return S_OK;
 }
-        
+
 HRESULT WINAPI IEnumSTATSTGImpl_Clone(
   IEnumSTATSTG* iface,
   IEnumSTATSTG**    ppenum)
@@ -3716,23 +3773,23 @@ HRESULT WINAPI IEnumSTATSTGImpl_Clone(
    */
   if (ppenum==0)
     return E_INVALIDARG;
-  
+
   newClone = IEnumSTATSTGImpl_Construct(This->parentStorage,
                This->firstPropertyNode);
 
-  
+
   /*
    * The new clone enumeration must point to the same current node as
    * the ole one.
    */
   newClone->stackSize    = This->stackSize    ;
   newClone->stackMaxSize = This->stackMaxSize ;
-  newClone->stackToVisit = 
+  newClone->stackToVisit =
     HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG) * newClone->stackMaxSize);
 
   memcpy(
-    newClone->stackToVisit, 
-    This->stackToVisit, 
+    newClone->stackToVisit,
+    This->stackToVisit,
     sizeof(ULONG) * newClone->stackSize);
 
   *ppenum = (IEnumSTATSTG*)newClone;
@@ -3748,7 +3805,7 @@ HRESULT WINAPI IEnumSTATSTGImpl_Clone(
 
 INT IEnumSTATSTGImpl_FindParentProperty(
   IEnumSTATSTGImpl *This,
-  ULONG             childProperty, 
+  ULONG             childProperty,
   StgProperty      *currentProperty,
   ULONG            *thisNodeId)
 {
@@ -3766,7 +3823,7 @@ INT IEnumSTATSTGImpl_FindParentProperty(
    * Start with the node at the top of the stack.
    */
   currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE);
-  
+
 
   while (currentSearchNode!=PROPERTY_NULL)
   {
@@ -3775,7 +3832,7 @@ INT IEnumSTATSTGImpl_FindParentProperty(
      */
     *thisNodeId = currentSearchNode;
 
-    /* 
+    /*
      * Remove the top node from the stack
      */
     IEnumSTATSTGImpl_PopSearchNode(This, TRUE);
@@ -3785,18 +3842,18 @@ INT IEnumSTATSTGImpl_FindParentProperty(
      */
     StorageImpl_ReadProperty(
       This->parentStorage,
-      currentSearchNode, 
+      currentSearchNode,
       currentProperty);
-      
+
     if (currentProperty->previousProperty == childProperty)
       return PROPERTY_RELATION_PREVIOUS;
 
-    else if (currentProperty->nextProperty == childProperty)  
+    else if (currentProperty->nextProperty == childProperty)
       return PROPERTY_RELATION_NEXT;
-  
+
     else if (currentProperty->dirProperty == childProperty)
       return PROPERTY_RELATION_DIR;
-       
+
     /*
      * Push the next search node in the search stack.
      */
@@ -3825,7 +3882,7 @@ ULONG IEnumSTATSTGImpl_FindProperty(
 
   while (currentSearchNode!=PROPERTY_NULL)
   {
-    /* 
+    /*
      * Remove the top node from the stack
      */
     IEnumSTATSTGImpl_PopSearchNode(This, TRUE);
@@ -3834,12 +3891,12 @@ ULONG IEnumSTATSTGImpl_FindProperty(
      * Read the property from the storage.
      */
     StorageImpl_ReadProperty(This->parentStorage,
-      currentSearchNode, 
+      currentSearchNode,
       currentProperty);
 
     if ( propertyNameCmp(
-          (OLECHAR*)currentProperty->name, 
-          (OLECHAR*)lpszPropName) == 0)
+          (const OLECHAR*)currentProperty->name,
+          (const OLECHAR*)lpszPropName) == 0)
       return currentSearchNode;
 
     /*
@@ -3877,7 +3934,7 @@ void IEnumSTATSTGImpl_PushSearchNode(
     This->stackMaxSize += ENUMSTATSGT_SIZE_INCREMENT;
 
     This->stackToVisit = HeapReAlloc(
-                           GetProcessHeap(), 
+                           GetProcessHeap(),
                            0,
                            This->stackToVisit,
                            sizeof(ULONG) * This->stackMaxSize);
@@ -3891,7 +3948,7 @@ void IEnumSTATSTGImpl_PushSearchNode(
    */
   readSuccessful = StorageImpl_ReadProperty(
                     This->parentStorage,
-                    nodeToPush, 
+                    nodeToPush,
                     &rootProperty);
 
   if (readSuccessful)
@@ -3922,46 +3979,211 @@ ULONG IEnumSTATSTGImpl_PopSearchNode(
   return topNode;
 }
 
+/*
+ * Virtual function table for the IEnumSTATSTGImpl class.
+ */
+static const IEnumSTATSTGVtbl IEnumSTATSTGImpl_Vtbl =
+{
+    IEnumSTATSTGImpl_QueryInterface,
+    IEnumSTATSTGImpl_AddRef,
+    IEnumSTATSTGImpl_Release,
+    IEnumSTATSTGImpl_Next,
+    IEnumSTATSTGImpl_Skip,
+    IEnumSTATSTGImpl_Reset,
+    IEnumSTATSTGImpl_Clone
+};
+
+/******************************************************************************
+** IEnumSTATSTGImpl implementation
+*/
+
+IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(
+  StorageImpl* parentStorage,
+  ULONG          firstPropertyNode)
+{
+  IEnumSTATSTGImpl* newEnumeration;
+
+  newEnumeration = HeapAlloc(GetProcessHeap(), 0, sizeof(IEnumSTATSTGImpl));
+
+  if (newEnumeration!=0)
+  {
+    /*
+     * Set-up the virtual function table and reference count.
+     */
+    newEnumeration->lpVtbl    = &IEnumSTATSTGImpl_Vtbl;
+    newEnumeration->ref       = 0;
+
+    /*
+     * We want to nail-down the reference to the storage in case the
+     * enumeration out-lives the storage in the client application.
+     */
+    newEnumeration->parentStorage = parentStorage;
+    IStorage_AddRef((IStorage*)newEnumeration->parentStorage);
+
+    newEnumeration->firstPropertyNode   = firstPropertyNode;
+
+    /*
+     * Initialize the search stack
+     */
+    newEnumeration->stackSize    = 0;
+    newEnumeration->stackMaxSize = ENUMSTATSGT_SIZE_INCREMENT;
+    newEnumeration->stackToVisit =
+      HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG)*ENUMSTATSGT_SIZE_INCREMENT);
+
+    /*
+     * Make sure the current node of the iterator is the first one.
+     */
+    IEnumSTATSTGImpl_Reset((IEnumSTATSTG*)newEnumeration);
+  }
+
+  return newEnumeration;
+}
+
+/*
+ * Virtual function table for the Storage32InternalImpl class.
+ */
+static const IStorageVtbl Storage32InternalImpl_Vtbl =
+{
+    StorageBaseImpl_QueryInterface,
+    StorageBaseImpl_AddRef,
+    StorageBaseImpl_Release,
+    StorageBaseImpl_CreateStream,
+    StorageBaseImpl_OpenStream,
+    StorageImpl_CreateStorage,
+    StorageBaseImpl_OpenStorage,
+    StorageImpl_CopyTo,
+    StorageImpl_MoveElementTo,
+    StorageInternalImpl_Commit,
+    StorageInternalImpl_Revert,
+    StorageBaseImpl_EnumElements,
+    StorageImpl_DestroyElement,
+    StorageBaseImpl_RenameElement,
+    StorageImpl_SetElementTimes,
+    StorageBaseImpl_SetClass,
+    StorageImpl_SetStateBits,
+    StorageBaseImpl_Stat
+};
+
+/******************************************************************************
+** Storage32InternalImpl implementation
+*/
+
+StorageInternalImpl* StorageInternalImpl_Construct(
+  StorageImpl* ancestorStorage,
+  DWORD        openFlags,
+  ULONG        rootPropertyIndex)
+{
+  StorageInternalImpl* newStorage;
+
+  /*
+   * Allocate space for the new storage object
+   */
+  newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageInternalImpl));
+
+  if (newStorage!=0)
+  {
+    memset(newStorage, 0, sizeof(StorageInternalImpl));
+
+    /*
+     * Initialize the virtual function table.
+     */
+    newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl;
+    newStorage->base.v_destructor = &StorageInternalImpl_Destroy;
+    newStorage->base.openFlags = openFlags;
+
+    /*
+     * Keep the ancestor storage pointer and nail a reference to it.
+     */
+    newStorage->base.ancestorStorage = ancestorStorage;
+    StorageBaseImpl_AddRef((IStorage*)(newStorage->base.ancestorStorage));
+
+    /*
+     * Keep the index of the root property set for this storage,
+     */
+    newStorage->base.rootPropertySetIndex = rootPropertyIndex;
+
+    return newStorage;
+  }
+
+  return 0;
+}
+
 /******************************************************************************
 ** StorageUtl implementation
 */
 
-void StorageUtl_ReadWord(void* buffer, ULONG offset, WORD* value)
+void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value)
+{
+  WORD tmp;
+
+  memcpy(&tmp, buffer+offset, sizeof(WORD));
+  *value = le16toh(tmp);
+}
+
+void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value)
+{
+  value = htole16(value);
+  memcpy(buffer+offset, &value, sizeof(WORD));
+}
+
+void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value)
 {
-  memcpy(value, (BYTE*)buffer+offset, sizeof(WORD));
+  DWORD tmp;
+
+  memcpy(&tmp, buffer+offset, sizeof(DWORD));
+  *value = le32toh(tmp);
 }
 
-void StorageUtl_WriteWord(void* buffer, ULONG offset, WORD value)
+void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value)
 {
-  memcpy((BYTE*)buffer+offset, &value, sizeof(WORD));
+  value = htole32(value);
+  memcpy(buffer+offset, &value, sizeof(DWORD));
 }
 
-void StorageUtl_ReadDWord(void* buffer, ULONG offset, DWORD* value)
+void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset,
+ ULARGE_INTEGER* value)
 {
-  memcpy(value, (BYTE*)buffer+offset, sizeof(DWORD));
+#ifdef WORDS_BIGENDIAN
+    ULARGE_INTEGER tmp;
+
+    memcpy(&tmp, buffer + offset, sizeof(ULARGE_INTEGER));
+    value->u.LowPart = htole32(tmp.u.HighPart);
+    value->u.HighPart = htole32(tmp.u.LowPart);
+#else
+    memcpy(value, buffer + offset, sizeof(ULARGE_INTEGER));
+#endif
 }
 
-void StorageUtl_WriteDWord(void* buffer, ULONG offset, DWORD value)
+void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
+ const ULARGE_INTEGER *value)
 {
-  memcpy((BYTE*)buffer+offset, &value, sizeof(DWORD));
+#ifdef WORDS_BIGENDIAN
+    ULARGE_INTEGER tmp;
+
+    tmp.u.LowPart = htole32(value->u.HighPart);
+    tmp.u.HighPart = htole32(value->u.LowPart);
+    memcpy(buffer + offset, &tmp, sizeof(ULARGE_INTEGER));
+#else
+    memcpy(buffer + offset, value, sizeof(ULARGE_INTEGER));
+#endif
 }
 
-void StorageUtl_ReadGUID(void* buffer, ULONG offset, GUID* value)
+void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value)
 {
   StorageUtl_ReadDWord(buffer, offset,   &(value->Data1));
   StorageUtl_ReadWord(buffer,  offset+4, &(value->Data2));
   StorageUtl_ReadWord(buffer,  offset+6, &(value->Data3));
 
-  memcpy(value->Data4, (BYTE*)buffer+offset+8, sizeof(value->Data4));
+  memcpy(value->Data4, buffer+offset+8, sizeof(value->Data4));
 }
 
-void StorageUtl_WriteGUID(void* buffer, ULONG offset, GUID* value)
+void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value)
 {
   StorageUtl_WriteDWord(buffer, offset,   value->Data1);
   StorageUtl_WriteWord(buffer,  offset+4, value->Data2);
   StorageUtl_WriteWord(buffer,  offset+6, value->Data3);
 
-  memcpy((BYTE*)buffer+offset+8, value->Data4, sizeof(value->Data4));
+  memcpy(buffer+offset+8, value->Data4, sizeof(value->Data4));
 }
 
 void StorageUtl_CopyPropertyToSTATSTG(
@@ -3972,18 +4194,20 @@ void StorageUtl_CopyPropertyToSTATSTG(
   /*
    * The copy of the string occurs only when the flag is not set
    */
-  if ((statFlags & STATFLAG_NONAME) != 0)
+  if( ((statFlags & STATFLAG_NONAME) != 0) || 
+       (source->name == NULL) || 
+       (source->name[0] == 0) )
   {
     destination->pwcsName = 0;
   }
   else
   {
-    destination->pwcsName = 
+    destination->pwcsName =
       CoTaskMemAlloc((lstrlenW(source->name)+1)*sizeof(WCHAR));
 
-    lstrcpyW((LPWSTR)destination->pwcsName, source->name);
+    strcpyW((LPWSTR)destination->pwcsName, source->name);
   }
-  
+
   switch (source->propertyType)
   {
     case PROPTYPE_STORAGE:
@@ -3995,20 +4219,20 @@ void StorageUtl_CopyPropertyToSTATSTG(
       break;
     default:
       destination->type = STGTY_STREAM;
-      break;        
+      break;
   }
 
   destination->cbSize            = source->size;
-/*    
+/*
   currentReturnStruct->mtime     = {0}; TODO
   currentReturnStruct->ctime     = {0};
-  currentReturnStruct->atime     = {0}; 
+  currentReturnStruct->atime     = {0};
 */
   destination->grfMode           = 0;
-  destination->grfLocksSupported = 0; 
+  destination->grfLocksSupported = 0;
   destination->clsid             = source->propertyUniqueID;
-  destination->grfStateBits      = 0; 
-  destination->reserved          = 0; 
+  destination->grfStateBits      = 0;
+  destination->reserved          = 0;
 }
 
 /******************************************************************************
@@ -4016,7 +4240,7 @@ void StorageUtl_CopyPropertyToSTATSTG(
 */
 
 BlockChainStream* BlockChainStream_Construct(
-  StorageImpl* parentStorage,  
+  StorageImpl* parentStorage,
   ULONG*         headOfStreamPlaceHolder,
   ULONG          propertyIndex)
 {
@@ -4039,9 +4263,14 @@ BlockChainStream* BlockChainStream_Construct(
     newStream->numBlocks++;
     newStream->tailIndex = blockIndex;
 
-    blockIndex = StorageImpl_GetNextBlockInChain(
-                   parentStorage,
-                   blockIndex);
+    if(FAILED(StorageImpl_GetNextBlockInChain(
+             parentStorage,
+             blockIndex,
+             &blockIndex)))
+    {
+      HeapFree(GetProcessHeap(), 0, newStream);
+      return NULL;
+    }
   }
 
   return newStream;
@@ -4089,7 +4318,7 @@ ULONG BlockChainStream_GetHeadOfChain(BlockChainStream* This)
  *
  * Returns the number of blocks that comprises this chain.
  * This is not the size of the stream as the last block may not be full!
- * 
+ *
  */
 ULONG BlockChainStream_GetCount(BlockChainStream* This)
 {
@@ -4102,16 +4331,18 @@ ULONG BlockChainStream_GetCount(BlockChainStream* This)
   {
     count++;
 
-    blockIndex = StorageImpl_GetNextBlockInChain(
-                   This->parentStorage, 
-                   blockIndex);
+    if(FAILED(StorageImpl_GetNextBlockInChain(
+                   This->parentStorage,
+                   blockIndex,
+                  &blockIndex)))
+      return 0;
   }
 
   return count;
 }
 
 /******************************************************************************
- *      BlockChainStream_ReadAt 
+ *      BlockChainStream_ReadAt
  *
  * Reads a specified number of bytes from this chain at the specified offset.
  * bytesRead may be NULL.
@@ -4123,8 +4354,8 @@ BOOL BlockChainStream_ReadAt(BlockChainStream* This,
   void*          buffer,
   ULONG*         bytesRead)
 {
-  ULONG blockNoInSequence = offset.s.LowPart / This->parentStorage->bigBlockSize;
-  ULONG offsetInBlock     = offset.s.LowPart % This->parentStorage->bigBlockSize;
+  ULONG blockNoInSequence = offset.u.LowPart / This->parentStorage->bigBlockSize;
+  ULONG offsetInBlock     = offset.u.LowPart % This->parentStorage->bigBlockSize;
   ULONG bytesToReadInBuffer;
   ULONG blockIndex;
   BYTE* bufferWalker;
@@ -4151,9 +4382,8 @@ BOOL BlockChainStream_ReadAt(BlockChainStream* This,
 
   while ( (blockNoInSequence > 0) &&  (blockIndex != BLOCK_END_OF_CHAIN))
   {
-    blockIndex = 
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
-    
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex)))
+      return FALSE;
     blockNoInSequence--;
   }
 
@@ -4164,30 +4394,30 @@ BOOL BlockChainStream_ReadAt(BlockChainStream* This,
    */
   *bytesRead   = 0;
   bufferWalker = buffer;
-  
+
   while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) )
   {
     /*
      * Calculate how many bytes we can copy from this big block.
      */
-    bytesToReadInBuffer = 
-      MIN(This->parentStorage->bigBlockSize - offsetInBlock, size);
-    
+    bytesToReadInBuffer =
+      min(This->parentStorage->bigBlockSize - offsetInBlock, size);
+
     /*
      * Copy those bytes to the buffer
      */
-    bigBlockBuffer = 
+    bigBlockBuffer =
       StorageImpl_GetROBigBlock(This->parentStorage, blockIndex);
-    
+
     memcpy(bufferWalker, bigBlockBuffer + offsetInBlock, bytesToReadInBuffer);
-    
+
     StorageImpl_ReleaseBigBlock(This->parentStorage, bigBlockBuffer);
-    
+
     /*
      * Step to the next big block.
      */
-    blockIndex    = 
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex)))
+      return FALSE;
 
     bufferWalker += bytesToReadInBuffer;
     size         -= bytesToReadInBuffer;
@@ -4195,7 +4425,7 @@ BOOL BlockChainStream_ReadAt(BlockChainStream* This,
     offsetInBlock = 0;  /* There is no offset on the next block */
 
   }
-  
+
   return (size == 0);
 }
 
@@ -4212,11 +4442,11 @@ BOOL BlockChainStream_WriteAt(BlockChainStream* This,
   const void*       buffer,
   ULONG*            bytesWritten)
 {
-  ULONG blockNoInSequence = offset.s.LowPart / This->parentStorage->bigBlockSize;
-  ULONG offsetInBlock     = offset.s.LowPart % This->parentStorage->bigBlockSize;
+  ULONG blockNoInSequence = offset.u.LowPart / This->parentStorage->bigBlockSize;
+  ULONG offsetInBlock     = offset.u.LowPart % This->parentStorage->bigBlockSize;
   ULONG bytesToWrite;
   ULONG blockIndex;
-  BYTE* bufferWalker;
+  const BYTE* bufferWalker;
   BYTE* bigBlockBuffer;
 
   /*
@@ -4240,9 +4470,9 @@ BOOL BlockChainStream_WriteAt(BlockChainStream* This,
 
   while ( (blockNoInSequence > 0) &&  (blockIndex != BLOCK_END_OF_CHAIN))
   {
-    blockIndex = 
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
-    
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
+                                             &blockIndex)))
+      return FALSE;
     blockNoInSequence--;
   }
 
@@ -4253,37 +4483,37 @@ BOOL BlockChainStream_WriteAt(BlockChainStream* This,
    * This is OK since we don't intend to modify that buffer.
    */
   *bytesWritten   = 0;
-  bufferWalker = (BYTE*)buffer;
+  bufferWalker = (const BYTE*)buffer;
 
   while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) )
   {
     /*
      * Calculate how many bytes we can copy from this big block.
      */
-    bytesToWrite = 
-      MIN(This->parentStorage->bigBlockSize - offsetInBlock, size);
-    
+    bytesToWrite =
+      min(This->parentStorage->bigBlockSize - offsetInBlock, size);
+
     /*
      * Copy those bytes to the buffer
      */
     bigBlockBuffer = StorageImpl_GetBigBlock(This->parentStorage, blockIndex);
-    
+
     memcpy(bigBlockBuffer + offsetInBlock, bufferWalker, bytesToWrite);
-    
+
     StorageImpl_ReleaseBigBlock(This->parentStorage, bigBlockBuffer);
-    
+
     /*
      * Step to the next big block.
      */
-    blockIndex    = 
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
-
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
+                                             &blockIndex)))
+      return FALSE;
     bufferWalker  += bytesToWrite;
     size          -= bytesToWrite;
     *bytesWritten += bytesToWrite;
     offsetInBlock  = 0;      /* There is no offset on the next block */
   }
-  
+
   return (size == 0);
 }
 
@@ -4308,9 +4538,9 @@ BOOL BlockChainStream_Shrink(BlockChainStream* This,
   /*
    * Figure out how many blocks are needed to contain the new size
    */
-  numBlocks = newSize.s.LowPart / This->parentStorage->bigBlockSize;
+  numBlocks = newSize.u.LowPart / This->parentStorage->bigBlockSize;
 
-  if ((newSize.s.LowPart % This->parentStorage->bigBlockSize) != 0)
+  if ((newSize.u.LowPart % This->parentStorage->bigBlockSize) != 0)
     numBlocks++;
 
   blockIndex = BlockChainStream_GetHeadOfChain(This);
@@ -4320,20 +4550,21 @@ BOOL BlockChainStream_Shrink(BlockChainStream* This,
    */
   while (count < numBlocks)
   {
-    blockIndex = 
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
-
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
+                                             &blockIndex)))
+      return FALSE;
     count++;
   }
 
   /* Get the next block before marking the new end */
-  extraBlock = 
-    StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
+  if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
+                                           &extraBlock)))
+    return FALSE;
 
   /* Mark the new end of chain */
   StorageImpl_SetNextBlockInChain(
-    This->parentStorage, 
-    blockIndex, 
+    This->parentStorage,
+    blockIndex,
     BLOCK_END_OF_CHAIN);
 
   This->tailIndex = blockIndex;
@@ -4344,9 +4575,9 @@ BOOL BlockChainStream_Shrink(BlockChainStream* This,
    */
   while (extraBlock != BLOCK_END_OF_CHAIN)
   {
-    blockIndex = 
-      StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock);
-
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock,
+                                             &blockIndex)))
+      return FALSE;
     StorageImpl_FreeBigBlock(This->parentStorage, extraBlock);
     extraBlock = blockIndex;
   }
@@ -4388,14 +4619,14 @@ BOOL BlockChainStream_Enlarge(BlockChainStream* This,
       assert(This->ownerPropertyIndex != PROPERTY_NULL);
 
       StorageImpl_ReadProperty(
-        This->parentStorage, 
+        This->parentStorage,
         This->ownerPropertyIndex,
         &chainProp);
 
-      chainProp.startingBlock = blockIndex; 
+      chainProp.startingBlock = blockIndex;
 
       StorageImpl_WriteProperty(
-        This->parentStorage, 
+        This->parentStorage,
         This->ownerPropertyIndex,
         &chainProp);
     }
@@ -4407,9 +4638,9 @@ BOOL BlockChainStream_Enlarge(BlockChainStream* This,
   /*
    * Figure out how many blocks are needed to contain this stream
    */
-  newNumBlocks = newSize.s.LowPart / This->parentStorage->bigBlockSize;
+  newNumBlocks = newSize.u.LowPart / This->parentStorage->bigBlockSize;
 
-  if ((newSize.s.LowPart % This->parentStorage->bigBlockSize) != 0)
+  if ((newSize.u.LowPart % This->parentStorage->bigBlockSize) != 0)
     newNumBlocks++;
 
   /*
@@ -4424,8 +4655,9 @@ BOOL BlockChainStream_Enlarge(BlockChainStream* This,
       This->numBlocks++;
       currentBlock = blockIndex;
 
-      blockIndex =
-        StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock);
+      if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock,
+                                               &blockIndex)))
+       return FALSE;
     }
 
     This->tailIndex = currentBlock;
@@ -4444,13 +4676,13 @@ BOOL BlockChainStream_Enlarge(BlockChainStream* This,
       blockIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage);
 
       StorageImpl_SetNextBlockInChain(
-       This->parentStorage, 
-       currentBlock, 
+       This->parentStorage,
+       currentBlock,
        blockIndex);
 
       StorageImpl_SetNextBlockInChain(
-        This->parentStorage, 
-       blockIndex, 
+        This->parentStorage,
+       blockIndex,
        BLOCK_END_OF_CHAIN);
 
       currentBlock = blockIndex;
@@ -4472,7 +4704,7 @@ BOOL BlockChainStream_Enlarge(BlockChainStream* This,
  *
  * TODO: Free the actual blocks in the file when we shrink the chain.
  *       Currently, the blocks are still in the file. So the file size
- *       doesn't shrink even if we shrink streams. 
+ *       doesn't shrink even if we shrink streams.
  */
 BOOL BlockChainStream_SetSize(
   BlockChainStream* This,
@@ -4480,28 +4712,28 @@ BOOL BlockChainStream_SetSize(
 {
   ULARGE_INTEGER size = BlockChainStream_GetSize(This);
 
-  if (newSize.s.LowPart == size.s.LowPart)
+  if (newSize.u.LowPart == size.u.LowPart)
     return TRUE;
 
-  if (newSize.s.LowPart < size.s.LowPart)
+  if (newSize.u.LowPart < size.u.LowPart)
   {
     BlockChainStream_Shrink(This, newSize);
   }
   else
   {
-    ULARGE_INTEGER fileSize = 
+    ULARGE_INTEGER fileSize =
       BIGBLOCKFILE_GetSize(This->parentStorage->bigBlockFile);
 
-    ULONG diff = newSize.s.LowPart - size.s.LowPart;
+    ULONG diff = newSize.u.LowPart - size.u.LowPart;
 
     /*
      * Make sure the file stays a multiple of blocksize
      */
     if ((diff % This->parentStorage->bigBlockSize) != 0)
-      diff += (This->parentStorage->bigBlockSize - 
+      diff += (This->parentStorage->bigBlockSize -
                 (diff % This->parentStorage->bigBlockSize) );
 
-    fileSize.s.LowPart += diff;
+    fileSize.u.LowPart += diff;
     BIGBLOCKFILE_SetSize(This->parentStorage->bigBlockFile, fileSize);
 
     BlockChainStream_Enlarge(This, newSize);
@@ -4522,8 +4754,8 @@ ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This)
 
   if(This->headOfStreamPlaceHolder == NULL)
   {
-    /* 
-     * This chain is a data stream read the property and return 
+    /*
+     * This chain is a data stream read the property and return
      * the appropriate size
      */
     StorageImpl_ReadProperty(
@@ -4536,15 +4768,15 @@ ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This)
   else
   {
     /*
-     * this chain is a chain that does not have a property, figure out the 
-     * size by making the product number of used blocks times the 
+     * this chain is a chain that does not have a property, figure out the
+     * size by making the product number of used blocks times the
      * size of them
      */
     ULARGE_INTEGER result;
-    result.s.HighPart = 0;
+    result.u.HighPart = 0;
 
-    result.s.LowPart  = 
-      BlockChainStream_GetCount(This) * 
+    result.u.LowPart  =
+      BlockChainStream_GetCount(This) *
       This->parentStorage->bigBlockSize;
 
     return result;
@@ -4556,7 +4788,7 @@ ULARGE_INTEGER BlockChainStream_GetSize(BlockChainStream* This)
 */
 
 SmallBlockChainStream* SmallBlockChainStream_Construct(
-  StorageImpl* parentStorage,  
+  StorageImpl* parentStorage,
   ULONG          propertyIndex)
 {
   SmallBlockChainStream* newStream;
@@ -4607,23 +4839,25 @@ ULONG SmallBlockChainStream_GetHeadOfChain(
  *      SmallBlockChainStream_GetNextBlockInChain
  *
  * Returns the index of the next small block in this chain.
- * 
+ *
  * Return Values:
  *    - BLOCK_END_OF_CHAIN: end of this chain
  *    - BLOCK_UNUSED: small block 'blockIndex' is free
  */
-ULONG SmallBlockChainStream_GetNextBlockInChain(
+HRESULT SmallBlockChainStream_GetNextBlockInChain(
   SmallBlockChainStream* This,
-  ULONG                  blockIndex)
+  ULONG                  blockIndex,
+  ULONG*                 nextBlockInChain)
 {
   ULARGE_INTEGER offsetOfBlockInDepot;
   DWORD  buffer;
-  ULONG  nextBlockInChain = BLOCK_END_OF_CHAIN;
   ULONG  bytesRead;
   BOOL success;
 
-  offsetOfBlockInDepot.s.HighPart = 0;
-  offsetOfBlockInDepot.s.LowPart  = blockIndex * sizeof(ULONG);
+  *nextBlockInChain = BLOCK_END_OF_CHAIN;
+
+  offsetOfBlockInDepot.u.HighPart = 0;
+  offsetOfBlockInDepot.u.LowPart  = blockIndex * sizeof(ULONG);
 
   /*
    * Read those bytes in the buffer from the small block file.
@@ -4637,10 +4871,11 @@ ULONG SmallBlockChainStream_GetNextBlockInChain(
 
   if (success)
   {
-    StorageUtl_ReadDWord(&buffer, 0, &nextBlockInChain);
+    StorageUtl_ReadDWord((BYTE *)&buffer, 0, nextBlockInChain);
+    return S_OK;
   }
 
-  return nextBlockInChain;
+  return STG_E_READFAULT;
 }
 
 /******************************************************************************
@@ -4660,10 +4895,10 @@ void SmallBlockChainStream_SetNextBlockInChain(
   DWORD  buffer;
   ULONG  bytesWritten;
 
-  offsetOfBlockInDepot.s.HighPart = 0;
-  offsetOfBlockInDepot.s.LowPart  = blockIndex * sizeof(ULONG);
+  offsetOfBlockInDepot.u.HighPart = 0;
+  offsetOfBlockInDepot.u.LowPart  = blockIndex * sizeof(ULONG);
 
-  StorageUtl_WriteDWord(&buffer, 0, nextBlock);
+  StorageUtl_WriteDWord((BYTE *)&buffer, 0, nextBlock);
 
   /*
    * Read those bytes in the buffer from the small block file.
@@ -4706,14 +4941,14 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
   BOOL success = TRUE;
   ULONG smallBlocksPerBigBlock;
 
-  offsetOfBlockInDepot.s.HighPart = 0;
+  offsetOfBlockInDepot.u.HighPart = 0;
 
   /*
    * Scan the small block depot for a free block
    */
   while (nextBlockIndex != BLOCK_UNUSED)
   {
-    offsetOfBlockInDepot.s.LowPart = blockIndex * sizeof(ULONG);
+    offsetOfBlockInDepot.u.LowPart = blockIndex * sizeof(ULONG);
 
     success = BlockChainStream_ReadAt(
                 This->parentStorage->smallBlockDepotChain,
@@ -4727,14 +4962,14 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
      */
     if (success)
     {
-      StorageUtl_ReadDWord(&buffer, 0, &nextBlockIndex);
+      StorageUtl_ReadDWord((BYTE *)&buffer, 0, &nextBlockIndex);
 
       if (nextBlockIndex != BLOCK_UNUSED)
         blockIndex++;
     }
     else
     {
-      ULONG count = 
+      ULONG count =
         BlockChainStream_GetCount(This->parentStorage->smallBlockDepotChain);
 
       ULONG sbdIndex = This->parentStorage->smallBlockDepotStart;
@@ -4745,26 +4980,25 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
       while (nextBlock != BLOCK_END_OF_CHAIN)
       {
         sbdIndex = nextBlock;
-        nextBlock = 
-          StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex);
+       StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex, &nextBlock);
       }
 
       newsbdIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage);
       if (sbdIndex != BLOCK_END_OF_CHAIN)
         StorageImpl_SetNextBlockInChain(
-          This->parentStorage, 
-          sbdIndex, 
+          This->parentStorage,
+          sbdIndex,
           newsbdIndex);
 
       StorageImpl_SetNextBlockInChain(
-        This->parentStorage, 
-        newsbdIndex, 
+        This->parentStorage,
+        newsbdIndex,
         BLOCK_END_OF_CHAIN);
 
       /*
        * Initialize all the small blocks to free
        */
-      smallBlockDepot = 
+      smallBlockDepot =
         StorageImpl_GetBigBlock(This->parentStorage, newsbdIndex);
 
       memset(smallBlockDepot, BLOCK_UNUSED, This->parentStorage->bigBlockSize);
@@ -4776,7 +5010,7 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
          * We have just created the small block depot.
          */
         StgProperty rootProp;
-        ULONG sbStartIndex; 
+        ULONG sbStartIndex;
 
         /*
          * Save it in the header
@@ -4785,34 +5019,34 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
         StorageImpl_SaveFileHeader(This->parentStorage);
 
         /*
-         * And allocate the first big block that will contain small blocks 
+         * And allocate the first big block that will contain small blocks
          */
-        sbStartIndex = 
+        sbStartIndex =
           StorageImpl_GetNextFreeBigBlock(This->parentStorage);
 
         StorageImpl_SetNextBlockInChain(
-          This->parentStorage, 
-          sbStartIndex, 
+          This->parentStorage,
+          sbStartIndex,
           BLOCK_END_OF_CHAIN);
 
         StorageImpl_ReadProperty(
-          This->parentStorage, 
-          This->parentStorage->rootPropertySetIndex, 
+          This->parentStorage,
+          This->parentStorage->base.rootPropertySetIndex,
           &rootProp);
 
         rootProp.startingBlock = sbStartIndex;
-        rootProp.size.s.HighPart = 0;
-        rootProp.size.s.LowPart  = This->parentStorage->bigBlockSize;
+        rootProp.size.u.HighPart = 0;
+        rootProp.size.u.LowPart  = This->parentStorage->bigBlockSize;
 
         StorageImpl_WriteProperty(
-          This->parentStorage, 
-          This->parentStorage->rootPropertySetIndex, 
+          This->parentStorage,
+          This->parentStorage->base.rootPropertySetIndex,
           &rootProp);
       }
     }
   }
 
-  smallBlocksPerBigBlock = 
+  smallBlocksPerBigBlock =
     This->parentStorage->bigBlockSize / This->parentStorage->smallBlockSize;
 
   /*
@@ -4824,22 +5058,22 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
     ULONG blocksRequired = (blockIndex / smallBlocksPerBigBlock) + 1;
 
     StorageImpl_ReadProperty(
-      This->parentStorage, 
-      This->parentStorage->rootPropertySetIndex, 
+      This->parentStorage,
+      This->parentStorage->base.rootPropertySetIndex,
       &rootProp);
 
-    if (rootProp.size.s.LowPart < 
+    if (rootProp.size.u.LowPart <
        (blocksRequired * This->parentStorage->bigBlockSize))
     {
-      rootProp.size.s.LowPart += This->parentStorage->bigBlockSize;
+      rootProp.size.u.LowPart += This->parentStorage->bigBlockSize;
 
       BlockChainStream_SetSize(
-        This->parentStorage->smallBlockRootChain, 
+        This->parentStorage->smallBlockRootChain,
         rootProp.size);
 
       StorageImpl_WriteProperty(
-        This->parentStorage, 
-        This->parentStorage->rootPropertySetIndex, 
+        This->parentStorage,
+        This->parentStorage->base.rootPropertySetIndex,
         &rootProp);
     }
   }
@@ -4852,7 +5086,7 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
  *
  * Reads a specified number of bytes from this chain at the specified offset.
  * bytesRead may be NULL.
- * Failure will be returned if the specified number of bytes has not been read. 
+ * Failure will be returned if the specified number of bytes has not been read.
  */
 BOOL SmallBlockChainStream_ReadAt(
   SmallBlockChainStream* This,
@@ -4862,10 +5096,10 @@ BOOL SmallBlockChainStream_ReadAt(
   ULONG*                 bytesRead)
 {
   ULARGE_INTEGER offsetInBigBlockFile;
-  ULONG blockNoInSequence = 
-    offset.s.LowPart / This->parentStorage->smallBlockSize;
+  ULONG blockNoInSequence =
+    offset.u.LowPart / This->parentStorage->smallBlockSize;
 
-  ULONG offsetInBlock = offset.s.LowPart % This->parentStorage->smallBlockSize;
+  ULONG offsetInBlock = offset.u.LowPart % This->parentStorage->smallBlockSize;
   ULONG bytesToReadInBuffer;
   ULONG blockIndex;
   ULONG bytesReadFromBigBlockFile;
@@ -4874,7 +5108,7 @@ BOOL SmallBlockChainStream_ReadAt(
   /*
    * This should never happen on a small block file.
    */
-  assert(offset.s.HighPart==0);
+  assert(offset.u.HighPart==0);
 
   /*
    * Find the first block in the stream that contains part of the buffer.
@@ -4883,8 +5117,9 @@ BOOL SmallBlockChainStream_ReadAt(
 
   while ( (blockNoInSequence > 0) &&  (blockIndex != BLOCK_END_OF_CHAIN))
   {
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
-
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
+                                                       &blockIndex)))
+      return FALSE;
     blockNoInSequence--;
   }
 
@@ -4899,17 +5134,17 @@ BOOL SmallBlockChainStream_ReadAt(
     /*
      * Calculate how many bytes we can copy from this small block.
      */
-    bytesToReadInBuffer = 
-      MIN(This->parentStorage->smallBlockSize - offsetInBlock, size);
+    bytesToReadInBuffer =
+      min(This->parentStorage->smallBlockSize - offsetInBlock, size);
 
     /*
      * Calculate the offset of the small block in the small block file.
      */
-    offsetInBigBlockFile.s.HighPart  = 0;
-    offsetInBigBlockFile.s.LowPart   = 
+    offsetInBigBlockFile.u.HighPart  = 0;
+    offsetInBigBlockFile.u.LowPart   =
       blockIndex * This->parentStorage->smallBlockSize;
 
-    offsetInBigBlockFile.s.LowPart  += offsetInBlock;
+    offsetInBigBlockFile.u.LowPart  += offsetInBlock;
 
     /*
      * Read those bytes in the buffer from the small block file.
@@ -4925,7 +5160,8 @@ BOOL SmallBlockChainStream_ReadAt(
     /*
      * Step to the next big block.
      */
-    blockIndex    = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
+      return FALSE;
     bufferWalker += bytesToReadInBuffer;
     size         -= bytesToReadInBuffer;
     *bytesRead   += bytesToReadInBuffer;
@@ -4950,32 +5186,32 @@ BOOL SmallBlockChainStream_WriteAt(
   ULONG*         bytesWritten)
 {
   ULARGE_INTEGER offsetInBigBlockFile;
-  ULONG blockNoInSequence = 
-    offset.s.LowPart / This->parentStorage->smallBlockSize;
+  ULONG blockNoInSequence =
+    offset.u.LowPart / This->parentStorage->smallBlockSize;
 
-  ULONG offsetInBlock = offset.s.LowPart % This->parentStorage->smallBlockSize;
+  ULONG offsetInBlock = offset.u.LowPart % This->parentStorage->smallBlockSize;
   ULONG bytesToWriteInBuffer;
   ULONG blockIndex;
   ULONG bytesWrittenFromBigBlockFile;
-  BYTE* bufferWalker;
-  
+  const BYTE* bufferWalker;
+
   /*
    * This should never happen on a small block file.
    */
-  assert(offset.s.HighPart==0);
-  
+  assert(offset.u.HighPart==0);
+
   /*
    * Find the first block in the stream that contains part of the buffer.
    */
   blockIndex = SmallBlockChainStream_GetHeadOfChain(This);
-  
+
   while ( (blockNoInSequence > 0) &&  (blockIndex != BLOCK_END_OF_CHAIN))
   {
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
-    
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
+      return FALSE;
     blockNoInSequence--;
   }
-  
+
   /*
    * Start writing the buffer.
    *
@@ -4983,24 +5219,24 @@ BOOL SmallBlockChainStream_WriteAt(
    * This is OK since we don't intend to modify that buffer.
    */
   *bytesWritten   = 0;
-  bufferWalker = (BYTE*)buffer;
+  bufferWalker = (const BYTE*)buffer;
   while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) )
   {
     /*
      * Calculate how many bytes we can copy to this small block.
      */
-    bytesToWriteInBuffer = 
-      MIN(This->parentStorage->smallBlockSize - offsetInBlock, size);
-    
+    bytesToWriteInBuffer =
+      min(This->parentStorage->smallBlockSize - offsetInBlock, size);
+
     /*
      * Calculate the offset of the small block in the small block file.
      */
-    offsetInBigBlockFile.s.HighPart  = 0;
-    offsetInBigBlockFile.s.LowPart   = 
+    offsetInBigBlockFile.u.HighPart  = 0;
+    offsetInBigBlockFile.u.LowPart   =
       blockIndex * This->parentStorage->smallBlockSize;
 
-    offsetInBigBlockFile.s.LowPart  += offsetInBlock;
-    
+    offsetInBigBlockFile.u.LowPart  += offsetInBlock;
+
     /*
      * Write those bytes in the buffer to the small block file.
      */
@@ -5009,26 +5245,28 @@ BOOL SmallBlockChainStream_WriteAt(
       bytesToWriteInBuffer,
       bufferWalker,
       &bytesWrittenFromBigBlockFile);
-    
+
     assert(bytesWrittenFromBigBlockFile == bytesToWriteInBuffer);
-    
+
     /*
      * Step to the next big block.
      */
-    blockIndex    = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
+                                                       &blockIndex)))
+      return FALSE;
     bufferWalker  += bytesToWriteInBuffer;
     size          -= bytesToWriteInBuffer;
     *bytesWritten += bytesToWriteInBuffer;
     offsetInBlock  = 0;     /* There is no offset on the next block */
   }
-  
+
   return (size == 0);
 }
 
 /******************************************************************************
  *       SmallBlockChainStream_Shrink
  *
- * Shrinks this chain in the small block depot. 
+ * Shrinks this chain in the small block depot.
  */
 BOOL SmallBlockChainStream_Shrink(
   SmallBlockChainStream* This,
@@ -5038,9 +5276,9 @@ BOOL SmallBlockChainStream_Shrink(
   ULONG numBlocks;
   ULONG count = 0;
 
-  numBlocks = newSize.s.LowPart / This->parentStorage->smallBlockSize;
+  numBlocks = newSize.u.LowPart / This->parentStorage->smallBlockSize;
 
-  if ((newSize.s.LowPart % This->parentStorage->smallBlockSize) != 0)
+  if ((newSize.u.LowPart % This->parentStorage->smallBlockSize) != 0)
     numBlocks++;
 
   blockIndex = SmallBlockChainStream_GetHeadOfChain(This);
@@ -5050,19 +5288,21 @@ BOOL SmallBlockChainStream_Shrink(
    */
   while (count < numBlocks)
   {
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
+                                                       &blockIndex)))
+      return FALSE;
     count++;
   }
 
   /*
    * If the count is 0, we have a special case, the head of the chain was
-   * just freed. 
+   * just freed.
    */
   if (count == 0)
   {
     StgProperty chainProp;
 
-    StorageImpl_ReadProperty(This->parentStorage, 
+    StorageImpl_ReadProperty(This->parentStorage,
                             This->ownerPropertyIndex,
                             &chainProp);
 
@@ -5080,12 +5320,14 @@ BOOL SmallBlockChainStream_Shrink(
   else
   {
     /* Get the next block before marking the new end */
-    extraBlock = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
+                                                       &extraBlock)))
+      return FALSE;
 
     /* Mark the new end of chain */
     SmallBlockChainStream_SetNextBlockInChain(
-      This, 
-      blockIndex, 
+      This,
+      blockIndex,
       BLOCK_END_OF_CHAIN);
   }
 
@@ -5094,12 +5336,14 @@ BOOL SmallBlockChainStream_Shrink(
    */
   while (extraBlock != BLOCK_END_OF_CHAIN)
   {
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, extraBlock);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, extraBlock,
+                                                       &blockIndex)))
+      return FALSE;
     SmallBlockChainStream_FreeBlock(This, extraBlock);
     extraBlock = blockIndex;
   }
 
-  return TRUE;  
+  return TRUE;
 }
 
 /******************************************************************************
@@ -5135,8 +5379,8 @@ BOOL SmallBlockChainStream_Enlarge(
 
     blockIndex = chainProp.startingBlock;
     SmallBlockChainStream_SetNextBlockInChain(
-      This, 
-      blockIndex, 
+      This,
+      blockIndex,
       BLOCK_END_OF_CHAIN);
   }
 
@@ -5145,9 +5389,9 @@ BOOL SmallBlockChainStream_Enlarge(
   /*
    * Figure out how many blocks are needed to contain this stream
    */
-  newNumBlocks = newSize.s.LowPart / This->parentStorage->smallBlockSize;
+  newNumBlocks = newSize.u.LowPart / This->parentStorage->smallBlockSize;
 
-  if ((newSize.s.LowPart % This->parentStorage->smallBlockSize) != 0)
+  if ((newSize.u.LowPart % This->parentStorage->smallBlockSize) != 0)
     newNumBlocks++;
 
   /*
@@ -5157,7 +5401,8 @@ BOOL SmallBlockChainStream_Enlarge(
   {
     oldNumBlocks++;
     currentBlock = blockIndex;
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, currentBlock);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, currentBlock, &blockIndex)))
+      return FALSE;
   }
 
   /*
@@ -5169,8 +5414,8 @@ BOOL SmallBlockChainStream_Enlarge(
     SmallBlockChainStream_SetNextBlockInChain(This, currentBlock, blockIndex);
 
     SmallBlockChainStream_SetNextBlockInChain(
-      This, 
-      blockIndex, 
+      This,
+      blockIndex,
       BLOCK_END_OF_CHAIN);
 
     currentBlock = blockIndex;
@@ -5197,7 +5442,8 @@ ULONG SmallBlockChainStream_GetCount(SmallBlockChainStream* This)
   {
     count++;
 
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
+      return 0;
   }
 
   return count;
@@ -5211,7 +5457,7 @@ ULONG SmallBlockChainStream_GetCount(SmallBlockChainStream* This)
  *
  * TODO: Free the actual blocks in the file when we shrink the chain.
  *       Currently, the blocks are still in the file. So the file size
- *       doesn't shrink even if we shrink streams. 
+ *       doesn't shrink even if we shrink streams.
  */
 BOOL SmallBlockChainStream_SetSize(
                 SmallBlockChainStream* This,
@@ -5219,10 +5465,10 @@ BOOL SmallBlockChainStream_SetSize(
 {
   ULARGE_INTEGER size = SmallBlockChainStream_GetSize(This);
 
-  if (newSize.s.LowPart == size.s.LowPart)
+  if (newSize.u.LowPart == size.u.LowPart)
     return TRUE;
 
-  if (newSize.s.LowPart < size.s.LowPart)
+  if (newSize.u.LowPart < size.u.LowPart)
   {
     SmallBlockChainStream_Shrink(This, newSize);
   }
@@ -5252,7 +5498,7 @@ ULARGE_INTEGER SmallBlockChainStream_GetSize(SmallBlockChainStream* This)
 }
 
 /******************************************************************************
- *    StgCreateDocfile32  [OLE32.144]
+ *    StgCreateDocfile  [OLE32.@]
  */
 HRESULT WINAPI StgCreateDocfile(
   LPCOLESTR pwcsName,
@@ -5262,15 +5508,15 @@ HRESULT WINAPI StgCreateDocfile(
 {
   StorageImpl* newStorage = 0;
   HANDLE       hFile      = INVALID_HANDLE_VALUE;
-  HRESULT        hr         = S_OK;
+  HRESULT        hr         = STG_E_INVALIDFLAG;
   DWORD          shareMode;
   DWORD          accessMode;
   DWORD          creationMode;
   DWORD          fileAttributes;
   WCHAR          tempFileName[MAX_PATH];
 
-  TRACE("(%s, %lx, %ld, %p)\n", 
-       debugstr_w(pwcsName), grfMode, 
+  TRACE("(%s, %lx, %ld, %p)\n",
+       debugstr_w(pwcsName), grfMode,
        reserved, ppstgOpen);
 
   /*
@@ -5278,12 +5524,39 @@ HRESULT WINAPI StgCreateDocfile(
    */
   if (ppstgOpen == 0)
     return STG_E_INVALIDPOINTER;
+  if (reserved != 0)
+    return STG_E_INVALIDPARAMETER;
 
   /*
    * Validate the STGM flags
    */
   if ( FAILED( validateSTGM(grfMode) ))
-    return STG_E_INVALIDFLAG;
+    goto end;
+
+  /* StgCreateDocFile always opens for write */
+  switch(STGM_ACCESS_MODE(grfMode))
+  {
+  case STGM_WRITE:
+  case STGM_READWRITE:
+    break;
+  default:
+    goto end;
+  }
+
+  /* can't share write */
+  switch(STGM_SHARE_MODE(grfMode))
+  {
+  case STGM_SHARE_EXCLUSIVE:
+  case STGM_SHARE_DENY_WRITE:
+    break;
+  default:
+    goto end;
+  }
+
+  /* shared reading requires transacted mode */
+  if( STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE &&
+     !(grfMode&STGM_TRANSACTED) )
+    goto end;
 
   /*
    * Generate a unique name.
@@ -5291,7 +5564,10 @@ HRESULT WINAPI StgCreateDocfile(
   if (pwcsName == 0)
   {
     WCHAR tempPath[MAX_PATH];
-    WCHAR prefix[] = { 'S', 'T', 'O', 0 };
+    static const WCHAR prefix[] = { 'S', 'T', 'O', 0 };
+
+    if (STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE)
+      goto end;
 
     memset(tempPath, 0, sizeof(tempPath));
     memset(tempFileName, 0, sizeof(tempFileName));
@@ -5302,15 +5578,23 @@ HRESULT WINAPI StgCreateDocfile(
     if (GetTempFileNameW(tempPath, prefix, 0, tempFileName) != 0)
       pwcsName = tempFileName;
     else
-      return STG_E_INSUFFICIENTMEMORY;
+    {
+      hr = STG_E_INSUFFICIENTMEMORY;
+      goto end;
+    }
+
+    creationMode = TRUNCATE_EXISTING;
+  }
+  else
+  {
+    creationMode = GetCreationModeFromSTGM(grfMode);
   }
 
   /*
-   * Interpret the STGM value grfMode 
+   * Interpret the STGM value grfMode
    */
   shareMode    = GetShareModeFromSTGM(grfMode);
   accessMode   = GetAccessModeFromSTGM(grfMode);
-  creationMode = GetCreationModeFromSTGM(grfMode);
 
   if (grfMode & STGM_DELETEONRELEASE)
     fileAttributes = FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_DELETE_ON_CLOSE;
@@ -5328,36 +5612,44 @@ HRESULT WINAPI StgCreateDocfile(
   hFile = CreateFileW(pwcsName,
                         accessMode,
                         shareMode,
-            NULL,
+                        NULL,
                         creationMode,
                         fileAttributes,
-            0);
+                        0);
+
   if (hFile == INVALID_HANDLE_VALUE)
   {
-    return E_FAIL;
+    if(GetLastError() == ERROR_FILE_EXISTS)
+      hr = STG_E_FILEALREADYEXISTS;
+    else
+      hr = E_FAIL;
+    goto end;
   }
 
   /*
    * Allocate and initialize the new IStorage32object.
    */
   newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl));
+
   if (newStorage == 0)
-    return STG_E_INSUFFICIENTMEMORY;
+  {
+    hr = STG_E_INSUFFICIENTMEMORY;
+    goto end;
+  }
 
   hr = StorageImpl_Construct(
          newStorage,
          hFile,
+        pwcsName,
          NULL,
          grfMode,
          TRUE,
          TRUE);
+
   if (FAILED(hr))
   {
     HeapFree(GetProcessHeap(), 0, newStorage);
-    return hr;
+    goto end;
   }
 
   /*
@@ -5367,19 +5659,113 @@ HRESULT WINAPI StgCreateDocfile(
          (IStorage*)newStorage,
          (REFIID)&IID_IStorage,
          (void**)ppstgOpen);
+end:
+  TRACE("<-- %p  r = %08lx\n", *ppstgOpen, hr);
 
   return hr;
 }
 
 /******************************************************************************
- *              StgOpenStorage32        [OLE32.148]
+ *              StgCreateStorageEx        [OLE32.@]
+ */
+HRESULT WINAPI StgCreateStorageEx(const WCHAR* pwcsName, DWORD grfMode, DWORD stgfmt, DWORD grfAttrs, STGOPTIONS* pStgOptions, void* reserved, REFIID riid, void** ppObjectOpen)
+{
+    TRACE("(%s, %lx, %lx, %lx, %p, %p, %p, %p)\n", debugstr_w(pwcsName),
+          grfMode, stgfmt, grfAttrs, pStgOptions, reserved, riid, ppObjectOpen);
+
+    if (stgfmt != STGFMT_FILE && grfAttrs != 0)
+    {
+        ERR("grfAttrs must be 0 if stgfmt != STGFMT_FILE\n");
+        return STG_E_INVALIDPARAMETER;  
+    }
+
+    if (stgfmt != STGFMT_FILE && grfAttrs != 0 && grfAttrs != FILE_FLAG_NO_BUFFERING)
+    {
+        ERR("grfAttrs must be 0 or FILE_FLAG_NO_BUFFERING if stgfmt == STGFMT_FILE\n");
+        return STG_E_INVALIDPARAMETER;  
+    }
+
+    if (stgfmt == STGFMT_FILE)
+    {
+        ERR("Cannot use STGFMT_FILE - this is NTFS only\n");  
+        return STG_E_INVALIDPARAMETER;
+    }
+
+    if (stgfmt == STGFMT_STORAGE || stgfmt == STGFMT_DOCFILE)
+    {
+        FIXME("Stub: calling StgCreateDocfile, but ignoring pStgOptions and grfAttrs\n");
+        return StgCreateDocfile(pwcsName, grfMode, 0, (IStorage **)ppObjectOpen); 
+    }
+
+    ERR("Invalid stgfmt argument\n");
+    return STG_E_INVALIDPARAMETER;
+}
+
+/******************************************************************************
+ *              StgCreatePropSetStg       [OLE32.@]
+ */
+HRESULT WINAPI StgCreatePropSetStg(IStorage *pstg, DWORD reserved,
+ IPropertySetStorage **ppPropSetStg)
+{
+    HRESULT hr;
+
+    TRACE("(%p, 0x%lx, %p): stub\n", pstg, reserved, ppPropSetStg);
+    if (reserved)
+        hr = STG_E_INVALIDPARAMETER;
+    else
+        hr = StorageBaseImpl_QueryInterface(pstg, &IID_IPropertySetStorage,
+         (void**)ppPropSetStg);
+    return hr;
+}
+
+/******************************************************************************
+ *              StgOpenStorageEx      [OLE32.@]
+ */
+HRESULT WINAPI StgOpenStorageEx(const WCHAR* pwcsName, DWORD grfMode, DWORD stgfmt, DWORD grfAttrs, STGOPTIONS* pStgOptions, void* reserved, REFIID riid, void** ppObjectOpen)
+{
+    TRACE("(%s, %lx, %lx, %lx, %p, %p, %p, %p)\n", debugstr_w(pwcsName),
+          grfMode, stgfmt, grfAttrs, pStgOptions, reserved, riid, ppObjectOpen);
+
+    if (stgfmt != STGFMT_DOCFILE && grfAttrs != 0)
+    {
+        ERR("grfAttrs must be 0 if stgfmt != STGFMT_DOCFILE\n");
+        return STG_E_INVALIDPARAMETER;  
+    }
+
+    if (stgfmt != STGFMT_DOCFILE && grfAttrs != 0 && grfAttrs != FILE_FLAG_NO_BUFFERING)
+    {
+        ERR("grfAttrs must be 0 or FILE_FLAG_NO_BUFFERING if stgfmt == STGFMT_DOCFILE\n");
+        return STG_E_INVALIDPARAMETER;  
+    }
+
+    if (stgfmt == STGFMT_FILE)
+    {
+        ERR("Cannot use STGFMT_FILE - this is NTFS only\n");  
+        return STG_E_INVALIDPARAMETER;
+    }
+
+    if (stgfmt == STGFMT_STORAGE || stgfmt == STGFMT_DOCFILE || stgfmt == STGFMT_ANY)
+    {
+        if (stgfmt == STGFMT_ANY) 
+            WARN("STGFMT_ANY assuming storage\n");
+        FIXME("Stub: calling StgOpenStorage, but ignoring pStgOptions and grfAttrs\n");
+        return StgOpenStorage(pwcsName, NULL, grfMode, (SNB)NULL, 0, (IStorage **)ppObjectOpen); 
+    }
+
+    ERR("Invalid stgfmt argument\n");
+    return STG_E_INVALIDPARAMETER;
+}
+
+
+/******************************************************************************
+ *              StgOpenStorage        [OLE32.@]
  */
 HRESULT WINAPI StgOpenStorage(
   const OLECHAR *pwcsName,
   IStorage      *pstgPriority,
   DWORD           grfMode,
   SNB           snbExclude,
-  DWORD           reserved, 
+  DWORD           reserved,
   IStorage      **ppstgOpen)
 {
   StorageImpl* newStorage = 0;
@@ -5387,22 +5773,65 @@ HRESULT WINAPI StgOpenStorage(
   HANDLE       hFile = 0;
   DWORD          shareMode;
   DWORD          accessMode;
+  WCHAR          fullname[MAX_PATH];
+  DWORD          length;
 
-  TRACE("(%s, %p, %lx, %p, %ld, %p)\n", 
+  TRACE("(%s, %p, %lx, %p, %ld, %p)\n",
        debugstr_w(pwcsName), pstgPriority, grfMode,
        snbExclude, reserved, ppstgOpen);
 
   /*
-   * Perform a sanity check
+   * Perform sanity checks
    */
-  if (( pwcsName == 0) || (ppstgOpen == 0) )
-    return STG_E_INVALIDPOINTER;
+  if (pwcsName == 0)
+  {
+    hr = STG_E_INVALIDNAME;
+    goto end;
+  }
+
+  if (ppstgOpen == 0)
+  {
+    hr = STG_E_INVALIDPOINTER;
+    goto end;
+  }
+
+  if (reserved)
+  {
+    hr = STG_E_INVALIDPARAMETER;
+    goto end;
+  }
+
+  /*
+   * Validate the sharing mode
+   */
+  switch(STGM_SHARE_MODE(grfMode))
+  {
+  case STGM_SHARE_EXCLUSIVE:
+  case STGM_SHARE_DENY_WRITE:
+    break;
+  default:
+    hr = STG_E_INVALIDFLAG;
+    goto end;
+  }
 
   /*
    * Validate the STGM flags
    */
-  if ( FAILED( validateSTGM(grfMode) ))
-    return STG_E_INVALIDFLAG;
+  if ( FAILED( validateSTGM(grfMode) ) ||
+       (grfMode&STGM_CREATE))
+  {
+    hr = STG_E_INVALIDFLAG;
+    goto end;
+  }
+
+  /* shared reading requires transacted mode */
+  if( STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE &&
+      STGM_ACCESS_MODE(grfMode) == STGM_READWRITE &&
+     !(grfMode&STGM_TRANSACTED) )
+  {
+    hr = STG_E_INVALIDFLAG;
+    goto end;
+  }
 
   /*
    * Interpret the STGM value grfMode
@@ -5414,21 +5843,21 @@ HRESULT WINAPI StgOpenStorage(
    * Initialize the "out" parameter.
    */
   *ppstgOpen = 0;
-  
-  hFile = CreateFileW( pwcsName, 
+
+  hFile = CreateFileW( pwcsName,
                        accessMode,
                        shareMode,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
                        0);
-  
-  
+
   if (hFile==INVALID_HANDLE_VALUE)
   {
-    HRESULT hr = E_FAIL;
     DWORD last_error = GetLastError();
 
+    hr = E_FAIL;
+
     switch (last_error)
     {
       case ERROR_FILE_NOT_FOUND:
@@ -5452,31 +5881,58 @@ HRESULT WINAPI StgOpenStorage(
         hr = E_FAIL;
     }
 
-    return hr;
+    goto end;
+  }
+
+  /*
+   * Refuse to open the file if it's too small to be a structured storage file
+   * FIXME: verify the file when reading instead of here
+   */
+  length = GetFileSize(hFile, NULL);
+  if (length < 0x100)
+  {
+    CloseHandle(hFile);
+    hr = STG_E_FILEALREADYEXISTS;
+    goto end;
   }
 
   /*
    * Allocate and initialize the new IStorage32object.
    */
   newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl));
-  
+
   if (newStorage == 0)
-    return STG_E_INSUFFICIENTMEMORY;
+  {
+    hr = STG_E_INSUFFICIENTMEMORY;
+    goto end;
+  }
 
+  /* if the file's length was zero, initialize the storage */
   hr = StorageImpl_Construct(
          newStorage,
          hFile,
+        pwcsName,
          NULL,
          grfMode,
          TRUE,
-         FALSE);
-  
+        FALSE );
+
   if (FAILED(hr))
   {
     HeapFree(GetProcessHeap(), 0, newStorage);
-    return hr;
+    /*
+     * According to the docs if the file is not a storage, return STG_E_FILEALREADYEXISTS
+     */
+    if(hr == STG_E_INVALIDHEADER)
+       hr = STG_E_FILEALREADYEXISTS;
+    goto end;
   }
-  
+
+  /* prepare the file name string given in lieu of the root property name */
+  GetFullPathNameW(pwcsName, MAX_PATH, fullname, NULL);
+  memcpy(newStorage->filename, fullname, PROPERTY_NAME_BUFFER_LEN);
+  newStorage->filename[PROPERTY_NAME_BUFFER_LEN-1] = '\0';
+
   /*
    * Get an "out" pointer for the caller.
    */
@@ -5484,12 +5940,14 @@ HRESULT WINAPI StgOpenStorage(
          (IStorage*)newStorage,
          (REFIID)&IID_IStorage,
          (void**)ppstgOpen);
-  
+
+end:
+  TRACE("<-- %08lx, IStorage %p\n", hr, ppstgOpen ? *ppstgOpen : NULL);
   return hr;
 }
 
 /******************************************************************************
- *    StgCreateDocfileOnILockBytes    [OLE32.145]
+ *    StgCreateDocfileOnILockBytes    [OLE32.@]
  */
 HRESULT WINAPI StgCreateDocfileOnILockBytes(
       ILockBytes *plkbyt,
@@ -5517,6 +5975,7 @@ HRESULT WINAPI StgCreateDocfileOnILockBytes(
   hr = StorageImpl_Construct(
          newStorage,
          0,
+        0,
          plkbyt,
          grfMode,
          FALSE,
@@ -5536,11 +5995,11 @@ HRESULT WINAPI StgCreateDocfileOnILockBytes(
          (REFIID)&IID_IStorage,
          (void**)ppstgOpen);
 
-  return hr;  
+  return hr;
 }
 
 /******************************************************************************
- *    StgOpenStorageOnILockBytes    [OLE32.149]
+ *    StgOpenStorageOnILockBytes    [OLE32.@]
  */
 HRESULT WINAPI StgOpenStorageOnILockBytes(
       ILockBytes *plkbyt,
@@ -5574,13 +6033,14 @@ HRESULT WINAPI StgOpenStorageOnILockBytes(
    * Allocate and initialize the new IStorage object.
    */
   newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl));
+
   if (newStorage == 0)
     return STG_E_INSUFFICIENTMEMORY;
 
   hr = StorageImpl_Construct(
          newStorage,
          0,
+         0,
          plkbyt,
          grfMode,
          FALSE,
@@ -5604,19 +6064,32 @@ HRESULT WINAPI StgOpenStorageOnILockBytes(
 }
 
 /******************************************************************************
- *              StgSetTimes [ole32.150]
+ *              StgSetTimes [ole32.@]
+ *              StgSetTimes [OLE32.@]
  *
  *
  */
-HRESULT WINAPI StgSetTimes(WCHAR * str, FILETIME * a, FILETIME * b, FILETIME *c )
+HRESULT WINAPI StgSetTimes(OLECHAR const *str, FILETIME const *pctime,
+                           FILETIME const *patime, FILETIME const *pmtime)
 {
+  IStorage *stg = NULL;
+  HRESULT r;
  
-  FIXME("(%p, %p, %p, %p),stub!\n", str, a, b, c);
-  return FALSE;
+  TRACE("%s %p %p %p\n", debugstr_w(str), pctime, patime, pmtime);
+
+  r = StgOpenStorage(str, NULL, STGM_READWRITE | STGM_SHARE_DENY_WRITE,
+                     0, 0, &stg);
+  if( SUCCEEDED(r) )
+  {
+    r = IStorage_SetElementTimes(stg, NULL, pctime, patime, pmtime);
+    IStorage_Release(stg);
+  }
+
+  return r;
 }
 
 /******************************************************************************
- *              StgIsStorageILockBytes        [OLE32.147]
+ *              StgIsStorageILockBytes        [OLE32.@]
  *
  * Determines if the ILockBytes contains a storage object.
  */
@@ -5625,8 +6098,8 @@ HRESULT WINAPI StgIsStorageILockBytes(ILockBytes *plkbyt)
   BYTE sig[8];
   ULARGE_INTEGER offset;
 
-  offset.s.HighPart = 0;
-  offset.s.LowPart  = 0;
+  offset.u.HighPart = 0;
+  offset.u.LowPart  = 0;
 
   ILockBytes_ReadAt(plkbyt, offset, sig, sizeof(sig), NULL);
 
@@ -5637,7 +6110,7 @@ HRESULT WINAPI StgIsStorageILockBytes(ILockBytes *plkbyt)
 }
 
 /******************************************************************************
- *              WriteClassStg32        [OLE32.158]
+ *              WriteClassStg        [OLE32.@]
  *
  * This method will store the specified CLSID in the specified storage object
  */
@@ -5652,8 +6125,8 @@ HRESULT WINAPI WriteClassStg(IStorage* pStg, REFCLSID rclsid)
   return hRes;
 }
 
-/*******************************************************************************************
- *    ReadClassStg
+/***********************************************************************
+ *    ReadClassStg (OLE32.@)
  *
  * This method reads the CLSID previously written to a storage object with the WriteClassStg.
  */
@@ -5661,7 +6134,7 @@ HRESULT WINAPI ReadClassStg(IStorage *pstg,CLSID *pclsid){
 
     STATSTG pstatstg;
     HRESULT hRes;
-    
+
     TRACE("()\n");
 
     if(pclsid==NULL)
@@ -5677,49 +6150,58 @@ HRESULT WINAPI ReadClassStg(IStorage *pstg,CLSID *pclsid){
     return hRes;
 }
 
-/*************************************************************************************
- *    OleLoadFromStream
+/***********************************************************************
+ *    OleLoadFromStream (OLE32.@)
  *
  * This function loads an object from stream
  */
 HRESULT  WINAPI OleLoadFromStream(IStream *pStm,REFIID iidInterface,void** ppvObj)
 {
-    CLSID clsid;
-    HRESULT res;
+    CLSID      clsid;
+    HRESULT    res;
+    LPPERSISTSTREAM    xstm;
 
-    FIXME("(),stub!\n");
+    TRACE("(%p,%s,%p)\n",pStm,debugstr_guid(iidInterface),ppvObj);
 
     res=ReadClassStm(pStm,&clsid);
-
-    if (SUCCEEDED(res)){
-        
-        res=CoCreateInstance(&clsid,NULL,CLSCTX_INPROC_SERVER,iidInterface,ppvObj);
-
-        if (SUCCEEDED(res))
-
-            res=IPersistStream_Load((IPersistStream*)ppvObj,pStm);
+    if (!SUCCEEDED(res))
+       return res;
+    res=CoCreateInstance(&clsid,NULL,CLSCTX_INPROC_SERVER,iidInterface,ppvObj);
+    if (!SUCCEEDED(res))
+       return res;
+    res=IUnknown_QueryInterface((IUnknown*)*ppvObj,&IID_IPersistStream,(LPVOID*)&xstm);
+    if (!SUCCEEDED(res)) {
+       IUnknown_Release((IUnknown*)*ppvObj);
+       return res;
     }
-
+    res=IPersistStream_Load(xstm,pStm);
+    IPersistStream_Release(xstm);
+    /* FIXME: all refcounts ok at this point? I think they should be:
+     *                 pStm    : unchanged
+     *         ppvObj  : 1
+     *         xstm    : 0 (released)
+     */
     return res;
 }
 
-/************************************************************************************************
- *    OleSaveToStream
+/***********************************************************************
+ *    OleSaveToStream (OLE32.@)
  *
- * This function saves an object with the IPersistStream interface on it to the specified stream
+ * This function saves an object with the IPersistStream interface on it
+ * to the specified stream.
  */
 HRESULT  WINAPI OleSaveToStream(IPersistStream *pPStm,IStream *pStm)
 {
 
     CLSID clsid;
     HRESULT res;
-    
+
     TRACE("(%p,%p)\n",pPStm,pStm);
 
     res=IPersistStream_GetClassID(pPStm,&clsid);
 
     if (SUCCEEDED(res)){
-        
+
         res=WriteClassStm(pStm,&clsid);
 
         if (SUCCEEDED(res))
@@ -5734,19 +6216,22 @@ HRESULT  WINAPI OleSaveToStream(IPersistStream *pPStm,IStream *pStm)
 /****************************************************************************
  * This method validate a STGM parameter that can contain the values below
  *
+ * The stgm modes in 0x0000ffff are not bit masks, but distinct 4 bit values.
+ * The stgm values contained in 0xffff0000 are bitmasks.
+ *
  * STGM_DIRECT               0x00000000
  * STGM_TRANSACTED           0x00010000
  * STGM_SIMPLE               0x08000000
- * 
+ *
  * STGM_READ                 0x00000000
  * STGM_WRITE                0x00000001
  * STGM_READWRITE            0x00000002
- * 
+ *
  * STGM_SHARE_DENY_NONE      0x00000040
  * STGM_SHARE_DENY_READ      0x00000030
  * STGM_SHARE_DENY_WRITE     0x00000020
  * STGM_SHARE_EXCLUSIVE      0x00000010
- * 
+ *
  * STGM_PRIORITY             0x00040000
  * STGM_DELETEONRELEASE      0x04000000
  *
@@ -5759,79 +6244,74 @@ HRESULT  WINAPI OleSaveToStream(IPersistStream *pPStm,IStream *pStm)
  */
 static HRESULT validateSTGM(DWORD stgm)
 {
-  BOOL bSTGM_TRANSACTED       = ((stgm & STGM_TRANSACTED) == STGM_TRANSACTED);
-  BOOL bSTGM_SIMPLE           = ((stgm & STGM_SIMPLE) == STGM_SIMPLE);
-  BOOL bSTGM_DIRECT           = ! (bSTGM_TRANSACTED || bSTGM_SIMPLE);
-   
-  BOOL bSTGM_WRITE            = ((stgm & STGM_WRITE) == STGM_WRITE);
-  BOOL bSTGM_READWRITE        = ((stgm & STGM_READWRITE) == STGM_READWRITE);
-  BOOL bSTGM_READ             = ! (bSTGM_WRITE || bSTGM_READWRITE);
-   
-  BOOL bSTGM_SHARE_DENY_NONE  =
-                     ((stgm & STGM_SHARE_DENY_NONE)  == STGM_SHARE_DENY_NONE);
-
-  BOOL bSTGM_SHARE_DENY_READ  =
-                     ((stgm & STGM_SHARE_DENY_READ)  == STGM_SHARE_DENY_READ);
-
-  BOOL bSTGM_SHARE_DENY_WRITE =
-                     ((stgm & STGM_SHARE_DENY_WRITE) == STGM_SHARE_DENY_WRITE);
-
-  BOOL bSTGM_SHARE_EXCLUSIVE  =
-                     ((stgm & STGM_SHARE_EXCLUSIVE)  == STGM_SHARE_EXCLUSIVE);
-
-  BOOL bSTGM_CREATE           = ((stgm & STGM_CREATE) == STGM_CREATE);
-  BOOL bSTGM_CONVERT          = ((stgm & STGM_CONVERT) == STGM_CONVERT);
-   
-  BOOL bSTGM_NOSCRATCH        = ((stgm & STGM_NOSCRATCH) == STGM_NOSCRATCH);
-  BOOL bSTGM_NOSNAPSHOT       = ((stgm & STGM_NOSNAPSHOT) == STGM_NOSNAPSHOT);
-
-  /* 
-   * STGM_DIRECT | STGM_TRANSACTED | STGM_SIMPLE
-   */
-  if ( ! bSTGM_DIRECT )
-    if( bSTGM_TRANSACTED && bSTGM_SIMPLE )
-      return E_FAIL;
+  DWORD access = STGM_ACCESS_MODE(stgm);
+  DWORD share  = STGM_SHARE_MODE(stgm);
+  DWORD create = STGM_CREATE_MODE(stgm);
 
-  /* 
-   * STGM_WRITE |  STGM_READWRITE | STGM_READ
-   */
-  if ( ! bSTGM_READ )
-    if( bSTGM_WRITE && bSTGM_READWRITE )
-      return E_FAIL;
+  if (stgm&~STGM_KNOWN_FLAGS)
+  {
+    ERR("unknown flags %08lx\n", stgm);
+    return E_FAIL;
+  }
+
+  switch (access)
+  {
+  case STGM_READ:
+  case STGM_WRITE:
+  case STGM_READWRITE:
+    break;
+  default:
+    return E_FAIL;
+  }
+
+  switch (share)
+  {
+  case STGM_SHARE_DENY_NONE:
+  case STGM_SHARE_DENY_READ:
+  case STGM_SHARE_DENY_WRITE:
+  case STGM_SHARE_EXCLUSIVE:
+    break;
+  default:
+    return E_FAIL;
+  }
+
+  switch (create)
+  {
+  case STGM_CREATE:
+  case STGM_FAILIFTHERE:
+    break;
+  default:
+    return E_FAIL;
+  }
 
   /*
-   * STGM_SHARE_DENY_NONE | others 
-   * (I assume here that DENY_READ implies DENY_WRITE)
+   * STGM_DIRECT | STGM_TRANSACTED | STGM_SIMPLE
    */
-  if ( bSTGM_SHARE_DENY_NONE )
-    if ( bSTGM_SHARE_DENY_READ ||
-         bSTGM_SHARE_DENY_WRITE || 
-         bSTGM_SHARE_EXCLUSIVE) 
+  if ( (stgm & STGM_TRANSACTED) && (stgm & STGM_SIMPLE) )
       return E_FAIL;
 
   /*
    * STGM_CREATE | STGM_CONVERT
    * if both are false, STGM_FAILIFTHERE is set to TRUE
    */
-  if ( bSTGM_CREATE && bSTGM_CONVERT )
+  if ( create == STGM_CREATE && (stgm & STGM_CONVERT) )
     return E_FAIL;
 
   /*
    * STGM_NOSCRATCH requires STGM_TRANSACTED
    */
-  if ( bSTGM_NOSCRATCH && ! bSTGM_TRANSACTED )
+  if ( (stgm & STGM_NOSCRATCH) && !(stgm & STGM_TRANSACTED) )
     return E_FAIL;
-  
+
   /*
-   * STGM_NOSNAPSHOT requires STGM_TRANSACTED and 
+   * STGM_NOSNAPSHOT requires STGM_TRANSACTED and
    * not STGM_SHARE_EXCLUSIVE or STGM_SHARE_DENY_WRITE`
    */
-  if (bSTGM_NOSNAPSHOT)
-  {
-    if ( ! ( bSTGM_TRANSACTED && 
-           !(bSTGM_SHARE_EXCLUSIVE || bSTGM_SHARE_DENY_WRITE)) )
+  if ( (stgm & STGM_NOSNAPSHOT) &&
+        (!(stgm & STGM_TRANSACTED) ||
+         share == STGM_SHARE_EXCLUSIVE ||
+         share == STGM_SHARE_DENY_WRITE) )
     return E_FAIL;
-  }
 
   return S_OK;
 }
@@ -5840,33 +6320,24 @@ static HRESULT validateSTGM(DWORD stgm)
  *      GetShareModeFromSTGM
  *
  * This method will return a share mode flag from a STGM value.
- * The STGM value is assumed valid. 
+ * The STGM value is assumed valid.
  */
 static DWORD GetShareModeFromSTGM(DWORD stgm)
 {
-  DWORD dwShareMode = 0;
-  BOOL bSTGM_SHARE_DENY_NONE  =
-                     ((stgm & STGM_SHARE_DENY_NONE)  == STGM_SHARE_DENY_NONE);
-
-  BOOL bSTGM_SHARE_DENY_READ  =
-                     ((stgm & STGM_SHARE_DENY_READ)  == STGM_SHARE_DENY_READ);
-
-  BOOL bSTGM_SHARE_DENY_WRITE =
-                     ((stgm & STGM_SHARE_DENY_WRITE) == STGM_SHARE_DENY_WRITE);
-
-  BOOL bSTGM_SHARE_EXCLUSIVE  =
-                     ((stgm & STGM_SHARE_EXCLUSIVE)  == STGM_SHARE_EXCLUSIVE);
-
-  if ((bSTGM_SHARE_EXCLUSIVE) || (bSTGM_SHARE_DENY_READ))
-    dwShareMode = 0;
-
-  if (bSTGM_SHARE_DENY_NONE)
-    dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-
-  if (bSTGM_SHARE_DENY_WRITE)
-    dwShareMode = FILE_SHARE_READ;
-
-  return dwShareMode;
+  switch (STGM_SHARE_MODE(stgm))
+  {
+  case STGM_SHARE_DENY_NONE:
+    return FILE_SHARE_READ | FILE_SHARE_WRITE;
+  case STGM_SHARE_DENY_READ:
+    return FILE_SHARE_WRITE;
+  case STGM_SHARE_DENY_WRITE:
+    return FILE_SHARE_READ;
+  case STGM_SHARE_EXCLUSIVE:
+    return 0;
+  }
+  ERR("Invalid share mode!\n");
+  assert(0);
+  return 0;
 }
 
 /****************************************************************************
@@ -5877,21 +6348,17 @@ static DWORD GetShareModeFromSTGM(DWORD stgm)
  */
 static DWORD GetAccessModeFromSTGM(DWORD stgm)
 {
-  DWORD dwDesiredAccess = GENERIC_READ;
-  BOOL bSTGM_WRITE     = ((stgm & STGM_WRITE) == STGM_WRITE);
-  BOOL bSTGM_READWRITE = ((stgm & STGM_READWRITE) == STGM_READWRITE);
-  BOOL bSTGM_READ      = ! (bSTGM_WRITE || bSTGM_READWRITE);
-
-  if (bSTGM_READ)
-    dwDesiredAccess = GENERIC_READ;
-
-  if (bSTGM_WRITE)
-    dwDesiredAccess |= GENERIC_WRITE;
-
-  if (bSTGM_READWRITE)
-    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
-
-  return dwDesiredAccess;
+  switch (STGM_ACCESS_MODE(stgm))
+  {
+  case STGM_READ:
+    return GENERIC_READ;
+  case STGM_WRITE:
+  case STGM_READWRITE:
+    return GENERIC_READ | GENERIC_WRITE;
+  }
+  ERR("Invalid access mode!\n");
+  assert(0);
+  return 0;
 }
 
 /****************************************************************************
@@ -5902,23 +6369,26 @@ static DWORD GetAccessModeFromSTGM(DWORD stgm)
  */
 static DWORD GetCreationModeFromSTGM(DWORD stgm)
 {
-  if ( stgm & STGM_CREATE)
+  switch(STGM_CREATE_MODE(stgm))
+  {
+  case STGM_CREATE:
     return CREATE_ALWAYS;
-  if (stgm & STGM_CONVERT) {
+  case STGM_CONVERT:
     FIXME("STGM_CONVERT not implemented!\n");
     return CREATE_NEW;
+  case STGM_FAILIFTHERE:
+    return CREATE_NEW;
   }
-  /* All other cases */
-  if (stgm & ~ (STGM_CREATE|STGM_CONVERT))
-       FIXME("unhandled storage mode : 0x%08lx\n",stgm & ~ (STGM_CREATE|STGM_CONVERT));
-  return CREATE_NEW;
+  ERR("Invalid create mode!\n");
+  assert(0);
+  return 0;
 }
 
 
 /*************************************************************************
- * OLECONVERT_LoadOLE10 [Internal] 
+ * OLECONVERT_LoadOLE10 [Internal]
  *
- * Loads the OLE10 STREAM to memory 
+ * Loads the OLE10 STREAM to memory
  *
  * PARAMS
  *     pOleStream   [I] The OLESTREAM
@@ -5931,7 +6401,7 @@ static DWORD GetCreationModeFromSTGM(DWORD stgm)
  *
  * NOTES
  *     This function is used by OleConvertOLESTREAMToIStorage only.
- *     
+ *
  *     Memory allocated for pData must be freed by the caller
  */
 HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *pData, BOOL bStrem1)
@@ -5976,7 +6446,7 @@ HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *
        {
                if(pData->dwTypeID != 0)
                {
-                       /* Get the lenght of the OleTypeName */
+                       /* Get the length of the OleTypeName */
                        dwSize = pOleStream->lpstbl->Get(pOleStream, (void *) &(pData->dwOleTypeNameLength), sizeof(pData->dwOleTypeNameLength));
                        if(dwSize != sizeof(pData->dwOleTypeNameLength))
                        {
@@ -6004,9 +6474,9 @@ HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *
                                }
                        if(hRes == S_OK)
                        {
-                                       if(pData->dwOleObjFileNameLength < 1) //there is no file name exist
+                                       if(pData->dwOleObjFileNameLength < 1) /* there is no file name exist */
                                                pData->dwOleObjFileNameLength = sizeof(pData->dwOleObjFileNameLength);
-                                       pData->pstrOleObjFileName = (CHAR *)malloc(pData->dwOleObjFileNameLength);
+                                       pData->pstrOleObjFileName = HeapAlloc(GetProcessHeap(), 0, pData->dwOleObjFileNameLength);
                                        if(pData->pstrOleObjFileName)
                                        {
                                                dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)(pData->pstrOleObjFileName),pData->dwOleObjFileNameLength);
@@ -6039,7 +6509,7 @@ HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *
                        }
                        if(hRes == S_OK)
                        {
-                               /* Get the Lenght of the Data */
+                               /* Get the Length of the Data */
                                dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwDataLength), sizeof(pData->dwDataLength));
                                if(dwSize != sizeof(pData->dwDataLength))
                                {
@@ -6047,9 +6517,9 @@ HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *
                                }
                        }
 
-                       if(hRes == S_OK) // I don't know what is this 8 byts information is we have to figure out
+                       if(hRes == S_OK) /* I don't know what is this 8 byts information is we have to figure out */
                        {
-                               if(!bStrem1) //if it is a second OLE stream data
+                               if(!bStrem1) /* if it is a second OLE stream data */
                                {
                                        pData->dwDataLength -= 8;
                                        dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)(pData->strUnknown), sizeof(pData->strUnknown));
@@ -6063,7 +6533,7 @@ HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *
                        {
                                if(pData->dwDataLength > 0)
                                {
-                                       pData->pData = (BYTE *)HeapAlloc(GetProcessHeap(),0,pData->dwDataLength);
+                                       pData->pData = HeapAlloc(GetProcessHeap(),0,pData->dwDataLength);
 
                                        /* Get Data (ex. IStorage, Metafile, or BMP) */
                                        if(pData->pData)
@@ -6086,9 +6556,9 @@ HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *
 }
 
 /*************************************************************************
- * OLECONVERT_SaveOLE10 [Internal] 
+ * OLECONVERT_SaveOLE10 [Internal]
  *
- * Saves the OLE10 STREAM From memory 
+ * Saves the OLE10 STREAM From memory
  *
  * PARAMS
  *     pData        [I] Data Structure for the OLESTREAM Data
@@ -6100,7 +6570,7 @@ HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *
  *
  * NOTES
  *     This function is used by OleConvertIStorageToOLESTREAM only.
- *     
+ *
  */
 HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREAM pOleStream)
 {
@@ -6127,7 +6597,7 @@ HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREAM pOleS
 
     if(pData->dwOleID == OLESTREAM_ID && pData->dwTypeID != 0 && hRes == S_OK)
     {
-        /* Set the Lenght of the OleTypeName */
+        /* Set the Length of the OleTypeName */
         dwSize = pOleStream->lpstbl->Put(pOleStream, (void *)&(pData->dwOleTypeNameLength), sizeof(pData->dwOleTypeNameLength));
         if(dwSize != sizeof(pData->dwOleTypeNameLength))
         {
@@ -6169,7 +6639,7 @@ HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREAM pOleS
 
         if(hRes == S_OK)
         {
-            /* Set the lenght of the Data */
+            /* Set the length of the Data */
             dwSize = pOleStream->lpstbl->Put(pOleStream, (void *)&(pData->dwDataLength), sizeof(pData->dwDataLength));
             if(dwSize != sizeof(pData->dwDataLength))
             {
@@ -6194,12 +6664,12 @@ HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREAM pOleS
 }
 
 /*************************************************************************
- * OLECONVERT_GetOLE20FromOLE10[Internal] 
+ * OLECONVERT_GetOLE20FromOLE10[Internal]
  *
  * This function copies OLE10 Data (the IStorage in the OLESTREAM) to disk,
- * opens it, and copies the content to the dest IStorage for 
+ * opens it, and copies the content to the dest IStorage for
  * OleConvertOLESTREAMToIStorage
- * 
+ *
  *
  * PARAMS
  *     pDestStorage  [I] The IStorage to copy the data to
@@ -6210,8 +6680,8 @@ HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREAM pOleS
  *     Nothing
  *
  * NOTES
- *     
- *     
+ *
+ *
  */
 void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD nBufferLength)
 {
@@ -6220,7 +6690,7 @@ void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD n
     IStorage *pTempStorage;
     DWORD dwNumOfBytesWritten;
     WCHAR wstrTempDir[MAX_PATH], wstrTempFile[MAX_PATH];
-    WCHAR wstrPrefix[] = {'s', 'i', 's', 0};
+    static const WCHAR wstrPrefix[] = {'s', 'i', 's', 0};
 
     /* Create a temp File */
     GetTempPathW(MAX_PATH, wstrTempDir);
@@ -6246,9 +6716,9 @@ void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD n
 
 
 /*************************************************************************
- * OLECONVERT_WriteOLE20ToBuffer [Internal] 
+ * OLECONVERT_WriteOLE20ToBuffer [Internal]
  *
- * Saves the OLE10 STREAM From memory 
+ * Saves the OLE10 STREAM From memory
  *
  * PARAMS
  *     pStorage  [I] The Src IStorage to copy
@@ -6261,7 +6731,7 @@ void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD n
  *     Memory allocated for pData must be freed by the caller
  *
  *     Used by OleConvertIStorageToOLESTREAM only.
- *     
+ *
  */
 DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData)
 {
@@ -6270,10 +6740,10 @@ DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData)
     DWORD nDataLength = 0;
     IStorage *pTempStorage;
     WCHAR wstrTempDir[MAX_PATH], wstrTempFile[MAX_PATH];
-    WCHAR wstrPrefix[] = {'s', 'i', 's', 0};
+    static const WCHAR wstrPrefix[] = {'s', 'i', 's', 0};
 
     *pData = NULL;
-    
+
     /* Create temp Storage */
     GetTempPathW(MAX_PATH, wstrTempDir);
     GetTempFileNameW(wstrTempDir, wstrPrefix, 0, wstrTempFile);
@@ -6290,7 +6760,7 @@ DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData)
         if(hFile != INVALID_HANDLE_VALUE)
         {
             nDataLength = GetFileSize(hFile, NULL);
-            *pData = (BYTE *) HeapAlloc(GetProcessHeap(),0,nDataLength);
+            *pData = HeapAlloc(GetProcessHeap(),0,nDataLength);
             ReadFile(hFile, *pData, nDataLength, &nDataLength, 0);
             CloseHandle(hFile);
         }
@@ -6300,9 +6770,9 @@ DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData)
 }
 
 /*************************************************************************
- * OLECONVERT_CreateOleStream [Internal] 
+ * OLECONVERT_CreateOleStream [Internal]
  *
- * Creates the "\001OLE" stream in the IStorage if neccessary.
+ * Creates the "\001OLE" stream in the IStorage if necessary.
  *
  * PARAMS
  *     pStorage     [I] Dest storage to create the stream in
@@ -6315,24 +6785,24 @@ DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData)
  *
  *     This stream is still unknown, MS Word seems to have extra data
  *     but since the data is stored in the OLESTREAM there should be
- *     no need to recreate the stream.  If the stream is manually 
+ *     no need to recreate the stream.  If the stream is manually
  *     deleted it will create it with this default data.
- *     
+ *
  */
 void OLECONVERT_CreateOleStream(LPSTORAGE pStorage)
 {
     HRESULT hRes;
     IStream *pStream;
-    WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0};
-    BYTE pOleStreamHeader [] = 
+    static const WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0};
+    BYTE pOleStreamHeader [] =
     {
-        0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-        0x00, 0x00, 0x00, 0x00 
+        0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00
     };
-    
+
     /* Create stream if not present */
-    hRes = IStorage_CreateStream(pStorage, wstrStreamName, 
+    hRes = IStorage_CreateStream(pStorage, wstrStreamName,
         STGM_WRITE  | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream );
 
     if(hRes == S_OK)
@@ -6343,14 +6813,224 @@ void OLECONVERT_CreateOleStream(LPSTORAGE pStorage)
     }
 }
 
+/* write a string to a stream, preceded by its length */
+static HRESULT STREAM_WriteString( IStream *stm, LPCWSTR string )
+{
+    HRESULT r;
+    LPSTR str;
+    DWORD len = 0;
+
+    if( string )
+        len = WideCharToMultiByte( CP_ACP, 0, string, -1, NULL, 0, NULL, NULL);
+    r = IStream_Write( stm, &len, sizeof(len), NULL);
+    if( FAILED( r ) )
+        return r;
+    if(len == 0)
+        return r;
+    str = CoTaskMemAlloc( len );
+    WideCharToMultiByte( CP_ACP, 0, string, -1, str, len, NULL, NULL);
+    r = IStream_Write( stm, str, len, NULL);
+    CoTaskMemFree( str );
+    return r;
+}
+
+/* read a string preceded by its length from a stream */
+static HRESULT STREAM_ReadString( IStream *stm, LPWSTR *string )
+{
+    HRESULT r;
+    DWORD len, count = 0;
+    LPSTR str;
+    LPWSTR wstr;
+
+    r = IStream_Read( stm, &len, sizeof(len), &count );
+    if( FAILED( r ) )
+        return r;
+    if( count != sizeof(len) )
+        return E_OUTOFMEMORY;
+
+    TRACE("%ld bytes\n",len);
+    
+    str = CoTaskMemAlloc( len );
+    if( !str )
+        return E_OUTOFMEMORY;
+    count = 0;
+    r = IStream_Read( stm, str, len, &count );
+    if( FAILED( r ) )
+        return r;
+    if( count != len )
+    {
+        CoTaskMemFree( str );
+        return E_OUTOFMEMORY;
+    }
+
+    TRACE("Read string %s\n",debugstr_an(str,len));
+
+    len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
+    wstr = CoTaskMemAlloc( (len + 1)*sizeof (WCHAR) );
+    if( wstr )
+         MultiByteToWideChar( CP_ACP, 0, str, count, wstr, len );
+    CoTaskMemFree( str );
+
+    *string = wstr;
+
+    return r;
+}
+
+
+static HRESULT STORAGE_WriteCompObj( LPSTORAGE pstg, CLSID *clsid,
+    LPCWSTR lpszUserType, LPCWSTR szClipName, LPCWSTR szProgIDName )
+{
+    IStream *pstm;
+    HRESULT r = S_OK;
+    static const WCHAR szwStreamName[] = {1, 'C', 'o', 'm', 'p', 'O', 'b', 'j', 0};
+
+    static const BYTE unknown1[12] =
+       { 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+         0xFF, 0xFF, 0xFF, 0xFF};
+    static const BYTE unknown2[16] =
+       { 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+    TRACE("%p %s %s %s %s\n", pstg, debugstr_guid(clsid),
+           debugstr_w(lpszUserType), debugstr_w(szClipName),
+           debugstr_w(szProgIDName));
+
+    /*  Create a CompObj stream if it doesn't exist */
+    r = IStorage_CreateStream(pstg, szwStreamName,
+        STGM_WRITE  | STGM_SHARE_EXCLUSIVE, 0, 0, &pstm );
+    if( FAILED (r) )
+        return r;
+
+    /* Write CompObj Structure to stream */
+    r = IStream_Write(pstm, unknown1, sizeof(unknown1), NULL);
+
+    if( SUCCEEDED( r ) )
+        r = WriteClassStm( pstm, clsid );
+
+    if( SUCCEEDED( r ) )
+        r = STREAM_WriteString( pstm, lpszUserType );
+    if( SUCCEEDED( r ) )
+        r = STREAM_WriteString( pstm, szClipName );
+    if( SUCCEEDED( r ) )
+        r = STREAM_WriteString( pstm, szProgIDName );
+    if( SUCCEEDED( r ) )
+        r = IStream_Write(pstm, unknown2, sizeof(unknown2), NULL);
+
+    IStream_Release( pstm );
+
+    return r;
+}
+
+/***********************************************************************
+ *               WriteFmtUserTypeStg (OLE32.@)
+ */
+HRESULT WINAPI WriteFmtUserTypeStg(
+         LPSTORAGE pstg, CLIPFORMAT cf, LPOLESTR lpszUserType)
+{
+    HRESULT r;
+    WCHAR szwClipName[0x40];
+    CLSID clsid = CLSID_NULL;
+    LPWSTR wstrProgID = NULL;
+    DWORD n;
+
+    TRACE("(%p,%x,%s)\n",pstg,cf,debugstr_w(lpszUserType));
+
+    /* get the clipboard format name */
+    n = GetClipboardFormatNameW( cf, szwClipName, sizeof(szwClipName) );
+    szwClipName[n]=0;
+
+    TRACE("Clipboard name is %s\n", debugstr_w(szwClipName));
+
+    /* FIXME: There's room to save a CLSID and its ProgID, but
+       the CLSID is not looked up in the registry and in all the
+       tests I wrote it was CLSID_NULL.  Where does it come from?
+    */
+
+    /* get the real program ID.  This may fail, but that's fine */
+    ProgIDFromCLSID(&clsid, &wstrProgID);
+
+    TRACE("progid is %s\n",debugstr_w(wstrProgID));
+
+    r = STORAGE_WriteCompObj( pstg, &clsid, 
+                              lpszUserType, szwClipName, wstrProgID );
+
+    CoTaskMemFree(wstrProgID);
+
+    return r;
+}
+
+
+/******************************************************************************
+ *              ReadFmtUserTypeStg        [OLE32.@]
+ */
+HRESULT WINAPI ReadFmtUserTypeStg (LPSTORAGE pstg, CLIPFORMAT* pcf, LPOLESTR* lplpszUserType)
+{
+    HRESULT r;
+    IStream *stm = 0;
+    static const WCHAR szCompObj[] = { 1, 'C','o','m','p','O','b','j', 0 };
+    unsigned char unknown1[12];
+    unsigned char unknown2[16];
+    DWORD count;
+    LPWSTR szProgIDName = NULL, szCLSIDName = NULL, szOleTypeName = NULL;
+    CLSID clsid;
+
+    TRACE("(%p,%p,%p)\n", pstg, pcf, lplpszUserType);
+
+    r = IStorage_OpenStream( pstg, szCompObj, NULL, 
+                    STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm );
+    if( FAILED ( r ) )
+    {
+        WARN("Failed to open stream r = %08lx\n", r);
+        return r;
+    }
+
+    /* read the various parts of the structure */
+    r = IStream_Read( stm, unknown1, sizeof(unknown1), &count );
+    if( FAILED( r ) || ( count != sizeof(unknown1) ) )
+        goto end;
+    r = ReadClassStm( stm, &clsid );
+    if( FAILED( r ) )
+        goto end;
+
+    r = STREAM_ReadString( stm, &szCLSIDName );
+    if( FAILED( r ) )
+        goto end;
+
+    r = STREAM_ReadString( stm, &szOleTypeName );
+    if( FAILED( r ) )
+        goto end;
+
+    r = STREAM_ReadString( stm, &szProgIDName );
+    if( FAILED( r ) )
+        goto end;
+
+    r = IStream_Read( stm, unknown2, sizeof(unknown2), &count );
+    if( FAILED( r ) || ( count != sizeof(unknown2) ) )
+        goto end;
+
+    /* ok, success... now we just need to store what we found */
+    if( pcf )
+        *pcf = RegisterClipboardFormatW( szOleTypeName );
+    CoTaskMemFree( szOleTypeName );
+
+    if( lplpszUserType )
+        *lplpszUserType = szCLSIDName;
+    CoTaskMemFree( szProgIDName );
+
+end:
+    IStream_Release( stm );
+
+    return r;
+}
+
 
 /*************************************************************************
- * OLECONVERT_CreateCompObjStream [Internal] 
+ * OLECONVERT_CreateCompObjStream [Internal]
  *
  * Creates a "\001CompObj" is the destination IStorage if necessary.
  *
  * PARAMS
- *     pStorage       [I] The dest IStorage to create the CompObj Stream 
+ *     pStorage       [I] The dest IStorage to create the CompObj Stream
  *                        if necessary.
  *     strOleTypeName [I] The ProgID
  *
@@ -6362,17 +7042,18 @@ void OLECONVERT_CreateOleStream(LPSTORAGE pStorage)
  *     This function is used by OleConvertOLESTREAMToIStorage only.
  *
  *     The stream data is stored in the OLESTREAM and there should be
- *     no need to recreate the stream.  If the stream is manually 
+ *     no need to recreate the stream.  If the stream is manually
  *     deleted it will attempt to create it by querying the registry.
  *
- *     
+ *
  */
 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName)
 {
     IStream *pStream;
     HRESULT hStorageRes, hRes = S_OK;
     OLECONVERT_ISTORAGE_COMPOBJ IStorageCompObj;
-    WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0};
+    static const WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0};
+    WCHAR bufferW[OLESTREAM_MAX_STR_LEN];
 
     BYTE pCompObjUnknown1[] = {0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
     BYTE pCompObjUnknown2[] = {0xF4, 0x39, 0xB2, 0x71};
@@ -6384,7 +7065,7 @@ HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName
 
 
     /*  Create a CompObj stream if it doesn't exist */
-    hStorageRes = IStorage_CreateStream(pStorage, wstrStreamName, 
+    hStorageRes = IStorage_CreateStream(pStorage, wstrStreamName,
         STGM_WRITE  | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream );
     if(hStorageRes == S_OK)
     {
@@ -6393,23 +7074,21 @@ HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName
         strcpy(IStorageCompObj.strOleTypeName, strOleTypeName);
 
         /* copy the OleTypeName to the compobj struct */
-        /* Note: in the test made, these where Identical      */
+        /* Note: in the test made, these were Identical      */
         IStorageCompObj.dwProgIDNameLength = strlen(strOleTypeName)+1;
         strcpy(IStorageCompObj.strProgIDName, strOleTypeName);
 
         /* Get the CLSID */
-        hRes = CLSIDFromProgID16(IStorageCompObj.strProgIDName, &(IStorageCompObj.clsid));
+        MultiByteToWideChar( CP_ACP, 0, IStorageCompObj.strProgIDName, -1,
+                             bufferW, OLESTREAM_MAX_STR_LEN );
+        hRes = CLSIDFromProgID(bufferW, &(IStorageCompObj.clsid));
 
-        if(hRes != S_OK)
-        {
-            hRes = REGDB_E_CLASSNOTREG;
-        }
-        else
+        if(hRes == S_OK)
         {
             HKEY hKey;
             LONG hErr;
             /* Get the CLSID Default Name from the Registry */
-            hErr = RegOpenKeyA(HKEY_CLASSES_ROOT, IStorageCompObj.strProgIDName, &hKey); 
+            hErr = RegOpenKeyA(HKEY_CLASSES_ROOT, IStorageCompObj.strProgIDName, &hKey);
             if(hErr == ERROR_SUCCESS)
             {
                 char strTemp[OLESTREAM_MAX_STR_LEN];
@@ -6421,34 +7100,29 @@ HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName
                 }
                 RegCloseKey(hKey);
             }
-            if(hErr != ERROR_SUCCESS)
-            {
-                hRes = REGDB_E_CLASSNOTREG;
-            }
         }
 
-        if(hRes == S_OK )
+        /* Write CompObj Structure to stream */
+        hRes = IStream_Write(pStream, IStorageCompObj.byUnknown1, sizeof(IStorageCompObj.byUnknown1), NULL);
+
+        WriteClassStm(pStream,&(IStorageCompObj.clsid));
+
+        hRes = IStream_Write(pStream, &(IStorageCompObj.dwCLSIDNameLength), sizeof(IStorageCompObj.dwCLSIDNameLength), NULL);
+        if(IStorageCompObj.dwCLSIDNameLength > 0)
         {
-            /* Write CompObj Structure to stream */
-            hRes = IStream_Write(pStream, IStorageCompObj.byUnknown1, sizeof(IStorageCompObj.byUnknown1), NULL);
-            hRes = IStream_Write(pStream, &(IStorageCompObj.clsid) , sizeof(IStorageCompObj.clsid ), NULL);
-            hRes = IStream_Write(pStream, &(IStorageCompObj.dwCLSIDNameLength), sizeof(IStorageCompObj.dwCLSIDNameLength), NULL);
-            if(IStorageCompObj.dwCLSIDNameLength > 0)
-            {
-                hRes = IStream_Write(pStream, IStorageCompObj.strCLSIDName, IStorageCompObj.dwCLSIDNameLength, NULL);
-            }
-            hRes = IStream_Write(pStream, &(IStorageCompObj.dwOleTypeNameLength) , sizeof(IStorageCompObj.dwOleTypeNameLength), NULL);
-            if(IStorageCompObj.dwOleTypeNameLength > 0)
-            {
-                hRes = IStream_Write(pStream, IStorageCompObj.strOleTypeName , IStorageCompObj.dwOleTypeNameLength, NULL);
-            }
-            hRes = IStream_Write(pStream, &(IStorageCompObj.dwProgIDNameLength) , sizeof(IStorageCompObj.dwProgIDNameLength), NULL);
-            if(IStorageCompObj.dwProgIDNameLength > 0)
-            {
-                hRes = IStream_Write(pStream, IStorageCompObj.strProgIDName , IStorageCompObj.dwProgIDNameLength, NULL);
-            }
-            hRes = IStream_Write(pStream, IStorageCompObj.byUnknown2 , sizeof(IStorageCompObj.byUnknown2), NULL);
+            hRes = IStream_Write(pStream, IStorageCompObj.strCLSIDName, IStorageCompObj.dwCLSIDNameLength, NULL);
+        }
+        hRes = IStream_Write(pStream, &(IStorageCompObj.dwOleTypeNameLength) , sizeof(IStorageCompObj.dwOleTypeNameLength), NULL);
+        if(IStorageCompObj.dwOleTypeNameLength > 0)
+        {
+            hRes = IStream_Write(pStream, IStorageCompObj.strOleTypeName , IStorageCompObj.dwOleTypeNameLength, NULL);
+        }
+        hRes = IStream_Write(pStream, &(IStorageCompObj.dwProgIDNameLength) , sizeof(IStorageCompObj.dwProgIDNameLength), NULL);
+        if(IStorageCompObj.dwProgIDNameLength > 0)
+        {
+            hRes = IStream_Write(pStream, IStorageCompObj.strProgIDName , IStorageCompObj.dwProgIDNameLength, NULL);
         }
+        hRes = IStream_Write(pStream, IStorageCompObj.byUnknown2 , sizeof(IStorageCompObj.byUnknown2), NULL);
         IStream_Release(pStream);
     }
     return hRes;
@@ -6456,14 +7130,14 @@ HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName
 
 
 /*************************************************************************
- * OLECONVERT_CreateOlePresStream[Internal] 
+ * OLECONVERT_CreateOlePresStream[Internal]
  *
  * Creates the "\002OlePres000" Stream with the Metafile data
  *
  * PARAMS
  *     pStorage     [I] The dest IStorage to create \002OLEPres000 stream in.
  *     dwExtentX    [I] Width of the Metafile
- *     dwExtentY    [I] Height of the Metafile 
+ *     dwExtentY    [I] Height of the Metafile
  *     pData        [I] Metafile data
  *     dwDataLength [I] Size of the Metafile data
  *
@@ -6473,31 +7147,31 @@ HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName
  *
  * NOTES
  *     This function is used by OleConvertOLESTREAMToIStorage only.
- *     
+ *
  */
 void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX, DWORD dwExtentY , BYTE *pData, DWORD dwDataLength)
 {
     HRESULT hRes;
     IStream *pStream;
-    WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
-    BYTE pOlePresStreamHeader [] = 
+    static const WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
+    BYTE pOlePresStreamHeader [] =
     {
-        0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 
-        0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+        0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+        0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
         0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00
     };
 
-    BYTE pOlePresStreamHeaderEmpty [] = 
+    BYTE pOlePresStreamHeaderEmpty [] =
     {
-        0x00, 0x00, 0x00, 0x00, 
-        0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+        0x00, 0x00, 0x00, 0x00,
+        0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
         0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00
     };
-     
+
     /* Create the OlePres000 Stream */
-    hRes = IStorage_CreateStream(pStorage, wstrStreamName, 
+    hRes = IStorage_CreateStream(pStorage, wstrStreamName,
         STGM_CREATE | STGM_WRITE  | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream );
 
     if(hRes == S_OK)
@@ -6521,7 +7195,7 @@ void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX, DWORD d
         OlePres.dwExtentX = dwExtentX;
         OlePres.dwExtentY = -dwExtentY;
 
-        /* Set Data and Lenght */
+        /* Set Data and Length */
         if(dwDataLength > sizeof(METAFILEPICT16))
         {
             OlePres.dwSize = dwDataLength - sizeof(METAFILEPICT16);
@@ -6541,7 +7215,7 @@ void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX, DWORD d
 }
 
 /*************************************************************************
- * OLECONVERT_CreateOle10NativeStream [Internal] 
+ * OLECONVERT_CreateOle10NativeStream [Internal]
  *
  * Creates the "\001Ole10Native" Stream (should contain a BMP)
  *
@@ -6557,16 +7231,16 @@ void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX, DWORD d
  *     This function is used by OleConvertOLESTREAMToIStorage only.
  *
  *     Might need to verify the data and return appropriate error message
- *     
+ *
  */
 void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, BYTE *pData, DWORD dwDataLength)
 {
     HRESULT hRes;
     IStream *pStream;
-    WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0};
-    
+    static const WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0};
+
     /* Create the Ole10Native Stream */
-    hRes = IStorage_CreateStream(pStorage, wstrStreamName, 
+    hRes = IStorage_CreateStream(pStorage, wstrStreamName,
         STGM_CREATE | STGM_WRITE  | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream );
 
     if(hRes == S_OK)
@@ -6580,7 +7254,7 @@ void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, BYTE *pData, DWORD d
 }
 
 /*************************************************************************
- * OLECONVERT_GetOLE10ProgID [Internal] 
+ * OLECONVERT_GetOLE10ProgID [Internal]
  *
  * Finds the ProgID (or OleTypeID) from the IStorage
  *
@@ -6596,7 +7270,7 @@ void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, BYTE *pData, DWORD d
  * NOTES
  *     This function is used by OleConvertIStorageToOLESTREAM only.
  *
- *     
+ *
  */
 HRESULT OLECONVERT_GetOLE10ProgID(LPSTORAGE pStorage, char *strProgID, DWORD *dwSize)
 {
@@ -6604,24 +7278,24 @@ HRESULT OLECONVERT_GetOLE10ProgID(LPSTORAGE pStorage, char *strProgID, DWORD *dw
     IStream *pStream;
     LARGE_INTEGER iSeekPos;
     OLECONVERT_ISTORAGE_COMPOBJ CompObj;
-    WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0};
+    static const WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0};
 
     /* Open the CompObj Stream */
-    hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL,  
+    hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL,
         STGM_READ  | STGM_SHARE_EXCLUSIVE, 0, &pStream );
     if(hRes == S_OK)
     {
 
         /*Get the OleType from the CompObj Stream */
-        iSeekPos.s.LowPart = sizeof(CompObj.byUnknown1) + sizeof(CompObj.clsid);
-        iSeekPos.s.HighPart = 0;
+        iSeekPos.u.LowPart = sizeof(CompObj.byUnknown1) + sizeof(CompObj.clsid);
+        iSeekPos.u.HighPart = 0;
 
         IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL);
         IStream_Read(pStream, &CompObj.dwCLSIDNameLength, sizeof(CompObj.dwCLSIDNameLength), NULL);
-        iSeekPos.s.LowPart = CompObj.dwCLSIDNameLength;
+        iSeekPos.u.LowPart = CompObj.dwCLSIDNameLength;
         IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR , NULL);
         IStream_Read(pStream, &CompObj.dwOleTypeNameLength, sizeof(CompObj.dwOleTypeNameLength), NULL);
-        iSeekPos.s.LowPart = CompObj.dwOleTypeNameLength;
+        iSeekPos.u.LowPart = CompObj.dwOleTypeNameLength;
         IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR , NULL);
 
         IStream_Read(pStream, dwSize, sizeof(*dwSize), NULL);
@@ -6644,13 +7318,13 @@ HRESULT OLECONVERT_GetOLE10ProgID(LPSTORAGE pStorage, char *strProgID, DWORD *dw
         {
             *dwSize = WideCharToMultiByte(CP_ACP, 0, wstrProgID, -1, strProgID, *dwSize, NULL, FALSE);
         }
+
     }
     return hRes;
 }
 
 /*************************************************************************
- * OLECONVERT_GetOle10PresData [Internal] 
+ * OLECONVERT_GetOle10PresData [Internal]
  *
  * Converts IStorage "/001Ole10Native" stream to a OLE10 Stream
  *
@@ -6665,15 +7339,15 @@ HRESULT OLECONVERT_GetOLE10ProgID(LPSTORAGE pStorage, char *strProgID, DWORD *dw
  *     This function is used by OleConvertIStorageToOLESTREAM only.
  *
  *     Memory allocated for pData must be freed by the caller
- *      
- *     
+ *
+ *
  */
 void OLECONVERT_GetOle10PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData)
 {
 
     HRESULT hRes;
     IStream *pStream;
-    WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0};
+    static const WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0};
 
     /* Initialize Default data for OLESTREAM */
     pOleStreamData[0].dwOleID = OLESTREAM_ID;
@@ -6686,7 +7360,7 @@ void OLECONVERT_GetOle10PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
     pOleStreamData[1].pData = NULL;
 
     /* Open Ole10Native Stream */
-    hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL,  
+    hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL,
         STGM_READ  | STGM_SHARE_EXCLUSIVE, 0, &pStream );
     if(hRes == S_OK)
     {
@@ -6695,7 +7369,7 @@ void OLECONVERT_GetOle10PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
         IStream_Read(pStream, &(pOleStreamData->dwDataLength), sizeof(pOleStreamData->dwDataLength), NULL);
         if(pOleStreamData->dwDataLength > 0)
         {
-            pOleStreamData->pData = (LPSTR) HeapAlloc(GetProcessHeap(),0,pOleStreamData->dwDataLength);
+            pOleStreamData->pData = HeapAlloc(GetProcessHeap(),0,pOleStreamData->dwDataLength);
             IStream_Read(pStream, pOleStreamData->pData, pOleStreamData->dwDataLength, NULL);
         }
         IStream_Release(pStream);
@@ -6705,7 +7379,7 @@ void OLECONVERT_GetOle10PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
 
 
 /*************************************************************************
- * OLECONVERT_GetOle20PresData[Internal] 
+ * OLECONVERT_GetOle20PresData[Internal]
  *
  * Converts IStorage "/002OlePres000" stream to a OLE10 Stream
  *
@@ -6718,7 +7392,7 @@ void OLECONVERT_GetOle10PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
  *
  * NOTES
  *     This function is used by OleConvertIStorageToOLESTREAM only.
- *     
+ *
  *     Memory allocated for pData must be freed by the caller
  */
 void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData)
@@ -6726,7 +7400,7 @@ void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
     HRESULT hRes;
     IStream *pStream;
     OLECONVERT_ISTORAGE_OLEPRES olePress;
-    WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
+    static const WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
 
     /* Initialize Default data for OLESTREAM */
     pOleStreamData[0].dwOleID = OLESTREAM_ID;
@@ -6745,13 +7419,13 @@ void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
 
 
     /* Open OlePress000 stream */
-    hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL,  
+    hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL,
         STGM_READ  | STGM_SHARE_EXCLUSIVE, 0, &pStream );
     if(hRes == S_OK)
     {
         LARGE_INTEGER iSeekPos;
         METAFILEPICT16 MetaFilePict;
-        char strMetafilePictName[] = "METAFILEPICT";
+        static const char strMetafilePictName[] = "METAFILEPICT";
 
         /* Set the TypeID for a Metafile */
         pOleStreamData[1].dwTypeID = 5;
@@ -6760,8 +7434,8 @@ void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
         pOleStreamData[1].dwOleTypeNameLength = strlen(strMetafilePictName) +1;
         strcpy(pOleStreamData[1].strOleTypeName, strMetafilePictName);
 
-        iSeekPos.s.HighPart = 0;
-        iSeekPos.s.LowPart = sizeof(olePress.byUnknown1);
+        iSeekPos.u.HighPart = 0;
+        iSeekPos.u.LowPart = sizeof(olePress.byUnknown1);
 
         /* Get Presentation Data */
         IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL);
@@ -6784,7 +7458,7 @@ void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
             MetaFilePict.hMF = 0;
 
             /* Get Metafile Data */
-            pOleStreamData[1].pData = (BYTE *) HeapAlloc(GetProcessHeap(),0,pOleStreamData[1].dwDataLength);
+            pOleStreamData[1].pData = HeapAlloc(GetProcessHeap(),0,pOleStreamData[1].dwDataLength);
             memcpy(pOleStreamData[1].pData, &MetaFilePict, sizeof(MetaFilePict));
             IStream_Read(pStream, &(pOleStreamData[1].pData[sizeof(MetaFilePict)]), pOleStreamData[1].dwDataLength-sizeof(METAFILEPICT16), NULL);
         }
@@ -6793,7 +7467,7 @@ void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
 }
 
 /*************************************************************************
- * OleConvertOLESTREAMToIStorage [OLE32.87] 
+ * OleConvertOLESTREAMToIStorage [OLE32.@]
  *
  * Read info on MSDN
  *
@@ -6802,11 +7476,11 @@ void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *
  *      Still unsure of some mem fields for OLE 10 Stream
  *      Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj",
  *      and "\001OLE" streams
- *     
+ *
  */
 HRESULT WINAPI OleConvertOLESTREAMToIStorage (
-    LPOLESTREAM pOleStream, 
-    LPSTORAGE pstg, 
+    LPOLESTREAM pOleStream,
+    LPSTORAGE pstg,
     const DVTARGETDEVICE* ptd)
 {
     int i;
@@ -6873,21 +7547,15 @@ HRESULT WINAPI OleConvertOLESTREAMToIStorage (
     /* Free allocated memory */
     for(i=0; i < 2; i++)
     {
-        if(pOleStreamData[i].pData != NULL)
-        {
-            HeapFree(GetProcessHeap(),0,pOleStreamData[i].pData);
-        }
-        if(pOleStreamData[i].pstrOleObjFileName != NULL)
-       {
-               HeapFree(GetProcessHeap(),0,pOleStreamData[i].pstrOleObjFileName);
-               pOleStreamData[i].pstrOleObjFileName = NULL;
-       }
+        HeapFree(GetProcessHeap(),0,pOleStreamData[i].pData);
+        HeapFree(GetProcessHeap(),0,pOleStreamData[i].pstrOleObjFileName);
+        pOleStreamData[i].pstrOleObjFileName = NULL;
     }
     return hRes;
 }
 
 /*************************************************************************
- * OleConvertIStorageToOLESTREAM [OLE32.85]
+ * OleConvertIStorageToOLESTREAM [OLE32.@]
  *
  * Read info on MSDN
  *
@@ -6897,17 +7565,17 @@ HRESULT WINAPI OleConvertOLESTREAMToIStorage (
  *      Still unsure of some mem fields for OLE 10 Stream
  *      Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj",
  *      and "\001OLE" streams.
- *     
+ *
  */
 HRESULT WINAPI OleConvertIStorageToOLESTREAM (
-    LPSTORAGE pstg, 
+    LPSTORAGE pstg,
     LPOLESTREAM pOleStream)
 {
     int i;
     HRESULT hRes = S_OK;
     IStream *pStream;
     OLECONVERT_OLESTREAM_DATA pOleStreamData[2];
-    WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0};
+    static const WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0};
 
 
     memset(pOleStreamData, 0, sizeof(pOleStreamData));
@@ -6924,17 +7592,17 @@ HRESULT WINAPI OleConvertIStorageToOLESTREAM (
     }
     if(hRes == S_OK)
     {
-        /*Was it originaly Ole10 */
-        hRes = IStorage_OpenStream(pstg, wstrStreamName, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);    
+        /* Was it originally Ole10 */
+        hRes = IStorage_OpenStream(pstg, wstrStreamName, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);
         if(hRes == S_OK)
         {
             IStream_Release(pStream);
-            /*Get Presentation Data for Ole10Native */
+            /* Get Presentation Data for Ole10Native */
             OLECONVERT_GetOle10PresData(pstg, pOleStreamData);
         }
         else
         {
-            /*Get Presentation Data (OLE20)*/
+            /* Get Presentation Data (OLE20) */
             OLECONVERT_GetOle20PresData(pstg, pOleStreamData);
         }
 
@@ -6950,11 +7618,57 @@ HRESULT WINAPI OleConvertIStorageToOLESTREAM (
     /* Free allocated memory */
     for(i=0; i < 2; i++)
     {
-        if(pOleStreamData[i].pData != NULL)
-        {
-            HeapFree(GetProcessHeap(),0,pOleStreamData[i].pData);
-        }
+        HeapFree(GetProcessHeap(),0,pOleStreamData[i].pData);
     }
 
     return hRes;
 }
+
+/***********************************************************************
+ *             GetConvertStg (OLE32.@)
+ */
+HRESULT WINAPI GetConvertStg(IStorage *stg) {
+    FIXME("unimplemented stub!\n");
+    return E_FAIL;
+}
+
+/******************************************************************************
+ * StgIsStorageFile [OLE32.@]
+ */
+HRESULT WINAPI
+StgIsStorageFile(LPCOLESTR fn)
+{
+       HANDLE          hf;
+       BYTE            magic[8];
+       DWORD           bytes_read;
+
+       TRACE("(\'%s\')\n", debugstr_w(fn));
+       hf = CreateFileW(fn, GENERIC_READ,
+                        FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+       if (hf == INVALID_HANDLE_VALUE)
+               return STG_E_FILENOTFOUND;
+
+       if (!ReadFile(hf, magic, 8, &bytes_read, NULL))
+       {
+               WARN(" unable to read file\n");
+               CloseHandle(hf);
+               return S_FALSE;
+       }
+
+       CloseHandle(hf);
+
+       if (bytes_read != 8) {
+               WARN(" too short\n");
+               return S_FALSE;
+       }
+
+       if (!memcmp(magic,STORAGE_magic,8)) {
+               WARN(" -> YES\n");
+               return S_OK;
+       }
+
+       WARN(" -> Invalid header.\n");
+       return S_FALSE;
+}