Ugh, it seems that Windows doesn't even check to make sure the storage file is at least 24 bytes long. It looks like we were -too- good at checking for valid storage files. Versus current CVS ChangeLog: -Move StgIsStorageFile16's implementation to StgIsStorageFile; port it to Win32. -Move StgIsStorageFile from storage.c to storage32.c -StgIsStorageFile only returns S_OK, STG_E_FILENOTFOUND, and S_FALSE (checked against MSDN and WinXP) -StgIsStorageFile doesn't check if a file is large enough to be a storage file, it only checks for the presence of the 8-byte magic (checked against WinXP)
Index: dlls/ole32/storage.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/storage.c,v retrieving revision 1.25 diff -u -r1.25 storage.c --- dlls/ole32/storage.c 12 Sep 2002 22:28:01 -0000 1.25 +++ dlls/ole32/storage.c 16 Nov 2002 01:04:19 -0000 @@ -30,6 +30,7 @@ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif +#include "heap.h" #include "windef.h" #include "winternl.h" #include "winerror.h" @@ -76,8 +77,6 @@ static const BYTE STORAGE_magic[8] ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1}; -static const BYTE STORAGE_notmagic[8]={0x0e,0x11,0xfc,0x0d,0xd0,0xcf,0x11,0xe0}; -static const BYTE STORAGE_oldmagic[8]={0xd0,0xcf,0x11,0xe0,0x0e,0x11,0xfc,0x0d}; #define BIGSIZE 512 #define SMALLSIZE 64 @@ -1638,55 +1637,17 @@ * StgIsStorageFile [STORAGE.5] */ HRESULT WINAPI StgIsStorageFile16(LPCOLESTR16 fn) { - HFILE hf; - OFSTRUCT ofs; - BYTE magic[24]; + LPWSTR strW; + HRESULT ret; - TRACE("(\'%s\')\n",fn); - hf = OpenFile(fn,&ofs,OF_SHARE_DENY_NONE); - if (hf==HFILE_ERROR) - return STG_E_FILENOTFOUND; - if (24!=_lread(hf,magic,24)) { - WARN(" too short\n"); - _lclose(hf); - return S_FALSE; - } - if (!memcmp(magic,STORAGE_magic,8)) { - WARN(" -> YES\n"); - _lclose(hf); - return S_OK; - } - if (!memcmp(magic,STORAGE_notmagic,8)) { - WARN(" -> NO\n"); - _lclose(hf); - return S_FALSE; - } - if (!memcmp(magic,STORAGE_oldmagic,8)) { - WARN(" -> old format\n"); - _lclose(hf); - return STG_E_OLDFORMAT; - } - WARN(" -> Invalid header.\n"); - _lclose(hf); - return STG_E_INVALIDHEADER; -} + strW = HEAP_strdupAtoW( GetProcessHeap(), 0, fn ); -/****************************************************************************** - * StgIsStorageFile [OLE32.146] - */ -HRESULT WINAPI -StgIsStorageFile(LPCOLESTR fn) -{ - HRESULT ret; - DWORD len = WideCharToMultiByte( CP_ACP, 0, fn, -1, NULL, 0, NULL, NULL ); - LPSTR strA = HeapAlloc( GetProcessHeap(), 0, len ); - - WideCharToMultiByte( CP_ACP, 0, fn, -1, strA, len, NULL, NULL ); - ret = StgIsStorageFile16(strA); - HeapFree( GetProcessHeap(), 0, strA ); - return ret; -} + ret = StgIsStorageFile( strW ); + HeapFree( GetProcessHeap(), 0, strW ); + + return ret; +} /****************************************************************************** * StgOpenStorage [STORAGE.3] Index: dlls/ole32/storage32.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/storage32.c,v retrieving revision 1.34 diff -u -r1.34 storage32.c --- dlls/ole32/storage32.c 16 Aug 2002 19:55:14 -0000 1.34 +++ dlls/ole32/storage32.c 16 Nov 2002 01:04:20 -0000 @@ -7155,3 +7155,44 @@ FIXME("(%s), unimplemented stub!\n",debugstr_guid(guid)); return E_FAIL; } + +/****************************************************************************** + * StgIsStorageFile [OLE32.146] + */ +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; +}