ole32: Use ILockBytes_Stat to get the filename of a storage.
diff --git a/dlls/ole32/filelockbytes.c b/dlls/ole32/filelockbytes.c
index 2491a82..29bd1b1 100644
--- a/dlls/ole32/filelockbytes.c
+++ b/dlls/ole32/filelockbytes.c
@@ -41,6 +41,7 @@
 #include "storage32.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(storage);
 
@@ -51,6 +52,7 @@
     ULARGE_INTEGER filesize;
     HANDLE hfile;
     DWORD flProtect;
+    LPWSTR pwcsName;
 } FileLockBytesImpl;
 
 static const ILockBytesVtbl FileLockBytesImpl_Vtbl;
@@ -85,9 +87,10 @@
  *
  * Initialize a big block object supported by a file.
  */
-HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, ILockBytes **pLockBytes)
+HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes)
 {
   FileLockBytesImpl *This;
+  WCHAR fullpath[MAX_PATH];
 
   if (hFile == INVALID_HANDLE_VALUE)
     return E_FAIL;
@@ -104,6 +107,23 @@
 					 &This->filesize.u.HighPart);
   This->flProtect = GetProtectMode(openFlags);
 
+  if(pwcsName) {
+    if (!GetFullPathNameW(pwcsName, MAX_PATH, fullpath, NULL))
+    {
+      lstrcpynW(fullpath, pwcsName, MAX_PATH);
+    }
+    This->pwcsName = HeapAlloc(GetProcessHeap(), 0,
+                              (lstrlenW(fullpath)+1)*sizeof(WCHAR));
+    if (!This->pwcsName)
+    {
+       HeapFree(GetProcessHeap(), 0, This);
+       return E_OUTOFMEMORY;
+    }
+    strcpyW(This->pwcsName, fullpath);
+  }
+  else
+    This->pwcsName = NULL;
+
   TRACE("file len %u\n", This->filesize.u.LowPart);
 
   *pLockBytes = (ILockBytes*)This;
@@ -145,6 +165,7 @@
     if (ref == 0)
     {
         CloseHandle(This->hfile);
+        HeapFree(GetProcessHeap(), 0, This->pwcsName);
         HeapFree(GetProcessHeap(), 0, This);
     }
 
@@ -324,12 +345,16 @@
 {
     FileLockBytesImpl* This = (FileLockBytesImpl*)iface;
 
-    if (!(STATFLAG_NONAME & grfStatFlag))
+    if (!(STATFLAG_NONAME & grfStatFlag) && This->pwcsName)
     {
-        FIXME("reading filename not supported\n");
-    }
+        pstatstg->pwcsName =
+          CoTaskMemAlloc((lstrlenW(This->pwcsName)+1)*sizeof(WCHAR));
 
-    pstatstg->pwcsName = NULL;
+        strcpyW(pstatstg->pwcsName, This->pwcsName);
+    }
+    else
+        pstatstg->pwcsName = NULL;
+
     pstatstg->type = STGTY_LOCKBYTES;
     pstatstg->cbSize = This->filesize;
     /* FIXME: If the implementation is exported, we'll need to set other fields. */
diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index 860f130..0eefb09 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -2583,6 +2583,19 @@
   return hr;
 }
 
+static HRESULT StorageImpl_GetFilename(StorageBaseImpl* iface, LPWSTR *result)
+{
+  StorageImpl *This = (StorageImpl*) iface;
+  STATSTG statstg;
+  HRESULT hr;
+
+  hr = ILockBytes_Stat(This->lockBytes, &statstg, 0);
+
+  *result = statstg.pwcsName;
+
+  return hr;
+}
+
 /*
  * Virtual function table for the IStorage32Impl class.
  */
@@ -2612,6 +2625,7 @@
 {
   StorageImpl_Destroy,
   StorageImpl_Invalidate,
+  StorageImpl_GetFilename,
   StorageImpl_CreateDirEntry,
   StorageImpl_BaseWriteDirEntry,
   StorageImpl_BaseReadDirEntry,
@@ -2636,7 +2650,6 @@
   HRESULT     hr = S_OK;
   DirEntry currentEntry;
   DirRef      currentEntryRef;
-  WCHAR fullpath[MAX_PATH];
 
   if ( FAILED( validateSTGM(openFlags) ))
     return STG_E_INVALIDFLAG;
@@ -2662,29 +2675,13 @@
 
   This->hFile = hFile;
 
-  if(pwcsName) {
-      if (!GetFullPathNameW(pwcsName, MAX_PATH, fullpath, NULL))
-      {
-        lstrcpynW(fullpath, pwcsName, MAX_PATH);
-      }
-      This->pwcsName = HeapAlloc(GetProcessHeap(), 0,
-                                (lstrlenW(fullpath)+1)*sizeof(WCHAR));
-      if (!This->pwcsName)
-      {
-         hr = STG_E_INSUFFICIENTMEMORY;
-         goto end;
-      }
-      strcpyW(This->pwcsName, fullpath);
-      This->base.filename = This->pwcsName;
-  }
-
   /*
    * Initialize the big block cache.
    */
   This->bigBlockSize   = sector_size;
   This->smallBlockSize = DEF_SMALL_BLOCK_SIZE;
   if (hFile)
-    hr = FileLockBytesImpl_Construct(hFile, openFlags, &This->lockBytes);
+    hr = FileLockBytesImpl_Construct(hFile, openFlags, pwcsName, &This->lockBytes);
   else
   {
     This->lockBytes = pLkbyt;
@@ -2875,8 +2872,6 @@
 
   StorageImpl_Invalidate(iface);
 
-  HeapFree(GetProcessHeap(), 0, This->pwcsName);
-
   BlockChainStream_Destroy(This->smallBlockRootChain);
   BlockChainStream_Destroy(This->rootBlockChain);
   BlockChainStream_Destroy(This->smallBlockDepotChain);
@@ -4649,6 +4644,13 @@
   HeapFree(GetProcessHeap(), 0, This);
 }
 
+static HRESULT TransactedSnapshotImpl_GetFilename(StorageBaseImpl* iface, LPWSTR *result)
+{
+  TransactedSnapshotImpl* This = (TransactedSnapshotImpl*) iface;
+
+  return StorageBaseImpl_GetFilename(This->transactedParent, result);
+}
+
 static HRESULT TransactedSnapshotImpl_CreateDirEntry(StorageBaseImpl *base,
   const DirEntry *newData, DirRef *index)
 {
@@ -4896,6 +4898,7 @@
 {
   TransactedSnapshotImpl_Destroy,
   TransactedSnapshotImpl_Invalidate,
+  TransactedSnapshotImpl_GetFilename,
   TransactedSnapshotImpl_CreateDirEntry,
   TransactedSnapshotImpl_WriteDirEntry,
   TransactedSnapshotImpl_ReadDirEntry,
@@ -4929,8 +4932,6 @@
 
     (*result)->base.openFlags = parentStorage->openFlags;
 
-    (*result)->base.filename = parentStorage->filename;
-
     /* Create a new temporary storage to act as the scratch file. */
     hr = StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE,
         0, (IStorage**)&(*result)->scratch);
@@ -5043,6 +5044,13 @@
   HeapFree(GetProcessHeap(), 0, This);
 }
 
+static HRESULT StorageInternalImpl_GetFilename(StorageBaseImpl* iface, LPWSTR *result)
+{
+  StorageInternalImpl* This = (StorageInternalImpl*) iface;
+
+  return StorageBaseImpl_GetFilename(This->parentStorage, result);
+}
+
 static HRESULT StorageInternalImpl_CreateDirEntry(StorageBaseImpl *base,
   const DirEntry *newData, DirRef *index)
 {
@@ -5468,6 +5476,7 @@
 {
   StorageInternalImpl_Destroy,
   StorageInternalImpl_Invalidate,
+  StorageInternalImpl_GetFilename,
   StorageInternalImpl_CreateDirEntry,
   StorageInternalImpl_WriteDirEntry,
   StorageInternalImpl_ReadDirEntry,
@@ -5608,33 +5617,26 @@
   const DirEntry*       source,
   int                   statFlags)
 {
-  LPCWSTR entryName;
-
-  if (source->stgType == STGTY_ROOT)
-  {
-    /* replace the name of root entry (often "Root Entry") by the file name */
-    entryName = storage->filename;
-  }
-  else
-  {
-    entryName = source->name;
-  }
-
   /*
    * The copy of the string occurs only when the flag is not set
    */
-  if( ((statFlags & STATFLAG_NONAME) != 0) || 
-       (entryName == NULL) ||
-       (entryName[0] == 0) )
+  if (!(statFlags & STATFLAG_NONAME) && source->stgType == STGTY_ROOT)
+  {
+    /* Use the filename for the root storage. */
+    destination->pwcsName = 0;
+    StorageBaseImpl_GetFilename(storage, &destination->pwcsName);
+  }
+  else if( ((statFlags & STATFLAG_NONAME) != 0) ||
+       (source->name[0] == 0) )
   {
     destination->pwcsName = 0;
   }
   else
   {
     destination->pwcsName =
-      CoTaskMemAlloc((lstrlenW(entryName)+1)*sizeof(WCHAR));
+      CoTaskMemAlloc((lstrlenW(source->name)+1)*sizeof(WCHAR));
 
-    strcpyW(destination->pwcsName, entryName);
+    strcpyW(destination->pwcsName, source->name);
   }
 
   switch (source->stgType)
diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h
index 335b4bc..7f0a6d5 100644
--- a/dlls/ole32/storage32.h
+++ b/dlls/ole32/storage32.h
@@ -154,7 +154,7 @@
   ULARGE_INTEGER size;
 };
 
-HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, ILockBytes **pLockBytes);
+HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes);
 
 /*************************************************************************
  * Ole Convert support
@@ -221,9 +221,6 @@
    */
   DWORD stateBits;
 
-  /* If set, this overrides the root storage name returned by IStorage_Stat */
-  LPCWSTR          filename;
-
   BOOL             create;     /* Was the storage created or opened.
                                   The behaviour of STGM_SIMPLE depends on this */
   /*
@@ -237,6 +234,7 @@
 struct StorageBaseImplVtbl {
   void (*Destroy)(StorageBaseImpl*);
   void (*Invalidate)(StorageBaseImpl*);
+  HRESULT (*GetFilename)(StorageBaseImpl*,LPWSTR*);
   HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*);
   HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*);
   HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*);
@@ -257,6 +255,11 @@
   This->baseVtbl->Invalidate(This);
 }
 
+static inline HRESULT StorageBaseImpl_GetFilename(StorageBaseImpl *This, LPWSTR *result)
+{
+  return This->baseVtbl->GetFilename(This, result);
+}
+
 static inline HRESULT StorageBaseImpl_CreateDirEntry(StorageBaseImpl *This,
   const DirEntry *newData, DirRef *index)
 {
@@ -337,7 +340,6 @@
    * class
    */
   HANDLE           hFile;      /* Physical support for the Docfile */
-  LPOLESTR         pwcsName;   /* Full path of the document file */
 
   /*
    * File header