mirror of
https://github.com/reactos/reactos.git
synced 2024-07-21 19:58: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@
|
SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = ole32.dll
|
MODULE = ole32.dll
|
||||||
|
IMPORTLIB = libole32.$(IMPLIBEXT)
|
||||||
IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll
|
IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll
|
||||||
EXTRALIBS = -luuid $(LIBUNICODE)
|
EXTRALIBS = -luuid $(LIBUNICODE)
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,6 @@
|
||||||
#include "wownt32.h"
|
#include "wownt32.h"
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
#include "ole32_main.h"
|
|
||||||
#include "compobj_private.h"
|
#include "compobj_private.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
@ -75,6 +74,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
|
|
||||||
typedef LPCSTR LPCOLESTR16;
|
typedef LPCSTR LPCOLESTR16;
|
||||||
|
|
||||||
|
HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* This section defines variables internal to the COM module.
|
* 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_Add(HANDLE hLibrary);
|
||||||
static void COMPOBJ_DllList_FreeUnused(int Timeout);
|
static void COMPOBJ_DllList_FreeUnused(int Timeout);
|
||||||
|
|
||||||
void COMPOBJ_InitProcess( void )
|
static void COMPOBJ_InitProcess( void )
|
||||||
{
|
{
|
||||||
WNDCLASSW wclass;
|
WNDCLASSW wclass;
|
||||||
|
|
||||||
|
@ -189,12 +190,12 @@ void COMPOBJ_InitProcess( void )
|
||||||
RegisterClassW(&wclass);
|
RegisterClassW(&wclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
void COMPOBJ_UninitProcess( void )
|
static void COMPOBJ_UninitProcess( void )
|
||||||
{
|
{
|
||||||
UnregisterClassW(wszAptWinClass, OLE32_hInstance);
|
UnregisterClassW(wszAptWinClass, OLE32_hInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void COM_TlsDestroy()
|
static void COM_TlsDestroy()
|
||||||
{
|
{
|
||||||
struct oletls *info = NtCurrentTeb()->ReservedForOle;
|
struct oletls *info = NtCurrentTeb()->ReservedForOle;
|
||||||
if (info)
|
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
|
/* 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.
|
pending RPCs are ignored. Non-COM messages are discarded at this point.
|
||||||
*/
|
*/
|
||||||
void COM_FlushMessageQueue(void)
|
static void COM_FlushMessageQueue(void)
|
||||||
{
|
{
|
||||||
MSG message;
|
MSG message;
|
||||||
APARTMENT *apt = COM_CurrentApt();
|
APARTMENT *apt = COM_CurrentApt();
|
||||||
|
@ -1531,7 +1532,8 @@ end:
|
||||||
*
|
*
|
||||||
* Reads a registry value and expands it when necessary
|
* 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;
|
HRESULT hres;
|
||||||
HKEY key;
|
HKEY key;
|
||||||
|
@ -2425,6 +2427,25 @@ ULONG WINAPI CoReleaseServerProcess(void)
|
||||||
return 1;
|
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.@]
|
* CoQueryProxyBlanket [OLE32.@]
|
||||||
*
|
*
|
||||||
|
@ -2635,3 +2656,32 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
|
||||||
TRACE("-- 0x%08lx\n", hr);
|
TRACE("-- 0x%08lx\n", hr);
|
||||||
return 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);
|
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 */
|
/* 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 */
|
/* Apartment Functions */
|
||||||
|
@ -254,4 +254,6 @@ static inline APARTMENT* COM_CurrentApt(void)
|
||||||
# define DEBUG_CLEAR_CRITSEC_NAME(cs)
|
# define DEBUG_CLEAR_CRITSEC_NAME(cs)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern HINSTANCE OLE32_hInstance; /* FIXME: make static */
|
||||||
|
|
||||||
#endif /* __WINE_OLE_COMPOBJ_H */
|
#endif /* __WINE_OLE_COMPOBJ_H */
|
||||||
|
|
|
@ -616,9 +616,36 @@ CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
***************************************************************************************/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -57,114 +57,29 @@ typedef struct FileMonikerImpl{
|
||||||
|
|
||||||
LPOLESTR filePathName; /* path string identified by this filemoniker */
|
LPOLESTR filePathName; /* path string identified by this filemoniker */
|
||||||
|
|
||||||
|
IUnknown *pMarshal; /* custom marshaler */
|
||||||
} FileMonikerImpl;
|
} 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 */
|
/* Local function used by filemoniker implementation */
|
||||||
HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
|
static HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
|
||||||
HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface);
|
static 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
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* FileMoniker_QueryInterface
|
* 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;
|
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.*/
|
/* Perform a sanity check on the parameters.*/
|
||||||
if ( (This==0) || (ppvObject==0) )
|
if ( (This==0) || (ppvObject==0) )
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
/* Initialize the return parameter */
|
/* Initialize the return parameter */
|
||||||
*ppvObject = 0;
|
*ppvObject = 0;
|
||||||
|
|
||||||
/* Compare the riid with the interface IDs implemented by this object.*/
|
/* Compare the riid with the interface IDs implemented by this object.*/
|
||||||
if (IsEqualIID(&IID_IUnknown, riid) ||
|
if (IsEqualIID(&IID_IUnknown, riid) ||
|
||||||
|
@ -176,21 +91,31 @@ HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
|
||||||
|
|
||||||
else if (IsEqualIID(&IID_IROTData, riid))
|
else if (IsEqualIID(&IID_IROTData, riid))
|
||||||
*ppvObject = (IROTData*)&(This->lpvtbl2);
|
*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.*/
|
/* Check that we obtained an interface.*/
|
||||||
if ((*ppvObject)==0)
|
if ((*ppvObject)==0)
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
|
|
||||||
/* Query Interface always increases the reference count by one when it is successful */
|
/* Query Interface always increases the reference count by one when it is successful */
|
||||||
FileMonikerImpl_AddRef(iface);
|
IMoniker_AddRef(iface);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_AddRef
|
* FileMoniker_AddRef
|
||||||
******************************************************************************/
|
*/
|
||||||
ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface)
|
static ULONG WINAPI
|
||||||
|
FileMonikerImpl_AddRef(IMoniker* iface)
|
||||||
{
|
{
|
||||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||||
|
|
||||||
|
@ -201,8 +126,9 @@ ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_Release
|
* FileMoniker_Release
|
||||||
******************************************************************************/
|
*/
|
||||||
ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface)
|
static ULONG WINAPI
|
||||||
|
FileMonikerImpl_Release(IMoniker* iface)
|
||||||
{
|
{
|
||||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||||
ULONG ref;
|
ULONG ref;
|
||||||
|
@ -219,9 +145,9 @@ ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_GetClassID
|
* FileMoniker_GetClassID
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
CLSID *pClassID)/* Pointer to CLSID of object */
|
FileMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID)
|
||||||
{
|
{
|
||||||
TRACE("(%p,%p)\n",iface,pClassID);
|
TRACE("(%p,%p)\n",iface,pClassID);
|
||||||
|
|
||||||
|
@ -235,12 +161,14 @@ HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface,
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_IsDirty
|
* 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);
|
TRACE("(%p)\n",iface);
|
||||||
|
|
||||||
|
@ -249,8 +177,12 @@ HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_Load
|
* 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;
|
HRESULT res;
|
||||||
CHAR* filePathA;
|
CHAR* filePathA;
|
||||||
|
@ -263,36 +195,49 @@ HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
||||||
|
|
||||||
TRACE("(%p,%p)\n",iface,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 */
|
/* first WORD is non significative */
|
||||||
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
|
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
|
||||||
if (bread!=sizeof(WORD) || wbuffer!=0)
|
if (bread!=sizeof(WORD) || wbuffer!=0)
|
||||||
|
{
|
||||||
|
ERR("Couldn't read 0 word\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
/* read filePath string length (plus one) */
|
/* read filePath string length (plus one) */
|
||||||
res=IStream_Read(pStm,&length,sizeof(DWORD),&bread);
|
res=IStream_Read(pStm,&length,sizeof(DWORD),&bread);
|
||||||
if (bread != sizeof(DWORD))
|
if (bread != sizeof(DWORD))
|
||||||
|
{
|
||||||
|
ERR("Couldn't read file string length\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
/* read filePath string */
|
/* read filePath string */
|
||||||
filePathA=HeapAlloc(GetProcessHeap(),0,length);
|
filePathA=HeapAlloc(GetProcessHeap(),0,length);
|
||||||
res=IStream_Read(pStm,filePathA,length,&bread);
|
res=IStream_Read(pStm,filePathA,length,&bread);
|
||||||
HeapFree(GetProcessHeap(),0,filePathA);
|
HeapFree(GetProcessHeap(),0,filePathA);
|
||||||
if (bread != length)
|
if (bread != length)
|
||||||
|
{
|
||||||
|
ERR("Couldn't read file path string\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
/* read the first constant */
|
/* read the first constant */
|
||||||
IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
|
IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
|
||||||
if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
|
if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
|
||||||
|
{
|
||||||
|
ERR("Couldn't read 0xDEADFFFF constant\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
length--;
|
length--;
|
||||||
|
|
||||||
for(i=0;i<10;i++){
|
for(i=0;i<10;i++){
|
||||||
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
|
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
|
||||||
if (bread!=sizeof(WORD) || wbuffer!=0)
|
if (bread!=sizeof(WORD) || wbuffer!=0)
|
||||||
|
{
|
||||||
|
ERR("Couldn't read 0 padding\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length>8)
|
if (length>8)
|
||||||
|
@ -334,30 +279,28 @@ HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_Save
|
* FileMoniker_Save
|
||||||
******************************************************************************/
|
*
|
||||||
HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface,
|
* This function saves data of this object. In the beginning I thougth
|
||||||
IStream* pStm,/* pointer to the stream where the object is to be saved */
|
* that I have just to write the filePath string on Stream. But, when I
|
||||||
BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
|
* 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;
|
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||||
|
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
|
@ -426,9 +369,9 @@ HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface,
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_GetSizeMax
|
* FileMoniker_GetSizeMax
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
|
FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
|
||||||
{
|
{
|
||||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||||
DWORD len=lstrlenW(This->filePathName);
|
DWORD len=lstrlenW(This->filePathName);
|
||||||
|
@ -436,7 +379,7 @@ HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
|
||||||
|
|
||||||
TRACE("(%p,%p)\n",iface,pcbSize);
|
TRACE("(%p,%p)\n",iface,pcbSize);
|
||||||
|
|
||||||
if (pcbSize!=NULL)
|
if (!pcbSize)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
/* for more details see FileMonikerImpl_Save coments */
|
/* for more details see FileMonikerImpl_Save coments */
|
||||||
|
@ -461,77 +404,6 @@ HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
|
||||||
return S_OK;
|
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)
|
* FileMoniker_Destroy (local function)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -539,6 +411,7 @@ HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This)
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n",This);
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
if (This->pMarshal) IUnknown_Release(This->pMarshal);
|
||||||
HeapFree(GetProcessHeap(),0,This->filePathName);
|
HeapFree(GetProcessHeap(),0,This->filePathName);
|
||||||
HeapFree(GetProcessHeap(),0,This);
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
|
||||||
|
@ -547,12 +420,10 @@ HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_BindToObject
|
* FileMoniker_BindToObject
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
IBindCtx* pbc,
|
FileMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
|
||||||
IMoniker* pmkToLeft,
|
REFIID riid, VOID** ppvResult)
|
||||||
REFIID riid,
|
|
||||||
VOID** ppvResult)
|
|
||||||
{
|
{
|
||||||
HRESULT res=E_FAIL;
|
HRESULT res=E_FAIL;
|
||||||
CLSID clsID;
|
CLSID clsID;
|
||||||
|
@ -662,12 +533,10 @@ HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_BindToStorage
|
* FileMoniker_BindToStorage
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
IBindCtx* pbc,
|
FileMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
|
||||||
IMoniker* pmkToLeft,
|
REFIID riid, VOID** ppvObject)
|
||||||
REFIID riid,
|
|
||||||
VOID** ppvObject)
|
|
||||||
{
|
{
|
||||||
LPOLESTR filePath=0;
|
LPOLESTR filePath=0;
|
||||||
IStorage *pstg=0;
|
IStorage *pstg=0;
|
||||||
|
@ -680,7 +549,7 @@ HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
|
||||||
if (IsEqualIID(&IID_IStorage, riid)){
|
if (IsEqualIID(&IID_IStorage, riid)){
|
||||||
|
|
||||||
/* get the file name */
|
/* get the file name */
|
||||||
FileMonikerImpl_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
|
IMoniker_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
|
||||||
|
|
||||||
/* verifie if the file contains a storage object */
|
/* verifie if the file contains a storage object */
|
||||||
res=StgIsStorageFile(filePath);
|
res=StgIsStorageFile(filePath);
|
||||||
|
@ -718,30 +587,28 @@ HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_Reduce
|
* FileMoniker_Reduce
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
IBindCtx* pbc,
|
FileMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
|
||||||
DWORD dwReduceHowFar,
|
IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
|
||||||
IMoniker** ppmkToLeft,
|
|
||||||
IMoniker** ppmkReduced)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
|
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
|
||||||
|
|
||||||
if (ppmkReduced==NULL)
|
if (ppmkReduced==NULL)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
FileMonikerImpl_AddRef(iface);
|
IMoniker_AddRef(iface);
|
||||||
|
|
||||||
*ppmkReduced=iface;
|
*ppmkReduced=iface;
|
||||||
|
|
||||||
return MK_S_REDUCED_TO_SELF;
|
return MK_S_REDUCED_TO_SELF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_ComposeWith
|
* FileMoniker_ComposeWith
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
IMoniker* pmkRight,
|
FileMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
|
||||||
BOOL fOnlyIfNotGeneric,
|
BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
|
||||||
IMoniker** ppmkComposite)
|
|
||||||
{
|
{
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
LPOLESTR str1=0,str2=0,*strDec1=0,*strDec2=0,newStr=0;
|
LPOLESTR str1=0,str2=0,*strDec1=0,*strDec2=0,newStr=0;
|
||||||
|
@ -768,7 +635,7 @@ HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
|
||||||
|
|
||||||
CreateBindCtx(0,&bind);
|
CreateBindCtx(0,&bind);
|
||||||
|
|
||||||
FileMonikerImpl_GetDisplayName(iface,bind,NULL,&str1);
|
IMoniker_GetDisplayName(iface,bind,NULL,&str1);
|
||||||
IMoniker_GetDisplayName(pmkRight,bind,NULL,&str2);
|
IMoniker_GetDisplayName(pmkRight,bind,NULL,&str2);
|
||||||
|
|
||||||
/* decompose pathnames of the two monikers : (to prepare the path merge operation ) */
|
/* decompose pathnames of the two monikers : (to prepare the path merge operation ) */
|
||||||
|
@ -838,8 +705,9 @@ HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_Enum
|
* 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);
|
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
|
||||||
|
|
||||||
|
@ -853,8 +721,9 @@ HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker*
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_IsEqual
|
* FileMoniker_IsEqual
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
static HRESULT WINAPI
|
||||||
|
FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
|
||||||
{
|
{
|
||||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||||
CLSID clsid;
|
CLSID clsid;
|
||||||
|
@ -886,8 +755,9 @@ HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_Hash
|
* FileMoniker_Hash
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
static HRESULT WINAPI
|
||||||
|
FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
||||||
{
|
{
|
||||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||||
|
|
||||||
|
@ -920,11 +790,10 @@ HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_IsRunning
|
* FileMoniker_IsRunning
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
IBindCtx* pbc,
|
FileMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
|
||||||
IMoniker* pmkToLeft,
|
IMoniker* pmkNewlyRunning)
|
||||||
IMoniker* pmkNewlyRunning)
|
|
||||||
{
|
{
|
||||||
IRunningObjectTable* rot;
|
IRunningObjectTable* rot;
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
|
@ -952,10 +821,9 @@ HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_GetTimeOfLastChange
|
* FileMoniker_GetTimeOfLastChange
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
IBindCtx* pbc,
|
FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
|
||||||
IMoniker* pmkToLeft,
|
IMoniker* pmkToLeft, FILETIME* pFileTime)
|
||||||
FILETIME* pFileTime)
|
|
||||||
{
|
{
|
||||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||||
IRunningObjectTable* rot;
|
IRunningObjectTable* rot;
|
||||||
|
@ -990,10 +858,10 @@ HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_Inverse
|
* 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);
|
TRACE("(%p,%p)\n",iface,ppmk);
|
||||||
|
|
||||||
return CreateAntiMoniker(ppmk);
|
return CreateAntiMoniker(ppmk);
|
||||||
|
@ -1001,8 +869,9 @@ HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_CommonPrefixWith
|
* 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;
|
LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath;
|
||||||
|
@ -1089,8 +958,8 @@ HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOth
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* DecomposePath (local function)
|
* DecomposePath (local function)
|
||||||
******************************************************************************/
|
*/
|
||||||
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
|
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
|
||||||
{
|
{
|
||||||
static const WCHAR bSlash[] = {'\\',0};
|
static const WCHAR bSlash[] = {'\\',0};
|
||||||
WCHAR word[MAX_PATH];
|
WCHAR word[MAX_PATH];
|
||||||
|
@ -1144,8 +1013,9 @@ int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_RelativePathTo
|
* 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;
|
IBindCtx *bind;
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
|
@ -1219,11 +1089,10 @@ HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther,
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_GetDisplayName
|
* FileMoniker_GetDisplayName
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
IBindCtx* pbc,
|
FileMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
|
||||||
IMoniker* pmkToLeft,
|
IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
|
||||||
LPOLESTR *ppszDisplayName)
|
|
||||||
{
|
{
|
||||||
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
FileMonikerImpl *This = (FileMonikerImpl *)iface;
|
||||||
|
|
||||||
|
@ -1250,13 +1119,10 @@ HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_ParseDisplayName
|
* FileMoniker_ParseDisplayName
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,
|
static HRESULT WINAPI
|
||||||
IBindCtx* pbc,
|
FileMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
|
||||||
IMoniker* pmkToLeft,
|
LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
|
||||||
LPOLESTR pszDisplayName,
|
|
||||||
ULONG* pchEaten,
|
|
||||||
IMoniker** ppmkOut)
|
|
||||||
{
|
{
|
||||||
FIXME("(%p,%p,%p,%p,%p,%p),stub!\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
|
FIXME("(%p,%p,%p,%p,%p,%p),stub!\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
@ -1264,8 +1130,9 @@ HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMoniker_IsSystemMoniker
|
* 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);
|
TRACE("(%p,%p)\n",iface,pwdMksys);
|
||||||
|
|
||||||
|
@ -1279,8 +1146,9 @@ HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* FileMonikerIROTData_QueryInterface
|
* 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);
|
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||||
|
@ -1293,19 +1161,21 @@ HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* FileMonikerIROTData_AddRef
|
* FileMonikerIROTData_AddRef
|
||||||
*/
|
*/
|
||||||
ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData *iface)
|
static ULONG WINAPI
|
||||||
|
FileMonikerROTDataImpl_AddRef(IROTData *iface)
|
||||||
{
|
{
|
||||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||||
|
|
||||||
TRACE("(%p)\n",This);
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
return FileMonikerImpl_AddRef(This);
|
return IMoniker_AddRef(This);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* FileMonikerIROTData_Release
|
* FileMonikerIROTData_Release
|
||||||
*/
|
*/
|
||||||
ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface)
|
static ULONG WINAPI
|
||||||
|
FileMonikerROTDataImpl_Release(IROTData* iface)
|
||||||
{
|
{
|
||||||
ICOM_THIS_From_IROTData(IMoniker, iface);
|
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||||
|
|
||||||
|
@ -1316,14 +1186,142 @@ ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FileMonikerIROTData_GetComparaisonData
|
* FileMonikerIROTData_GetComparaisonData
|
||||||
******************************************************************************/
|
*/
|
||||||
HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
|
static HRESULT WINAPI
|
||||||
BYTE* pbData,
|
FileMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
|
||||||
ULONG cbMax,
|
ULONG cbMax, ULONG* pcbData)
|
||||||
ULONG* pcbData)
|
|
||||||
{
|
{
|
||||||
FIXME("(),stub!\n");
|
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||||
return E_NOTIMPL;
|
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;
|
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);
|
#define _ICOM_THIS_From_IFTMarshal(class, name) class* This = (class*)(((char*)name)-_IFTMarshall_Offset);
|
||||||
|
|
||||||
/* inner IUnknown to handle aggregation */
|
/* 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;
|
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
||||||
|
@ -71,7 +72,7 @@ HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPV
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
|
static ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
|
||||||
{
|
{
|
||||||
|
|
||||||
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
||||||
|
@ -80,7 +81,7 @@ ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
|
||||||
return InterlockedIncrement (&This->ref);
|
return InterlockedIncrement (&This->ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
|
static ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
|
||||||
{
|
{
|
||||||
|
|
||||||
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
FTMarshalImpl *This = (FTMarshalImpl *)iface;
|
||||||
|
@ -99,7 +100,8 @@ static IUnknownVtbl iunkvt =
|
||||||
IiFTMUnknown_fnRelease
|
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);
|
_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);
|
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);
|
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||||
|
@ -117,7 +120,8 @@ ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
|
||||||
return IUnknown_AddRef (This->pUnkOuter);
|
return IUnknown_AddRef (This->pUnkOuter);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
|
static ULONG WINAPI
|
||||||
|
FTMarshalImpl_Release (LPMARSHAL iface)
|
||||||
{
|
{
|
||||||
|
|
||||||
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
|
||||||
|
@ -126,14 +130,16 @@ ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
|
||||||
return IUnknown_Release (This->pUnkOuter);
|
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)
|
void *pvDestContext, DWORD mshlflags, CLSID * pCid)
|
||||||
{
|
{
|
||||||
FIXME ("(), stub!\n");
|
FIXME ("(), stub!\n");
|
||||||
return S_OK;
|
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)
|
void *pvDestContext, DWORD mshlflags, DWORD * pSize)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -158,8 +164,9 @@ HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, vo
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
|
static HRESULT WINAPI
|
||||||
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
|
FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
|
||||||
|
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
|
||||||
{
|
{
|
||||||
|
|
||||||
IMarshal *pMarshal = NULL;
|
IMarshal *pMarshal = NULL;
|
||||||
|
@ -182,25 +189,26 @@ HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm,
|
||||||
return hres;
|
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");
|
FIXME ("(), stub!\n");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
|
static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
|
||||||
{
|
{
|
||||||
FIXME ("(), stub!\n");
|
FIXME ("(), stub!\n");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
|
static HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
|
||||||
{
|
{
|
||||||
FIXME ("(), stub!\n");
|
FIXME ("(), stub!\n");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMarshalVtbl ftmvtbl =
|
static IMarshalVtbl ftmvtbl =
|
||||||
{
|
{
|
||||||
FTMarshalImpl_QueryInterface,
|
FTMarshalImpl_QueryInterface,
|
||||||
FTMarshalImpl_AddRef,
|
FTMarshalImpl_AddRef,
|
||||||
|
|
|
@ -83,27 +83,6 @@ typedef struct StdGlobalInterfaceTableImpl
|
||||||
|
|
||||||
void* StdGlobalInterfaceTableInstance;
|
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 git_section;
|
||||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
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 };
|
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 **/
|
/** This destroys it again. It should revoke all the held interfaces first **/
|
||||||
void StdGlobalInterfaceTable_Destroy(void* self) {
|
void StdGlobalInterfaceTable_Destroy(void* self) {
|
||||||
TRACE("(%p)\n", 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.
|
* A helper function to traverse the list and find the entry that matches the cookie.
|
||||||
* Returns NULL if not found
|
* 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;
|
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||||
StdGITEntry* e;
|
StdGITEntry* e;
|
||||||
|
|
||||||
|
@ -174,34 +133,39 @@ StdGITEntry* StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWO
|
||||||
* Here's the boring boilerplate stuff for IUnknown
|
* Here's the boring boilerplate stuff for IUnknown
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject) {
|
static HRESULT WINAPI
|
||||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface,
|
||||||
|
REFIID riid, void** ppvObject)
|
||||||
|
{
|
||||||
/* Make sure silly coders can't crash us */
|
/* Make sure silly coders can't crash us */
|
||||||
if (ppvObject == 0) return E_INVALIDARG;
|
if (ppvObject == 0) return E_INVALIDARG;
|
||||||
|
|
||||||
*ppvObject = 0; /* assume we don't have the interface */
|
*ppvObject = 0; /* assume we don't have the interface */
|
||||||
|
|
||||||
/* Do we implement that interface? */
|
/* Do we implement that interface? */
|
||||||
if (IsEqualIID(&IID_IUnknown, riid)) {
|
if (IsEqualIID(&IID_IUnknown, riid) ||
|
||||||
*ppvObject = (IGlobalInterfaceTable*) self;
|
IsEqualIID(&IID_IGlobalInterfaceTable, riid))
|
||||||
} else if (IsEqualIID(&IID_IGlobalInterfaceTable, riid)) {
|
*ppvObject = iface;
|
||||||
*ppvObject = (IGlobalInterfaceTable*) self;
|
else
|
||||||
} else return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
|
|
||||||
/* Now inc the refcount */
|
/* Now inc the refcount */
|
||||||
StdGlobalInterfaceTable_AddRef(iface);
|
IGlobalInterfaceTable_AddRef(iface);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface) {
|
static ULONG WINAPI
|
||||||
|
StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface)
|
||||||
|
{
|
||||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||||
|
|
||||||
/* InterlockedIncrement(&self->ref); */
|
/* InterlockedIncrement(&self->ref); */
|
||||||
return self->ref;
|
return self->ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface) {
|
static ULONG WINAPI
|
||||||
|
StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface)
|
||||||
|
{
|
||||||
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||||
|
|
||||||
/* InterlockedDecrement(&self->ref); */
|
/* InterlockedDecrement(&self->ref); */
|
||||||
|
@ -218,12 +182,16 @@ ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface) {
|
||||||
* Now implement the actual IGlobalInterfaceTable interface
|
* 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;
|
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||||
IStream* stream = NULL;
|
IStream* stream = NULL;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
StdGITEntry* entry;
|
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);
|
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;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zero.QuadPart = 0;
|
||||||
IStream_Seek(stream, zero, SEEK_SET, NULL);
|
IStream_Seek(stream, zero, SEEK_SET, NULL);
|
||||||
|
|
||||||
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
|
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
|
||||||
|
@ -269,7 +238,10 @@ HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfac
|
||||||
return S_OK;
|
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;
|
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
|
||||||
StdGITEntry* entry;
|
StdGITEntry* entry;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -303,7 +275,11 @@ HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfac
|
||||||
return S_OK;
|
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;
|
StdGITEntry* entry;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
LARGE_INTEGER move;
|
LARGE_INTEGER move;
|
||||||
|
@ -341,18 +317,33 @@ HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTa
|
||||||
|
|
||||||
/* Classfactory definition - despite what MSDN says, some programs need this */
|
/* 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;
|
*ppv = NULL;
|
||||||
if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IGlobalInterfaceTable)) {
|
if (IsEqualIID(riid,&IID_IUnknown) ||
|
||||||
|
IsEqualIID(riid,&IID_IGlobalInterfaceTable))
|
||||||
|
{
|
||||||
*ppv = (LPVOID)iface;
|
*ppv = (LPVOID)iface;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
return E_NOINTERFACE;
|
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 (IsEqualIID(riid,&IID_IGlobalInterfaceTable)) {
|
||||||
if (StdGlobalInterfaceTableInstance == NULL)
|
if (StdGlobalInterfaceTableInstance == NULL)
|
||||||
StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct();
|
StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct();
|
||||||
|
@ -363,7 +354,8 @@ static HRESULT WINAPI GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
|
||||||
return E_NOINTERFACE;
|
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);
|
FIXME("(%d), stub!\n",fLock);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -375,10 +367,41 @@ static IClassFactoryVtbl GITClassFactoryVtbl = {
|
||||||
GITCF_CreateInstance,
|
GITCF_CreateInstance,
|
||||||
GITCF_LockServer
|
GITCF_LockServer
|
||||||
};
|
};
|
||||||
|
|
||||||
static IClassFactoryVtbl *PGITClassFactoryVtbl = &GITClassFactoryVtbl;
|
static IClassFactoryVtbl *PGITClassFactoryVtbl = &GITClassFactoryVtbl;
|
||||||
|
|
||||||
HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) {
|
HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv)
|
||||||
|
{
|
||||||
*ppv = &PGITClassFactoryVtbl;
|
*ppv = &PGITClassFactoryVtbl;
|
||||||
TRACE("Returning GIT classfactory\n");
|
TRACE("Returning GIT classfactory\n");
|
||||||
return S_OK;
|
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;
|
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.
|
* 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
|
* class. The pointer passed-in to this function will be freed and will not
|
||||||
* be valid anymore.
|
* be valid anymore.
|
||||||
*/
|
*/
|
||||||
void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
|
static void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", This);
|
TRACE("(%p)\n", This);
|
||||||
|
|
||||||
|
@ -323,11 +112,22 @@ void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
|
||||||
HeapFree(GetProcessHeap(), 0, 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
|
* This implements the IUnknown method QueryInterface for this
|
||||||
* class
|
* class
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
static HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
REFIID riid, /* [in] */
|
REFIID riid, /* [in] */
|
||||||
void** ppvObject) /* [iid_is][out] */
|
void** ppvObject) /* [iid_is][out] */
|
||||||
|
@ -372,22 +172,11 @@ HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
|
||||||
return S_OK;
|
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
|
* This implements the IUnknown method Release for this
|
||||||
* class
|
* class
|
||||||
*/
|
*/
|
||||||
ULONG WINAPI HGLOBALStreamImpl_Release(
|
static ULONG WINAPI HGLOBALStreamImpl_Release(
|
||||||
IStream* iface)
|
IStream* iface)
|
||||||
{
|
{
|
||||||
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
|
||||||
|
@ -415,7 +204,7 @@ ULONG WINAPI HGLOBALStreamImpl_Release(
|
||||||
*
|
*
|
||||||
* See the documentation of ISequentialStream for more info.
|
* See the documentation of ISequentialStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_Read(
|
static HRESULT WINAPI HGLOBALStreamImpl_Read(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
void* pv, /* [length_is][size_is][out] */
|
void* pv, /* [length_is][size_is][out] */
|
||||||
ULONG cb, /* [in] */
|
ULONG cb, /* [in] */
|
||||||
|
@ -486,7 +275,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Read(
|
||||||
*
|
*
|
||||||
* See the documentation of ISequentialStream for more info.
|
* See the documentation of ISequentialStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_Write(
|
static HRESULT WINAPI HGLOBALStreamImpl_Write(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
const void* pv, /* [size_is][in] */
|
const void* pv, /* [size_is][in] */
|
||||||
ULONG cb, /* [in] */
|
ULONG cb, /* [in] */
|
||||||
|
@ -560,7 +349,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Write(
|
||||||
*
|
*
|
||||||
* See the documentation of IStream for more info.
|
* See the documentation of IStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
static HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
LARGE_INTEGER dlibMove, /* [in] */
|
LARGE_INTEGER dlibMove, /* [in] */
|
||||||
DWORD dwOrigin, /* [in] */
|
DWORD dwOrigin, /* [in] */
|
||||||
|
@ -617,7 +406,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Seek(
|
||||||
*
|
*
|
||||||
* See the documentation of IStream for more info.
|
* See the documentation of IStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
ULARGE_INTEGER libNewSize) /* [in] */
|
ULARGE_INTEGER libNewSize) /* [in] */
|
||||||
{
|
{
|
||||||
|
@ -656,7 +445,7 @@ HRESULT WINAPI HGLOBALStreamImpl_SetSize(
|
||||||
*
|
*
|
||||||
* See the documentation of IStream for more info.
|
* See the documentation of IStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
|
static HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
IStream* pstm, /* [unique][in] */
|
IStream* pstm, /* [unique][in] */
|
||||||
ULARGE_INTEGER cb, /* [in] */
|
ULARGE_INTEGER cb, /* [in] */
|
||||||
|
@ -741,7 +530,7 @@ HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
|
||||||
*
|
*
|
||||||
* See the documentation of IStream for more info.
|
* See the documentation of IStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_Commit(
|
static HRESULT WINAPI HGLOBALStreamImpl_Commit(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
DWORD grfCommitFlags) /* [in] */
|
DWORD grfCommitFlags) /* [in] */
|
||||||
{
|
{
|
||||||
|
@ -756,7 +545,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Commit(
|
||||||
*
|
*
|
||||||
* See the documentation of IStream for more info.
|
* See the documentation of IStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_Revert(
|
static HRESULT WINAPI HGLOBALStreamImpl_Revert(
|
||||||
IStream* iface)
|
IStream* iface)
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -770,7 +559,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Revert(
|
||||||
*
|
*
|
||||||
* See the documentation of IStream for more info.
|
* See the documentation of IStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
|
static HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
ULARGE_INTEGER libOffset, /* [in] */
|
ULARGE_INTEGER libOffset, /* [in] */
|
||||||
ULARGE_INTEGER cb, /* [in] */
|
ULARGE_INTEGER cb, /* [in] */
|
||||||
|
@ -787,7 +576,7 @@ HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
|
||||||
*
|
*
|
||||||
* See the documentation of IStream for more info.
|
* See the documentation of IStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
|
static HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
ULARGE_INTEGER libOffset, /* [in] */
|
ULARGE_INTEGER libOffset, /* [in] */
|
||||||
ULARGE_INTEGER cb, /* [in] */
|
ULARGE_INTEGER cb, /* [in] */
|
||||||
|
@ -804,7 +593,7 @@ HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
|
||||||
*
|
*
|
||||||
* See the documentation of IStream for more info.
|
* See the documentation of IStream for more info.
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
static HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
STATSTG* pstatstg, /* [out] */
|
STATSTG* pstatstg, /* [out] */
|
||||||
DWORD grfStatFlag) /* [in] */
|
DWORD grfStatFlag) /* [in] */
|
||||||
|
@ -820,7 +609,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Stat(
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
static HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
||||||
IStream* iface,
|
IStream* iface,
|
||||||
IStream** ppstm) /* [out] */
|
IStream** ppstm) /* [out] */
|
||||||
{
|
{
|
||||||
|
@ -836,3 +625,133 @@ HRESULT WINAPI HGLOBALStreamImpl_Clone(
|
||||||
HGLOBALStreamImpl_Seek(*ppstm,offset,STREAM_SEEK_SET,&dummy);
|
HGLOBALStreamImpl_Seek(*ppstm,offset,STREAM_SEEK_SET,&dummy);
|
||||||
return S_OK;
|
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 */
|
LPOLESTR itemDelimiter; /* Delimiter string */
|
||||||
|
|
||||||
|
IUnknown *pMarshal; /* custom marshaler */
|
||||||
} ItemMonikerImpl;
|
} ItemMonikerImpl;
|
||||||
|
|
||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
|
@ -107,7 +108,7 @@ static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
|
||||||
static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
|
static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
|
||||||
|
|
||||||
/* IROTData prototype function */
|
/* 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,*/
|
/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
|
||||||
|
@ -146,7 +147,7 @@ static IROTDataVtbl VT_ROTDataImpl =
|
||||||
ItemMonikerROTDataImpl_QueryInterface,
|
ItemMonikerROTDataImpl_QueryInterface,
|
||||||
ItemMonikerROTDataImpl_AddRef,
|
ItemMonikerROTDataImpl_AddRef,
|
||||||
ItemMonikerROTDataImpl_Release,
|
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))
|
else if (IsEqualIID(&IID_IROTData, riid))
|
||||||
*ppvObject = (IROTData*)&(This->lpvtbl2);
|
*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.*/
|
/* Check that we obtained an interface.*/
|
||||||
if ((*ppvObject)==0)
|
if ((*ppvObject)==0)
|
||||||
|
@ -359,17 +369,16 @@ HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
|
||||||
|
|
||||||
TRACE("(%p,%p)\n",iface,pcbSize);
|
TRACE("(%p,%p)\n",iface,pcbSize);
|
||||||
|
|
||||||
if (pcbSize!=NULL)
|
if (!pcbSize)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
/* for more details see ItemMonikerImpl_Save coments */
|
/* for more details see ItemMonikerImpl_Save coments */
|
||||||
|
|
||||||
pcbSize->u.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
|
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 */
|
sizeof(DWORD) + /* DWORD which contains item name length */
|
||||||
nameLength + /* item name string */
|
nameLength*4 + /* item name string */
|
||||||
34; /* this constant was added ! because when I tested this function it usually */
|
18; /* strange, but true */
|
||||||
/* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
|
|
||||||
pcbSize->u.HighPart=0;
|
pcbSize->u.HighPart=0;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -391,6 +400,7 @@ HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDe
|
||||||
This->lpvtbl1 = &VT_ItemMonikerImpl;
|
This->lpvtbl1 = &VT_ItemMonikerImpl;
|
||||||
This->lpvtbl2 = &VT_ROTDataImpl;
|
This->lpvtbl2 = &VT_ROTDataImpl;
|
||||||
This->ref = 0;
|
This->ref = 0;
|
||||||
|
This->pMarshal = NULL;
|
||||||
|
|
||||||
This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
|
This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
|
||||||
if (!This->itemName)
|
if (!This->itemName)
|
||||||
|
@ -419,6 +429,7 @@ HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n",This);
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
if (This->pMarshal) IUnknown_Release(This->pMarshal);
|
||||||
HeapFree(GetProcessHeap(),0,This->itemName);
|
HeapFree(GetProcessHeap(),0,This->itemName);
|
||||||
HeapFree(GetProcessHeap(),0,This->itemDelimiter);
|
HeapFree(GetProcessHeap(),0,This->itemDelimiter);
|
||||||
HeapFree(GetProcessHeap(),0,This);
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
@ -952,13 +963,35 @@ ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* ItemMonikerIROTData_GetComparaisonData
|
* ItemMonikerIROTData_GetComparaisonData
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
|
HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
|
||||||
BYTE* pbData,
|
BYTE* pbData,
|
||||||
ULONG cbMax,
|
ULONG cbMax,
|
||||||
ULONG* pcbData)
|
ULONG* pcbData)
|
||||||
{
|
{
|
||||||
FIXME("(),stub!\n");
|
ICOM_THIS_From_IROTData(IMoniker, iface);
|
||||||
return E_NOTIMPL;
|
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);
|
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.
|
* 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!
|
* 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
|
* A triple is used: OXID (apt id), OID (stub manager id),
|
||||||
* manager id), IPID (interface ptr/stub id).
|
* IPID (interface ptr/stub id).
|
||||||
*
|
*
|
||||||
* OXIDs identify an apartment and are network scoped
|
* OXIDs identify an apartment and are network scoped
|
||||||
* OIDs identify a stub manager and are apartment scoped
|
* OIDs identify a stub manager and are apartment scoped
|
||||||
* IPIDs identify an interface stub and are apartment scoped
|
* IPIDs identify an interface stub and are apartment scoped
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline static HRESULT
|
inline static HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
|
||||||
get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) {
|
{
|
||||||
HRESULT hres;
|
HRESULT hr;
|
||||||
CLSID pxclsid;
|
CLSID clsid;
|
||||||
|
|
||||||
if ((hres = CoGetPSClsid(riid,&pxclsid)))
|
if ((hr = CoGetPSClsid(riid, &clsid)))
|
||||||
return hres;
|
return hr;
|
||||||
return CoGetClassObject(&pxclsid,CLSCTX_INPROC_SERVER,NULL,&IID_IPSFactoryBuffer,(LPVOID*)facbuf);
|
return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL,
|
||||||
|
&IID_IPSFactoryBuffer, (LPVOID*)facbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* creates a new stub manager */
|
/* creates a new stub manager */
|
||||||
|
@ -747,56 +746,61 @@ HRESULT apartment_disconnectproxies(struct apartment *apt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************** StdMarshal implementation ****************************/
|
/********************** StdMarshal implementation ****************************/
|
||||||
typedef struct _StdMarshalImpl {
|
typedef struct _StdMarshalImpl
|
||||||
IMarshalVtbl *lpvtbl;
|
{
|
||||||
DWORD ref;
|
const IMarshalVtbl *lpvtbl;
|
||||||
|
DWORD ref;
|
||||||
|
|
||||||
IID iid;
|
IID iid;
|
||||||
DWORD dwDestContext;
|
DWORD dwDestContext;
|
||||||
LPVOID pvDestContext;
|
LPVOID pvDestContext;
|
||||||
DWORD mshlflags;
|
DWORD mshlflags;
|
||||||
} StdMarshalImpl;
|
} StdMarshalImpl;
|
||||||
|
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
StdMarshalImpl_QueryInterface(LPMARSHAL iface,REFIID riid,LPVOID *ppv) {
|
StdMarshalImpl_QueryInterface(LPMARSHAL iface, REFIID riid, LPVOID *ppv)
|
||||||
*ppv = NULL;
|
{
|
||||||
if (IsEqualIID(&IID_IUnknown,riid) || IsEqualIID(&IID_IMarshal,riid)) {
|
*ppv = NULL;
|
||||||
*ppv = iface;
|
if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IMarshal, riid))
|
||||||
IUnknown_AddRef(iface);
|
{
|
||||||
return S_OK;
|
*ppv = iface;
|
||||||
}
|
IUnknown_AddRef(iface);
|
||||||
FIXME("No interface for %s.\n",debugstr_guid(riid));
|
return S_OK;
|
||||||
return E_NOINTERFACE;
|
}
|
||||||
|
FIXME("No interface for %s.\n", debugstr_guid(riid));
|
||||||
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI
|
static ULONG WINAPI
|
||||||
StdMarshalImpl_AddRef(LPMARSHAL iface) {
|
StdMarshalImpl_AddRef(LPMARSHAL iface)
|
||||||
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
{
|
||||||
return InterlockedIncrement(&This->ref);
|
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
||||||
|
return InterlockedIncrement(&This->ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI
|
static ULONG WINAPI
|
||||||
StdMarshalImpl_Release(LPMARSHAL iface) {
|
StdMarshalImpl_Release(LPMARSHAL iface)
|
||||||
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
{
|
||||||
ULONG ref = InterlockedDecrement(&This->ref);
|
StdMarshalImpl *This = (StdMarshalImpl *)iface;
|
||||||
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
if (!ref) HeapFree(GetProcessHeap(),0,This);
|
if (!ref) HeapFree(GetProcessHeap(),0,This);
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
StdMarshalImpl_GetUnmarshalClass(
|
StdMarshalImpl_GetUnmarshalClass(
|
||||||
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
||||||
void* pvDestContext, DWORD mshlflags, CLSID* pCid
|
void* pvDestContext, DWORD mshlflags, CLSID* pCid)
|
||||||
) {
|
{
|
||||||
memcpy(pCid,&CLSID_DfMarshal,sizeof(CLSID_DfMarshal));
|
*pCid = CLSID_DfMarshal;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
StdMarshalImpl_GetMarshalSizeMax(
|
StdMarshalImpl_GetMarshalSizeMax(
|
||||||
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
|
||||||
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
|
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
|
||||||
{
|
{
|
||||||
*pSize = sizeof(STDOBJREF);
|
*pSize = sizeof(STDOBJREF);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -804,48 +808,48 @@ StdMarshalImpl_GetMarshalSizeMax(
|
||||||
|
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
StdMarshalImpl_MarshalInterface(
|
StdMarshalImpl_MarshalInterface(
|
||||||
LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dwDestContext,
|
LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dwDestContext,
|
||||||
void* pvDestContext, DWORD mshlflags
|
void* pvDestContext, DWORD mshlflags)
|
||||||
) {
|
{
|
||||||
STDOBJREF stdobjref;
|
STDOBJREF stdobjref;
|
||||||
IUnknown *pUnk;
|
IUnknown *pUnk;
|
||||||
ULONG res;
|
ULONG res;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
APARTMENT *apt = COM_CurrentApt();
|
APARTMENT *apt = COM_CurrentApt();
|
||||||
|
|
||||||
TRACE("(...,%s,...)\n",debugstr_guid(riid));
|
|
||||||
|
|
||||||
if (!apt)
|
TRACE("(...,%s,...)\n", debugstr_guid(riid));
|
||||||
{
|
|
||||||
ERR("Apartment not initialized\n");
|
|
||||||
return CO_E_NOTINITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure this apartment can be reached from other threads / processes */
|
if (!apt)
|
||||||
RPC_StartRemoting(apt);
|
{
|
||||||
|
ERR("Apartment not initialized\n");
|
||||||
|
return CO_E_NOTINITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
|
/* make sure this apartment can be reached from other threads / processes */
|
||||||
if (hres != S_OK)
|
RPC_StartRemoting(apt);
|
||||||
{
|
|
||||||
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);
|
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)
|
if (hres)
|
||||||
{
|
{
|
||||||
FIXME("Failed to create ifstub, hres=0x%lx\n", hres);
|
ERR("Failed to create ifstub, hres=0x%lx\n", hres);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res);
|
hres = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||||
if (hres) return hres;
|
if (hres) return hres;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
|
/* 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
|
static HRESULT WINAPI
|
||||||
StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
|
StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
|
||||||
{
|
{
|
||||||
struct stub_manager *stubmgr;
|
struct stub_manager *stubmgr;
|
||||||
STDOBJREF stdobjref;
|
STDOBJREF stdobjref;
|
||||||
ULONG res;
|
ULONG res;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
APARTMENT *apt = COM_CurrentApt();
|
APARTMENT *apt = COM_CurrentApt();
|
||||||
APARTMENT *stub_apt;
|
APARTMENT *stub_apt;
|
||||||
OXID oxid;
|
OXID oxid;
|
||||||
|
|
||||||
TRACE("(...,%s,....)\n",debugstr_guid(riid));
|
TRACE("(...,%s,....)\n", debugstr_guid(riid));
|
||||||
|
|
||||||
/* we need an apartment to unmarshal into */
|
/* we need an apartment to unmarshal into */
|
||||||
if (!apt)
|
if (!apt)
|
||||||
{
|
{
|
||||||
ERR("Apartment not initialized\n");
|
ERR("Apartment not initialized\n");
|
||||||
return CO_E_NOTINITIALIZED;
|
return CO_E_NOTINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read STDOBJREF from wire */
|
/* read STDOBJREF from wire */
|
||||||
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
|
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||||
if (hres) return hres;
|
if (hres) return hres;
|
||||||
|
|
||||||
hres = apartment_getoxid(apt, &oxid);
|
hres = apartment_getoxid(apt, &oxid);
|
||||||
if (hres) return hres;
|
if (hres) return hres;
|
||||||
|
|
||||||
/* check if we're marshalling back to ourselves */
|
/* check if we're marshalling back to ourselves */
|
||||||
if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
|
if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
|
||||||
{
|
{
|
||||||
TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
|
TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
|
||||||
"returning original object %p\n", debugstr_guid(riid), stubmgr->object);
|
"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? */
|
/* unref the ifstub. FIXME: only do this on success? */
|
||||||
if (!stub_manager_is_table_marshaled(stubmgr))
|
if (!stub_manager_is_table_marshaled(stubmgr))
|
||||||
stub_manager_ext_release(stubmgr, 1);
|
stub_manager_ext_release(stubmgr, 1);
|
||||||
|
|
||||||
stub_manager_int_release(stubmgr);
|
stub_manager_int_release(stubmgr);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* notify stub manager about unmarshal if process-local object.
|
/* notify stub manager about unmarshal if process-local object.
|
||||||
* note: if the oxid is not found then we and native will quite happily
|
* note: if the oxid is not found then we and native will quite happily
|
||||||
* ignore table marshaling and normal marshaling rules regarding number of
|
* ignore table marshaling and normal marshaling rules regarding number of
|
||||||
* unmarshals, etc, but if you abuse these rules then your proxy could end
|
* unmarshals, etc, but if you abuse these rules then your proxy could end
|
||||||
* up returning RPC_E_DISCONNECTED. */
|
* up returning RPC_E_DISCONNECTED. */
|
||||||
if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
|
if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
|
||||||
{
|
{
|
||||||
if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
|
if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
|
||||||
{
|
{
|
||||||
if (!stub_manager_notify_unmarshal(stubmgr))
|
if (!stub_manager_notify_unmarshal(stubmgr))
|
||||||
hres = CO_E_OBJNOTCONNECTED;
|
hres = CO_E_OBJNOTCONNECTED;
|
||||||
|
|
||||||
stub_manager_int_release(stubmgr);
|
stub_manager_int_release(stubmgr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n",
|
WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n",
|
||||||
wine_dbgstr_longlong(stdobjref.oxid),
|
wine_dbgstr_longlong(stdobjref.oxid),
|
||||||
wine_dbgstr_longlong(stdobjref.oid));
|
wine_dbgstr_longlong(stdobjref.oid));
|
||||||
hres = CO_E_OBJNOTCONNECTED;
|
hres = CO_E_OBJNOTCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
apartment_release(stub_apt);
|
apartment_release(stub_apt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TRACE("Treating unmarshal from OXID %s as inter-process\n",
|
TRACE("Treating unmarshal from OXID %s as inter-process\n",
|
||||||
wine_dbgstr_longlong(stdobjref.oxid));
|
wine_dbgstr_longlong(stdobjref.oxid));
|
||||||
|
|
||||||
if (hres == S_OK)
|
if (hres == S_OK)
|
||||||
hres = unmarshal_object(&stdobjref, apt, riid, ppv);
|
hres = unmarshal_object(&stdobjref, apt, riid, ppv);
|
||||||
|
|
||||||
if (hres) WARN("Failed with error 0x%08lx\n", hres);
|
if (hres) WARN("Failed with error 0x%08lx\n", hres);
|
||||||
else TRACE("Successfully created proxy %p\n", *ppv);
|
else TRACE("Successfully created proxy %p\n", *ppv);
|
||||||
|
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
|
StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
|
||||||
|
{
|
||||||
STDOBJREF stdobjref;
|
STDOBJREF stdobjref;
|
||||||
ULONG res;
|
ULONG res;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -997,6 +1002,11 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
|
||||||
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
|
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||||
if (hres) return hres;
|
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)))
|
if (!(apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
|
||||||
{
|
{
|
||||||
WARN("Could not map OXID %s to apartment object\n",
|
WARN("Could not map OXID %s to apartment object\n",
|
||||||
|
@ -1020,12 +1030,14 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved) {
|
StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved)
|
||||||
FIXME("(), stub!\n");
|
{
|
||||||
return S_OK;
|
FIXME("(), stub!\n");
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMarshalVtbl stdmvtbl = {
|
static const IMarshalVtbl VT_StdMarshal =
|
||||||
|
{
|
||||||
StdMarshalImpl_QueryInterface,
|
StdMarshalImpl_QueryInterface,
|
||||||
StdMarshalImpl_AddRef,
|
StdMarshalImpl_AddRef,
|
||||||
StdMarshalImpl_Release,
|
StdMarshalImpl_Release,
|
||||||
|
@ -1043,7 +1055,7 @@ static HRESULT StdMarshalImpl_Construct(REFIID riid, void** ppvObject)
|
||||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(StdMarshalImpl));
|
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(StdMarshalImpl));
|
||||||
if (!pStdMarshal)
|
if (!pStdMarshal)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
pStdMarshal->lpvtbl = &stdmvtbl;
|
pStdMarshal->lpvtbl = &VT_StdMarshal;
|
||||||
pStdMarshal->ref = 0;
|
pStdMarshal->ref = 0;
|
||||||
return IMarshal_QueryInterface((IMarshal*)pStdMarshal, riid, ppvObject);
|
return IMarshal_QueryInterface((IMarshal*)pStdMarshal, riid, ppvObject);
|
||||||
}
|
}
|
||||||
|
@ -1075,28 +1087,27 @@ HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk,
|
||||||
DWORD dwDestContext, LPVOID pvDestContext,
|
DWORD dwDestContext, LPVOID pvDestContext,
|
||||||
DWORD mshlflags, LPMARSHAL *ppMarshal)
|
DWORD mshlflags, LPMARSHAL *ppMarshal)
|
||||||
{
|
{
|
||||||
StdMarshalImpl *dm;
|
StdMarshalImpl *dm;
|
||||||
|
|
||||||
if (pUnk == NULL) {
|
if (pUnk == NULL)
|
||||||
FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
|
{
|
||||||
debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,ppMarshal
|
FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
|
||||||
);
|
debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,ppMarshal);
|
||||||
return E_FAIL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
|
TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
|
||||||
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal
|
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal);
|
||||||
);
|
*ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
|
||||||
*ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
|
dm = (StdMarshalImpl*) *ppMarshal;
|
||||||
dm = (StdMarshalImpl*) *ppMarshal;
|
if (!dm) return E_FAIL;
|
||||||
if (!dm) return E_FAIL;
|
dm->lpvtbl = &VT_StdMarshal;
|
||||||
dm->lpvtbl = &stdmvtbl;
|
dm->ref = 1;
|
||||||
dm->ref = 1;
|
|
||||||
|
|
||||||
memcpy(&dm->iid,riid,sizeof(dm->iid));
|
dm->iid = *riid;
|
||||||
dm->dwDestContext = dwDestContext;
|
dm->dwDestContext = dwDestContext;
|
||||||
dm->pvDestContext = pvDestContext;
|
dm->pvDestContext = pvDestContext;
|
||||||
dm->mshlflags = mshlflags;
|
dm->mshlflags = mshlflags;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1157,7 +1168,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
|
||||||
}
|
}
|
||||||
else if (objref.flags & OBJREF_CUSTOM)
|
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);
|
FIELD_OFFSET(OBJREF, u_objref.u_custom);
|
||||||
TRACE("Using custom unmarshaling\n");
|
TRACE("Using custom unmarshaling\n");
|
||||||
/* read constant sized OR_CUSTOM data from stream */
|
/* 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 custom marshaling, add on size of custom header */
|
||||||
if (!IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal))
|
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);
|
FIELD_OFFSET(OBJREF, u_objref.u_custom);
|
||||||
|
|
||||||
IMarshal_Release(pMarshal);
|
IMarshal_Release(pMarshal);
|
||||||
|
@ -1281,7 +1292,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
CLSID marshaler_clsid;
|
CLSID marshaler_clsid;
|
||||||
OBJREF objref;
|
OBJREF objref;
|
||||||
IStream * pMarshalStream = NULL;
|
|
||||||
LPMARSHAL pMarshal;
|
LPMARSHAL pMarshal;
|
||||||
|
|
||||||
TRACE("(%p, %s, %p, %lx, %p, %lx)\n", pStream, debugstr_guid(riid), pUnk,
|
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");
|
TRACE("Using standard marshaling\n");
|
||||||
objref.flags = OBJREF_STANDARD;
|
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
|
else
|
||||||
{
|
{
|
||||||
TRACE("Using custom marshaling\n");
|
TRACE("Using custom marshaling\n");
|
||||||
objref.flags = OBJREF_CUSTOM;
|
objref.flags = OBJREF_CUSTOM;
|
||||||
/* we do custom marshaling into a memory stream so that we know what
|
objref.u_objref.u_custom.clsid = marshaler_clsid;
|
||||||
* size to write into the OR_CUSTOM header */
|
objref.u_objref.u_custom.cbExtension = 0;
|
||||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pMarshalStream);
|
objref.u_objref.u_custom.size = 0;
|
||||||
|
hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext,
|
||||||
|
pvDestContext, mshlFlags,
|
||||||
|
&objref.u_objref.u_custom.size);
|
||||||
if (hr)
|
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;
|
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");
|
TRACE("Calling IMarshal::MarshalInterace\n");
|
||||||
/* call helper object to do the actual marshaling */
|
/* 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);
|
pvDestContext, mshlFlags);
|
||||||
|
|
||||||
if (hr)
|
if (hr)
|
||||||
|
@ -1349,51 +1369,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
|
||||||
goto cleanup;
|
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:
|
cleanup:
|
||||||
if (pMarshalStream && (objref.flags & OBJREF_CUSTOM))
|
|
||||||
IStream_Release(pMarshalStream);
|
|
||||||
IMarshal_Release(pMarshal);
|
IMarshal_Release(pMarshal);
|
||||||
|
|
||||||
TRACE("completed with hr 0x%08lx\n", hr);
|
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,
|
static HRESULT WINAPI StdMarshalCF_CreateInstance(LPCLASSFACTORY iface,
|
||||||
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
|
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
|
||||||
{
|
{
|
||||||
if (IsEqualIID(riid,&IID_IMarshal))
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMarshal))
|
||||||
return StdMarshalImpl_Construct(riid, ppv);
|
return StdMarshalImpl_Construct(riid, ppv);
|
||||||
|
|
||||||
FIXME("(%s), not supported.\n",debugstr_guid(riid));
|
FIXME("(%s), not supported.\n",debugstr_guid(riid));
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI StdMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
|
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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IClassFactoryVtbl StdMarshalCFVtbl =
|
static const IClassFactoryVtbl StdMarshalCFVtbl =
|
||||||
{
|
{
|
||||||
StdMarshalCF_QueryInterface,
|
StdMarshalCF_QueryInterface,
|
||||||
StdMarshalCF_AddRef,
|
StdMarshalCF_AddRef,
|
||||||
|
@ -1623,7 +1599,7 @@ static IClassFactoryVtbl StdMarshalCFVtbl =
|
||||||
StdMarshalCF_CreateInstance,
|
StdMarshalCF_CreateInstance,
|
||||||
StdMarshalCF_LockServer
|
StdMarshalCF_LockServer
|
||||||
};
|
};
|
||||||
static IClassFactoryVtbl *StdMarshalCF = &StdMarshalCFVtbl;
|
static const IClassFactoryVtbl *StdMarshalCF = &StdMarshalCFVtbl;
|
||||||
|
|
||||||
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv)
|
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_AntiMoniker;
|
||||||
extern const CLSID CLSID_CompositeMoniker;
|
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__ */
|
#endif /* __WINE_MONIKER_H__ */
|
||||||
|
|
|
@ -50,9 +50,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
|
|
||||||
HINSTANCE16 COMPOBJ_hInstance = 0;
|
|
||||||
static int COMPOBJ_Attach = 0;
|
|
||||||
|
|
||||||
HTASK16 hETask = 0;
|
HTASK16 hETask = 0;
|
||||||
WORD Table_ETask[62];
|
WORD Table_ETask[62];
|
||||||
|
|
||||||
|
@ -299,7 +296,7 @@ extern BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* the allocated segmented pointer and a HRESULT
|
* the allocated segmented pointer and a HRESULT
|
||||||
*/
|
*/
|
||||||
HRESULT
|
static HRESULT
|
||||||
_xmalloc16(DWORD size, SEGPTR *ptr) {
|
_xmalloc16(DWORD size, SEGPTR *ptr) {
|
||||||
LPMALLOC16 mllc;
|
LPMALLOC16 mllc;
|
||||||
DWORD args[2];
|
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)
|
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);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* Copyright 1999 Francis Beaudet
|
* Copyright 1999 Francis Beaudet
|
||||||
* Copyright 1999 Noel Borthwick
|
* Copyright 1999 Noel Borthwick
|
||||||
* Copyright 1999, 2000 Marcus Meissner
|
* Copyright 1999, 2000 Marcus Meissner
|
||||||
|
* Copyright 2005 Juan Lang
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -48,7 +49,6 @@
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "wine/wingdi16.h"
|
#include "wine/wingdi16.h"
|
||||||
#include "wine/winuser16.h"
|
#include "wine/winuser16.h"
|
||||||
#include "ole32_main.h"
|
|
||||||
#include "compobj_private.h"
|
#include "compobj_private.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
@ -2292,13 +2292,13 @@ HRESULT WINAPI OleCreate(
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* OleSetAutoConvert [OLE32.@]
|
* OleSetAutoConvert [OLE32.@]
|
||||||
*/
|
*/
|
||||||
/* FIXME: convert to Unicode */
|
|
||||||
HRESULT WINAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew)
|
HRESULT WINAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew)
|
||||||
{
|
{
|
||||||
HKEY hkey = 0;
|
HKEY hkey = 0;
|
||||||
char buf[200], szClsidNew[200];
|
char buf[200], szClsidNew[200];
|
||||||
HRESULT res = S_OK;
|
HRESULT res = S_OK;
|
||||||
|
|
||||||
|
/* FIXME: convert to Unicode */
|
||||||
TRACE("(%s,%s)\n", debugstr_guid(clsidOld), debugstr_guid(clsidNew));
|
TRACE("(%s,%s)\n", debugstr_guid(clsidOld), debugstr_guid(clsidNew));
|
||||||
sprintf(buf,"CLSID\\");WINE_StringFromCLSID(clsidOld,&buf[6]);
|
sprintf(buf,"CLSID\\");WINE_StringFromCLSID(clsidOld,&buf[6]);
|
||||||
WINE_StringFromCLSID(clsidNew, szClsidNew);
|
WINE_StringFromCLSID(clsidNew, szClsidNew);
|
||||||
|
@ -2541,26 +2541,40 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
switch (pvar->vt & ~VT_VECTOR)
|
if (pvar->vt & VT_VECTOR)
|
||||||
{
|
{
|
||||||
case VT_VARIANT:
|
ULONG i;
|
||||||
FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems);
|
|
||||||
break;
|
switch (pvar->vt & ~VT_VECTOR)
|
||||||
case VT_CF:
|
{
|
||||||
OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems);
|
case VT_VARIANT:
|
||||||
break;
|
FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems);
|
||||||
case VT_BSTR:
|
break;
|
||||||
case VT_LPSTR:
|
case VT_CF:
|
||||||
case VT_LPWSTR:
|
OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems);
|
||||||
case VT_CLSID:
|
break;
|
||||||
FIXME("Freeing of vector sub-type not supported yet\n");
|
case VT_BSTR:
|
||||||
}
|
for (i = 0; i < pvar->u.cabstr.cElems; i++)
|
||||||
if (pvar->vt & ~VT_VECTOR)
|
PropSysFreeString(pvar->u.cabstr.pElems[i]);
|
||||||
{
|
break;
|
||||||
/* pick an arbitary VT_VECTOR structure - they all have the same
|
case VT_LPSTR:
|
||||||
* memory layout */
|
for (i = 0; i < pvar->u.calpstr.cElems; i++)
|
||||||
CoTaskMemFree(pvar->u.capropvar.pElems);
|
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));
|
ZeroMemory(pvar, sizeof(*pvar));
|
||||||
|
@ -2632,7 +2646,9 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
|
||||||
if (pvarSrc->vt & VT_VECTOR)
|
if (pvarSrc->vt & VT_VECTOR)
|
||||||
{
|
{
|
||||||
int elemSize;
|
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_I1: elemSize = sizeof(pvarSrc->u.cVal); break;
|
||||||
case VT_UI1: elemSize = sizeof(pvarSrc->u.bVal); 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_FILETIME: elemSize = sizeof(pvarSrc->u.filetime); break;
|
||||||
case VT_CLSID: elemSize = sizeof(*pvarSrc->u.puuid); break;
|
case VT_CLSID: elemSize = sizeof(*pvarSrc->u.puuid); break;
|
||||||
case VT_CF: elemSize = sizeof(*pvarSrc->u.pclipdata); 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:
|
case VT_VARIANT:
|
||||||
default:
|
default:
|
||||||
FIXME("Invalid element type: %ul\n", pvarSrc->vt & VT_VECTOR);
|
FIXME("Invalid element type: %ul\n", pvarSrc->vt & ~VT_VECTOR);
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
len = pvarSrc->u.capropvar.cElems;
|
len = pvarSrc->u.capropvar.cElems;
|
||||||
pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize);
|
pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize);
|
||||||
if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT))
|
if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT))
|
||||||
{
|
{
|
||||||
ULONG i;
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
PropVariantCopy(&pvarDest->u.capropvar.pElems[i], &pvarSrc->u.capropvar.pElems[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))
|
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))
|
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
|
else
|
||||||
CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize);
|
CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
WARN("Invalid/unsupported type %d\n", pvarSrc->vt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "wine/wingdi16.h"
|
#include "wine/wingdi16.h"
|
||||||
#include "wine/winuser16.h"
|
#include "wine/winuser16.h"
|
||||||
#include "ole32_main.h"
|
|
||||||
#include "ifs.h"
|
#include "ifs.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
1 stub WEP
|
#1 stub WEP
|
||||||
2 stub ROT16_ISRUNNING16
|
2 stub ROT16_ISRUNNING16
|
||||||
3 stub ISWIN32SHANDLE
|
3 stub ISWIN32SHANDLE
|
||||||
4 stub ___EXPORTEDSTUB
|
4 stub ___EXPORTEDSTUB
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
@ stdcall CoInitializeEx(ptr long)
|
@ stdcall CoInitializeEx(ptr long)
|
||||||
@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr)
|
@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr)
|
||||||
@ stdcall CoInitializeWOW(long long)
|
@ stdcall CoInitializeWOW(long long)
|
||||||
@ stub CoIsHandlerConnected #@ stdcall (ptr) return 0,ERR_NOTIMPLEMENTED
|
@ stdcall CoIsHandlerConnected(ptr)
|
||||||
@ stdcall CoIsOle1Class (ptr)
|
@ stdcall CoIsOle1Class (ptr)
|
||||||
@ stdcall CoLoadLibrary(wstr long)
|
@ stdcall CoLoadLibrary(wstr long)
|
||||||
@ stdcall CoLockObjectExternal(ptr long long)
|
@ stdcall CoLockObjectExternal(ptr long long)
|
||||||
|
@ -247,7 +247,7 @@
|
||||||
@ stub STGMEDIUM_UserUnmarshal
|
@ stub STGMEDIUM_UserUnmarshal
|
||||||
@ stub StgOpenAsyncDocfileOnIFillLockBytes
|
@ stub StgOpenAsyncDocfileOnIFillLockBytes
|
||||||
@ stdcall StgOpenStorage(wstr ptr long ptr long ptr)
|
@ 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 StgOpenStorageOnILockBytes(ptr ptr long long long ptr)
|
||||||
@ stdcall StgSetTimes(wstr ptr ptr ptr )
|
@ stdcall StgSetTimes(wstr ptr ptr ptr )
|
||||||
@ stdcall StringFromCLSID(ptr ptr)
|
@ stdcall StringFromCLSID(ptr ptr)
|
||||||
|
|
|
@ -27,13 +27,11 @@
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
#include "ole32_main.h"
|
#include "objbase.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
|
|
||||||
HINSTANCE OLE32_hInstance = 0;
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* OleMetafilePictFromIconAndLabel (OLE32.@)
|
* OleMetafilePictFromIconAndLabel (OLE32.@)
|
||||||
*/
|
*/
|
||||||
|
@ -110,33 +108,3 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
|
||||||
|
|
||||||
return hmem;
|
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;
|
} 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
|
* OleAdviseHolderImpl_Destructor
|
||||||
*/
|
*/
|
||||||
|
@ -357,6 +303,47 @@ OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
|
||||||
return S_OK;
|
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
|
* DataAdviseHolder Implementation
|
||||||
*/
|
*/
|
||||||
|
@ -375,73 +362,6 @@ typedef struct DataAdviseHolder
|
||||||
DataAdviseConnection* Connections;
|
DataAdviseConnection* Connections;
|
||||||
} DataAdviseHolder;
|
} 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
|
* DataAdviseHolder_Destructor
|
||||||
*/
|
*/
|
||||||
|
@ -605,7 +525,7 @@ static HRESULT WINAPI DataAdviseHolder_Advise(
|
||||||
if (This->Connections[index].sink != NULL) {
|
if (This->Connections[index].sink != NULL) {
|
||||||
IAdviseSink_AddRef(This->Connections[index].sink);
|
IAdviseSink_AddRef(This->Connections[index].sink);
|
||||||
if(advf & ADVF_PRIMEFIRST) {
|
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;
|
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
|
* API functions
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "wtypes.h"
|
#include "wtypes.h"
|
||||||
|
|
||||||
#include "compobj_private.h"
|
#include "compobj_private.h"
|
||||||
|
#include "moniker.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
@ -972,10 +973,8 @@ static IPSFactoryBufferVtbl *lppsfac = &psfacbufvtbl;
|
||||||
HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
|
HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
|
||||||
{
|
{
|
||||||
*ppv = NULL;
|
*ppv = NULL;
|
||||||
if (IsEqualIID(rclsid,&CLSID_PSFactoryBuffer)) {
|
if (IsEqualIID(rclsid, &CLSID_PSFactoryBuffer))
|
||||||
*ppv = &lppsfac;
|
return IPSFactoryBuffer_QueryInterface((IPSFactoryBuffer *)&lppsfac, iid, ppv);
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&(
|
if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&(
|
||||||
IsEqualIID(iid,&IID_IClassFactory) ||
|
IsEqualIID(iid,&IID_IClassFactory) ||
|
||||||
IsEqualIID(iid,&IID_IUnknown)
|
IsEqualIID(iid,&IID_IUnknown)
|
||||||
|
@ -984,6 +983,10 @@ HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
|
||||||
return MARSHAL_GetStandardMarshalCF(ppv);
|
return MARSHAL_GetStandardMarshalCF(ppv);
|
||||||
if (IsEqualIID(rclsid,&CLSID_StdGlobalInterfaceTable) && (IsEqualIID(iid,&IID_IClassFactory) || IsEqualIID(iid,&IID_IUnknown)))
|
if (IsEqualIID(rclsid,&CLSID_StdGlobalInterfaceTable) && (IsEqualIID(iid,&IID_IClassFactory) || IsEqualIID(iid,&IID_IUnknown)))
|
||||||
return StdGlobalInterfaceTable_GetFactory(ppv);
|
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));
|
FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
|
||||||
return CLASS_E_CLASSNOTAVAILABLE;
|
return CLASS_E_CLASSNOTAVAILABLE;
|
||||||
|
|
|
@ -30,17 +30,16 @@
|
||||||
* It's a little bit out of date, and more definitive references are given
|
* 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.
|
* below, but it gives the best "big picture" that I've found.
|
||||||
*
|
*
|
||||||
* TODO: There's a lot missing in here. Biggies:
|
* TODO:
|
||||||
* - There are all sorts of restricions I don't honor, like maximum property
|
* - I don't honor the maximum property set size.
|
||||||
* set byte size, maximum property name length
|
|
||||||
* - Certain bogus files could result in reading past the end of a buffer.
|
* - 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
|
* - 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
|
* endian, because I disregard whether the generator was a Mac. This means
|
||||||
* strings will probably be munged (as I don't understand Mac scripts.)
|
* strings will probably be munged (as I don't understand Mac scripts.)
|
||||||
* - Not all PROPVARIANT types are supported.
|
* - 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>
|
#include <assert.h>
|
||||||
|
@ -80,6 +79,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage);
|
||||||
|
|
||||||
#define CP_UNICODE 1200
|
#define CP_UNICODE 1200
|
||||||
|
|
||||||
|
#define MAX_VERSION_0_PROP_NAME_LENGTH 256
|
||||||
|
|
||||||
/* The format version (and what it implies) is described here:
|
/* The format version (and what it implies) is described here:
|
||||||
* http://msdn.microsoft.com/library/en-us/stg/stg/format_version.asp
|
* http://msdn.microsoft.com/library/en-us/stg/stg/format_version.asp
|
||||||
*/
|
*/
|
||||||
|
@ -130,6 +131,22 @@ static HRESULT PropertyStorage_CreateDictionaries(
|
||||||
static void PropertyStorage_DestroyDictionaries(
|
static void PropertyStorage_DestroyDictionaries(
|
||||||
struct tagPropertyStorage_impl *);
|
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;
|
static IPropertyStorageVtbl IPropertyStorage_Vtbl;
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -144,6 +161,7 @@ typedef struct tagPropertyStorage_impl
|
||||||
BOOL dirty;
|
BOOL dirty;
|
||||||
FMTID fmtid;
|
FMTID fmtid;
|
||||||
CLSID clsid;
|
CLSID clsid;
|
||||||
|
WORD format;
|
||||||
DWORD originatorOS;
|
DWORD originatorOS;
|
||||||
DWORD grfFlags;
|
DWORD grfFlags;
|
||||||
DWORD grfMode;
|
DWORD grfMode;
|
||||||
|
@ -235,8 +253,25 @@ static PROPVARIANT *PropertyStorage_FindPropertyByName(
|
||||||
assert(This);
|
assert(This);
|
||||||
if (!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (dictionary_find(This->name_to_propid, name, (void **)&propid))
|
if (This->codePage == CP_UNICODE)
|
||||||
ret = PropertyStorage_FindProperty(This, (PROPID)propid);
|
{
|
||||||
|
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);
|
TRACE("returning %p\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -280,34 +315,169 @@ static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
|
||||||
rgpspec[i].u.lpwstr);
|
rgpspec[i].u.lpwstr);
|
||||||
|
|
||||||
if (prop)
|
if (prop)
|
||||||
PropVariantCopy(&rgpropvar[i], prop);
|
PropertyStorage_PropVariantCopy(&rgpropvar[i], prop, GetACP(),
|
||||||
|
This->codePage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PROPVARIANT *prop = PropertyStorage_FindProperty(This,
|
switch (rgpspec[i].u.propid)
|
||||||
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)
|
if (prop)
|
||||||
PropVariantCopy(&rgpropvar[i], prop);
|
PropertyStorage_PropVariantCopy(&rgpropvar[i], prop,
|
||||||
|
GetACP(), This->codePage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&This->cs);
|
LeaveCriticalSection(&This->cs);
|
||||||
return hr;
|
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,
|
static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
|
||||||
PROPID propid, const PROPVARIANT *propvar)
|
PROPID propid, const PROPVARIANT *propvar, LCID lcid)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
PROPVARIANT *prop = PropertyStorage_FindProperty(This, propid);
|
PROPVARIANT *prop = PropertyStorage_FindProperty(This, propid);
|
||||||
|
|
||||||
assert(This);
|
assert(This);
|
||||||
assert(propvar);
|
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);
|
TRACE("Setting 0x%08lx to type %d\n", propid, propvar->vt);
|
||||||
if (prop)
|
if (prop)
|
||||||
{
|
{
|
||||||
PropVariantClear(prop);
|
PropVariantClear(prop);
|
||||||
PropVariantCopy(prop, propvar);
|
hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
|
||||||
|
lcid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -315,10 +485,16 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
|
||||||
sizeof(PROPVARIANT));
|
sizeof(PROPVARIANT));
|
||||||
if (prop)
|
if (prop)
|
||||||
{
|
{
|
||||||
PropVariantCopy(prop, propvar);
|
hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
|
||||||
dictionary_insert(This->propid_to_prop, (void *)propid, prop);
|
lcid);
|
||||||
if (propid > This->highestProp)
|
if (SUCCEEDED(hr))
|
||||||
This->highestProp = propid;
|
{
|
||||||
|
dictionary_insert(This->propid_to_prop, (void *)propid, prop);
|
||||||
|
if (propid > This->highestProp)
|
||||||
|
This->highestProp = propid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
HeapFree(GetProcessHeap(), 0, prop);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hr = STG_E_INSUFFICIENTMEMORY;
|
hr = STG_E_INSUFFICIENTMEMORY;
|
||||||
|
@ -326,6 +502,43 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
|
||||||
return hr;
|
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)
|
* IPropertyStorage_fnWriteMultiple (IPropertyStorage)
|
||||||
*/
|
*/
|
||||||
|
@ -371,19 +584,12 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PROPID nextId = max(propidNameFirst, This->highestProp + 1);
|
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);
|
hr = PropertyStorage_StoreNameWithId(This,
|
||||||
TRACE("Adding prop name %s, propid %ld\n", debugstr_w(name),
|
(LPCSTR)rgpspec[i].u.lpwstr, CP_UNICODE, nextId);
|
||||||
nextId);
|
if (SUCCEEDED(hr))
|
||||||
dictionary_insert(This->name_to_propid, name,
|
hr = PropertyStorage_StorePropWithId(This, nextId,
|
||||||
(void *)nextId);
|
&rgpropvar[i], GetACP());
|
||||||
dictionary_insert(This->propid_to_name, (void *)nextId,
|
|
||||||
name);
|
|
||||||
hr = PropertyStorage_StorePropWithId(This, nextId,
|
|
||||||
&rgpropvar[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,7 +605,13 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
|
||||||
/* Can only set the code page if nothing else has been set */
|
/* Can only set the code page if nothing else has been set */
|
||||||
if (dictionary_num_entries(This->propid_to_prop) == 0 &&
|
if (dictionary_num_entries(This->propid_to_prop) == 0 &&
|
||||||
rgpropvar[i].vt == VT_I2)
|
rgpropvar[i].vt == VT_I2)
|
||||||
|
{
|
||||||
This->codePage = rgpropvar[i].u.iVal;
|
This->codePage = rgpropvar[i].u.iVal;
|
||||||
|
if (This->codePage == CP_UNICODE)
|
||||||
|
This->grfFlags &= ~PROPSETFLAG_ANSI;
|
||||||
|
else
|
||||||
|
This->grfFlags |= PROPSETFLAG_ANSI;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
hr = STG_E_INVALIDPARAMETER;
|
hr = STG_E_INVALIDPARAMETER;
|
||||||
break;
|
break;
|
||||||
|
@ -419,7 +631,7 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
|
||||||
hr = STG_E_INVALIDPARAMETER;
|
hr = STG_E_INVALIDPARAMETER;
|
||||||
else
|
else
|
||||||
hr = PropertyStorage_StorePropWithId(This,
|
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;
|
hr = S_OK;
|
||||||
EnterCriticalSection(&This->cs);
|
EnterCriticalSection(&This->cs);
|
||||||
This->dirty = TRUE;
|
This->dirty = TRUE;
|
||||||
for (i = 0; i < cpropid; i++)
|
for (i = 0; SUCCEEDED(hr) && i < cpropid; i++)
|
||||||
{
|
{
|
||||||
if (rgpropid[i] != PID_ILLEGAL)
|
if (rgpropid[i] != PID_ILLEGAL)
|
||||||
{
|
hr = PropertyStorage_StoreNameWithId(This, (LPCSTR)rglpwstrName[i],
|
||||||
size_t len = lstrlenW(rglpwstrName[i]) + 1;
|
CP_UNICODE, rgpropid[i]);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
|
if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
|
||||||
IPropertyStorage_Commit(iface, STGC_DEFAULT);
|
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;
|
PropertyStorage_impl *This = (PropertyStorage_impl *)extra;
|
||||||
|
|
||||||
TRACE("(%s, %s)\n", debugstr_w(a), debugstr_w(b));
|
if (This->codePage == CP_UNICODE)
|
||||||
/* FIXME: this assumes property names are always Unicode, but they
|
{
|
||||||
* might be ANSI, depending on whether This->grfFlags & PROPSETFLAG_ANSI
|
TRACE("(%s, %s)\n", debugstr_w(a), debugstr_w(b));
|
||||||
* is true.
|
if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
|
||||||
*/
|
return lstrcmpW((LPCWSTR)a, (LPCWSTR)b);
|
||||||
if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
|
else
|
||||||
return strcmpW((LPCWSTR)a, (LPCWSTR)b);
|
return lstrcmpiW((LPCWSTR)a, (LPCWSTR)b);
|
||||||
|
}
|
||||||
else
|
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)
|
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,
|
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);
|
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
|
/* Reads the dictionary from the memory buffer beginning at ptr. Interprets
|
||||||
* the entries according to the values of This->codePage and This->locale.
|
* 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
|
* FIXME: there isn't any checking whether the read property extends past the
|
||||||
* end of the buffer.
|
* 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,
|
static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
|
||||||
BYTE *ptr)
|
BYTE *ptr)
|
||||||
|
@ -781,49 +1010,24 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
|
||||||
{
|
{
|
||||||
PROPID propid;
|
PROPID propid;
|
||||||
DWORD cbEntry;
|
DWORD cbEntry;
|
||||||
LPWSTR name = NULL;
|
|
||||||
|
|
||||||
StorageUtl_ReadDWord(ptr, 0, &propid);
|
StorageUtl_ReadDWord(ptr, 0, &propid);
|
||||||
ptr += sizeof(PROPID);
|
ptr += sizeof(PROPID);
|
||||||
StorageUtl_ReadDWord(ptr, 0, &cbEntry);
|
StorageUtl_ReadDWord(ptr, 0, &cbEntry);
|
||||||
ptr += sizeof(DWORD);
|
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);
|
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)
|
if (This->codePage != CP_UNICODE)
|
||||||
{
|
ptr[cbEntry - 1] = '\0';
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
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 */
|
/* Unicode entries are padded to DWORD boundaries */
|
||||||
if (cbEntry % sizeof(DWORD))
|
if (cbEntry % sizeof(DWORD))
|
||||||
ptr += sizeof(DWORD) - (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;
|
ptr += sizeof(DWORD) + cbEntry;
|
||||||
}
|
}
|
||||||
return hr;
|
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
|
/* FIXME: there isn't any checking whether the read property extends past the
|
||||||
* end of the buffer.
|
* 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;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
@ -861,10 +1066,12 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
|
||||||
StorageUtl_ReadWord(data, 0, &prop->u.uiVal);
|
StorageUtl_ReadWord(data, 0, &prop->u.uiVal);
|
||||||
TRACE("Read ushort %d\n", prop->u.uiVal);
|
TRACE("Read ushort %d\n", prop->u.uiVal);
|
||||||
break;
|
break;
|
||||||
|
case VT_INT:
|
||||||
case VT_I4:
|
case VT_I4:
|
||||||
StorageUtl_ReadDWord(data, 0, &prop->u.lVal);
|
StorageUtl_ReadDWord(data, 0, &prop->u.lVal);
|
||||||
TRACE("Read long %ld\n", prop->u.lVal);
|
TRACE("Read long %ld\n", prop->u.lVal);
|
||||||
break;
|
break;
|
||||||
|
case VT_UINT:
|
||||||
case VT_UI4:
|
case VT_UI4:
|
||||||
StorageUtl_ReadDWord(data, 0, &prop->u.ulVal);
|
StorageUtl_ReadDWord(data, 0, &prop->u.ulVal);
|
||||||
TRACE("Read ulong %ld\n", 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;
|
DWORD count;
|
||||||
|
|
||||||
StorageUtl_ReadDWord(data, 0, &count);
|
StorageUtl_ReadDWord(data, 0, &count);
|
||||||
prop->u.pszVal = CoTaskMemAlloc(count);
|
if (This->codePage == CP_UNICODE && count / 2)
|
||||||
if (prop->u.pszVal)
|
|
||||||
{
|
{
|
||||||
/* FIXME: if the host is big-endian, this'll suck */
|
WARN("Unicode string has odd number of bytes\n");
|
||||||
memcpy(prop->u.pszVal, data + sizeof(DWORD), count);
|
hr = STG_E_INVALIDHEADER;
|
||||||
/* 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));
|
|
||||||
}
|
}
|
||||||
else
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case VT_LPWSTR:
|
case VT_LPWSTR:
|
||||||
|
@ -896,9 +1122,11 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
|
||||||
prop->u.pwszVal = CoTaskMemAlloc(count * sizeof(WCHAR));
|
prop->u.pwszVal = CoTaskMemAlloc(count * sizeof(WCHAR));
|
||||||
if (prop->u.pwszVal)
|
if (prop->u.pwszVal)
|
||||||
{
|
{
|
||||||
/* FIXME: if the host is big-endian, gotta swap every char */
|
|
||||||
memcpy(prop->u.pwszVal, data + sizeof(DWORD),
|
memcpy(prop->u.pwszVal, data + sizeof(DWORD),
|
||||||
count * sizeof(WCHAR));
|
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));
|
TRACE("Read string value %s\n", debugstr_w(prop->u.pwszVal));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -906,8 +1134,8 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VT_FILETIME:
|
case VT_FILETIME:
|
||||||
/* FIXME: endianness */
|
StorageUtl_ReadULargeInteger(data, 0,
|
||||||
memcpy(&prop->u.filetime, data, sizeof(FILETIME));
|
(ULARGE_INTEGER *)&prop->u.filetime);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("unsupported type %d\n", prop->vt);
|
FIXME("unsupported type %d\n", prop->vt);
|
||||||
|
@ -1068,6 +1296,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
|
||||||
hr = STG_E_INVALIDHEADER;
|
hr = STG_E_INVALIDHEADER;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
This->format = hdr.wFormat;
|
||||||
memcpy(&This->clsid, &hdr.clsid, sizeof(This->clsid));
|
memcpy(&This->clsid, &hdr.clsid, sizeof(This->clsid));
|
||||||
This->originatorOS = hdr.dwOSVer;
|
This->originatorOS = hdr.dwOSVer;
|
||||||
if (PROPSETHDR_OSVER_KIND(hdr.dwOSVer) == PROPSETHDR_OSVER_KIND_MAC)
|
if (PROPSETHDR_OSVER_KIND(hdr.dwOSVer) == PROPSETHDR_OSVER_KIND_MAC)
|
||||||
|
@ -1139,7 +1368,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
|
||||||
{
|
{
|
||||||
PROPVARIANT prop;
|
PROPVARIANT prop;
|
||||||
|
|
||||||
if (SUCCEEDED(PropertyStorage_ReadProperty(&prop,
|
if (SUCCEEDED(PropertyStorage_ReadProperty(This, &prop,
|
||||||
buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER))))
|
buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER))))
|
||||||
{
|
{
|
||||||
TRACE("Read property with ID 0x%08lx, type %d\n",
|
TRACE("Read property with ID 0x%08lx, type %d\n",
|
||||||
|
@ -1157,10 +1386,12 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
|
||||||
case PID_BEHAVIOR:
|
case PID_BEHAVIOR:
|
||||||
if (prop.vt == VT_I4 && prop.u.lVal)
|
if (prop.vt == VT_I4 && prop.u.lVal)
|
||||||
This->grfFlags |= PROPSETFLAG_CASE_SENSITIVE;
|
This->grfFlags |= PROPSETFLAG_CASE_SENSITIVE;
|
||||||
|
/* The format should already be 1, but just in case */
|
||||||
|
This->format = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
hr = PropertyStorage_StorePropWithId(This,
|
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);
|
assert(hdr);
|
||||||
StorageUtl_WriteWord((BYTE *)&hdr->wByteOrder, 0,
|
StorageUtl_WriteWord((BYTE *)&hdr->wByteOrder, 0,
|
||||||
PROPSETHDR_BYTEORDER_MAGIC);
|
PROPSETHDR_BYTEORDER_MAGIC);
|
||||||
/* FIXME: should be able to write format 0 property sets too, depending
|
StorageUtl_WriteWord((BYTE *)&hdr->wFormat, 0, This->format);
|
||||||
* 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_WriteDWord((BYTE *)&hdr->dwOSVer, 0, This->originatorOS);
|
StorageUtl_WriteDWord((BYTE *)&hdr->dwOSVer, 0, This->originatorOS);
|
||||||
StorageUtl_WriteGUID((BYTE *)&hdr->clsid, 0, &This->clsid);
|
StorageUtl_WriteGUID((BYTE *)&hdr->clsid, 0, &This->clsid);
|
||||||
StorageUtl_WriteDWord((BYTE *)&hdr->reserved, 0, 1);
|
StorageUtl_WriteDWord((BYTE *)&hdr->reserved, 0, 1);
|
||||||
|
@ -1274,8 +1501,12 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
|
||||||
if (FAILED(c->hr))
|
if (FAILED(c->hr))
|
||||||
goto end;
|
goto end;
|
||||||
c->bytesWritten += sizeof(DWORD);
|
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);
|
c->hr = IStream_Write(This->stm, key, keyLen, &count);
|
||||||
|
PropertyStorage_ByteSwapString(key, keyLen);
|
||||||
if (FAILED(c->hr))
|
if (FAILED(c->hr))
|
||||||
goto end;
|
goto end;
|
||||||
c->bytesWritten += keyLen;
|
c->bytesWritten += keyLen;
|
||||||
|
@ -1290,35 +1521,17 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int len = WideCharToMultiByte(This->codePage, 0, (LPWSTR)key, -1, NULL,
|
DWORD keyLen;
|
||||||
0, NULL, NULL);
|
|
||||||
LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, len);
|
|
||||||
DWORD dwLen;
|
|
||||||
|
|
||||||
if (!buf)
|
StorageUtl_WriteDWord((LPBYTE)&keyLen, 0, strlen((LPCSTR)key) + 1);
|
||||||
{
|
c->hr = IStream_Write(This->stm, &keyLen, sizeof(keyLen), &count);
|
||||||
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);
|
|
||||||
if (FAILED(c->hr))
|
if (FAILED(c->hr))
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, buf);
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
|
||||||
c->bytesWritten += sizeof(DWORD);
|
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))
|
if (FAILED(c->hr))
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, buf);
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
c->bytesWritten += keyLen;
|
||||||
c->bytesWritten += len;
|
|
||||||
HeapFree(GetProcessHeap(), 0, buf);
|
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
return SUCCEEDED(c->hr);
|
return SUCCEEDED(c->hr);
|
||||||
|
@ -1482,6 +1695,16 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
|
||||||
bytesWritten = count + sizeof(DWORD);
|
bytesWritten = count + sizeof(DWORD);
|
||||||
break;
|
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:
|
default:
|
||||||
FIXME("unsupported type: %d\n", var->vt);
|
FIXME("unsupported type: %d\n", var->vt);
|
||||||
return STG_E_INVALIDPARAMETER;
|
return STG_E_INVALIDPARAMETER;
|
||||||
|
@ -1723,7 +1946,7 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
|
||||||
assert(pps);
|
assert(pps);
|
||||||
assert(rfmtid);
|
assert(rfmtid);
|
||||||
*pps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof **pps);
|
*pps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof **pps);
|
||||||
if (!pps)
|
if (!*pps)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
(*pps)->vtbl = &IPropertyStorage_Vtbl;
|
(*pps)->vtbl = &IPropertyStorage_Vtbl;
|
||||||
|
@ -1734,6 +1957,13 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
|
||||||
(*pps)->grfMode = grfMode;
|
(*pps)->grfMode = grfMode;
|
||||||
|
|
||||||
hr = PropertyStorage_CreateDictionaries(*pps);
|
hr = PropertyStorage_CreateDictionaries(*pps);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
IStream_Release(stm);
|
||||||
|
DeleteCriticalSection(&(*pps)->cs);
|
||||||
|
HeapFree(GetProcessHeap(), 0, *pps);
|
||||||
|
*pps = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -1774,7 +2004,10 @@ static HRESULT PropertyStorage_ConstructEmpty(IStream *stm,
|
||||||
hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
|
hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
ps->format = 0;
|
||||||
ps->grfFlags = grfFlags;
|
ps->grfFlags = grfFlags;
|
||||||
|
if (ps->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
|
||||||
|
ps->format = 1;
|
||||||
/* default to Unicode unless told not to, as specified here:
|
/* default to Unicode unless told not to, as specified here:
|
||||||
* http://msdn.microsoft.com/library/en-us/stg/stg/names_in_istorage.asp
|
* 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 WINAPI PropStgNameToFmtId(const LPOLESTR str, FMTID *rfmtid)
|
||||||
{
|
{
|
||||||
HRESULT hr = E_INVALIDARG;
|
HRESULT hr = STG_E_INVALIDNAME;
|
||||||
|
|
||||||
TRACE("%s, %p\n", debugstr_w(str), rfmtid);
|
TRACE("%s, %p\n", debugstr_w(str), rfmtid);
|
||||||
|
|
||||||
if (!rfmtid) return E_INVALIDARG;
|
if (!rfmtid) return E_INVALIDARG;
|
||||||
if (!str) return E_INVALIDARG;
|
if (!str) return STG_E_INVALIDNAME;
|
||||||
|
|
||||||
if (!lstrcmpiW(str, szDocSummaryInfo))
|
if (!lstrcmpiW(str, szDocSummaryInfo))
|
||||||
{
|
{
|
||||||
|
|
|
@ -296,6 +296,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
|
||||||
StgProperty currentProperty;
|
StgProperty currentProperty;
|
||||||
ULONG foundPropertyIndex;
|
ULONG foundPropertyIndex;
|
||||||
HRESULT res = STG_E_UNKNOWN;
|
HRESULT res = STG_E_UNKNOWN;
|
||||||
|
DWORD parent_grfMode;
|
||||||
|
|
||||||
TRACE("(%p, %s, %p, %lx, %ld, %p)\n",
|
TRACE("(%p, %s, %p, %lx, %ld, %p)\n",
|
||||||
iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm);
|
iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm);
|
||||||
|
@ -334,6 +335,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
|
||||||
goto end;
|
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
|
* Create a property enumeration to search the properties
|
||||||
*/
|
*/
|
||||||
|
@ -412,6 +423,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
|
||||||
StgProperty currentProperty;
|
StgProperty currentProperty;
|
||||||
ULONG foundPropertyIndex;
|
ULONG foundPropertyIndex;
|
||||||
HRESULT res = STG_E_UNKNOWN;
|
HRESULT res = STG_E_UNKNOWN;
|
||||||
|
DWORD parent_grfMode;
|
||||||
|
|
||||||
TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n",
|
TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n",
|
||||||
iface, debugstr_w(pwcsName), pstgPriority,
|
iface, debugstr_w(pwcsName), pstgPriority,
|
||||||
|
@ -453,6 +465,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
|
||||||
goto end;
|
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
|
* Initialize the out parameter
|
||||||
*/
|
*/
|
||||||
|
@ -489,6 +511,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
|
||||||
*/
|
*/
|
||||||
newStorage = StorageInternalImpl_Construct(
|
newStorage = StorageInternalImpl_Construct(
|
||||||
This->ancestorStorage,
|
This->ancestorStorage,
|
||||||
|
grfMode,
|
||||||
foundPropertyIndex);
|
foundPropertyIndex);
|
||||||
|
|
||||||
if (newStorage != 0)
|
if (newStorage != 0)
|
||||||
|
@ -804,6 +827,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
|
||||||
StgStreamImpl* newStream;
|
StgStreamImpl* newStream;
|
||||||
StgProperty currentProperty, newStreamProperty;
|
StgProperty currentProperty, newStreamProperty;
|
||||||
ULONG foundPropertyIndex, newPropertyIndex;
|
ULONG foundPropertyIndex, newPropertyIndex;
|
||||||
|
DWORD parent_grfMode;
|
||||||
|
|
||||||
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
|
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
|
||||||
iface, debugstr_w(pwcsName), grfMode,
|
iface, debugstr_w(pwcsName), grfMode,
|
||||||
|
@ -837,6 +861,13 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
|
||||||
(grfMode & STGM_TRANSACTED))
|
(grfMode & STGM_TRANSACTED))
|
||||||
return STG_E_INVALIDFUNCTION;
|
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
|
* Initialize the out parameter
|
||||||
*/
|
*/
|
||||||
|
@ -1005,6 +1036,7 @@ HRESULT WINAPI StorageImpl_CreateStorage(
|
||||||
ULONG foundPropertyIndex;
|
ULONG foundPropertyIndex;
|
||||||
ULONG newPropertyIndex;
|
ULONG newPropertyIndex;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
DWORD parent_grfMode;
|
||||||
|
|
||||||
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
|
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
|
||||||
iface, debugstr_w(pwcsName), grfMode,
|
iface, debugstr_w(pwcsName), grfMode,
|
||||||
|
@ -1026,6 +1058,13 @@ HRESULT WINAPI StorageImpl_CreateStorage(
|
||||||
(grfMode & STGM_DELETEONRELEASE) )
|
(grfMode & STGM_DELETEONRELEASE) )
|
||||||
return STG_E_INVALIDFLAG;
|
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
|
* Initialize the out parameter
|
||||||
*/
|
*/
|
||||||
|
@ -2186,6 +2225,7 @@ HRESULT StorageImpl_Construct(
|
||||||
This->base.lpVtbl = &Storage32Impl_Vtbl;
|
This->base.lpVtbl = &Storage32Impl_Vtbl;
|
||||||
This->base.pssVtbl = &IPropertySetStorage_Vtbl;
|
This->base.pssVtbl = &IPropertySetStorage_Vtbl;
|
||||||
This->base.v_destructor = &StorageImpl_Destroy;
|
This->base.v_destructor = &StorageImpl_Destroy;
|
||||||
|
This->base.openFlags = openFlags;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the top-level storage so initialize the ancestor pointer
|
* This is the top-level storage so initialize the ancestor pointer
|
||||||
|
@ -2379,7 +2419,7 @@ void StorageImpl_Destroy(StorageBaseImpl* iface)
|
||||||
BlockChainStream_Destroy(This->smallBlockDepotChain);
|
BlockChainStream_Destroy(This->smallBlockDepotChain);
|
||||||
|
|
||||||
BIGBLOCKFILE_Destructor(This->bigBlockFile);
|
BIGBLOCKFILE_Destructor(This->bigBlockFile);
|
||||||
return;
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -4013,7 +4053,8 @@ static IStorageVtbl Storage32InternalImpl_Vtbl =
|
||||||
|
|
||||||
StorageInternalImpl* StorageInternalImpl_Construct(
|
StorageInternalImpl* StorageInternalImpl_Construct(
|
||||||
StorageImpl* ancestorStorage,
|
StorageImpl* ancestorStorage,
|
||||||
ULONG rootPropertyIndex)
|
DWORD openFlags,
|
||||||
|
ULONG rootPropertyIndex)
|
||||||
{
|
{
|
||||||
StorageInternalImpl* newStorage;
|
StorageInternalImpl* newStorage;
|
||||||
|
|
||||||
|
@ -4031,6 +4072,7 @@ StorageInternalImpl* StorageInternalImpl_Construct(
|
||||||
*/
|
*/
|
||||||
newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl;
|
newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl;
|
||||||
newStorage->base.v_destructor = &StorageInternalImpl_Destroy;
|
newStorage->base.v_destructor = &StorageInternalImpl_Destroy;
|
||||||
|
newStorage->base.openFlags = openFlags;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep the ancestor storage pointer and nail a reference to it.
|
* Keep the ancestor storage pointer and nail a reference to it.
|
||||||
|
@ -4051,30 +4093,64 @@ StorageInternalImpl* StorageInternalImpl_Construct(
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
** StorageUtl implementation
|
** 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)
|
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)
|
void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value)
|
||||||
{
|
{
|
||||||
|
value = htole16(value);
|
||||||
memcpy(buffer+offset, &value, sizeof(WORD));
|
memcpy(buffer+offset, &value, sizeof(WORD));
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value)
|
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)
|
void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value)
|
||||||
{
|
{
|
||||||
|
value = htole32(value);
|
||||||
memcpy(buffer+offset, &value, sizeof(DWORD));
|
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)
|
void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value)
|
||||||
{
|
{
|
||||||
StorageUtl_ReadDWord(buffer, offset, &(value->Data1));
|
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),
|
TRACE("(%s, %lx, %lx, %lx, %p, %p, %p, %p)\n", debugstr_w(pwcsName),
|
||||||
grfMode, stgfmt, grfAttrs, pStgOptions, reserved, riid, ppObjectOpen);
|
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;
|
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.@]
|
* StgOpenStorage [OLE32.@]
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
|
#include "winreg.h"
|
||||||
|
#include "winternl.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definitions for the file format offsets.
|
* Definitions for the file format offsets.
|
||||||
|
@ -237,6 +239,11 @@ struct StorageBaseImpl
|
||||||
* virtual Destructor method.
|
* virtual Destructor method.
|
||||||
*/
|
*/
|
||||||
void (*v_destructor)(StorageBaseImpl*);
|
void (*v_destructor)(StorageBaseImpl*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flags that this storage was opened or created with
|
||||||
|
*/
|
||||||
|
DWORD openFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,6 +404,7 @@ struct StorageInternalImpl
|
||||||
*/
|
*/
|
||||||
StorageInternalImpl* StorageInternalImpl_Construct(
|
StorageInternalImpl* StorageInternalImpl_Construct(
|
||||||
StorageImpl* ancestorStorage,
|
StorageImpl* ancestorStorage,
|
||||||
|
DWORD openFlags,
|
||||||
ULONG rootTropertyIndex);
|
ULONG rootTropertyIndex);
|
||||||
|
|
||||||
void StorageInternalImpl_Destroy(
|
void StorageInternalImpl_Destroy(
|
||||||
|
@ -524,15 +532,38 @@ StgStreamImpl* StgStreamImpl_Construct(
|
||||||
ULONG ownerProperty);
|
ULONG ownerProperty);
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************
|
/******************************************************************************
|
||||||
* The StorageUtl_ functions are miscelaneous utility functions. Most of which are
|
* Endian conversion macros
|
||||||
* abstractions used to read values from file buffers without having to worry
|
*/
|
||||||
* about bit order
|
#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_ReadWord(const BYTE* buffer, ULONG offset, WORD* value);
|
||||||
void StorageUtl_WriteWord(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_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value);
|
||||||
void StorageUtl_WriteDWord(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_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value);
|
||||||
void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
|
void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
|
||||||
void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination,
|
void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination,
|
||||||
|
|
|
@ -50,6 +50,10 @@
|
||||||
#define STG_LAYOUT_INTERLEAVED 1
|
#define STG_LAYOUT_INTERLEAVED 1
|
||||||
#define COM_RIGHTS_EXECUTE 1
|
#define COM_RIGHTS_EXECUTE 1
|
||||||
#define COM_RIGHTS_SAFE_FOR_SCRIPTING 2
|
#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 {
|
typedef enum tagREGCLS {
|
||||||
REGCLS_SINGLEUSE = 0,
|
REGCLS_SINGLEUSE = 0,
|
||||||
REGCLS_MULTIPLEUSE = 1,
|
REGCLS_MULTIPLEUSE = 1,
|
||||||
|
|
Loading…
Reference in a new issue