mirror of
https://github.com/reactos/reactos.git
synced 2024-07-08 21:55:08 +00:00
Sync to Wine-20050524:
Alexandre Julliard <julliard@winehq.org> - Added rules for building import libraries in the individual dll makefiles, and added support for building a .def.a static import library too. - Removed unnecessary code in the 16-bit DllEntryPoint function of some dlls, and also fixed its ordinal in a few places. - Comment out stub WEP entry points so that we can call WEP for builtin dlls too. Juan Lang <juan_lang@yahoo.com> - Obvious fixes to PropVariantClear and PropVariantCopy for vector types. - Add a comment, and a no-op cleanup. - Differentiate between version 0 and version 1 property storages. - Store property names in the code page of the property set. - maintain proper byte order - maintain PROPSETFLAG_ANSI flag based on codepage - update comments - Correct/improve error checking in IPropertyStorage. - convert strings between property storage's code page and system code page - add tests for setting code page - fix tests and behavior to match WinXP - Define and use endian conversion macros for big-endian machines. Marcus Meissner <marcus@jet.franken.de> - Move the Dll init function to compobj.c to avoid having global variables. Remove need of ole32_main.h. - Make HGLOBALStream_* functions static. - Make _xmalloc16() static. - Staticify FTMarshalImpl definition. Francois Gouget <fgouget@free.fr> - Specify the proper call convention in the PropSysFreeString() implementation. - Tweak the API documentation to silence winapi_check warnings. Robert Shearman <rob@codeweavers.com> - Add error messages on failure in file moniker load function. - Fix incorrect pointer check in both monikers. - Fix max size calculation of item moniker to match native. - Add a generic moniker marshaler that works by saving & loading monikers to & from the stream. - Use the generic moniker marshal in the file & item monikers and add a class factory for each. - Implement IROTData::GetComparisonData for file & item monikers. - Add a useful trace message. - Fix more places where custom header size was calculated exclusive of the data size member. - Optimize custom marshaling by getting size before calling the custom marshaler so we can write the header before and not use a second stream. - Change remaining blocks of code with 2-space indentation to 4-space indentation. - Make vtables const. - Remove an unnecessary memcpy and let the compiler do the work. - Write custom header up to and including size, not excluding. - Add a stub implementation of CoIsHandlerConnected. - Marshal objects & monikers into the ROT. - Test for this behaviour. Mike McCormack <mike@codeweavers.com> - Remove unnecessary declarations and make functions static. - Remove forward declarations. - Make sure a stream can't be created in read only storage. - Fix a memory leak in the ole storage implementation. - Remove function prototypes. Kevin Koltzau <kevin@plop.org> - Implement Hash function on composite moniker. Jeff Latimer <jeffl@defcen.gov.au> - Implement the IEnumMoniker interface for the ROT and provide tests to exercise the interface. Pierre d'Herbemont <stegefin@free.fr> - Big Endian specific code fixes in order to conform with NONAMELESSSTRUCT. Matthew Mastracci <matt@aclaro.com> - Replace stub entry for StgOpenStorageEx with call to StgOpenStorage. - Replace StgCreateStorageEx stub with call to StgCreateDocfile and add required STGFMT_* enumerations. svn path=/trunk/; revision=15562
This commit is contained in:
parent
dde52a04c5
commit
8eff322fdd
|
@ -4,6 +4,7 @@ TOPOBJDIR = ../..
|
|||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = ole32.dll
|
||||
IMPORTLIB = libole32.$(IMPLIBEXT)
|
||||
IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll
|
||||
EXTRALIBS = -luuid $(LIBUNICODE)
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
#include "wownt32.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "objbase.h"
|
||||
#include "ole32_main.h"
|
||||
#include "compobj_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
@ -75,6 +74,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|||
|
||||
typedef LPCSTR LPCOLESTR16;
|
||||
|
||||
HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */
|
||||
|
||||
/****************************************************************************
|
||||
* This section defines variables internal to the COM module.
|
||||
*
|
||||
|
@ -169,7 +170,7 @@ static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LP
|
|||
static void COMPOBJ_DLLList_Add(HANDLE hLibrary);
|
||||
static void COMPOBJ_DllList_FreeUnused(int Timeout);
|
||||
|
||||
void COMPOBJ_InitProcess( void )
|
||||
static void COMPOBJ_InitProcess( void )
|
||||
{
|
||||
WNDCLASSW wclass;
|
||||
|
||||
|
@ -189,12 +190,12 @@ void COMPOBJ_InitProcess( void )
|
|||
RegisterClassW(&wclass);
|
||||
}
|
||||
|
||||
void COMPOBJ_UninitProcess( void )
|
||||
static void COMPOBJ_UninitProcess( void )
|
||||
{
|
||||
UnregisterClassW(wszAptWinClass, OLE32_hInstance);
|
||||
}
|
||||
|
||||
void COM_TlsDestroy()
|
||||
static void COM_TlsDestroy()
|
||||
{
|
||||
struct oletls *info = NtCurrentTeb()->ReservedForOle;
|
||||
if (info)
|
||||
|
@ -624,7 +625,7 @@ HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
|
|||
/* On COM finalization for a STA thread, the message queue is flushed to ensure no
|
||||
pending RPCs are ignored. Non-COM messages are discarded at this point.
|
||||
*/
|
||||
void COM_FlushMessageQueue(void)
|
||||
static void COM_FlushMessageQueue(void)
|
||||
{
|
||||
MSG message;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
|
@ -1531,7 +1532,8 @@ end:
|
|||
*
|
||||
* Reads a registry value and expands it when necessary
|
||||
*/
|
||||
HRESULT compobj_RegReadPath(char * keyname, char * valuename, char * dst, DWORD dstlen)
|
||||
static HRESULT
|
||||
compobj_RegReadPath(char * keyname, char * valuename, char * dst, DWORD dstlen)
|
||||
{
|
||||
HRESULT hres;
|
||||
HKEY key;
|
||||
|
@ -2425,6 +2427,25 @@ ULONG WINAPI CoReleaseServerProcess(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoIsHandlerConnected [OLE32.@]
|
||||
*
|
||||
* Determines whether a proxy is connected to a remote stub.
|
||||
*
|
||||
* PARAMS
|
||||
* pUnk [I] Pointer to object that may or may not be connected.
|
||||
*
|
||||
* RETURNS
|
||||
* TRUE if pUnk is not a proxy or if pUnk is connected to a remote stub, or
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
BOOL WINAPI CoIsHandlerConnected(IUnknown *pUnk)
|
||||
{
|
||||
FIXME("%p\n", pUnk);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoQueryProxyBlanket [OLE32.@]
|
||||
*
|
||||
|
@ -2635,3 +2656,32 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
|
|||
TRACE("-- 0x%08lx\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllMain (OLE32.@)
|
||||
*/
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||
{
|
||||
TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
|
||||
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
OLE32_hInstance = hinstDLL;
|
||||
COMPOBJ_InitProcess();
|
||||
if (TRACE_ON(ole)) CoRegisterMallocSpy((LPVOID)-1);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (TRACE_ON(ole)) CoRevokeMallocSpy();
|
||||
COMPOBJ_UninitProcess();
|
||||
OLE32_hInstance = 0;
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
COM_TlsDestroy();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* NOTE: DllRegisterServer and DllUnregisterServer are in regsvr.c */
|
||||
|
|
|
@ -203,7 +203,7 @@ HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
|
|||
HRESULT WINAPI RunningObjectTableImpl_UnInitialize(void);
|
||||
|
||||
/* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
|
||||
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
|
||||
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
|
||||
|
||||
|
||||
/* Apartment Functions */
|
||||
|
@ -254,4 +254,6 @@ static inline APARTMENT* COM_CurrentApt(void)
|
|||
# define DEBUG_CLEAR_CRITSEC_NAME(cs)
|
||||
#endif
|
||||
|
||||
extern HINSTANCE OLE32_hInstance; /* FIXME: make static */
|
||||
|
||||
#endif /* __WINE_OLE_COMPOBJ_H */
|
||||
|
|
|
@ -616,9 +616,36 @@ CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
|||
static HRESULT WINAPI
|
||||
CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
||||
{
|
||||
FIXME("(),stub!\n");
|
||||
IEnumMoniker *enumMoniker;
|
||||
IMoniker *tempMk;
|
||||
HRESULT res;
|
||||
DWORD tempHash;
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p,%p)\n",iface,pdwHash);
|
||||
|
||||
if (pdwHash==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
res = IMoniker_Enum(iface,TRUE,&enumMoniker);
|
||||
if(FAILED(res))
|
||||
return res;
|
||||
|
||||
while(1){
|
||||
res=IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL);
|
||||
if(FAILED(res))
|
||||
break;
|
||||
|
||||
res = IMoniker_Hash(tempMk, &tempHash);
|
||||
if(FAILED(res))
|
||||
break;
|
||||
*pdwHash = (*pdwHash * 37) + tempHash;
|
||||
|
||||
IMoniker_Release(tempMk);
|
||||
}
|
||||
|
||||
IEnumMoniker_Release(enumMoniker);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/***************************************************************************************
|
||||
* FileMonikers implementation
|
||||
/*
|
||||
* FileMonikers implementation
|
||||
*
|
||||
* Copyright 1999 Noomen Hamza
|
||||
* Copyright 1999 Noomen Hamza
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -16,7 +16,7 @@
|
|||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
***************************************************************************************/
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -57,114 +57,29 @@ typedef struct FileMonikerImpl{
|
|||
|
||||
LPOLESTR filePathName; /* path string identified by this filemoniker */
|
||||
|
||||
IUnknown *pMarshal; /* custom marshaler */
|
||||
} FileMonikerImpl;
|
||||
|
||||
/********************************************************************************/
|
||||
/* FileMoniker prototype functions : */
|
||||
|
||||
/* IUnknown prototype functions */
|
||||
static HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
|
||||
static ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface);
|
||||
static ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface);
|
||||
|
||||
/* IPersist prototype functions */
|
||||
static HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
|
||||
|
||||
/* IPersistStream prototype functions */
|
||||
static HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface);
|
||||
static HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface, IStream* pStm);
|
||||
static HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
|
||||
static HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
|
||||
|
||||
/* IMoniker prototype functions */
|
||||
static HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
|
||||
static HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
|
||||
static HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
|
||||
static HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
|
||||
static HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
|
||||
static HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
|
||||
static HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
|
||||
static HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
|
||||
static HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pFileTime);
|
||||
static HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
|
||||
static HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
|
||||
static HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
|
||||
static HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
|
||||
static HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
|
||||
static HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
|
||||
|
||||
/********************************************************************************/
|
||||
/* IROTData prototype functions */
|
||||
|
||||
/* IUnknown prototype functions */
|
||||
static HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
|
||||
static ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData* iface);
|
||||
static ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface);
|
||||
|
||||
/* IROTData prototype function */
|
||||
static HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
|
||||
|
||||
/* Local function used by filemoniker implementation */
|
||||
HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
|
||||
HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface);
|
||||
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** tabStr);
|
||||
|
||||
|
||||
/********************************************************************************/
|
||||
/* Virtual function table for the FileMonikerImpl class which include IPersist,*/
|
||||
/* IPersistStream and IMoniker functions. */
|
||||
static IMonikerVtbl VT_FileMonikerImpl =
|
||||
{
|
||||
FileMonikerImpl_QueryInterface,
|
||||
FileMonikerImpl_AddRef,
|
||||
FileMonikerImpl_Release,
|
||||
FileMonikerImpl_GetClassID,
|
||||
FileMonikerImpl_IsDirty,
|
||||
FileMonikerImpl_Load,
|
||||
FileMonikerImpl_Save,
|
||||
FileMonikerImpl_GetSizeMax,
|
||||
FileMonikerImpl_BindToObject,
|
||||
FileMonikerImpl_BindToStorage,
|
||||
FileMonikerImpl_Reduce,
|
||||
FileMonikerImpl_ComposeWith,
|
||||
FileMonikerImpl_Enum,
|
||||
FileMonikerImpl_IsEqual,
|
||||
FileMonikerImpl_Hash,
|
||||
FileMonikerImpl_IsRunning,
|
||||
FileMonikerImpl_GetTimeOfLastChange,
|
||||
FileMonikerImpl_Inverse,
|
||||
FileMonikerImpl_CommonPrefixWith,
|
||||
FileMonikerImpl_RelativePathTo,
|
||||
FileMonikerImpl_GetDisplayName,
|
||||
FileMonikerImpl_ParseDisplayName,
|
||||
FileMonikerImpl_IsSystemMoniker
|
||||
};
|
||||
|
||||
/********************************************************************************/
|
||||
/* Virtual function table for the IROTData class. */
|
||||
static IROTDataVtbl VT_ROTDataImpl =
|
||||
{
|
||||
FileMonikerROTDataImpl_QueryInterface,
|
||||
FileMonikerROTDataImpl_AddRef,
|
||||
FileMonikerROTDataImpl_Release,
|
||||
FileMonikerROTDataImpl_GetComparaisonData
|
||||
};
|
||||
static HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
|
||||
static HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface);
|
||||
|
||||
/*******************************************************************************
|
||||
* FileMoniker_QueryInterface
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
|
||||
{
|
||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||
|
||||
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
|
||||
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
|
||||
|
||||
/* Perform a sanity check on the parameters.*/
|
||||
if ( (This==0) || (ppvObject==0) )
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* Initialize the return parameter */
|
||||
*ppvObject = 0;
|
||||
*ppvObject = 0;
|
||||
|
||||
/* Compare the riid with the interface IDs implemented by this object.*/
|
||||
if (IsEqualIID(&IID_IUnknown, riid) ||
|
||||
|
@ -176,21 +91,31 @@ HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
|
|||
|
||||
else if (IsEqualIID(&IID_IROTData, riid))
|
||||
*ppvObject = (IROTData*)&(This->lpvtbl2);
|
||||
else if (IsEqualIID(&IID_IMarshal, riid))
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!This->pMarshal)
|
||||
hr = MonikerMarshal_Create(iface, &This->pMarshal);
|
||||
if (hr != S_OK)
|
||||
return hr;
|
||||
return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
|
||||
}
|
||||
|
||||
/* Check that we obtained an interface.*/
|
||||
if ((*ppvObject)==0)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/* Query Interface always increases the reference count by one when it is successful */
|
||||
FileMonikerImpl_AddRef(iface);
|
||||
IMoniker_AddRef(iface);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FileMoniker_AddRef
|
||||
******************************************************************************/
|
||||
ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface)
|
||||
*/
|
||||
static ULONG WINAPI
|
||||
FileMonikerImpl_AddRef(IMoniker* iface)
|
||||
{
|
||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||
|
||||
|
@ -201,8 +126,9 @@ ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface)
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_Release
|
||||
******************************************************************************/
|
||||
ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface)
|
||||
*/
|
||||
static ULONG WINAPI
|
||||
FileMonikerImpl_Release(IMoniker* iface)
|
||||
{
|
||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||
ULONG ref;
|
||||
|
@ -219,9 +145,9 @@ ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface)
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_GetClassID
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface,
|
||||
CLSID *pClassID)/* Pointer to CLSID of object */
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID)
|
||||
{
|
||||
TRACE("(%p,%p)\n",iface,pClassID);
|
||||
|
||||
|
@ -235,12 +161,14 @@ HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface,
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_IsDirty
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface)
|
||||
*
|
||||
* Note that the OLE-provided implementations of the IPersistStream::IsDirty
|
||||
* method in the OLE-provided moniker interfaces always return S_FALSE because
|
||||
* their internal state never changes.
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_IsDirty(IMoniker* iface)
|
||||
{
|
||||
/* Note that the OLE-provided implementations of the IPersistStream::IsDirty
|
||||
method in the OLE-provided moniker interfaces always return S_FALSE because
|
||||
their internal state never changes. */
|
||||
|
||||
TRACE("(%p)\n",iface);
|
||||
|
||||
|
@ -249,8 +177,12 @@ HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface)
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_Load
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
||||
*
|
||||
* this function locates and reads from the stream the filePath string
|
||||
* written by FileMonikerImpl_Save
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
||||
{
|
||||
HRESULT res;
|
||||
CHAR* filePathA;
|
||||
|
@ -263,36 +195,49 @@ HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
|||
|
||||
TRACE("(%p,%p)\n",iface,pStm);
|
||||
|
||||
/* this function locates and reads from the stream the filePath string written by FileMonikerImpl_Save */
|
||||
|
||||
/* first WORD is non significative */
|
||||
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
|
||||
if (bread!=sizeof(WORD) || wbuffer!=0)
|
||||
{
|
||||
ERR("Couldn't read 0 word\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* read filePath string length (plus one) */
|
||||
res=IStream_Read(pStm,&length,sizeof(DWORD),&bread);
|
||||
if (bread != sizeof(DWORD))
|
||||
{
|
||||
ERR("Couldn't read file string length\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* read filePath string */
|
||||
filePathA=HeapAlloc(GetProcessHeap(),0,length);
|
||||
res=IStream_Read(pStm,filePathA,length,&bread);
|
||||
HeapFree(GetProcessHeap(),0,filePathA);
|
||||
if (bread != length)
|
||||
{
|
||||
ERR("Couldn't read file path string\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* read the first constant */
|
||||
IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
|
||||
if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
|
||||
{
|
||||
ERR("Couldn't read 0xDEADFFFF constant\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
length--;
|
||||
|
||||
for(i=0;i<10;i++){
|
||||
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
|
||||
if (bread!=sizeof(WORD) || wbuffer!=0)
|
||||
{
|
||||
ERR("Couldn't read 0 padding\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (length>8)
|
||||
|
@ -334,30 +279,28 @@ HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_Save
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface,
|
||||
IStream* pStm,/* pointer to the stream where the object is to be saved */
|
||||
BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
|
||||
*
|
||||
* This function saves data of this object. In the beginning I thougth
|
||||
* that I have just to write the filePath string on Stream. But, when I
|
||||
* tested this function whith windows programs samples, I noticed that it
|
||||
* was not the case. So I analysed data written by this function on
|
||||
* Windows and what this did function exactly ! But I have no idea about
|
||||
* its logic !
|
||||
* I guessed data which must be written on stream is:
|
||||
* 1) WORD constant:zero
|
||||
* 2) length of the path string ("\0" included)
|
||||
* 3) path string type A
|
||||
* 4) DWORD constant : 0xDEADFFFF
|
||||
* 5) ten WORD constant: zero
|
||||
* 6) DWORD: double-length of the the path string type W ("\0" not
|
||||
* included)
|
||||
* 7) WORD constant: 0x3
|
||||
* 8) filePath unicode string.
|
||||
* if the length(filePath) > 8 or length(filePath) == 8 stop at step 5)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
|
||||
{
|
||||
/* this function saves data of this object. In the beginning I thougth
|
||||
* that I have just to write the filePath string on Stream. But, when I
|
||||
* tested this function whith windows programs samples, I noticed that it
|
||||
* was not the case. So I analysed data written by this function on
|
||||
* Windows and what this did function exactly ! But I have no idea about
|
||||
* its logic !
|
||||
* I guessed data which must be written on stream is:
|
||||
* 1) WORD constant:zero
|
||||
* 2) length of the path string ("\0" included)
|
||||
* 3) path string type A
|
||||
* 4) DWORD constant : 0xDEADFFFF
|
||||
* 5) ten WORD constant: zero
|
||||
* 6) DWORD: double-length of the the path string type W ("\0" not
|
||||
* included)
|
||||
* 7) WORD constant: 0x3
|
||||
* 8) filePath unicode string.
|
||||
* if the length(filePath) > 8 or length(filePath) == 8 stop at step 5)
|
||||
*/
|
||||
|
||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||
|
||||
HRESULT res;
|
||||
|
@ -426,9 +369,9 @@ HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface,
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_GetSizeMax
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
|
||||
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
|
||||
{
|
||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||
DWORD len=lstrlenW(This->filePathName);
|
||||
|
@ -436,7 +379,7 @@ HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
|
|||
|
||||
TRACE("(%p,%p)\n",iface,pcbSize);
|
||||
|
||||
if (pcbSize!=NULL)
|
||||
if (!pcbSize)
|
||||
return E_POINTER;
|
||||
|
||||
/* for more details see FileMonikerImpl_Save coments */
|
||||
|
@ -461,77 +404,6 @@ HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FileMoniker_Construct (local function)
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPathName)
|
||||
{
|
||||
int nb=0,i;
|
||||
int sizeStr=lstrlenW(lpszPathName);
|
||||
LPOLESTR *tabStr=0;
|
||||
static const WCHAR twoPoint[]={'.','.',0};
|
||||
static const WCHAR bkSlash[]={'\\',0};
|
||||
BYTE addBkSlash;
|
||||
|
||||
TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName));
|
||||
|
||||
/* Initialize the virtual fgunction table. */
|
||||
This->lpvtbl1 = &VT_FileMonikerImpl;
|
||||
This->lpvtbl2 = &VT_ROTDataImpl;
|
||||
This->ref = 0;
|
||||
|
||||
This->filePathName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr+1));
|
||||
|
||||
if (This->filePathName==NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
strcpyW(This->filePathName,lpszPathName);
|
||||
|
||||
nb=FileMonikerImpl_DecomposePath(This->filePathName,&tabStr);
|
||||
|
||||
if (nb > 0 ){
|
||||
|
||||
addBkSlash=1;
|
||||
if (lstrcmpW(tabStr[0],twoPoint)!=0)
|
||||
addBkSlash=0;
|
||||
else
|
||||
for(i=0;i<nb;i++){
|
||||
|
||||
if ( (lstrcmpW(tabStr[i],twoPoint)!=0) && (lstrcmpW(tabStr[i],bkSlash)!=0) ){
|
||||
addBkSlash=0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
if (lstrcmpW(tabStr[i],bkSlash)==0 && i<nb-1 && lstrcmpW(tabStr[i+1],bkSlash)==0){
|
||||
*tabStr[i]=0;
|
||||
sizeStr--;
|
||||
addBkSlash=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lstrcmpW(tabStr[nb-1],bkSlash)==0)
|
||||
addBkSlash=0;
|
||||
|
||||
This->filePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR));
|
||||
|
||||
*This->filePathName=0;
|
||||
|
||||
for(i=0;tabStr[i]!=NULL;i++)
|
||||
strcatW(This->filePathName,tabStr[i]);
|
||||
|
||||
if (addBkSlash)
|
||||
strcatW(This->filePathName,bkSlash);
|
||||
}
|
||||
|
||||
for(i=0; tabStr[i]!=NULL;i++)
|
||||
CoTaskMemFree(tabStr[i]);
|
||||
CoTaskMemFree(tabStr);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FileMoniker_Destroy (local function)
|
||||
*******************************************************************************/
|
||||
|
@ -539,6 +411,7 @@ HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This)
|
|||
{
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if (This->pMarshal) IUnknown_Release(This->pMarshal);
|
||||
HeapFree(GetProcessHeap(),0,This->filePathName);
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
|
||||
|
@ -547,12 +420,10 @@ HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This)
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_BindToObject
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
REFIID riid,
|
||||
VOID** ppvResult)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
|
||||
REFIID riid, VOID** ppvResult)
|
||||
{
|
||||
HRESULT res=E_FAIL;
|
||||
CLSID clsID;
|
||||
|
@ -662,12 +533,10 @@ HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_BindToStorage
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
REFIID riid,
|
||||
VOID** ppvObject)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
|
||||
REFIID riid, VOID** ppvObject)
|
||||
{
|
||||
LPOLESTR filePath=0;
|
||||
IStorage *pstg=0;
|
||||
|
@ -680,7 +549,7 @@ HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
|
|||
if (IsEqualIID(&IID_IStorage, riid)){
|
||||
|
||||
/* get the file name */
|
||||
FileMonikerImpl_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
|
||||
IMoniker_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
|
||||
|
||||
/* verifie if the file contains a storage object */
|
||||
res=StgIsStorageFile(filePath);
|
||||
|
@ -718,30 +587,28 @@ HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
|
|||
/******************************************************************************
|
||||
* FileMoniker_Reduce
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
DWORD dwReduceHowFar,
|
||||
IMoniker** ppmkToLeft,
|
||||
IMoniker** ppmkReduced)
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
|
||||
IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
|
||||
{
|
||||
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
|
||||
|
||||
if (ppmkReduced==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
FileMonikerImpl_AddRef(iface);
|
||||
IMoniker_AddRef(iface);
|
||||
|
||||
*ppmkReduced=iface;
|
||||
|
||||
return MK_S_REDUCED_TO_SELF;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FileMoniker_ComposeWith
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
|
||||
IMoniker* pmkRight,
|
||||
BOOL fOnlyIfNotGeneric,
|
||||
IMoniker** ppmkComposite)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
|
||||
BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
|
||||
{
|
||||
HRESULT res;
|
||||
LPOLESTR str1=0,str2=0,*strDec1=0,*strDec2=0,newStr=0;
|
||||
|
@ -768,7 +635,7 @@ HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
|
|||
|
||||
CreateBindCtx(0,&bind);
|
||||
|
||||
FileMonikerImpl_GetDisplayName(iface,bind,NULL,&str1);
|
||||
IMoniker_GetDisplayName(iface,bind,NULL,&str1);
|
||||
IMoniker_GetDisplayName(pmkRight,bind,NULL,&str2);
|
||||
|
||||
/* decompose pathnames of the two monikers : (to prepare the path merge operation ) */
|
||||
|
@ -838,8 +705,9 @@ HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_Enum
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
|
||||
{
|
||||
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
|
||||
|
||||
|
@ -853,8 +721,9 @@ HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker*
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_IsEqual
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
||||
{
|
||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||
CLSID clsid;
|
||||
|
@ -886,8 +755,9 @@ HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_Hash
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
||||
{
|
||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||
|
||||
|
@ -920,11 +790,10 @@ HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_IsRunning
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
IMoniker* pmkNewlyRunning)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
|
||||
IMoniker* pmkNewlyRunning)
|
||||
{
|
||||
IRunningObjectTable* rot;
|
||||
HRESULT res;
|
||||
|
@ -952,10 +821,9 @@ HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,
|
|||
/******************************************************************************
|
||||
* FileMoniker_GetTimeOfLastChange
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
FILETIME* pFileTime)
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft, FILETIME* pFileTime)
|
||||
{
|
||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||
IRunningObjectTable* rot;
|
||||
|
@ -990,10 +858,10 @@ HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_Inverse
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
|
||||
{
|
||||
|
||||
TRACE("(%p,%p)\n",iface,ppmk);
|
||||
|
||||
return CreateAntiMoniker(ppmk);
|
||||
|
@ -1001,8 +869,9 @@ HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_CommonPrefixWith
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
|
||||
{
|
||||
|
||||
LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath;
|
||||
|
@ -1089,8 +958,8 @@ HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOth
|
|||
|
||||
/******************************************************************************
|
||||
* DecomposePath (local function)
|
||||
******************************************************************************/
|
||||
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
|
||||
*/
|
||||
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
|
||||
{
|
||||
static const WCHAR bSlash[] = {'\\',0};
|
||||
WCHAR word[MAX_PATH];
|
||||
|
@ -1144,8 +1013,9 @@ int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_RelativePathTo
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
|
||||
{
|
||||
IBindCtx *bind;
|
||||
HRESULT res;
|
||||
|
@ -1219,11 +1089,10 @@ HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther,
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_GetDisplayName
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
LPOLESTR *ppszDisplayName)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
|
||||
{
|
||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||
|
||||
|
@ -1250,13 +1119,10 @@ HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_ParseDisplayName
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,
|
||||
IBindCtx* pbc,
|
||||
IMoniker* pmkToLeft,
|
||||
LPOLESTR pszDisplayName,
|
||||
ULONG* pchEaten,
|
||||
IMoniker** ppmkOut)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
|
||||
LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
|
||||
{
|
||||
FIXME("(%p,%p,%p,%p,%p,%p),stub!\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
|
||||
return E_NOTIMPL;
|
||||
|
@ -1264,8 +1130,9 @@ HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,
|
|||
|
||||
/******************************************************************************
|
||||
* FileMoniker_IsSystemMoniker
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
|
||||
{
|
||||
TRACE("(%p,%p)\n",iface,pwdMksys);
|
||||
|
||||
|
@ -1279,8 +1146,9 @@ HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
|
|||
|
||||
/*******************************************************************************
|
||||
* FileMonikerIROTData_QueryInterface
|
||||
*******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
|
||||
{
|
||||
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
|
@ -1293,19 +1161,21 @@ HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid
|
|||
/***********************************************************************
|
||||
* FileMonikerIROTData_AddRef
|
||||
*/
|
||||
ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData *iface)
|
||||
static ULONG WINAPI
|
||||
FileMonikerROTDataImpl_AddRef(IROTData *iface)
|
||||
{
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
return FileMonikerImpl_AddRef(This);
|
||||
return IMoniker_AddRef(This);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FileMonikerIROTData_Release
|
||||
*/
|
||||
ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface)
|
||||
static ULONG WINAPI
|
||||
FileMonikerROTDataImpl_Release(IROTData* iface)
|
||||
{
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
|
||||
|
@ -1316,14 +1186,142 @@ ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface)
|
|||
|
||||
/******************************************************************************
|
||||
* FileMonikerIROTData_GetComparaisonData
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
|
||||
BYTE* pbData,
|
||||
ULONG cbMax,
|
||||
ULONG* pcbData)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
|
||||
ULONG cbMax, ULONG* pcbData)
|
||||
{
|
||||
FIXME("(),stub!\n");
|
||||
return E_NOTIMPL;
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
FileMonikerImpl *This1 = (FileMonikerImpl *)This;
|
||||
int len = (strlenW(This1->filePathName)+1);
|
||||
int i;
|
||||
LPWSTR pszFileName;
|
||||
|
||||
TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
|
||||
|
||||
*pcbData = sizeof(CLSID) + len * sizeof(WCHAR);
|
||||
if (cbMax < *pcbData)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
memcpy(pbData, &CLSID_FileMoniker, sizeof(CLSID));
|
||||
pszFileName = (LPWSTR)(pbData+sizeof(CLSID));
|
||||
for (i = 0; i < len; i++)
|
||||
pszFileName[i] = toupperW(This1->filePathName[i]);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Virtual function table for the FileMonikerImpl class which include IPersist,
|
||||
* IPersistStream and IMoniker functions.
|
||||
*/
|
||||
static IMonikerVtbl VT_FileMonikerImpl =
|
||||
{
|
||||
FileMonikerImpl_QueryInterface,
|
||||
FileMonikerImpl_AddRef,
|
||||
FileMonikerImpl_Release,
|
||||
FileMonikerImpl_GetClassID,
|
||||
FileMonikerImpl_IsDirty,
|
||||
FileMonikerImpl_Load,
|
||||
FileMonikerImpl_Save,
|
||||
FileMonikerImpl_GetSizeMax,
|
||||
FileMonikerImpl_BindToObject,
|
||||
FileMonikerImpl_BindToStorage,
|
||||
FileMonikerImpl_Reduce,
|
||||
FileMonikerImpl_ComposeWith,
|
||||
FileMonikerImpl_Enum,
|
||||
FileMonikerImpl_IsEqual,
|
||||
FileMonikerImpl_Hash,
|
||||
FileMonikerImpl_IsRunning,
|
||||
FileMonikerImpl_GetTimeOfLastChange,
|
||||
FileMonikerImpl_Inverse,
|
||||
FileMonikerImpl_CommonPrefixWith,
|
||||
FileMonikerImpl_RelativePathTo,
|
||||
FileMonikerImpl_GetDisplayName,
|
||||
FileMonikerImpl_ParseDisplayName,
|
||||
FileMonikerImpl_IsSystemMoniker
|
||||
};
|
||||
|
||||
/* Virtual function table for the IROTData class. */
|
||||
static IROTDataVtbl VT_ROTDataImpl =
|
||||
{
|
||||
FileMonikerROTDataImpl_QueryInterface,
|
||||
FileMonikerROTDataImpl_AddRef,
|
||||
FileMonikerROTDataImpl_Release,
|
||||
FileMonikerROTDataImpl_GetComparisonData
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* FileMoniker_Construct (local function)
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPathName)
|
||||
{
|
||||
int nb=0,i;
|
||||
int sizeStr=lstrlenW(lpszPathName);
|
||||
LPOLESTR *tabStr=0;
|
||||
static const WCHAR twoPoint[]={'.','.',0};
|
||||
static const WCHAR bkSlash[]={'\\',0};
|
||||
BYTE addBkSlash;
|
||||
|
||||
TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName));
|
||||
|
||||
/* Initialize the virtual fgunction table. */
|
||||
This->lpvtbl1 = &VT_FileMonikerImpl;
|
||||
This->lpvtbl2 = &VT_ROTDataImpl;
|
||||
This->ref = 0;
|
||||
This->pMarshal = NULL;
|
||||
|
||||
This->filePathName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr+1));
|
||||
|
||||
if (This->filePathName==NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
strcpyW(This->filePathName,lpszPathName);
|
||||
|
||||
nb=FileMonikerImpl_DecomposePath(This->filePathName,&tabStr);
|
||||
|
||||
if (nb > 0 ){
|
||||
|
||||
addBkSlash=1;
|
||||
if (lstrcmpW(tabStr[0],twoPoint)!=0)
|
||||
addBkSlash=0;
|
||||
else
|
||||
for(i=0;i<nb;i++){
|
||||
|
||||
if ( (lstrcmpW(tabStr[i],twoPoint)!=0) && (lstrcmpW(tabStr[i],bkSlash)!=0) ){
|
||||
addBkSlash=0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
if (lstrcmpW(tabStr[i],bkSlash)==0 && i<nb-1 && lstrcmpW(tabStr[i+1],bkSlash)==0){
|
||||
*tabStr[i]=0;
|
||||
sizeStr--;
|
||||
addBkSlash=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lstrcmpW(tabStr[nb-1],bkSlash)==0)
|
||||
addBkSlash=0;
|
||||
|
||||
This->filePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR));
|
||||
|
||||
*This->filePathName=0;
|
||||
|
||||
for(i=0;tabStr[i]!=NULL;i++)
|
||||
strcatW(This->filePathName,tabStr[i]);
|
||||
|
||||
if (addBkSlash)
|
||||
strcatW(This->filePathName,bkSlash);
|
||||
}
|
||||
|
||||
for(i=0; tabStr[i]!=NULL;i++)
|
||||
CoTaskMemFree(tabStr[i]);
|
||||
CoTaskMemFree(tabStr);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -1358,3 +1356,75 @@ HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk)
|
|||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FileMonikerCF_QueryInterface(LPCLASSFACTORY iface,
|
||||
REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
|
||||
{
|
||||
*ppv = iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI FileMonikerCF_AddRef(LPCLASSFACTORY iface)
|
||||
{
|
||||
return 2; /* non-heap based object */
|
||||
}
|
||||
|
||||
static ULONG WINAPI FileMonikerCF_Release(LPCLASSFACTORY iface)
|
||||
{
|
||||
return 1; /* non-heap based object */
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FileMonikerCF_CreateInstance(LPCLASSFACTORY iface,
|
||||
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
FileMonikerImpl* newFileMoniker;
|
||||
HRESULT hr;
|
||||
static const WCHAR wszEmpty[] = { 0 };
|
||||
|
||||
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
|
||||
|
||||
*ppv = NULL;
|
||||
|
||||
if (pUnk)
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl));
|
||||
if (!newFileMoniker)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hr = FileMonikerImpl_Construct(newFileMoniker, wszEmpty);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker, riid, ppv);
|
||||
if (FAILED(hr))
|
||||
HeapFree(GetProcessHeap(),0,newFileMoniker);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FileMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
|
||||
{
|
||||
FIXME("(%d), stub!\n",fLock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IClassFactoryVtbl FileMonikerCFVtbl =
|
||||
{
|
||||
FileMonikerCF_QueryInterface,
|
||||
FileMonikerCF_AddRef,
|
||||
FileMonikerCF_Release,
|
||||
FileMonikerCF_CreateInstance,
|
||||
FileMonikerCF_LockServer
|
||||
};
|
||||
static const IClassFactoryVtbl *FileMonikerCF = &FileMonikerCFVtbl;
|
||||
|
||||
HRESULT FileMonikerCF_Create(REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
return IClassFactory_QueryInterface((IClassFactory *)&FileMonikerCF, riid, ppv);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,8 @@ typedef struct _FTMarshalImpl {
|
|||
#define _ICOM_THIS_From_IFTMarshal(class, name) class* This = (class*)(((char*)name)-_IFTMarshall_Offset);
|
||||
|
||||
/* inner IUnknown to handle aggregation */
|
||||
HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
|
||||
static HRESULT WINAPI
|
||||
IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
||||
|
@ -71,7 +72,7 @@ HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPV
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
|
||||
static ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
||||
|
@ -80,7 +81,7 @@ ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
|
|||
return InterlockedIncrement (&This->ref);
|
||||
}
|
||||
|
||||
ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
|
||||
static ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
||||
|
@ -99,7 +100,8 @@ static IUnknownVtbl iunkvt =
|
|||
IiFTMUnknown_fnRelease
|
||||
};
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
|
||||
{
|
||||
|
||||
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||
|
@ -108,7 +110,8 @@ HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOI
|
|||
return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv);
|
||||
}
|
||||
|
||||
ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
|
||||
static ULONG WINAPI
|
||||
FTMarshalImpl_AddRef (LPMARSHAL iface)
|
||||
{
|
||||
|
||||
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||
|
@ -117,7 +120,8 @@ ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
|
|||
return IUnknown_AddRef (This->pUnkOuter);
|
||||
}
|
||||
|
||||
ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
|
||||
static ULONG WINAPI
|
||||
FTMarshalImpl_Release (LPMARSHAL iface)
|
||||
{
|
||||
|
||||
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||
|
@ -126,14 +130,16 @@ ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
|
|||
return IUnknown_Release (This->pUnkOuter);
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
|
||||
void *pvDestContext, DWORD mshlflags, CLSID * pCid)
|
||||
{
|
||||
FIXME ("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
|
||||
void *pvDestContext, DWORD mshlflags, DWORD * pSize)
|
||||
{
|
||||
|
||||
|
@ -158,8 +164,9 @@ HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, vo
|
|||
return hres;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
|
||||
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
|
||||
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
|
||||
{
|
||||
|
||||
IMarshal *pMarshal = NULL;
|
||||
|
@ -182,25 +189,26 @@ HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm,
|
|||
return hres;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
|
||||
{
|
||||
FIXME ("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
|
||||
static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
|
||||
{
|
||||
FIXME ("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
|
||||
static HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
|
||||
{
|
||||
FIXME ("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IMarshalVtbl ftmvtbl =
|
||||
static IMarshalVtbl ftmvtbl =
|
||||
{
|
||||
FTMarshalImpl_QueryInterface,
|
||||
FTMarshalImpl_AddRef,
|
||||
|
|
|
@ -83,27 +83,6 @@ typedef struct StdGlobalInterfaceTableImpl
|
|||
|
||||
void* StdGlobalInterfaceTableInstance;
|
||||
|
||||
|
||||
/* IUnknown */
|
||||
static HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject);
|
||||
static ULONG WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface);
|
||||
static ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface);
|
||||
/* IGlobalInterfaceTable */
|
||||
static HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfaceTable* iface, IUnknown* pUnk, REFIID riid, DWORD* pdwCookie);
|
||||
static HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie);
|
||||
static HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie, REFIID riid, void **ppv);
|
||||
|
||||
/* Virtual function table */
|
||||
static IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl =
|
||||
{
|
||||
StdGlobalInterfaceTable_QueryInterface,
|
||||
StdGlobalInterfaceTable_AddRef,
|
||||
StdGlobalInterfaceTable_Release,
|
||||
StdGlobalInterfaceTable_RegisterInterfaceInGlobal,
|
||||
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal,
|
||||
StdGlobalInterfaceTable_GetInterfaceFromGlobal
|
||||
};
|
||||
|
||||
static CRITICAL_SECTION git_section;
|
||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
{
|
||||
|
@ -114,28 +93,6 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
|
|||
static CRITICAL_SECTION git_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
/***
|
||||
* Let's go! Here is the constructor and destructor for the class.
|
||||
*
|
||||
*/
|
||||
|
||||
/** This function constructs the GIT. It should only be called once **/
|
||||
void* StdGlobalInterfaceTable_Construct() {
|
||||
StdGlobalInterfaceTableImpl* newGIT;
|
||||
|
||||
newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl));
|
||||
if (newGIT == 0) return newGIT;
|
||||
|
||||
newGIT->lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
|
||||
newGIT->ref = 1; /* Initialise the reference count */
|
||||
newGIT->firstEntry = NULL; /* we start with an empty table */
|
||||
newGIT->lastEntry = NULL;
|
||||
newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
|
||||
TRACE("Created the GIT at %p\n", newGIT);
|
||||
|
||||
return (void*)newGIT;
|
||||
}
|
||||
|
||||
/** This destroys it again. It should revoke all the held interfaces first **/
|
||||
void StdGlobalInterfaceTable_Destroy(void* self) {
|
||||
TRACE("(%p)\n", self);
|
||||
|
@ -149,7 +106,9 @@ void StdGlobalInterfaceTable_Destroy(void* self) {
|
|||
* A helper function to traverse the list and find the entry that matches the cookie.
|
||||
* Returns NULL if not found
|
||||
*/
|
||||
StdGITEntry* StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie) {
|
||||
static StdGITEntry*
|
||||
StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie)
|
||||
{
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
StdGITEntry* e;
|
||||
|
||||
|
@ -174,34 +133,39 @@ StdGITEntry* StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWO
|
|||
* Here's the boring boilerplate stuff for IUnknown
|
||||
*/
|
||||
|
||||
HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject) {
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface,
|
||||
REFIID riid, void** ppvObject)
|
||||
{
|
||||
/* Make sure silly coders can't crash us */
|
||||
if (ppvObject == 0) return E_INVALIDARG;
|
||||
|
||||
*ppvObject = 0; /* assume we don't have the interface */
|
||||
|
||||
/* Do we implement that interface? */
|
||||
if (IsEqualIID(&IID_IUnknown, riid)) {
|
||||
*ppvObject = (IGlobalInterfaceTable*) self;
|
||||
} else if (IsEqualIID(&IID_IGlobalInterfaceTable, riid)) {
|
||||
*ppvObject = (IGlobalInterfaceTable*) self;
|
||||
} else return E_NOINTERFACE;
|
||||
if (IsEqualIID(&IID_IUnknown, riid) ||
|
||||
IsEqualIID(&IID_IGlobalInterfaceTable, riid))
|
||||
*ppvObject = iface;
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
|
||||
/* Now inc the refcount */
|
||||
StdGlobalInterfaceTable_AddRef(iface);
|
||||
IGlobalInterfaceTable_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface) {
|
||||
static ULONG WINAPI
|
||||
StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface)
|
||||
{
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
|
||||
/* InterlockedIncrement(&self->ref); */
|
||||
return self->ref;
|
||||
}
|
||||
|
||||
ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface) {
|
||||
static ULONG WINAPI
|
||||
StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface)
|
||||
{
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
|
||||
/* InterlockedDecrement(&self->ref); */
|
||||
|
@ -218,12 +182,16 @@ ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface) {
|
|||
* Now implement the actual IGlobalInterfaceTable interface
|
||||
*/
|
||||
|
||||
HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfaceTable* iface, IUnknown* pUnk, REFIID riid, DWORD* pdwCookie) {
|
||||
static HRESULT WINAPI
|
||||
StdGlobalInterfaceTable_RegisterInterfaceInGlobal(
|
||||
IGlobalInterfaceTable* iface, IUnknown* pUnk,
|
||||
REFIID riid, DWORD* pdwCookie)
|
||||
{
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
IStream* stream = NULL;
|
||||
HRESULT hres;
|
||||
StdGITEntry* entry;
|
||||
static const LARGE_INTEGER zero;
|
||||
LARGE_INTEGER zero;
|
||||
|
||||
TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=0x%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie);
|
||||
|
||||
|
@ -241,6 +209,7 @@ HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfac
|
|||
return hres;
|
||||
}
|
||||
|
||||
zero.QuadPart = 0;
|
||||
IStream_Seek(stream, zero, SEEK_SET, NULL);
|
||||
|
||||
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
|
||||
|
@ -269,7 +238,10 @@ HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfac
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie) {
|
||||
static HRESULT WINAPI
|
||||
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
|
||||
IGlobalInterfaceTable* iface, DWORD dwCookie)
|
||||
{
|
||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||
StdGITEntry* entry;
|
||||
HRESULT hr;
|
||||
|
@ -303,7 +275,11 @@ HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfac
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie, REFIID riid, void **ppv) {
|
||||
static HRESULT WINAPI
|
||||
StdGlobalInterfaceTable_GetInterfaceFromGlobal(
|
||||
IGlobalInterfaceTable* iface, DWORD dwCookie,
|
||||
REFIID riid, void **ppv)
|
||||
{
|
||||
StdGITEntry* entry;
|
||||
HRESULT hres;
|
||||
LARGE_INTEGER move;
|
||||
|
@ -341,18 +317,33 @@ HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTa
|
|||
|
||||
/* Classfactory definition - despite what MSDN says, some programs need this */
|
||||
|
||||
static HRESULT WINAPI GITCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) {
|
||||
static HRESULT WINAPI
|
||||
GITCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IGlobalInterfaceTable)) {
|
||||
if (IsEqualIID(riid,&IID_IUnknown) ||
|
||||
IsEqualIID(riid,&IID_IGlobalInterfaceTable))
|
||||
{
|
||||
*ppv = (LPVOID)iface;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
static ULONG WINAPI GITCF_AddRef(LPCLASSFACTORY iface) { return 2; }
|
||||
static ULONG WINAPI GITCF_Release(LPCLASSFACTORY iface) { return 1; }
|
||||
|
||||
static HRESULT WINAPI GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) {
|
||||
static ULONG WINAPI GITCF_AddRef(LPCLASSFACTORY iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI GITCF_Release(LPCLASSFACTORY iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
|
||||
REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
if (IsEqualIID(riid,&IID_IGlobalInterfaceTable)) {
|
||||
if (StdGlobalInterfaceTableInstance == NULL)
|
||||
StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct();
|
||||
|
@ -363,7 +354,8 @@ static HRESULT WINAPI GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
|
|||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) {
|
||||
static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
|
||||
{
|
||||
FIXME("(%d), stub!\n",fLock);
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -375,10 +367,41 @@ static IClassFactoryVtbl GITClassFactoryVtbl = {
|
|||
GITCF_CreateInstance,
|
||||
GITCF_LockServer
|
||||
};
|
||||
|
||||
static IClassFactoryVtbl *PGITClassFactoryVtbl = &GITClassFactoryVtbl;
|
||||
|
||||
HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) {
|
||||
HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv)
|
||||
{
|
||||
*ppv = &PGITClassFactoryVtbl;
|
||||
TRACE("Returning GIT classfactory\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Virtual function table */
|
||||
static IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl =
|
||||
{
|
||||
StdGlobalInterfaceTable_QueryInterface,
|
||||
StdGlobalInterfaceTable_AddRef,
|
||||
StdGlobalInterfaceTable_Release,
|
||||
StdGlobalInterfaceTable_RegisterInterfaceInGlobal,
|
||||
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal,
|
||||
StdGlobalInterfaceTable_GetInterfaceFromGlobal
|
||||
};
|
||||
|
||||
/** This function constructs the GIT. It should only be called once **/
|
||||
void* StdGlobalInterfaceTable_Construct()
|
||||
{
|
||||
StdGlobalInterfaceTableImpl* newGIT;
|
||||
|
||||
newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl));
|
||||
if (newGIT == 0) return newGIT;
|
||||
|
||||
newGIT->lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
|
||||
newGIT->ref = 1; /* Initialise the reference count */
|
||||
newGIT->firstEntry = NULL; /* we start with an empty table */
|
||||
newGIT->lastEntry = NULL;
|
||||
newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
|
||||
TRACE("Created the GIT at %p\n", newGIT);
|
||||
|
||||
return (void*)newGIT;
|
||||
}
|
||||
|
|
|
@ -86,217 +86,6 @@ struct HGLOBALStreamImpl
|
|||
|
||||
typedef struct HGLOBALStreamImpl HGLOBALStreamImpl;
|
||||
|
||||
/*
|
||||
* Method definition for the StgStreamImpl class.
|
||||
*/
|
||||
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
|
||||
HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease);
|
||||
|
||||
void HGLOBALStreamImpl_Destroy(
|
||||
HGLOBALStreamImpl* This);
|
||||
|
||||
void HGLOBALStreamImpl_OpenBlockChain(
|
||||
HGLOBALStreamImpl* This);
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
||||
IStream* iface,
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject); /* [iid_is][out] */
|
||||
|
||||
ULONG WINAPI HGLOBALStreamImpl_AddRef(
|
||||
IStream* iface);
|
||||
|
||||
ULONG WINAPI HGLOBALStreamImpl_Release(
|
||||
IStream* iface);
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Read(
|
||||
IStream* iface,
|
||||
void* pv, /* [length_is][size_is][out] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbRead); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Write(
|
||||
IStream* iface,
|
||||
const void* pv, /* [size_is][in] */
|
||||
ULONG cb, /* [in] */
|
||||
ULONG* pcbWritten); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
||||
IStream* iface,
|
||||
LARGE_INTEGER dlibMove, /* [in] */
|
||||
DWORD dwOrigin, /* [in] */
|
||||
ULARGE_INTEGER* plibNewPosition); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libNewSize); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
|
||||
IStream* iface,
|
||||
IStream* pstm, /* [unique][in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
ULARGE_INTEGER* pcbRead, /* [out] */
|
||||
ULARGE_INTEGER* pcbWritten); /* [out] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Commit(
|
||||
IStream* iface,
|
||||
DWORD grfCommitFlags); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Revert(
|
||||
IStream* iface);
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
DWORD dwLockType); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
||||
IStream* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag); /* [in] */
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
||||
IStream* iface,
|
||||
IStream** ppstm); /* [out] */
|
||||
|
||||
|
||||
/*
|
||||
* Virtual function table for the HGLOBALStreamImpl class.
|
||||
*/
|
||||
static IStreamVtbl HGLOBALStreamImpl_Vtbl =
|
||||
{
|
||||
HGLOBALStreamImpl_QueryInterface,
|
||||
HGLOBALStreamImpl_AddRef,
|
||||
HGLOBALStreamImpl_Release,
|
||||
HGLOBALStreamImpl_Read,
|
||||
HGLOBALStreamImpl_Write,
|
||||
HGLOBALStreamImpl_Seek,
|
||||
HGLOBALStreamImpl_SetSize,
|
||||
HGLOBALStreamImpl_CopyTo,
|
||||
HGLOBALStreamImpl_Commit,
|
||||
HGLOBALStreamImpl_Revert,
|
||||
HGLOBALStreamImpl_LockRegion,
|
||||
HGLOBALStreamImpl_UnlockRegion,
|
||||
HGLOBALStreamImpl_Stat,
|
||||
HGLOBALStreamImpl_Clone
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* CreateStreamOnHGlobal [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI CreateStreamOnHGlobal(
|
||||
HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease,
|
||||
LPSTREAM* ppstm)
|
||||
{
|
||||
HGLOBALStreamImpl* newStream;
|
||||
|
||||
newStream = HGLOBALStreamImpl_Construct(hGlobal,
|
||||
fDeleteOnRelease);
|
||||
|
||||
if (newStream!=NULL)
|
||||
{
|
||||
return IUnknown_QueryInterface((IUnknown*)newStream,
|
||||
&IID_IStream,
|
||||
(void**)ppstm);
|
||||
}
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetHGlobalFromStream [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
|
||||
{
|
||||
HGLOBALStreamImpl* pStream;
|
||||
|
||||
if (pstm == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pStream = (HGLOBALStreamImpl*) pstm;
|
||||
|
||||
/*
|
||||
* Verify that the stream object was created with CreateStreamOnHGlobal.
|
||||
*/
|
||||
if (pStream->lpVtbl == &HGLOBALStreamImpl_Vtbl)
|
||||
*phglobal = pStream->supportHandle;
|
||||
else
|
||||
{
|
||||
*phglobal = 0;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
** HGLOBALStreamImpl implementation
|
||||
*/
|
||||
|
||||
/***
|
||||
* This is the constructor for the HGLOBALStreamImpl class.
|
||||
*
|
||||
* Params:
|
||||
* hGlobal - Handle that will support the stream. can be NULL.
|
||||
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
|
||||
* when the IStream object is destroyed.
|
||||
*/
|
||||
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
|
||||
HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease)
|
||||
{
|
||||
HGLOBALStreamImpl* newStream;
|
||||
|
||||
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
|
||||
|
||||
if (newStream!=0)
|
||||
{
|
||||
/*
|
||||
* Set-up the virtual function table and reference count.
|
||||
*/
|
||||
newStream->lpVtbl = &HGLOBALStreamImpl_Vtbl;
|
||||
newStream->ref = 0;
|
||||
|
||||
/*
|
||||
* Initialize the support.
|
||||
*/
|
||||
newStream->supportHandle = hGlobal;
|
||||
newStream->deleteOnRelease = fDeleteOnRelease;
|
||||
|
||||
/*
|
||||
* This method will allocate a handle if one is not supplied.
|
||||
*/
|
||||
if (!newStream->supportHandle)
|
||||
{
|
||||
newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
|
||||
GMEM_SHARE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the stream at the beginning.
|
||||
*/
|
||||
newStream->currentPosition.u.HighPart = 0;
|
||||
newStream->currentPosition.u.LowPart = 0;
|
||||
|
||||
/*
|
||||
* Initialize the size of the stream to the size of the handle.
|
||||
*/
|
||||
newStream->streamSize.u.HighPart = 0;
|
||||
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
|
||||
}
|
||||
|
||||
return newStream;
|
||||
}
|
||||
|
||||
/***
|
||||
* This is the destructor of the HGLOBALStreamImpl class.
|
||||
*
|
||||
|
@ -304,7 +93,7 @@ HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
|
|||
* class. The pointer passed-in to this function will be freed and will not
|
||||
* be valid anymore.
|
||||
*/
|
||||
void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
|
||||
static void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
|
||||
{
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
|
@ -323,11 +112,22 @@ void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
|
|||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method AddRef for this
|
||||
* class
|
||||
*/
|
||||
static ULONG WINAPI HGLOBALStreamImpl_AddRef(
|
||||
IStream* iface)
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method QueryInterface for this
|
||||
* class
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
||||
IStream* iface,
|
||||
REFIID riid, /* [in] */
|
||||
void** ppvObject) /* [iid_is][out] */
|
||||
|
@ -372,22 +172,11 @@ HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method AddRef for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI HGLOBALStreamImpl_AddRef(
|
||||
IStream* iface)
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
/***
|
||||
* This implements the IUnknown method Release for this
|
||||
* class
|
||||
*/
|
||||
ULONG WINAPI HGLOBALStreamImpl_Release(
|
||||
static ULONG WINAPI HGLOBALStreamImpl_Release(
|
||||
IStream* iface)
|
||||
{
|
||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||
|
@ -415,7 +204,7 @@ ULONG WINAPI HGLOBALStreamImpl_Release(
|
|||
*
|
||||
* See the documentation of ISequentialStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Read(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_Read(
|
||||
IStream* iface,
|
||||
void* pv, /* [length_is][size_is][out] */
|
||||
ULONG cb, /* [in] */
|
||||
|
@ -486,7 +275,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Read(
|
|||
*
|
||||
* See the documentation of ISequentialStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Write(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_Write(
|
||||
IStream* iface,
|
||||
const void* pv, /* [size_is][in] */
|
||||
ULONG cb, /* [in] */
|
||||
|
@ -560,7 +349,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Write(
|
|||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
||||
IStream* iface,
|
||||
LARGE_INTEGER dlibMove, /* [in] */
|
||||
DWORD dwOrigin, /* [in] */
|
||||
|
@ -617,7 +406,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
|||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libNewSize) /* [in] */
|
||||
{
|
||||
|
@ -656,7 +445,7 @@ HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
|||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
|
||||
IStream* iface,
|
||||
IStream* pstm, /* [unique][in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
|
@ -741,7 +530,7 @@ HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
|
|||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Commit(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_Commit(
|
||||
IStream* iface,
|
||||
DWORD grfCommitFlags) /* [in] */
|
||||
{
|
||||
|
@ -756,7 +545,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Commit(
|
|||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Revert(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_Revert(
|
||||
IStream* iface)
|
||||
{
|
||||
return S_OK;
|
||||
|
@ -770,7 +559,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Revert(
|
|||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
|
@ -787,7 +576,7 @@ HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
|
|||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
|
||||
IStream* iface,
|
||||
ULARGE_INTEGER libOffset, /* [in] */
|
||||
ULARGE_INTEGER cb, /* [in] */
|
||||
|
@ -804,7 +593,7 @@ HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
|
|||
*
|
||||
* See the documentation of IStream for more info.
|
||||
*/
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
||||
IStream* iface,
|
||||
STATSTG* pstatstg, /* [out] */
|
||||
DWORD grfStatFlag) /* [in] */
|
||||
|
@ -820,7 +609,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
||||
static HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
||||
IStream* iface,
|
||||
IStream** ppstm) /* [out] */
|
||||
{
|
||||
|
@ -836,3 +625,133 @@ HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
|||
HGLOBALStreamImpl_Seek(*ppstm,offset,STREAM_SEEK_SET,&dummy);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Virtual function table for the HGLOBALStreamImpl class.
|
||||
*/
|
||||
static IStreamVtbl HGLOBALStreamImpl_Vtbl =
|
||||
{
|
||||
HGLOBALStreamImpl_QueryInterface,
|
||||
HGLOBALStreamImpl_AddRef,
|
||||
HGLOBALStreamImpl_Release,
|
||||
HGLOBALStreamImpl_Read,
|
||||
HGLOBALStreamImpl_Write,
|
||||
HGLOBALStreamImpl_Seek,
|
||||
HGLOBALStreamImpl_SetSize,
|
||||
HGLOBALStreamImpl_CopyTo,
|
||||
HGLOBALStreamImpl_Commit,
|
||||
HGLOBALStreamImpl_Revert,
|
||||
HGLOBALStreamImpl_LockRegion,
|
||||
HGLOBALStreamImpl_UnlockRegion,
|
||||
HGLOBALStreamImpl_Stat,
|
||||
HGLOBALStreamImpl_Clone
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
** HGLOBALStreamImpl implementation
|
||||
*/
|
||||
|
||||
/***
|
||||
* This is the constructor for the HGLOBALStreamImpl class.
|
||||
*
|
||||
* Params:
|
||||
* hGlobal - Handle that will support the stream. can be NULL.
|
||||
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
|
||||
* when the IStream object is destroyed.
|
||||
*/
|
||||
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
|
||||
HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease)
|
||||
{
|
||||
HGLOBALStreamImpl* newStream;
|
||||
|
||||
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
|
||||
|
||||
if (newStream!=0)
|
||||
{
|
||||
/*
|
||||
* Set-up the virtual function table and reference count.
|
||||
*/
|
||||
newStream->lpVtbl = &HGLOBALStreamImpl_Vtbl;
|
||||
newStream->ref = 0;
|
||||
|
||||
/*
|
||||
* Initialize the support.
|
||||
*/
|
||||
newStream->supportHandle = hGlobal;
|
||||
newStream->deleteOnRelease = fDeleteOnRelease;
|
||||
|
||||
/*
|
||||
* This method will allocate a handle if one is not supplied.
|
||||
*/
|
||||
if (!newStream->supportHandle)
|
||||
{
|
||||
newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
|
||||
GMEM_SHARE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the stream at the beginning.
|
||||
*/
|
||||
newStream->currentPosition.u.HighPart = 0;
|
||||
newStream->currentPosition.u.LowPart = 0;
|
||||
|
||||
/*
|
||||
* Initialize the size of the stream to the size of the handle.
|
||||
*/
|
||||
newStream->streamSize.u.HighPart = 0;
|
||||
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
|
||||
}
|
||||
|
||||
return newStream;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateStreamOnHGlobal [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI CreateStreamOnHGlobal(
|
||||
HGLOBAL hGlobal,
|
||||
BOOL fDeleteOnRelease,
|
||||
LPSTREAM* ppstm)
|
||||
{
|
||||
HGLOBALStreamImpl* newStream;
|
||||
|
||||
newStream = HGLOBALStreamImpl_Construct(hGlobal,
|
||||
fDeleteOnRelease);
|
||||
|
||||
if (newStream!=NULL)
|
||||
{
|
||||
return IUnknown_QueryInterface((IUnknown*)newStream,
|
||||
&IID_IStream,
|
||||
(void**)ppstm);
|
||||
}
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetHGlobalFromStream [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
|
||||
{
|
||||
HGLOBALStreamImpl* pStream;
|
||||
|
||||
if (pstm == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
pStream = (HGLOBALStreamImpl*) pstm;
|
||||
|
||||
/*
|
||||
* Verify that the stream object was created with CreateStreamOnHGlobal.
|
||||
*/
|
||||
if (pStream->lpVtbl == &HGLOBALStreamImpl_Vtbl)
|
||||
*phglobal = pStream->supportHandle;
|
||||
else
|
||||
{
|
||||
*phglobal = 0;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef struct ItemMonikerImpl{
|
|||
|
||||
LPOLESTR itemDelimiter; /* Delimiter string */
|
||||
|
||||
IUnknown *pMarshal; /* custom marshaler */
|
||||
} ItemMonikerImpl;
|
||||
|
||||
/********************************************************************************/
|
||||
|
@ -107,7 +108,7 @@ static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
|
|||
static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
|
||||
|
||||
/* IROTData prototype function */
|
||||
static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
|
||||
static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
|
||||
|
||||
/********************************************************************************/
|
||||
/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
|
||||
|
@ -146,7 +147,7 @@ static IROTDataVtbl VT_ROTDataImpl =
|
|||
ItemMonikerROTDataImpl_QueryInterface,
|
||||
ItemMonikerROTDataImpl_AddRef,
|
||||
ItemMonikerROTDataImpl_Release,
|
||||
ItemMonikerROTDataImpl_GetComparaisonData
|
||||
ItemMonikerROTDataImpl_GetComparisonData
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -175,6 +176,15 @@ HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
|
|||
|
||||
else if (IsEqualIID(&IID_IROTData, riid))
|
||||
*ppvObject = (IROTData*)&(This->lpvtbl2);
|
||||
else if (IsEqualIID(&IID_IMarshal, riid))
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!This->pMarshal)
|
||||
hr = MonikerMarshal_Create(iface, &This->pMarshal);
|
||||
if (hr != S_OK)
|
||||
return hr;
|
||||
return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
|
||||
}
|
||||
|
||||
/* Check that we obtained an interface.*/
|
||||
if ((*ppvObject)==0)
|
||||
|
@ -359,17 +369,16 @@ HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
|
|||
|
||||
TRACE("(%p,%p)\n",iface,pcbSize);
|
||||
|
||||
if (pcbSize!=NULL)
|
||||
if (!pcbSize)
|
||||
return E_POINTER;
|
||||
|
||||
/* for more details see ItemMonikerImpl_Save coments */
|
||||
|
||||
pcbSize->u.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
|
||||
delimiterLength + /* item delimiter string */
|
||||
delimiterLength*4 + /* item delimiter string */
|
||||
sizeof(DWORD) + /* DWORD which contains item name length */
|
||||
nameLength + /* item name string */
|
||||
34; /* this constant was added ! because when I tested this function it usually */
|
||||
/* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
|
||||
nameLength*4 + /* item name string */
|
||||
18; /* strange, but true */
|
||||
pcbSize->u.HighPart=0;
|
||||
|
||||
return S_OK;
|
||||
|
@ -391,6 +400,7 @@ HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDe
|
|||
This->lpvtbl1 = &VT_ItemMonikerImpl;
|
||||
This->lpvtbl2 = &VT_ROTDataImpl;
|
||||
This->ref = 0;
|
||||
This->pMarshal = NULL;
|
||||
|
||||
This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
|
||||
if (!This->itemName)
|
||||
|
@ -419,6 +429,7 @@ HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
|
|||
{
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if (This->pMarshal) IUnknown_Release(This->pMarshal);
|
||||
HeapFree(GetProcessHeap(),0,This->itemName);
|
||||
HeapFree(GetProcessHeap(),0,This->itemDelimiter);
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
|
@ -952,13 +963,35 @@ ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
|
|||
/******************************************************************************
|
||||
* ItemMonikerIROTData_GetComparaisonData
|
||||
******************************************************************************/
|
||||
HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
|
||||
HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
|
||||
BYTE* pbData,
|
||||
ULONG cbMax,
|
||||
ULONG* pcbData)
|
||||
{
|
||||
FIXME("(),stub!\n");
|
||||
return E_NOTIMPL;
|
||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||
ItemMonikerImpl *This1 = (ItemMonikerImpl *)This;
|
||||
int len = (strlenW(This1->itemName)+1);
|
||||
int i;
|
||||
LPWSTR pszItemName;
|
||||
LPWSTR pszItemDelimiter;
|
||||
|
||||
TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
|
||||
|
||||
*pcbData = sizeof(CLSID) + sizeof(WCHAR) + len * sizeof(WCHAR);
|
||||
if (cbMax < *pcbData)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* write CLSID */
|
||||
memcpy(pbData, &CLSID_ItemMoniker, sizeof(CLSID));
|
||||
/* write delimiter */
|
||||
pszItemDelimiter = (LPWSTR)(pbData+sizeof(CLSID));
|
||||
*pszItemDelimiter = *This1->itemDelimiter;
|
||||
/* write name */
|
||||
pszItemName = pszItemDelimiter + 1;
|
||||
for (i = 0; i < len; i++)
|
||||
pszItemName[i] = toupperW(This1->itemName[i]);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -986,3 +1019,75 @@ HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONI
|
|||
|
||||
return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&IID_IMoniker,(void**)ppmk);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ItemMonikerCF_QueryInterface(LPCLASSFACTORY iface,
|
||||
REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
|
||||
{
|
||||
*ppv = iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ItemMonikerCF_AddRef(LPCLASSFACTORY iface)
|
||||
{
|
||||
return 2; /* non-heap based object */
|
||||
}
|
||||
|
||||
static ULONG WINAPI ItemMonikerCF_Release(LPCLASSFACTORY iface)
|
||||
{
|
||||
return 1; /* non-heap based object */
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ItemMonikerCF_CreateInstance(LPCLASSFACTORY iface,
|
||||
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
ItemMonikerImpl* newItemMoniker;
|
||||
HRESULT hr;
|
||||
static const WCHAR wszEmpty[] = { 0 };
|
||||
|
||||
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
|
||||
|
||||
*ppv = NULL;
|
||||
|
||||
if (pUnk)
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
|
||||
if (!newItemMoniker)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hr = ItemMonikerImpl_Construct(newItemMoniker, wszEmpty, wszEmpty);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker, riid, ppv);
|
||||
if (FAILED(hr))
|
||||
HeapFree(GetProcessHeap(),0,newItemMoniker);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ItemMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
|
||||
{
|
||||
FIXME("(%d), stub!\n",fLock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IClassFactoryVtbl ItemMonikerCFVtbl =
|
||||
{
|
||||
ItemMonikerCF_QueryInterface,
|
||||
ItemMonikerCF_AddRef,
|
||||
ItemMonikerCF_Release,
|
||||
ItemMonikerCF_CreateInstance,
|
||||
ItemMonikerCF_LockServer
|
||||
};
|
||||
static const IClassFactoryVtbl *ItemMonikerCF = &ItemMonikerCFVtbl;
|
||||
|
||||
HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
return IClassFactory_QueryInterface((IClassFactory *)&ItemMonikerCF, riid, ppv);
|
||||
}
|
||||
|
|
|
@ -63,26 +63,25 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
|
|||
*
|
||||
* So basically we need a set of values that make it unique.
|
||||
*
|
||||
* Process Identifier, Object IUnknown ptr, IID
|
||||
*
|
||||
* Note that the IUnknown_QI(ob,xiid,&ppv) always returns the SAME ppv value!
|
||||
*
|
||||
* In Windows, a different triple is used: OXID (apt id), OID (stub
|
||||
* manager id), IPID (interface ptr/stub id).
|
||||
* A triple is used: OXID (apt id), OID (stub manager id),
|
||||
* IPID (interface ptr/stub id).
|
||||
*
|
||||
* OXIDs identify an apartment and are network scoped
|
||||
* OIDs identify a stub manager and are apartment scoped
|
||||
* IPIDs identify an interface stub and are apartment scoped
|
||||
*/
|
||||
|
||||
inline static HRESULT
|
||||
get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) {
|
||||
HRESULT hres;
|
||||
CLSID pxclsid;
|
||||
inline static HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
|
||||
{
|
||||
HRESULT hr;
|
||||
CLSID clsid;
|
||||
|
||||
if ((hres = CoGetPSClsid(riid,&pxclsid)))
|
||||
return hres;
|
||||
return CoGetClassObject(&pxclsid,CLSCTX_INPROC_SERVER,NULL,&IID_IPSFactoryBuffer,(LPVOID*)facbuf);
|
||||
if ((hr = CoGetPSClsid(riid, &clsid)))
|
||||
return hr;
|
||||
return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL,
|
||||
&IID_IPSFactoryBuffer, (LPVOID*)facbuf);
|
||||
}
|
||||
|
||||
/* creates a new stub manager */
|
||||
|
@ -747,56 +746,61 @@ HRESULT apartment_disconnectproxies(struct apartment *apt)
|
|||
}
|
||||
|
||||
/********************** StdMarshal implementation ****************************/
|
||||
typedef struct _StdMarshalImpl {
|
||||
IMarshalVtbl *lpvtbl;
|
||||
DWORD ref;
|
||||
typedef struct _StdMarshalImpl
|
||||
{
|
||||
const IMarshalVtbl *lpvtbl;
|
||||
DWORD ref;
|
||||
|
||||
IID iid;
|
||||
DWORD dwDestContext;
|
||||
LPVOID pvDestContext;
|
||||
DWORD mshlflags;
|
||||
IID iid;
|
||||
DWORD dwDestContext;
|
||||
LPVOID pvDestContext;
|
||||
DWORD mshlflags;
|
||||
} StdMarshalImpl;
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_QueryInterface(LPMARSHAL iface,REFIID riid,LPVOID *ppv) {
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(&IID_IUnknown,riid) || IsEqualIID(&IID_IMarshal,riid)) {
|
||||
*ppv = iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("No interface for %s.\n",debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_QueryInterface(LPMARSHAL iface, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IMarshal, riid))
|
||||
{
|
||||
*ppv = iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
FIXME("No interface for %s.\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
StdMarshalImpl_AddRef(LPMARSHAL iface) {
|
||||
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
StdMarshalImpl_AddRef(LPMARSHAL iface)
|
||||
{
|
||||
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
StdMarshalImpl_Release(LPMARSHAL iface) {
|
||||
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
StdMarshalImpl_Release(LPMARSHAL iface)
|
||||
{
|
||||
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (!ref) HeapFree(GetProcessHeap(),0,This);
|
||||
return ref;
|
||||
if (!ref) HeapFree(GetProcessHeap(),0,This);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_GetUnmarshalClass(
|
||||
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
||||
void* pvDestContext, DWORD mshlflags, CLSID* pCid
|
||||
) {
|
||||
memcpy(pCid,&CLSID_DfMarshal,sizeof(CLSID_DfMarshal));
|
||||
return S_OK;
|
||||
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
||||
void* pvDestContext, DWORD mshlflags, CLSID* pCid)
|
||||
{
|
||||
*pCid = CLSID_DfMarshal;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_GetMarshalSizeMax(
|
||||
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
||||
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
|
||||
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
||||
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
|
||||
{
|
||||
*pSize = sizeof(STDOBJREF);
|
||||
return S_OK;
|
||||
|
@ -804,48 +808,48 @@ StdMarshalImpl_GetMarshalSizeMax(
|
|||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_MarshalInterface(
|
||||
LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dwDestContext,
|
||||
void* pvDestContext, DWORD mshlflags
|
||||
) {
|
||||
STDOBJREF stdobjref;
|
||||
IUnknown *pUnk;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
|
||||
TRACE("(...,%s,...)\n",debugstr_guid(riid));
|
||||
LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dwDestContext,
|
||||
void* pvDestContext, DWORD mshlflags)
|
||||
{
|
||||
STDOBJREF stdobjref;
|
||||
IUnknown *pUnk;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
|
||||
if (!apt)
|
||||
{
|
||||
ERR("Apartment not initialized\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
TRACE("(...,%s,...)\n", debugstr_guid(riid));
|
||||
|
||||
/* make sure this apartment can be reached from other threads / processes */
|
||||
RPC_StartRemoting(apt);
|
||||
if (!apt)
|
||||
{
|
||||
ERR("Apartment not initialized\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
ERR("object doesn't expose interface %s, failing with error 0x%08lx\n",
|
||||
debugstr_guid(riid), hres);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
/* make sure this apartment can be reached from other threads / processes */
|
||||
RPC_StartRemoting(apt);
|
||||
|
||||
hres = marshal_object(apt, &stdobjref, riid, pUnk, mshlflags);
|
||||
hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
ERR("object doesn't expose interface %s, failing with error 0x%08lx\n",
|
||||
debugstr_guid(riid), hres);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
hres = marshal_object(apt, &stdobjref, riid, pUnk, mshlflags);
|
||||
|
||||
IUnknown_Release(pUnk);
|
||||
IUnknown_Release(pUnk);
|
||||
|
||||
if (hres)
|
||||
{
|
||||
FIXME("Failed to create ifstub, hres=0x%lx\n", hres);
|
||||
return hres;
|
||||
}
|
||||
if (hres)
|
||||
{
|
||||
ERR("Failed to create ifstub, hres=0x%lx\n", hres);
|
||||
return hres;
|
||||
}
|
||||
|
||||
hres = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||
if (hres) return hres;
|
||||
hres = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||
if (hres) return hres;
|
||||
|
||||
return S_OK;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
|
||||
|
@ -907,85 +911,86 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
|
|||
static HRESULT WINAPI
|
||||
StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
|
||||
{
|
||||
struct stub_manager *stubmgr;
|
||||
STDOBJREF stdobjref;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
APARTMENT *stub_apt;
|
||||
OXID oxid;
|
||||
struct stub_manager *stubmgr;
|
||||
STDOBJREF stdobjref;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
APARTMENT *stub_apt;
|
||||
OXID oxid;
|
||||
|
||||
TRACE("(...,%s,....)\n",debugstr_guid(riid));
|
||||
TRACE("(...,%s,....)\n", debugstr_guid(riid));
|
||||
|
||||
/* we need an apartment to unmarshal into */
|
||||
if (!apt)
|
||||
{
|
||||
ERR("Apartment not initialized\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
/* we need an apartment to unmarshal into */
|
||||
if (!apt)
|
||||
{
|
||||
ERR("Apartment not initialized\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
/* read STDOBJREF from wire */
|
||||
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||
if (hres) return hres;
|
||||
/* read STDOBJREF from wire */
|
||||
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||
if (hres) return hres;
|
||||
|
||||
hres = apartment_getoxid(apt, &oxid);
|
||||
if (hres) return hres;
|
||||
hres = apartment_getoxid(apt, &oxid);
|
||||
if (hres) return hres;
|
||||
|
||||
/* check if we're marshalling back to ourselves */
|
||||
if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
|
||||
{
|
||||
TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
|
||||
"returning original object %p\n", debugstr_guid(riid), stubmgr->object);
|
||||
/* check if we're marshalling back to ourselves */
|
||||
if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
|
||||
{
|
||||
TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
|
||||
"returning original object %p\n", debugstr_guid(riid), stubmgr->object);
|
||||
|
||||
hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
|
||||
hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
|
||||
|
||||
/* unref the ifstub. FIXME: only do this on success? */
|
||||
if (!stub_manager_is_table_marshaled(stubmgr))
|
||||
stub_manager_ext_release(stubmgr, 1);
|
||||
/* unref the ifstub. FIXME: only do this on success? */
|
||||
if (!stub_manager_is_table_marshaled(stubmgr))
|
||||
stub_manager_ext_release(stubmgr, 1);
|
||||
|
||||
stub_manager_int_release(stubmgr);
|
||||
return hres;
|
||||
}
|
||||
stub_manager_int_release(stubmgr);
|
||||
return hres;
|
||||
}
|
||||
|
||||
/* notify stub manager about unmarshal if process-local object.
|
||||
* note: if the oxid is not found then we and native will quite happily
|
||||
* ignore table marshaling and normal marshaling rules regarding number of
|
||||
* unmarshals, etc, but if you abuse these rules then your proxy could end
|
||||
* up returning RPC_E_DISCONNECTED. */
|
||||
if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
|
||||
{
|
||||
if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
|
||||
{
|
||||
if (!stub_manager_notify_unmarshal(stubmgr))
|
||||
hres = CO_E_OBJNOTCONNECTED;
|
||||
/* notify stub manager about unmarshal if process-local object.
|
||||
* note: if the oxid is not found then we and native will quite happily
|
||||
* ignore table marshaling and normal marshaling rules regarding number of
|
||||
* unmarshals, etc, but if you abuse these rules then your proxy could end
|
||||
* up returning RPC_E_DISCONNECTED. */
|
||||
if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
|
||||
{
|
||||
if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
|
||||
{
|
||||
if (!stub_manager_notify_unmarshal(stubmgr))
|
||||
hres = CO_E_OBJNOTCONNECTED;
|
||||
|
||||
stub_manager_int_release(stubmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n",
|
||||
wine_dbgstr_longlong(stdobjref.oxid),
|
||||
wine_dbgstr_longlong(stdobjref.oid));
|
||||
hres = CO_E_OBJNOTCONNECTED;
|
||||
}
|
||||
stub_manager_int_release(stubmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n",
|
||||
wine_dbgstr_longlong(stdobjref.oxid),
|
||||
wine_dbgstr_longlong(stdobjref.oid));
|
||||
hres = CO_E_OBJNOTCONNECTED;
|
||||
}
|
||||
|
||||
apartment_release(stub_apt);
|
||||
}
|
||||
else
|
||||
TRACE("Treating unmarshal from OXID %s as inter-process\n",
|
||||
apartment_release(stub_apt);
|
||||
}
|
||||
else
|
||||
TRACE("Treating unmarshal from OXID %s as inter-process\n",
|
||||
wine_dbgstr_longlong(stdobjref.oxid));
|
||||
|
||||
if (hres == S_OK)
|
||||
hres = unmarshal_object(&stdobjref, apt, riid, ppv);
|
||||
if (hres == S_OK)
|
||||
hres = unmarshal_object(&stdobjref, apt, riid, ppv);
|
||||
|
||||
if (hres) WARN("Failed with error 0x%08lx\n", hres);
|
||||
else TRACE("Successfully created proxy %p\n", *ppv);
|
||||
if (hres) WARN("Failed with error 0x%08lx\n", hres);
|
||||
else TRACE("Successfully created proxy %p\n", *ppv);
|
||||
|
||||
return hres;
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
|
||||
StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
|
||||
{
|
||||
STDOBJREF stdobjref;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
|
@ -997,6 +1002,11 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
|
|||
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||
if (hres) return hres;
|
||||
|
||||
TRACE("oxid = %s, oid = %s, ipid = %s\n",
|
||||
wine_dbgstr_longlong(stdobjref.oxid),
|
||||
wine_dbgstr_longlong(stdobjref.oid),
|
||||
wine_dbgstr_guid(&stdobjref.ipid));
|
||||
|
||||
if (!(apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
|
||||
{
|
||||
WARN("Could not map OXID %s to apartment object\n",
|
||||
|
@ -1020,12 +1030,14 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
|
|||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved) {
|
||||
FIXME("(), stub!\n");
|
||||
return S_OK;
|
||||
StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved)
|
||||
{
|
||||
FIXME("(), stub!\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IMarshalVtbl stdmvtbl = {
|
||||
static const IMarshalVtbl VT_StdMarshal =
|
||||
{
|
||||
StdMarshalImpl_QueryInterface,
|
||||
StdMarshalImpl_AddRef,
|
||||
StdMarshalImpl_Release,
|
||||
|
@ -1043,7 +1055,7 @@ static HRESULT StdMarshalImpl_Construct(REFIID riid, void** ppvObject)
|
|||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(StdMarshalImpl));
|
||||
if (!pStdMarshal)
|
||||
return E_OUTOFMEMORY;
|
||||
pStdMarshal->lpvtbl = &stdmvtbl;
|
||||
pStdMarshal->lpvtbl = &VT_StdMarshal;
|
||||
pStdMarshal->ref = 0;
|
||||
return IMarshal_QueryInterface((IMarshal*)pStdMarshal, riid, ppvObject);
|
||||
}
|
||||
|
@ -1075,28 +1087,27 @@ HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk,
|
|||
DWORD dwDestContext, LPVOID pvDestContext,
|
||||
DWORD mshlflags, LPMARSHAL *ppMarshal)
|
||||
{
|
||||
StdMarshalImpl *dm;
|
||||
StdMarshalImpl *dm;
|
||||
|
||||
if (pUnk == NULL) {
|
||||
FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
|
||||
debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,ppMarshal
|
||||
);
|
||||
return E_FAIL;
|
||||
}
|
||||
TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
|
||||
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal
|
||||
);
|
||||
*ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
|
||||
dm = (StdMarshalImpl*) *ppMarshal;
|
||||
if (!dm) return E_FAIL;
|
||||
dm->lpvtbl = &stdmvtbl;
|
||||
dm->ref = 1;
|
||||
if (pUnk == NULL)
|
||||
{
|
||||
FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
|
||||
debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,ppMarshal);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
|
||||
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal);
|
||||
*ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
|
||||
dm = (StdMarshalImpl*) *ppMarshal;
|
||||
if (!dm) return E_FAIL;
|
||||
dm->lpvtbl = &VT_StdMarshal;
|
||||
dm->ref = 1;
|
||||
|
||||
memcpy(&dm->iid,riid,sizeof(dm->iid));
|
||||
dm->dwDestContext = dwDestContext;
|
||||
dm->pvDestContext = pvDestContext;
|
||||
dm->mshlflags = mshlflags;
|
||||
return S_OK;
|
||||
dm->iid = *riid;
|
||||
dm->dwDestContext = dwDestContext;
|
||||
dm->pvDestContext = pvDestContext;
|
||||
dm->mshlflags = mshlflags;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1157,7 +1168,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
|
|||
}
|
||||
else if (objref.flags & OBJREF_CUSTOM)
|
||||
{
|
||||
ULONG custom_header_size = FIELD_OFFSET(OBJREF, u_objref.u_custom.size) -
|
||||
ULONG custom_header_size = FIELD_OFFSET(OBJREF, u_objref.u_custom.pData) -
|
||||
FIELD_OFFSET(OBJREF, u_objref.u_custom);
|
||||
TRACE("Using custom unmarshaling\n");
|
||||
/* read constant sized OR_CUSTOM data from stream */
|
||||
|
@ -1234,7 +1245,7 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk,
|
|||
|
||||
/* if custom marshaling, add on size of custom header */
|
||||
if (!IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal))
|
||||
*pulSize += FIELD_OFFSET(OBJREF, u_objref.u_custom.size) -
|
||||
*pulSize += FIELD_OFFSET(OBJREF, u_objref.u_custom.pData) -
|
||||
FIELD_OFFSET(OBJREF, u_objref.u_custom);
|
||||
|
||||
IMarshal_Release(pMarshal);
|
||||
|
@ -1281,7 +1292,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
|
|||
HRESULT hr;
|
||||
CLSID marshaler_clsid;
|
||||
OBJREF objref;
|
||||
IStream * pMarshalStream = NULL;
|
||||
LPMARSHAL pMarshal;
|
||||
|
||||
TRACE("(%p, %s, %p, %lx, %p, %lx)\n", pStream, debugstr_guid(riid), pUnk,
|
||||
|
@ -1314,33 +1324,43 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
|
|||
{
|
||||
TRACE("Using standard marshaling\n");
|
||||
objref.flags = OBJREF_STANDARD;
|
||||
pMarshalStream = pStream;
|
||||
|
||||
/* write the common OBJREF header to the stream */
|
||||
hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL);
|
||||
if (hr)
|
||||
{
|
||||
ERR("Failed to write OBJREF header to stream, 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Using custom marshaling\n");
|
||||
objref.flags = OBJREF_CUSTOM;
|
||||
/* we do custom marshaling into a memory stream so that we know what
|
||||
* size to write into the OR_CUSTOM header */
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pMarshalStream);
|
||||
objref.u_objref.u_custom.clsid = marshaler_clsid;
|
||||
objref.u_objref.u_custom.cbExtension = 0;
|
||||
objref.u_objref.u_custom.size = 0;
|
||||
hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext,
|
||||
pvDestContext, mshlFlags,
|
||||
&objref.u_objref.u_custom.size);
|
||||
if (hr)
|
||||
{
|
||||
ERR("CreateStreamOnHGLOBAL failed with 0x%08lx\n", hr);
|
||||
ERR("Failed to get max size of marshal data, error 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
/* write constant sized common header and OR_CUSTOM data into stream */
|
||||
hr = IStream_Write(pStream, &objref,
|
||||
FIELD_OFFSET(OBJREF, u_objref.u_custom.pData), NULL);
|
||||
if (hr)
|
||||
{
|
||||
ERR("Failed to write OR_CUSTOM header to stream with 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* write the common OBJREF header to the stream */
|
||||
hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL);
|
||||
if (hr)
|
||||
{
|
||||
ERR("Failed to write OBJREF header to stream, 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
TRACE("Calling IMarshal::MarshalInterace\n");
|
||||
/* call helper object to do the actual marshaling */
|
||||
hr = IMarshal_MarshalInterface(pMarshal, pMarshalStream, riid, pUnk, dwDestContext,
|
||||
hr = IMarshal_MarshalInterface(pMarshal, pStream, riid, pUnk, dwDestContext,
|
||||
pvDestContext, mshlFlags);
|
||||
|
||||
if (hr)
|
||||
|
@ -1349,51 +1369,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (objref.flags & OBJREF_CUSTOM)
|
||||
{
|
||||
ULONG custom_header_size = FIELD_OFFSET(OBJREF, u_objref.u_custom.size) -
|
||||
FIELD_OFFSET(OBJREF, u_objref.u_custom);
|
||||
HGLOBAL hGlobal;
|
||||
LPVOID data;
|
||||
hr = GetHGlobalFromStream(pMarshalStream, &hGlobal);
|
||||
if (hr)
|
||||
{
|
||||
ERR("Couldn't get HGLOBAL from stream\n");
|
||||
hr = E_UNEXPECTED;
|
||||
goto cleanup;
|
||||
}
|
||||
objref.u_objref.u_custom.clsid = marshaler_clsid;
|
||||
objref.u_objref.u_custom.cbExtension = 0;
|
||||
objref.u_objref.u_custom.size = GlobalSize(hGlobal);
|
||||
/* write constant sized OR_CUSTOM data into stream */
|
||||
hr = IStream_Write(pStream, &objref.u_objref.u_custom,
|
||||
custom_header_size, NULL);
|
||||
if (hr)
|
||||
{
|
||||
ERR("Failed to write OR_CUSTOM header to stream with 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
data = GlobalLock(hGlobal);
|
||||
if (!data)
|
||||
{
|
||||
ERR("GlobalLock failed\n");
|
||||
hr = E_UNEXPECTED;
|
||||
goto cleanup;
|
||||
}
|
||||
/* write custom marshal data */
|
||||
hr = IStream_Write(pStream, data, objref.u_objref.u_custom.size, NULL);
|
||||
if (hr)
|
||||
{
|
||||
ERR("Failed to write custom marshal data with 0x%08lx\n", hr);
|
||||
goto cleanup;
|
||||
}
|
||||
GlobalUnlock(hGlobal);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (pMarshalStream && (objref.flags & OBJREF_CUSTOM))
|
||||
IStream_Release(pMarshalStream);
|
||||
IMarshal_Release(pMarshal);
|
||||
|
||||
TRACE("completed with hr 0x%08lx\n", hr);
|
||||
|
@ -1602,11 +1578,11 @@ static ULONG WINAPI StdMarshalCF_Release(LPCLASSFACTORY iface)
|
|||
static HRESULT WINAPI StdMarshalCF_CreateInstance(LPCLASSFACTORY iface,
|
||||
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
if (IsEqualIID(riid,&IID_IMarshal))
|
||||
return StdMarshalImpl_Construct(riid, ppv);
|
||||
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMarshal))
|
||||
return StdMarshalImpl_Construct(riid, ppv);
|
||||
|
||||
FIXME("(%s), not supported.\n",debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
FIXME("(%s), not supported.\n",debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI StdMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
|
||||
|
@ -1615,7 +1591,7 @@ static HRESULT WINAPI StdMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static IClassFactoryVtbl StdMarshalCFVtbl =
|
||||
static const IClassFactoryVtbl StdMarshalCFVtbl =
|
||||
{
|
||||
StdMarshalCF_QueryInterface,
|
||||
StdMarshalCF_AddRef,
|
||||
|
@ -1623,7 +1599,7 @@ static IClassFactoryVtbl StdMarshalCFVtbl =
|
|||
StdMarshalCF_CreateInstance,
|
||||
StdMarshalCF_LockServer
|
||||
};
|
||||
static IClassFactoryVtbl *StdMarshalCF = &StdMarshalCFVtbl;
|
||||
static const IClassFactoryVtbl *StdMarshalCF = &StdMarshalCFVtbl;
|
||||
|
||||
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,4 +8,10 @@ extern const CLSID CLSID_ItemMoniker;
|
|||
extern const CLSID CLSID_AntiMoniker;
|
||||
extern const CLSID CLSID_CompositeMoniker;
|
||||
|
||||
HRESULT FileMonikerCF_Create(REFIID riid, LPVOID *ppv);
|
||||
HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv);
|
||||
|
||||
HRESULT MonikerMarshal_Create(IMoniker *inner, IUnknown **outer);
|
||||
|
||||
|
||||
#endif /* __WINE_MONIKER_H__ */
|
||||
|
|
|
@ -50,9 +50,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
HINSTANCE16 COMPOBJ_hInstance = 0;
|
||||
static int COMPOBJ_Attach = 0;
|
||||
|
||||
HTASK16 hETask = 0;
|
||||
WORD Table_ETask[62];
|
||||
|
||||
|
@ -299,7 +296,7 @@ extern BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
|
|||
* RETURNS
|
||||
* the allocated segmented pointer and a HRESULT
|
||||
*/
|
||||
HRESULT
|
||||
static HRESULT
|
||||
_xmalloc16(DWORD size, SEGPTR *ptr) {
|
||||
LPMALLOC16 mllc;
|
||||
DWORD args[2];
|
||||
|
@ -512,16 +509,5 @@ HRESULT WINAPI CoGetState16(LPDWORD state)
|
|||
BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
|
||||
{
|
||||
TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
|
||||
switch(Reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
if (!COMPOBJ_Attach++) COMPOBJ_hInstance = hInst;
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
if(!--COMPOBJ_Attach)
|
||||
COMPOBJ_hInstance = 0;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Copyright 1999 Francis Beaudet
|
||||
* Copyright 1999 Noel Borthwick
|
||||
* Copyright 1999, 2000 Marcus Meissner
|
||||
* Copyright 2005 Juan Lang
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -48,7 +49,6 @@
|
|||
#include "wine/winbase16.h"
|
||||
#include "wine/wingdi16.h"
|
||||
#include "wine/winuser16.h"
|
||||
#include "ole32_main.h"
|
||||
#include "compobj_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
@ -2292,13 +2292,13 @@ HRESULT WINAPI OleCreate(
|
|||
/******************************************************************************
|
||||
* OleSetAutoConvert [OLE32.@]
|
||||
*/
|
||||
/* FIXME: convert to Unicode */
|
||||
HRESULT WINAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
char buf[200], szClsidNew[200];
|
||||
HRESULT res = S_OK;
|
||||
|
||||
/* FIXME: convert to Unicode */
|
||||
TRACE("(%s,%s)\n", debugstr_guid(clsidOld), debugstr_guid(clsidNew));
|
||||
sprintf(buf,"CLSID\\");WINE_StringFromCLSID(clsidOld,&buf[6]);
|
||||
WINE_StringFromCLSID(clsidNew, szClsidNew);
|
||||
|
@ -2541,26 +2541,40 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */
|
|||
}
|
||||
break;
|
||||
default:
|
||||
switch (pvar->vt & ~VT_VECTOR)
|
||||
if (pvar->vt & VT_VECTOR)
|
||||
{
|
||||
case VT_VARIANT:
|
||||
FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems);
|
||||
break;
|
||||
case VT_CF:
|
||||
OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems);
|
||||
break;
|
||||
case VT_BSTR:
|
||||
case VT_LPSTR:
|
||||
case VT_LPWSTR:
|
||||
case VT_CLSID:
|
||||
FIXME("Freeing of vector sub-type not supported yet\n");
|
||||
}
|
||||
if (pvar->vt & ~VT_VECTOR)
|
||||
{
|
||||
/* pick an arbitary VT_VECTOR structure - they all have the same
|
||||
* memory layout */
|
||||
CoTaskMemFree(pvar->u.capropvar.pElems);
|
||||
ULONG i;
|
||||
|
||||
switch (pvar->vt & ~VT_VECTOR)
|
||||
{
|
||||
case VT_VARIANT:
|
||||
FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems);
|
||||
break;
|
||||
case VT_CF:
|
||||
OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems);
|
||||
break;
|
||||
case VT_BSTR:
|
||||
for (i = 0; i < pvar->u.cabstr.cElems; i++)
|
||||
PropSysFreeString(pvar->u.cabstr.pElems[i]);
|
||||
break;
|
||||
case VT_LPSTR:
|
||||
for (i = 0; i < pvar->u.calpstr.cElems; i++)
|
||||
CoTaskMemFree(pvar->u.calpstr.pElems[i]);
|
||||
break;
|
||||
case VT_LPWSTR:
|
||||
for (i = 0; i < pvar->u.calpwstr.cElems; i++)
|
||||
CoTaskMemFree(pvar->u.calpwstr.pElems[i]);
|
||||
break;
|
||||
}
|
||||
if (pvar->vt & ~VT_VECTOR)
|
||||
{
|
||||
/* pick an arbitary VT_VECTOR structure - they all have the same
|
||||
* memory layout */
|
||||
CoTaskMemFree(pvar->u.capropvar.pElems);
|
||||
}
|
||||
}
|
||||
else
|
||||
WARN("Invalid/unsupported type %d\n", pvar->vt);
|
||||
}
|
||||
|
||||
ZeroMemory(pvar, sizeof(*pvar));
|
||||
|
@ -2632,7 +2646,9 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
|
|||
if (pvarSrc->vt & VT_VECTOR)
|
||||
{
|
||||
int elemSize;
|
||||
switch(pvarSrc->vt & VT_VECTOR)
|
||||
ULONG i;
|
||||
|
||||
switch(pvarSrc->vt & ~VT_VECTOR)
|
||||
{
|
||||
case VT_I1: elemSize = sizeof(pvarSrc->u.cVal); break;
|
||||
case VT_UI1: elemSize = sizeof(pvarSrc->u.bVal); break;
|
||||
|
@ -2651,20 +2667,19 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
|
|||
case VT_FILETIME: elemSize = sizeof(pvarSrc->u.filetime); break;
|
||||
case VT_CLSID: elemSize = sizeof(*pvarSrc->u.puuid); break;
|
||||
case VT_CF: elemSize = sizeof(*pvarSrc->u.pclipdata); break;
|
||||
case VT_BSTR: elemSize = sizeof(*pvarSrc->u.bstrVal); break;
|
||||
case VT_LPSTR: elemSize = sizeof(*pvarSrc->u.pszVal); break;
|
||||
case VT_LPWSTR: elemSize = sizeof(*pvarSrc->u.pwszVal); break;
|
||||
|
||||
case VT_BSTR:
|
||||
case VT_LPSTR:
|
||||
case VT_LPWSTR:
|
||||
case VT_VARIANT:
|
||||
default:
|
||||
FIXME("Invalid element type: %ul\n", pvarSrc->vt & VT_VECTOR);
|
||||
FIXME("Invalid element type: %ul\n", pvarSrc->vt & ~VT_VECTOR);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
len = pvarSrc->u.capropvar.cElems;
|
||||
pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize);
|
||||
if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT))
|
||||
{
|
||||
ULONG i;
|
||||
for (i = 0; i < len; i++)
|
||||
PropVariantCopy(&pvarDest->u.capropvar.pElems[i], &pvarSrc->u.capropvar.pElems[i]);
|
||||
}
|
||||
|
@ -2674,19 +2689,37 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
|
|||
}
|
||||
else if (pvarSrc->vt == (VT_VECTOR | VT_BSTR))
|
||||
{
|
||||
FIXME("Copy BSTRs\n");
|
||||
for (i = 0; i < len; i++)
|
||||
pvarDest->u.cabstr.pElems[i] = PropSysAllocString(pvarSrc->u.cabstr.pElems[i]);
|
||||
}
|
||||
else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR))
|
||||
{
|
||||
FIXME("Copy LPSTRs\n");
|
||||
size_t strLen;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
strLen = lstrlenA(pvarSrc->u.calpstr.pElems[i]) + 1;
|
||||
pvarDest->u.calpstr.pElems[i] = CoTaskMemAlloc(strLen);
|
||||
memcpy(pvarDest->u.calpstr.pElems[i],
|
||||
pvarSrc->u.calpstr.pElems[i], strLen);
|
||||
}
|
||||
}
|
||||
else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR))
|
||||
else if (pvarSrc->vt == (VT_VECTOR | VT_LPWSTR))
|
||||
{
|
||||
FIXME("Copy LPWSTRs\n");
|
||||
size_t strLen;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
strLen = (lstrlenW(pvarSrc->u.calpwstr.pElems[i]) + 1) *
|
||||
sizeof(WCHAR);
|
||||
pvarDest->u.calpstr.pElems[i] = CoTaskMemAlloc(strLen);
|
||||
memcpy(pvarDest->u.calpstr.pElems[i],
|
||||
pvarSrc->u.calpstr.pElems[i], strLen);
|
||||
}
|
||||
}
|
||||
else
|
||||
CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize);
|
||||
}
|
||||
else
|
||||
WARN("Invalid/unsupported type %d\n", pvarSrc->vt);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "wine/winbase16.h"
|
||||
#include "wine/wingdi16.h"
|
||||
#include "wine/winuser16.h"
|
||||
#include "ole32_main.h"
|
||||
#include "ifs.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
1 stub WEP
|
||||
#1 stub WEP
|
||||
2 stub ROT16_ISRUNNING16
|
||||
3 stub ISWIN32SHANDLE
|
||||
4 stub ___EXPORTEDSTUB
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
@ stdcall CoInitializeEx(ptr long)
|
||||
@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr)
|
||||
@ stdcall CoInitializeWOW(long long)
|
||||
@ stub CoIsHandlerConnected #@ stdcall (ptr) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stdcall CoIsHandlerConnected(ptr)
|
||||
@ stdcall CoIsOle1Class (ptr)
|
||||
@ stdcall CoLoadLibrary(wstr long)
|
||||
@ stdcall CoLockObjectExternal(ptr long long)
|
||||
|
@ -247,7 +247,7 @@
|
|||
@ stub STGMEDIUM_UserUnmarshal
|
||||
@ stub StgOpenAsyncDocfileOnIFillLockBytes
|
||||
@ stdcall StgOpenStorage(wstr ptr long ptr long ptr)
|
||||
@ stub StgOpenStorageEx
|
||||
@ stdcall StgOpenStorageEx(wstr long long long ptr ptr ptr ptr)
|
||||
@ stdcall StgOpenStorageOnILockBytes(ptr ptr long long long ptr)
|
||||
@ stdcall StgSetTimes(wstr ptr ptr ptr )
|
||||
@ stdcall StringFromCLSID(ptr ptr)
|
||||
|
|
|
@ -27,13 +27,11 @@
|
|||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "ole32_main.h"
|
||||
#include "objbase.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
HINSTANCE OLE32_hInstance = 0;
|
||||
|
||||
/***********************************************************************
|
||||
* OleMetafilePictFromIconAndLabel (OLE32.@)
|
||||
*/
|
||||
|
@ -110,33 +108,3 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
|
|||
|
||||
return hmem;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DllMain (OLE32.@)
|
||||
*/
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||
{
|
||||
TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
|
||||
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
OLE32_hInstance = hinstDLL;
|
||||
COMPOBJ_InitProcess();
|
||||
if (TRACE_ON(ole)) CoRegisterMallocSpy((LPVOID)-1);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (TRACE_ON(ole)) CoRevokeMallocSpy();
|
||||
COMPOBJ_UninitProcess();
|
||||
OLE32_hInstance = 0;
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
COM_TlsDestroy();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* NOTE: DllRegisterServer and DllUnregisterServer are in regsvr.c */
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2000 Huw D M Davies for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_OLE32_MAIN_H
|
||||
#define __WINE_OLE32_MAIN_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "objbase.h"
|
||||
|
||||
extern HINSTANCE OLE32_hInstance;
|
||||
|
||||
void COMPOBJ_InitProcess( void );
|
||||
void COMPOBJ_UninitProcess( void );
|
||||
void COM_TlsDestroy( void );
|
||||
|
||||
#endif /* __WINE_OLE32_MAIN_H */
|
|
@ -50,60 +50,6 @@ typedef struct OleAdviseHolderImpl
|
|||
|
||||
} OleAdviseHolderImpl;
|
||||
|
||||
static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor(void);
|
||||
static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*);
|
||||
static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER);
|
||||
static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER);
|
||||
static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER);
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl_VTable
|
||||
*/
|
||||
static struct IOleAdviseHolderVtbl oahvt =
|
||||
{
|
||||
OleAdviseHolderImpl_QueryInterface,
|
||||
OleAdviseHolderImpl_AddRef,
|
||||
OleAdviseHolderImpl_Release,
|
||||
OleAdviseHolderImpl_Advise,
|
||||
OleAdviseHolderImpl_Unadvise,
|
||||
OleAdviseHolderImpl_EnumAdvise,
|
||||
OleAdviseHolderImpl_SendOnRename,
|
||||
OleAdviseHolderImpl_SendOnSave,
|
||||
OleAdviseHolderImpl_SendOnClose
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl_Constructor
|
||||
*/
|
||||
|
||||
static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
|
||||
{
|
||||
OleAdviseHolderImpl* lpoah;
|
||||
DWORD index;
|
||||
|
||||
lpoah = HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl));
|
||||
|
||||
lpoah->lpVtbl = &oahvt;
|
||||
lpoah->ref = 1;
|
||||
lpoah->maxSinks = INITIAL_SINKS;
|
||||
lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
lpoah->maxSinks * sizeof(IAdviseSink*));
|
||||
|
||||
for (index = 0; index < lpoah->maxSinks; index++)
|
||||
lpoah->arrayOfSinks[index]=0;
|
||||
|
||||
TRACE("returning %p\n", lpoah);
|
||||
return (LPOLEADVISEHOLDER)lpoah;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl_Destructor
|
||||
*/
|
||||
|
@ -357,6 +303,47 @@ OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl_VTable
|
||||
*/
|
||||
static struct IOleAdviseHolderVtbl oahvt =
|
||||
{
|
||||
OleAdviseHolderImpl_QueryInterface,
|
||||
OleAdviseHolderImpl_AddRef,
|
||||
OleAdviseHolderImpl_Release,
|
||||
OleAdviseHolderImpl_Advise,
|
||||
OleAdviseHolderImpl_Unadvise,
|
||||
OleAdviseHolderImpl_EnumAdvise,
|
||||
OleAdviseHolderImpl_SendOnRename,
|
||||
OleAdviseHolderImpl_SendOnSave,
|
||||
OleAdviseHolderImpl_SendOnClose
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* OleAdviseHolderImpl_Constructor
|
||||
*/
|
||||
|
||||
static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
|
||||
{
|
||||
OleAdviseHolderImpl* lpoah;
|
||||
DWORD index;
|
||||
|
||||
lpoah = HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl));
|
||||
|
||||
lpoah->lpVtbl = &oahvt;
|
||||
lpoah->ref = 1;
|
||||
lpoah->maxSinks = INITIAL_SINKS;
|
||||
lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
lpoah->maxSinks * sizeof(IAdviseSink*));
|
||||
|
||||
for (index = 0; index < lpoah->maxSinks; index++)
|
||||
lpoah->arrayOfSinks[index]=0;
|
||||
|
||||
TRACE("returning %p\n", lpoah);
|
||||
return (LPOLEADVISEHOLDER)lpoah;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DataAdviseHolder Implementation
|
||||
*/
|
||||
|
@ -375,73 +362,6 @@ typedef struct DataAdviseHolder
|
|||
DataAdviseConnection* Connections;
|
||||
} DataAdviseHolder;
|
||||
|
||||
/**************************************************************************
|
||||
* DataAdviseHolder method prototypes
|
||||
*/
|
||||
static IDataAdviseHolder* DataAdviseHolder_Constructor(void);
|
||||
static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy);
|
||||
static HRESULT WINAPI DataAdviseHolder_QueryInterface(
|
||||
IDataAdviseHolder* iface,
|
||||
REFIID riid,
|
||||
void** ppvObject);
|
||||
static ULONG WINAPI DataAdviseHolder_AddRef(
|
||||
IDataAdviseHolder* iface);
|
||||
static ULONG WINAPI DataAdviseHolder_Release(
|
||||
IDataAdviseHolder* iface);
|
||||
static HRESULT WINAPI DataAdviseHolder_Advise(
|
||||
IDataAdviseHolder* iface,
|
||||
IDataObject* pDataObject,
|
||||
FORMATETC* pFetc,
|
||||
DWORD advf,
|
||||
IAdviseSink* pAdvise,
|
||||
DWORD* pdwConnection);
|
||||
static HRESULT WINAPI DataAdviseHolder_Unadvise(
|
||||
IDataAdviseHolder* iface,
|
||||
DWORD dwConnection);
|
||||
static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
|
||||
IDataAdviseHolder* iface,
|
||||
IEnumSTATDATA** ppenumAdvise);
|
||||
static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
|
||||
IDataAdviseHolder* iface,
|
||||
IDataObject* pDataObject,
|
||||
DWORD dwReserved,
|
||||
DWORD advf);
|
||||
|
||||
/**************************************************************************
|
||||
* DataAdviseHolderImpl_VTable
|
||||
*/
|
||||
static struct IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable =
|
||||
{
|
||||
DataAdviseHolder_QueryInterface,
|
||||
DataAdviseHolder_AddRef,
|
||||
DataAdviseHolder_Release,
|
||||
DataAdviseHolder_Advise,
|
||||
DataAdviseHolder_Unadvise,
|
||||
DataAdviseHolder_EnumAdvise,
|
||||
DataAdviseHolder_SendOnDataChange
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* DataAdviseHolder_Constructor
|
||||
*/
|
||||
static IDataAdviseHolder* DataAdviseHolder_Constructor()
|
||||
{
|
||||
DataAdviseHolder* newHolder;
|
||||
|
||||
newHolder = HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder));
|
||||
|
||||
newHolder->lpVtbl = &DataAdviseHolderImpl_VTable;
|
||||
newHolder->ref = 1;
|
||||
newHolder->maxCons = INITIAL_SINKS;
|
||||
newHolder->Connections = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
newHolder->maxCons *
|
||||
sizeof(DataAdviseConnection));
|
||||
|
||||
TRACE("returning %p\n", newHolder);
|
||||
return (IDataAdviseHolder*)newHolder;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DataAdviseHolder_Destructor
|
||||
*/
|
||||
|
@ -605,7 +525,7 @@ static HRESULT WINAPI DataAdviseHolder_Advise(
|
|||
if (This->Connections[index].sink != NULL) {
|
||||
IAdviseSink_AddRef(This->Connections[index].sink);
|
||||
if(advf & ADVF_PRIMEFIRST) {
|
||||
DataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
|
||||
IDataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -702,6 +622,41 @@ static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DataAdviseHolderImpl_VTable
|
||||
*/
|
||||
static struct IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable =
|
||||
{
|
||||
DataAdviseHolder_QueryInterface,
|
||||
DataAdviseHolder_AddRef,
|
||||
DataAdviseHolder_Release,
|
||||
DataAdviseHolder_Advise,
|
||||
DataAdviseHolder_Unadvise,
|
||||
DataAdviseHolder_EnumAdvise,
|
||||
DataAdviseHolder_SendOnDataChange
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* DataAdviseHolder_Constructor
|
||||
*/
|
||||
static IDataAdviseHolder* DataAdviseHolder_Constructor()
|
||||
{
|
||||
DataAdviseHolder* newHolder;
|
||||
|
||||
newHolder = HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder));
|
||||
|
||||
newHolder->lpVtbl = &DataAdviseHolderImpl_VTable;
|
||||
newHolder->ref = 1;
|
||||
newHolder->maxCons = INITIAL_SINKS;
|
||||
newHolder->Connections = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
newHolder->maxCons *
|
||||
sizeof(DataAdviseConnection));
|
||||
|
||||
TRACE("returning %p\n", newHolder);
|
||||
return (IDataAdviseHolder*)newHolder;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* API functions
|
||||
*/
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "wtypes.h"
|
||||
|
||||
#include "compobj_private.h"
|
||||
#include "moniker.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -972,10 +973,8 @@ static IPSFactoryBufferVtbl *lppsfac = &psfacbufvtbl;
|
|||
HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(rclsid,&CLSID_PSFactoryBuffer)) {
|
||||
*ppv = &lppsfac;
|
||||
return S_OK;
|
||||
}
|
||||
if (IsEqualIID(rclsid, &CLSID_PSFactoryBuffer))
|
||||
return IPSFactoryBuffer_QueryInterface((IPSFactoryBuffer *)&lppsfac, iid, ppv);
|
||||
if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&(
|
||||
IsEqualIID(iid,&IID_IClassFactory) ||
|
||||
IsEqualIID(iid,&IID_IUnknown)
|
||||
|
@ -984,6 +983,10 @@ HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
|
|||
return MARSHAL_GetStandardMarshalCF(ppv);
|
||||
if (IsEqualIID(rclsid,&CLSID_StdGlobalInterfaceTable) && (IsEqualIID(iid,&IID_IClassFactory) || IsEqualIID(iid,&IID_IUnknown)))
|
||||
return StdGlobalInterfaceTable_GetFactory(ppv);
|
||||
if (IsEqualCLSID(rclsid, &CLSID_FileMoniker))
|
||||
return FileMonikerCF_Create(iid, ppv);
|
||||
if (IsEqualCLSID(rclsid, &CLSID_ItemMoniker))
|
||||
return ItemMonikerCF_Create(iid, ppv);
|
||||
|
||||
FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
|
|
|
@ -30,17 +30,16 @@
|
|||
* It's a little bit out of date, and more definitive references are given
|
||||
* below, but it gives the best "big picture" that I've found.
|
||||
*
|
||||
* TODO: There's a lot missing in here. Biggies:
|
||||
* - There are all sorts of restricions I don't honor, like maximum property
|
||||
* set byte size, maximum property name length
|
||||
* TODO:
|
||||
* - I don't honor the maximum property set size.
|
||||
* - Certain bogus files could result in reading past the end of a buffer.
|
||||
* - This will probably fail on big-endian machines, especially reading and
|
||||
* writing strings.
|
||||
* - Mac-generated files won't be read correctly, even if they're little
|
||||
* endian, because I disregard whether the generator was a Mac. This means
|
||||
* strings will probably be munged (as I don't understand Mac scripts.)
|
||||
* - Not all PROPVARIANT types are supported.
|
||||
* There are lots more unimplemented features, see FIXMEs below.
|
||||
* - User defined properties are not supported, see comment in
|
||||
* PropertyStorage_ReadFromStream
|
||||
* - IPropertyStorage::Enum is unimplemented
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -80,6 +79,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage);
|
|||
|
||||
#define CP_UNICODE 1200
|
||||
|
||||
#define MAX_VERSION_0_PROP_NAME_LENGTH 256
|
||||
|
||||
/* The format version (and what it implies) is described here:
|
||||
* http://msdn.microsoft.com/library/en-us/stg/stg/format_version.asp
|
||||
*/
|
||||
|
@ -130,6 +131,22 @@ static HRESULT PropertyStorage_CreateDictionaries(
|
|||
static void PropertyStorage_DestroyDictionaries(
|
||||
struct tagPropertyStorage_impl *);
|
||||
|
||||
/* Copies from propvar to prop. If propvar's type is VT_LPSTR, copies the
|
||||
* string using PropertyStorage_StringCopy.
|
||||
*/
|
||||
static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop,
|
||||
const PROPVARIANT *propvar, LCID targetCP, LCID srcCP);
|
||||
|
||||
/* Copies the string src, which is encoded using code page srcCP, and returns
|
||||
* it in *dst, in the code page specified by targetCP. The returned string is
|
||||
* allocated using CoTaskMemAlloc.
|
||||
* If srcCP is CP_UNICODE, src is in fact an LPCWSTR. Similarly, if targetCP
|
||||
* is CP_UNICODE, the returned string is in fact an LPWSTR.
|
||||
* Returns S_OK on success, something else on failure.
|
||||
*/
|
||||
static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
|
||||
LCID targetCP);
|
||||
|
||||
static IPropertyStorageVtbl IPropertyStorage_Vtbl;
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -144,6 +161,7 @@ typedef struct tagPropertyStorage_impl
|
|||
BOOL dirty;
|
||||
FMTID fmtid;
|
||||
CLSID clsid;
|
||||
WORD format;
|
||||
DWORD originatorOS;
|
||||
DWORD grfFlags;
|
||||
DWORD grfMode;
|
||||
|
@ -235,8 +253,25 @@ static PROPVARIANT *PropertyStorage_FindPropertyByName(
|
|||
assert(This);
|
||||
if (!name)
|
||||
return NULL;
|
||||
if (dictionary_find(This->name_to_propid, name, (void **)&propid))
|
||||
ret = PropertyStorage_FindProperty(This, (PROPID)propid);
|
||||
if (This->codePage == CP_UNICODE)
|
||||
{
|
||||
if (dictionary_find(This->name_to_propid, name, (void **)&propid))
|
||||
ret = PropertyStorage_FindProperty(This, (PROPID)propid);
|
||||
}
|
||||
else
|
||||
{
|
||||
LPSTR ansiName;
|
||||
HRESULT hr = PropertyStorage_StringCopy((LPCSTR)name, CP_UNICODE,
|
||||
&ansiName, This->codePage);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (dictionary_find(This->name_to_propid, ansiName,
|
||||
(void **)&propid))
|
||||
ret = PropertyStorage_FindProperty(This, (PROPID)propid);
|
||||
CoTaskMemFree(ansiName);
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -280,34 +315,169 @@ static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
|
|||
rgpspec[i].u.lpwstr);
|
||||
|
||||
if (prop)
|
||||
PropVariantCopy(&rgpropvar[i], prop);
|
||||
PropertyStorage_PropVariantCopy(&rgpropvar[i], prop, GetACP(),
|
||||
This->codePage);
|
||||
}
|
||||
else
|
||||
{
|
||||
PROPVARIANT *prop = PropertyStorage_FindProperty(This,
|
||||
rgpspec[i].u.propid);
|
||||
switch (rgpspec[i].u.propid)
|
||||
{
|
||||
case PID_CODEPAGE:
|
||||
rgpropvar[i].vt = VT_I2;
|
||||
rgpropvar[i].u.iVal = This->codePage;
|
||||
break;
|
||||
case PID_LOCALE:
|
||||
rgpropvar[i].vt = VT_I4;
|
||||
rgpropvar[i].u.lVal = This->locale;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
PROPVARIANT *prop = PropertyStorage_FindProperty(This,
|
||||
rgpspec[i].u.propid);
|
||||
|
||||
if (prop)
|
||||
PropVariantCopy(&rgpropvar[i], prop);
|
||||
if (prop)
|
||||
PropertyStorage_PropVariantCopy(&rgpropvar[i], prop,
|
||||
GetACP(), This->codePage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&This->cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
|
||||
LCID dstCP)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
int len;
|
||||
|
||||
TRACE("%s, %p, %ld, %ld\n",
|
||||
srcCP == CP_UNICODE ? debugstr_w((LPCWSTR)src) : debugstr_a(src), dst,
|
||||
dstCP, srcCP);
|
||||
assert(src);
|
||||
assert(dst);
|
||||
*dst = NULL;
|
||||
if (dstCP == srcCP)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (dstCP == CP_UNICODE)
|
||||
len = (strlenW((LPCWSTR)src) + 1) * sizeof(WCHAR);
|
||||
else
|
||||
len = strlen(src) + 1;
|
||||
*dst = CoTaskMemAlloc(len * sizeof(WCHAR));
|
||||
if (!*dst)
|
||||
hr = STG_E_INSUFFICIENTMEMORY;
|
||||
else
|
||||
memcpy(*dst, src, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dstCP == CP_UNICODE)
|
||||
{
|
||||
len = MultiByteToWideChar(srcCP, 0, src, -1, NULL, 0);
|
||||
*dst = CoTaskMemAlloc(len * sizeof(WCHAR));
|
||||
if (!*dst)
|
||||
hr = STG_E_INSUFFICIENTMEMORY;
|
||||
else
|
||||
MultiByteToWideChar(srcCP, 0, src, -1, (LPWSTR)*dst, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
LPWSTR wideStr;
|
||||
|
||||
if (srcCP == CP_UNICODE)
|
||||
wideStr = (LPWSTR)src;
|
||||
else
|
||||
{
|
||||
len = MultiByteToWideChar(srcCP, 0, src, -1, NULL, 0);
|
||||
wideStr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||
if (wideStr)
|
||||
MultiByteToWideChar(srcCP, 0, src, -1, wideStr, len);
|
||||
else
|
||||
hr = STG_E_INSUFFICIENTMEMORY;
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
len = WideCharToMultiByte(dstCP, 0, wideStr, -1, NULL, 0,
|
||||
NULL, NULL);
|
||||
*dst = CoTaskMemAlloc(len);
|
||||
if (!*dst)
|
||||
hr = STG_E_INSUFFICIENTMEMORY;
|
||||
else
|
||||
{
|
||||
BOOL defCharUsed = FALSE;
|
||||
|
||||
if (WideCharToMultiByte(dstCP, 0, wideStr, -1, *dst, len,
|
||||
NULL, &defCharUsed) == 0 || defCharUsed)
|
||||
{
|
||||
CoTaskMemFree(*dst);
|
||||
*dst = NULL;
|
||||
hr = HRESULT_FROM_WIN32(ERROR_NO_UNICODE_TRANSLATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wideStr != (LPWSTR)src)
|
||||
HeapFree(GetProcessHeap(), 0, wideStr);
|
||||
}
|
||||
}
|
||||
TRACE("returning 0x%08lx (%s)\n", hr,
|
||||
dstCP == CP_UNICODE ? debugstr_w((LPCWSTR)*dst) : debugstr_a(*dst));
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop,
|
||||
const PROPVARIANT *propvar, LCID targetCP, LCID srcCP)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
assert(prop);
|
||||
assert(propvar);
|
||||
if (propvar->vt == VT_LPSTR)
|
||||
{
|
||||
hr = PropertyStorage_StringCopy(propvar->u.pszVal, srcCP,
|
||||
&prop->u.pszVal, targetCP);
|
||||
if (SUCCEEDED(hr))
|
||||
prop->vt = VT_LPSTR;
|
||||
}
|
||||
else
|
||||
PropVariantCopy(prop, propvar);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* Stores the property with id propid and value propvar into this property
|
||||
* storage. lcid is ignored if propvar's type is not VT_LPSTR. If propvar's
|
||||
* type is VT_LPSTR, converts the string using lcid as the source code page
|
||||
* and This->codePage as the target code page before storing.
|
||||
* As a side effect, may change This->format to 1 if the type of propvar is
|
||||
* a version 1-only property.
|
||||
*/
|
||||
static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
|
||||
PROPID propid, const PROPVARIANT *propvar)
|
||||
PROPID propid, const PROPVARIANT *propvar, LCID lcid)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
PROPVARIANT *prop = PropertyStorage_FindProperty(This, propid);
|
||||
|
||||
assert(This);
|
||||
assert(propvar);
|
||||
if (propvar->vt & VT_BYREF || propvar->vt & VT_ARRAY)
|
||||
This->format = 1;
|
||||
switch (propvar->vt)
|
||||
{
|
||||
case VT_DECIMAL:
|
||||
case VT_I1:
|
||||
case VT_INT:
|
||||
case VT_UINT:
|
||||
case VT_VECTOR|VT_I1:
|
||||
This->format = 1;
|
||||
}
|
||||
TRACE("Setting 0x%08lx to type %d\n", propid, propvar->vt);
|
||||
if (prop)
|
||||
{
|
||||
PropVariantClear(prop);
|
||||
PropVariantCopy(prop, propvar);
|
||||
hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
|
||||
lcid);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -315,10 +485,16 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
|
|||
sizeof(PROPVARIANT));
|
||||
if (prop)
|
||||
{
|
||||
PropVariantCopy(prop, propvar);
|
||||
dictionary_insert(This->propid_to_prop, (void *)propid, prop);
|
||||
if (propid > This->highestProp)
|
||||
This->highestProp = propid;
|
||||
hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
|
||||
lcid);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dictionary_insert(This->propid_to_prop, (void *)propid, prop);
|
||||
if (propid > This->highestProp)
|
||||
This->highestProp = propid;
|
||||
}
|
||||
else
|
||||
HeapFree(GetProcessHeap(), 0, prop);
|
||||
}
|
||||
else
|
||||
hr = STG_E_INSUFFICIENTMEMORY;
|
||||
|
@ -326,6 +502,43 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
|
|||
return hr;
|
||||
}
|
||||
|
||||
/* Adds the name srcName to the name dictionaries, mapped to property ID id.
|
||||
* srcName is encoded in code page cp, and is converted to This->codePage.
|
||||
* If cp is CP_UNICODE, srcName is actually a unicode string.
|
||||
* As a side effect, may change This->format to 1 if srcName is too long for
|
||||
* a version 0 property storage.
|
||||
* Doesn't validate id.
|
||||
*/
|
||||
static HRESULT PropertyStorage_StoreNameWithId(PropertyStorage_impl *This,
|
||||
LPCSTR srcName, LCID cp, PROPID id)
|
||||
{
|
||||
LPSTR name;
|
||||
HRESULT hr;
|
||||
|
||||
assert(srcName);
|
||||
|
||||
hr = PropertyStorage_StringCopy((LPCSTR)srcName, cp, &name, This->codePage);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (This->codePage == CP_UNICODE)
|
||||
{
|
||||
if (lstrlenW((LPWSTR)name) >= MAX_VERSION_0_PROP_NAME_LENGTH)
|
||||
This->format = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(name) >= MAX_VERSION_0_PROP_NAME_LENGTH)
|
||||
This->format = 1;
|
||||
}
|
||||
TRACE("Adding prop name %s, propid %ld\n",
|
||||
This->codePage == CP_UNICODE ? debugstr_w((LPCWSTR)name) :
|
||||
debugstr_a(name), id);
|
||||
dictionary_insert(This->name_to_propid, name, (void *)id);
|
||||
dictionary_insert(This->propid_to_name, (void *)id, name);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* IPropertyStorage_fnWriteMultiple (IPropertyStorage)
|
||||
*/
|
||||
|
@ -371,19 +584,12 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
|
|||
else
|
||||
{
|
||||
PROPID nextId = max(propidNameFirst, This->highestProp + 1);
|
||||
size_t len = strlenW(rgpspec[i].u.lpwstr) + 1;
|
||||
LPWSTR name = HeapAlloc(GetProcessHeap(), 0,
|
||||
len * sizeof(WCHAR));
|
||||
|
||||
strcpyW(name, rgpspec[i].u.lpwstr);
|
||||
TRACE("Adding prop name %s, propid %ld\n", debugstr_w(name),
|
||||
nextId);
|
||||
dictionary_insert(This->name_to_propid, name,
|
||||
(void *)nextId);
|
||||
dictionary_insert(This->propid_to_name, (void *)nextId,
|
||||
name);
|
||||
hr = PropertyStorage_StorePropWithId(This, nextId,
|
||||
&rgpropvar[i]);
|
||||
hr = PropertyStorage_StoreNameWithId(This,
|
||||
(LPCSTR)rgpspec[i].u.lpwstr, CP_UNICODE, nextId);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = PropertyStorage_StorePropWithId(This, nextId,
|
||||
&rgpropvar[i], GetACP());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -399,7 +605,13 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
|
|||
/* Can only set the code page if nothing else has been set */
|
||||
if (dictionary_num_entries(This->propid_to_prop) == 0 &&
|
||||
rgpropvar[i].vt == VT_I2)
|
||||
{
|
||||
This->codePage = rgpropvar[i].u.iVal;
|
||||
if (This->codePage == CP_UNICODE)
|
||||
This->grfFlags &= ~PROPSETFLAG_ANSI;
|
||||
else
|
||||
This->grfFlags |= PROPSETFLAG_ANSI;
|
||||
}
|
||||
else
|
||||
hr = STG_E_INVALIDPARAMETER;
|
||||
break;
|
||||
|
@ -419,7 +631,7 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
|
|||
hr = STG_E_INVALIDPARAMETER;
|
||||
else
|
||||
hr = PropertyStorage_StorePropWithId(This,
|
||||
rgpspec[i].u.propid, &rgpropvar[i]);
|
||||
rgpspec[i].u.propid, &rgpropvar[i], GetACP());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -541,17 +753,11 @@ static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
|
|||
hr = S_OK;
|
||||
EnterCriticalSection(&This->cs);
|
||||
This->dirty = TRUE;
|
||||
for (i = 0; i < cpropid; i++)
|
||||
for (i = 0; SUCCEEDED(hr) && i < cpropid; i++)
|
||||
{
|
||||
if (rgpropid[i] != PID_ILLEGAL)
|
||||
{
|
||||
size_t len = lstrlenW(rglpwstrName[i]) + 1;
|
||||
LPWSTR name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||
|
||||
strcpyW(name, rglpwstrName[i]);
|
||||
dictionary_insert(This->name_to_propid, name, (void *)rgpropid[i]);
|
||||
dictionary_insert(This->propid_to_name, (void *)rgpropid[i], name);
|
||||
}
|
||||
hr = PropertyStorage_StoreNameWithId(This, (LPCSTR)rglpwstrName[i],
|
||||
CP_UNICODE, rgpropid[i]);
|
||||
}
|
||||
if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
|
||||
IPropertyStorage_Commit(iface, STGC_DEFAULT);
|
||||
|
@ -728,20 +934,27 @@ static int PropertyStorage_PropNameCompare(const void *a, const void *b,
|
|||
{
|
||||
PropertyStorage_impl *This = (PropertyStorage_impl *)extra;
|
||||
|
||||
TRACE("(%s, %s)\n", debugstr_w(a), debugstr_w(b));
|
||||
/* FIXME: this assumes property names are always Unicode, but they
|
||||
* might be ANSI, depending on whether This->grfFlags & PROPSETFLAG_ANSI
|
||||
* is true.
|
||||
*/
|
||||
if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
|
||||
return strcmpW((LPCWSTR)a, (LPCWSTR)b);
|
||||
if (This->codePage == CP_UNICODE)
|
||||
{
|
||||
TRACE("(%s, %s)\n", debugstr_w(a), debugstr_w(b));
|
||||
if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
|
||||
return lstrcmpW((LPCWSTR)a, (LPCWSTR)b);
|
||||
else
|
||||
return lstrcmpiW((LPCWSTR)a, (LPCWSTR)b);
|
||||
}
|
||||
else
|
||||
return strcmpiW((LPCWSTR)a, (LPCWSTR)b);
|
||||
{
|
||||
TRACE("(%s, %s)\n", debugstr_a(a), debugstr_a(b));
|
||||
if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
|
||||
return lstrcmpA((LPCSTR)a, (LPCSTR)b);
|
||||
else
|
||||
return lstrcmpiA((LPCSTR)a, (LPCSTR)b);
|
||||
}
|
||||
}
|
||||
|
||||
static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, k);
|
||||
CoTaskMemFree(k);
|
||||
}
|
||||
|
||||
static int PropertyStorage_PropCompare(const void *a, const void *b,
|
||||
|
@ -757,12 +970,28 @@ static void PropertyStorage_PropertyDestroy(void *k, void *d, void *extra)
|
|||
HeapFree(GetProcessHeap(), 0, d);
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
/* Swaps each character in str to or from little endian; assumes the conversion
|
||||
* is symmetric, that is, that le16toh is equivalent to htole16.
|
||||
*/
|
||||
static void PropertyStorage_ByteSwapString(LPWSTR str, size_t len)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
/* Swap characters to host order.
|
||||
* FIXME: alignment?
|
||||
*/
|
||||
for (i = 0; i < len; i++)
|
||||
str[i] = le16toh(str[i]);
|
||||
}
|
||||
#else
|
||||
#define PropertyStorage_ByteSwapString(s, l)
|
||||
#endif
|
||||
|
||||
/* Reads the dictionary from the memory buffer beginning at ptr. Interprets
|
||||
* the entries according to the values of This->codePage and This->locale.
|
||||
* FIXME: there isn't any checking whether the read property extends past the
|
||||
* end of the buffer.
|
||||
* FIXME: this always stores dictionary entries as Unicode, but it should store
|
||||
* them as ANSI if (This->grfFlags & PROPSETFLAG_ANSI) is true.
|
||||
*/
|
||||
static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
|
||||
BYTE *ptr)
|
||||
|
@ -781,49 +1010,24 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
|
|||
{
|
||||
PROPID propid;
|
||||
DWORD cbEntry;
|
||||
LPWSTR name = NULL;
|
||||
|
||||
StorageUtl_ReadDWord(ptr, 0, &propid);
|
||||
ptr += sizeof(PROPID);
|
||||
StorageUtl_ReadDWord(ptr, 0, &cbEntry);
|
||||
ptr += sizeof(DWORD);
|
||||
/* FIXME: if host is big-endian, this'll suck to convert */
|
||||
TRACE("Reading entry with ID 0x%08lx, %ld bytes\n", propid, cbEntry);
|
||||
/* Make sure the source string is NULL-terminated */
|
||||
if (This->codePage != CP_UNICODE)
|
||||
{
|
||||
int len = MultiByteToWideChar(This->codePage, 0, ptr, cbEntry,
|
||||
NULL, 0);
|
||||
|
||||
if (!len)
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
else
|
||||
{
|
||||
name = HeapAlloc(GetProcessHeap(), 0,
|
||||
len * sizeof(WCHAR));
|
||||
if (name)
|
||||
MultiByteToWideChar(This->codePage, 0, ptr, cbEntry, name,
|
||||
len);
|
||||
else
|
||||
hr = STG_E_INSUFFICIENTMEMORY;
|
||||
}
|
||||
}
|
||||
ptr[cbEntry - 1] = '\0';
|
||||
else
|
||||
*((LPWSTR)ptr + cbEntry / sizeof(WCHAR)) = '\0';
|
||||
hr = PropertyStorage_StoreNameWithId(This, ptr, This->codePage, propid);
|
||||
if (This->codePage == CP_UNICODE)
|
||||
{
|
||||
name = HeapAlloc(GetProcessHeap(), 0, cbEntry);
|
||||
if (name)
|
||||
lstrcpyW(name, (LPWSTR)ptr);
|
||||
else
|
||||
hr = STG_E_INSUFFICIENTMEMORY;
|
||||
/* Unicode entries are padded to DWORD boundaries */
|
||||
if (cbEntry % sizeof(DWORD))
|
||||
ptr += sizeof(DWORD) - (cbEntry % sizeof(DWORD));
|
||||
}
|
||||
if (name)
|
||||
{
|
||||
dictionary_insert(This->name_to_propid, name, (void *)propid);
|
||||
dictionary_insert(This->propid_to_name, (void *)propid, name);
|
||||
TRACE("Property %s maps to id %ld\n", debugstr_w(name), propid);
|
||||
}
|
||||
ptr += sizeof(DWORD) + cbEntry;
|
||||
}
|
||||
return hr;
|
||||
|
@ -832,7 +1036,8 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
|
|||
/* FIXME: there isn't any checking whether the read property extends past the
|
||||
* end of the buffer.
|
||||
*/
|
||||
static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
|
||||
static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
|
||||
PROPVARIANT *prop, const BYTE *data)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
|
@ -861,10 +1066,12 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
|
|||
StorageUtl_ReadWord(data, 0, &prop->u.uiVal);
|
||||
TRACE("Read ushort %d\n", prop->u.uiVal);
|
||||
break;
|
||||
case VT_INT:
|
||||
case VT_I4:
|
||||
StorageUtl_ReadDWord(data, 0, &prop->u.lVal);
|
||||
TRACE("Read long %ld\n", prop->u.lVal);
|
||||
break;
|
||||
case VT_UINT:
|
||||
case VT_UI4:
|
||||
StorageUtl_ReadDWord(data, 0, &prop->u.ulVal);
|
||||
TRACE("Read ulong %ld\n", prop->u.ulVal);
|
||||
|
@ -874,18 +1081,37 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
|
|||
DWORD count;
|
||||
|
||||
StorageUtl_ReadDWord(data, 0, &count);
|
||||
prop->u.pszVal = CoTaskMemAlloc(count);
|
||||
if (prop->u.pszVal)
|
||||
if (This->codePage == CP_UNICODE && count / 2)
|
||||
{
|
||||
/* FIXME: if the host is big-endian, this'll suck */
|
||||
memcpy(prop->u.pszVal, data + sizeof(DWORD), count);
|
||||
/* FIXME: so far so good, but this may be Unicode or DBCS depending
|
||||
* on This->codePage.
|
||||
*/
|
||||
TRACE("Read string value %s\n", debugstr_a(prop->u.pszVal));
|
||||
WARN("Unicode string has odd number of bytes\n");
|
||||
hr = STG_E_INVALIDHEADER;
|
||||
}
|
||||
else
|
||||
hr = STG_E_INSUFFICIENTMEMORY;
|
||||
{
|
||||
prop->u.pszVal = CoTaskMemAlloc(count);
|
||||
if (prop->u.pszVal)
|
||||
{
|
||||
memcpy(prop->u.pszVal, data + sizeof(DWORD), count);
|
||||
/* This is stored in the code page specified in This->codePage.
|
||||
* Don't convert it, the caller will just store it as-is.
|
||||
*/
|
||||
if (This->codePage == CP_UNICODE)
|
||||
{
|
||||
/* Make sure it's NULL-terminated */
|
||||
prop->u.pszVal[count / sizeof(WCHAR) - 1] = '\0';
|
||||
TRACE("Read string value %s\n",
|
||||
debugstr_w(prop->u.pwszVal));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make sure it's NULL-terminated */
|
||||
prop->u.pszVal[count - 1] = '\0';
|
||||
TRACE("Read string value %s\n", debugstr_a(prop->u.pszVal));
|
||||
}
|
||||
}
|
||||
else
|
||||
hr = STG_E_INSUFFICIENTMEMORY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VT_LPWSTR:
|
||||
|
@ -896,9 +1122,11 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
|
|||
prop->u.pwszVal = CoTaskMemAlloc(count * sizeof(WCHAR));
|
||||
if (prop->u.pwszVal)
|
||||
{
|
||||
/* FIXME: if the host is big-endian, gotta swap every char */
|
||||
memcpy(prop->u.pwszVal, data + sizeof(DWORD),
|
||||
count * sizeof(WCHAR));
|
||||
/* make sure string is NULL-terminated */
|
||||
prop->u.pwszVal[count - 1] = '\0';
|
||||
PropertyStorage_ByteSwapString(prop->u.pwszVal, count);
|
||||
TRACE("Read string value %s\n", debugstr_w(prop->u.pwszVal));
|
||||
}
|
||||
else
|
||||
|
@ -906,8 +1134,8 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
|
|||
break;
|
||||
}
|
||||
case VT_FILETIME:
|
||||
/* FIXME: endianness */
|
||||
memcpy(&prop->u.filetime, data, sizeof(FILETIME));
|
||||
StorageUtl_ReadULargeInteger(data, 0,
|
||||
(ULARGE_INTEGER *)&prop->u.filetime);
|
||||
break;
|
||||
default:
|
||||
FIXME("unsupported type %d\n", prop->vt);
|
||||
|
@ -1068,6 +1296,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
|
|||
hr = STG_E_INVALIDHEADER;
|
||||
goto end;
|
||||
}
|
||||
This->format = hdr.wFormat;
|
||||
memcpy(&This->clsid, &hdr.clsid, sizeof(This->clsid));
|
||||
This->originatorOS = hdr.dwOSVer;
|
||||
if (PROPSETHDR_OSVER_KIND(hdr.dwOSVer) == PROPSETHDR_OSVER_KIND_MAC)
|
||||
|
@ -1139,7 +1368,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
|
|||
{
|
||||
PROPVARIANT prop;
|
||||
|
||||
if (SUCCEEDED(PropertyStorage_ReadProperty(&prop,
|
||||
if (SUCCEEDED(PropertyStorage_ReadProperty(This, &prop,
|
||||
buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER))))
|
||||
{
|
||||
TRACE("Read property with ID 0x%08lx, type %d\n",
|
||||
|
@ -1157,10 +1386,12 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
|
|||
case PID_BEHAVIOR:
|
||||
if (prop.vt == VT_I4 && prop.u.lVal)
|
||||
This->grfFlags |= PROPSETFLAG_CASE_SENSITIVE;
|
||||
/* The format should already be 1, but just in case */
|
||||
This->format = 1;
|
||||
break;
|
||||
default:
|
||||
hr = PropertyStorage_StorePropWithId(This,
|
||||
idOffset->propid, &prop);
|
||||
idOffset->propid, &prop, This->codePage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1204,11 +1435,7 @@ static void PropertyStorage_MakeHeader(PropertyStorage_impl *This,
|
|||
assert(hdr);
|
||||
StorageUtl_WriteWord((BYTE *)&hdr->wByteOrder, 0,
|
||||
PROPSETHDR_BYTEORDER_MAGIC);
|
||||
/* FIXME: should be able to write format 0 property sets too, depending
|
||||
* on whether I have too long string names or if case-sensitivity is set.
|
||||
* For now always write format 1.
|
||||
*/
|
||||
StorageUtl_WriteWord((BYTE *)&hdr->wFormat, 0, 1);
|
||||
StorageUtl_WriteWord((BYTE *)&hdr->wFormat, 0, This->format);
|
||||
StorageUtl_WriteDWord((BYTE *)&hdr->dwOSVer, 0, This->originatorOS);
|
||||
StorageUtl_WriteGUID((BYTE *)&hdr->clsid, 0, &This->clsid);
|
||||
StorageUtl_WriteDWord((BYTE *)&hdr->reserved, 0, 1);
|
||||
|
@ -1274,8 +1501,12 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
|
|||
if (FAILED(c->hr))
|
||||
goto end;
|
||||
c->bytesWritten += sizeof(DWORD);
|
||||
/* FIXME: endian-convert every char (yuck) */
|
||||
/* Rather than allocate a copy, I'll swap the string to little-endian
|
||||
* in-place, write it, then swap it back.
|
||||
*/
|
||||
PropertyStorage_ByteSwapString(key, keyLen);
|
||||
c->hr = IStream_Write(This->stm, key, keyLen, &count);
|
||||
PropertyStorage_ByteSwapString(key, keyLen);
|
||||
if (FAILED(c->hr))
|
||||
goto end;
|
||||
c->bytesWritten += keyLen;
|
||||
|
@ -1290,35 +1521,17 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
|
|||
}
|
||||
else
|
||||
{
|
||||
int len = WideCharToMultiByte(This->codePage, 0, (LPWSTR)key, -1, NULL,
|
||||
0, NULL, NULL);
|
||||
LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
DWORD dwLen;
|
||||
DWORD keyLen;
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
c->hr = STG_E_INSUFFICIENTMEMORY;
|
||||
goto end;
|
||||
}
|
||||
/* FIXME: endian-convert multibyte chars? Ick! */
|
||||
WideCharToMultiByte(This->codePage, 0, (LPWSTR)key, -1, buf, len,
|
||||
NULL, NULL);
|
||||
StorageUtl_WriteDWord((LPBYTE)&dwLen, 0, len);
|
||||
c->hr = IStream_Write(This->stm, &dwLen, sizeof(dwLen), &count);
|
||||
StorageUtl_WriteDWord((LPBYTE)&keyLen, 0, strlen((LPCSTR)key) + 1);
|
||||
c->hr = IStream_Write(This->stm, &keyLen, sizeof(keyLen), &count);
|
||||
if (FAILED(c->hr))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
goto end;
|
||||
}
|
||||
c->bytesWritten += sizeof(DWORD);
|
||||
c->hr = IStream_Write(This->stm, buf, len, &count);
|
||||
c->hr = IStream_Write(This->stm, key, keyLen, &count);
|
||||
if (FAILED(c->hr))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
goto end;
|
||||
}
|
||||
c->bytesWritten += len;
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
c->bytesWritten += keyLen;
|
||||
}
|
||||
end:
|
||||
return SUCCEEDED(c->hr);
|
||||
|
@ -1482,6 +1695,16 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
|
|||
bytesWritten = count + sizeof(DWORD);
|
||||
break;
|
||||
}
|
||||
case VT_FILETIME:
|
||||
{
|
||||
FILETIME temp;
|
||||
|
||||
StorageUtl_WriteULargeInteger((BYTE *)&temp, 0,
|
||||
(ULARGE_INTEGER *)&var->u.filetime);
|
||||
hr = IStream_Write(This->stm, &temp, sizeof(FILETIME), &count);
|
||||
bytesWritten = count;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("unsupported type: %d\n", var->vt);
|
||||
return STG_E_INVALIDPARAMETER;
|
||||
|
@ -1723,7 +1946,7 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
|
|||
assert(pps);
|
||||
assert(rfmtid);
|
||||
*pps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof **pps);
|
||||
if (!pps)
|
||||
if (!*pps)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
(*pps)->vtbl = &IPropertyStorage_Vtbl;
|
||||
|
@ -1734,6 +1957,13 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
|
|||
(*pps)->grfMode = grfMode;
|
||||
|
||||
hr = PropertyStorage_CreateDictionaries(*pps);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IStream_Release(stm);
|
||||
DeleteCriticalSection(&(*pps)->cs);
|
||||
HeapFree(GetProcessHeap(), 0, *pps);
|
||||
*pps = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
@ -1774,7 +2004,10 @@ static HRESULT PropertyStorage_ConstructEmpty(IStream *stm,
|
|||
hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ps->format = 0;
|
||||
ps->grfFlags = grfFlags;
|
||||
if (ps->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
|
||||
ps->format = 1;
|
||||
/* default to Unicode unless told not to, as specified here:
|
||||
* http://msdn.microsoft.com/library/en-us/stg/stg/names_in_istorage.asp
|
||||
*/
|
||||
|
@ -2106,12 +2339,12 @@ HRESULT WINAPI FmtIdToPropStgName(const FMTID *rfmtid, LPOLESTR str)
|
|||
*/
|
||||
HRESULT WINAPI PropStgNameToFmtId(const LPOLESTR str, FMTID *rfmtid)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
HRESULT hr = STG_E_INVALIDNAME;
|
||||
|
||||
TRACE("%s, %p\n", debugstr_w(str), rfmtid);
|
||||
|
||||
if (!rfmtid) return E_INVALIDARG;
|
||||
if (!str) return E_INVALIDARG;
|
||||
if (!str) return STG_E_INVALIDNAME;
|
||||
|
||||
if (!lstrcmpiW(str, szDocSummaryInfo))
|
||||
{
|
||||
|
|
|
@ -296,6 +296,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
|
|||
StgProperty currentProperty;
|
||||
ULONG foundPropertyIndex;
|
||||
HRESULT res = STG_E_UNKNOWN;
|
||||
DWORD parent_grfMode;
|
||||
|
||||
TRACE("(%p, %s, %p, %lx, %ld, %p)\n",
|
||||
iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm);
|
||||
|
@ -334,6 +335,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
|
|||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we're compatible with the parent's storage mode
|
||||
*/
|
||||
parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
|
||||
if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
|
||||
{
|
||||
res = STG_E_ACCESSDENIED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a property enumeration to search the properties
|
||||
*/
|
||||
|
@ -412,6 +423,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
|
|||
StgProperty currentProperty;
|
||||
ULONG foundPropertyIndex;
|
||||
HRESULT res = STG_E_UNKNOWN;
|
||||
DWORD parent_grfMode;
|
||||
|
||||
TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n",
|
||||
iface, debugstr_w(pwcsName), pstgPriority,
|
||||
|
@ -453,6 +465,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
|
|||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we're compatible with the parent's storage mode
|
||||
*/
|
||||
parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
|
||||
if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
|
||||
{
|
||||
res = STG_E_ACCESSDENIED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the out parameter
|
||||
*/
|
||||
|
@ -489,6 +511,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
|
|||
*/
|
||||
newStorage = StorageInternalImpl_Construct(
|
||||
This->ancestorStorage,
|
||||
grfMode,
|
||||
foundPropertyIndex);
|
||||
|
||||
if (newStorage != 0)
|
||||
|
@ -804,6 +827,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
|
|||
StgStreamImpl* newStream;
|
||||
StgProperty currentProperty, newStreamProperty;
|
||||
ULONG foundPropertyIndex, newPropertyIndex;
|
||||
DWORD parent_grfMode;
|
||||
|
||||
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
|
||||
iface, debugstr_w(pwcsName), grfMode,
|
||||
|
@ -837,6 +861,13 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
|
|||
(grfMode & STGM_TRANSACTED))
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
|
||||
/*
|
||||
* Check that we're compatible with the parent's storage mode
|
||||
*/
|
||||
parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
|
||||
if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
|
||||
return STG_E_ACCESSDENIED;
|
||||
|
||||
/*
|
||||
* Initialize the out parameter
|
||||
*/
|
||||
|
@ -1005,6 +1036,7 @@ HRESULT WINAPI StorageImpl_CreateStorage(
|
|||
ULONG foundPropertyIndex;
|
||||
ULONG newPropertyIndex;
|
||||
HRESULT hr;
|
||||
DWORD parent_grfMode;
|
||||
|
||||
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
|
||||
iface, debugstr_w(pwcsName), grfMode,
|
||||
|
@ -1026,6 +1058,13 @@ HRESULT WINAPI StorageImpl_CreateStorage(
|
|||
(grfMode & STGM_DELETEONRELEASE) )
|
||||
return STG_E_INVALIDFLAG;
|
||||
|
||||
/*
|
||||
* Check that we're compatible with the parent's storage mode
|
||||
*/
|
||||
parent_grfMode = STGM_ACCESS_MODE( This->base.ancestorStorage->base.openFlags );
|
||||
if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
|
||||
return STG_E_ACCESSDENIED;
|
||||
|
||||
/*
|
||||
* Initialize the out parameter
|
||||
*/
|
||||
|
@ -2186,6 +2225,7 @@ HRESULT StorageImpl_Construct(
|
|||
This->base.lpVtbl = &Storage32Impl_Vtbl;
|
||||
This->base.pssVtbl = &IPropertySetStorage_Vtbl;
|
||||
This->base.v_destructor = &StorageImpl_Destroy;
|
||||
This->base.openFlags = openFlags;
|
||||
|
||||
/*
|
||||
* This is the top-level storage so initialize the ancestor pointer
|
||||
|
@ -2379,7 +2419,7 @@ void StorageImpl_Destroy(StorageBaseImpl* iface)
|
|||
BlockChainStream_Destroy(This->smallBlockDepotChain);
|
||||
|
||||
BIGBLOCKFILE_Destructor(This->bigBlockFile);
|
||||
return;
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -4013,7 +4053,8 @@ static IStorageVtbl Storage32InternalImpl_Vtbl =
|
|||
|
||||
StorageInternalImpl* StorageInternalImpl_Construct(
|
||||
StorageImpl* ancestorStorage,
|
||||
ULONG rootPropertyIndex)
|
||||
DWORD openFlags,
|
||||
ULONG rootPropertyIndex)
|
||||
{
|
||||
StorageInternalImpl* newStorage;
|
||||
|
||||
|
@ -4031,6 +4072,7 @@ StorageInternalImpl* StorageInternalImpl_Construct(
|
|||
*/
|
||||
newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl;
|
||||
newStorage->base.v_destructor = &StorageInternalImpl_Destroy;
|
||||
newStorage->base.openFlags = openFlags;
|
||||
|
||||
/*
|
||||
* Keep the ancestor storage pointer and nail a reference to it.
|
||||
|
@ -4051,30 +4093,64 @@ StorageInternalImpl* StorageInternalImpl_Construct(
|
|||
|
||||
/******************************************************************************
|
||||
** StorageUtl implementation
|
||||
* FIXME: these should read and write in little-endian order on all
|
||||
* architectures, but right now just assume the host is little-endian.
|
||||
*/
|
||||
|
||||
void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value)
|
||||
{
|
||||
memcpy(value, buffer+offset, sizeof(WORD));
|
||||
WORD tmp;
|
||||
|
||||
memcpy(&tmp, buffer+offset, sizeof(WORD));
|
||||
*value = le16toh(tmp);
|
||||
}
|
||||
|
||||
void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value)
|
||||
{
|
||||
value = htole16(value);
|
||||
memcpy(buffer+offset, &value, sizeof(WORD));
|
||||
}
|
||||
|
||||
void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value)
|
||||
{
|
||||
memcpy(value, buffer+offset, sizeof(DWORD));
|
||||
DWORD tmp;
|
||||
|
||||
memcpy(&tmp, buffer+offset, sizeof(DWORD));
|
||||
*value = le32toh(tmp);
|
||||
}
|
||||
|
||||
void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value)
|
||||
{
|
||||
value = htole32(value);
|
||||
memcpy(buffer+offset, &value, sizeof(DWORD));
|
||||
}
|
||||
|
||||
void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset,
|
||||
ULARGE_INTEGER* value)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ULARGE_INTEGER tmp;
|
||||
|
||||
memcpy(&tmp, buffer + offset, sizeof(ULARGE_INTEGER));
|
||||
value->u.LowPart = htole32(tmp.u.HighPart);
|
||||
value->u.HighPart = htole32(tmp.u.LowPart);
|
||||
#else
|
||||
memcpy(value, buffer + offset, sizeof(ULARGE_INTEGER));
|
||||
#endif
|
||||
}
|
||||
|
||||
void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
|
||||
const ULARGE_INTEGER *value)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
ULARGE_INTEGER tmp;
|
||||
|
||||
tmp.u.LowPart = htole32(value->u.HighPart);
|
||||
tmp.u.HighPart = htole32(value->u.LowPart);
|
||||
memcpy(buffer + offset, &tmp, sizeof(ULARGE_INTEGER));
|
||||
#else
|
||||
memcpy(buffer + offset, value, sizeof(ULARGE_INTEGER));
|
||||
#endif
|
||||
}
|
||||
|
||||
void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value)
|
||||
{
|
||||
StorageUtl_ReadDWord(buffer, offset, &(value->Data1));
|
||||
|
@ -5579,7 +5655,33 @@ HRESULT WINAPI StgCreateStorageEx(const WCHAR* pwcsName, DWORD grfMode, DWORD st
|
|||
{
|
||||
TRACE("(%s, %lx, %lx, %lx, %p, %p, %p, %p)\n", debugstr_w(pwcsName),
|
||||
grfMode, stgfmt, grfAttrs, pStgOptions, reserved, riid, ppObjectOpen);
|
||||
return STG_E_UNIMPLEMENTEDFUNCTION;
|
||||
|
||||
if (stgfmt != STGFMT_FILE && grfAttrs != 0)
|
||||
{
|
||||
ERR("grfAttrs must be 0 if stgfmt != STGFMT_FILE\n");
|
||||
return STG_E_INVALIDPARAMETER;
|
||||
}
|
||||
|
||||
if (stgfmt != STGFMT_FILE && grfAttrs != 0 && grfAttrs != FILE_FLAG_NO_BUFFERING)
|
||||
{
|
||||
ERR("grfAttrs must be 0 or FILE_FLAG_NO_BUFFERING if stgfmt == STGFMT_FILE\n");
|
||||
return STG_E_INVALIDPARAMETER;
|
||||
}
|
||||
|
||||
if (stgfmt == STGFMT_FILE)
|
||||
{
|
||||
ERR("Cannot use STGFMT_FILE - this is NTFS only\n");
|
||||
return STG_E_INVALIDPARAMETER;
|
||||
}
|
||||
|
||||
if (stgfmt == STGFMT_STORAGE || stgfmt == STGFMT_DOCFILE)
|
||||
{
|
||||
FIXME("Stub: calling StgCreateDocfile, but ignoring pStgOptions and grfAttrs\n");
|
||||
return StgCreateDocfile(pwcsName, grfMode, 0, (IStorage **)ppObjectOpen);
|
||||
}
|
||||
|
||||
ERR("Invalid stgfmt argument\n");
|
||||
return STG_E_INVALIDPARAMETER;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -5599,6 +5701,45 @@ HRESULT WINAPI StgCreatePropSetStg(IStorage *pstg, DWORD reserved,
|
|||
return hr;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* StgOpenStorageEx [OLE32.@]
|
||||
*/
|
||||
HRESULT WINAPI StgOpenStorageEx(const WCHAR* pwcsName, DWORD grfMode, DWORD stgfmt, DWORD grfAttrs, STGOPTIONS* pStgOptions, void* reserved, REFIID riid, void** ppObjectOpen)
|
||||
{
|
||||
TRACE("(%s, %lx, %lx, %lx, %p, %p, %p, %p)\n", debugstr_w(pwcsName),
|
||||
grfMode, stgfmt, grfAttrs, pStgOptions, reserved, riid, ppObjectOpen);
|
||||
|
||||
if (stgfmt != STGFMT_DOCFILE && grfAttrs != 0)
|
||||
{
|
||||
ERR("grfAttrs must be 0 if stgfmt != STGFMT_DOCFILE\n");
|
||||
return STG_E_INVALIDPARAMETER;
|
||||
}
|
||||
|
||||
if (stgfmt != STGFMT_DOCFILE && grfAttrs != 0 && grfAttrs != FILE_FLAG_NO_BUFFERING)
|
||||
{
|
||||
ERR("grfAttrs must be 0 or FILE_FLAG_NO_BUFFERING if stgfmt == STGFMT_DOCFILE\n");
|
||||
return STG_E_INVALIDPARAMETER;
|
||||
}
|
||||
|
||||
if (stgfmt == STGFMT_FILE)
|
||||
{
|
||||
ERR("Cannot use STGFMT_FILE - this is NTFS only\n");
|
||||
return STG_E_INVALIDPARAMETER;
|
||||
}
|
||||
|
||||
if (stgfmt == STGFMT_STORAGE || stgfmt == STGFMT_DOCFILE || stgfmt == STGFMT_ANY)
|
||||
{
|
||||
if (stgfmt == STGFMT_ANY)
|
||||
WARN("STGFMT_ANY assuming storage\n");
|
||||
FIXME("Stub: calling StgOpenStorage, but ignoring pStgOptions and grfAttrs\n");
|
||||
return StgOpenStorage(pwcsName, NULL, grfMode, (SNB)NULL, 0, (IStorage **)ppObjectOpen);
|
||||
}
|
||||
|
||||
ERR("Invalid stgfmt argument\n");
|
||||
return STG_E_INVALIDPARAMETER;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* StgOpenStorage [OLE32.@]
|
||||
*/
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "winbase.h"
|
||||
#include "winnt.h"
|
||||
#include "objbase.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
|
||||
/*
|
||||
* Definitions for the file format offsets.
|
||||
|
@ -237,6 +239,11 @@ struct StorageBaseImpl
|
|||
* virtual Destructor method.
|
||||
*/
|
||||
void (*v_destructor)(StorageBaseImpl*);
|
||||
|
||||
/*
|
||||
* flags that this storage was opened or created with
|
||||
*/
|
||||
DWORD openFlags;
|
||||
};
|
||||
|
||||
|
||||
|
@ -397,6 +404,7 @@ struct StorageInternalImpl
|
|||
*/
|
||||
StorageInternalImpl* StorageInternalImpl_Construct(
|
||||
StorageImpl* ancestorStorage,
|
||||
DWORD openFlags,
|
||||
ULONG rootTropertyIndex);
|
||||
|
||||
void StorageInternalImpl_Destroy(
|
||||
|
@ -524,15 +532,38 @@ StgStreamImpl* StgStreamImpl_Construct(
|
|||
ULONG ownerProperty);
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* The StorageUtl_ functions are miscelaneous utility functions. Most of which are
|
||||
* abstractions used to read values from file buffers without having to worry
|
||||
* about bit order
|
||||
/******************************************************************************
|
||||
* Endian conversion macros
|
||||
*/
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
||||
#define htole32(x) RtlUlongByteSwap(x)
|
||||
#define htole16(x) RtlUshortByteSwap(x)
|
||||
#define le32toh(x) RtlUlongByteSwap(x)
|
||||
#define le16toh(x) RtlUshortByteSwap(x)
|
||||
|
||||
#else
|
||||
|
||||
#define htole32(x) (x)
|
||||
#define htole16(x) (x)
|
||||
#define le32toh(x) (x)
|
||||
#define le16toh(x) (x)
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* The StorageUtl_ functions are miscellaneous utility functions. Most of which
|
||||
* are abstractions used to read values from file buffers without having to
|
||||
* worry about bit order
|
||||
*/
|
||||
void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value);
|
||||
void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value);
|
||||
void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value);
|
||||
void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value);
|
||||
void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset,
|
||||
ULARGE_INTEGER* value);
|
||||
void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
|
||||
const ULARGE_INTEGER *value);
|
||||
void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value);
|
||||
void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
|
||||
void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination,
|
||||
|
|
|
@ -50,6 +50,10 @@
|
|||
#define STG_LAYOUT_INTERLEAVED 1
|
||||
#define COM_RIGHTS_EXECUTE 1
|
||||
#define COM_RIGHTS_SAFE_FOR_SCRIPTING 2
|
||||
#define STGFMT_STORAGE 0
|
||||
#define STGFMT_FILE 3
|
||||
#define STGFMT_ANY 4
|
||||
#define STGFMT_DOCFILE 5
|
||||
typedef enum tagREGCLS {
|
||||
REGCLS_SINGLEUSE = 0,
|
||||
REGCLS_MULTIPLEUSE = 1,
|
||||
|
|
Loading…
Reference in a new issue