Commit ed1d88b6 authored by Thuy Nguyen's avatar Thuy Nguyen Committed by Alexandre Julliard

Implementation of IStorage supported by an implementation of

ILockBytes on top of an HGLOBAL.
parent 264360fc
......@@ -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);
......
......@@ -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;
......
......@@ -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
......@@ -95,8 +103,10 @@ static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags);
*/
BigBlockFile * BIGBLOCKFILE_Construct(
HANDLE hFile,
ILockBytes* pLkByt,
DWORD openFlags,
ULONG blocksize)
ULONG blocksize,
BOOL fileBased)
{
LPBIGBLOCKFILE This;
......@@ -105,16 +115,52 @@ BigBlockFile * BIGBLOCKFILE_Construct(
if (This == 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);
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,
......@@ -126,14 +172,10 @@ BigBlockFile * BIGBLOCKFILE_Construct(
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
*/
......@@ -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
return TRUE;
}
/******************************************************************************
* BIGBLOCKFILE_MemInit
*
* Initialize a big block object supported by an ILockBytes on HGLOABL.
*/
This->headblock = NULL;
static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
{
This->hfile = 0;
This->hfilemap = NULL;
This->maplisthead = NULL;
return This;
/*
* 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(
LPBIGBLOCKFILE This)
{
if (This->fileBased)
{
/* unmap all views and destroy the mapped page list
*/
BIGBLOCKFILE_FreeAllMappedPages(This);
......@@ -173,6 +248,17 @@ void BIGBLOCKFILE_Destructor(
*/
CloseHandle(This->hfilemap);
CloseHandle(This->hfile);
}
else
{
GlobalUnlock(This->hbytearray);
ILockBytes_Release(This->pLkbyt);
}
/*
* Destroy the blocks list.
*/
BIGBLOCKFILE_RemoveAllBlocks(This);
/* destroy this
*/
......@@ -264,6 +350,8 @@ void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
if (theBigBlock == NULL)
return;
if (This->fileBased)
{
/*
* find out which page this block is in
*/
......@@ -273,6 +361,7 @@ void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
* release this page
*/
BIGBLOCKFILE_ReleaseMappedPage(This, page_num, theBigBlock->access_mode);
}
/*
* remove block from list
......@@ -291,6 +380,8 @@ void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
if (This->filesize.LowPart == newSize.LowPart)
return;
if (This->fileBased)
{
/*
* unmap all views, must be done before call to SetEndFile
*/
......@@ -316,6 +407,27 @@ void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
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);
}
/*
* empty the blocks list.
*/
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,6 +481,10 @@ static void* BIGBLOCKFILE_GetBigBlockPointer(
* else aBigBlock->lpBigBlock == NULL, it's a new block
*/
if (This->fileBased)
{
DWORD page_num;
/* find out which page this block is in
*/
page_num = index / BLOCKS_PER_PAGE;
......@@ -380,6 +496,12 @@ static void* BIGBLOCKFILE_GetBigBlockPointer(
/* 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;
......@@ -509,6 +631,24 @@ static BigBlock* BIGBLOCKFILE_AddBigBlock(
}
/******************************************************************************
* 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]
*
* Removes the specified block from the blocks list.
......
......@@ -1570,26 +1570,6 @@ static void _create_istorage16(LPSTORAGE16 *stg) {
*/
/******************************************************************************
* 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]
*/
HRESULT WINAPI StgCreateDocFile16(
......
......@@ -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,122 @@ HRESULT WINAPI StgOpenStorage(
hr = StorageImpl_Construct(
newStorage,
hFile,
grfMode);
NULL,
grfMode,
TRUE);
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;
}
/******************************************************************************
* 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))
{
......@@ -5385,7 +5506,28 @@ HRESULT WINAPI StgOpenStorage(
}
/******************************************************************************
* WriteClassStg32 [OLE32.148]
* 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
*/
......
......@@ -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,
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment