mirror of
https://github.com/reactos/reactos.git
synced 2025-05-13 14:20:31 +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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
FIXME("(%s, %p): stub\n", debugstr_guid(riid), ppv);
|
||||
struct oletls *info = COM_CurrentInfo();
|
||||
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
|
||||
|
||||
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 )
|
||||
{
|
||||
struct oletls *info = COM_CurrentInfo();
|
||||
static int calls;
|
||||
if(!(calls++)) FIXME( "stub\n" );
|
||||
if (token) *token = 0;
|
||||
if (!info)
|
||||
return E_OUTOFMEMORY;
|
||||
if (token) *token = info->context_token;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
|
|
@ -175,12 +175,18 @@ struct oletls
|
|||
struct apartment *apt;
|
||||
IErrorInfo *errorinfo; /* see errorinfo.c */
|
||||
IUnknown *state; /* see CoSetState */
|
||||
DWORD apt_mask; /* apartment mask (+0Ch on x86) */
|
||||
IInitializeSpy *spy; /* The "SPY" from CoInitializeSpy */
|
||||
DWORD inits; /* number of times CoInitializeEx called */
|
||||
DWORD ole_inits; /* number of times OleInitialize called */
|
||||
GUID causality_id; /* unique identifier for each COM call */
|
||||
LONG pending_call_count_client; /* number of client 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 CoSetState(ptr)
|
||||
@ stdcall CoSuspendClassObjects()
|
||||
@ stub CoSwitchCallContext
|
||||
@ stdcall CoSwitchCallContext(ptr ptr)
|
||||
@ stdcall CoTaskMemAlloc(long)
|
||||
@ stdcall CoTaskMemFree(ptr)
|
||||
@ stdcall CoTaskMemRealloc(ptr long)
|
||||
|
|
|
@ -16,5 +16,4 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
cpp_quote("#include <winuser.h>")
|
||||
#include "oleidl.idl"
|
||||
|
|
|
@ -85,6 +85,8 @@ typedef struct
|
|||
* file this mapping represents. (The mappings are always
|
||||
* PAGE_SIZE-aligned.)
|
||||
*/
|
||||
|
||||
typedef struct MappedPage MappedPage;
|
||||
struct MappedPage
|
||||
{
|
||||
MappedPage *next;
|
||||
|
@ -99,22 +101,23 @@ struct MappedPage
|
|||
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
|
||||
*/
|
||||
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
|
||||
* pass expressions with side effects. */
|
||||
|
@ -153,58 +156,6 @@ static inline void BIGBLOCKFILE_Zero(BlockBits *bb)
|
|||
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
|
||||
*
|
||||
|
@ -212,10 +163,7 @@ BigBlockFile * BIGBLOCKFILE_Construct(
|
|||
*/
|
||||
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
|
||||
{
|
||||
This->pLkbyt = NULL;
|
||||
This->hbytearray = 0;
|
||||
This->pbytearray = NULL;
|
||||
|
||||
This->pLkbyt = NULL;
|
||||
This->hfile = hFile;
|
||||
|
||||
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->hfilemap = 0;
|
||||
This->hfile = 0;
|
||||
This->hfilemap = 0;
|
||||
This->pLkbyt = plkbyt;
|
||||
ILockBytes_AddRef(This->pLkbyt);
|
||||
|
||||
/*
|
||||
* Retrieve the handle to the byte array from the LockByte object.
|
||||
*/
|
||||
if (GetHGlobalFromILockBytes(plkbyt, &(This->hbytearray)) != S_OK)
|
||||
{
|
||||
FIXME("May not be an ILockBytes on HGLOBAL\n");
|
||||
return FALSE;
|
||||
}
|
||||
/* We'll get the size directly with ILockBytes_Stat */
|
||||
This->filesize.QuadPart = 0;
|
||||
|
||||
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.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);
|
||||
TRACE("ILockBytes %p\n", This->pLkbyt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -445,6 +251,64 @@ static void BIGBLOCKFILE_LinkHeadPage(MappedPage **head, MappedPage *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]
|
||||
*
|
||||
|
@ -495,77 +359,16 @@ static void * BIGBLOCKFILE_GetMappedView(
|
|||
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)
|
||||
{
|
||||
TRACE("%d at %p\n", page->page_index, page->lpBytes);
|
||||
|
||||
assert(This->fileBased);
|
||||
|
||||
if (page->refcnt > 0)
|
||||
ERR("unmapping inuse page %p\n", page->lpBytes);
|
||||
|
||||
if (This->fileBased && page->lpBytes)
|
||||
if (page->lpBytes)
|
||||
UnmapViewOfFile(page->lpBytes);
|
||||
|
||||
page->lpBytes = NULL;
|
||||
|
@ -898,9 +701,79 @@ static HRESULT ImplBIGBLOCKFILE_WriteAt(
|
|||
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,
|
||||
void* buffer, ULONG size, ULONG* bytesRead)
|
||||
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_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)
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
return ImplBIGBLOCKFILE_WriteAt(This,offset,buffer,size,bytesRead);
|
||||
else
|
||||
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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Declaration of the data structures
|
||||
*/
|
||||
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
|
||||
|
@ -184,8 +164,8 @@ BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile,
|
|||
ULONG blocksize,
|
||||
BOOL fileBased);
|
||||
void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
|
||||
void BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index);
|
||||
void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
|
||||
HRESULT BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index);
|
||||
HRESULT BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
|
||||
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
|
||||
void* buffer, ULONG size, ULONG* bytesRead);
|
||||
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
|
||||
|
|
|
@ -157,10 +157,10 @@ typedef struct tagPICTDESC {
|
|||
} DUMMYUNIONNAME;
|
||||
} PICTDESC, *LPPICTDESC;
|
||||
|
||||
typedef long OLE_XPOS_PIXELS;
|
||||
typedef long OLE_YPOS_PIXELS;
|
||||
typedef long OLE_XSIZE_PIXELS;
|
||||
typedef long OLE_YSIZE_PIXELS;
|
||||
typedef LONG OLE_XPOS_PIXELS;
|
||||
typedef LONG OLE_YPOS_PIXELS;
|
||||
typedef LONG OLE_XSIZE_PIXELS;
|
||||
typedef LONG OLE_YSIZE_PIXELS;
|
||||
typedef float OLE_XPOS_CONTAINER;
|
||||
typedef float OLE_YPOS_CONTAINER;
|
||||
typedef float OLE_XSIZE_CONTAINER;
|
||||
|
|
|
@ -24,6 +24,8 @@ import "objidl.idl";
|
|||
|
||||
interface IOleInPlaceActiveObject;
|
||||
|
||||
cpp_quote("#include <winuser.h>")
|
||||
|
||||
/*****************************************************************************
|
||||
* IOleTypes interface
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue