Implementation of IStorage supported by an implementation of

ILockBytes on top of an HGLOBAL.
oldstable
Thuy Nguyen 1999-05-08 10:05:08 +00:00 committed by Alexandre Julliard
parent 264360fc21
commit ed1d88b610
7 changed files with 375 additions and 104 deletions

View File

@ -690,6 +690,7 @@ HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName,DWORD grfMode,DWORD reserved,
HRESULT WINAPI StgIsStorageFile16(LPCOLESTR16 fn);
HRESULT WINAPI StgIsStorageFile(LPCOLESTR fn);
HRESULT WINAPI StgIsStorageILockBytes(ILockBytes *plkbyt);
HRESULT WINAPI StgOpenStorage16(const OLECHAR16* pwcsName,IStorage16* pstgPriority,DWORD grfMode,SNB16 snbExclude,DWORD reserved,IStorage16**ppstgOpen);
HRESULT WINAPI StgOpenStorage(const OLECHAR* pwcsName,IStorage* pstgPriority,DWORD grfMode,SNB snbExclude,DWORD reserved,IStorage**ppstgOpen);

View File

@ -157,11 +157,11 @@ HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal)
HGLOBALLockBytesImpl* const pMemLockBytes = (HGLOBALLockBytesImpl*)plkbyt;
if (pMemLockBytes->lpvtbl == &HGLOBALLockBytesImpl_Vtbl)
phglobal = &pMemLockBytes->supportHandle;
*phglobal = pMemLockBytes->supportHandle;
else
phglobal = NULL;
*phglobal = 0;
if (phglobal == NULL)
if (*phglobal == 0)
return E_INVALIDARG;
return S_OK;

View File

@ -26,9 +26,14 @@
#include "winbase.h"
#include "winerror.h"
#include "wine/obj_storage.h"
#include "ole2.h"
#include "storage32.h"
#include "debug.h"
DEFAULT_DEBUG_CHANNEL(storage)
/***********************************************************
* Data structures used internally by the BigBlockFile
* class.
@ -85,6 +90,9 @@ static BigBlock* BIGBLOCKFILE_AddBigBlock(LPBIGBLOCKFILE This,
ULONG index);
static BigBlock* BIGBLOCKFILE_CreateBlock(ULONG index);
static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags);
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile);
static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt);
static void BIGBLOCKFILE_RemoveAllBlocks(LPBIGBLOCKFILE This);
/******************************************************************************
* BIGBLOCKFILE_Construct
@ -94,9 +102,11 @@ static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags);
* and the blocks in use list.
*/
BigBlockFile * BIGBLOCKFILE_Construct(
HANDLE hFile,
HANDLE hFile,
ILockBytes* pLkByt,
DWORD openFlags,
ULONG blocksize)
ULONG blocksize,
BOOL fileBased)
{
LPBIGBLOCKFILE This;
@ -105,36 +115,68 @@ BigBlockFile * BIGBLOCKFILE_Construct(
if (This == NULL)
return NULL;
This->hfile = hFile;
if (This->hfile == INVALID_HANDLE_VALUE)
This->fileBased = fileBased;
if (This->fileBased)
{
HeapFree(GetProcessHeap(), 0, This);
return NULL;
if (!BIGBLOCKFILE_FileInit(This, hFile))
{
HeapFree(GetProcessHeap(), 0, This);
return NULL;
}
}
else
{
if (!BIGBLOCKFILE_MemInit(This, pLkByt))
{
HeapFree(GetProcessHeap(), 0, This);
return NULL;
}
}
This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags);
This->blocksize = blocksize;
/* initialize the block list
*/
This->headblock = NULL;
return This;
}
/******************************************************************************
* BIGBLOCKFILE_FileInit
*
* Initialize a big block object supported by a file.
*/
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
{
This->pLkbyt = NULL;
This->hbytearray = 0;
This->pbytearray = NULL;
This->hfile = hFile;
if (This->hfile == INVALID_HANDLE_VALUE)
return FALSE;
/* create the file mapping object
*/
This->hfilemap = CreateFileMappingA(This->hfile,
NULL,
This->flProtect,
0, 0,
NULL);
NULL,
This->flProtect,
0, 0,
NULL);
if (This->hfilemap == NULL)
{
CloseHandle(This->hfile);
HeapFree(GetProcessHeap(), 0, This);
return NULL;
return FALSE;
}
/* initialize this
*/
This->filesize.LowPart = GetFileSize(This->hfile, NULL);
This->blocksize = blocksize;
/* create the mapped pages list
*/
This->maplisthead = HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
@ -143,17 +185,48 @@ BigBlockFile * BIGBLOCKFILE_Construct(
{
CloseHandle(This->hfilemap);
CloseHandle(This->hfile);
HeapFree(GetProcessHeap(), 0, This);
return NULL;
return FALSE;
}
This->maplisthead->next = NULL;
/* initialize the block list
*/
This->headblock = NULL;
return TRUE;
}
return This;
/******************************************************************************
* BIGBLOCKFILE_MemInit
*
* Initialize a big block object supported by an ILockBytes on HGLOABL.
*/
static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
{
This->hfile = 0;
This->hfilemap = NULL;
This->maplisthead = NULL;
/*
* Retrieve the handle to the byte array from the LockByte object.
*/
if (GetHGlobalFromILockBytes(plkbyt, &(This->hbytearray)) != S_OK)
{
FIXME(storage, "May not be an ILockBytes on HGLOBAL\n");
return FALSE;
}
This->pLkbyt = plkbyt;
/*
* Increment the reference count of the ILockByte object since
* we're keeping a reference to it.
*/
ILockBytes_AddRef(This->pLkbyt);
This->filesize.LowPart = GlobalSize(This->hbytearray);
This->filesize.HighPart = 0;
This->pbytearray = GlobalLock(This->hbytearray);
return TRUE;
}
/******************************************************************************
@ -164,15 +237,28 @@ BigBlockFile * BIGBLOCKFILE_Construct(
void BIGBLOCKFILE_Destructor(
LPBIGBLOCKFILE This)
{
/* unmap all views and destroy the mapped page list
*/
BIGBLOCKFILE_FreeAllMappedPages(This);
HeapFree(GetProcessHeap(), 0, This->maplisthead);
if (This->fileBased)
{
/* unmap all views and destroy the mapped page list
*/
BIGBLOCKFILE_FreeAllMappedPages(This);
HeapFree(GetProcessHeap(), 0, This->maplisthead);
/* close all open handles
*/
CloseHandle(This->hfilemap);
CloseHandle(This->hfile);
}
else
{
GlobalUnlock(This->hbytearray);
ILockBytes_Release(This->pLkbyt);
}
/* close all open handles
/*
* Destroy the blocks list.
*/
CloseHandle(This->hfilemap);
CloseHandle(This->hfile);
BIGBLOCKFILE_RemoveAllBlocks(This);
/* destroy this
*/
@ -264,15 +350,18 @@ void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
if (theBigBlock == NULL)
return;
/*
* find out which page this block is in
*/
page_num = theBigBlock->index / BLOCKS_PER_PAGE;
/*
* release this page
*/
BIGBLOCKFILE_ReleaseMappedPage(This, page_num, theBigBlock->access_mode);
if (This->fileBased)
{
/*
* find out which page this block is in
*/
page_num = theBigBlock->index / BLOCKS_PER_PAGE;
/*
* release this page
*/
BIGBLOCKFILE_ReleaseMappedPage(This, page_num, theBigBlock->access_mode);
}
/*
* remove block from list
@ -291,31 +380,54 @@ void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
if (This->filesize.LowPart == newSize.LowPart)
return;
/*
* unmap all views, must be done before call to SetEndFile
*/
BIGBLOCKFILE_FreeAllMappedPages(This);
if (This->fileBased)
{
/*
* unmap all views, must be done before call to SetEndFile
*/
BIGBLOCKFILE_FreeAllMappedPages(This);
/*
* close file-mapping object, must be done before call to SetEndFile
*/
CloseHandle(This->hfilemap);
This->hfilemap = NULL;
/*
* set the new end of file
*/
SetFilePointer(This->hfile, newSize.LowPart, NULL, FILE_BEGIN);
SetEndOfFile(This->hfile);
/*
* re-create the file mapping object
*/
This->hfilemap = CreateFileMappingA(This->hfile,
NULL,
This->flProtect,
0, 0,
NULL);
}
else
{
GlobalUnlock(This->hbytearray);
/*
* Resize the byte array object.
*/
ILockBytes_SetSize(This->pLkbyt, newSize);
/*
* Re-acquire the handle, it may have changed.
*/
GetHGlobalFromILockBytes(This->pLkbyt, &This->hbytearray);
This->pbytearray = GlobalLock(This->hbytearray);
}
/*
* close file-mapping object, must be done before call to SetEndFile
* empty the blocks list.
*/
CloseHandle(This->hfilemap);
This->hfilemap = NULL;
/*
* set the new end of file
*/
SetFilePointer(This->hfile, newSize.LowPart, NULL, FILE_BEGIN);
SetEndOfFile(This->hfile);
/*
* re-create the file mapping object
*/
This->hfilemap = CreateFileMappingA(This->hfile,
NULL,
This->flProtect,
0, 0,
NULL);
BIGBLOCKFILE_RemoveAllBlocks(This);
This->filesize.LowPart = newSize.LowPart;
This->filesize.HighPart = newSize.HighPart;
@ -342,7 +454,7 @@ static void* BIGBLOCKFILE_GetBigBlockPointer(
ULONG index,
DWORD desired_access)
{
DWORD page_num, block_num;
DWORD block_num;
void * pBytes;
BigBlock *aBigBlock;
@ -369,17 +481,27 @@ static void* BIGBLOCKFILE_GetBigBlockPointer(
* else aBigBlock->lpBigBlock == NULL, it's a new block
*/
/* find out which page this block is in
*/
page_num = index / BLOCKS_PER_PAGE;
if (This->fileBased)
{
DWORD page_num;
/* offset of the block in the page
*/
block_num = index % BLOCKS_PER_PAGE;
/* get a pointer to the first byte in the page
*/
pBytes = BIGBLOCKFILE_GetMappedView(This, page_num, desired_access);
/* find out which page this block is in
*/
page_num = index / BLOCKS_PER_PAGE;
/* offset of the block in the page
*/
block_num = index % BLOCKS_PER_PAGE;
/* get a pointer to the first byte in the page
*/
pBytes = BIGBLOCKFILE_GetMappedView(This, page_num, desired_access);
}
else
{
pBytes = This->pbytearray;
block_num = index;
}
if (pBytes == NULL)
return NULL;
@ -508,6 +630,24 @@ static BigBlock* BIGBLOCKFILE_AddBigBlock(
return NULL;
}
/******************************************************************************
* BIGBLOCKFILE_RemoveAllBlocks [PRIVATE]
*
* Removes all blocks from the blocks list.
*/
static void BIGBLOCKFILE_RemoveAllBlocks(
LPBIGBLOCKFILE This)
{
BigBlock *current;
while (This->headblock != NULL)
{
current = This->headblock;
This->headblock = current->next;
HeapFree(GetProcessHeap(), 0, current);
}
}
/******************************************************************************
* BIGBLOCKFILE_RemoveBlock [PRIVATE]
*

View File

@ -1569,26 +1569,6 @@ static void _create_istorage16(LPSTORAGE16 *stg) {
* Storage API functions
*/
/******************************************************************************
* StgOpenStorageOnILockBytes [OLE32.149]
*/
HRESULT WINAPI StgOpenStorageOnILockBytes(ILockBytes *plkbyt, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
{
FIXME_(ole)("(not shown) stub!\n");
return S_OK;
}
/******************************************************************************
* StgCreateDocfileOnILockBytes [OLE32.145]
*/
HRESULT WINAPI StgCreateDocfileOnILockBytes(ILockBytes *plkbyt,DWORD grfMode, DWORD reserved, IStorage** ppstgOpen)
{
FIXME_(ole)("(not shown) stub!\n");
return S_OK;
}
/******************************************************************************
* StgCreateDocFile16 [STORAGE.1]
*/

View File

@ -2023,7 +2023,9 @@ HRESULT WINAPI StorageImpl_SetStateBits(
HRESULT StorageImpl_Construct(
StorageImpl* This,
HANDLE hFile,
DWORD openFlags)
ILockBytes* pLkbyt,
DWORD openFlags,
BOOL fileBased)
{
HRESULT hr = S_OK;
StgProperty currentProperty;
@ -2058,8 +2060,10 @@ HRESULT StorageImpl_Construct(
This->bigBlockSize = DEF_BIG_BLOCK_SIZE;
This->smallBlockSize = DEF_SMALL_BLOCK_SIZE;
This->bigBlockFile = BIGBLOCKFILE_Construct(hFile,
pLkbyt,
openFlags,
This->bigBlockSize);
This->bigBlockSize,
fileBased);
if (This->bigBlockFile == 0)
return E_FAIL;
@ -5277,7 +5281,9 @@ HRESULT WINAPI StgCreateDocfile(
hr = StorageImpl_Construct(
newStorage,
hFile,
grfMode);
NULL,
grfMode,
TRUE);
if (FAILED(hr))
{
@ -5365,7 +5371,9 @@ HRESULT WINAPI StgOpenStorage(
hr = StorageImpl_Construct(
newStorage,
hFile,
grfMode);
NULL,
grfMode,
TRUE);
if (FAILED(hr))
{
@ -5385,7 +5393,141 @@ HRESULT WINAPI StgOpenStorage(
}
/******************************************************************************
* WriteClassStg32 [OLE32.148]
* StgCreateDocfileOnILockBytes [OLE32.145]
*/
HRESULT WINAPI StgCreateDocfileOnILockBytes(
ILockBytes *plkbyt,
DWORD grfMode,
DWORD reserved,
IStorage** ppstgOpen)
{
StorageImpl* newStorage = 0;
HRESULT hr = S_OK;
/*
* Validate the parameters
*/
if ((ppstgOpen == 0) || (plkbyt == 0))
return STG_E_INVALIDPOINTER;
/*
* 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,
plkbyt,
grfMode,
FALSE);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, newStorage);
return hr;
}
/*
* Get an "out" pointer for the caller.
*/
hr = StorageBaseImpl_QueryInterface(
(IStorage*)newStorage,
(REFIID)&IID_IStorage,
(void**)ppstgOpen);
return hr;
}
/******************************************************************************
* StgOpenStorageOnILockBytes [OLE32.149]
*/
HRESULT WINAPI StgOpenStorageOnILockBytes(
ILockBytes *plkbyt,
IStorage *pstgPriority,
DWORD grfMode,
SNB snbExclude,
DWORD reserved,
IStorage **ppstgOpen)
{
StorageImpl* newStorage = 0;
HRESULT hr = S_OK;
/*
* Perform a sanity check
*/
if ((plkbyt == 0) || (ppstgOpen == 0))
return STG_E_INVALIDPOINTER;
/*
* Validate the STGM flags
*/
if ( FAILED( validateSTGM(grfMode) ))
return STG_E_INVALIDFLAG;
/*
* Initialize the "out" parameter.
*/
*ppstgOpen = 0;
/*
* 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,
plkbyt,
grfMode,
FALSE);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, newStorage);
return hr;
}
/*
* Get an "out" pointer for the caller.
*/
hr = StorageBaseImpl_QueryInterface(
(IStorage*)newStorage,
(REFIID)&IID_IStorage,
(void**)ppstgOpen);
return hr;
}
/******************************************************************************
* StgIsStorageILockBytes [OLE32.147]
*
* Determines if the ILockBytes contains a storage object.
*/
HRESULT WINAPI StgIsStorageILockBytes(ILockBytes *plkbyt)
{
BYTE sig[8];
ULARGE_INTEGER offset;
offset.HighPart = 0;
offset.LowPart = 0;
ILockBytes_ReadAt(plkbyt, offset, sig, sizeof(sig), NULL);
if (memcmp(sig, STORAGE_magic, sizeof(STORAGE_magic)) == 0)
return S_OK;
return S_FALSE;
}
/******************************************************************************
* WriteClassStg32 [OLE32.158]
*
* This method will store the specified CLSID in the specified storage object
*/

View File

@ -135,12 +135,16 @@ typedef struct BigBlock BigBlock,*LPBIGBLOCK;
struct BigBlockFile
{
BOOL fileBased;
ULARGE_INTEGER filesize;
ULONG blocksize;
HANDLE hfile;
HANDLE hfilemap;
DWORD flProtect;
MappedPage *maplisthead;
ILockBytes *pLkbyt;
HGLOBAL hbytearray;
LPVOID pbytearray;
BigBlock *headblock;
};
@ -149,8 +153,10 @@ struct BigBlockFile
* data structure.
*/
BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile,
ILockBytes* pLkByt,
DWORD openFlags,
ULONG blocksize);
ULONG blocksize,
BOOL fileBased);
void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index);
void* BIGBLOCKFILE_GetROBigBlock(LPBIGBLOCKFILE This, ULONG index);
@ -367,7 +373,9 @@ void StorageImpl_Destroy(
HRESULT StorageImpl_Construct(
StorageImpl* This,
HANDLE hFile,
DWORD openFlags);
ILockBytes* pLkbyt,
DWORD openFlags,
BOOL fileBased);
BOOL StorageImpl_ReadBigBlock(
StorageImpl* This,

View File

@ -147,7 +147,7 @@ type win32
144 stdcall StgCreateDocfile(wstr long long ptr) StgCreateDocfile
145 stdcall StgCreateDocfileOnILockBytes(ptr long long ptr) StgCreateDocfileOnILockBytes
146 stdcall StgIsStorageFile(wstr) StgIsStorageFile
147 stub StgIsStorageILockBytes
147 stdcall StgIsStorageILockBytes(ptr) StgIsStorageILockBytes
148 stdcall StgOpenStorage(wstr ptr long ptr long ptr) StgOpenStorage
149 stdcall StgOpenStorageOnILockBytes(ptr ptr long long long ptr) StgOpenStorageOnILockBytes
150 stub StgSetTimes