ole32: Use ILockBytes_Stat to get the filename of a storage.

This commit is contained in:
Vincent Povirk 2010-07-17 13:00:17 -05:00 committed by Alexandre Julliard
parent 14f8f9d5b5
commit d0e6e4aa82
3 changed files with 78 additions and 49 deletions

View File

@ -41,6 +41,7 @@
#include "storage32.h" #include "storage32.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage); WINE_DEFAULT_DEBUG_CHANNEL(storage);
@ -51,6 +52,7 @@ typedef struct FileLockBytesImpl
ULARGE_INTEGER filesize; ULARGE_INTEGER filesize;
HANDLE hfile; HANDLE hfile;
DWORD flProtect; DWORD flProtect;
LPWSTR pwcsName;
} FileLockBytesImpl; } FileLockBytesImpl;
static const ILockBytesVtbl FileLockBytesImpl_Vtbl; static const ILockBytesVtbl FileLockBytesImpl_Vtbl;
@ -85,9 +87,10 @@ static DWORD GetProtectMode(DWORD openFlags)
* *
* Initialize a big block object supported by a file. * 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; FileLockBytesImpl *This;
WCHAR fullpath[MAX_PATH];
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
return E_FAIL; return E_FAIL;
@ -104,6 +107,23 @@ HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, ILockBytes **
&This->filesize.u.HighPart); &This->filesize.u.HighPart);
This->flProtect = GetProtectMode(openFlags); 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); TRACE("file len %u\n", This->filesize.u.LowPart);
*pLockBytes = (ILockBytes*)This; *pLockBytes = (ILockBytes*)This;
@ -145,6 +165,7 @@ static ULONG WINAPI FileLockBytesImpl_Release(ILockBytes *iface)
if (ref == 0) if (ref == 0)
{ {
CloseHandle(This->hfile); CloseHandle(This->hfile);
HeapFree(GetProcessHeap(), 0, This->pwcsName);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
@ -324,12 +345,16 @@ static HRESULT WINAPI FileLockBytesImpl_Stat(ILockBytes* iface,
{ {
FileLockBytesImpl* This = (FileLockBytesImpl*)iface; 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));
strcpyW(pstatstg->pwcsName, This->pwcsName);
}
else
pstatstg->pwcsName = NULL;
pstatstg->pwcsName = NULL;
pstatstg->type = STGTY_LOCKBYTES; pstatstg->type = STGTY_LOCKBYTES;
pstatstg->cbSize = This->filesize; pstatstg->cbSize = This->filesize;
/* FIXME: If the implementation is exported, we'll need to set other fields. */ /* FIXME: If the implementation is exported, we'll need to set other fields. */

View File

@ -2583,6 +2583,19 @@ static HRESULT StorageImpl_StreamLink(StorageBaseImpl *base, DirRef dst,
return hr; 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. * Virtual function table for the IStorage32Impl class.
*/ */
@ -2612,6 +2625,7 @@ static const StorageBaseImplVtbl StorageImpl_BaseVtbl =
{ {
StorageImpl_Destroy, StorageImpl_Destroy,
StorageImpl_Invalidate, StorageImpl_Invalidate,
StorageImpl_GetFilename,
StorageImpl_CreateDirEntry, StorageImpl_CreateDirEntry,
StorageImpl_BaseWriteDirEntry, StorageImpl_BaseWriteDirEntry,
StorageImpl_BaseReadDirEntry, StorageImpl_BaseReadDirEntry,
@ -2636,7 +2650,6 @@ static HRESULT StorageImpl_Construct(
HRESULT hr = S_OK; HRESULT hr = S_OK;
DirEntry currentEntry; DirEntry currentEntry;
DirRef currentEntryRef; DirRef currentEntryRef;
WCHAR fullpath[MAX_PATH];
if ( FAILED( validateSTGM(openFlags) )) if ( FAILED( validateSTGM(openFlags) ))
return STG_E_INVALIDFLAG; return STG_E_INVALIDFLAG;
@ -2662,29 +2675,13 @@ static HRESULT StorageImpl_Construct(
This->hFile = hFile; 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. * Initialize the big block cache.
*/ */
This->bigBlockSize = sector_size; This->bigBlockSize = sector_size;
This->smallBlockSize = DEF_SMALL_BLOCK_SIZE; This->smallBlockSize = DEF_SMALL_BLOCK_SIZE;
if (hFile) if (hFile)
hr = FileLockBytesImpl_Construct(hFile, openFlags, &This->lockBytes); hr = FileLockBytesImpl_Construct(hFile, openFlags, pwcsName, &This->lockBytes);
else else
{ {
This->lockBytes = pLkbyt; This->lockBytes = pLkbyt;
@ -2875,8 +2872,6 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface)
StorageImpl_Invalidate(iface); StorageImpl_Invalidate(iface);
HeapFree(GetProcessHeap(), 0, This->pwcsName);
BlockChainStream_Destroy(This->smallBlockRootChain); BlockChainStream_Destroy(This->smallBlockRootChain);
BlockChainStream_Destroy(This->rootBlockChain); BlockChainStream_Destroy(This->rootBlockChain);
BlockChainStream_Destroy(This->smallBlockDepotChain); BlockChainStream_Destroy(This->smallBlockDepotChain);
@ -4649,6 +4644,13 @@ static void TransactedSnapshotImpl_Destroy( StorageBaseImpl *iface)
HeapFree(GetProcessHeap(), 0, This); 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, static HRESULT TransactedSnapshotImpl_CreateDirEntry(StorageBaseImpl *base,
const DirEntry *newData, DirRef *index) const DirEntry *newData, DirRef *index)
{ {
@ -4896,6 +4898,7 @@ static const StorageBaseImplVtbl TransactedSnapshotImpl_BaseVtbl =
{ {
TransactedSnapshotImpl_Destroy, TransactedSnapshotImpl_Destroy,
TransactedSnapshotImpl_Invalidate, TransactedSnapshotImpl_Invalidate,
TransactedSnapshotImpl_GetFilename,
TransactedSnapshotImpl_CreateDirEntry, TransactedSnapshotImpl_CreateDirEntry,
TransactedSnapshotImpl_WriteDirEntry, TransactedSnapshotImpl_WriteDirEntry,
TransactedSnapshotImpl_ReadDirEntry, TransactedSnapshotImpl_ReadDirEntry,
@ -4929,8 +4932,6 @@ static HRESULT TransactedSnapshotImpl_Construct(StorageBaseImpl *parentStorage,
(*result)->base.openFlags = parentStorage->openFlags; (*result)->base.openFlags = parentStorage->openFlags;
(*result)->base.filename = parentStorage->filename;
/* Create a new temporary storage to act as the scratch file. */ /* Create a new temporary storage to act as the scratch file. */
hr = StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE, hr = StgCreateDocfile(NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE,
0, (IStorage**)&(*result)->scratch); 0, (IStorage**)&(*result)->scratch);
@ -5043,6 +5044,13 @@ static void StorageInternalImpl_Destroy( StorageBaseImpl *iface)
HeapFree(GetProcessHeap(), 0, This); 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, static HRESULT StorageInternalImpl_CreateDirEntry(StorageBaseImpl *base,
const DirEntry *newData, DirRef *index) const DirEntry *newData, DirRef *index)
{ {
@ -5468,6 +5476,7 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl =
{ {
StorageInternalImpl_Destroy, StorageInternalImpl_Destroy,
StorageInternalImpl_Invalidate, StorageInternalImpl_Invalidate,
StorageInternalImpl_GetFilename,
StorageInternalImpl_CreateDirEntry, StorageInternalImpl_CreateDirEntry,
StorageInternalImpl_WriteDirEntry, StorageInternalImpl_WriteDirEntry,
StorageInternalImpl_ReadDirEntry, StorageInternalImpl_ReadDirEntry,
@ -5608,33 +5617,26 @@ void StorageUtl_CopyDirEntryToSTATSTG(
const DirEntry* source, const DirEntry* source,
int statFlags) 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 * The copy of the string occurs only when the flag is not set
*/ */
if( ((statFlags & STATFLAG_NONAME) != 0) || if (!(statFlags & STATFLAG_NONAME) && source->stgType == STGTY_ROOT)
(entryName == NULL) || {
(entryName[0] == 0) ) /* 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; destination->pwcsName = 0;
} }
else else
{ {
destination->pwcsName = 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) switch (source->stgType)

View File

@ -154,7 +154,7 @@ struct DirEntry
ULARGE_INTEGER size; 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 * Ole Convert support
@ -221,9 +221,6 @@ struct StorageBaseImpl
*/ */
DWORD stateBits; DWORD stateBits;
/* If set, this overrides the root storage name returned by IStorage_Stat */
LPCWSTR filename;
BOOL create; /* Was the storage created or opened. BOOL create; /* Was the storage created or opened.
The behaviour of STGM_SIMPLE depends on this */ The behaviour of STGM_SIMPLE depends on this */
/* /*
@ -237,6 +234,7 @@ struct StorageBaseImpl
struct StorageBaseImplVtbl { struct StorageBaseImplVtbl {
void (*Destroy)(StorageBaseImpl*); void (*Destroy)(StorageBaseImpl*);
void (*Invalidate)(StorageBaseImpl*); void (*Invalidate)(StorageBaseImpl*);
HRESULT (*GetFilename)(StorageBaseImpl*,LPWSTR*);
HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*); HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*);
HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*); HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*);
HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*); HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*);
@ -257,6 +255,11 @@ static inline void StorageBaseImpl_Invalidate(StorageBaseImpl *This)
This->baseVtbl->Invalidate(This); 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, static inline HRESULT StorageBaseImpl_CreateDirEntry(StorageBaseImpl *This,
const DirEntry *newData, DirRef *index) const DirEntry *newData, DirRef *index)
{ {
@ -337,7 +340,6 @@ struct StorageImpl
* class * class
*/ */
HANDLE hFile; /* Physical support for the Docfile */ HANDLE hFile; /* Physical support for the Docfile */
LPOLESTR pwcsName; /* Full path of the document file */
/* /*
* File header * File header