Implementation of IStorage supported by an implementation of

ILockBytes on top of an HGLOBAL.
This commit is contained in:
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 StgIsStorageFile16(LPCOLESTR16 fn);
HRESULT WINAPI StgIsStorageFile(LPCOLESTR 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 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); 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; HGLOBALLockBytesImpl* const pMemLockBytes = (HGLOBALLockBytesImpl*)plkbyt;
if (pMemLockBytes->lpvtbl == &HGLOBALLockBytesImpl_Vtbl) if (pMemLockBytes->lpvtbl == &HGLOBALLockBytesImpl_Vtbl)
phglobal = &pMemLockBytes->supportHandle; *phglobal = pMemLockBytes->supportHandle;
else else
phglobal = NULL; *phglobal = 0;
if (phglobal == NULL) if (*phglobal == 0)
return E_INVALIDARG; return E_INVALIDARG;
return S_OK; return S_OK;

View File

@ -26,9 +26,14 @@
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "wine/obj_storage.h" #include "wine/obj_storage.h"
#include "ole2.h"
#include "storage32.h" #include "storage32.h"
#include "debug.h"
DEFAULT_DEBUG_CHANNEL(storage)
/*********************************************************** /***********************************************************
* Data structures used internally by the BigBlockFile * Data structures used internally by the BigBlockFile
* class. * class.
@ -85,6 +90,9 @@ static BigBlock* BIGBLOCKFILE_AddBigBlock(LPBIGBLOCKFILE This,
ULONG index); ULONG index);
static BigBlock* BIGBLOCKFILE_CreateBlock(ULONG index); static BigBlock* BIGBLOCKFILE_CreateBlock(ULONG index);
static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags); 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 * BIGBLOCKFILE_Construct
@ -95,8 +103,10 @@ static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags);
*/ */
BigBlockFile * BIGBLOCKFILE_Construct( BigBlockFile * BIGBLOCKFILE_Construct(
HANDLE hFile, HANDLE hFile,
ILockBytes* pLkByt,
DWORD openFlags, DWORD openFlags,
ULONG blocksize) ULONG blocksize,
BOOL fileBased)
{ {
LPBIGBLOCKFILE This; LPBIGBLOCKFILE This;
@ -105,16 +115,52 @@ BigBlockFile * BIGBLOCKFILE_Construct(
if (This == NULL) if (This == NULL)
return NULL; return NULL;
This->hfile = hFile; This->fileBased = fileBased;
if (This->hfile == INVALID_HANDLE_VALUE) if (This->fileBased)
{
if (!BIGBLOCKFILE_FileInit(This, hFile))
{ {
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
return NULL; return NULL;
} }
}
else
{
if (!BIGBLOCKFILE_MemInit(This, pLkByt))
{
HeapFree(GetProcessHeap(), 0, This);
return NULL;
}
}
This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags); 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 /* create the file mapping object
*/ */
This->hfilemap = CreateFileMappingA(This->hfile, This->hfilemap = CreateFileMappingA(This->hfile,
@ -126,14 +172,10 @@ BigBlockFile * BIGBLOCKFILE_Construct(
if (This->hfilemap == NULL) if (This->hfilemap == NULL)
{ {
CloseHandle(This->hfile); CloseHandle(This->hfile);
HeapFree(GetProcessHeap(), 0, This); return FALSE;
return NULL;
} }
/* initialize this
*/
This->filesize.LowPart = GetFileSize(This->hfile, NULL); This->filesize.LowPart = GetFileSize(This->hfile, NULL);
This->blocksize = blocksize;
/* create the mapped pages list /* create the mapped pages list
*/ */
@ -143,17 +185,48 @@ BigBlockFile * BIGBLOCKFILE_Construct(
{ {
CloseHandle(This->hfilemap); CloseHandle(This->hfilemap);
CloseHandle(This->hfile); CloseHandle(This->hfile);
HeapFree(GetProcessHeap(), 0, This); return FALSE;
return NULL;
} }
This->maplisthead->next = NULL; This->maplisthead->next = NULL;
/* initialize the block list return TRUE;
*/ }
This->headblock = NULL;
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,6 +237,8 @@ BigBlockFile * BIGBLOCKFILE_Construct(
void BIGBLOCKFILE_Destructor( void BIGBLOCKFILE_Destructor(
LPBIGBLOCKFILE This) LPBIGBLOCKFILE This)
{ {
if (This->fileBased)
{
/* unmap all views and destroy the mapped page list /* unmap all views and destroy the mapped page list
*/ */
BIGBLOCKFILE_FreeAllMappedPages(This); BIGBLOCKFILE_FreeAllMappedPages(This);
@ -173,6 +248,17 @@ void BIGBLOCKFILE_Destructor(
*/ */
CloseHandle(This->hfilemap); CloseHandle(This->hfilemap);
CloseHandle(This->hfile); CloseHandle(This->hfile);
}
else
{
GlobalUnlock(This->hbytearray);
ILockBytes_Release(This->pLkbyt);
}
/*
* Destroy the blocks list.
*/
BIGBLOCKFILE_RemoveAllBlocks(This);
/* destroy this /* destroy this
*/ */
@ -264,6 +350,8 @@ void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
if (theBigBlock == NULL) if (theBigBlock == NULL)
return; return;
if (This->fileBased)
{
/* /*
* find out which page this block is in * find out which page this block is in
*/ */
@ -273,6 +361,7 @@ void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
* release this page * release this page
*/ */
BIGBLOCKFILE_ReleaseMappedPage(This, page_num, theBigBlock->access_mode); BIGBLOCKFILE_ReleaseMappedPage(This, page_num, theBigBlock->access_mode);
}
/* /*
* remove block from list * remove block from list
@ -291,6 +380,8 @@ void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
if (This->filesize.LowPart == newSize.LowPart) if (This->filesize.LowPart == newSize.LowPart)
return; return;
if (This->fileBased)
{
/* /*
* unmap all views, must be done before call to SetEndFile * unmap all views, must be done before call to SetEndFile
*/ */
@ -316,6 +407,27 @@ void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
This->flProtect, This->flProtect,
0, 0, 0, 0,
NULL); 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);
}
/*
* empty the blocks list.
*/
BIGBLOCKFILE_RemoveAllBlocks(This);
This->filesize.LowPart = newSize.LowPart; This->filesize.LowPart = newSize.LowPart;
This->filesize.HighPart = newSize.HighPart; This->filesize.HighPart = newSize.HighPart;
@ -342,7 +454,7 @@ static void* BIGBLOCKFILE_GetBigBlockPointer(
ULONG index, ULONG index,
DWORD desired_access) DWORD desired_access)
{ {
DWORD page_num, block_num; DWORD block_num;
void * pBytes; void * pBytes;
BigBlock *aBigBlock; BigBlock *aBigBlock;
@ -369,6 +481,10 @@ static void* BIGBLOCKFILE_GetBigBlockPointer(
* else aBigBlock->lpBigBlock == NULL, it's a new block * else aBigBlock->lpBigBlock == NULL, it's a new block
*/ */
if (This->fileBased)
{
DWORD page_num;
/* find out which page this block is in /* find out which page this block is in
*/ */
page_num = index / BLOCKS_PER_PAGE; page_num = index / BLOCKS_PER_PAGE;
@ -380,6 +496,12 @@ static void* BIGBLOCKFILE_GetBigBlockPointer(
/* get a pointer to the first byte in the page /* get a pointer to the first byte in the page
*/ */
pBytes = BIGBLOCKFILE_GetMappedView(This, page_num, desired_access); pBytes = BIGBLOCKFILE_GetMappedView(This, page_num, desired_access);
}
else
{
pBytes = This->pbytearray;
block_num = index;
}
if (pBytes == NULL) if (pBytes == NULL)
return NULL; return NULL;
@ -508,6 +630,24 @@ static BigBlock* BIGBLOCKFILE_AddBigBlock(
return NULL; 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] * BIGBLOCKFILE_RemoveBlock [PRIVATE]
* *

View File

@ -1569,26 +1569,6 @@ static void _create_istorage16(LPSTORAGE16 *stg) {
* Storage API functions * 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] * StgCreateDocFile16 [STORAGE.1]
*/ */

View File

@ -2023,7 +2023,9 @@ HRESULT WINAPI StorageImpl_SetStateBits(
HRESULT StorageImpl_Construct( HRESULT StorageImpl_Construct(
StorageImpl* This, StorageImpl* This,
HANDLE hFile, HANDLE hFile,
DWORD openFlags) ILockBytes* pLkbyt,
DWORD openFlags,
BOOL fileBased)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
StgProperty currentProperty; StgProperty currentProperty;
@ -2058,8 +2060,10 @@ HRESULT StorageImpl_Construct(
This->bigBlockSize = DEF_BIG_BLOCK_SIZE; This->bigBlockSize = DEF_BIG_BLOCK_SIZE;
This->smallBlockSize = DEF_SMALL_BLOCK_SIZE; This->smallBlockSize = DEF_SMALL_BLOCK_SIZE;
This->bigBlockFile = BIGBLOCKFILE_Construct(hFile, This->bigBlockFile = BIGBLOCKFILE_Construct(hFile,
pLkbyt,
openFlags, openFlags,
This->bigBlockSize); This->bigBlockSize,
fileBased);
if (This->bigBlockFile == 0) if (This->bigBlockFile == 0)
return E_FAIL; return E_FAIL;
@ -5277,7 +5281,9 @@ HRESULT WINAPI StgCreateDocfile(
hr = StorageImpl_Construct( hr = StorageImpl_Construct(
newStorage, newStorage,
hFile, hFile,
grfMode); NULL,
grfMode,
TRUE);
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -5365,7 +5371,9 @@ HRESULT WINAPI StgOpenStorage(
hr = StorageImpl_Construct( hr = StorageImpl_Construct(
newStorage, newStorage,
hFile, hFile,
grfMode); NULL,
grfMode,
TRUE);
if (FAILED(hr)) 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 * 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 struct BigBlockFile
{ {
BOOL fileBased;
ULARGE_INTEGER filesize; ULARGE_INTEGER filesize;
ULONG blocksize; ULONG blocksize;
HANDLE hfile; HANDLE hfile;
HANDLE hfilemap; HANDLE hfilemap;
DWORD flProtect; DWORD flProtect;
MappedPage *maplisthead; MappedPage *maplisthead;
ILockBytes *pLkbyt;
HGLOBAL hbytearray;
LPVOID pbytearray;
BigBlock *headblock; BigBlock *headblock;
}; };
@ -149,8 +153,10 @@ struct BigBlockFile
* data structure. * data structure.
*/ */
BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile, BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile,
ILockBytes* pLkByt,
DWORD openFlags, DWORD openFlags,
ULONG blocksize); ULONG blocksize,
BOOL fileBased);
void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This); void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index); void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index);
void* BIGBLOCKFILE_GetROBigBlock(LPBIGBLOCKFILE This, ULONG index); void* BIGBLOCKFILE_GetROBigBlock(LPBIGBLOCKFILE This, ULONG index);
@ -367,7 +373,9 @@ void StorageImpl_Destroy(
HRESULT StorageImpl_Construct( HRESULT StorageImpl_Construct(
StorageImpl* This, StorageImpl* This,
HANDLE hFile, HANDLE hFile,
DWORD openFlags); ILockBytes* pLkbyt,
DWORD openFlags,
BOOL fileBased);
BOOL StorageImpl_ReadBigBlock( BOOL StorageImpl_ReadBigBlock(
StorageImpl* This, StorageImpl* This,

View File

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