mirror of
https://github.com/reactos/reactos.git
synced 2025-05-13 22:30:21 +00:00
sync ole32 with wine 1.1.14
svn path=/trunk/; revision=39225
This commit is contained in:
parent
5bb24c753a
commit
cca55b4587
8 changed files with 325 additions and 324 deletions
|
@ -1694,7 +1694,7 @@ HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid)
|
||||||
return CO_E_CLASSSTRING;
|
return CO_E_CLASSSTRING;
|
||||||
}
|
}
|
||||||
RegCloseKey(xhkey);
|
RegCloseKey(xhkey);
|
||||||
return CLSIDFromString(buf2,clsid);
|
return __CLSIDFromString(buf2,clsid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3352,10 +3352,46 @@ HRESULT WINAPI CoCopyProxy(IUnknown *pProxy, IUnknown **ppCopy)
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI CoGetCallContext(REFIID riid, void **ppv)
|
HRESULT WINAPI CoGetCallContext(REFIID riid, void **ppv)
|
||||||
{
|
{
|
||||||
FIXME("(%s, %p): stub\n", debugstr_guid(riid), ppv);
|
struct oletls *info = COM_CurrentInfo();
|
||||||
|
|
||||||
*ppv = NULL;
|
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
|
||||||
return E_NOINTERFACE;
|
|
||||||
|
if (!info)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
if (!info->call_state)
|
||||||
|
return RPC_E_CALL_COMPLETE;
|
||||||
|
|
||||||
|
return IUnknown_QueryInterface(info->call_state, riid, ppv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* CoSwitchCallContext [OLE32.@]
|
||||||
|
*
|
||||||
|
* Switches the context of the currently executing server call in the current
|
||||||
|
* thread.
|
||||||
|
*
|
||||||
|
* PARAMS
|
||||||
|
* pObject [I] Pointer to new context object
|
||||||
|
* ppOldObject [O] Pointer to memory that will receive old context object pointer
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* Success: S_OK.
|
||||||
|
* Failure: HRESULT code.
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI CoSwitchCallContext(IUnknown *pObject, IUnknown **ppOldObject)
|
||||||
|
{
|
||||||
|
struct oletls *info = COM_CurrentInfo();
|
||||||
|
|
||||||
|
TRACE("(%p, %p)\n", pObject, ppOldObject);
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
*ppOldObject = info->call_state;
|
||||||
|
info->call_state = pObject; /* CoSwitchCallContext does not addref nor release objects */
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -3915,9 +3951,12 @@ HRESULT WINAPI CoGetObjectContext(REFIID riid, void **ppv)
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI CoGetContextToken( ULONG_PTR *token )
|
HRESULT WINAPI CoGetContextToken( ULONG_PTR *token )
|
||||||
{
|
{
|
||||||
|
struct oletls *info = COM_CurrentInfo();
|
||||||
static int calls;
|
static int calls;
|
||||||
if(!(calls++)) FIXME( "stub\n" );
|
if(!(calls++)) FIXME( "stub\n" );
|
||||||
if (token) *token = 0;
|
if (!info)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
if (token) *token = info->context_token;
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,12 +175,18 @@ struct oletls
|
||||||
struct apartment *apt;
|
struct apartment *apt;
|
||||||
IErrorInfo *errorinfo; /* see errorinfo.c */
|
IErrorInfo *errorinfo; /* see errorinfo.c */
|
||||||
IUnknown *state; /* see CoSetState */
|
IUnknown *state; /* see CoSetState */
|
||||||
|
DWORD apt_mask; /* apartment mask (+0Ch on x86) */
|
||||||
IInitializeSpy *spy; /* The "SPY" from CoInitializeSpy */
|
IInitializeSpy *spy; /* The "SPY" from CoInitializeSpy */
|
||||||
DWORD inits; /* number of times CoInitializeEx called */
|
DWORD inits; /* number of times CoInitializeEx called */
|
||||||
DWORD ole_inits; /* number of times OleInitialize called */
|
DWORD ole_inits; /* number of times OleInitialize called */
|
||||||
GUID causality_id; /* unique identifier for each COM call */
|
GUID causality_id; /* unique identifier for each COM call */
|
||||||
LONG pending_call_count_client; /* number of client calls pending */
|
LONG pending_call_count_client; /* number of client calls pending */
|
||||||
LONG pending_call_count_server; /* number of server calls pending */
|
LONG pending_call_count_server; /* number of server calls pending */
|
||||||
|
DWORD unknown;
|
||||||
|
ULONG_PTR context_token; /* (+38h on x86) */
|
||||||
|
IUnknown *call_state; /* current call context (+3Ch on x86) */
|
||||||
|
DWORD unknown2[46];
|
||||||
|
IUnknown *cancel_object; /* cancel object set by CoSetCancelObject (+F8h on x86) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
@ stdcall CoSetProxyBlanket(ptr long long wstr long long ptr long)
|
@ stdcall CoSetProxyBlanket(ptr long long wstr long long ptr long)
|
||||||
@ stdcall CoSetState(ptr)
|
@ stdcall CoSetState(ptr)
|
||||||
@ stdcall CoSuspendClassObjects()
|
@ stdcall CoSuspendClassObjects()
|
||||||
@ stub CoSwitchCallContext
|
@ stdcall CoSwitchCallContext(ptr ptr)
|
||||||
@ stdcall CoTaskMemAlloc(long)
|
@ stdcall CoTaskMemAlloc(long)
|
||||||
@ stdcall CoTaskMemFree(ptr)
|
@ stdcall CoTaskMemFree(ptr)
|
||||||
@ stdcall CoTaskMemRealloc(ptr long)
|
@ stdcall CoTaskMemRealloc(ptr long)
|
||||||
|
|
|
@ -16,5 +16,4 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cpp_quote("#include <winuser.h>")
|
|
||||||
#include "oleidl.idl"
|
#include "oleidl.idl"
|
||||||
|
|
|
@ -85,6 +85,8 @@ typedef struct
|
||||||
* file this mapping represents. (The mappings are always
|
* file this mapping represents. (The mappings are always
|
||||||
* PAGE_SIZE-aligned.)
|
* PAGE_SIZE-aligned.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct MappedPage MappedPage;
|
||||||
struct MappedPage
|
struct MappedPage
|
||||||
{
|
{
|
||||||
MappedPage *next;
|
MappedPage *next;
|
||||||
|
@ -99,22 +101,23 @@ struct MappedPage
|
||||||
BlockBits writable_blocks;
|
BlockBits writable_blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BigBlockFile
|
||||||
|
{
|
||||||
|
BOOL fileBased;
|
||||||
|
ULARGE_INTEGER filesize;
|
||||||
|
ULONG blocksize;
|
||||||
|
HANDLE hfile;
|
||||||
|
HANDLE hfilemap;
|
||||||
|
DWORD flProtect;
|
||||||
|
MappedPage *maplist;
|
||||||
|
MappedPage *victimhead, *victimtail;
|
||||||
|
ULONG num_victim_pages;
|
||||||
|
ILockBytes *pLkbyt;
|
||||||
|
};
|
||||||
|
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
* Prototypes for private methods
|
* Prototypes for private methods
|
||||||
*/
|
*/
|
||||||
static void* BIGBLOCKFILE_GetMappedView(LPBIGBLOCKFILE This,
|
|
||||||
DWORD page_index);
|
|
||||||
static void BIGBLOCKFILE_ReleaseMappedPage(LPBIGBLOCKFILE This,
|
|
||||||
MappedPage *page);
|
|
||||||
static void BIGBLOCKFILE_FreeAllMappedPages(LPBIGBLOCKFILE This);
|
|
||||||
static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This);
|
|
||||||
static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This);
|
|
||||||
static MappedPage* BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
|
|
||||||
ULONG page_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_DeleteList(LPBIGBLOCKFILE This, MappedPage *list);
|
|
||||||
|
|
||||||
/* Note that this evaluates a and b multiple times, so don't
|
/* Note that this evaluates a and b multiple times, so don't
|
||||||
* pass expressions with side effects. */
|
* pass expressions with side effects. */
|
||||||
|
@ -153,58 +156,6 @@ static inline void BIGBLOCKFILE_Zero(BlockBits *bb)
|
||||||
memset(bb->bits, 0, sizeof(bb->bits));
|
memset(bb->bits, 0, sizeof(bb->bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* BIGBLOCKFILE_Construct
|
|
||||||
*
|
|
||||||
* Construct a big block file. Create the file mapping object.
|
|
||||||
* Create the read only mapped pages list, the writable mapped page list
|
|
||||||
* and the blocks in use list.
|
|
||||||
*/
|
|
||||||
BigBlockFile * BIGBLOCKFILE_Construct(
|
|
||||||
HANDLE hFile,
|
|
||||||
ILockBytes* pLkByt,
|
|
||||||
DWORD openFlags,
|
|
||||||
ULONG blocksize,
|
|
||||||
BOOL fileBased)
|
|
||||||
{
|
|
||||||
LPBIGBLOCKFILE This;
|
|
||||||
|
|
||||||
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BigBlockFile));
|
|
||||||
|
|
||||||
if (This == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
This->fileBased = fileBased;
|
|
||||||
|
|
||||||
This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags);
|
|
||||||
|
|
||||||
This->blocksize = blocksize;
|
|
||||||
|
|
||||||
This->maplist = NULL;
|
|
||||||
This->victimhead = NULL;
|
|
||||||
This->victimtail = NULL;
|
|
||||||
This->num_victim_pages = 0;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return This;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* BIGBLOCKFILE_FileInit
|
* BIGBLOCKFILE_FileInit
|
||||||
*
|
*
|
||||||
|
@ -212,10 +163,7 @@ BigBlockFile * BIGBLOCKFILE_Construct(
|
||||||
*/
|
*/
|
||||||
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
|
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
|
||||||
{
|
{
|
||||||
This->pLkbyt = NULL;
|
This->pLkbyt = NULL;
|
||||||
This->hbytearray = 0;
|
|
||||||
This->pbytearray = NULL;
|
|
||||||
|
|
||||||
This->hfile = hFile;
|
This->hfile = hFile;
|
||||||
|
|
||||||
if (This->hfile == INVALID_HANDLE_VALUE)
|
if (This->hfile == INVALID_HANDLE_VALUE)
|
||||||
|
@ -251,164 +199,22 @@ static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* BIGBLOCKFILE_MemInit
|
* BIGBLOCKFILE_LockBytesInit
|
||||||
*
|
*
|
||||||
* Initialize a big block object supported by an ILockBytes on HGLOABL.
|
* Initialize a big block object supported by an ILockBytes.
|
||||||
*/
|
*/
|
||||||
static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
|
static BOOL BIGBLOCKFILE_LockBytesInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
|
||||||
{
|
{
|
||||||
This->hfile = 0;
|
This->hfile = 0;
|
||||||
This->hfilemap = 0;
|
This->hfilemap = 0;
|
||||||
|
This->pLkbyt = plkbyt;
|
||||||
|
ILockBytes_AddRef(This->pLkbyt);
|
||||||
|
|
||||||
/*
|
/* We'll get the size directly with ILockBytes_Stat */
|
||||||
* Retrieve the handle to the byte array from the LockByte object.
|
This->filesize.QuadPart = 0;
|
||||||
*/
|
|
||||||
if (GetHGlobalFromILockBytes(plkbyt, &(This->hbytearray)) != S_OK)
|
|
||||||
{
|
|
||||||
FIXME("May not be an ILockBytes on HGLOBAL\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
This->pLkbyt = plkbyt;
|
TRACE("ILockBytes %p\n", This->pLkbyt);
|
||||||
|
return TRUE;
|
||||||
/*
|
|
||||||
* Increment the reference count of the ILockByte object since
|
|
||||||
* we're keeping a reference to it.
|
|
||||||
*/
|
|
||||||
ILockBytes_AddRef(This->pLkbyt);
|
|
||||||
|
|
||||||
This->filesize.u.LowPart = GlobalSize(This->hbytearray);
|
|
||||||
This->filesize.u.HighPart = 0;
|
|
||||||
|
|
||||||
This->pbytearray = GlobalLock(This->hbytearray);
|
|
||||||
|
|
||||||
TRACE("mem on %p len %u\n", This->pbytearray, This->filesize.u.LowPart);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* BIGBLOCKFILE_Destructor
|
|
||||||
*
|
|
||||||
* Destructor. Clean up, free memory.
|
|
||||||
*/
|
|
||||||
void BIGBLOCKFILE_Destructor(
|
|
||||||
LPBIGBLOCKFILE This)
|
|
||||||
{
|
|
||||||
BIGBLOCKFILE_FreeAllMappedPages(This);
|
|
||||||
|
|
||||||
if (This->fileBased)
|
|
||||||
{
|
|
||||||
CloseHandle(This->hfilemap);
|
|
||||||
CloseHandle(This->hfile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GlobalUnlock(This->hbytearray);
|
|
||||||
ILockBytes_Release(This->pLkbyt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destroy this
|
|
||||||
*/
|
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* BIGBLOCKFILE_EnsureExists
|
|
||||||
*
|
|
||||||
* Grows the file if necessary to make sure the block is valid.
|
|
||||||
*/
|
|
||||||
void BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* block index starts at -1
|
|
||||||
* translate to zero based index
|
|
||||||
*/
|
|
||||||
if (index == 0xffffffff)
|
|
||||||
index = 0;
|
|
||||||
else
|
|
||||||
index++;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* make sure that the block physically exists
|
|
||||||
*/
|
|
||||||
if ((This->blocksize * (index + 1)) > This->filesize.u.LowPart)
|
|
||||||
{
|
|
||||||
ULARGE_INTEGER newSize;
|
|
||||||
|
|
||||||
newSize.u.HighPart = 0;
|
|
||||||
newSize.u.LowPart = This->blocksize * (index + 1);
|
|
||||||
|
|
||||||
BIGBLOCKFILE_SetSize(This, newSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* BIGBLOCKFILE_SetSize
|
|
||||||
*
|
|
||||||
* Sets the size of the file.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
|
|
||||||
{
|
|
||||||
if (This->filesize.u.LowPart == newSize.u.LowPart)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TRACE("from %u to %u\n", This->filesize.u.LowPart, newSize.u.LowPart);
|
|
||||||
/*
|
|
||||||
* unmap all views, must be done before call to SetEndFile
|
|
||||||
*
|
|
||||||
* Just ditch the victim list because there is no guarantee we will need them
|
|
||||||
* and it is not worth the performance hit to unmap and remap them all.
|
|
||||||
*/
|
|
||||||
BIGBLOCKFILE_DeleteList(This, This->victimhead);
|
|
||||||
This->victimhead = NULL;
|
|
||||||
This->victimtail = NULL;
|
|
||||||
This->num_victim_pages = 0;
|
|
||||||
|
|
||||||
BIGBLOCKFILE_UnmapAllMappedPages(This);
|
|
||||||
|
|
||||||
if (This->fileBased)
|
|
||||||
{
|
|
||||||
LARGE_INTEGER newpos;
|
|
||||||
|
|
||||||
newpos.QuadPart = newSize.QuadPart;
|
|
||||||
if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN))
|
|
||||||
{
|
|
||||||
if( This->hfilemap ) CloseHandle(This->hfilemap);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
This->filesize.u.LowPart = newSize.u.LowPart;
|
|
||||||
This->filesize.u.HighPart = newSize.u.HighPart;
|
|
||||||
|
|
||||||
BIGBLOCKFILE_RemapAllMappedPages(This);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -445,6 +251,64 @@ static void BIGBLOCKFILE_LinkHeadPage(MappedPage **head, MappedPage *page)
|
||||||
*head = page;
|
*head = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL BIGBLOCKFILE_MapPage(BigBlockFile *This, MappedPage *page)
|
||||||
|
{
|
||||||
|
DWORD lowoffset = PAGE_SIZE * page->page_index;
|
||||||
|
DWORD numBytesToMap;
|
||||||
|
DWORD desired_access;
|
||||||
|
|
||||||
|
assert(This->fileBased);
|
||||||
|
|
||||||
|
if( !This->hfilemap )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (lowoffset + PAGE_SIZE > This->filesize.u.LowPart)
|
||||||
|
numBytesToMap = This->filesize.u.LowPart - lowoffset;
|
||||||
|
else
|
||||||
|
numBytesToMap = PAGE_SIZE;
|
||||||
|
|
||||||
|
if (This->flProtect == PAGE_READONLY)
|
||||||
|
desired_access = FILE_MAP_READ;
|
||||||
|
else
|
||||||
|
desired_access = FILE_MAP_WRITE;
|
||||||
|
|
||||||
|
page->lpBytes = MapViewOfFile(This->hfilemap, desired_access, 0,
|
||||||
|
lowoffset, numBytesToMap);
|
||||||
|
page->mapped_bytes = numBytesToMap;
|
||||||
|
|
||||||
|
TRACE("mapped page %u to %p\n", page->page_index, page->lpBytes);
|
||||||
|
|
||||||
|
return page->lpBytes != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static MappedPage *BIGBLOCKFILE_CreatePage(BigBlockFile *This, ULONG page_index)
|
||||||
|
{
|
||||||
|
MappedPage *page;
|
||||||
|
|
||||||
|
page = HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
|
||||||
|
if (page == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
page->page_index = page_index;
|
||||||
|
page->refcnt = 1;
|
||||||
|
|
||||||
|
page->next = NULL;
|
||||||
|
page->prev = NULL;
|
||||||
|
|
||||||
|
if (!BIGBLOCKFILE_MapPage(This, page))
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(),0,page);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIGBLOCKFILE_Zero(&page->readable_blocks);
|
||||||
|
BIGBLOCKFILE_Zero(&page->writable_blocks);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* BIGBLOCKFILE_GetMappedView [PRIVATE]
|
* BIGBLOCKFILE_GetMappedView [PRIVATE]
|
||||||
*
|
*
|
||||||
|
@ -495,77 +359,16 @@ static void * BIGBLOCKFILE_GetMappedView(
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL BIGBLOCKFILE_MapPage(LPBIGBLOCKFILE This, MappedPage *page)
|
|
||||||
{
|
|
||||||
DWORD lowoffset = PAGE_SIZE * page->page_index;
|
|
||||||
|
|
||||||
if (This->fileBased)
|
|
||||||
{
|
|
||||||
DWORD numBytesToMap;
|
|
||||||
DWORD desired_access;
|
|
||||||
|
|
||||||
if( !This->hfilemap )
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (lowoffset + PAGE_SIZE > This->filesize.u.LowPart)
|
|
||||||
numBytesToMap = This->filesize.u.LowPart - lowoffset;
|
|
||||||
else
|
|
||||||
numBytesToMap = PAGE_SIZE;
|
|
||||||
|
|
||||||
if (This->flProtect == PAGE_READONLY)
|
|
||||||
desired_access = FILE_MAP_READ;
|
|
||||||
else
|
|
||||||
desired_access = FILE_MAP_WRITE;
|
|
||||||
|
|
||||||
page->lpBytes = MapViewOfFile(This->hfilemap, desired_access, 0,
|
|
||||||
lowoffset, numBytesToMap);
|
|
||||||
page->mapped_bytes = numBytesToMap;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
page->lpBytes = (LPBYTE)This->pbytearray + lowoffset;
|
|
||||||
page->mapped_bytes = PAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("mapped page %u to %p\n", page->page_index, page->lpBytes);
|
|
||||||
|
|
||||||
return page->lpBytes != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MappedPage *BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
|
|
||||||
ULONG page_index)
|
|
||||||
{
|
|
||||||
MappedPage *page;
|
|
||||||
|
|
||||||
page = HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
|
|
||||||
if (page == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
page->page_index = page_index;
|
|
||||||
page->refcnt = 1;
|
|
||||||
|
|
||||||
page->next = NULL;
|
|
||||||
page->prev = NULL;
|
|
||||||
|
|
||||||
if (!BIGBLOCKFILE_MapPage(This, page))
|
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(),0,page);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
BIGBLOCKFILE_Zero(&page->readable_blocks);
|
|
||||||
BIGBLOCKFILE_Zero(&page->writable_blocks);
|
|
||||||
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void BIGBLOCKFILE_UnmapPage(LPBIGBLOCKFILE This, MappedPage *page)
|
static void BIGBLOCKFILE_UnmapPage(LPBIGBLOCKFILE This, MappedPage *page)
|
||||||
{
|
{
|
||||||
TRACE("%d at %p\n", page->page_index, page->lpBytes);
|
TRACE("%d at %p\n", page->page_index, page->lpBytes);
|
||||||
|
|
||||||
|
assert(This->fileBased);
|
||||||
|
|
||||||
if (page->refcnt > 0)
|
if (page->refcnt > 0)
|
||||||
ERR("unmapping inuse page %p\n", page->lpBytes);
|
ERR("unmapping inuse page %p\n", page->lpBytes);
|
||||||
|
|
||||||
if (This->fileBased && page->lpBytes)
|
if (page->lpBytes)
|
||||||
UnmapViewOfFile(page->lpBytes);
|
UnmapViewOfFile(page->lpBytes);
|
||||||
|
|
||||||
page->lpBytes = NULL;
|
page->lpBytes = NULL;
|
||||||
|
@ -898,9 +701,79 @@ static HRESULT ImplBIGBLOCKFILE_WriteAt(
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* BIGBLOCKFILE_Construct
|
||||||
|
*
|
||||||
|
* Construct a big block file. Create the file mapping object.
|
||||||
|
* Create the read only mapped pages list, the writable mapped page list
|
||||||
|
* and the blocks in use list.
|
||||||
|
*/
|
||||||
|
BigBlockFile *BIGBLOCKFILE_Construct(HANDLE hFile, ILockBytes* pLkByt, DWORD openFlags,
|
||||||
|
ULONG blocksize, BOOL fileBased)
|
||||||
|
{
|
||||||
|
BigBlockFile *This;
|
||||||
|
|
||||||
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
|
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BigBlockFile));
|
||||||
void* buffer, ULONG size, ULONG* bytesRead)
|
|
||||||
|
if (This == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
This->fileBased = fileBased;
|
||||||
|
This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags);
|
||||||
|
This->blocksize = blocksize;
|
||||||
|
|
||||||
|
This->maplist = NULL;
|
||||||
|
This->victimhead = NULL;
|
||||||
|
This->victimtail = NULL;
|
||||||
|
This->num_victim_pages = 0;
|
||||||
|
|
||||||
|
if (This->fileBased)
|
||||||
|
{
|
||||||
|
if (!BIGBLOCKFILE_FileInit(This, hFile))
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!BIGBLOCKFILE_LockBytesInit(This, pLkByt))
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return This;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* BIGBLOCKFILE_Destructor
|
||||||
|
*
|
||||||
|
* Destructor. Clean up, free memory.
|
||||||
|
*/
|
||||||
|
void BIGBLOCKFILE_Destructor(BigBlockFile *This)
|
||||||
|
{
|
||||||
|
BIGBLOCKFILE_FreeAllMappedPages(This);
|
||||||
|
|
||||||
|
if (This->fileBased)
|
||||||
|
{
|
||||||
|
CloseHandle(This->hfilemap);
|
||||||
|
CloseHandle(This->hfile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ILockBytes_Release(This->pLkbyt);
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* BIGBLOCKFILE_ReadAt
|
||||||
|
*/
|
||||||
|
HRESULT BIGBLOCKFILE_ReadAt(BigBlockFile *This, ULARGE_INTEGER offset,
|
||||||
|
void* buffer, ULONG size, ULONG* bytesRead)
|
||||||
{
|
{
|
||||||
if (This->fileBased)
|
if (This->fileBased)
|
||||||
return ImplBIGBLOCKFILE_ReadAt(This,offset,buffer,size,bytesRead);
|
return ImplBIGBLOCKFILE_ReadAt(This,offset,buffer,size,bytesRead);
|
||||||
|
@ -908,11 +781,113 @@ HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
|
||||||
return ILockBytes_ReadAt(This->pLkbyt,offset,buffer,size,bytesRead);
|
return ILockBytes_ReadAt(This->pLkbyt,offset,buffer,size,bytesRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
|
/******************************************************************************
|
||||||
const void* buffer, ULONG size, ULONG* bytesRead)
|
* BIGBLOCKFILE_WriteAt
|
||||||
|
*/
|
||||||
|
HRESULT BIGBLOCKFILE_WriteAt(BigBlockFile *This, ULARGE_INTEGER offset,
|
||||||
|
const void* buffer, ULONG size, ULONG* bytesRead)
|
||||||
{
|
{
|
||||||
if (This->fileBased)
|
if (This->fileBased)
|
||||||
return ImplBIGBLOCKFILE_WriteAt(This,offset,buffer,size,bytesRead);
|
return ImplBIGBLOCKFILE_WriteAt(This,offset,buffer,size,bytesRead);
|
||||||
else
|
else
|
||||||
return ILockBytes_WriteAt(This->pLkbyt,offset,buffer,size,bytesRead);
|
return ILockBytes_WriteAt(This->pLkbyt,offset,buffer,size,bytesRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* BIGBLOCKFILE_SetSize
|
||||||
|
*
|
||||||
|
* Sets the size of the file.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
HRESULT BIGBLOCKFILE_SetSize(BigBlockFile *This, ULARGE_INTEGER newSize)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
LARGE_INTEGER newpos;
|
||||||
|
|
||||||
|
if (!This->fileBased)
|
||||||
|
return ILockBytes_SetSize(This->pLkbyt, newSize);
|
||||||
|
|
||||||
|
if (This->filesize.u.LowPart == newSize.u.LowPart)
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
TRACE("from %u to %u\n", This->filesize.u.LowPart, newSize.u.LowPart);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unmap all views, must be done before call to SetEndFile.
|
||||||
|
*
|
||||||
|
* Just ditch the victim list because there is no guarantee we will need them
|
||||||
|
* and it is not worth the performance hit to unmap and remap them all.
|
||||||
|
*/
|
||||||
|
BIGBLOCKFILE_DeleteList(This, This->victimhead);
|
||||||
|
This->victimhead = NULL;
|
||||||
|
This->victimtail = NULL;
|
||||||
|
This->num_victim_pages = 0;
|
||||||
|
|
||||||
|
BIGBLOCKFILE_UnmapAllMappedPages(This);
|
||||||
|
|
||||||
|
newpos.QuadPart = newSize.QuadPart;
|
||||||
|
if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN))
|
||||||
|
{
|
||||||
|
if( This->hfilemap ) CloseHandle(This->hfilemap);
|
||||||
|
|
||||||
|
SetEndOfFile(This->hfile);
|
||||||
|
|
||||||
|
/* re-create the file mapping object */
|
||||||
|
This->hfilemap = CreateFileMappingA(This->hfile, NULL, This->flProtect,
|
||||||
|
0, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
This->filesize = newSize;
|
||||||
|
BIGBLOCKFILE_RemapAllMappedPages(This);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* BIGBLOCKFILE_GetSize
|
||||||
|
*
|
||||||
|
* Gets the size of the file.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static HRESULT BIGBLOCKFILE_GetSize(BigBlockFile *This, ULARGE_INTEGER *size)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
if(This->fileBased)
|
||||||
|
*size = This->filesize;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
STATSTG stat;
|
||||||
|
hr = ILockBytes_Stat(This->pLkbyt, &stat, STATFLAG_NONAME);
|
||||||
|
if(SUCCEEDED(hr)) *size = stat.cbSize;
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* BIGBLOCKFILE_EnsureExists
|
||||||
|
*
|
||||||
|
* Grows the file if necessary to make sure the block is valid.
|
||||||
|
*/
|
||||||
|
HRESULT BIGBLOCKFILE_EnsureExists(BigBlockFile *This, ULONG index)
|
||||||
|
{
|
||||||
|
ULARGE_INTEGER size;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
/* Block index starts at -1 translate to zero based index */
|
||||||
|
if (index == 0xffffffff)
|
||||||
|
index = 0;
|
||||||
|
else
|
||||||
|
index++;
|
||||||
|
|
||||||
|
hr = BIGBLOCKFILE_GetSize(This, &size);
|
||||||
|
if(FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
/* make sure that the block physically exists */
|
||||||
|
if ((This->blocksize * (index + 1)) > size.QuadPart)
|
||||||
|
{
|
||||||
|
ULARGE_INTEGER newSize;
|
||||||
|
|
||||||
|
newSize.QuadPart = This->blocksize * (index + 1);
|
||||||
|
hr = BIGBLOCKFILE_SetSize(This, newSize);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
|
@ -152,27 +152,7 @@ struct StgProperty
|
||||||
* this section appear in stg_bigblockfile.c
|
* this section appear in stg_bigblockfile.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Declaration of the data structures
|
|
||||||
*/
|
|
||||||
typedef struct BigBlockFile BigBlockFile,*LPBIGBLOCKFILE;
|
typedef struct BigBlockFile BigBlockFile,*LPBIGBLOCKFILE;
|
||||||
typedef struct MappedPage MappedPage,*LPMAPPEDPAGE;
|
|
||||||
|
|
||||||
struct BigBlockFile
|
|
||||||
{
|
|
||||||
BOOL fileBased;
|
|
||||||
ULARGE_INTEGER filesize;
|
|
||||||
ULONG blocksize;
|
|
||||||
HANDLE hfile;
|
|
||||||
HANDLE hfilemap;
|
|
||||||
DWORD flProtect;
|
|
||||||
MappedPage *maplist;
|
|
||||||
MappedPage *victimhead, *victimtail;
|
|
||||||
ULONG num_victim_pages;
|
|
||||||
ILockBytes *pLkbyt;
|
|
||||||
HGLOBAL hbytearray;
|
|
||||||
LPVOID pbytearray;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Declaration of the functions used to manipulate the BigBlockFile
|
* Declaration of the functions used to manipulate the BigBlockFile
|
||||||
|
@ -184,8 +164,8 @@ BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile,
|
||||||
ULONG blocksize,
|
ULONG blocksize,
|
||||||
BOOL fileBased);
|
BOOL fileBased);
|
||||||
void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
|
void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
|
||||||
void BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index);
|
HRESULT BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index);
|
||||||
void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
|
HRESULT BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
|
||||||
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
|
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
|
||||||
void* buffer, ULONG size, ULONG* bytesRead);
|
void* buffer, ULONG size, ULONG* bytesRead);
|
||||||
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
|
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
|
||||||
|
|
|
@ -157,10 +157,10 @@ typedef struct tagPICTDESC {
|
||||||
} DUMMYUNIONNAME;
|
} DUMMYUNIONNAME;
|
||||||
} PICTDESC, *LPPICTDESC;
|
} PICTDESC, *LPPICTDESC;
|
||||||
|
|
||||||
typedef long OLE_XPOS_PIXELS;
|
typedef LONG OLE_XPOS_PIXELS;
|
||||||
typedef long OLE_YPOS_PIXELS;
|
typedef LONG OLE_YPOS_PIXELS;
|
||||||
typedef long OLE_XSIZE_PIXELS;
|
typedef LONG OLE_XSIZE_PIXELS;
|
||||||
typedef long OLE_YSIZE_PIXELS;
|
typedef LONG OLE_YSIZE_PIXELS;
|
||||||
typedef float OLE_XPOS_CONTAINER;
|
typedef float OLE_XPOS_CONTAINER;
|
||||||
typedef float OLE_YPOS_CONTAINER;
|
typedef float OLE_YPOS_CONTAINER;
|
||||||
typedef float OLE_XSIZE_CONTAINER;
|
typedef float OLE_XSIZE_CONTAINER;
|
||||||
|
|
|
@ -24,6 +24,8 @@ import "objidl.idl";
|
||||||
|
|
||||||
interface IOleInPlaceActiveObject;
|
interface IOleInPlaceActiveObject;
|
||||||
|
|
||||||
|
cpp_quote("#include <winuser.h>")
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* IOleTypes interface
|
* IOleTypes interface
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue