From: Fabian Maurer dark.shadow4@web.de
--- dlls/coml2/Makefile.in | 7 +++++++ dlls/coml2/coml2.spec | 2 ++ dlls/{ole32 => coml2}/memlockbytes.c | 0 dlls/ole32/Makefile.in | 3 +-- dlls/ole32/ole32.spec | 4 ++-- 5 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 dlls/coml2/Makefile.in create mode 100644 dlls/coml2/coml2.spec rename dlls/{ole32 => coml2}/memlockbytes.c (100%)
diff --git a/dlls/coml2/Makefile.in b/dlls/coml2/Makefile.in new file mode 100644 index 00000000000..9887ccff873 --- /dev/null +++ b/dlls/coml2/Makefile.in @@ -0,0 +1,7 @@ +EXTRADEFS = -DWINOLE32API= +MODULE = coml2.dll +IMPORTLIB = coml2 +IMPORTS = uuid + +SOURCES = \ + memlockbytes.c diff --git a/dlls/coml2/coml2.spec b/dlls/coml2/coml2.spec new file mode 100644 index 00000000000..7070e5ca3b2 --- /dev/null +++ b/dlls/coml2/coml2.spec @@ -0,0 +1,2 @@ +@ stdcall CreateILockBytesOnHGlobal(ptr long ptr) +@ stdcall GetHGlobalFromILockBytes(ptr ptr) diff --git a/dlls/ole32/memlockbytes.c b/dlls/coml2/memlockbytes.c similarity index 100% rename from dlls/ole32/memlockbytes.c rename to dlls/coml2/memlockbytes.c diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in index b65de3bd68a..ee0fcc41f7d 100644 --- a/dlls/ole32/Makefile.in +++ b/dlls/ole32/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -D_OLE32_ MODULE = ole32.dll IMPORTLIB = ole32 -IMPORTS = uuid advapi32 user32 gdi32 combase rpcrt4 kernelbase +IMPORTS = uuid advapi32 user32 gdi32 combase rpcrt4 kernelbase coml2 DELAYIMPORTS = oleaut32
SOURCES = \ @@ -26,7 +26,6 @@ SOURCES = \ irot.idl \ itemmoniker.c \ marshal.c \ - memlockbytes.c \ moniker.c \ nodrop.svg \ ole2.c \ diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index e9982036eeb..e61b90b20e3 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -101,7 +101,7 @@ @ stdcall CreateErrorInfo(ptr) combase.CreateErrorInfo @ stdcall CreateFileMoniker(wstr ptr) @ stdcall CreateGenericComposite(ptr ptr ptr) -@ stdcall CreateILockBytesOnHGlobal(ptr long ptr) +@ stdcall -import CreateILockBytesOnHGlobal(ptr long ptr) @ stdcall CreateItemMoniker(wstr wstr ptr) @ stdcall CreateObjrefMoniker(ptr ptr) @ stdcall CreateOleAdviseHolder(ptr) @@ -121,7 +121,7 @@ @ stdcall GetConvertStg(ptr) @ stub GetDocumentBitStg @ stdcall GetErrorInfo(long ptr) combase.GetErrorInfo -@ stdcall GetHGlobalFromILockBytes(ptr ptr) +@ stdcall -import GetHGlobalFromILockBytes(ptr ptr) @ stdcall GetHGlobalFromStream(ptr ptr) combase.GetHGlobalFromStream @ stub GetHookInterface @ stdcall GetRunningObjectTable(long ptr)
From: Fabian Maurer dark.shadow4@web.de
--- dlls/coml2/Makefile.in | 3 +- dlls/coml2/coml2.spec | 1 + dlls/coml2/storage32.c | 87 +++++++ dlls/coml2/storage32.h | 571 +++++++++++++++++++++++++++++++++++++++++ dlls/ole32/ole32.spec | 2 +- dlls/ole32/storage32.c | 30 --- 6 files changed, 662 insertions(+), 32 deletions(-) create mode 100644 dlls/coml2/storage32.c create mode 100644 dlls/coml2/storage32.h
diff --git a/dlls/coml2/Makefile.in b/dlls/coml2/Makefile.in index 9887ccff873..5aa96ded363 100644 --- a/dlls/coml2/Makefile.in +++ b/dlls/coml2/Makefile.in @@ -4,4 +4,5 @@ IMPORTLIB = coml2 IMPORTS = uuid
SOURCES = \ - memlockbytes.c + memlockbytes.c \ + storage32.c diff --git a/dlls/coml2/coml2.spec b/dlls/coml2/coml2.spec index 7070e5ca3b2..fb55f26e46c 100644 --- a/dlls/coml2/coml2.spec +++ b/dlls/coml2/coml2.spec @@ -1,2 +1,3 @@ @ stdcall CreateILockBytesOnHGlobal(ptr long ptr) +@ stdcall GetConvertStg(ptr) @ stdcall GetHGlobalFromILockBytes(ptr ptr) diff --git a/dlls/coml2/storage32.c b/dlls/coml2/storage32.c new file mode 100644 index 00000000000..cb9756aeffb --- /dev/null +++ b/dlls/coml2/storage32.c @@ -0,0 +1,87 @@ +/* + * Compound Storage (32 bit version) + * Storage implementation + * + * This file contains the compound file implementation + * of the storage interface. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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. + */ + +#include <assert.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winuser.h" +#include "wine/debug.h" + +#include "storage32.h" +#include "ole2.h" /* For Write/ReadClassStm */ + +#include "winreg.h" +#include "wine/wingdi16.h" + +WINE_DEFAULT_DEBUG_CHANNEL(storage); + +enum stream_1ole_flags { + OleStream_LinkedObject = 0x00000001, + OleStream_Convert = 0x00000004 +}; + +/*********************************************************************** + * GetConvertStg (OLE32.@) + */ +HRESULT WINAPI GetConvertStg(IStorage *stg) +{ + static const DWORD version_magic = 0x02000001; + DWORD header[2]; + IStream *stream; + HRESULT hr; + + TRACE("%p\n", stg); + + if (!stg) return E_INVALIDARG; + + hr = IStorage_OpenStream(stg, L"\1Ole", NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream); + if (FAILED(hr)) return hr; + + hr = IStream_Read(stream, header, sizeof(header), NULL); + IStream_Release(stream); + if (FAILED(hr)) return hr; + + if (header[0] != version_magic) + { + ERR("got wrong version magic for 1Ole stream, %#lx.\n", header[0]); + return E_FAIL; + } + + return header[1] & OleStream_Convert ? S_OK : S_FALSE; +} diff --git a/dlls/coml2/storage32.h b/dlls/coml2/storage32.h new file mode 100644 index 00000000000..dd4b89aceec --- /dev/null +++ b/dlls/coml2/storage32.h @@ -0,0 +1,571 @@ +/* + * Compound Storage (32 bit version) + * + * Implemented using the documentation of the LAOLA project at + * URL:http://wwwwbs.cs.tu-berlin.de/~schwartz/pmh/index.html + * (Thanks to Martin Schwartz schwartz@cs.tu-berlin.de) + * + * This include file contains definitions of types and function + * prototypes that are used in the many files implementing the + * storage functionality + * + * Copyright 1998,1999 Francis Beaudet + * Copyright 1998,1999 Thuy Nguyen + * Copyright 2010 Vincent Povirk for CodeWeavers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#ifndef __STORAGE32_H__ +#define __STORAGE32_H__ + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "objbase.h" +#include "winreg.h" +#include "winternl.h" +#include "wine/list.h" + +/* + * Definitions for the file format offsets. + */ +static const ULONG OFFSET_MINORVERSION = 0x00000018; +static const ULONG OFFSET_MAJORVERSION = 0x0000001a; +static const ULONG OFFSET_BYTEORDERMARKER = 0x0000001c; +static const ULONG OFFSET_BIGBLOCKSIZEBITS = 0x0000001e; +static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020; +static const ULONG OFFSET_DIRSECTORCOUNT = 0x00000028; +static const ULONG OFFSET_BBDEPOTCOUNT = 0x0000002C; +static const ULONG OFFSET_ROOTSTARTBLOCK = 0x00000030; +static const ULONG OFFSET_TRANSACTIONSIG = 0x00000034; +static const ULONG OFFSET_SMALLBLOCKLIMIT = 0x00000038; +static const ULONG OFFSET_SBDEPOTSTART = 0x0000003C; +static const ULONG OFFSET_SBDEPOTCOUNT = 0x00000040; +static const ULONG OFFSET_EXTBBDEPOTSTART = 0x00000044; +static const ULONG OFFSET_EXTBBDEPOTCOUNT = 0x00000048; +static const ULONG OFFSET_BBDEPOTSTART = 0x0000004C; +static const ULONG OFFSET_PS_NAME = 0x00000000; +static const ULONG OFFSET_PS_NAMELENGTH = 0x00000040; +static const ULONG OFFSET_PS_STGTYPE = 0x00000042; +static const ULONG OFFSET_PS_LEFTCHILD = 0x00000044; +static const ULONG OFFSET_PS_RIGHTCHILD = 0x00000048; +static const ULONG OFFSET_PS_DIRROOT = 0x0000004C; +static const ULONG OFFSET_PS_GUID = 0x00000050; +static const ULONG OFFSET_PS_CTIMELOW = 0x00000064; +static const ULONG OFFSET_PS_CTIMEHIGH = 0x00000068; +static const ULONG OFFSET_PS_MTIMELOW = 0x0000006C; +static const ULONG OFFSET_PS_MTIMEHIGH = 0x00000070; +static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074; +static const ULONG OFFSET_PS_SIZE = 0x00000078; +static const ULONG OFFSET_PS_SIZE_HIGH = 0x0000007C; +static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009; +static const WORD MIN_BIG_BLOCK_SIZE_BITS = 0x0009; +static const WORD MAX_BIG_BLOCK_SIZE_BITS = 0x000c; +static const WORD DEF_SMALL_BLOCK_SIZE_BITS = 0x0006; +static const WORD DEF_BIG_BLOCK_SIZE = 0x0200; +static const WORD DEF_SMALL_BLOCK_SIZE = 0x0040; +static const ULONG BLOCK_FIRST_SPECIAL = 0xFFFFFFFB; +static const ULONG BLOCK_EXTBBDEPOT = 0xFFFFFFFC; +static const ULONG BLOCK_SPECIAL = 0xFFFFFFFD; +static const ULONG BLOCK_END_OF_CHAIN = 0xFFFFFFFE; +static const ULONG BLOCK_UNUSED = 0xFFFFFFFF; +static const ULONG DIRENTRY_NULL = 0xFFFFFFFF; + +#define DIRENTRY_NAME_MAX_LEN 0x20 +#define DIRENTRY_NAME_BUFFER_LEN 0x40 + +#define RAW_DIRENTRY_SIZE 0x00000080 + +#define HEADER_SIZE 512 + +#define MIN_BIG_BLOCK_SIZE 0x200 +#define MAX_BIG_BLOCK_SIZE 0x1000 + +/* + * Type of child entry link + */ +#define DIRENTRY_RELATION_PREVIOUS 0 +#define DIRENTRY_RELATION_NEXT 1 +#define DIRENTRY_RELATION_DIR 2 + +/* + * type constant used in files for the root storage + */ +#define STGTY_ROOT 0x05 + +#define COUNT_BBDEPOTINHEADER 109 + +/* FIXME: This value is stored in the header, but we hard-code it to 0x1000. */ +#define LIMIT_TO_USE_SMALL_BLOCK 0x1000 + +#define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f) +#define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0) +#define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000) + +#define STGM_KNOWN_FLAGS (0xf0ff | \ + STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \ + STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE) + +/* + * Forward declarations of all the structures used by the storage + * module. + */ +typedef struct StorageBaseImpl StorageBaseImpl; +typedef struct StorageBaseImplVtbl StorageBaseImplVtbl; +typedef struct StorageImpl StorageImpl; +typedef struct BlockChainStream BlockChainStream; +typedef struct SmallBlockChainStream SmallBlockChainStream; +typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl; +typedef struct DirEntry DirEntry; +typedef struct StgStreamImpl StgStreamImpl; + +/* + * A reference to a directory entry in the file or a transacted cache. + */ +typedef ULONG DirRef; + +/* + * This utility structure is used to read/write the information in a directory + * entry. + */ +struct DirEntry +{ + WCHAR name[DIRENTRY_NAME_MAX_LEN]; + WORD sizeOfNameString; + BYTE stgType; + DirRef leftChild; + DirRef rightChild; + DirRef dirRootEntry; + GUID clsid; + FILETIME ctime; + FILETIME mtime; + ULONG startingBlock; + ULARGE_INTEGER size; +}; + +HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes); + +/************************************************************************* + * Ole Convert support + */ + +HRESULT STORAGE_CreateOleStream(IStorage*, DWORD); +HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName); + +enum swmr_mode +{ + SWMR_None, + SWMR_Writer, + SWMR_Reader +}; + +/**************************************************************************** + * StorageBaseImpl definitions. + * + * This structure defines the base information contained in all implementations + * of IStorage contained in this file storage implementation. + * + * In OOP terms, this is the base class for all the IStorage implementations + * contained in this file. + */ +struct StorageBaseImpl +{ + IStorage IStorage_iface; + IPropertySetStorage IPropertySetStorage_iface; /* interface for adding a properties stream */ + IDirectWriterLock IDirectWriterLock_iface; + LONG ref; + + /* + * Stream tracking list + */ + + struct list strmHead; + + /* + * Storage tracking list + */ + struct list storageHead; + + /* + * TRUE if this object has been invalidated + */ + BOOL reverted; + + /* + * Index of the directory entry of this storage + */ + DirRef storageDirEntry; + + /* + * virtual methods. + */ + const StorageBaseImplVtbl *baseVtbl; + + /* + * flags that this storage was opened or created with + */ + DWORD openFlags; + + /* + * State bits appear to only be preserved while running. No in the stream + */ + DWORD stateBits; + + BOOL create; /* Was the storage created or opened. + The behaviour of STGM_SIMPLE depends on this */ + /* + * If this storage was opened in transacted mode, the object that implements + * the transacted snapshot or cache. + */ + StorageBaseImpl *transactedChild; + enum swmr_mode lockingrole; +}; + +/* virtual methods for StorageBaseImpl objects */ +struct StorageBaseImplVtbl { + void (*Destroy)(StorageBaseImpl*); + void (*Invalidate)(StorageBaseImpl*); + HRESULT (*Flush)(StorageBaseImpl*); + HRESULT (*GetFilename)(StorageBaseImpl*,LPWSTR*); + HRESULT (*CreateDirEntry)(StorageBaseImpl*,const DirEntry*,DirRef*); + HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*); + HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*); + HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef); + HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*); + HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*); + HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER); + HRESULT (*StreamLink)(StorageBaseImpl*,DirRef,DirRef); + HRESULT (*GetTransactionSig)(StorageBaseImpl*,ULONG*,BOOL); + HRESULT (*SetTransactionSig)(StorageBaseImpl*,ULONG); + HRESULT (*LockTransaction)(StorageBaseImpl*,BOOL); + HRESULT (*UnlockTransaction)(StorageBaseImpl*,BOOL); +}; + +static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This) +{ + This->baseVtbl->Destroy(This); +} + +static inline void StorageBaseImpl_Invalidate(StorageBaseImpl *This) +{ + This->baseVtbl->Invalidate(This); +} + +static inline HRESULT StorageBaseImpl_Flush(StorageBaseImpl *This) +{ + return This->baseVtbl->Flush(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) +{ + return This->baseVtbl->CreateDirEntry(This, newData, index); +} + +static inline HRESULT StorageBaseImpl_WriteDirEntry(StorageBaseImpl *This, + DirRef index, const DirEntry *data) +{ + return This->baseVtbl->WriteDirEntry(This, index, data); +} + +static inline HRESULT StorageBaseImpl_ReadDirEntry(StorageBaseImpl *This, + DirRef index, DirEntry *data) +{ + return This->baseVtbl->ReadDirEntry(This, index, data); +} + +static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This, + DirRef index) +{ + return This->baseVtbl->DestroyDirEntry(This, index); +} + +/* Read up to size bytes from this directory entry's stream at the given offset. */ +static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead) +{ + return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead); +} + +/* Write size bytes to this directory entry's stream at the given offset, + * growing the stream if necessary. */ +static inline HRESULT StorageBaseImpl_StreamWriteAt(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER offset, ULONG size, const void *buffer, ULONG *bytesWritten) +{ + return This->baseVtbl->StreamWriteAt(This, index, offset, size, buffer, bytesWritten); +} + +static inline HRESULT StorageBaseImpl_StreamSetSize(StorageBaseImpl *This, + DirRef index, ULARGE_INTEGER newsize) +{ + return This->baseVtbl->StreamSetSize(This, index, newsize); +} + +/* Make dst point to the same stream that src points to. Other stream operations + * will not work properly for entries that point to the same stream, so this + * must be a very temporary state, and only one entry pointing to a given stream + * may be reachable at any given time. */ +static inline HRESULT StorageBaseImpl_StreamLink(StorageBaseImpl *This, + DirRef dst, DirRef src) +{ + return This->baseVtbl->StreamLink(This, dst, src); +} + +static inline HRESULT StorageBaseImpl_GetTransactionSig(StorageBaseImpl *This, + ULONG* result, BOOL refresh) +{ + return This->baseVtbl->GetTransactionSig(This, result, refresh); +} + +static inline HRESULT StorageBaseImpl_SetTransactionSig(StorageBaseImpl *This, + ULONG value) +{ + return This->baseVtbl->SetTransactionSig(This, value); +} + +static inline HRESULT StorageBaseImpl_LockTransaction(StorageBaseImpl *This, BOOL write) +{ + return This->baseVtbl->LockTransaction(This, write); +} + +static inline HRESULT StorageBaseImpl_UnlockTransaction(StorageBaseImpl *This, BOOL write) +{ + return This->baseVtbl->UnlockTransaction(This, write); +} + +/**************************************************************************** + * StorageBaseImpl stream list handlers + */ + +void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm); +void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm); + +/* Number of BlockChainStream objects to cache in a StorageImpl */ +#define BLOCKCHAIN_CACHE_SIZE 4 + +/**************************************************************************** + * StorageImpl definitions. + * + * This implementation of the IStorage interface represents a root + * storage. Basically, a document file. + */ +struct StorageImpl +{ + struct StorageBaseImpl base; + + /* + * File header + */ + WORD bigBlockSizeBits; + WORD smallBlockSizeBits; + ULONG bigBlockSize; + ULONG smallBlockSize; + ULONG bigBlockDepotCount; + ULONG rootStartBlock; + ULONG smallBlockLimit; + ULONG smallBlockDepotStart; + ULONG extBigBlockDepotStart; + ULONG *extBigBlockDepotLocations; + ULONG extBigBlockDepotLocationsSize; + ULONG extBigBlockDepotCount; + ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER]; + ULONG transactionSig; + + ULONG extBlockDepotCached[MAX_BIG_BLOCK_SIZE / 4]; + ULONG indexExtBlockDepotCached; + + ULONG blockDepotCached[MAX_BIG_BLOCK_SIZE / 4]; + ULONG indexBlockDepotCached; + ULONG prevFreeBlock; + + /* All small blocks before this one are known to be in use. */ + ULONG firstFreeSmallBlock; + + /* + * Abstraction of the big block chains for the chains of the header. + */ + BlockChainStream* rootBlockChain; + BlockChainStream* smallBlockDepotChain; + BlockChainStream* smallBlockRootChain; + + /* Cache of block chain streams objects for directory entries */ + BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE]; + UINT blockChainToEvict; + + ULONG locks_supported; + + ILockBytes* lockBytes; + + ULONG locked_bytes[8]; +}; + +/**************************************************************************** + * StgStreamImpl definitions. + * + * This class implements the IStream interface and represents a stream + * located inside a storage object. + */ +struct StgStreamImpl +{ + IStream IStream_iface; + LONG ref; + + /* + * We are an entry in the storage object's stream handler list + */ + struct list StrmListEntry; + + /* + * Storage that is the parent(owner) of the stream + */ + StorageBaseImpl* parentStorage; + + /* + * Access mode of this stream. + */ + DWORD grfMode; + + /* + * Index of the directory entry that owns (points to) this stream. + */ + DirRef dirEntry; + + /* + * This is the current position of the cursor in the stream + */ + ULARGE_INTEGER currentPosition; +}; + +static inline StgStreamImpl *impl_from_IStream( IStream *iface ) +{ + return CONTAINING_RECORD(iface, StgStreamImpl, IStream_iface); +} + +/* + * Method definition for the StgStreamImpl class. + */ +StgStreamImpl* StgStreamImpl_Construct( + StorageBaseImpl* parentStorage, + DWORD grfMode, + DirRef dirEntry); + + +/* Range lock constants. + * + * The storage format reserves the region from 0x7fffff00-0x7fffffff for + * locking and synchronization. Because it reserves the entire block containing + * that range, and the minimum block size is 512 bytes, 0x7ffffe00-0x7ffffeff + * also cannot be used for any other purpose. + * Unfortunately, the spec doesn't say which bytes + * within that range are used, and for what. These are guesses based on testing. + * In particular, ends of ranges may be wrong. + + 0x0 through 0x57: Unknown. Causes read-only exclusive opens to fail. + 0x58 through 0x6b: Priority mode. + 0x6c through 0x7f: No snapshot mode. + 0x80: Commit lock. + 0x81 through 0x91: Priority mode, again. Not sure why it uses two regions. + 0x92: Lock-checking lock. Held while opening so ranges can be tested without + causing spurious failures if others try to grab or test those ranges at the + same time. + 0x93 through 0xa6: Read mode. + 0xa7 through 0xba: Write mode. + 0xbb through 0xce: Deny read. + 0xcf through 0xe2: Deny write. + 0xe2 through 0xff: Unknown. Causes read-only exclusive opens to fail. +*/ + +#define RANGELOCK_UNK1_FIRST 0x7ffffe00 +#define RANGELOCK_UNK1_LAST 0x7fffff57 +#define RANGELOCK_PRIORITY1_FIRST 0x7fffff58 +#define RANGELOCK_PRIORITY1_LAST 0x7fffff6b +#define RANGELOCK_NOSNAPSHOT_FIRST 0x7fffff6c +#define RANGELOCK_NOSNAPSHOT_LAST 0x7fffff7f +#define RANGELOCK_COMMIT 0x7fffff80 +#define RANGELOCK_PRIORITY2_FIRST 0x7fffff81 +#define RANGELOCK_PRIORITY2_LAST 0x7fffff91 +#define RANGELOCK_CHECKLOCKS 0x7fffff92 +#define RANGELOCK_READ_FIRST 0x7fffff93 +#define RANGELOCK_READ_LAST 0x7fffffa6 +#define RANGELOCK_WRITE_FIRST 0x7fffffa7 +#define RANGELOCK_WRITE_LAST 0x7fffffba +#define RANGELOCK_DENY_READ_FIRST 0x7fffffbb +#define RANGELOCK_DENY_READ_LAST 0x7fffffce +#define RANGELOCK_DENY_WRITE_FIRST 0x7fffffcf +#define RANGELOCK_DENY_WRITE_LAST 0x7fffffe2 +#define RANGELOCK_UNK2_FIRST 0x7fffffe3 +#define RANGELOCK_UNK2_LAST 0x7fffffff +#define RANGELOCK_TRANSACTION_FIRST RANGELOCK_COMMIT +#define RANGELOCK_TRANSACTION_LAST RANGELOCK_CHECKLOCKS +#define RANGELOCK_FIRST RANGELOCK_UNK1_FIRST +#define RANGELOCK_LAST RANGELOCK_UNK2_LAST + +/* internal value for LockRegion/UnlockRegion */ +#define WINE_LOCK_READ 0x80000000 + + +/****************************************************************************** + * Endian conversion macros + */ +#ifdef WORDS_BIGENDIAN + +#ifndef htole32 +#define htole32(x) RtlUlongByteSwap(x) +#endif +#ifndef htole16 +#define htole16(x) RtlUshortByteSwap(x) +#endif +#define lendian32toh(x) RtlUlongByteSwap(x) +#define lendian16toh(x) RtlUshortByteSwap(x) + +#else + +#ifndef htole32 +#define htole32(x) (x) +#endif +#ifndef htole16 +#define htole16(x) (x) +#endif +#define lendian32toh(x) (x) +#define lendian16toh(x) (x) + +#endif + +/****************************************************************************** + * The StorageUtl_ functions are miscellaneous utility functions. Most of which + * are abstractions used to read values from file buffers without having to + * worry about bit order + */ +void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value); +void StorageUtl_WriteWord(void *buffer, ULONG offset, WORD value); +void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value); +void StorageUtl_WriteDWord(void *buffer, ULONG offset, DWORD value); +void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset, + ULARGE_INTEGER* value); +void StorageUtl_WriteULargeInteger(void *buffer, ULONG offset, const ULARGE_INTEGER *value); +void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value); +void StorageUtl_WriteGUID(void *buffer, ULONG offset, const GUID* value); +void StorageUtl_CopyDirEntryToSTATSTG(StorageBaseImpl *storage,STATSTG* destination, + const DirEntry* source, int statFlags); + + +#endif /* __STORAGE32_H__ */ diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index e61b90b20e3..268619aa14a 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -118,7 +118,7 @@ @ stdcall FmtIdToPropStgName(ptr wstr) @ stdcall FreePropVariantArray(long ptr) combase.FreePropVariantArray @ stdcall GetClassFile(wstr ptr) -@ stdcall GetConvertStg(ptr) +@ stdcall GetConvertStg(ptr) coml2.GetConvertStg @ stub GetDocumentBitStg @ stdcall GetErrorInfo(long ptr) combase.GetErrorInfo @ stdcall -import GetHGlobalFromILockBytes(ptr ptr) diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 0d3f9922d78..5b11db7ff96 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -10565,36 +10565,6 @@ HRESULT WINAPI OleConvertIStorageToOLESTREAMEx ( LPSTORAGE stg, CLIPFORMAT cf, L return E_NOTIMPL; }
-/*********************************************************************** - * GetConvertStg (OLE32.@) - */ -HRESULT WINAPI GetConvertStg(IStorage *stg) -{ - static const DWORD version_magic = 0x02000001; - DWORD header[2]; - IStream *stream; - HRESULT hr; - - TRACE("%p\n", stg); - - if (!stg) return E_INVALIDARG; - - hr = IStorage_OpenStream(stg, L"\1Ole", NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream); - if (FAILED(hr)) return hr; - - hr = IStream_Read(stream, header, sizeof(header), NULL); - IStream_Release(stream); - if (FAILED(hr)) return hr; - - if (header[0] != version_magic) - { - ERR("got wrong version magic for 1Ole stream, %#lx.\n", header[0]); - return E_FAIL; - } - - return header[1] & OleStream_Convert ? S_OK : S_FALSE; -} - /*********************************************************************** * SetConvertStg (OLE32.@) */
From: Fabian Maurer dark.shadow4@web.de
--- dlls/coml2/coml2.spec | 1 + dlls/coml2/storage32.c | 37 +++++++++++++++++++++++++++++++++++++ dlls/ole32/ole32.spec | 2 +- dlls/ole32/storage32.c | 38 -------------------------------------- 4 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/dlls/coml2/coml2.spec b/dlls/coml2/coml2.spec index fb55f26e46c..6573dfffcfb 100644 --- a/dlls/coml2/coml2.spec +++ b/dlls/coml2/coml2.spec @@ -1,3 +1,4 @@ @ stdcall CreateILockBytesOnHGlobal(ptr long ptr) @ stdcall GetConvertStg(ptr) @ stdcall GetHGlobalFromILockBytes(ptr ptr) +@ stdcall ReadClassStm(ptr ptr) diff --git a/dlls/coml2/storage32.c b/dlls/coml2/storage32.c index cb9756aeffb..5ce75559a19 100644 --- a/dlls/coml2/storage32.c +++ b/dlls/coml2/storage32.c @@ -51,6 +51,43 @@
WINE_DEFAULT_DEBUG_CHANNEL(storage);
+/*********************************************************************** + * ReadClassStm (OLE32.@) + * + * Reads a CLSID from a stream. + * + * PARAMS + * pStm [I] Stream to read from. + * rclsid [O] CLSID to read. + * + * RETURNS + * Success: S_OK. + * Failure: HRESULT code. + */ +HRESULT WINAPI ReadClassStm(IStream *pStm, CLSID *pclsid) +{ + ULONG nbByte; + HRESULT res; + + TRACE("(%p,%p)\n", pStm, pclsid); + + if (!pStm || !pclsid) + return E_INVALIDARG; + + /* clear the output args */ + *pclsid = CLSID_NULL; + + res = IStream_Read(pStm, pclsid, sizeof(CLSID), &nbByte); + + if (FAILED(res)) + return res; + + if (nbByte != sizeof(CLSID)) + return STG_E_READFAULT; + else + return S_OK; +} + enum stream_1ole_flags { OleStream_LinkedObject = 0x00000001, OleStream_Convert = 0x00000004 diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 268619aa14a..6a10ad05369 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -247,7 +247,7 @@ @ stdcall PropVariantClear(ptr) combase.PropVariantClear @ stdcall PropVariantCopy(ptr ptr) combase.PropVariantCopy @ stdcall ReadClassStg(ptr ptr) -@ stdcall ReadClassStm(ptr ptr) +@ stdcall ReadClassStm(ptr ptr) coml2.ReadClassStm @ stdcall ReadFmtUserTypeStg(ptr ptr ptr) @ stub ReadOleStg @ stub ReadStringStream diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 5b11db7ff96..e463400d2bb 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -9484,44 +9484,6 @@ HRESULT WINAPI WriteClassStm(IStream *pStm,REFCLSID rclsid) return IStream_Write(pStm,rclsid,sizeof(CLSID),NULL); }
-/*********************************************************************** - * ReadClassStm (OLE32.@) - * - * Reads a CLSID from a stream. - * - * PARAMS - * pStm [I] Stream to read from. - * rclsid [O] CLSID to read. - * - * RETURNS - * Success: S_OK. - * Failure: HRESULT code. - */ -HRESULT WINAPI ReadClassStm(IStream *pStm,CLSID *pclsid) -{ - ULONG nbByte; - HRESULT res; - - TRACE("(%p,%p)\n",pStm,pclsid); - - if (!pStm || !pclsid) - return E_INVALIDARG; - - /* clear the output args */ - *pclsid = CLSID_NULL; - - res = IStream_Read(pStm, pclsid, sizeof(CLSID), &nbByte); - - if (FAILED(res)) - return res; - - if (nbByte != sizeof(CLSID)) - return STG_E_READFAULT; - else - return S_OK; -} - - /************************************************************************ * OleConvert Functions ***********************************************************************/
From: Fabian Maurer dark.shadow4@web.de
--- dlls/coml2/coml2.spec | 1 + dlls/coml2/storage32.c | 23 +++++++++++++++++++++++ dlls/ole32/ole32.spec | 2 +- dlls/ole32/storage32.c | 23 ----------------------- 4 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/dlls/coml2/coml2.spec b/dlls/coml2/coml2.spec index 6573dfffcfb..624e1493ff0 100644 --- a/dlls/coml2/coml2.spec +++ b/dlls/coml2/coml2.spec @@ -2,3 +2,4 @@ @ stdcall GetConvertStg(ptr) @ stdcall GetHGlobalFromILockBytes(ptr ptr) @ stdcall ReadClassStm(ptr ptr) +@ stdcall WriteClassStm(ptr ptr) diff --git a/dlls/coml2/storage32.c b/dlls/coml2/storage32.c index 5ce75559a19..4ddc3069bc3 100644 --- a/dlls/coml2/storage32.c +++ b/dlls/coml2/storage32.c @@ -51,6 +51,29 @@
WINE_DEFAULT_DEBUG_CHANNEL(storage);
+/*********************************************************************** + * WriteClassStm (OLE32.@) + * + * Writes a CLSID to a stream. + * + * PARAMS + * pStm [I] Stream to write to. + * rclsid [I] CLSID to write. + * + * RETURNS + * Success: S_OK. + * Failure: HRESULT code. + */ +HRESULT WINAPI WriteClassStm(IStream *pStm, REFCLSID rclsid) +{ + TRACE("(%p,%p)\n", pStm, rclsid); + + if (!pStm || !rclsid) + return E_INVALIDARG; + + return IStream_Write(pStm, rclsid, sizeof(CLSID), NULL); +} + /*********************************************************************** * ReadClassStm (OLE32.@) * diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 6a10ad05369..47d515ace63 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -295,7 +295,7 @@ @ stdcall WdtpInterfacePointer_UserSize(ptr long long ptr ptr) combase.WdtpInterfacePointer_UserSize @ stdcall WdtpInterfacePointer_UserUnmarshal(ptr ptr ptr ptr) combase.WdtpInterfacePointer_UserUnmarshal @ stdcall WriteClassStg(ptr ptr) -@ stdcall WriteClassStm(ptr ptr) +@ stdcall WriteClassStm(ptr ptr) coml2.WriteClassStm @ stdcall WriteFmtUserTypeStg(ptr long ptr) @ stub WriteOleStg @ stub WriteStringStream diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index e463400d2bb..ff14e295584 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -9461,29 +9461,6 @@ StgIsStorageFile(LPCOLESTR fn) return S_FALSE; }
-/*********************************************************************** - * WriteClassStm (OLE32.@) - * - * Writes a CLSID to a stream. - * - * PARAMS - * pStm [I] Stream to write to. - * rclsid [I] CLSID to write. - * - * RETURNS - * Success: S_OK. - * Failure: HRESULT code. - */ -HRESULT WINAPI WriteClassStm(IStream *pStm,REFCLSID rclsid) -{ - TRACE("(%p,%p)\n",pStm,rclsid); - - if (!pStm || !rclsid) - return E_INVALIDARG; - - return IStream_Write(pStm,rclsid,sizeof(CLSID),NULL); -} - /************************************************************************ * OleConvert Functions ***********************************************************************/
From: Fabian Maurer dark.shadow4@web.de
--- dlls/coml2/coml2.spec | 1 + dlls/coml2/storage32.c | 35 +++++++++++++++++++++++++++++++++++ dlls/ole32/ole32.spec | 2 +- dlls/ole32/storage32.c | 35 ----------------------------------- 4 files changed, 37 insertions(+), 36 deletions(-)
diff --git a/dlls/coml2/coml2.spec b/dlls/coml2/coml2.spec index 624e1493ff0..4ffa41e2d08 100644 --- a/dlls/coml2/coml2.spec +++ b/dlls/coml2/coml2.spec @@ -1,5 +1,6 @@ @ stdcall CreateILockBytesOnHGlobal(ptr long ptr) @ stdcall GetConvertStg(ptr) @ stdcall GetHGlobalFromILockBytes(ptr ptr) +@ stdcall ReadClassStg(ptr ptr) @ stdcall ReadClassStm(ptr ptr) @ stdcall WriteClassStm(ptr ptr) diff --git a/dlls/coml2/storage32.c b/dlls/coml2/storage32.c index 4ddc3069bc3..63d82e2dcb8 100644 --- a/dlls/coml2/storage32.c +++ b/dlls/coml2/storage32.c @@ -51,6 +51,41 @@
WINE_DEFAULT_DEBUG_CHANNEL(storage);
+/*********************************************************************** + * ReadClassStg (OLE32.@) + * + * This method reads the CLSID previously written to a storage object with + * the WriteClassStg. + * + * PARAMS + * pstg [I] IStorage pointer + * pclsid [O] Pointer to where the CLSID is written + * + * RETURNS + * Success: S_OK. + * Failure: HRESULT code. + */ +HRESULT WINAPI ReadClassStg(IStorage *pstg, CLSID *pclsid) +{ + STATSTG pstatstg; + HRESULT hRes; + + TRACE("(%p, %p)\n", pstg, pclsid); + + if (!pstg || !pclsid) + return E_INVALIDARG; + + /* + * read a STATSTG structure (contains the clsid) from the storage + */ + hRes = IStorage_Stat(pstg, &pstatstg, STATFLAG_NONAME); + + if (SUCCEEDED(hRes)) + *pclsid = pstatstg.clsid; + + return hRes; +} + /*********************************************************************** * WriteClassStm (OLE32.@) * diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 47d515ace63..87244d9f696 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -246,7 +246,7 @@ @ stdcall PropSysFreeString(wstr) @ stdcall PropVariantClear(ptr) combase.PropVariantClear @ stdcall PropVariantCopy(ptr ptr) combase.PropVariantCopy -@ stdcall ReadClassStg(ptr ptr) +@ stdcall ReadClassStg(ptr ptr) coml2.ReadClassStg @ stdcall ReadClassStm(ptr ptr) coml2.ReadClassStm @ stdcall ReadFmtUserTypeStg(ptr ptr ptr) @ stub ReadOleStg diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index ff14e295584..5d1299a5797 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -9042,41 +9042,6 @@ HRESULT WINAPI WriteClassStg(IStorage* pStg, REFCLSID rclsid) return IStorage_SetClass(pStg, rclsid); }
-/*********************************************************************** - * ReadClassStg (OLE32.@) - * - * This method reads the CLSID previously written to a storage object with - * the WriteClassStg. - * - * PARAMS - * pstg [I] IStorage pointer - * pclsid [O] Pointer to where the CLSID is written - * - * RETURNS - * Success: S_OK. - * Failure: HRESULT code. - */ -HRESULT WINAPI ReadClassStg(IStorage *pstg,CLSID *pclsid){ - - STATSTG pstatstg; - HRESULT hRes; - - TRACE("(%p, %p)\n", pstg, pclsid); - - if(!pstg || !pclsid) - return E_INVALIDARG; - - /* - * read a STATSTG structure (contains the clsid) from the storage - */ - hRes=IStorage_Stat(pstg,&pstatstg,STATFLAG_NONAME); - - if(SUCCEEDED(hRes)) - *pclsid=pstatstg.clsid; - - return hRes; -} - /*********************************************************************** * OleLoadFromStream (OLE32.@) *
From: Fabian Maurer dark.shadow4@web.de
--- dlls/coml2/coml2.spec | 1 + dlls/coml2/storage32.c | 16 ++++++++++++++++ dlls/ole32/ole32.spec | 2 +- dlls/ole32/storage32.c | 16 ---------------- 4 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/dlls/coml2/coml2.spec b/dlls/coml2/coml2.spec index 4ffa41e2d08..71c099244c4 100644 --- a/dlls/coml2/coml2.spec +++ b/dlls/coml2/coml2.spec @@ -3,4 +3,5 @@ @ stdcall GetHGlobalFromILockBytes(ptr ptr) @ stdcall ReadClassStg(ptr ptr) @ stdcall ReadClassStm(ptr ptr) +@ stdcall WriteClassStg(ptr ptr) @ stdcall WriteClassStm(ptr ptr) diff --git a/dlls/coml2/storage32.c b/dlls/coml2/storage32.c index 63d82e2dcb8..25b617f88c1 100644 --- a/dlls/coml2/storage32.c +++ b/dlls/coml2/storage32.c @@ -51,6 +51,22 @@
WINE_DEFAULT_DEBUG_CHANNEL(storage);
+/****************************************************************************** + * WriteClassStg [OLE32.@] + * + * This method will store the specified CLSID in the specified storage object + */ +HRESULT WINAPI WriteClassStg(IStorage *pStg, REFCLSID rclsid) +{ + if (!pStg) + return E_INVALIDARG; + + if (!rclsid) + return STG_E_INVALIDPOINTER; + + return IStorage_SetClass(pStg, rclsid); +} + /*********************************************************************** * ReadClassStg (OLE32.@) * diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 87244d9f696..8603fb0f09f 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -294,7 +294,7 @@ @ stdcall WdtpInterfacePointer_UserMarshal(ptr long ptr ptr ptr) combase.WdtpInterfacePointer_UserMarshal @ stdcall WdtpInterfacePointer_UserSize(ptr long long ptr ptr) combase.WdtpInterfacePointer_UserSize @ stdcall WdtpInterfacePointer_UserUnmarshal(ptr ptr ptr ptr) combase.WdtpInterfacePointer_UserUnmarshal -@ stdcall WriteClassStg(ptr ptr) +@ stdcall WriteClassStg(ptr ptr) coml2.WriteClassStg @ stdcall WriteClassStm(ptr ptr) coml2.WriteClassStm @ stdcall WriteFmtUserTypeStg(ptr long ptr) @ stub WriteOleStg diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 5d1299a5797..3335186ff90 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -9026,22 +9026,6 @@ HRESULT WINAPI StgIsStorageILockBytes(ILockBytes *plkbyt) return S_FALSE; }
-/****************************************************************************** - * WriteClassStg [OLE32.@] - * - * This method will store the specified CLSID in the specified storage object - */ -HRESULT WINAPI WriteClassStg(IStorage* pStg, REFCLSID rclsid) -{ - if(!pStg) - return E_INVALIDARG; - - if(!rclsid) - return STG_E_INVALIDPOINTER; - - return IStorage_SetClass(pStg, rclsid); -} - /*********************************************************************** * OleLoadFromStream (OLE32.@) *
As far as I can tell they all should use -import. Also, what do you need storage32.h for?