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:
Gé van Geldorp 2005-05-28 09:30:04 +00:00
parent dde52a04c5
commit 8eff322fdd
25 changed files with 2748 additions and 1652 deletions

View file

@ -4,6 +4,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = ole32.dll
IMPORTLIB = libole32.$(IMPLIBEXT)
IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll
EXTRALIBS = -luuid $(LIBUNICODE)

View file

@ -66,7 +66,6 @@
#include "wownt32.h"
#include "wine/unicode.h"
#include "objbase.h"
#include "ole32_main.h"
#include "compobj_private.h"
#include "wine/debug.h"
@ -75,6 +74,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
typedef LPCSTR LPCOLESTR16;
HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */
/****************************************************************************
* This section defines variables internal to the COM module.
*
@ -169,7 +170,7 @@ static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LP
static void COMPOBJ_DLLList_Add(HANDLE hLibrary);
static void COMPOBJ_DllList_FreeUnused(int Timeout);
void COMPOBJ_InitProcess( void )
static void COMPOBJ_InitProcess( void )
{
WNDCLASSW wclass;
@ -189,12 +190,12 @@ void COMPOBJ_InitProcess( void )
RegisterClassW(&wclass);
}
void COMPOBJ_UninitProcess( void )
static void COMPOBJ_UninitProcess( void )
{
UnregisterClassW(wszAptWinClass, OLE32_hInstance);
}
void COM_TlsDestroy()
static void COM_TlsDestroy()
{
struct oletls *info = NtCurrentTeb()->ReservedForOle;
if (info)
@ -624,7 +625,7 @@ HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
/* On COM finalization for a STA thread, the message queue is flushed to ensure no
pending RPCs are ignored. Non-COM messages are discarded at this point.
*/
void COM_FlushMessageQueue(void)
static void COM_FlushMessageQueue(void)
{
MSG message;
APARTMENT *apt = COM_CurrentApt();
@ -1531,7 +1532,8 @@ end:
*
* Reads a registry value and expands it when necessary
*/
HRESULT compobj_RegReadPath(char * keyname, char * valuename, char * dst, DWORD dstlen)
static HRESULT
compobj_RegReadPath(char * keyname, char * valuename, char * dst, DWORD dstlen)
{
HRESULT hres;
HKEY key;
@ -2425,6 +2427,25 @@ ULONG WINAPI CoReleaseServerProcess(void)
return 1;
}
/***********************************************************************
* CoIsHandlerConnected [OLE32.@]
*
* Determines whether a proxy is connected to a remote stub.
*
* PARAMS
* pUnk [I] Pointer to object that may or may not be connected.
*
* RETURNS
* TRUE if pUnk is not a proxy or if pUnk is connected to a remote stub, or
* FALSE otherwise.
*/
BOOL WINAPI CoIsHandlerConnected(IUnknown *pUnk)
{
FIXME("%p\n", pUnk);
return TRUE;
}
/***********************************************************************
* CoQueryProxyBlanket [OLE32.@]
*
@ -2635,3 +2656,32 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
TRACE("-- 0x%08lx\n", hr);
return hr;
}
/***********************************************************************
* DllMain (OLE32.@)
*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
{
TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
OLE32_hInstance = hinstDLL;
COMPOBJ_InitProcess();
if (TRACE_ON(ole)) CoRegisterMallocSpy((LPVOID)-1);
break;
case DLL_PROCESS_DETACH:
if (TRACE_ON(ole)) CoRevokeMallocSpy();
COMPOBJ_UninitProcess();
OLE32_hInstance = 0;
break;
case DLL_THREAD_DETACH:
COM_TlsDestroy();
break;
}
return TRUE;
}
/* NOTE: DllRegisterServer and DllUnregisterServer are in regsvr.c */

View file

@ -203,7 +203,7 @@ HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
HRESULT WINAPI RunningObjectTableImpl_UnInitialize(void);
/* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
/* Apartment Functions */
@ -254,4 +254,6 @@ static inline APARTMENT* COM_CurrentApt(void)
# define DEBUG_CLEAR_CRITSEC_NAME(cs)
#endif
extern HINSTANCE OLE32_hInstance; /* FIXME: make static */
#endif /* __WINE_OLE_COMPOBJ_H */

View file

@ -616,9 +616,36 @@ CompositeMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
static HRESULT WINAPI
CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
FIXME("(),stub!\n");
IEnumMoniker *enumMoniker;
IMoniker *tempMk;
HRESULT res;
DWORD tempHash;
return E_NOTIMPL;
TRACE("(%p,%p)\n",iface,pdwHash);
if (pdwHash==NULL)
return E_POINTER;
res = IMoniker_Enum(iface,TRUE,&enumMoniker);
if(FAILED(res))
return res;
while(1){
res=IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL);
if(FAILED(res))
break;
res = IMoniker_Hash(tempMk, &tempHash);
if(FAILED(res))
break;
*pdwHash = (*pdwHash * 37) + tempHash;
IMoniker_Release(tempMk);
}
IEnumMoniker_Release(enumMoniker);
return res;
}
/******************************************************************************

View file

@ -1,7 +1,7 @@
/***************************************************************************************
* FileMonikers implementation
/*
* FileMonikers implementation
*
* Copyright 1999 Noomen Hamza
* Copyright 1999 Noomen Hamza
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -16,7 +16,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************************/
*/
#include <assert.h>
#include <stdarg.h>
@ -57,114 +57,29 @@ typedef struct FileMonikerImpl{
LPOLESTR filePathName; /* path string identified by this filemoniker */
IUnknown *pMarshal; /* custom marshaler */
} FileMonikerImpl;
/********************************************************************************/
/* FileMoniker prototype functions : */
/* IUnknown prototype functions */
static HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
static ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface);
static ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface);
/* IPersist prototype functions */
static HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
/* IPersistStream prototype functions */
static HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface);
static HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface, IStream* pStm);
static HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
static HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
/* IMoniker prototype functions */
static HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
static HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
static HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
static HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
static HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
static HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
static HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
static HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
static HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pFileTime);
static HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
static HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
static HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
static HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
static HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
static HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
/********************************************************************************/
/* IROTData prototype functions */
/* IUnknown prototype functions */
static HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
static ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData* iface);
static ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface);
/* IROTData prototype function */
static HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
/* Local function used by filemoniker implementation */
HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface);
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** tabStr);
/********************************************************************************/
/* Virtual function table for the FileMonikerImpl class which include IPersist,*/
/* IPersistStream and IMoniker functions. */
static IMonikerVtbl VT_FileMonikerImpl =
{
FileMonikerImpl_QueryInterface,
FileMonikerImpl_AddRef,
FileMonikerImpl_Release,
FileMonikerImpl_GetClassID,
FileMonikerImpl_IsDirty,
FileMonikerImpl_Load,
FileMonikerImpl_Save,
FileMonikerImpl_GetSizeMax,
FileMonikerImpl_BindToObject,
FileMonikerImpl_BindToStorage,
FileMonikerImpl_Reduce,
FileMonikerImpl_ComposeWith,
FileMonikerImpl_Enum,
FileMonikerImpl_IsEqual,
FileMonikerImpl_Hash,
FileMonikerImpl_IsRunning,
FileMonikerImpl_GetTimeOfLastChange,
FileMonikerImpl_Inverse,
FileMonikerImpl_CommonPrefixWith,
FileMonikerImpl_RelativePathTo,
FileMonikerImpl_GetDisplayName,
FileMonikerImpl_ParseDisplayName,
FileMonikerImpl_IsSystemMoniker
};
/********************************************************************************/
/* Virtual function table for the IROTData class. */
static IROTDataVtbl VT_ROTDataImpl =
{
FileMonikerROTDataImpl_QueryInterface,
FileMonikerROTDataImpl_AddRef,
FileMonikerROTDataImpl_Release,
FileMonikerROTDataImpl_GetComparaisonData
};
static HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
static HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface);
/*******************************************************************************
* FileMoniker_QueryInterface
*******************************************************************************/
HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
*/
static HRESULT WINAPI
FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
/* Perform a sanity check on the parameters.*/
if ( (This==0) || (ppvObject==0) )
return E_INVALIDARG;
/* Initialize the return parameter */
*ppvObject = 0;
*ppvObject = 0;
/* Compare the riid with the interface IDs implemented by this object.*/
if (IsEqualIID(&IID_IUnknown, riid) ||
@ -176,21 +91,31 @@ HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
else if (IsEqualIID(&IID_IROTData, riid))
*ppvObject = (IROTData*)&(This->lpvtbl2);
else if (IsEqualIID(&IID_IMarshal, riid))
{
HRESULT hr = S_OK;
if (!This->pMarshal)
hr = MonikerMarshal_Create(iface, &This->pMarshal);
if (hr != S_OK)
return hr;
return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
}
/* Check that we obtained an interface.*/
if ((*ppvObject)==0)
return E_NOINTERFACE;
/* Query Interface always increases the reference count by one when it is successful */
FileMonikerImpl_AddRef(iface);
IMoniker_AddRef(iface);
return S_OK;
}
/******************************************************************************
* FileMoniker_AddRef
******************************************************************************/
ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface)
*/
static ULONG WINAPI
FileMonikerImpl_AddRef(IMoniker* iface)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
@ -201,8 +126,9 @@ ULONG WINAPI FileMonikerImpl_AddRef(IMoniker* iface)
/******************************************************************************
* FileMoniker_Release
******************************************************************************/
ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface)
*/
static ULONG WINAPI
FileMonikerImpl_Release(IMoniker* iface)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
ULONG ref;
@ -219,9 +145,9 @@ ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface)
/******************************************************************************
* FileMoniker_GetClassID
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface,
CLSID *pClassID)/* Pointer to CLSID of object */
*/
static HRESULT WINAPI
FileMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID)
{
TRACE("(%p,%p)\n",iface,pClassID);
@ -235,12 +161,14 @@ HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface,
/******************************************************************************
* FileMoniker_IsDirty
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface)
*
* Note that the OLE-provided implementations of the IPersistStream::IsDirty
* method in the OLE-provided moniker interfaces always return S_FALSE because
* their internal state never changes.
*/
static HRESULT WINAPI
FileMonikerImpl_IsDirty(IMoniker* iface)
{
/* Note that the OLE-provided implementations of the IPersistStream::IsDirty
method in the OLE-provided moniker interfaces always return S_FALSE because
their internal state never changes. */
TRACE("(%p)\n",iface);
@ -249,8 +177,12 @@ HRESULT WINAPI FileMonikerImpl_IsDirty(IMoniker* iface)
/******************************************************************************
* FileMoniker_Load
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
*
* this function locates and reads from the stream the filePath string
* written by FileMonikerImpl_Save
*/
static HRESULT WINAPI
FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{
HRESULT res;
CHAR* filePathA;
@ -263,36 +195,49 @@ HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
TRACE("(%p,%p)\n",iface,pStm);
/* this function locates and reads from the stream the filePath string written by FileMonikerImpl_Save */
/* first WORD is non significative */
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
if (bread!=sizeof(WORD) || wbuffer!=0)
{
ERR("Couldn't read 0 word\n");
return E_FAIL;
}
/* read filePath string length (plus one) */
res=IStream_Read(pStm,&length,sizeof(DWORD),&bread);
if (bread != sizeof(DWORD))
{
ERR("Couldn't read file string length\n");
return E_FAIL;
}
/* read filePath string */
filePathA=HeapAlloc(GetProcessHeap(),0,length);
res=IStream_Read(pStm,filePathA,length,&bread);
HeapFree(GetProcessHeap(),0,filePathA);
if (bread != length)
{
ERR("Couldn't read file path string\n");
return E_FAIL;
}
/* read the first constant */
IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
{
ERR("Couldn't read 0xDEADFFFF constant\n");
return E_FAIL;
}
length--;
for(i=0;i<10;i++){
res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
if (bread!=sizeof(WORD) || wbuffer!=0)
{
ERR("Couldn't read 0 padding\n");
return E_FAIL;
}
}
if (length>8)
@ -334,30 +279,28 @@ HRESULT WINAPI FileMonikerImpl_Load(IMoniker* iface,IStream* pStm)
/******************************************************************************
* FileMoniker_Save
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface,
IStream* pStm,/* pointer to the stream where the object is to be saved */
BOOL fClearDirty)/* Specifies whether to clear the dirty flag */
*
* This function saves data of this object. In the beginning I thougth
* that I have just to write the filePath string on Stream. But, when I
* tested this function whith windows programs samples, I noticed that it
* was not the case. So I analysed data written by this function on
* Windows and what this did function exactly ! But I have no idea about
* its logic !
* I guessed data which must be written on stream is:
* 1) WORD constant:zero
* 2) length of the path string ("\0" included)
* 3) path string type A
* 4) DWORD constant : 0xDEADFFFF
* 5) ten WORD constant: zero
* 6) DWORD: double-length of the the path string type W ("\0" not
* included)
* 7) WORD constant: 0x3
* 8) filePath unicode string.
* if the length(filePath) > 8 or length(filePath) == 8 stop at step 5)
*/
static HRESULT WINAPI
FileMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
{
/* this function saves data of this object. In the beginning I thougth
* that I have just to write the filePath string on Stream. But, when I
* tested this function whith windows programs samples, I noticed that it
* was not the case. So I analysed data written by this function on
* Windows and what this did function exactly ! But I have no idea about
* its logic !
* I guessed data which must be written on stream is:
* 1) WORD constant:zero
* 2) length of the path string ("\0" included)
* 3) path string type A
* 4) DWORD constant : 0xDEADFFFF
* 5) ten WORD constant: zero
* 6) DWORD: double-length of the the path string type W ("\0" not
* included)
* 7) WORD constant: 0x3
* 8) filePath unicode string.
* if the length(filePath) > 8 or length(filePath) == 8 stop at step 5)
*/
FileMonikerImpl *This = (FileMonikerImpl *)iface;
HRESULT res;
@ -426,9 +369,9 @@ HRESULT WINAPI FileMonikerImpl_Save(IMoniker* iface,
/******************************************************************************
* FileMoniker_GetSizeMax
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
*/
static HRESULT WINAPI
FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
DWORD len=lstrlenW(This->filePathName);
@ -436,7 +379,7 @@ HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
TRACE("(%p,%p)\n",iface,pcbSize);
if (pcbSize!=NULL)
if (!pcbSize)
return E_POINTER;
/* for more details see FileMonikerImpl_Save coments */
@ -461,77 +404,6 @@ HRESULT WINAPI FileMonikerImpl_GetSizeMax(IMoniker* iface,
return S_OK;
}
/******************************************************************************
* FileMoniker_Construct (local function)
*******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPathName)
{
int nb=0,i;
int sizeStr=lstrlenW(lpszPathName);
LPOLESTR *tabStr=0;
static const WCHAR twoPoint[]={'.','.',0};
static const WCHAR bkSlash[]={'\\',0};
BYTE addBkSlash;
TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName));
/* Initialize the virtual fgunction table. */
This->lpvtbl1 = &VT_FileMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->filePathName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr+1));
if (This->filePathName==NULL)
return E_OUTOFMEMORY;
strcpyW(This->filePathName,lpszPathName);
nb=FileMonikerImpl_DecomposePath(This->filePathName,&tabStr);
if (nb > 0 ){
addBkSlash=1;
if (lstrcmpW(tabStr[0],twoPoint)!=0)
addBkSlash=0;
else
for(i=0;i<nb;i++){
if ( (lstrcmpW(tabStr[i],twoPoint)!=0) && (lstrcmpW(tabStr[i],bkSlash)!=0) ){
addBkSlash=0;
break;
}
else
if (lstrcmpW(tabStr[i],bkSlash)==0 && i<nb-1 && lstrcmpW(tabStr[i+1],bkSlash)==0){
*tabStr[i]=0;
sizeStr--;
addBkSlash=0;
break;
}
}
if (lstrcmpW(tabStr[nb-1],bkSlash)==0)
addBkSlash=0;
This->filePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR));
*This->filePathName=0;
for(i=0;tabStr[i]!=NULL;i++)
strcatW(This->filePathName,tabStr[i]);
if (addBkSlash)
strcatW(This->filePathName,bkSlash);
}
for(i=0; tabStr[i]!=NULL;i++)
CoTaskMemFree(tabStr[i]);
CoTaskMemFree(tabStr);
return S_OK;
}
/******************************************************************************
* FileMoniker_Destroy (local function)
*******************************************************************************/
@ -539,6 +411,7 @@ HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This)
{
TRACE("(%p)\n",This);
if (This->pMarshal) IUnknown_Release(This->pMarshal);
HeapFree(GetProcessHeap(),0,This->filePathName);
HeapFree(GetProcessHeap(),0,This);
@ -547,12 +420,10 @@ HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This)
/******************************************************************************
* FileMoniker_BindToObject
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
*/
static HRESULT WINAPI
FileMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
REFIID riid, VOID** ppvResult)
{
HRESULT res=E_FAIL;
CLSID clsID;
@ -662,12 +533,10 @@ HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,
/******************************************************************************
* FileMoniker_BindToStorage
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvObject)
*/
static HRESULT WINAPI
FileMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
REFIID riid, VOID** ppvObject)
{
LPOLESTR filePath=0;
IStorage *pstg=0;
@ -680,7 +549,7 @@ HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
if (IsEqualIID(&IID_IStorage, riid)){
/* get the file name */
FileMonikerImpl_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
IMoniker_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
/* verifie if the file contains a storage object */
res=StgIsStorageFile(filePath);
@ -718,30 +587,28 @@ HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
/******************************************************************************
* FileMoniker_Reduce
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Reduce(IMoniker* iface,
IBindCtx* pbc,
DWORD dwReduceHowFar,
IMoniker** ppmkToLeft,
IMoniker** ppmkReduced)
static HRESULT WINAPI
FileMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
FileMonikerImpl_AddRef(iface);
IMoniker_AddRef(iface);
*ppmkReduced=iface;
return MK_S_REDUCED_TO_SELF;
}
/******************************************************************************
* FileMoniker_ComposeWith
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric,
IMoniker** ppmkComposite)
*/
static HRESULT WINAPI
FileMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
{
HRESULT res;
LPOLESTR str1=0,str2=0,*strDec1=0,*strDec2=0,newStr=0;
@ -768,7 +635,7 @@ HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
CreateBindCtx(0,&bind);
FileMonikerImpl_GetDisplayName(iface,bind,NULL,&str1);
IMoniker_GetDisplayName(iface,bind,NULL,&str1);
IMoniker_GetDisplayName(pmkRight,bind,NULL,&str2);
/* decompose pathnames of the two monikers : (to prepare the path merge operation ) */
@ -838,8 +705,9 @@ HRESULT WINAPI FileMonikerImpl_ComposeWith(IMoniker* iface,
/******************************************************************************
* FileMoniker_Enum
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
*/
static HRESULT WINAPI
FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
@ -853,8 +721,9 @@ HRESULT WINAPI FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker*
/******************************************************************************
* FileMoniker_IsEqual
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
*/
static HRESULT WINAPI
FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
CLSID clsid;
@ -886,8 +755,9 @@ HRESULT WINAPI FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker
/******************************************************************************
* FileMoniker_Hash
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
*/
static HRESULT WINAPI
FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
@ -920,11 +790,10 @@ HRESULT WINAPI FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
/******************************************************************************
* FileMoniker_IsRunning
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning)
*/
static HRESULT WINAPI
FileMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning)
{
IRunningObjectTable* rot;
HRESULT res;
@ -952,10 +821,9 @@ HRESULT WINAPI FileMonikerImpl_IsRunning(IMoniker* iface,
/******************************************************************************
* FileMoniker_GetTimeOfLastChange
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
FILETIME* pFileTime)
static HRESULT WINAPI
FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, FILETIME* pFileTime)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
IRunningObjectTable* rot;
@ -990,10 +858,10 @@ HRESULT WINAPI FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
/******************************************************************************
* FileMoniker_Inverse
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
*/
static HRESULT WINAPI
FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
{
TRACE("(%p,%p)\n",iface,ppmk);
return CreateAntiMoniker(ppmk);
@ -1001,8 +869,9 @@ HRESULT WINAPI FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
/******************************************************************************
* FileMoniker_CommonPrefixWith
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
*/
static HRESULT WINAPI
FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath;
@ -1089,8 +958,8 @@ HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOth
/******************************************************************************
* DecomposePath (local function)
******************************************************************************/
int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
*/
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
{
static const WCHAR bSlash[] = {'\\',0};
WCHAR word[MAX_PATH];
@ -1144,8 +1013,9 @@ int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
/******************************************************************************
* FileMoniker_RelativePathTo
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
*/
static HRESULT WINAPI
FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
IBindCtx *bind;
HRESULT res;
@ -1219,11 +1089,10 @@ HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther,
/******************************************************************************
* FileMoniker_GetDisplayName
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR *ppszDisplayName)
*/
static HRESULT WINAPI
FileMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
@ -1250,13 +1119,10 @@ HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,
/******************************************************************************
* FileMoniker_ParseDisplayName
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR pszDisplayName,
ULONG* pchEaten,
IMoniker** ppmkOut)
*/
static HRESULT WINAPI
FileMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
{
FIXME("(%p,%p,%p,%p,%p,%p),stub!\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
return E_NOTIMPL;
@ -1264,8 +1130,9 @@ HRESULT WINAPI FileMonikerImpl_ParseDisplayName(IMoniker* iface,
/******************************************************************************
* FileMoniker_IsSystemMoniker
******************************************************************************/
HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
*/
static HRESULT WINAPI
FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
TRACE("(%p,%p)\n",iface,pwdMksys);
@ -1279,8 +1146,9 @@ HRESULT WINAPI FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
/*******************************************************************************
* FileMonikerIROTData_QueryInterface
*******************************************************************************/
HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
*/
static HRESULT WINAPI
FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
{
ICOM_THIS_From_IROTData(IMoniker, iface);
@ -1293,19 +1161,21 @@ HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid
/***********************************************************************
* FileMonikerIROTData_AddRef
*/
ULONG WINAPI FileMonikerROTDataImpl_AddRef(IROTData *iface)
static ULONG WINAPI
FileMonikerROTDataImpl_AddRef(IROTData *iface)
{
ICOM_THIS_From_IROTData(IMoniker, iface);
TRACE("(%p)\n",This);
return FileMonikerImpl_AddRef(This);
return IMoniker_AddRef(This);
}
/***********************************************************************
* FileMonikerIROTData_Release
*/
ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface)
static ULONG WINAPI
FileMonikerROTDataImpl_Release(IROTData* iface)
{
ICOM_THIS_From_IROTData(IMoniker, iface);
@ -1316,14 +1186,142 @@ ULONG WINAPI FileMonikerROTDataImpl_Release(IROTData* iface)
/******************************************************************************
* FileMonikerIROTData_GetComparaisonData
******************************************************************************/
HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
BYTE* pbData,
ULONG cbMax,
ULONG* pcbData)
*/
static HRESULT WINAPI
FileMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
ULONG cbMax, ULONG* pcbData)
{
FIXME("(),stub!\n");
return E_NOTIMPL;
ICOM_THIS_From_IROTData(IMoniker, iface);
FileMonikerImpl *This1 = (FileMonikerImpl *)This;
int len = (strlenW(This1->filePathName)+1);
int i;
LPWSTR pszFileName;
TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID) + len * sizeof(WCHAR);
if (cbMax < *pcbData)
return E_OUTOFMEMORY;
memcpy(pbData, &CLSID_FileMoniker, sizeof(CLSID));
pszFileName = (LPWSTR)(pbData+sizeof(CLSID));
for (i = 0; i < len; i++)
pszFileName[i] = toupperW(This1->filePathName[i]);
return S_OK;
}
/*
* Virtual function table for the FileMonikerImpl class which include IPersist,
* IPersistStream and IMoniker functions.
*/
static IMonikerVtbl VT_FileMonikerImpl =
{
FileMonikerImpl_QueryInterface,
FileMonikerImpl_AddRef,
FileMonikerImpl_Release,
FileMonikerImpl_GetClassID,
FileMonikerImpl_IsDirty,
FileMonikerImpl_Load,
FileMonikerImpl_Save,
FileMonikerImpl_GetSizeMax,
FileMonikerImpl_BindToObject,
FileMonikerImpl_BindToStorage,
FileMonikerImpl_Reduce,
FileMonikerImpl_ComposeWith,
FileMonikerImpl_Enum,
FileMonikerImpl_IsEqual,
FileMonikerImpl_Hash,
FileMonikerImpl_IsRunning,
FileMonikerImpl_GetTimeOfLastChange,
FileMonikerImpl_Inverse,
FileMonikerImpl_CommonPrefixWith,
FileMonikerImpl_RelativePathTo,
FileMonikerImpl_GetDisplayName,
FileMonikerImpl_ParseDisplayName,
FileMonikerImpl_IsSystemMoniker
};
/* Virtual function table for the IROTData class. */
static IROTDataVtbl VT_ROTDataImpl =
{
FileMonikerROTDataImpl_QueryInterface,
FileMonikerROTDataImpl_AddRef,
FileMonikerROTDataImpl_Release,
FileMonikerROTDataImpl_GetComparisonData
};
/******************************************************************************
* FileMoniker_Construct (local function)
*/
static HRESULT WINAPI
FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPathName)
{
int nb=0,i;
int sizeStr=lstrlenW(lpszPathName);
LPOLESTR *tabStr=0;
static const WCHAR twoPoint[]={'.','.',0};
static const WCHAR bkSlash[]={'\\',0};
BYTE addBkSlash;
TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName));
/* Initialize the virtual fgunction table. */
This->lpvtbl1 = &VT_FileMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->pMarshal = NULL;
This->filePathName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr+1));
if (This->filePathName==NULL)
return E_OUTOFMEMORY;
strcpyW(This->filePathName,lpszPathName);
nb=FileMonikerImpl_DecomposePath(This->filePathName,&tabStr);
if (nb > 0 ){
addBkSlash=1;
if (lstrcmpW(tabStr[0],twoPoint)!=0)
addBkSlash=0;
else
for(i=0;i<nb;i++){
if ( (lstrcmpW(tabStr[i],twoPoint)!=0) && (lstrcmpW(tabStr[i],bkSlash)!=0) ){
addBkSlash=0;
break;
}
else
if (lstrcmpW(tabStr[i],bkSlash)==0 && i<nb-1 && lstrcmpW(tabStr[i+1],bkSlash)==0){
*tabStr[i]=0;
sizeStr--;
addBkSlash=0;
break;
}
}
if (lstrcmpW(tabStr[nb-1],bkSlash)==0)
addBkSlash=0;
This->filePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR));
*This->filePathName=0;
for(i=0;tabStr[i]!=NULL;i++)
strcatW(This->filePathName,tabStr[i]);
if (addBkSlash)
strcatW(This->filePathName,bkSlash);
}
for(i=0; tabStr[i]!=NULL;i++)
CoTaskMemFree(tabStr[i]);
CoTaskMemFree(tabStr);
return S_OK;
}
/******************************************************************************
@ -1358,3 +1356,75 @@ HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk)
return hr;
}
static HRESULT WINAPI FileMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IUnknown_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI FileMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI FileMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI FileMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
FileMonikerImpl* newFileMoniker;
HRESULT hr;
static const WCHAR wszEmpty[] = { 0 };
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pUnk)
return CLASS_E_NOAGGREGATION;
newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl));
if (!newFileMoniker)
return E_OUTOFMEMORY;
hr = FileMonikerImpl_Construct(newFileMoniker, wszEmpty);
if (SUCCEEDED(hr))
hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker, riid, ppv);
if (FAILED(hr))
HeapFree(GetProcessHeap(),0,newFileMoniker);
return hr;
}
static HRESULT WINAPI FileMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl FileMonikerCFVtbl =
{
FileMonikerCF_QueryInterface,
FileMonikerCF_AddRef,
FileMonikerCF_Release,
FileMonikerCF_CreateInstance,
FileMonikerCF_LockServer
};
static const IClassFactoryVtbl *FileMonikerCF = &FileMonikerCFVtbl;
HRESULT FileMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&FileMonikerCF, riid, ppv);
}

View file

@ -51,7 +51,8 @@ typedef struct _FTMarshalImpl {
#define _ICOM_THIS_From_IFTMarshal(class, name) class* This = (class*)(((char*)name)-_IFTMarshall_Offset);
/* inner IUnknown to handle aggregation */
HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
static HRESULT WINAPI
IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
{
FTMarshalImpl *This = (FTMarshalImpl *)iface;
@ -71,7 +72,7 @@ HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPV
return S_OK;
}
ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
static ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
{
FTMarshalImpl *This = (FTMarshalImpl *)iface;
@ -80,7 +81,7 @@ ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
return InterlockedIncrement (&This->ref);
}
ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
static ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
{
FTMarshalImpl *This = (FTMarshalImpl *)iface;
@ -99,7 +100,8 @@ static IUnknownVtbl iunkvt =
IiFTMUnknown_fnRelease
};
HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
static HRESULT WINAPI
FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
{
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
@ -108,7 +110,8 @@ HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOI
return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv);
}
ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
static ULONG WINAPI
FTMarshalImpl_AddRef (LPMARSHAL iface)
{
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
@ -117,7 +120,8 @@ ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
return IUnknown_AddRef (This->pUnkOuter);
}
ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
static ULONG WINAPI
FTMarshalImpl_Release (LPMARSHAL iface)
{
_ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
@ -126,14 +130,16 @@ ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
return IUnknown_Release (This->pUnkOuter);
}
HRESULT WINAPI FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
static HRESULT WINAPI
FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
void *pvDestContext, DWORD mshlflags, CLSID * pCid)
{
FIXME ("(), stub!\n");
return S_OK;
}
HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
static HRESULT WINAPI
FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
void *pvDestContext, DWORD mshlflags, DWORD * pSize)
{
@ -158,8 +164,9 @@ HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, vo
return hres;
}
HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
static HRESULT WINAPI
FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
{
IMarshal *pMarshal = NULL;
@ -182,25 +189,26 @@ HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm,
return hres;
}
HRESULT WINAPI FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
static HRESULT WINAPI
FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
{
FIXME ("(), stub!\n");
return S_OK;
}
HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
{
FIXME ("(), stub!\n");
return S_OK;
}
HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
static HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
{
FIXME ("(), stub!\n");
return S_OK;
}
IMarshalVtbl ftmvtbl =
static IMarshalVtbl ftmvtbl =
{
FTMarshalImpl_QueryInterface,
FTMarshalImpl_AddRef,

View file

@ -83,27 +83,6 @@ typedef struct StdGlobalInterfaceTableImpl
void* StdGlobalInterfaceTableInstance;
/* IUnknown */
static HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject);
static ULONG WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface);
static ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface);
/* IGlobalInterfaceTable */
static HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfaceTable* iface, IUnknown* pUnk, REFIID riid, DWORD* pdwCookie);
static HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie);
static HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie, REFIID riid, void **ppv);
/* Virtual function table */
static IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl =
{
StdGlobalInterfaceTable_QueryInterface,
StdGlobalInterfaceTable_AddRef,
StdGlobalInterfaceTable_Release,
StdGlobalInterfaceTable_RegisterInterfaceInGlobal,
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal,
StdGlobalInterfaceTable_GetInterfaceFromGlobal
};
static CRITICAL_SECTION git_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
@ -114,28 +93,6 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
static CRITICAL_SECTION git_section = { &critsect_debug, -1, 0, 0, 0, 0 };
/***
* Let's go! Here is the constructor and destructor for the class.
*
*/
/** This function constructs the GIT. It should only be called once **/
void* StdGlobalInterfaceTable_Construct() {
StdGlobalInterfaceTableImpl* newGIT;
newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl));
if (newGIT == 0) return newGIT;
newGIT->lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
newGIT->ref = 1; /* Initialise the reference count */
newGIT->firstEntry = NULL; /* we start with an empty table */
newGIT->lastEntry = NULL;
newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
TRACE("Created the GIT at %p\n", newGIT);
return (void*)newGIT;
}
/** This destroys it again. It should revoke all the held interfaces first **/
void StdGlobalInterfaceTable_Destroy(void* self) {
TRACE("(%p)\n", self);
@ -149,7 +106,9 @@ void StdGlobalInterfaceTable_Destroy(void* self) {
* A helper function to traverse the list and find the entry that matches the cookie.
* Returns NULL if not found
*/
StdGITEntry* StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie) {
static StdGITEntry*
StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie)
{
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
StdGITEntry* e;
@ -174,34 +133,39 @@ StdGITEntry* StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWO
* Here's the boring boilerplate stuff for IUnknown
*/
HRESULT WINAPI StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, REFIID riid, void** ppvObject) {
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
static HRESULT WINAPI
StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface,
REFIID riid, void** ppvObject)
{
/* Make sure silly coders can't crash us */
if (ppvObject == 0) return E_INVALIDARG;
*ppvObject = 0; /* assume we don't have the interface */
/* Do we implement that interface? */
if (IsEqualIID(&IID_IUnknown, riid)) {
*ppvObject = (IGlobalInterfaceTable*) self;
} else if (IsEqualIID(&IID_IGlobalInterfaceTable, riid)) {
*ppvObject = (IGlobalInterfaceTable*) self;
} else return E_NOINTERFACE;
if (IsEqualIID(&IID_IUnknown, riid) ||
IsEqualIID(&IID_IGlobalInterfaceTable, riid))
*ppvObject = iface;
else
return E_NOINTERFACE;
/* Now inc the refcount */
StdGlobalInterfaceTable_AddRef(iface);
IGlobalInterfaceTable_AddRef(iface);
return S_OK;
}
ULONG WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface) {
static ULONG WINAPI
StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface)
{
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
/* InterlockedIncrement(&self->ref); */
return self->ref;
}
ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface) {
static ULONG WINAPI
StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface)
{
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
/* InterlockedDecrement(&self->ref); */
@ -218,12 +182,16 @@ ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface) {
* Now implement the actual IGlobalInterfaceTable interface
*/
HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfaceTable* iface, IUnknown* pUnk, REFIID riid, DWORD* pdwCookie) {
static HRESULT WINAPI
StdGlobalInterfaceTable_RegisterInterfaceInGlobal(
IGlobalInterfaceTable* iface, IUnknown* pUnk,
REFIID riid, DWORD* pdwCookie)
{
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
IStream* stream = NULL;
HRESULT hres;
StdGITEntry* entry;
static const LARGE_INTEGER zero;
LARGE_INTEGER zero;
TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=0x%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie);
@ -241,6 +209,7 @@ HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfac
return hres;
}
zero.QuadPart = 0;
IStream_Seek(stream, zero, SEEK_SET, NULL);
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
@ -269,7 +238,10 @@ HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfac
return S_OK;
}
HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie) {
static HRESULT WINAPI
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
IGlobalInterfaceTable* iface, DWORD dwCookie)
{
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
StdGITEntry* entry;
HRESULT hr;
@ -303,7 +275,11 @@ HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfac
return S_OK;
}
HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie, REFIID riid, void **ppv) {
static HRESULT WINAPI
StdGlobalInterfaceTable_GetInterfaceFromGlobal(
IGlobalInterfaceTable* iface, DWORD dwCookie,
REFIID riid, void **ppv)
{
StdGITEntry* entry;
HRESULT hres;
LARGE_INTEGER move;
@ -341,18 +317,33 @@ HRESULT WINAPI StdGlobalInterfaceTable_GetInterfaceFromGlobal(IGlobalInterfaceTa
/* Classfactory definition - despite what MSDN says, some programs need this */
static HRESULT WINAPI GITCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) {
static HRESULT WINAPI
GITCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IGlobalInterfaceTable)) {
if (IsEqualIID(riid,&IID_IUnknown) ||
IsEqualIID(riid,&IID_IGlobalInterfaceTable))
{
*ppv = (LPVOID)iface;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI GITCF_AddRef(LPCLASSFACTORY iface) { return 2; }
static ULONG WINAPI GITCF_Release(LPCLASSFACTORY iface) { return 1; }
static HRESULT WINAPI GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) {
static ULONG WINAPI GITCF_AddRef(LPCLASSFACTORY iface)
{
return 2;
}
static ULONG WINAPI GITCF_Release(LPCLASSFACTORY iface)
{
return 1;
}
static HRESULT WINAPI
GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
REFIID riid, LPVOID *ppv)
{
if (IsEqualIID(riid,&IID_IGlobalInterfaceTable)) {
if (StdGlobalInterfaceTableInstance == NULL)
StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct();
@ -363,7 +354,8 @@ static HRESULT WINAPI GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
return E_NOINTERFACE;
}
static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) {
static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
@ -375,10 +367,41 @@ static IClassFactoryVtbl GITClassFactoryVtbl = {
GITCF_CreateInstance,
GITCF_LockServer
};
static IClassFactoryVtbl *PGITClassFactoryVtbl = &GITClassFactoryVtbl;
HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) {
HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv)
{
*ppv = &PGITClassFactoryVtbl;
TRACE("Returning GIT classfactory\n");
return S_OK;
}
/* Virtual function table */
static IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl =
{
StdGlobalInterfaceTable_QueryInterface,
StdGlobalInterfaceTable_AddRef,
StdGlobalInterfaceTable_Release,
StdGlobalInterfaceTable_RegisterInterfaceInGlobal,
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal,
StdGlobalInterfaceTable_GetInterfaceFromGlobal
};
/** This function constructs the GIT. It should only be called once **/
void* StdGlobalInterfaceTable_Construct()
{
StdGlobalInterfaceTableImpl* newGIT;
newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl));
if (newGIT == 0) return newGIT;
newGIT->lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
newGIT->ref = 1; /* Initialise the reference count */
newGIT->firstEntry = NULL; /* we start with an empty table */
newGIT->lastEntry = NULL;
newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
TRACE("Created the GIT at %p\n", newGIT);
return (void*)newGIT;
}

View file

@ -86,217 +86,6 @@ struct HGLOBALStreamImpl
typedef struct HGLOBALStreamImpl HGLOBALStreamImpl;
/*
* Method definition for the StgStreamImpl class.
*/
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
HGLOBAL hGlobal,
BOOL fDeleteOnRelease);
void HGLOBALStreamImpl_Destroy(
HGLOBALStreamImpl* This);
void HGLOBALStreamImpl_OpenBlockChain(
HGLOBALStreamImpl* This);
HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
IStream* iface,
REFIID riid, /* [in] */
void** ppvObject); /* [iid_is][out] */
ULONG WINAPI HGLOBALStreamImpl_AddRef(
IStream* iface);
ULONG WINAPI HGLOBALStreamImpl_Release(
IStream* iface);
HRESULT WINAPI HGLOBALStreamImpl_Read(
IStream* iface,
void* pv, /* [length_is][size_is][out] */
ULONG cb, /* [in] */
ULONG* pcbRead); /* [out] */
HRESULT WINAPI HGLOBALStreamImpl_Write(
IStream* iface,
const void* pv, /* [size_is][in] */
ULONG cb, /* [in] */
ULONG* pcbWritten); /* [out] */
HRESULT WINAPI HGLOBALStreamImpl_Seek(
IStream* iface,
LARGE_INTEGER dlibMove, /* [in] */
DWORD dwOrigin, /* [in] */
ULARGE_INTEGER* plibNewPosition); /* [out] */
HRESULT WINAPI HGLOBALStreamImpl_SetSize(
IStream* iface,
ULARGE_INTEGER libNewSize); /* [in] */
HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
IStream* iface,
IStream* pstm, /* [unique][in] */
ULARGE_INTEGER cb, /* [in] */
ULARGE_INTEGER* pcbRead, /* [out] */
ULARGE_INTEGER* pcbWritten); /* [out] */
HRESULT WINAPI HGLOBALStreamImpl_Commit(
IStream* iface,
DWORD grfCommitFlags); /* [in] */
HRESULT WINAPI HGLOBALStreamImpl_Revert(
IStream* iface);
HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
IStream* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType); /* [in] */
HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
IStream* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType); /* [in] */
HRESULT WINAPI HGLOBALStreamImpl_Stat(
IStream* iface,
STATSTG* pstatstg, /* [out] */
DWORD grfStatFlag); /* [in] */
HRESULT WINAPI HGLOBALStreamImpl_Clone(
IStream* iface,
IStream** ppstm); /* [out] */
/*
* Virtual function table for the HGLOBALStreamImpl class.
*/
static IStreamVtbl HGLOBALStreamImpl_Vtbl =
{
HGLOBALStreamImpl_QueryInterface,
HGLOBALStreamImpl_AddRef,
HGLOBALStreamImpl_Release,
HGLOBALStreamImpl_Read,
HGLOBALStreamImpl_Write,
HGLOBALStreamImpl_Seek,
HGLOBALStreamImpl_SetSize,
HGLOBALStreamImpl_CopyTo,
HGLOBALStreamImpl_Commit,
HGLOBALStreamImpl_Revert,
HGLOBALStreamImpl_LockRegion,
HGLOBALStreamImpl_UnlockRegion,
HGLOBALStreamImpl_Stat,
HGLOBALStreamImpl_Clone
};
/***********************************************************************
* CreateStreamOnHGlobal [OLE32.@]
*/
HRESULT WINAPI CreateStreamOnHGlobal(
HGLOBAL hGlobal,
BOOL fDeleteOnRelease,
LPSTREAM* ppstm)
{
HGLOBALStreamImpl* newStream;
newStream = HGLOBALStreamImpl_Construct(hGlobal,
fDeleteOnRelease);
if (newStream!=NULL)
{
return IUnknown_QueryInterface((IUnknown*)newStream,
&IID_IStream,
(void**)ppstm);
}
return E_OUTOFMEMORY;
}
/***********************************************************************
* GetHGlobalFromStream [OLE32.@]
*/
HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
{
HGLOBALStreamImpl* pStream;
if (pstm == NULL)
return E_INVALIDARG;
pStream = (HGLOBALStreamImpl*) pstm;
/*
* Verify that the stream object was created with CreateStreamOnHGlobal.
*/
if (pStream->lpVtbl == &HGLOBALStreamImpl_Vtbl)
*phglobal = pStream->supportHandle;
else
{
*phglobal = 0;
return E_INVALIDARG;
}
return S_OK;
}
/******************************************************************************
** HGLOBALStreamImpl implementation
*/
/***
* This is the constructor for the HGLOBALStreamImpl class.
*
* Params:
* hGlobal - Handle that will support the stream. can be NULL.
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
* when the IStream object is destroyed.
*/
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
HGLOBAL hGlobal,
BOOL fDeleteOnRelease)
{
HGLOBALStreamImpl* newStream;
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
if (newStream!=0)
{
/*
* Set-up the virtual function table and reference count.
*/
newStream->lpVtbl = &HGLOBALStreamImpl_Vtbl;
newStream->ref = 0;
/*
* Initialize the support.
*/
newStream->supportHandle = hGlobal;
newStream->deleteOnRelease = fDeleteOnRelease;
/*
* This method will allocate a handle if one is not supplied.
*/
if (!newStream->supportHandle)
{
newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
GMEM_SHARE, 0);
}
/*
* Start the stream at the beginning.
*/
newStream->currentPosition.u.HighPart = 0;
newStream->currentPosition.u.LowPart = 0;
/*
* Initialize the size of the stream to the size of the handle.
*/
newStream->streamSize.u.HighPart = 0;
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
}
return newStream;
}
/***
* This is the destructor of the HGLOBALStreamImpl class.
*
@ -304,7 +93,7 @@ HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
* class. The pointer passed-in to this function will be freed and will not
* be valid anymore.
*/
void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
static void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
{
TRACE("(%p)\n", This);
@ -323,11 +112,22 @@ void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
HeapFree(GetProcessHeap(), 0, This);
}
/***
* This implements the IUnknown method AddRef for this
* class
*/
static ULONG WINAPI HGLOBALStreamImpl_AddRef(
IStream* iface)
{
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
return InterlockedIncrement(&This->ref);
}
/***
* This implements the IUnknown method QueryInterface for this
* class
*/
HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
static HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
IStream* iface,
REFIID riid, /* [in] */
void** ppvObject) /* [iid_is][out] */
@ -372,22 +172,11 @@ HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
return S_OK;
}
/***
* This implements the IUnknown method AddRef for this
* class
*/
ULONG WINAPI HGLOBALStreamImpl_AddRef(
IStream* iface)
{
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
return InterlockedIncrement(&This->ref);
}
/***
* This implements the IUnknown method Release for this
* class
*/
ULONG WINAPI HGLOBALStreamImpl_Release(
static ULONG WINAPI HGLOBALStreamImpl_Release(
IStream* iface)
{
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
@ -415,7 +204,7 @@ ULONG WINAPI HGLOBALStreamImpl_Release(
*
* See the documentation of ISequentialStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_Read(
static HRESULT WINAPI HGLOBALStreamImpl_Read(
IStream* iface,
void* pv, /* [length_is][size_is][out] */
ULONG cb, /* [in] */
@ -486,7 +275,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Read(
*
* See the documentation of ISequentialStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_Write(
static HRESULT WINAPI HGLOBALStreamImpl_Write(
IStream* iface,
const void* pv, /* [size_is][in] */
ULONG cb, /* [in] */
@ -560,7 +349,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Write(
*
* See the documentation of IStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_Seek(
static HRESULT WINAPI HGLOBALStreamImpl_Seek(
IStream* iface,
LARGE_INTEGER dlibMove, /* [in] */
DWORD dwOrigin, /* [in] */
@ -617,7 +406,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Seek(
*
* See the documentation of IStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_SetSize(
static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
IStream* iface,
ULARGE_INTEGER libNewSize) /* [in] */
{
@ -656,7 +445,7 @@ HRESULT WINAPI HGLOBALStreamImpl_SetSize(
*
* See the documentation of IStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
static HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
IStream* iface,
IStream* pstm, /* [unique][in] */
ULARGE_INTEGER cb, /* [in] */
@ -741,7 +530,7 @@ HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
*
* See the documentation of IStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_Commit(
static HRESULT WINAPI HGLOBALStreamImpl_Commit(
IStream* iface,
DWORD grfCommitFlags) /* [in] */
{
@ -756,7 +545,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Commit(
*
* See the documentation of IStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_Revert(
static HRESULT WINAPI HGLOBALStreamImpl_Revert(
IStream* iface)
{
return S_OK;
@ -770,7 +559,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Revert(
*
* See the documentation of IStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
static HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
IStream* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@ -787,7 +576,7 @@ HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
*
* See the documentation of IStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
static HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
IStream* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@ -804,7 +593,7 @@ HRESULT WINAPI HGLOBALStreamImpl_UnlockRegion(
*
* See the documentation of IStream for more info.
*/
HRESULT WINAPI HGLOBALStreamImpl_Stat(
static HRESULT WINAPI HGLOBALStreamImpl_Stat(
IStream* iface,
STATSTG* pstatstg, /* [out] */
DWORD grfStatFlag) /* [in] */
@ -820,7 +609,7 @@ HRESULT WINAPI HGLOBALStreamImpl_Stat(
return S_OK;
}
HRESULT WINAPI HGLOBALStreamImpl_Clone(
static HRESULT WINAPI HGLOBALStreamImpl_Clone(
IStream* iface,
IStream** ppstm) /* [out] */
{
@ -836,3 +625,133 @@ HRESULT WINAPI HGLOBALStreamImpl_Clone(
HGLOBALStreamImpl_Seek(*ppstm,offset,STREAM_SEEK_SET,&dummy);
return S_OK;
}
/*
* Virtual function table for the HGLOBALStreamImpl class.
*/
static IStreamVtbl HGLOBALStreamImpl_Vtbl =
{
HGLOBALStreamImpl_QueryInterface,
HGLOBALStreamImpl_AddRef,
HGLOBALStreamImpl_Release,
HGLOBALStreamImpl_Read,
HGLOBALStreamImpl_Write,
HGLOBALStreamImpl_Seek,
HGLOBALStreamImpl_SetSize,
HGLOBALStreamImpl_CopyTo,
HGLOBALStreamImpl_Commit,
HGLOBALStreamImpl_Revert,
HGLOBALStreamImpl_LockRegion,
HGLOBALStreamImpl_UnlockRegion,
HGLOBALStreamImpl_Stat,
HGLOBALStreamImpl_Clone
};
/******************************************************************************
** HGLOBALStreamImpl implementation
*/
/***
* This is the constructor for the HGLOBALStreamImpl class.
*
* Params:
* hGlobal - Handle that will support the stream. can be NULL.
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
* when the IStream object is destroyed.
*/
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
HGLOBAL hGlobal,
BOOL fDeleteOnRelease)
{
HGLOBALStreamImpl* newStream;
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
if (newStream!=0)
{
/*
* Set-up the virtual function table and reference count.
*/
newStream->lpVtbl = &HGLOBALStreamImpl_Vtbl;
newStream->ref = 0;
/*
* Initialize the support.
*/
newStream->supportHandle = hGlobal;
newStream->deleteOnRelease = fDeleteOnRelease;
/*
* This method will allocate a handle if one is not supplied.
*/
if (!newStream->supportHandle)
{
newStream->supportHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD |
GMEM_SHARE, 0);
}
/*
* Start the stream at the beginning.
*/
newStream->currentPosition.u.HighPart = 0;
newStream->currentPosition.u.LowPart = 0;
/*
* Initialize the size of the stream to the size of the handle.
*/
newStream->streamSize.u.HighPart = 0;
newStream->streamSize.u.LowPart = GlobalSize(newStream->supportHandle);
}
return newStream;
}
/***********************************************************************
* CreateStreamOnHGlobal [OLE32.@]
*/
HRESULT WINAPI CreateStreamOnHGlobal(
HGLOBAL hGlobal,
BOOL fDeleteOnRelease,
LPSTREAM* ppstm)
{
HGLOBALStreamImpl* newStream;
newStream = HGLOBALStreamImpl_Construct(hGlobal,
fDeleteOnRelease);
if (newStream!=NULL)
{
return IUnknown_QueryInterface((IUnknown*)newStream,
&IID_IStream,
(void**)ppstm);
}
return E_OUTOFMEMORY;
}
/***********************************************************************
* GetHGlobalFromStream [OLE32.@]
*/
HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
{
HGLOBALStreamImpl* pStream;
if (pstm == NULL)
return E_INVALIDARG;
pStream = (HGLOBALStreamImpl*) pstm;
/*
* Verify that the stream object was created with CreateStreamOnHGlobal.
*/
if (pStream->lpVtbl == &HGLOBALStreamImpl_Vtbl)
*phglobal = pStream->supportHandle;
else
{
*phglobal = 0;
return E_INVALIDARG;
}
return S_OK;
}

View file

@ -58,6 +58,7 @@ typedef struct ItemMonikerImpl{
LPOLESTR itemDelimiter; /* Delimiter string */
IUnknown *pMarshal; /* custom marshaler */
} ItemMonikerImpl;
/********************************************************************************/
@ -107,7 +108,7 @@ static ULONG WINAPI ItemMonikerROTDataImpl_AddRef(IROTData* iface);
static ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface);
/* IROTData prototype function */
static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
static HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
/********************************************************************************/
/* Virtual function table for the ItemMonikerImpl class which include IPersist,*/
@ -146,7 +147,7 @@ static IROTDataVtbl VT_ROTDataImpl =
ItemMonikerROTDataImpl_QueryInterface,
ItemMonikerROTDataImpl_AddRef,
ItemMonikerROTDataImpl_Release,
ItemMonikerROTDataImpl_GetComparaisonData
ItemMonikerROTDataImpl_GetComparisonData
};
/*******************************************************************************
@ -175,6 +176,15 @@ HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
else if (IsEqualIID(&IID_IROTData, riid))
*ppvObject = (IROTData*)&(This->lpvtbl2);
else if (IsEqualIID(&IID_IMarshal, riid))
{
HRESULT hr = S_OK;
if (!This->pMarshal)
hr = MonikerMarshal_Create(iface, &This->pMarshal);
if (hr != S_OK)
return hr;
return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
}
/* Check that we obtained an interface.*/
if ((*ppvObject)==0)
@ -359,17 +369,16 @@ HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
TRACE("(%p,%p)\n",iface,pcbSize);
if (pcbSize!=NULL)
if (!pcbSize)
return E_POINTER;
/* for more details see ItemMonikerImpl_Save coments */
pcbSize->u.LowPart = sizeof(DWORD) + /* DWORD which contains delimiter length */
delimiterLength + /* item delimiter string */
delimiterLength*4 + /* item delimiter string */
sizeof(DWORD) + /* DWORD which contains item name length */
nameLength + /* item name string */
34; /* this constant was added ! because when I tested this function it usually */
/* returns 34 bytes more than the number of bytes used by IMoniker::Save function */
nameLength*4 + /* item name string */
18; /* strange, but true */
pcbSize->u.HighPart=0;
return S_OK;
@ -391,6 +400,7 @@ HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDe
This->lpvtbl1 = &VT_ItemMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->pMarshal = NULL;
This->itemName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr1+1));
if (!This->itemName)
@ -419,6 +429,7 @@ HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
{
TRACE("(%p)\n",This);
if (This->pMarshal) IUnknown_Release(This->pMarshal);
HeapFree(GetProcessHeap(),0,This->itemName);
HeapFree(GetProcessHeap(),0,This->itemDelimiter);
HeapFree(GetProcessHeap(),0,This);
@ -952,13 +963,35 @@ ULONG WINAPI ItemMonikerROTDataImpl_Release(IROTData* iface)
/******************************************************************************
* ItemMonikerIROTData_GetComparaisonData
******************************************************************************/
HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
BYTE* pbData,
ULONG cbMax,
ULONG* pcbData)
{
FIXME("(),stub!\n");
return E_NOTIMPL;
ICOM_THIS_From_IROTData(IMoniker, iface);
ItemMonikerImpl *This1 = (ItemMonikerImpl *)This;
int len = (strlenW(This1->itemName)+1);
int i;
LPWSTR pszItemName;
LPWSTR pszItemDelimiter;
TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID) + sizeof(WCHAR) + len * sizeof(WCHAR);
if (cbMax < *pcbData)
return E_OUTOFMEMORY;
/* write CLSID */
memcpy(pbData, &CLSID_ItemMoniker, sizeof(CLSID));
/* write delimiter */
pszItemDelimiter = (LPWSTR)(pbData+sizeof(CLSID));
*pszItemDelimiter = *This1->itemDelimiter;
/* write name */
pszItemName = pszItemDelimiter + 1;
for (i = 0; i < len; i++)
pszItemName[i] = toupperW(This1->itemName[i]);
return S_OK;
}
/******************************************************************************
@ -986,3 +1019,75 @@ HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR lpszItem, LPMONI
return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&IID_IMoniker,(void**)ppmk);
}
static HRESULT WINAPI ItemMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
{
*ppv = iface;
IUnknown_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI ItemMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI ItemMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI ItemMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
ItemMonikerImpl* newItemMoniker;
HRESULT hr;
static const WCHAR wszEmpty[] = { 0 };
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pUnk)
return CLASS_E_NOAGGREGATION;
newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
if (!newItemMoniker)
return E_OUTOFMEMORY;
hr = ItemMonikerImpl_Construct(newItemMoniker, wszEmpty, wszEmpty);
if (SUCCEEDED(hr))
hr = ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker, riid, ppv);
if (FAILED(hr))
HeapFree(GetProcessHeap(),0,newItemMoniker);
return hr;
}
static HRESULT WINAPI ItemMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl ItemMonikerCFVtbl =
{
ItemMonikerCF_QueryInterface,
ItemMonikerCF_AddRef,
ItemMonikerCF_Release,
ItemMonikerCF_CreateInstance,
ItemMonikerCF_LockServer
};
static const IClassFactoryVtbl *ItemMonikerCF = &ItemMonikerCFVtbl;
HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&ItemMonikerCF, riid, ppv);
}

View file

@ -63,26 +63,25 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
*
* So basically we need a set of values that make it unique.
*
* Process Identifier, Object IUnknown ptr, IID
*
* Note that the IUnknown_QI(ob,xiid,&ppv) always returns the SAME ppv value!
*
* In Windows, a different triple is used: OXID (apt id), OID (stub
* manager id), IPID (interface ptr/stub id).
* A triple is used: OXID (apt id), OID (stub manager id),
* IPID (interface ptr/stub id).
*
* OXIDs identify an apartment and are network scoped
* OIDs identify a stub manager and are apartment scoped
* IPIDs identify an interface stub and are apartment scoped
*/
inline static HRESULT
get_facbuf_for_iid(REFIID riid,IPSFactoryBuffer **facbuf) {
HRESULT hres;
CLSID pxclsid;
inline static HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
{
HRESULT hr;
CLSID clsid;
if ((hres = CoGetPSClsid(riid,&pxclsid)))
return hres;
return CoGetClassObject(&pxclsid,CLSCTX_INPROC_SERVER,NULL,&IID_IPSFactoryBuffer,(LPVOID*)facbuf);
if ((hr = CoGetPSClsid(riid, &clsid)))
return hr;
return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL,
&IID_IPSFactoryBuffer, (LPVOID*)facbuf);
}
/* creates a new stub manager */
@ -747,56 +746,61 @@ HRESULT apartment_disconnectproxies(struct apartment *apt)
}
/********************** StdMarshal implementation ****************************/
typedef struct _StdMarshalImpl {
IMarshalVtbl *lpvtbl;
DWORD ref;
typedef struct _StdMarshalImpl
{
const IMarshalVtbl *lpvtbl;
DWORD ref;
IID iid;
DWORD dwDestContext;
LPVOID pvDestContext;
DWORD mshlflags;
IID iid;
DWORD dwDestContext;
LPVOID pvDestContext;
DWORD mshlflags;
} StdMarshalImpl;
static HRESULT WINAPI
StdMarshalImpl_QueryInterface(LPMARSHAL iface,REFIID riid,LPVOID *ppv) {
*ppv = NULL;
if (IsEqualIID(&IID_IUnknown,riid) || IsEqualIID(&IID_IMarshal,riid)) {
*ppv = iface;
IUnknown_AddRef(iface);
return S_OK;
}
FIXME("No interface for %s.\n",debugstr_guid(riid));
return E_NOINTERFACE;
static HRESULT WINAPI
StdMarshalImpl_QueryInterface(LPMARSHAL iface, REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IMarshal, riid))
{
*ppv = iface;
IUnknown_AddRef(iface);
return S_OK;
}
FIXME("No interface for %s.\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
static ULONG WINAPI
StdMarshalImpl_AddRef(LPMARSHAL iface) {
StdMarshalImpl *This = (StdMarshalImpl *)iface;
return InterlockedIncrement(&This->ref);
StdMarshalImpl_AddRef(LPMARSHAL iface)
{
StdMarshalImpl *This = (StdMarshalImpl *)iface;
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI
StdMarshalImpl_Release(LPMARSHAL iface) {
StdMarshalImpl *This = (StdMarshalImpl *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
StdMarshalImpl_Release(LPMARSHAL iface)
{
StdMarshalImpl *This = (StdMarshalImpl *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
if (!ref) HeapFree(GetProcessHeap(),0,This);
return ref;
if (!ref) HeapFree(GetProcessHeap(),0,This);
return ref;
}
static HRESULT WINAPI
StdMarshalImpl_GetUnmarshalClass(
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, CLSID* pCid
) {
memcpy(pCid,&CLSID_DfMarshal,sizeof(CLSID_DfMarshal));
return S_OK;
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, CLSID* pCid)
{
*pCid = CLSID_DfMarshal;
return S_OK;
}
static HRESULT WINAPI
StdMarshalImpl_GetMarshalSizeMax(
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
{
*pSize = sizeof(STDOBJREF);
return S_OK;
@ -804,48 +808,48 @@ StdMarshalImpl_GetMarshalSizeMax(
static HRESULT WINAPI
StdMarshalImpl_MarshalInterface(
LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags
) {
STDOBJREF stdobjref;
IUnknown *pUnk;
ULONG res;
HRESULT hres;
APARTMENT *apt = COM_CurrentApt();
TRACE("(...,%s,...)\n",debugstr_guid(riid));
LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags)
{
STDOBJREF stdobjref;
IUnknown *pUnk;
ULONG res;
HRESULT hres;
APARTMENT *apt = COM_CurrentApt();
if (!apt)
{
ERR("Apartment not initialized\n");
return CO_E_NOTINITIALIZED;
}
TRACE("(...,%s,...)\n", debugstr_guid(riid));
/* make sure this apartment can be reached from other threads / processes */
RPC_StartRemoting(apt);
if (!apt)
{
ERR("Apartment not initialized\n");
return CO_E_NOTINITIALIZED;
}
hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
if (hres != S_OK)
{
ERR("object doesn't expose interface %s, failing with error 0x%08lx\n",
debugstr_guid(riid), hres);
return E_NOINTERFACE;
}
/* make sure this apartment can be reached from other threads / processes */
RPC_StartRemoting(apt);
hres = marshal_object(apt, &stdobjref, riid, pUnk, mshlflags);
hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
if (hres != S_OK)
{
ERR("object doesn't expose interface %s, failing with error 0x%08lx\n",
debugstr_guid(riid), hres);
return E_NOINTERFACE;
}
hres = marshal_object(apt, &stdobjref, riid, pUnk, mshlflags);
IUnknown_Release(pUnk);
IUnknown_Release(pUnk);
if (hres)
{
FIXME("Failed to create ifstub, hres=0x%lx\n", hres);
return hres;
}
if (hres)
{
ERR("Failed to create ifstub, hres=0x%lx\n", hres);
return hres;
}
hres = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res);
if (hres) return hres;
hres = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res);
if (hres) return hres;
return S_OK;
return S_OK;
}
/* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
@ -907,85 +911,86 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
static HRESULT WINAPI
StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
{
struct stub_manager *stubmgr;
STDOBJREF stdobjref;
ULONG res;
HRESULT hres;
APARTMENT *apt = COM_CurrentApt();
APARTMENT *stub_apt;
OXID oxid;
struct stub_manager *stubmgr;
STDOBJREF stdobjref;
ULONG res;
HRESULT hres;
APARTMENT *apt = COM_CurrentApt();
APARTMENT *stub_apt;
OXID oxid;
TRACE("(...,%s,....)\n",debugstr_guid(riid));
TRACE("(...,%s,....)\n", debugstr_guid(riid));
/* we need an apartment to unmarshal into */
if (!apt)
{
ERR("Apartment not initialized\n");
return CO_E_NOTINITIALIZED;
}
/* we need an apartment to unmarshal into */
if (!apt)
{
ERR("Apartment not initialized\n");
return CO_E_NOTINITIALIZED;
}
/* read STDOBJREF from wire */
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
if (hres) return hres;
/* read STDOBJREF from wire */
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
if (hres) return hres;
hres = apartment_getoxid(apt, &oxid);
if (hres) return hres;
hres = apartment_getoxid(apt, &oxid);
if (hres) return hres;
/* check if we're marshalling back to ourselves */
if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
{
TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
"returning original object %p\n", debugstr_guid(riid), stubmgr->object);
/* check if we're marshalling back to ourselves */
if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
{
TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
"returning original object %p\n", debugstr_guid(riid), stubmgr->object);
hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
/* unref the ifstub. FIXME: only do this on success? */
if (!stub_manager_is_table_marshaled(stubmgr))
stub_manager_ext_release(stubmgr, 1);
/* unref the ifstub. FIXME: only do this on success? */
if (!stub_manager_is_table_marshaled(stubmgr))
stub_manager_ext_release(stubmgr, 1);
stub_manager_int_release(stubmgr);
return hres;
}
stub_manager_int_release(stubmgr);
return hres;
}
/* notify stub manager about unmarshal if process-local object.
* note: if the oxid is not found then we and native will quite happily
* ignore table marshaling and normal marshaling rules regarding number of
* unmarshals, etc, but if you abuse these rules then your proxy could end
* up returning RPC_E_DISCONNECTED. */
if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
{
if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
{
if (!stub_manager_notify_unmarshal(stubmgr))
hres = CO_E_OBJNOTCONNECTED;
/* notify stub manager about unmarshal if process-local object.
* note: if the oxid is not found then we and native will quite happily
* ignore table marshaling and normal marshaling rules regarding number of
* unmarshals, etc, but if you abuse these rules then your proxy could end
* up returning RPC_E_DISCONNECTED. */
if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
{
if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
{
if (!stub_manager_notify_unmarshal(stubmgr))
hres = CO_E_OBJNOTCONNECTED;
stub_manager_int_release(stubmgr);
}
else
{
WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n",
wine_dbgstr_longlong(stdobjref.oxid),
wine_dbgstr_longlong(stdobjref.oid));
hres = CO_E_OBJNOTCONNECTED;
}
stub_manager_int_release(stubmgr);
}
else
{
WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n",
wine_dbgstr_longlong(stdobjref.oxid),
wine_dbgstr_longlong(stdobjref.oid));
hres = CO_E_OBJNOTCONNECTED;
}
apartment_release(stub_apt);
}
else
TRACE("Treating unmarshal from OXID %s as inter-process\n",
apartment_release(stub_apt);
}
else
TRACE("Treating unmarshal from OXID %s as inter-process\n",
wine_dbgstr_longlong(stdobjref.oxid));
if (hres == S_OK)
hres = unmarshal_object(&stdobjref, apt, riid, ppv);
if (hres == S_OK)
hres = unmarshal_object(&stdobjref, apt, riid, ppv);
if (hres) WARN("Failed with error 0x%08lx\n", hres);
else TRACE("Successfully created proxy %p\n", *ppv);
if (hres) WARN("Failed with error 0x%08lx\n", hres);
else TRACE("Successfully created proxy %p\n", *ppv);
return hres;
return hres;
}
static HRESULT WINAPI
StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
{
STDOBJREF stdobjref;
ULONG res;
HRESULT hres;
@ -997,6 +1002,11 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
if (hres) return hres;
TRACE("oxid = %s, oid = %s, ipid = %s\n",
wine_dbgstr_longlong(stdobjref.oxid),
wine_dbgstr_longlong(stdobjref.oid),
wine_dbgstr_guid(&stdobjref.ipid));
if (!(apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
{
WARN("Could not map OXID %s to apartment object\n",
@ -1020,12 +1030,14 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
}
static HRESULT WINAPI
StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved) {
FIXME("(), stub!\n");
return S_OK;
StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved)
{
FIXME("(), stub!\n");
return S_OK;
}
IMarshalVtbl stdmvtbl = {
static const IMarshalVtbl VT_StdMarshal =
{
StdMarshalImpl_QueryInterface,
StdMarshalImpl_AddRef,
StdMarshalImpl_Release,
@ -1043,7 +1055,7 @@ static HRESULT StdMarshalImpl_Construct(REFIID riid, void** ppvObject)
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(StdMarshalImpl));
if (!pStdMarshal)
return E_OUTOFMEMORY;
pStdMarshal->lpvtbl = &stdmvtbl;
pStdMarshal->lpvtbl = &VT_StdMarshal;
pStdMarshal->ref = 0;
return IMarshal_QueryInterface((IMarshal*)pStdMarshal, riid, ppvObject);
}
@ -1075,28 +1087,27 @@ HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk,
DWORD dwDestContext, LPVOID pvDestContext,
DWORD mshlflags, LPMARSHAL *ppMarshal)
{
StdMarshalImpl *dm;
StdMarshalImpl *dm;
if (pUnk == NULL) {
FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,ppMarshal
);
return E_FAIL;
}
TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal
);
*ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
dm = (StdMarshalImpl*) *ppMarshal;
if (!dm) return E_FAIL;
dm->lpvtbl = &stdmvtbl;
dm->ref = 1;
if (pUnk == NULL)
{
FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,ppMarshal);
return E_NOTIMPL;
}
TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal);
*ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
dm = (StdMarshalImpl*) *ppMarshal;
if (!dm) return E_FAIL;
dm->lpvtbl = &VT_StdMarshal;
dm->ref = 1;
memcpy(&dm->iid,riid,sizeof(dm->iid));
dm->dwDestContext = dwDestContext;
dm->pvDestContext = pvDestContext;
dm->mshlflags = mshlflags;
return S_OK;
dm->iid = *riid;
dm->dwDestContext = dwDestContext;
dm->pvDestContext = pvDestContext;
dm->mshlflags = mshlflags;
return S_OK;
}
/***********************************************************************
@ -1157,7 +1168,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
}
else if (objref.flags & OBJREF_CUSTOM)
{
ULONG custom_header_size = FIELD_OFFSET(OBJREF, u_objref.u_custom.size) -
ULONG custom_header_size = FIELD_OFFSET(OBJREF, u_objref.u_custom.pData) -
FIELD_OFFSET(OBJREF, u_objref.u_custom);
TRACE("Using custom unmarshaling\n");
/* read constant sized OR_CUSTOM data from stream */
@ -1234,7 +1245,7 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk,
/* if custom marshaling, add on size of custom header */
if (!IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal))
*pulSize += FIELD_OFFSET(OBJREF, u_objref.u_custom.size) -
*pulSize += FIELD_OFFSET(OBJREF, u_objref.u_custom.pData) -
FIELD_OFFSET(OBJREF, u_objref.u_custom);
IMarshal_Release(pMarshal);
@ -1281,7 +1292,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
HRESULT hr;
CLSID marshaler_clsid;
OBJREF objref;
IStream * pMarshalStream = NULL;
LPMARSHAL pMarshal;
TRACE("(%p, %s, %p, %lx, %p, %lx)\n", pStream, debugstr_guid(riid), pUnk,
@ -1314,33 +1324,43 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
{
TRACE("Using standard marshaling\n");
objref.flags = OBJREF_STANDARD;
pMarshalStream = pStream;
/* write the common OBJREF header to the stream */
hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL);
if (hr)
{
ERR("Failed to write OBJREF header to stream, 0x%08lx\n", hr);
goto cleanup;
}
}
else
{
TRACE("Using custom marshaling\n");
objref.flags = OBJREF_CUSTOM;
/* we do custom marshaling into a memory stream so that we know what
* size to write into the OR_CUSTOM header */
hr = CreateStreamOnHGlobal(NULL, TRUE, &pMarshalStream);
objref.u_objref.u_custom.clsid = marshaler_clsid;
objref.u_objref.u_custom.cbExtension = 0;
objref.u_objref.u_custom.size = 0;
hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext,
pvDestContext, mshlFlags,
&objref.u_objref.u_custom.size);
if (hr)
{
ERR("CreateStreamOnHGLOBAL failed with 0x%08lx\n", hr);
ERR("Failed to get max size of marshal data, error 0x%08lx\n", hr);
goto cleanup;
}
/* write constant sized common header and OR_CUSTOM data into stream */
hr = IStream_Write(pStream, &objref,
FIELD_OFFSET(OBJREF, u_objref.u_custom.pData), NULL);
if (hr)
{
ERR("Failed to write OR_CUSTOM header to stream with 0x%08lx\n", hr);
goto cleanup;
}
}
/* write the common OBJREF header to the stream */
hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL);
if (hr)
{
ERR("Failed to write OBJREF header to stream, 0x%08lx\n", hr);
goto cleanup;
}
TRACE("Calling IMarshal::MarshalInterace\n");
/* call helper object to do the actual marshaling */
hr = IMarshal_MarshalInterface(pMarshal, pMarshalStream, riid, pUnk, dwDestContext,
hr = IMarshal_MarshalInterface(pMarshal, pStream, riid, pUnk, dwDestContext,
pvDestContext, mshlFlags);
if (hr)
@ -1349,51 +1369,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
goto cleanup;
}
if (objref.flags & OBJREF_CUSTOM)
{
ULONG custom_header_size = FIELD_OFFSET(OBJREF, u_objref.u_custom.size) -
FIELD_OFFSET(OBJREF, u_objref.u_custom);
HGLOBAL hGlobal;
LPVOID data;
hr = GetHGlobalFromStream(pMarshalStream, &hGlobal);
if (hr)
{
ERR("Couldn't get HGLOBAL from stream\n");
hr = E_UNEXPECTED;
goto cleanup;
}
objref.u_objref.u_custom.clsid = marshaler_clsid;
objref.u_objref.u_custom.cbExtension = 0;
objref.u_objref.u_custom.size = GlobalSize(hGlobal);
/* write constant sized OR_CUSTOM data into stream */
hr = IStream_Write(pStream, &objref.u_objref.u_custom,
custom_header_size, NULL);
if (hr)
{
ERR("Failed to write OR_CUSTOM header to stream with 0x%08lx\n", hr);
goto cleanup;
}
data = GlobalLock(hGlobal);
if (!data)
{
ERR("GlobalLock failed\n");
hr = E_UNEXPECTED;
goto cleanup;
}
/* write custom marshal data */
hr = IStream_Write(pStream, data, objref.u_objref.u_custom.size, NULL);
if (hr)
{
ERR("Failed to write custom marshal data with 0x%08lx\n", hr);
goto cleanup;
}
GlobalUnlock(hGlobal);
}
cleanup:
if (pMarshalStream && (objref.flags & OBJREF_CUSTOM))
IStream_Release(pMarshalStream);
IMarshal_Release(pMarshal);
TRACE("completed with hr 0x%08lx\n", hr);
@ -1602,11 +1578,11 @@ static ULONG WINAPI StdMarshalCF_Release(LPCLASSFACTORY iface)
static HRESULT WINAPI StdMarshalCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
if (IsEqualIID(riid,&IID_IMarshal))
return StdMarshalImpl_Construct(riid, ppv);
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMarshal))
return StdMarshalImpl_Construct(riid, ppv);
FIXME("(%s), not supported.\n",debugstr_guid(riid));
return E_NOINTERFACE;
FIXME("(%s), not supported.\n",debugstr_guid(riid));
return E_NOINTERFACE;
}
static HRESULT WINAPI StdMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
@ -1615,7 +1591,7 @@ static HRESULT WINAPI StdMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
return S_OK;
}
static IClassFactoryVtbl StdMarshalCFVtbl =
static const IClassFactoryVtbl StdMarshalCFVtbl =
{
StdMarshalCF_QueryInterface,
StdMarshalCF_AddRef,
@ -1623,7 +1599,7 @@ static IClassFactoryVtbl StdMarshalCFVtbl =
StdMarshalCF_CreateInstance,
StdMarshalCF_LockServer
};
static IClassFactoryVtbl *StdMarshalCF = &StdMarshalCFVtbl;
static const IClassFactoryVtbl *StdMarshalCF = &StdMarshalCFVtbl;
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv)
{

File diff suppressed because it is too large Load diff

View file

@ -8,4 +8,10 @@ extern const CLSID CLSID_ItemMoniker;
extern const CLSID CLSID_AntiMoniker;
extern const CLSID CLSID_CompositeMoniker;
HRESULT FileMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT MonikerMarshal_Create(IMoniker *inner, IUnknown **outer);
#endif /* __WINE_MONIKER_H__ */

View file

@ -50,9 +50,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
HINSTANCE16 COMPOBJ_hInstance = 0;
static int COMPOBJ_Attach = 0;
HTASK16 hETask = 0;
WORD Table_ETask[62];
@ -299,7 +296,7 @@ extern BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
* RETURNS
* the allocated segmented pointer and a HRESULT
*/
HRESULT
static HRESULT
_xmalloc16(DWORD size, SEGPTR *ptr) {
LPMALLOC16 mllc;
DWORD args[2];
@ -512,16 +509,5 @@ HRESULT WINAPI CoGetState16(LPDWORD state)
BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
{
TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
switch(Reason)
{
case DLL_PROCESS_ATTACH:
if (!COMPOBJ_Attach++) COMPOBJ_hInstance = hInst;
break;
case DLL_PROCESS_DETACH:
if(!--COMPOBJ_Attach)
COMPOBJ_hInstance = 0;
break;
}
return TRUE;
}

View file

@ -5,6 +5,7 @@
* Copyright 1999 Francis Beaudet
* Copyright 1999 Noel Borthwick
* Copyright 1999, 2000 Marcus Meissner
* Copyright 2005 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -48,7 +49,6 @@
#include "wine/winbase16.h"
#include "wine/wingdi16.h"
#include "wine/winuser16.h"
#include "ole32_main.h"
#include "compobj_private.h"
#include "wine/debug.h"
@ -2292,13 +2292,13 @@ HRESULT WINAPI OleCreate(
/******************************************************************************
* OleSetAutoConvert [OLE32.@]
*/
/* FIXME: convert to Unicode */
HRESULT WINAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew)
{
HKEY hkey = 0;
char buf[200], szClsidNew[200];
HRESULT res = S_OK;
/* FIXME: convert to Unicode */
TRACE("(%s,%s)\n", debugstr_guid(clsidOld), debugstr_guid(clsidNew));
sprintf(buf,"CLSID\\");WINE_StringFromCLSID(clsidOld,&buf[6]);
WINE_StringFromCLSID(clsidNew, szClsidNew);
@ -2541,26 +2541,40 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */
}
break;
default:
switch (pvar->vt & ~VT_VECTOR)
if (pvar->vt & VT_VECTOR)
{
case VT_VARIANT:
FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems);
break;
case VT_CF:
OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems);
break;
case VT_BSTR:
case VT_LPSTR:
case VT_LPWSTR:
case VT_CLSID:
FIXME("Freeing of vector sub-type not supported yet\n");
}
if (pvar->vt & ~VT_VECTOR)
{
/* pick an arbitary VT_VECTOR structure - they all have the same
* memory layout */
CoTaskMemFree(pvar->u.capropvar.pElems);
ULONG i;
switch (pvar->vt & ~VT_VECTOR)
{
case VT_VARIANT:
FreePropVariantArray(pvar->u.capropvar.cElems, pvar->u.capropvar.pElems);
break;
case VT_CF:
OLE_FreeClipDataArray(pvar->u.caclipdata.cElems, pvar->u.caclipdata.pElems);
break;
case VT_BSTR:
for (i = 0; i < pvar->u.cabstr.cElems; i++)
PropSysFreeString(pvar->u.cabstr.pElems[i]);
break;
case VT_LPSTR:
for (i = 0; i < pvar->u.calpstr.cElems; i++)
CoTaskMemFree(pvar->u.calpstr.pElems[i]);
break;
case VT_LPWSTR:
for (i = 0; i < pvar->u.calpwstr.cElems; i++)
CoTaskMemFree(pvar->u.calpwstr.pElems[i]);
break;
}
if (pvar->vt & ~VT_VECTOR)
{
/* pick an arbitary VT_VECTOR structure - they all have the same
* memory layout */
CoTaskMemFree(pvar->u.capropvar.pElems);
}
}
else
WARN("Invalid/unsupported type %d\n", pvar->vt);
}
ZeroMemory(pvar, sizeof(*pvar));
@ -2632,7 +2646,9 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
if (pvarSrc->vt & VT_VECTOR)
{
int elemSize;
switch(pvarSrc->vt & VT_VECTOR)
ULONG i;
switch(pvarSrc->vt & ~VT_VECTOR)
{
case VT_I1: elemSize = sizeof(pvarSrc->u.cVal); break;
case VT_UI1: elemSize = sizeof(pvarSrc->u.bVal); break;
@ -2651,20 +2667,19 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
case VT_FILETIME: elemSize = sizeof(pvarSrc->u.filetime); break;
case VT_CLSID: elemSize = sizeof(*pvarSrc->u.puuid); break;
case VT_CF: elemSize = sizeof(*pvarSrc->u.pclipdata); break;
case VT_BSTR: elemSize = sizeof(*pvarSrc->u.bstrVal); break;
case VT_LPSTR: elemSize = sizeof(*pvarSrc->u.pszVal); break;
case VT_LPWSTR: elemSize = sizeof(*pvarSrc->u.pwszVal); break;
case VT_BSTR:
case VT_LPSTR:
case VT_LPWSTR:
case VT_VARIANT:
default:
FIXME("Invalid element type: %ul\n", pvarSrc->vt & VT_VECTOR);
FIXME("Invalid element type: %ul\n", pvarSrc->vt & ~VT_VECTOR);
return E_INVALIDARG;
}
len = pvarSrc->u.capropvar.cElems;
pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize);
if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT))
{
ULONG i;
for (i = 0; i < len; i++)
PropVariantCopy(&pvarDest->u.capropvar.pElems[i], &pvarSrc->u.capropvar.pElems[i]);
}
@ -2674,19 +2689,37 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
}
else if (pvarSrc->vt == (VT_VECTOR | VT_BSTR))
{
FIXME("Copy BSTRs\n");
for (i = 0; i < len; i++)
pvarDest->u.cabstr.pElems[i] = PropSysAllocString(pvarSrc->u.cabstr.pElems[i]);
}
else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR))
{
FIXME("Copy LPSTRs\n");
size_t strLen;
for (i = 0; i < len; i++)
{
strLen = lstrlenA(pvarSrc->u.calpstr.pElems[i]) + 1;
pvarDest->u.calpstr.pElems[i] = CoTaskMemAlloc(strLen);
memcpy(pvarDest->u.calpstr.pElems[i],
pvarSrc->u.calpstr.pElems[i], strLen);
}
}
else if (pvarSrc->vt == (VT_VECTOR | VT_LPSTR))
else if (pvarSrc->vt == (VT_VECTOR | VT_LPWSTR))
{
FIXME("Copy LPWSTRs\n");
size_t strLen;
for (i = 0; i < len; i++)
{
strLen = (lstrlenW(pvarSrc->u.calpwstr.pElems[i]) + 1) *
sizeof(WCHAR);
pvarDest->u.calpstr.pElems[i] = CoTaskMemAlloc(strLen);
memcpy(pvarDest->u.calpstr.pElems[i],
pvarSrc->u.calpstr.pElems[i], strLen);
}
}
else
CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize);
}
else
WARN("Invalid/unsupported type %d\n", pvarSrc->vt);
}
return S_OK;

View file

@ -45,7 +45,6 @@
#include "wine/winbase16.h"
#include "wine/wingdi16.h"
#include "wine/winuser16.h"
#include "ole32_main.h"
#include "ifs.h"
#include "wine/debug.h"

View file

@ -1,4 +1,4 @@
1 stub WEP
#1 stub WEP
2 stub ROT16_ISRUNNING16
3 stub ISWIN32SHANDLE
4 stub ___EXPORTEDSTUB

View file

@ -40,7 +40,7 @@
@ stdcall CoInitializeEx(ptr long)
@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr)
@ stdcall CoInitializeWOW(long long)
@ stub CoIsHandlerConnected #@ stdcall (ptr) return 0,ERR_NOTIMPLEMENTED
@ stdcall CoIsHandlerConnected(ptr)
@ stdcall CoIsOle1Class (ptr)
@ stdcall CoLoadLibrary(wstr long)
@ stdcall CoLockObjectExternal(ptr long long)
@ -247,7 +247,7 @@
@ stub STGMEDIUM_UserUnmarshal
@ stub StgOpenAsyncDocfileOnIFillLockBytes
@ stdcall StgOpenStorage(wstr ptr long ptr long ptr)
@ stub StgOpenStorageEx
@ stdcall StgOpenStorageEx(wstr long long long ptr ptr ptr ptr)
@ stdcall StgOpenStorageOnILockBytes(ptr ptr long long long ptr)
@ stdcall StgSetTimes(wstr ptr ptr ptr )
@ stdcall StringFromCLSID(ptr ptr)

View file

@ -27,13 +27,11 @@
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "ole32_main.h"
#include "objbase.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
HINSTANCE OLE32_hInstance = 0;
/***********************************************************************
* OleMetafilePictFromIconAndLabel (OLE32.@)
*/
@ -110,33 +108,3 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
return hmem;
}
/***********************************************************************
* DllMain (OLE32.@)
*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
{
TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
OLE32_hInstance = hinstDLL;
COMPOBJ_InitProcess();
if (TRACE_ON(ole)) CoRegisterMallocSpy((LPVOID)-1);
break;
case DLL_PROCESS_DETACH:
if (TRACE_ON(ole)) CoRevokeMallocSpy();
COMPOBJ_UninitProcess();
OLE32_hInstance = 0;
break;
case DLL_THREAD_DETACH:
COM_TlsDestroy();
break;
}
return TRUE;
}
/* NOTE: DllRegisterServer and DllUnregisterServer are in regsvr.c */

View file

@ -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 */

View file

@ -50,60 +50,6 @@ typedef struct OleAdviseHolderImpl
} OleAdviseHolderImpl;
static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor(void);
static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy);
static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*);
static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER);
static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER);
static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*);
static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD);
static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **);
static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *);
static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER);
static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER);
/**************************************************************************
* OleAdviseHolderImpl_VTable
*/
static struct IOleAdviseHolderVtbl oahvt =
{
OleAdviseHolderImpl_QueryInterface,
OleAdviseHolderImpl_AddRef,
OleAdviseHolderImpl_Release,
OleAdviseHolderImpl_Advise,
OleAdviseHolderImpl_Unadvise,
OleAdviseHolderImpl_EnumAdvise,
OleAdviseHolderImpl_SendOnRename,
OleAdviseHolderImpl_SendOnSave,
OleAdviseHolderImpl_SendOnClose
};
/**************************************************************************
* OleAdviseHolderImpl_Constructor
*/
static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
{
OleAdviseHolderImpl* lpoah;
DWORD index;
lpoah = HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl));
lpoah->lpVtbl = &oahvt;
lpoah->ref = 1;
lpoah->maxSinks = INITIAL_SINKS;
lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
0,
lpoah->maxSinks * sizeof(IAdviseSink*));
for (index = 0; index < lpoah->maxSinks; index++)
lpoah->arrayOfSinks[index]=0;
TRACE("returning %p\n", lpoah);
return (LPOLEADVISEHOLDER)lpoah;
}
/**************************************************************************
* OleAdviseHolderImpl_Destructor
*/
@ -357,6 +303,47 @@ OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
return S_OK;
}
/**************************************************************************
* OleAdviseHolderImpl_VTable
*/
static struct IOleAdviseHolderVtbl oahvt =
{
OleAdviseHolderImpl_QueryInterface,
OleAdviseHolderImpl_AddRef,
OleAdviseHolderImpl_Release,
OleAdviseHolderImpl_Advise,
OleAdviseHolderImpl_Unadvise,
OleAdviseHolderImpl_EnumAdvise,
OleAdviseHolderImpl_SendOnRename,
OleAdviseHolderImpl_SendOnSave,
OleAdviseHolderImpl_SendOnClose
};
/**************************************************************************
* OleAdviseHolderImpl_Constructor
*/
static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
{
OleAdviseHolderImpl* lpoah;
DWORD index;
lpoah = HeapAlloc(GetProcessHeap(), 0, sizeof(OleAdviseHolderImpl));
lpoah->lpVtbl = &oahvt;
lpoah->ref = 1;
lpoah->maxSinks = INITIAL_SINKS;
lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
0,
lpoah->maxSinks * sizeof(IAdviseSink*));
for (index = 0; index < lpoah->maxSinks; index++)
lpoah->arrayOfSinks[index]=0;
TRACE("returning %p\n", lpoah);
return (LPOLEADVISEHOLDER)lpoah;
}
/**************************************************************************
* DataAdviseHolder Implementation
*/
@ -375,73 +362,6 @@ typedef struct DataAdviseHolder
DataAdviseConnection* Connections;
} DataAdviseHolder;
/**************************************************************************
* DataAdviseHolder method prototypes
*/
static IDataAdviseHolder* DataAdviseHolder_Constructor(void);
static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy);
static HRESULT WINAPI DataAdviseHolder_QueryInterface(
IDataAdviseHolder* iface,
REFIID riid,
void** ppvObject);
static ULONG WINAPI DataAdviseHolder_AddRef(
IDataAdviseHolder* iface);
static ULONG WINAPI DataAdviseHolder_Release(
IDataAdviseHolder* iface);
static HRESULT WINAPI DataAdviseHolder_Advise(
IDataAdviseHolder* iface,
IDataObject* pDataObject,
FORMATETC* pFetc,
DWORD advf,
IAdviseSink* pAdvise,
DWORD* pdwConnection);
static HRESULT WINAPI DataAdviseHolder_Unadvise(
IDataAdviseHolder* iface,
DWORD dwConnection);
static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
IDataAdviseHolder* iface,
IEnumSTATDATA** ppenumAdvise);
static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
IDataAdviseHolder* iface,
IDataObject* pDataObject,
DWORD dwReserved,
DWORD advf);
/**************************************************************************
* DataAdviseHolderImpl_VTable
*/
static struct IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable =
{
DataAdviseHolder_QueryInterface,
DataAdviseHolder_AddRef,
DataAdviseHolder_Release,
DataAdviseHolder_Advise,
DataAdviseHolder_Unadvise,
DataAdviseHolder_EnumAdvise,
DataAdviseHolder_SendOnDataChange
};
/******************************************************************************
* DataAdviseHolder_Constructor
*/
static IDataAdviseHolder* DataAdviseHolder_Constructor()
{
DataAdviseHolder* newHolder;
newHolder = HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder));
newHolder->lpVtbl = &DataAdviseHolderImpl_VTable;
newHolder->ref = 1;
newHolder->maxCons = INITIAL_SINKS;
newHolder->Connections = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
newHolder->maxCons *
sizeof(DataAdviseConnection));
TRACE("returning %p\n", newHolder);
return (IDataAdviseHolder*)newHolder;
}
/******************************************************************************
* DataAdviseHolder_Destructor
*/
@ -605,7 +525,7 @@ static HRESULT WINAPI DataAdviseHolder_Advise(
if (This->Connections[index].sink != NULL) {
IAdviseSink_AddRef(This->Connections[index].sink);
if(advf & ADVF_PRIMEFIRST) {
DataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
IDataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
}
}
/*
@ -702,6 +622,41 @@ static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
return S_OK;
}
/**************************************************************************
* DataAdviseHolderImpl_VTable
*/
static struct IDataAdviseHolderVtbl DataAdviseHolderImpl_VTable =
{
DataAdviseHolder_QueryInterface,
DataAdviseHolder_AddRef,
DataAdviseHolder_Release,
DataAdviseHolder_Advise,
DataAdviseHolder_Unadvise,
DataAdviseHolder_EnumAdvise,
DataAdviseHolder_SendOnDataChange
};
/******************************************************************************
* DataAdviseHolder_Constructor
*/
static IDataAdviseHolder* DataAdviseHolder_Constructor()
{
DataAdviseHolder* newHolder;
newHolder = HeapAlloc(GetProcessHeap(), 0, sizeof(DataAdviseHolder));
newHolder->lpVtbl = &DataAdviseHolderImpl_VTable;
newHolder->ref = 1;
newHolder->maxCons = INITIAL_SINKS;
newHolder->Connections = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
newHolder->maxCons *
sizeof(DataAdviseConnection));
TRACE("returning %p\n", newHolder);
return (IDataAdviseHolder*)newHolder;
}
/***********************************************************************
* API functions
*/

View file

@ -58,6 +58,7 @@
#include "wtypes.h"
#include "compobj_private.h"
#include "moniker.h"
#include "wine/debug.h"
@ -972,10 +973,8 @@ static IPSFactoryBufferVtbl *lppsfac = &psfacbufvtbl;
HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(rclsid,&CLSID_PSFactoryBuffer)) {
*ppv = &lppsfac;
return S_OK;
}
if (IsEqualIID(rclsid, &CLSID_PSFactoryBuffer))
return IPSFactoryBuffer_QueryInterface((IPSFactoryBuffer *)&lppsfac, iid, ppv);
if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&(
IsEqualIID(iid,&IID_IClassFactory) ||
IsEqualIID(iid,&IID_IUnknown)
@ -984,6 +983,10 @@ HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
return MARSHAL_GetStandardMarshalCF(ppv);
if (IsEqualIID(rclsid,&CLSID_StdGlobalInterfaceTable) && (IsEqualIID(iid,&IID_IClassFactory) || IsEqualIID(iid,&IID_IUnknown)))
return StdGlobalInterfaceTable_GetFactory(ppv);
if (IsEqualCLSID(rclsid, &CLSID_FileMoniker))
return FileMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ItemMoniker))
return ItemMonikerCF_Create(iid, ppv);
FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
return CLASS_E_CLASSNOTAVAILABLE;

View file

@ -30,17 +30,16 @@
* It's a little bit out of date, and more definitive references are given
* below, but it gives the best "big picture" that I've found.
*
* TODO: There's a lot missing in here. Biggies:
* - There are all sorts of restricions I don't honor, like maximum property
* set byte size, maximum property name length
* TODO:
* - I don't honor the maximum property set size.
* - Certain bogus files could result in reading past the end of a buffer.
* - This will probably fail on big-endian machines, especially reading and
* writing strings.
* - Mac-generated files won't be read correctly, even if they're little
* endian, because I disregard whether the generator was a Mac. This means
* strings will probably be munged (as I don't understand Mac scripts.)
* - Not all PROPVARIANT types are supported.
* There are lots more unimplemented features, see FIXMEs below.
* - User defined properties are not supported, see comment in
* PropertyStorage_ReadFromStream
* - IPropertyStorage::Enum is unimplemented
*/
#include <assert.h>
@ -80,6 +79,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage);
#define CP_UNICODE 1200
#define MAX_VERSION_0_PROP_NAME_LENGTH 256
/* The format version (and what it implies) is described here:
* http://msdn.microsoft.com/library/en-us/stg/stg/format_version.asp
*/
@ -130,6 +131,22 @@ static HRESULT PropertyStorage_CreateDictionaries(
static void PropertyStorage_DestroyDictionaries(
struct tagPropertyStorage_impl *);
/* Copies from propvar to prop. If propvar's type is VT_LPSTR, copies the
* string using PropertyStorage_StringCopy.
*/
static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop,
const PROPVARIANT *propvar, LCID targetCP, LCID srcCP);
/* Copies the string src, which is encoded using code page srcCP, and returns
* it in *dst, in the code page specified by targetCP. The returned string is
* allocated using CoTaskMemAlloc.
* If srcCP is CP_UNICODE, src is in fact an LPCWSTR. Similarly, if targetCP
* is CP_UNICODE, the returned string is in fact an LPWSTR.
* Returns S_OK on success, something else on failure.
*/
static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
LCID targetCP);
static IPropertyStorageVtbl IPropertyStorage_Vtbl;
/***********************************************************************
@ -144,6 +161,7 @@ typedef struct tagPropertyStorage_impl
BOOL dirty;
FMTID fmtid;
CLSID clsid;
WORD format;
DWORD originatorOS;
DWORD grfFlags;
DWORD grfMode;
@ -235,8 +253,25 @@ static PROPVARIANT *PropertyStorage_FindPropertyByName(
assert(This);
if (!name)
return NULL;
if (dictionary_find(This->name_to_propid, name, (void **)&propid))
ret = PropertyStorage_FindProperty(This, (PROPID)propid);
if (This->codePage == CP_UNICODE)
{
if (dictionary_find(This->name_to_propid, name, (void **)&propid))
ret = PropertyStorage_FindProperty(This, (PROPID)propid);
}
else
{
LPSTR ansiName;
HRESULT hr = PropertyStorage_StringCopy((LPCSTR)name, CP_UNICODE,
&ansiName, This->codePage);
if (SUCCEEDED(hr))
{
if (dictionary_find(This->name_to_propid, ansiName,
(void **)&propid))
ret = PropertyStorage_FindProperty(This, (PROPID)propid);
CoTaskMemFree(ansiName);
}
}
TRACE("returning %p\n", ret);
return ret;
}
@ -280,34 +315,169 @@ static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
rgpspec[i].u.lpwstr);
if (prop)
PropVariantCopy(&rgpropvar[i], prop);
PropertyStorage_PropVariantCopy(&rgpropvar[i], prop, GetACP(),
This->codePage);
}
else
{
PROPVARIANT *prop = PropertyStorage_FindProperty(This,
rgpspec[i].u.propid);
switch (rgpspec[i].u.propid)
{
case PID_CODEPAGE:
rgpropvar[i].vt = VT_I2;
rgpropvar[i].u.iVal = This->codePage;
break;
case PID_LOCALE:
rgpropvar[i].vt = VT_I4;
rgpropvar[i].u.lVal = This->locale;
break;
default:
{
PROPVARIANT *prop = PropertyStorage_FindProperty(This,
rgpspec[i].u.propid);
if (prop)
PropVariantCopy(&rgpropvar[i], prop);
if (prop)
PropertyStorage_PropVariantCopy(&rgpropvar[i], prop,
GetACP(), This->codePage);
}
}
}
}
LeaveCriticalSection(&This->cs);
return hr;
}
static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
LCID dstCP)
{
HRESULT hr = S_OK;
int len;
TRACE("%s, %p, %ld, %ld\n",
srcCP == CP_UNICODE ? debugstr_w((LPCWSTR)src) : debugstr_a(src), dst,
dstCP, srcCP);
assert(src);
assert(dst);
*dst = NULL;
if (dstCP == srcCP)
{
size_t len;
if (dstCP == CP_UNICODE)
len = (strlenW((LPCWSTR)src) + 1) * sizeof(WCHAR);
else
len = strlen(src) + 1;
*dst = CoTaskMemAlloc(len * sizeof(WCHAR));
if (!*dst)
hr = STG_E_INSUFFICIENTMEMORY;
else
memcpy(*dst, src, len);
}
else
{
if (dstCP == CP_UNICODE)
{
len = MultiByteToWideChar(srcCP, 0, src, -1, NULL, 0);
*dst = CoTaskMemAlloc(len * sizeof(WCHAR));
if (!*dst)
hr = STG_E_INSUFFICIENTMEMORY;
else
MultiByteToWideChar(srcCP, 0, src, -1, (LPWSTR)*dst, len);
}
else
{
LPWSTR wideStr;
if (srcCP == CP_UNICODE)
wideStr = (LPWSTR)src;
else
{
len = MultiByteToWideChar(srcCP, 0, src, -1, NULL, 0);
wideStr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (wideStr)
MultiByteToWideChar(srcCP, 0, src, -1, wideStr, len);
else
hr = STG_E_INSUFFICIENTMEMORY;
}
if (SUCCEEDED(hr))
{
len = WideCharToMultiByte(dstCP, 0, wideStr, -1, NULL, 0,
NULL, NULL);
*dst = CoTaskMemAlloc(len);
if (!*dst)
hr = STG_E_INSUFFICIENTMEMORY;
else
{
BOOL defCharUsed = FALSE;
if (WideCharToMultiByte(dstCP, 0, wideStr, -1, *dst, len,
NULL, &defCharUsed) == 0 || defCharUsed)
{
CoTaskMemFree(*dst);
*dst = NULL;
hr = HRESULT_FROM_WIN32(ERROR_NO_UNICODE_TRANSLATION);
}
}
}
if (wideStr != (LPWSTR)src)
HeapFree(GetProcessHeap(), 0, wideStr);
}
}
TRACE("returning 0x%08lx (%s)\n", hr,
dstCP == CP_UNICODE ? debugstr_w((LPCWSTR)*dst) : debugstr_a(*dst));
return hr;
}
static HRESULT PropertyStorage_PropVariantCopy(PROPVARIANT *prop,
const PROPVARIANT *propvar, LCID targetCP, LCID srcCP)
{
HRESULT hr = S_OK;
assert(prop);
assert(propvar);
if (propvar->vt == VT_LPSTR)
{
hr = PropertyStorage_StringCopy(propvar->u.pszVal, srcCP,
&prop->u.pszVal, targetCP);
if (SUCCEEDED(hr))
prop->vt = VT_LPSTR;
}
else
PropVariantCopy(prop, propvar);
return hr;
}
/* Stores the property with id propid and value propvar into this property
* storage. lcid is ignored if propvar's type is not VT_LPSTR. If propvar's
* type is VT_LPSTR, converts the string using lcid as the source code page
* and This->codePage as the target code page before storing.
* As a side effect, may change This->format to 1 if the type of propvar is
* a version 1-only property.
*/
static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
PROPID propid, const PROPVARIANT *propvar)
PROPID propid, const PROPVARIANT *propvar, LCID lcid)
{
HRESULT hr = S_OK;
PROPVARIANT *prop = PropertyStorage_FindProperty(This, propid);
assert(This);
assert(propvar);
if (propvar->vt & VT_BYREF || propvar->vt & VT_ARRAY)
This->format = 1;
switch (propvar->vt)
{
case VT_DECIMAL:
case VT_I1:
case VT_INT:
case VT_UINT:
case VT_VECTOR|VT_I1:
This->format = 1;
}
TRACE("Setting 0x%08lx to type %d\n", propid, propvar->vt);
if (prop)
{
PropVariantClear(prop);
PropVariantCopy(prop, propvar);
hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
lcid);
}
else
{
@ -315,10 +485,16 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
sizeof(PROPVARIANT));
if (prop)
{
PropVariantCopy(prop, propvar);
dictionary_insert(This->propid_to_prop, (void *)propid, prop);
if (propid > This->highestProp)
This->highestProp = propid;
hr = PropertyStorage_PropVariantCopy(prop, propvar, This->codePage,
lcid);
if (SUCCEEDED(hr))
{
dictionary_insert(This->propid_to_prop, (void *)propid, prop);
if (propid > This->highestProp)
This->highestProp = propid;
}
else
HeapFree(GetProcessHeap(), 0, prop);
}
else
hr = STG_E_INSUFFICIENTMEMORY;
@ -326,6 +502,43 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
return hr;
}
/* Adds the name srcName to the name dictionaries, mapped to property ID id.
* srcName is encoded in code page cp, and is converted to This->codePage.
* If cp is CP_UNICODE, srcName is actually a unicode string.
* As a side effect, may change This->format to 1 if srcName is too long for
* a version 0 property storage.
* Doesn't validate id.
*/
static HRESULT PropertyStorage_StoreNameWithId(PropertyStorage_impl *This,
LPCSTR srcName, LCID cp, PROPID id)
{
LPSTR name;
HRESULT hr;
assert(srcName);
hr = PropertyStorage_StringCopy((LPCSTR)srcName, cp, &name, This->codePage);
if (SUCCEEDED(hr))
{
if (This->codePage == CP_UNICODE)
{
if (lstrlenW((LPWSTR)name) >= MAX_VERSION_0_PROP_NAME_LENGTH)
This->format = 1;
}
else
{
if (strlen(name) >= MAX_VERSION_0_PROP_NAME_LENGTH)
This->format = 1;
}
TRACE("Adding prop name %s, propid %ld\n",
This->codePage == CP_UNICODE ? debugstr_w((LPCWSTR)name) :
debugstr_a(name), id);
dictionary_insert(This->name_to_propid, name, (void *)id);
dictionary_insert(This->propid_to_name, (void *)id, name);
}
return hr;
}
/************************************************************************
* IPropertyStorage_fnWriteMultiple (IPropertyStorage)
*/
@ -371,19 +584,12 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
else
{
PROPID nextId = max(propidNameFirst, This->highestProp + 1);
size_t len = strlenW(rgpspec[i].u.lpwstr) + 1;
LPWSTR name = HeapAlloc(GetProcessHeap(), 0,
len * sizeof(WCHAR));
strcpyW(name, rgpspec[i].u.lpwstr);
TRACE("Adding prop name %s, propid %ld\n", debugstr_w(name),
nextId);
dictionary_insert(This->name_to_propid, name,
(void *)nextId);
dictionary_insert(This->propid_to_name, (void *)nextId,
name);
hr = PropertyStorage_StorePropWithId(This, nextId,
&rgpropvar[i]);
hr = PropertyStorage_StoreNameWithId(This,
(LPCSTR)rgpspec[i].u.lpwstr, CP_UNICODE, nextId);
if (SUCCEEDED(hr))
hr = PropertyStorage_StorePropWithId(This, nextId,
&rgpropvar[i], GetACP());
}
}
}
@ -399,7 +605,13 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
/* Can only set the code page if nothing else has been set */
if (dictionary_num_entries(This->propid_to_prop) == 0 &&
rgpropvar[i].vt == VT_I2)
{
This->codePage = rgpropvar[i].u.iVal;
if (This->codePage == CP_UNICODE)
This->grfFlags &= ~PROPSETFLAG_ANSI;
else
This->grfFlags |= PROPSETFLAG_ANSI;
}
else
hr = STG_E_INVALIDPARAMETER;
break;
@ -419,7 +631,7 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
hr = STG_E_INVALIDPARAMETER;
else
hr = PropertyStorage_StorePropWithId(This,
rgpspec[i].u.propid, &rgpropvar[i]);
rgpspec[i].u.propid, &rgpropvar[i], GetACP());
}
}
}
@ -541,17 +753,11 @@ static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
hr = S_OK;
EnterCriticalSection(&This->cs);
This->dirty = TRUE;
for (i = 0; i < cpropid; i++)
for (i = 0; SUCCEEDED(hr) && i < cpropid; i++)
{
if (rgpropid[i] != PID_ILLEGAL)
{
size_t len = lstrlenW(rglpwstrName[i]) + 1;
LPWSTR name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
strcpyW(name, rglpwstrName[i]);
dictionary_insert(This->name_to_propid, name, (void *)rgpropid[i]);
dictionary_insert(This->propid_to_name, (void *)rgpropid[i], name);
}
hr = PropertyStorage_StoreNameWithId(This, (LPCSTR)rglpwstrName[i],
CP_UNICODE, rgpropid[i]);
}
if (This->grfFlags & PROPSETFLAG_UNBUFFERED)
IPropertyStorage_Commit(iface, STGC_DEFAULT);
@ -728,20 +934,27 @@ static int PropertyStorage_PropNameCompare(const void *a, const void *b,
{
PropertyStorage_impl *This = (PropertyStorage_impl *)extra;
TRACE("(%s, %s)\n", debugstr_w(a), debugstr_w(b));
/* FIXME: this assumes property names are always Unicode, but they
* might be ANSI, depending on whether This->grfFlags & PROPSETFLAG_ANSI
* is true.
*/
if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
return strcmpW((LPCWSTR)a, (LPCWSTR)b);
if (This->codePage == CP_UNICODE)
{
TRACE("(%s, %s)\n", debugstr_w(a), debugstr_w(b));
if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
return lstrcmpW((LPCWSTR)a, (LPCWSTR)b);
else
return lstrcmpiW((LPCWSTR)a, (LPCWSTR)b);
}
else
return strcmpiW((LPCWSTR)a, (LPCWSTR)b);
{
TRACE("(%s, %s)\n", debugstr_a(a), debugstr_a(b));
if (This->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
return lstrcmpA((LPCSTR)a, (LPCSTR)b);
else
return lstrcmpiA((LPCSTR)a, (LPCSTR)b);
}
}
static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
{
HeapFree(GetProcessHeap(), 0, k);
CoTaskMemFree(k);
}
static int PropertyStorage_PropCompare(const void *a, const void *b,
@ -757,12 +970,28 @@ static void PropertyStorage_PropertyDestroy(void *k, void *d, void *extra)
HeapFree(GetProcessHeap(), 0, d);
}
#ifdef WORDS_BIGENDIAN
/* Swaps each character in str to or from little endian; assumes the conversion
* is symmetric, that is, that le16toh is equivalent to htole16.
*/
static void PropertyStorage_ByteSwapString(LPWSTR str, size_t len)
{
DWORD i;
/* Swap characters to host order.
* FIXME: alignment?
*/
for (i = 0; i < len; i++)
str[i] = le16toh(str[i]);
}
#else
#define PropertyStorage_ByteSwapString(s, l)
#endif
/* Reads the dictionary from the memory buffer beginning at ptr. Interprets
* the entries according to the values of This->codePage and This->locale.
* FIXME: there isn't any checking whether the read property extends past the
* end of the buffer.
* FIXME: this always stores dictionary entries as Unicode, but it should store
* them as ANSI if (This->grfFlags & PROPSETFLAG_ANSI) is true.
*/
static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
BYTE *ptr)
@ -781,49 +1010,24 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
{
PROPID propid;
DWORD cbEntry;
LPWSTR name = NULL;
StorageUtl_ReadDWord(ptr, 0, &propid);
ptr += sizeof(PROPID);
StorageUtl_ReadDWord(ptr, 0, &cbEntry);
ptr += sizeof(DWORD);
/* FIXME: if host is big-endian, this'll suck to convert */
TRACE("Reading entry with ID 0x%08lx, %ld bytes\n", propid, cbEntry);
/* Make sure the source string is NULL-terminated */
if (This->codePage != CP_UNICODE)
{
int len = MultiByteToWideChar(This->codePage, 0, ptr, cbEntry,
NULL, 0);
if (!len)
hr = HRESULT_FROM_WIN32(GetLastError());
else
{
name = HeapAlloc(GetProcessHeap(), 0,
len * sizeof(WCHAR));
if (name)
MultiByteToWideChar(This->codePage, 0, ptr, cbEntry, name,
len);
else
hr = STG_E_INSUFFICIENTMEMORY;
}
}
ptr[cbEntry - 1] = '\0';
else
*((LPWSTR)ptr + cbEntry / sizeof(WCHAR)) = '\0';
hr = PropertyStorage_StoreNameWithId(This, ptr, This->codePage, propid);
if (This->codePage == CP_UNICODE)
{
name = HeapAlloc(GetProcessHeap(), 0, cbEntry);
if (name)
lstrcpyW(name, (LPWSTR)ptr);
else
hr = STG_E_INSUFFICIENTMEMORY;
/* Unicode entries are padded to DWORD boundaries */
if (cbEntry % sizeof(DWORD))
ptr += sizeof(DWORD) - (cbEntry % sizeof(DWORD));
}
if (name)
{
dictionary_insert(This->name_to_propid, name, (void *)propid);
dictionary_insert(This->propid_to_name, (void *)propid, name);
TRACE("Property %s maps to id %ld\n", debugstr_w(name), propid);
}
ptr += sizeof(DWORD) + cbEntry;
}
return hr;
@ -832,7 +1036,8 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
/* FIXME: there isn't any checking whether the read property extends past the
* end of the buffer.
*/
static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
PROPVARIANT *prop, const BYTE *data)
{
HRESULT hr = S_OK;
@ -861,10 +1066,12 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
StorageUtl_ReadWord(data, 0, &prop->u.uiVal);
TRACE("Read ushort %d\n", prop->u.uiVal);
break;
case VT_INT:
case VT_I4:
StorageUtl_ReadDWord(data, 0, &prop->u.lVal);
TRACE("Read long %ld\n", prop->u.lVal);
break;
case VT_UINT:
case VT_UI4:
StorageUtl_ReadDWord(data, 0, &prop->u.ulVal);
TRACE("Read ulong %ld\n", prop->u.ulVal);
@ -874,18 +1081,37 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
DWORD count;
StorageUtl_ReadDWord(data, 0, &count);
prop->u.pszVal = CoTaskMemAlloc(count);
if (prop->u.pszVal)
if (This->codePage == CP_UNICODE && count / 2)
{
/* FIXME: if the host is big-endian, this'll suck */
memcpy(prop->u.pszVal, data + sizeof(DWORD), count);
/* FIXME: so far so good, but this may be Unicode or DBCS depending
* on This->codePage.
*/
TRACE("Read string value %s\n", debugstr_a(prop->u.pszVal));
WARN("Unicode string has odd number of bytes\n");
hr = STG_E_INVALIDHEADER;
}
else
hr = STG_E_INSUFFICIENTMEMORY;
{
prop->u.pszVal = CoTaskMemAlloc(count);
if (prop->u.pszVal)
{
memcpy(prop->u.pszVal, data + sizeof(DWORD), count);
/* This is stored in the code page specified in This->codePage.
* Don't convert it, the caller will just store it as-is.
*/
if (This->codePage == CP_UNICODE)
{
/* Make sure it's NULL-terminated */
prop->u.pszVal[count / sizeof(WCHAR) - 1] = '\0';
TRACE("Read string value %s\n",
debugstr_w(prop->u.pwszVal));
}
else
{
/* Make sure it's NULL-terminated */
prop->u.pszVal[count - 1] = '\0';
TRACE("Read string value %s\n", debugstr_a(prop->u.pszVal));
}
}
else
hr = STG_E_INSUFFICIENTMEMORY;
}
break;
}
case VT_LPWSTR:
@ -896,9 +1122,11 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
prop->u.pwszVal = CoTaskMemAlloc(count * sizeof(WCHAR));
if (prop->u.pwszVal)
{
/* FIXME: if the host is big-endian, gotta swap every char */
memcpy(prop->u.pwszVal, data + sizeof(DWORD),
count * sizeof(WCHAR));
/* make sure string is NULL-terminated */
prop->u.pwszVal[count - 1] = '\0';
PropertyStorage_ByteSwapString(prop->u.pwszVal, count);
TRACE("Read string value %s\n", debugstr_w(prop->u.pwszVal));
}
else
@ -906,8 +1134,8 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data)
break;
}
case VT_FILETIME:
/* FIXME: endianness */
memcpy(&prop->u.filetime, data, sizeof(FILETIME));
StorageUtl_ReadULargeInteger(data, 0,
(ULARGE_INTEGER *)&prop->u.filetime);
break;
default:
FIXME("unsupported type %d\n", prop->vt);
@ -1068,6 +1296,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
hr = STG_E_INVALIDHEADER;
goto end;
}
This->format = hdr.wFormat;
memcpy(&This->clsid, &hdr.clsid, sizeof(This->clsid));
This->originatorOS = hdr.dwOSVer;
if (PROPSETHDR_OSVER_KIND(hdr.dwOSVer) == PROPSETHDR_OSVER_KIND_MAC)
@ -1139,7 +1368,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
{
PROPVARIANT prop;
if (SUCCEEDED(PropertyStorage_ReadProperty(&prop,
if (SUCCEEDED(PropertyStorage_ReadProperty(This, &prop,
buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER))))
{
TRACE("Read property with ID 0x%08lx, type %d\n",
@ -1157,10 +1386,12 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
case PID_BEHAVIOR:
if (prop.vt == VT_I4 && prop.u.lVal)
This->grfFlags |= PROPSETFLAG_CASE_SENSITIVE;
/* The format should already be 1, but just in case */
This->format = 1;
break;
default:
hr = PropertyStorage_StorePropWithId(This,
idOffset->propid, &prop);
idOffset->propid, &prop, This->codePage);
}
}
}
@ -1204,11 +1435,7 @@ static void PropertyStorage_MakeHeader(PropertyStorage_impl *This,
assert(hdr);
StorageUtl_WriteWord((BYTE *)&hdr->wByteOrder, 0,
PROPSETHDR_BYTEORDER_MAGIC);
/* FIXME: should be able to write format 0 property sets too, depending
* on whether I have too long string names or if case-sensitivity is set.
* For now always write format 1.
*/
StorageUtl_WriteWord((BYTE *)&hdr->wFormat, 0, 1);
StorageUtl_WriteWord((BYTE *)&hdr->wFormat, 0, This->format);
StorageUtl_WriteDWord((BYTE *)&hdr->dwOSVer, 0, This->originatorOS);
StorageUtl_WriteGUID((BYTE *)&hdr->clsid, 0, &This->clsid);
StorageUtl_WriteDWord((BYTE *)&hdr->reserved, 0, 1);
@ -1274,8 +1501,12 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
if (FAILED(c->hr))
goto end;
c->bytesWritten += sizeof(DWORD);
/* FIXME: endian-convert every char (yuck) */
/* Rather than allocate a copy, I'll swap the string to little-endian
* in-place, write it, then swap it back.
*/
PropertyStorage_ByteSwapString(key, keyLen);
c->hr = IStream_Write(This->stm, key, keyLen, &count);
PropertyStorage_ByteSwapString(key, keyLen);
if (FAILED(c->hr))
goto end;
c->bytesWritten += keyLen;
@ -1290,35 +1521,17 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
}
else
{
int len = WideCharToMultiByte(This->codePage, 0, (LPWSTR)key, -1, NULL,
0, NULL, NULL);
LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, len);
DWORD dwLen;
DWORD keyLen;
if (!buf)
{
c->hr = STG_E_INSUFFICIENTMEMORY;
goto end;
}
/* FIXME: endian-convert multibyte chars? Ick! */
WideCharToMultiByte(This->codePage, 0, (LPWSTR)key, -1, buf, len,
NULL, NULL);
StorageUtl_WriteDWord((LPBYTE)&dwLen, 0, len);
c->hr = IStream_Write(This->stm, &dwLen, sizeof(dwLen), &count);
StorageUtl_WriteDWord((LPBYTE)&keyLen, 0, strlen((LPCSTR)key) + 1);
c->hr = IStream_Write(This->stm, &keyLen, sizeof(keyLen), &count);
if (FAILED(c->hr))
{
HeapFree(GetProcessHeap(), 0, buf);
goto end;
}
c->bytesWritten += sizeof(DWORD);
c->hr = IStream_Write(This->stm, buf, len, &count);
c->hr = IStream_Write(This->stm, key, keyLen, &count);
if (FAILED(c->hr))
{
HeapFree(GetProcessHeap(), 0, buf);
goto end;
}
c->bytesWritten += len;
HeapFree(GetProcessHeap(), 0, buf);
c->bytesWritten += keyLen;
}
end:
return SUCCEEDED(c->hr);
@ -1482,6 +1695,16 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
bytesWritten = count + sizeof(DWORD);
break;
}
case VT_FILETIME:
{
FILETIME temp;
StorageUtl_WriteULargeInteger((BYTE *)&temp, 0,
(ULARGE_INTEGER *)&var->u.filetime);
hr = IStream_Write(This->stm, &temp, sizeof(FILETIME), &count);
bytesWritten = count;
break;
}
default:
FIXME("unsupported type: %d\n", var->vt);
return STG_E_INVALIDPARAMETER;
@ -1723,7 +1946,7 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
assert(pps);
assert(rfmtid);
*pps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof **pps);
if (!pps)
if (!*pps)
return E_OUTOFMEMORY;
(*pps)->vtbl = &IPropertyStorage_Vtbl;
@ -1734,6 +1957,13 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
(*pps)->grfMode = grfMode;
hr = PropertyStorage_CreateDictionaries(*pps);
if (FAILED(hr))
{
IStream_Release(stm);
DeleteCriticalSection(&(*pps)->cs);
HeapFree(GetProcessHeap(), 0, *pps);
*pps = NULL;
}
return hr;
}
@ -1774,7 +2004,10 @@ static HRESULT PropertyStorage_ConstructEmpty(IStream *stm,
hr = PropertyStorage_BaseConstruct(stm, rfmtid, grfMode, &ps);
if (SUCCEEDED(hr))
{
ps->format = 0;
ps->grfFlags = grfFlags;
if (ps->grfFlags & PROPSETFLAG_CASE_SENSITIVE)
ps->format = 1;
/* default to Unicode unless told not to, as specified here:
* http://msdn.microsoft.com/library/en-us/stg/stg/names_in_istorage.asp
*/
@ -2106,12 +2339,12 @@ HRESULT WINAPI FmtIdToPropStgName(const FMTID *rfmtid, LPOLESTR str)
*/
HRESULT WINAPI PropStgNameToFmtId(const LPOLESTR str, FMTID *rfmtid)
{
HRESULT hr = E_INVALIDARG;
HRESULT hr = STG_E_INVALIDNAME;
TRACE("%s, %p\n", debugstr_w(str), rfmtid);
if (!rfmtid) return E_INVALIDARG;
if (!str) return E_INVALIDARG;
if (!str) return STG_E_INVALIDNAME;
if (!lstrcmpiW(str, szDocSummaryInfo))
{

View file

@ -296,6 +296,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
StgProperty currentProperty;
ULONG foundPropertyIndex;
HRESULT res = STG_E_UNKNOWN;
DWORD parent_grfMode;
TRACE("(%p, %s, %p, %lx, %ld, %p)\n",
iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm);
@ -334,6 +335,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
goto end;
}
/*
* Check that we're compatible with the parent's storage mode
*/
parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
{
res = STG_E_ACCESSDENIED;
goto end;
}
/*
* Create a property enumeration to search the properties
*/
@ -412,6 +423,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
StgProperty currentProperty;
ULONG foundPropertyIndex;
HRESULT res = STG_E_UNKNOWN;
DWORD parent_grfMode;
TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n",
iface, debugstr_w(pwcsName), pstgPriority,
@ -453,6 +465,16 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
goto end;
}
/*
* Check that we're compatible with the parent's storage mode
*/
parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
{
res = STG_E_ACCESSDENIED;
goto end;
}
/*
* Initialize the out parameter
*/
@ -489,6 +511,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
*/
newStorage = StorageInternalImpl_Construct(
This->ancestorStorage,
grfMode,
foundPropertyIndex);
if (newStorage != 0)
@ -804,6 +827,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
StgStreamImpl* newStream;
StgProperty currentProperty, newStreamProperty;
ULONG foundPropertyIndex, newPropertyIndex;
DWORD parent_grfMode;
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
iface, debugstr_w(pwcsName), grfMode,
@ -837,6 +861,13 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
(grfMode & STGM_TRANSACTED))
return STG_E_INVALIDFUNCTION;
/*
* Check that we're compatible with the parent's storage mode
*/
parent_grfMode = STGM_ACCESS_MODE( This->ancestorStorage->base.openFlags );
if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
return STG_E_ACCESSDENIED;
/*
* Initialize the out parameter
*/
@ -1005,6 +1036,7 @@ HRESULT WINAPI StorageImpl_CreateStorage(
ULONG foundPropertyIndex;
ULONG newPropertyIndex;
HRESULT hr;
DWORD parent_grfMode;
TRACE("(%p, %s, %lx, %ld, %ld, %p)\n",
iface, debugstr_w(pwcsName), grfMode,
@ -1026,6 +1058,13 @@ HRESULT WINAPI StorageImpl_CreateStorage(
(grfMode & STGM_DELETEONRELEASE) )
return STG_E_INVALIDFLAG;
/*
* Check that we're compatible with the parent's storage mode
*/
parent_grfMode = STGM_ACCESS_MODE( This->base.ancestorStorage->base.openFlags );
if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
return STG_E_ACCESSDENIED;
/*
* Initialize the out parameter
*/
@ -2186,6 +2225,7 @@ HRESULT StorageImpl_Construct(
This->base.lpVtbl = &Storage32Impl_Vtbl;
This->base.pssVtbl = &IPropertySetStorage_Vtbl;
This->base.v_destructor = &StorageImpl_Destroy;
This->base.openFlags = openFlags;
/*
* This is the top-level storage so initialize the ancestor pointer
@ -2379,7 +2419,7 @@ void StorageImpl_Destroy(StorageBaseImpl* iface)
BlockChainStream_Destroy(This->smallBlockDepotChain);
BIGBLOCKFILE_Destructor(This->bigBlockFile);
return;
HeapFree(GetProcessHeap(), 0, This);
}
/******************************************************************************
@ -4013,7 +4053,8 @@ static IStorageVtbl Storage32InternalImpl_Vtbl =
StorageInternalImpl* StorageInternalImpl_Construct(
StorageImpl* ancestorStorage,
ULONG rootPropertyIndex)
DWORD openFlags,
ULONG rootPropertyIndex)
{
StorageInternalImpl* newStorage;
@ -4031,6 +4072,7 @@ StorageInternalImpl* StorageInternalImpl_Construct(
*/
newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl;
newStorage->base.v_destructor = &StorageInternalImpl_Destroy;
newStorage->base.openFlags = openFlags;
/*
* Keep the ancestor storage pointer and nail a reference to it.
@ -4051,30 +4093,64 @@ StorageInternalImpl* StorageInternalImpl_Construct(
/******************************************************************************
** StorageUtl implementation
* FIXME: these should read and write in little-endian order on all
* architectures, but right now just assume the host is little-endian.
*/
void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value)
{
memcpy(value, buffer+offset, sizeof(WORD));
WORD tmp;
memcpy(&tmp, buffer+offset, sizeof(WORD));
*value = le16toh(tmp);
}
void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value)
{
value = htole16(value);
memcpy(buffer+offset, &value, sizeof(WORD));
}
void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value)
{
memcpy(value, buffer+offset, sizeof(DWORD));
DWORD tmp;
memcpy(&tmp, buffer+offset, sizeof(DWORD));
*value = le32toh(tmp);
}
void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value)
{
value = htole32(value);
memcpy(buffer+offset, &value, sizeof(DWORD));
}
void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset,
ULARGE_INTEGER* value)
{
#ifdef WORDS_BIGENDIAN
ULARGE_INTEGER tmp;
memcpy(&tmp, buffer + offset, sizeof(ULARGE_INTEGER));
value->u.LowPart = htole32(tmp.u.HighPart);
value->u.HighPart = htole32(tmp.u.LowPart);
#else
memcpy(value, buffer + offset, sizeof(ULARGE_INTEGER));
#endif
}
void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
const ULARGE_INTEGER *value)
{
#ifdef WORDS_BIGENDIAN
ULARGE_INTEGER tmp;
tmp.u.LowPart = htole32(value->u.HighPart);
tmp.u.HighPart = htole32(value->u.LowPart);
memcpy(buffer + offset, &tmp, sizeof(ULARGE_INTEGER));
#else
memcpy(buffer + offset, value, sizeof(ULARGE_INTEGER));
#endif
}
void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value)
{
StorageUtl_ReadDWord(buffer, offset, &(value->Data1));
@ -5579,7 +5655,33 @@ HRESULT WINAPI StgCreateStorageEx(const WCHAR* pwcsName, DWORD grfMode, DWORD st
{
TRACE("(%s, %lx, %lx, %lx, %p, %p, %p, %p)\n", debugstr_w(pwcsName),
grfMode, stgfmt, grfAttrs, pStgOptions, reserved, riid, ppObjectOpen);
return STG_E_UNIMPLEMENTEDFUNCTION;
if (stgfmt != STGFMT_FILE && grfAttrs != 0)
{
ERR("grfAttrs must be 0 if stgfmt != STGFMT_FILE\n");
return STG_E_INVALIDPARAMETER;
}
if (stgfmt != STGFMT_FILE && grfAttrs != 0 && grfAttrs != FILE_FLAG_NO_BUFFERING)
{
ERR("grfAttrs must be 0 or FILE_FLAG_NO_BUFFERING if stgfmt == STGFMT_FILE\n");
return STG_E_INVALIDPARAMETER;
}
if (stgfmt == STGFMT_FILE)
{
ERR("Cannot use STGFMT_FILE - this is NTFS only\n");
return STG_E_INVALIDPARAMETER;
}
if (stgfmt == STGFMT_STORAGE || stgfmt == STGFMT_DOCFILE)
{
FIXME("Stub: calling StgCreateDocfile, but ignoring pStgOptions and grfAttrs\n");
return StgCreateDocfile(pwcsName, grfMode, 0, (IStorage **)ppObjectOpen);
}
ERR("Invalid stgfmt argument\n");
return STG_E_INVALIDPARAMETER;
}
/******************************************************************************
@ -5599,6 +5701,45 @@ HRESULT WINAPI StgCreatePropSetStg(IStorage *pstg, DWORD reserved,
return hr;
}
/******************************************************************************
* StgOpenStorageEx [OLE32.@]
*/
HRESULT WINAPI StgOpenStorageEx(const WCHAR* pwcsName, DWORD grfMode, DWORD stgfmt, DWORD grfAttrs, STGOPTIONS* pStgOptions, void* reserved, REFIID riid, void** ppObjectOpen)
{
TRACE("(%s, %lx, %lx, %lx, %p, %p, %p, %p)\n", debugstr_w(pwcsName),
grfMode, stgfmt, grfAttrs, pStgOptions, reserved, riid, ppObjectOpen);
if (stgfmt != STGFMT_DOCFILE && grfAttrs != 0)
{
ERR("grfAttrs must be 0 if stgfmt != STGFMT_DOCFILE\n");
return STG_E_INVALIDPARAMETER;
}
if (stgfmt != STGFMT_DOCFILE && grfAttrs != 0 && grfAttrs != FILE_FLAG_NO_BUFFERING)
{
ERR("grfAttrs must be 0 or FILE_FLAG_NO_BUFFERING if stgfmt == STGFMT_DOCFILE\n");
return STG_E_INVALIDPARAMETER;
}
if (stgfmt == STGFMT_FILE)
{
ERR("Cannot use STGFMT_FILE - this is NTFS only\n");
return STG_E_INVALIDPARAMETER;
}
if (stgfmt == STGFMT_STORAGE || stgfmt == STGFMT_DOCFILE || stgfmt == STGFMT_ANY)
{
if (stgfmt == STGFMT_ANY)
WARN("STGFMT_ANY assuming storage\n");
FIXME("Stub: calling StgOpenStorage, but ignoring pStgOptions and grfAttrs\n");
return StgOpenStorage(pwcsName, NULL, grfMode, (SNB)NULL, 0, (IStorage **)ppObjectOpen);
}
ERR("Invalid stgfmt argument\n");
return STG_E_INVALIDPARAMETER;
}
/******************************************************************************
* StgOpenStorage [OLE32.@]
*/

View file

@ -35,6 +35,8 @@
#include "winbase.h"
#include "winnt.h"
#include "objbase.h"
#include "winreg.h"
#include "winternl.h"
/*
* Definitions for the file format offsets.
@ -237,6 +239,11 @@ struct StorageBaseImpl
* virtual Destructor method.
*/
void (*v_destructor)(StorageBaseImpl*);
/*
* flags that this storage was opened or created with
*/
DWORD openFlags;
};
@ -397,6 +404,7 @@ struct StorageInternalImpl
*/
StorageInternalImpl* StorageInternalImpl_Construct(
StorageImpl* ancestorStorage,
DWORD openFlags,
ULONG rootTropertyIndex);
void StorageInternalImpl_Destroy(
@ -524,15 +532,38 @@ StgStreamImpl* StgStreamImpl_Construct(
ULONG ownerProperty);
/********************************************************************************
* The StorageUtl_ functions are miscelaneous utility functions. Most of which are
* abstractions used to read values from file buffers without having to worry
* about bit order
/******************************************************************************
* Endian conversion macros
*/
#ifdef WORDS_BIGENDIAN
#define htole32(x) RtlUlongByteSwap(x)
#define htole16(x) RtlUshortByteSwap(x)
#define le32toh(x) RtlUlongByteSwap(x)
#define le16toh(x) RtlUshortByteSwap(x)
#else
#define htole32(x) (x)
#define htole16(x) (x)
#define le32toh(x) (x)
#define le16toh(x) (x)
#endif
/******************************************************************************
* The StorageUtl_ functions are miscellaneous utility functions. Most of which
* are abstractions used to read values from file buffers without having to
* worry about bit order
*/
void StorageUtl_ReadWord(const BYTE* buffer, ULONG offset, WORD* value);
void StorageUtl_WriteWord(BYTE* buffer, ULONG offset, WORD value);
void StorageUtl_ReadDWord(const BYTE* buffer, ULONG offset, DWORD* value);
void StorageUtl_WriteDWord(BYTE* buffer, ULONG offset, DWORD value);
void StorageUtl_ReadULargeInteger(const BYTE* buffer, ULONG offset,
ULARGE_INTEGER* value);
void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
const ULARGE_INTEGER *value);
void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value);
void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination,

View file

@ -50,6 +50,10 @@
#define STG_LAYOUT_INTERLEAVED 1
#define COM_RIGHTS_EXECUTE 1
#define COM_RIGHTS_SAFE_FOR_SCRIPTING 2
#define STGFMT_STORAGE 0
#define STGFMT_FILE 3
#define STGFMT_ANY 4
#define STGFMT_DOCFILE 5
typedef enum tagREGCLS {
REGCLS_SINGLEUSE = 0,
REGCLS_MULTIPLEUSE = 1,