update riched20,ole32,oleaut32 to latest wine versions

disable ks,portcls,wdm because of broken ks.h
updated psdk,ddk headers
updated uuid and wine libs
implement IdlHeader handling in rbuild
added new idl files and removed the old header files
TODO: get rid of the WINELIB_NAME_AW macros, fix ks.h

svn path=/trunk/; revision=26428
This commit is contained in:
Christoph von Wittich 2007-04-20 02:30:53 +00:00
parent dfb2099f2c
commit 1f121135ab
288 changed files with 81424 additions and 47222 deletions

View File

@ -1,4 +1,5 @@
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
@ -7,8 +8,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Display Panel\0"
#define REACTOS_STR_INTERNAL_NAME "desk\0"
#define REACTOS_STR_ORIGINAL_FILENAME "desk.cpl\0"
//#include <reactos/version.rc>
#include <reactos/version.rc>
IDC_DESK_ICON ICON "resources/applet.ico"
IDC_DESK_ICON2 ICON "resources/applet.ico"
@ -29,3 +29,4 @@ IDC_MONITOR BITMAP "resources/monitor.bmp"
#include "lang/ru-RU.rc"
#include "lang/sv-SE.rc"
#include "lang/uk-UA.rc"

View File

@ -1,8 +1,6 @@
#ifndef __CPL_DESK_RESOURCE_H__
#define __CPL_DESK_RESOURCE_H__
#include <commctrl.h>
/* metrics */
#define PROPSHEETWIDTH 246
#define PROPSHEETHEIGHT 228

View File

@ -14,7 +14,7 @@
#define COM_NO_WINDOWS_H
#define _COMDLG32_
#if defined (_MSC_VER)
//#if defined (_MSC_VER)
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
@ -27,32 +27,23 @@
#include <guiddef.h>
#include <dlgs.h>
#include <cderr.h>
#endif
#include "wine/windef.h"
#include "winbase.h"
#include "wine/wingdi.h"
#include "wine/winuser.h"
#include "wine/commdlg.h"
#include "wine/shellapi.h"
//#endif
#if !defined (_MSC_VER)
#include "psdk/shlguid.h"
#include "psdk/shlobj.h"
#endif
#include "wine/shlguid.h"
#include "wine/shlobj.h"
#include "shlguid.h"
#include "shlobj.h"
#if !defined (_MSC_VER)
#include "psdk/shlguid.h"
#include "psdk/shlwapi.h"
#include "wine/shlwapi.h"
#endif
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "wine/guiddef.h"
#include "wine/dlgs.h"
#include "wine/debug.h"
#include "wine/unicode.h"

View File

@ -1,4 +1,4 @@
/***************************************************************************************
/*
* AntiMonikers implementation
*
* Copyright 1999 Noomen Hamza
@ -15,8 +15,8 @@
*
* 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
***************************************************************************************/
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
@ -35,10 +35,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
const CLSID CLSID_AntiMoniker = {
0x305, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
};
/* AntiMoniker data structure */
typedef struct AntiMonikerImpl{
@ -51,6 +47,7 @@ typedef struct AntiMonikerImpl{
LONG ref; /* reference counter for this object */
IUnknown *pMarshal; /* custom marshaler */
} AntiMonikerImpl;
static inline IMoniker *impl_from_IROTData( IROTData *iface )
@ -84,6 +81,15 @@ AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
*ppvObject = iface;
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)
@ -122,7 +128,11 @@ AntiMonikerImpl_Release(IMoniker* iface)
ref = InterlockedDecrement(&This->ref);
/* destroy the object if there's no more reference on it */
if (ref == 0) HeapFree(GetProcessHeap(),0,This);
if (ref == 0)
{
if (This->pMarshal) IUnknown_Release(This->pMarshal);
HeapFree(GetProcessHeap(),0,This);
}
return ref;
}
@ -133,7 +143,7 @@ AntiMonikerImpl_Release(IMoniker* iface)
static HRESULT WINAPI
AntiMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
{
TRACE("(%p,%p),stub!\n",iface,pClassID);
TRACE("(%p,%p)\n",iface,pClassID);
if (pClassID==NULL)
return E_POINTER;
@ -202,7 +212,7 @@ AntiMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
{
TRACE("(%p,%p)\n",iface,pcbSize);
if (pcbSize!=NULL)
if (!pcbSize)
return E_POINTER;
/* for more details see AntiMonikerImpl_Save coments */
@ -248,7 +258,7 @@ static HRESULT WINAPI
AntiMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
@ -325,7 +335,7 @@ static HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
if (pdwHash==NULL)
return E_POINTER;
*pdwHash=0;
*pdwHash = 0x80000001;
return S_OK;
}
@ -395,7 +405,7 @@ AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** p
IMoniker_IsSystemMoniker(pmkOther,&mkSys);
if(mkSys==MKSYS_ITEMMONIKER){
if(mkSys==MKSYS_ANTIMONIKER){
IMoniker_AddRef(iface);
@ -525,11 +535,21 @@ static ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface)
* AntiMonikerIROTData_GetComparaisonData
******************************************************************************/
static HRESULT WINAPI
AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface, BYTE* pbData,
AntiMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
ULONG cbMax, ULONG* pcbData)
{
FIXME("(),stub!\n");
return E_NOTIMPL;
DWORD constant = 1;
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID) + sizeof(DWORD);
if (cbMax < *pcbData)
return E_OUTOFMEMORY;
memcpy(pbData, &CLSID_AntiMoniker, sizeof(CLSID));
memcpy(pbData+sizeof(CLSID), &constant, sizeof(DWORD));
return S_OK;
}
/********************************************************************************/
@ -569,7 +589,7 @@ static const IROTDataVtbl VT_ROTDataImpl =
AntiMonikerROTDataImpl_QueryInterface,
AntiMonikerROTDataImpl_AddRef,
AntiMonikerROTDataImpl_Release,
AntiMonikerROTDataImpl_GetComparaisonData
AntiMonikerROTDataImpl_GetComparisonData
};
/******************************************************************************
@ -584,6 +604,7 @@ static HRESULT AntiMonikerImpl_Construct(AntiMonikerImpl* This)
This->lpvtbl1 = &VT_AntiMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->pMarshal = NULL;
return S_OK;
}
@ -615,3 +636,72 @@ HRESULT WINAPI CreateAntiMoniker(LPMONIKER * ppmk)
return hr;
}
static HRESULT WINAPI AntiMonikerCF_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 AntiMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI AntiMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI AntiMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
IMoniker *pMoniker;
HRESULT hr;
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pUnk)
return CLASS_E_NOAGGREGATION;
hr = CreateAntiMoniker(&pMoniker);
if (FAILED(hr))
return hr;
hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
if (FAILED(hr))
IMoniker_Release(pMoniker);
return hr;
}
static HRESULT WINAPI AntiMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl AntiMonikerCFVtbl =
{
AntiMonikerCF_QueryInterface,
AntiMonikerCF_AddRef,
AntiMonikerCF_Release,
AntiMonikerCF_CreateInstance,
AntiMonikerCF_LockServer
};
static const IClassFactoryVtbl *AntiMonikerCF = &AntiMonikerCFVtbl;
HRESULT AntiMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&AntiMonikerCF, riid, ppv);
}

View File

@ -0,0 +1,882 @@
/*
* Class Monikers
*
* Copyright 1999 Noomen Hamza
* Copyright 2005-2007 Robert Shearman
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"
#include "wine/debug.h"
#include "ole2.h"
#include "wine/unicode.h"
#include "moniker.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
#define CHARS_IN_GUID 39
/* ClassMoniker data structure */
typedef struct ClassMoniker
{
const IMonikerVtbl* lpVtbl; /* VTable relative to the IMoniker interface.*/
const IROTDataVtbl* lpVtblRotData; /* VTable relative to the IROTData interface.*/
LONG ref; /* reference counter for this object */
CLSID clsid; /* clsid identified by this moniker */
IUnknown *pMarshal; /* custom marshaler */
} ClassMoniker;
static inline IMoniker *impl_from_IROTData( IROTData *iface )
{
return (IMoniker *)((char*)iface - FIELD_OFFSET(ClassMoniker, lpVtblRotData));
}
/*******************************************************************************
* ClassMoniker_QueryInterface
*******************************************************************************/
static HRESULT WINAPI ClassMoniker_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
{
ClassMoniker *This = (ClassMoniker *)iface;
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
/* Perform a sanity check on the parameters.*/
if (!ppvObject)
return E_POINTER;
/* Initialize the return parameter */
*ppvObject = 0;
/* Compare the riid with the interface IDs implemented by this object.*/
if (IsEqualIID(&IID_IUnknown, riid) ||
IsEqualIID(&IID_IPersist, riid) ||
IsEqualIID(&IID_IPersistStream, riid) ||
IsEqualIID(&IID_IMoniker, riid))
{
*ppvObject = iface;
}
else if (IsEqualIID(&IID_IROTData, riid))
*ppvObject = (IROTData*)&(This->lpVtblRotData);
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)
return E_NOINTERFACE;
/* Query Interface always increases the reference count by one when it is successful */
IMoniker_AddRef(iface);
return S_OK;
}
/******************************************************************************
* ClassMoniker_AddRef
******************************************************************************/
static ULONG WINAPI ClassMoniker_AddRef(IMoniker* iface)
{
ClassMoniker *This = (ClassMoniker *)iface;
TRACE("(%p)\n",This);
return InterlockedIncrement(&This->ref);
}
/******************************************************************************
* ClassMoniker_Destroy (local function)
*******************************************************************************/
static HRESULT WINAPI ClassMoniker_Destroy(ClassMoniker* This)
{
TRACE("(%p)\n",This);
if (This->pMarshal) IUnknown_Release(This->pMarshal);
HeapFree(GetProcessHeap(),0,This);
return S_OK;
}
/******************************************************************************
* ClassMoniker_Release
******************************************************************************/
static ULONG WINAPI ClassMoniker_Release(IMoniker* iface)
{
ClassMoniker *This = (ClassMoniker *)iface;
ULONG ref;
TRACE("(%p)\n",This);
ref = InterlockedDecrement(&This->ref);
/* destroy the object if there's no more reference on it */
if (ref == 0) ClassMoniker_Destroy(This);
return ref;
}
/******************************************************************************
* ClassMoniker_GetClassID
******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetClassID(IMoniker* iface,CLSID *pClassID)
{
TRACE("(%p,%p),stub!\n",iface,pClassID);
if (pClassID==NULL)
return E_POINTER;
*pClassID = CLSID_ClassMoniker;
return S_OK;
}
/******************************************************************************
* ClassMoniker_IsDirty
******************************************************************************/
static HRESULT WINAPI ClassMoniker_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);
return S_FALSE;
}
/******************************************************************************
* ClassMoniker_Load
******************************************************************************/
static HRESULT WINAPI ClassMoniker_Load(IMoniker* iface,IStream* pStm)
{
ClassMoniker *This = (ClassMoniker *)iface;
HRESULT hr;
DWORD zero;
TRACE("(%p)\n", pStm);
hr = IStream_Read(pStm, &This->clsid, sizeof(This->clsid), NULL);
if (hr != S_OK) return STG_E_READFAULT;
hr = IStream_Read(pStm, &zero, sizeof(zero), NULL);
if ((hr != S_OK) || (zero != 0)) return STG_E_READFAULT;
return S_OK;
}
/******************************************************************************
* ClassMoniker_Save
******************************************************************************/
static HRESULT WINAPI ClassMoniker_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 */
{
ClassMoniker *This = (ClassMoniker *)iface;
HRESULT hr;
DWORD zero = 0;
TRACE("(%p, %s)\n", pStm, fClearDirty ? "TRUE" : "FALSE");
hr = IStream_Write(pStm, &This->clsid, sizeof(This->clsid), NULL);
if (FAILED(hr)) return hr;
hr = IStream_Write(pStm, &zero, sizeof(zero), NULL);
return hr;
}
/******************************************************************************
* ClassMoniker_GetSizeMax
******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetSizeMax(IMoniker* iface,
ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
{
TRACE("(%p)\n", pcbSize);
pcbSize->QuadPart = sizeof(CLSID) + sizeof(DWORD);
return S_OK;
}
/******************************************************************************
* ClassMoniker_BindToObject
******************************************************************************/
static HRESULT WINAPI ClassMoniker_BindToObject(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
{
ClassMoniker *This = (ClassMoniker *)iface;
BIND_OPTS2 bindopts;
IClassActivator *pActivator;
HRESULT hr;
TRACE("(%p,%p,%p,%p)\n", pbc, pmkToLeft, riid, ppvResult);
bindopts.cbStruct = sizeof(bindopts);
IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts);
if (!pmkToLeft)
return CoGetClassObject(&This->clsid, bindopts.dwClassContext, NULL,
riid, ppvResult);
else
{
hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator,
(void **)&pActivator);
if (FAILED(hr)) return hr;
hr = IClassActivator_GetClassObject(pActivator, &This->clsid,
bindopts.dwClassContext,
bindopts.locale, riid, ppvResult);
IClassActivator_Release(pActivator);
return hr;
}
}
/******************************************************************************
* ClassMoniker_BindToStorage
******************************************************************************/
static HRESULT WINAPI ClassMoniker_BindToStorage(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
REFIID riid,
VOID** ppvResult)
{
TRACE("(%p,%p,%p,%p)\n",pbc, pmkToLeft, riid, ppvResult);
return ClassMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult);
}
/******************************************************************************
* ClassMoniker_Reduce
******************************************************************************/
static HRESULT WINAPI ClassMoniker_Reduce(IMoniker* iface,
IBindCtx* pbc,
DWORD dwReduceHowFar,
IMoniker** ppmkToLeft,
IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (!ppmkReduced)
return E_POINTER;
ClassMoniker_AddRef(iface);
*ppmkReduced = iface;
return MK_S_REDUCED_TO_SELF;
}
/******************************************************************************
* ClassMoniker_ComposeWith
******************************************************************************/
static HRESULT WINAPI ClassMoniker_ComposeWith(IMoniker* iface,
IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric,
IMoniker** ppmkComposite)
{
HRESULT res=S_OK;
DWORD mkSys,mkSys2;
IEnumMoniker* penumMk=0;
IMoniker *pmostLeftMk=0;
IMoniker* tempMkComposite=0;
TRACE("(%p,%d,%p)\n", pmkRight, fOnlyIfNotGeneric, ppmkComposite);
if ((ppmkComposite==NULL)||(pmkRight==NULL))
return E_POINTER;
*ppmkComposite=0;
IMoniker_IsSystemMoniker(pmkRight,&mkSys);
/* If pmkRight is an anti-moniker, the returned moniker is NULL */
if(mkSys==MKSYS_ANTIMONIKER)
return res;
else
/* if pmkRight is a composite whose leftmost component is an anti-moniker, */
/* the returned moniker is the composite after the leftmost anti-moniker is removed. */
if(mkSys==MKSYS_GENERICCOMPOSITE){
res=IMoniker_Enum(pmkRight,TRUE,&penumMk);
if (FAILED(res))
return res;
res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL);
IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2);
if(mkSys2==MKSYS_ANTIMONIKER){
IMoniker_Release(pmostLeftMk);
tempMkComposite=iface;
IMoniker_AddRef(iface);
while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){
res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite);
IMoniker_Release(tempMkComposite);
IMoniker_Release(pmostLeftMk);
tempMkComposite=*ppmkComposite;
IMoniker_AddRef(tempMkComposite);
}
return res;
}
else
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
}
/* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic
composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns
a NULL moniker and a return value of MK_E_NEEDGENERIC */
else
if (!fOnlyIfNotGeneric)
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
else
return MK_E_NEEDGENERIC;
}
/******************************************************************************
* ClassMoniker_Enum
******************************************************************************/
static HRESULT WINAPI ClassMoniker_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
if (ppenumMoniker == NULL)
return E_POINTER;
*ppenumMoniker = NULL;
return S_OK;
}
/******************************************************************************
* ClassMoniker_IsEqual
******************************************************************************/
static HRESULT WINAPI ClassMoniker_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
CLSID clsid;
LPOLESTR dispName1,dispName2;
IBindCtx* bind;
HRESULT res = S_FALSE;
TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
if (!pmkOtherMoniker) return S_FALSE;
/* check if both are ClassMoniker */
if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
if(!IsEqualCLSID(&clsid,&CLSID_ClassMoniker)) return S_FALSE;
/* check if both displaynames are the same */
if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) {
if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) {
if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) {
if(lstrcmpW(dispName1,dispName2)==0) res = S_OK;
CoTaskMemFree(dispName2);
}
CoTaskMemFree(dispName1);
}
}
return res;
}
/******************************************************************************
* ClassMoniker_Hash
******************************************************************************/
static HRESULT WINAPI ClassMoniker_Hash(IMoniker* iface,DWORD* pdwHash)
{
ClassMoniker *This = (ClassMoniker *)iface;
TRACE("(%p)\n", pdwHash);
*pdwHash = This->clsid.Data1;
return S_OK;
}
/******************************************************************************
* ClassMoniker_IsRunning
******************************************************************************/
static HRESULT WINAPI ClassMoniker_IsRunning(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning)
{
TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pmkNewlyRunning);
/* as in native */
return E_NOTIMPL;
}
/******************************************************************************
* ClassMoniker_GetTimeOfLastChange
******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetTimeOfLastChange(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
FILETIME* pItemTime)
{
TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, pItemTime);
return MK_E_UNAVAILABLE;
}
/******************************************************************************
* ClassMoniker_Inverse
******************************************************************************/
static HRESULT WINAPI ClassMoniker_Inverse(IMoniker* iface,IMoniker** ppmk)
{
TRACE("(%p)\n",ppmk);
if (!ppmk)
return E_POINTER;
return CreateAntiMoniker(ppmk);
}
/******************************************************************************
* ClassMoniker_CommonPrefixWith
******************************************************************************/
static HRESULT WINAPI ClassMoniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
DWORD mkSys;
TRACE("(%p, %p)\n", pmkOther, ppmkPrefix);
*ppmkPrefix = NULL;
IMoniker_IsSystemMoniker(pmkOther, &mkSys);
/* If the other moniker is an class moniker that is equal to this moniker, this method sets *ppmkPrefix */
/* to this moniker and returns MK_S_US */
if (mkSys == MKSYS_CLASSMONIKER)
{
if (IMoniker_IsEqual(iface, pmkOther) == S_OK)
{
*ppmkPrefix = iface;
IMoniker_AddRef(iface);
return MK_S_US;
}
else
return MK_E_NOPREFIX;
}
else
/* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */
/* the case where the other moniker is a generic composite. */
return MonikerCommonPrefixWith(iface, pmkOther, ppmkPrefix);
}
/******************************************************************************
* ClassMoniker_RelativePathTo
******************************************************************************/
static HRESULT WINAPI ClassMoniker_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
TRACE("(%p, %p)\n",pmOther,ppmkRelPath);
if (!ppmkRelPath)
return E_POINTER;
*ppmkRelPath = NULL;
return MK_E_NOTBINDABLE;
}
/******************************************************************************
* ClassMoniker_GetDisplayName
******************************************************************************/
static HRESULT WINAPI ClassMoniker_GetDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR *ppszDisplayName)
{
ClassMoniker *This = (ClassMoniker *)iface;
static const WCHAR wszClsidPrefix[] = {'c','l','s','i','d',':',0};
TRACE("(%p, %p, %p)\n", pbc, pmkToLeft, ppszDisplayName);
if (!ppszDisplayName)
return E_POINTER;
if (pmkToLeft)
return E_INVALIDARG;
*ppszDisplayName = CoTaskMemAlloc(sizeof(wszClsidPrefix) + (CHARS_IN_GUID-2) * sizeof(WCHAR));
StringFromGUID2(&This->clsid, *ppszDisplayName+sizeof(wszClsidPrefix)/sizeof(WCHAR)-2, CHARS_IN_GUID);
/* note: this overwrites the opening curly bracket of the CLSID string generated above */
memcpy(*ppszDisplayName, wszClsidPrefix, sizeof(wszClsidPrefix)-sizeof(WCHAR));
/* note: this overwrites the closing curly bracket of the CLSID string generated above */
(*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-2] = ':';
(*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-1] = '\0';
TRACE("string is %s\n", debugstr_w(*ppszDisplayName));
return S_OK;
}
/******************************************************************************
* ClassMoniker_ParseDisplayName
******************************************************************************/
static HRESULT WINAPI ClassMoniker_ParseDisplayName(IMoniker* iface,
IBindCtx* pbc,
IMoniker* pmkToLeft,
LPOLESTR pszDisplayName,
ULONG* pchEaten,
IMoniker** ppmkOut)
{
FIXME("(%p, %p, %s, %p, %p)\n", pbc, pmkToLeft, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
return E_NOTIMPL;
}
/******************************************************************************
* ClassMoniker_IsSystemMoniker
******************************************************************************/
static HRESULT WINAPI ClassMoniker_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
TRACE("(%p,%p)\n",iface,pwdMksys);
if (!pwdMksys)
return E_POINTER;
*pwdMksys = MKSYS_CLASSMONIKER;
return S_OK;
}
/*******************************************************************************
* ClassMonikerIROTData_QueryInterface
*******************************************************************************/
static HRESULT WINAPI ClassMonikerROTData_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
{
IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
return ClassMoniker_QueryInterface(This, riid, ppvObject);
}
/***********************************************************************
* ClassMonikerIROTData_AddRef
*/
static ULONG WINAPI ClassMonikerROTData_AddRef(IROTData *iface)
{
IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p)\n",iface);
return ClassMoniker_AddRef(This);
}
/***********************************************************************
* ClassMonikerIROTData_Release
*/
static ULONG WINAPI ClassMonikerROTData_Release(IROTData* iface)
{
IMoniker *This = impl_from_IROTData(iface);
TRACE("(%p)\n",iface);
return ClassMoniker_Release(This);
}
/******************************************************************************
* ClassMonikerIROTData_GetComparaisonData
******************************************************************************/
static HRESULT WINAPI ClassMonikerROTData_GetComparaisonData(IROTData* iface,
BYTE* pbData,
ULONG cbMax,
ULONG* pcbData)
{
ClassMoniker *This = (ClassMoniker *)impl_from_IROTData(iface);
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = 2*sizeof(CLSID);
if (cbMax < *pcbData)
return E_OUTOFMEMORY;
/* write CLSID of the moniker */
memcpy(pbData, &CLSID_ClassMoniker, sizeof(CLSID));
/* write CLSID the moniker represents */
memcpy(pbData+sizeof(CLSID), &This->clsid, sizeof(CLSID));
return S_OK;
}
/********************************************************************************/
/* Virtual function table for the ClassMoniker class which include IPersist,*/
/* IPersistStream and IMoniker functions. */
static const IMonikerVtbl ClassMonikerVtbl =
{
ClassMoniker_QueryInterface,
ClassMoniker_AddRef,
ClassMoniker_Release,
ClassMoniker_GetClassID,
ClassMoniker_IsDirty,
ClassMoniker_Load,
ClassMoniker_Save,
ClassMoniker_GetSizeMax,
ClassMoniker_BindToObject,
ClassMoniker_BindToStorage,
ClassMoniker_Reduce,
ClassMoniker_ComposeWith,
ClassMoniker_Enum,
ClassMoniker_IsEqual,
ClassMoniker_Hash,
ClassMoniker_IsRunning,
ClassMoniker_GetTimeOfLastChange,
ClassMoniker_Inverse,
ClassMoniker_CommonPrefixWith,
ClassMoniker_RelativePathTo,
ClassMoniker_GetDisplayName,
ClassMoniker_ParseDisplayName,
ClassMoniker_IsSystemMoniker
};
/********************************************************************************/
/* Virtual function table for the IROTData class. */
static const IROTDataVtbl ROTDataVtbl =
{
ClassMonikerROTData_QueryInterface,
ClassMonikerROTData_AddRef,
ClassMonikerROTData_Release,
ClassMonikerROTData_GetComparaisonData
};
/******************************************************************************
* ClassMoniker_Construct (local function)
*******************************************************************************/
static HRESULT WINAPI ClassMoniker_Construct(ClassMoniker* This, REFCLSID rclsid)
{
TRACE("(%p,%s)\n",This,debugstr_guid(rclsid));
/* Initialize the virtual function table. */
This->lpVtbl = &ClassMonikerVtbl;
This->lpVtblRotData = &ROTDataVtbl;
This->ref = 0;
This->clsid = *rclsid;
This->pMarshal = NULL;
return S_OK;
}
/******************************************************************************
* CreateClassMoniker [OLE32.@]
******************************************************************************/
HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker **ppmk)
{
ClassMoniker* newClassMoniker;
HRESULT hr;
TRACE("(%s,%p)\n", debugstr_guid(rclsid), ppmk);
newClassMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassMoniker));
if (!newClassMoniker)
return STG_E_INSUFFICIENTMEMORY;
hr = ClassMoniker_Construct(newClassMoniker, rclsid);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, newClassMoniker);
return hr;
}
return ClassMoniker_QueryInterface((IMoniker *)newClassMoniker, &IID_IMoniker, (void**)ppmk);
}
HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk)
{
HRESULT hr;
LPCWSTR s = strchrW(szDisplayName, ':');
LPCWSTR end;
CLSID clsid;
BYTE table[256];
int i;
if (!s)
return MK_E_SYNTAX;
s++;
for (end = s; *end && (*end != ':'); end++)
;
TRACE("parsing %s\n", debugstr_wn(s, end - s));
/* validate the CLSID string */
if (s[0] == '{')
{
if ((end - s != 38) || (s[37] != '}'))
return MK_E_SYNTAX;
s++;
}
else
{
if (end - s != 36)
return MK_E_SYNTAX;
}
for (i=0; i<36; i++)
{
if ((i == 8)||(i == 13)||(i == 18)||(i == 23))
{
if (s[i] != '-')
return MK_E_SYNTAX;
continue;
}
if (!(((s[i] >= '0') && (s[i] <= '9')) ||
((s[i] >= 'a') && (s[i] <= 'f')) ||
((s[i] >= 'A') && (s[i] <= 'F'))))
return MK_E_SYNTAX;
}
/* quick lookup table */
memset(table, 0, 256);
for (i = 0; i < 10; i++)
table['0' + i] = i;
for (i = 0; i < 6; i++)
{
table['A' + i] = i+10;
table['a' + i] = i+10;
}
/* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */
clsid.Data1 = (table[s[0]] << 28 | table[s[1]] << 24 | table[s[2]] << 20 | table[s[3]] << 16 |
table[s[4]] << 12 | table[s[5]] << 8 | table[s[6]] << 4 | table[s[7]]);
clsid.Data2 = table[s[9]] << 12 | table[s[10]] << 8 | table[s[11]] << 4 | table[s[12]];
clsid.Data3 = table[s[14]] << 12 | table[s[15]] << 8 | table[s[16]] << 4 | table[s[17]];
/* these are just sequential bytes */
clsid.Data4[0] = table[s[19]] << 4 | table[s[20]];
clsid.Data4[1] = table[s[21]] << 4 | table[s[22]];
clsid.Data4[2] = table[s[24]] << 4 | table[s[25]];
clsid.Data4[3] = table[s[26]] << 4 | table[s[27]];
clsid.Data4[4] = table[s[28]] << 4 | table[s[29]];
clsid.Data4[5] = table[s[30]] << 4 | table[s[31]];
clsid.Data4[6] = table[s[32]] << 4 | table[s[33]];
clsid.Data4[7] = table[s[34]] << 4 | table[s[35]];
hr = CreateClassMoniker(&clsid, ppmk);
if (SUCCEEDED(hr))
*pchEaten = (*end == ':' ? end + 1 : end) - szDisplayName;
return hr;
}
static HRESULT WINAPI ClassMonikerCF_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 ClassMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI ClassMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI ClassMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
HRESULT hr;
IMoniker *pmk;
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pUnk)
return CLASS_E_NOAGGREGATION;
hr = CreateClassMoniker(&CLSID_NULL, &pmk);
if (FAILED(hr)) return hr;
hr = IMoniker_QueryInterface(pmk, riid, ppv);
IMoniker_Release(pmk);
return hr;
}
static HRESULT WINAPI ClassMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl ClassMonikerCFVtbl =
{
ClassMonikerCF_QueryInterface,
ClassMonikerCF_AddRef,
ClassMonikerCF_Release,
ClassMonikerCF_CreateInstance,
ClassMonikerCF_LockServer
};
static const IClassFactoryVtbl *ClassMonikerCF = &ClassMonikerCFVtbl;
HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&ClassMonikerCF, riid, ppv);
}

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
12 stub COFREEALLLIBRARIES
13 pascal CoCreateInstance(ptr ptr long ptr ptr) CoCreateInstance16
14 stub STRINGFROMIID
15 pascal CoDisconnectObject(ptr long) CoDisconnectObject
15 pascal CoDisconnectObject(ptr long) CoDisconnectObject16
16 stub CORELEASEMARSHALDATA
17 pascal -ret16 CoFreeUnusedLibraries() CoFreeUnusedLibraries
18 pascal -ret16 IsEqualGUID(ptr ptr) IsEqualGUID16

View File

@ -19,7 +19,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_OLE_COMPOBJ_H
@ -41,6 +41,13 @@
struct apartment;
typedef struct apartment APARTMENT;
DEFINE_OLEGUID( CLSID_DfMarshal, 0x0000030b, 0, 0 );
DEFINE_OLEGUID( CLSID_PSFactoryBuffer, 0x00000320, 0, 0 );
DEFINE_OLEGUID( CLSID_InProcFreeMarshaler, 0x0000033a, 0, 0 );
/* signal to stub manager that this is a rem unknown object */
#define MSHLFLAGSP_REMUNKNOWN 0x80000000
/* Thread-safety Annotation Legend:
*
* RO - The value is read only. It never changes after creation, so no
@ -72,6 +79,7 @@ struct ifstub
IPID ipid; /* RO */
IUnknown *iface; /* RO */
MSHLFLAGS flags; /* so we can enforce process-local marshalling rules (RO) */
IRpcChannelBuffer*chan; /* channel passed to IRpcStubBuffer::Invoke (RO) */
};
@ -88,6 +96,7 @@ struct stub_manager
OID oid; /* apartment-scoped unique identifier (RO) */
IUnknown *object; /* the object we are managing the stub for (RO) */
ULONG next_ipid; /* currently unused (LOCK) */
OXID_INFO oxid_info; /* string binding, ipid of rem unknown and other information (RO) */
/* We need to keep a count of the outstanding marshals, so we can enforce the
* marshalling rules (ie, you can only unmarshal normal marshals once). Note
@ -107,7 +116,7 @@ struct ifproxy
STDOBJREF stdobjref; /* marshal data that represents this object (RO) */
IID iid; /* interface ID (RO) */
LPRPCPROXYBUFFER proxy; /* interface proxy (RO) */
DWORD refs; /* imported (public) references (MUTEX parent->remoting_mutex) */
ULONG refs; /* imported (public) references (LOCK) */
IRpcChannelBuffer *chan; /* channel to object (CS parent->cs) */
};
@ -116,9 +125,11 @@ struct proxy_manager
{
const IMultiQIVtbl *lpVtbl;
const IMarshalVtbl *lpVtblMarshal;
const IClientSecurityVtbl *lpVtblCliSec;
struct apartment *parent; /* owning apartment (RO) */
struct list entry; /* entry in apartment (CS parent->cs) */
OXID oxid; /* object exported ID (RO) */
OXID_INFO oxid_info; /* string binding, ipid of rem unknown and other information (RO) */
OID oid; /* object ID (RO) */
struct list interfaces; /* imported interfaces (CS cs) */
LONG refs; /* proxy reference count (LOCK) */
@ -126,28 +137,35 @@ struct proxy_manager
ULONG sorflags; /* STDOBJREF flags (RO) */
IRemUnknown *remunk; /* proxy to IRemUnknown used for lifecycle management (CS cs) */
HANDLE remoting_mutex; /* mutex used for synchronizing access to IRemUnknown */
MSHCTX dest_context; /* context used for activating optimisations (LOCK) */
void *dest_context_data; /* reserved context value (LOCK) */
};
/* this needs to become a COM object that implements IRemUnknown */
struct apartment
{
struct list entry;
struct list entry;
LONG refs; /* refcount of the apartment (LOCK) */
DWORD model; /* threading model (RO) */
BOOL multi_threaded; /* multi-threaded or single-threaded apartment? (RO) */
DWORD tid; /* thread id (RO) */
OXID oxid; /* object exporter ID (RO) */
LONG ipidc; /* interface pointer ID counter, starts at 1 (LOCK) */
HWND win; /* message window (RO) */
CRITICAL_SECTION cs; /* thread safety */
LPMESSAGEFILTER filter; /* message filter (CS cs) */
struct list proxies; /* imported objects (CS cs) */
struct list stubmgrs; /* stub managers for exported objects (CS cs) */
BOOL remunk_exported; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
struct list psclsids; /* list of registered PS CLSIDs (CS cs) */
struct list loaded_dlls; /* list of dlls loaded by this apartment (CS cs) */
/* FIXME: OID's should be given out by RPCSS */
OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
/* STA-only fields */
HWND win; /* message window (LOCK) */
LPMESSAGEFILTER filter; /* message filter (CS cs) */
BOOL main; /* is this a main-threaded-apartment? (RO) */
};
/* this is what is stored in TEB->ReservedForOle */
@ -157,22 +175,26 @@ struct oletls
IErrorInfo *errorinfo; /* see errorinfo.c */
IUnknown *state; /* see CoSetState */
DWORD inits; /* number of times CoInitializeEx called */
DWORD ole_inits; /* number of times OleInitialize called */
GUID causality_id; /* unique identifier for each COM call */
LONG pending_call_count_client; /* number of client calls pending */
LONG pending_call_count_server; /* number of server calls pending */
};
/* Global Interface Table Functions */
extern void* StdGlobalInterfaceTable_Construct(void);
extern void StdGlobalInterfaceTable_Destroy(void* self);
extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv);
extern void* StdGlobalInterfaceTableInstance;
/* FIXME: these shouldn't be needed, except for 16-bit functions */
extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *key);
HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey);
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
HRESULT FTMarshalCF_Create(REFIID riid, LPVOID *ppv);
/* Stub Manager */
@ -180,7 +202,7 @@ ULONG stub_manager_int_addref(struct stub_manager *This);
ULONG stub_manager_int_release(struct stub_manager *This);
struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object);
ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs);
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs);
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL last_unlock_releases);
struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, MSHLFLAGS flags);
struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags);
struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid);
@ -189,7 +211,7 @@ BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid);
BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid);
void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid);
HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret);
IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt);
HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface);
HRESULT start_apartment_remote_unknown(void);
HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags);
@ -199,12 +221,20 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
struct dispatch_params;
void RPC_StartRemoting(struct apartment *apt);
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf);
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
const OXID_INFO *oxid_info,
DWORD dest_context, void *dest_context_data,
IRpcChannelBuffer **chan);
HRESULT RPC_CreateServerChannel(IRpcChannelBuffer **chan);
void RPC_ExecuteCall(struct dispatch_params *params);
HRESULT RPC_RegisterInterface(REFIID riid);
void RPC_UnregisterInterface(REFIID riid);
void RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration);
void RPC_StopLocalServer(void *registration);
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook);
void RPC_UnregisterAllChannelHooks(void);
HRESULT RPC_ResolveOxid(OXID oxid, OXID_INFO *oxid_info);
/* This function initialize the Running Object Table */
HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
@ -212,9 +242,8 @@ HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
/* This function uninitialize the Running Object Table */
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 FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
/* Drag and drop */
void OLEDD_UnInitialize(void);
/* Apartment Functions */
@ -229,10 +258,14 @@ static inline HRESULT apartment_getoxid(struct apartment *apt, OXID *oxid)
*oxid = apt->oxid;
return S_OK;
}
HRESULT apartment_createwindowifneeded(struct apartment *apt);
HWND apartment_getwindow(struct apartment *apt);
void apartment_joinmta(void);
/* DCOM messages used by the apartment window (not compatible with native) */
#define DM_EXECUTERPC (WM_USER + 0) /* WPARAM = 0, LPARAM = (struct dispatch_params *) */
#define DM_HOSTOBJECT (WM_USER + 1) /* WPARAM = 0, LPARAM = (struct host_object_params *) */
/*
* Per-thread values are stored in the TEB on offset 0xF80,
@ -253,6 +286,16 @@ static inline APARTMENT* COM_CurrentApt(void)
return COM_CurrentInfo()->apt;
}
static inline GUID COM_CurrentCausalityId(void)
{
struct oletls *info = COM_CurrentInfo();
if (!info)
return GUID_NULL;
if (IsEqualGUID(&info->causality_id, &GUID_NULL))
CoCreateGuid(&info->causality_id);
return info->causality_id;
}
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
/* helpers for debugging */

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
@ -37,10 +37,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
static const CLSID CLSID_CompositeMoniker = {
0x309, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
};
#define BLOCK_TAB_SIZE 5 /* represent the first size table and it's increment block size */
/* CompositeMoniker data structure */
@ -54,6 +50,8 @@ typedef struct CompositeMonikerImpl{
*/
const IROTDataVtbl* lpvtbl2; /* VTable relative to the IROTData interface.*/
const IMarshalVtbl* lpvtblMarshal; /* VTable relative to the IMarshal interface.*/
LONG ref; /* reference counter for this object */
IMoniker** tabMoniker; /* dynamaic table containing all components (monikers) of this composite moniker */
@ -85,6 +83,11 @@ static inline IMoniker *impl_from_IROTData( IROTData *iface )
return (IMoniker *)((char*)iface - FIELD_OFFSET(CompositeMonikerImpl, lpvtbl2));
}
static inline IMoniker *impl_from_IMarshal( IMarshal *iface )
{
return (IMoniker *)((char*)iface - FIELD_OFFSET(CompositeMonikerImpl, lpvtblMarshal));
}
static HRESULT EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker,ULONG tabSize,ULONG currentPos,BOOL leftToRigth,IEnumMoniker ** ppmk);
/*******************************************************************************
@ -113,6 +116,8 @@ CompositeMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject
*ppvObject = iface;
else if (IsEqualIID(&IID_IROTData, riid))
*ppvObject = (IROTData*)&(This->lpvtbl2);
else if (IsEqualIID(&IID_IMarshal, riid))
*ppvObject = (IROTData*)&(This->lpvtblMarshal);
/* Check that we obtained an interface.*/
if ((*ppvObject)==0)
@ -137,6 +142,16 @@ CompositeMonikerImpl_AddRef(IMoniker* iface)
return InterlockedIncrement(&This->ref);
}
static void CompositeMonikerImpl_ReleaseMonikersInTable(CompositeMonikerImpl *This)
{
ULONG i;
for (i = 0; i < This->tabLastIndex; i++)
IMoniker_Release(This->tabMoniker[i]);
This->tabLastIndex = 0;
}
/******************************************************************************
* CompositeMoniker_Release
******************************************************************************/
@ -144,7 +159,6 @@ static ULONG WINAPI
CompositeMonikerImpl_Release(IMoniker* iface)
{
CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;
ULONG i;
ULONG ref;
TRACE("(%p)\n",This);
@ -155,8 +169,7 @@ CompositeMonikerImpl_Release(IMoniker* iface)
if (ref == 0){
/* release all the components before destroying this object */
for (i=0;i<This->tabLastIndex;i++)
IMoniker_Release(This->tabMoniker[i]);
CompositeMonikerImpl_ReleaseMonikersInTable(This);
HeapFree(GetProcessHeap(),0,This->tabMoniker);
HeapFree(GetProcessHeap(),0,This);
@ -170,7 +183,7 @@ CompositeMonikerImpl_Release(IMoniker* iface)
static HRESULT WINAPI
CompositeMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
{
TRACE("(%p,%p),stub!\n",iface,pClassID);
TRACE("(%p,%p)\n",iface,pClassID);
if (pClassID==NULL)
return E_POINTER;
@ -202,9 +215,8 @@ static HRESULT WINAPI
CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
{
HRESULT res;
DWORD constant;
CLSID clsid;
WCHAR string[1]={0};
DWORD moniker_count;
DWORD i;
CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;
@ -212,54 +224,22 @@ CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
/* this function call OleLoadFromStream function for each moniker within this object */
/* read the a constant written by CompositeMonikerImpl_Save (see CompositeMonikerImpl_Save for more details)*/
res=IStream_Read(pStm,&constant,sizeof(DWORD),NULL);
if (SUCCEEDED(res)&& constant!=3)
res=IStream_Read(pStm,&moniker_count,sizeof(DWORD),NULL);
if (res != S_OK)
{
ERR("couldn't reading moniker count from stream\n");
return E_FAIL;
}
while(1){
#if 0
CompositeMonikerImpl_ReleaseMonikersInTable(This);
for (i = 0; i < moniker_count; i++)
{
res=OleLoadFromStream(pStm,&IID_IMoniker,(void**)&This->tabMoniker[This->tabLastIndex]);
#endif
res=ReadClassStm(pStm,&clsid);
DPRINTF("res=%ld",res);
if (FAILED(res))
break;
if (IsEqualIID(&clsid,&CLSID_FileMoniker)){
res=CreateFileMoniker(string,&This->tabMoniker[This->tabLastIndex]);
if (FAILED(res))
break;
res=IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
if (FAILED(res))
break;
}
else if (IsEqualIID(&clsid,&CLSID_ItemMoniker)){
CreateItemMoniker(string,string,&This->tabMoniker[This->tabLastIndex]);
if (res!=S_OK)
break;
IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
if (FAILED(res))
break;
}
else if (IsEqualIID(&clsid,&CLSID_AntiMoniker)){
CreateAntiMoniker(&This->tabMoniker[This->tabLastIndex]);
if (FAILED(res))
break;
IMoniker_Load(This->tabMoniker[This->tabLastIndex],pStm);
if (FAILED(res))
break;
}
else if (IsEqualIID(&clsid,&CLSID_CompositeMoniker))
return E_FAIL;
else
{
FIXME("()\n");
/* FIXME: To whoever wrote this code: It's either return or break. it cannot be both! */
ERR("couldn't load moniker from stream, res = 0x%08x\n", res);
break;
return E_NOTIMPL;
}
/* resize the table if needed */
@ -282,10 +262,11 @@ CompositeMonikerImpl_Load(IMoniker* iface,IStream* pStm)
static HRESULT WINAPI
CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
{
CompositeMonikerImpl *This = (CompositeMonikerImpl *)iface;
HRESULT res;
IEnumMoniker *enumMk;
IMoniker *pmk;
DWORD constant=3;
DWORD moniker_count = This->tabLastIndex;
TRACE("(%p,%p,%d)\n",iface,pStm,fClearDirty);
@ -295,7 +276,8 @@ CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
* at the beginning of the stream. I don't known why (there's no
* indication in the specification) !
*/
res=IStream_Write(pStm,&constant,sizeof(constant),NULL);
res=IStream_Write(pStm,&moniker_count,sizeof(moniker_count),NULL);
if (FAILED(res)) return res;
IMoniker_Enum(iface,TRUE,&enumMk);
@ -307,7 +289,7 @@ CompositeMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
if (FAILED(res)){
IEnumMoniker_Release(pmk);
IEnumMoniker_Release(enumMk);
return res;
}
}
@ -333,22 +315,20 @@ CompositeMonikerImpl_GetSizeMax(IMoniker* iface,ULARGE_INTEGER* pcbSize)
TRACE("(%p,%p)\n",iface,pcbSize);
if (pcbSize!=NULL)
if (!pcbSize)
return E_POINTER;
pcbSize->u.LowPart =0;
pcbSize->u.HighPart=0;
pcbSize->QuadPart = sizeof(DWORD);
IMoniker_Enum(iface,TRUE,&enumMk);
while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)){
while(IEnumMoniker_Next(enumMk,1,&pmk,NULL)==S_OK){
IMoniker_GetSizeMax(pmk,&ptmpSize);
IMoniker_Release(pmk);
pcbSize->u.LowPart +=ptmpSize.u.LowPart;
pcbSize->u.HighPart+=ptmpSize.u.HighPart;
pcbSize->QuadPart = ptmpSize.QuadPart + sizeof(CLSID);
}
IEnumMoniker_Release(enumMk);
@ -401,7 +381,7 @@ CompositeMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc,
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
res=CompositeMonikerImpl_BindToObject(mostRigthMk,pbc,tempMk,riid,ppvResult);
res=IMoniker_BindToObject(mostRigthMk,pbc,tempMk,riid,ppvResult);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
@ -418,7 +398,7 @@ CompositeMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
{
HRESULT res;
IMoniker *tempMk,*antiMk,*mostRigthMk;
IMoniker *tempMk,*antiMk,*mostRigthMk,*leftMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
@ -428,26 +408,34 @@ CompositeMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc,
/* This method recursively calls BindToStorage on the rightmost component of the composite, */
/* passing the rest of the composite as the pmkToLeft parameter for that call. */
if (pmkToLeft!=NULL){
IMoniker_Enum(iface,FALSE,&enumMoniker);
IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
IEnumMoniker_Release(enumMoniker);
res=CreateAntiMoniker(&antiMk);
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
res=CompositeMonikerImpl_BindToStorage(mostRigthMk,pbc,tempMk,riid,ppvResult);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
return res;
if (pmkToLeft)
{
res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
if (FAILED(res)) return res;
}
else
return IMoniker_BindToStorage(iface,pbc,NULL,riid,ppvResult);
leftMk = iface;
IMoniker_Enum(iface, FALSE, &enumMoniker);
IEnumMoniker_Next(enumMoniker, 1, &mostRigthMk, NULL);
IEnumMoniker_Release(enumMoniker);
res = CreateAntiMoniker(&antiMk);
if (FAILED(res)) return res;
res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
if (FAILED(res)) return res;
IMoniker_Release(antiMk);
res = IMoniker_BindToStorage(mostRigthMk, pbc, tempMk, riid, ppvResult);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
if (pmkToLeft)
IMoniker_Release(leftMk);
return res;
}
/******************************************************************************
@ -461,7 +449,7 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar
IMoniker *tempMk,*antiMk,*mostRigthMk,*leftReducedComposedMk,*mostRigthReducedMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
@ -478,7 +466,7 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
return CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
return IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
}
else if (*ppmkToLeft==NULL)
@ -498,7 +486,7 @@ CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar
/* If any of the components reduces itself, the method returns S_OK and passes back a composite */
/* of the reduced components */
if (IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,NULL,&mostRigthReducedMk) &&
CompositeMonikerImpl_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
IMoniker_Reduce(mostRigthMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk)
)
return CreateGenericComposite(leftReducedComposedMk,mostRigthReducedMk,ppmkReduced);
@ -634,15 +622,13 @@ CompositeMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
if(FAILED(res))
return res;
while(1){
res=IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL);
if(FAILED(res))
break;
*pdwHash = 0;
while(IEnumMoniker_Next(enumMoniker,1,&tempMk,NULL)==S_OK){
res = IMoniker_Hash(tempMk, &tempHash);
if(FAILED(res))
break;
*pdwHash = (*pdwHash * 37) + tempHash;
*pdwHash = *pdwHash ^ tempHash;
IMoniker_Release(tempMk);
}
@ -737,9 +723,8 @@ static HRESULT WINAPI
CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, FILETIME* pCompositeTime)
{
IRunningObjectTable* rot;
HRESULT res;
IMoniker *tempMk,*antiMk,*mostRigthMk;
IMoniker *tempMk,*antiMk,*mostRigthMk,*leftMk;
IEnumMoniker *enumMoniker;
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pCompositeTime);
@ -751,36 +736,45 @@ CompositeMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
/* retrieve the time of last change. If the object is not in the ROT, the method recursively calls */
/* IMoniker::GetTimeOfLastChange on the rightmost component of the composite, passing the remainder */
/* of the composite as the pmkToLeft parameter for that call. */
if (pmkToLeft!=NULL){
if (pmkToLeft)
{
IRunningObjectTable* rot;
res=CreateGenericComposite(pmkToLeft,iface,&tempMk);
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
res = IMoniker_ComposeWith(pmkToLeft, iface, FALSE, &leftMk);
res = IBindCtx_GetRunningObjectTable(pbc,&rot);
if (FAILED(res))
{
IMoniker_Release(leftMk);
return res;
}
if (IRunningObjectTable_GetTimeOfLastChange(rot,tempMk,pCompositeTime)==S_OK)
return res;
else
IMoniker_Enum(iface,FALSE,&enumMoniker);
IEnumMoniker_Next(enumMoniker,1,&mostRigthMk,NULL);
IEnumMoniker_Release(enumMoniker);
res=CreateAntiMoniker(&antiMk);
res=IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
IMoniker_Release(antiMk);
res=CompositeMonikerImpl_GetTimeOfLastChange(mostRigthMk,pbc,tempMk,pCompositeTime);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
if (IRunningObjectTable_GetTimeOfLastChange(rot,leftMk,pCompositeTime)==S_OK)
{
IMoniker_Release(leftMk);
return res;
}
}
else
return IMoniker_GetTimeOfLastChange(iface,pbc,NULL,pCompositeTime);
leftMk = iface;
IMoniker_Enum(iface, FALSE, &enumMoniker);
IEnumMoniker_Next(enumMoniker, 1, &mostRigthMk, NULL);
IEnumMoniker_Release(enumMoniker);
res = CreateAntiMoniker(&antiMk);
res = IMoniker_ComposeWith(leftMk, antiMk, 0, &tempMk);
IMoniker_Release(antiMk);
res = IMoniker_GetTimeOfLastChange(mostRigthMk, pbc, tempMk, pCompositeTime);
IMoniker_Release(tempMk);
IMoniker_Release(mostRigthMk);
if (pmkToLeft)
IMoniker_Release(leftMk);
return res;
}
/******************************************************************************
@ -1245,14 +1239,267 @@ static ULONG WINAPI CompositeMonikerROTDataImpl_Release(IROTData* iface)
}
/******************************************************************************
* CompositeMonikerIROTData_GetComparaisonData
* CompositeMonikerIROTData_GetComparisonData
******************************************************************************/
static HRESULT WINAPI
CompositeMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
CompositeMonikerROTDataImpl_GetComparisonData(IROTData* iface,
BYTE* pbData, ULONG cbMax, ULONG* pcbData)
{
FIXME("(),stub!\n");
return E_NOTIMPL;
IMoniker *This = impl_from_IROTData(iface);
IEnumMoniker *pEnumMk;
IMoniker *pmk;
HRESULT hr;
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID);
hr = IMoniker_Enum(This, TRUE, &pEnumMk);
if (FAILED(hr)) return hr;
while(IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
{
IROTData *pROTData;
hr = IMoniker_QueryInterface(pmk, &IID_IROTData, (void **)&pROTData);
if (FAILED(hr))
ERR("moniker doesn't support IROTData interface\n");
if (SUCCEEDED(hr))
{
ULONG cbData;
hr = IROTData_GetComparisonData(pROTData, NULL, 0, &cbData);
IROTData_Release(pROTData);
if (SUCCEEDED(hr) || (hr == E_OUTOFMEMORY))
{
*pcbData += cbData;
hr = S_OK;
}
else
ERR("IROTData_GetComparisonData failed with error 0x%08x\n", hr);
}
IMoniker_Release(pmk);
if (FAILED(hr))
{
IEnumMoniker_Release(pEnumMk);
return hr;
}
}
if (cbMax < *pcbData)
return E_OUTOFMEMORY;
IEnumMoniker_Reset(pEnumMk);
memcpy(pbData, &CLSID_CompositeMoniker, sizeof(CLSID));
pbData += sizeof(CLSID);
cbMax -= sizeof(CLSID);
while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
{
IROTData *pROTData;
hr = IMoniker_QueryInterface(pmk, &IID_IROTData, (void **)&pROTData);
if (FAILED(hr))
ERR("moniker doesn't support IROTData interface\n");
if (SUCCEEDED(hr))
{
ULONG cbData;
hr = IROTData_GetComparisonData(pROTData, pbData, cbMax, &cbData);
IROTData_Release(pROTData);
if (SUCCEEDED(hr))
{
pbData += cbData;
cbMax -= cbData;
}
else
ERR("IROTData_GetComparisonData failed with error 0x%08x\n", hr);
}
IMoniker_Release(pmk);
if (FAILED(hr))
{
IEnumMoniker_Release(pEnumMk);
return hr;
}
}
IEnumMoniker_Release(pEnumMk);
return S_OK;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_QueryInterface(IMarshal *iface, REFIID riid, LPVOID *ppv)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppv);
return CompositeMonikerImpl_QueryInterface(This, riid, ppv);
}
static ULONG WINAPI CompositeMonikerMarshalImpl_AddRef(IMarshal *iface)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%p)\n",iface);
return CompositeMonikerImpl_AddRef(This);
}
static ULONG WINAPI CompositeMonikerMarshalImpl_Release(IMarshal *iface)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%p)\n",iface);
return CompositeMonikerImpl_Release(This);
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetUnmarshalClass(
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, CLSID* pCid)
{
IMoniker *This = impl_from_IMarshal(iface);
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pCid);
return IMoniker_GetClassID(This, pCid);
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_GetMarshalSizeMax(
LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
{
IMoniker *This = impl_from_IMarshal(iface);
IEnumMoniker *pEnumMk;
IMoniker *pmk;
HRESULT hr;
ULARGE_INTEGER size;
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pSize);
*pSize = 0x10; /* to match native */
hr = IMoniker_Enum(This, TRUE, &pEnumMk);
if (FAILED(hr)) return hr;
hr = IMoniker_GetSizeMax(This, &size);
while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
{
ULONG size;
hr = CoGetMarshalSizeMax(&size, &IID_IMoniker, (IUnknown *)pmk, dwDestContext, pvDestContext, mshlflags);
if (SUCCEEDED(hr))
*pSize += size;
IMoniker_Release(pmk);
if (FAILED(hr))
{
IEnumMoniker_Release(pEnumMk);
return hr;
}
}
IEnumMoniker_Release(pEnumMk);
return S_OK;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_MarshalInterface(LPMARSHAL iface, IStream *pStm,
REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags)
{
IMoniker *This = impl_from_IMarshal(iface);
IEnumMoniker *pEnumMk;
IMoniker *pmk;
HRESULT hr;
ULONG i = 0;
TRACE("(%p, %s, %p, %x, %p, %x)\n", pStm, debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags);
hr = IMoniker_Enum(This, TRUE, &pEnumMk);
if (FAILED(hr)) return hr;
while (IEnumMoniker_Next(pEnumMk, 1, &pmk, NULL) == S_OK)
{
hr = CoMarshalInterface(pStm, &IID_IMoniker, (IUnknown *)pmk, dwDestContext, pvDestContext, mshlflags);
IMoniker_Release(pmk);
if (FAILED(hr))
{
IEnumMoniker_Release(pEnumMk);
return hr;
}
i++;
}
if (i != 2)
FIXME("moniker count of %d not supported\n", i);
IEnumMoniker_Release(pEnumMk);
return S_OK;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
{
CompositeMonikerImpl *This = (CompositeMonikerImpl *)impl_from_IMarshal(iface);
HRESULT hr;
TRACE("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
CompositeMonikerImpl_ReleaseMonikersInTable(This);
/* resize the table if needed */
if (This->tabLastIndex + 2 > This->tabSize)
{
This->tabSize += max(BLOCK_TAB_SIZE, 2);
This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker));
if (This->tabMoniker==NULL)
return E_OUTOFMEMORY;
}
hr = CoUnmarshalInterface(pStm, &IID_IMoniker, (void**)&This->tabMoniker[This->tabLastIndex]);
if (FAILED(hr))
{
ERR("couldn't unmarshal moniker, hr = 0x%08x\n", hr);
return hr;
}
This->tabLastIndex++;
hr = CoUnmarshalInterface(pStm, &IID_IMoniker, (void**)&This->tabMoniker[This->tabLastIndex]);
if (FAILED(hr))
{
ERR("couldn't unmarshal moniker, hr = 0x%08x\n", hr);
return hr;
}
This->tabLastIndex++;
return IMoniker_QueryInterface((IMoniker *)&This->lpvtbl1, riid, ppv);
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
{
TRACE("(%p)\n", pStm);
/* can't release a state-based marshal as nothing on server side to
* release */
return S_OK;
}
static HRESULT WINAPI CompositeMonikerMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved)
{
TRACE("(0x%x)\n", dwReserved);
/* can't disconnect a state-based marshal as nothing on server side to
* disconnect from */
return S_OK;
}
/******************************************************************************
@ -1337,8 +1584,10 @@ EnumMonikerImpl_Next(IEnumMoniker* iface,ULONG celt, IMoniker** rgelt,
/* retrieve the requested number of moniker from the current position */
for(i=0;((This->currentPos < This->tabSize) && (i < celt));i++)
{
rgelt[i]=This->tabMoniker[This->currentPos++];
IMoniker_AddRef(rgelt[i]);
}
if (pceltFethed!=NULL)
*pceltFethed= i;
@ -1423,7 +1672,7 @@ EnumMonikerImpl_CreateEnumMoniker(IMoniker** tabMoniker, ULONG tabSize,
/* Initialize the virtual function table. */
newEnumMoniker->lpVtbl = &VT_EnumMonikerImpl;
newEnumMoniker->ref = 0;
newEnumMoniker->ref = 1;
newEnumMoniker->tabSize=tabSize;
newEnumMoniker->currentPos=currentPos;
@ -1491,27 +1740,47 @@ static const IROTDataVtbl VT_ROTDataImpl =
CompositeMonikerROTDataImpl_QueryInterface,
CompositeMonikerROTDataImpl_AddRef,
CompositeMonikerROTDataImpl_Release,
CompositeMonikerROTDataImpl_GetComparaisonData
CompositeMonikerROTDataImpl_GetComparisonData
};
static const IMarshalVtbl VT_MarshalImpl =
{
CompositeMonikerMarshalImpl_QueryInterface,
CompositeMonikerMarshalImpl_AddRef,
CompositeMonikerMarshalImpl_Release,
CompositeMonikerMarshalImpl_GetUnmarshalClass,
CompositeMonikerMarshalImpl_GetMarshalSizeMax,
CompositeMonikerMarshalImpl_MarshalInterface,
CompositeMonikerMarshalImpl_UnmarshalInterface,
CompositeMonikerMarshalImpl_ReleaseMarshalData,
CompositeMonikerMarshalImpl_DisconnectObject
};
/******************************************************************************
* Composite-Moniker_Construct (local function)
*******************************************************************************/
static HRESULT
CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,
CompositeMonikerImpl_Construct(IMoniker** ppMoniker,
LPMONIKER pmkFirst, LPMONIKER pmkRest)
{
DWORD mkSys;
IEnumMoniker *enumMoniker;
IMoniker *tempMk;
HRESULT res;
CompositeMonikerImpl *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This)
return E_OUTOFMEMORY;
TRACE("(%p,%p,%p)\n",This,pmkFirst,pmkRest);
/* Initialize the virtual function table. */
This->lpvtbl1 = &VT_CompositeMonikerImpl;
This->lpvtbl2 = &VT_ROTDataImpl;
This->ref = 0;
This->lpvtblMarshal= &VT_MarshalImpl;
This->ref = 1;
This->tabSize=BLOCK_TAB_SIZE;
This->tabLastIndex=0;
@ -1520,6 +1789,12 @@ CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,
if (This->tabMoniker==NULL)
return E_OUTOFMEMORY;
if (!pmkFirst && !pmkRest)
{
*ppMoniker = (IMoniker *)This;
return S_OK;
}
IMoniker_IsSystemMoniker(pmkFirst,&mkSys);
/* put the first moniker contents in the beginning of the table */
@ -1637,6 +1912,16 @@ CompositeMonikerImpl_Construct(CompositeMonikerImpl* This,
IEnumMoniker_Release(enumMoniker);
}
/* only one moniker, then just return it */
if (This->tabLastIndex == 1)
{
*ppMoniker = This->tabMoniker[0];
IMoniker_AddRef(*ppMoniker);
IMoniker_Release((IMoniker *)This);
}
else
*ppMoniker = (IMoniker *)This;
return S_OK;
}
@ -1647,7 +1932,7 @@ HRESULT WINAPI
CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest,
LPMONIKER* ppmkComposite)
{
CompositeMonikerImpl* newCompositeMoniker = 0;
IMoniker* moniker = 0;
HRESULT hr = S_OK;
TRACE("(%p,%p,%p)\n",pmkFirst,pmkRest,ppmkComposite);
@ -1669,24 +1954,13 @@ CreateGenericComposite(LPMONIKER pmkFirst, LPMONIKER pmkRest,
else if (pmkFirst==NULL && pmkRest==NULL)
return S_OK;
newCompositeMoniker = HeapAlloc(GetProcessHeap(), 0,sizeof(CompositeMonikerImpl));
hr = CompositeMonikerImpl_Construct(&moniker,pmkFirst,pmkRest);
if (newCompositeMoniker == 0)
return STG_E_INSUFFICIENTMEMORY;
hr = CompositeMonikerImpl_Construct(newCompositeMoniker,pmkFirst,pmkRest);
if (FAILED(hr)){
HeapFree(GetProcessHeap(),0,newCompositeMoniker);
if (FAILED(hr))
return hr;
}
if (newCompositeMoniker->tabLastIndex==1)
hr = IMoniker_QueryInterface(newCompositeMoniker->tabMoniker[0],&IID_IMoniker,(void**)ppmkComposite);
else
hr = IMoniker_QueryInterface((IMoniker*)newCompositeMoniker,&IID_IMoniker,(void**)ppmkComposite);
hr = IMoniker_QueryInterface(moniker,&IID_IMoniker,(void**)ppmkComposite);
IMoniker_Release(moniker);
return hr;
}
@ -1700,3 +1974,71 @@ MonikerCommonPrefixWith(IMoniker* pmkThis,IMoniker* pmkOther,IMoniker** ppmkComm
FIXME("(),stub!\n");
return E_NOTIMPL;
}
static HRESULT WINAPI CompositeMonikerCF_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 CompositeMonikerCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI CompositeMonikerCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI CompositeMonikerCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
IMoniker* pMoniker;
HRESULT hr;
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pUnk)
return CLASS_E_NOAGGREGATION;
hr = CompositeMonikerImpl_Construct(&pMoniker, NULL, NULL);
if (SUCCEEDED(hr))
{
hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
IMoniker_Release(pMoniker);
}
return hr;
}
static HRESULT WINAPI CompositeMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl CompositeMonikerCFVtbl =
{
CompositeMonikerCF_QueryInterface,
CompositeMonikerCF_AddRef,
CompositeMonikerCF_Release,
CompositeMonikerCF_CreateInstance,
CompositeMonikerCF_LockServer
};
static const IClassFactoryVtbl *CompositeMonikerCF = &CompositeMonikerCFVtbl;
HRESULT CompositeMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&CompositeMonikerCF, riid, ppv);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,515 +0,0 @@
/*** Autogenerated by WIDL 0.1 from dcom.idl - Do not edit ***/
#include <rpc.h>
#include <rpcndr.h>
#ifndef __WIDL_DCOM_H
#define __WIDL_DCOM_H
#ifdef __cplusplus
extern "C" {
#endif
#include <unknwn.h>
typedef MIDL_uhyper ID;
typedef ID MID;
typedef ID OXID;
typedef ID OID;
typedef ID SETID;
typedef GUID IPID;
typedef GUID CID;
typedef REFGUID REFIPID;
#define COM_MINOR_VERSION_1 (1)
#define COM_MINOR_VERSION_2 (2)
#define COM_MAJOR_VERSION (5)
#define COM_MINOR_VERSION (3)
typedef struct tagCOMVERSION {
unsigned short MajorVersion;
unsigned short MinorVersion;
} COMVERSION;
#define ORPCF_NULL (0)
#define ORPCF_LOCAL (1)
#define ORPCF_RESERVED1 (2)
#define ORPCF_RESERVED2 (4)
#define ORPCF_RESERVED3 (8)
#define ORPCF_RESERVED4 (16)
typedef struct tagORPC_EXTENT {
GUID id;
unsigned long size;
byte data[1];
} ORPC_EXTENT;
typedef struct tagORPC_EXTENT_ARRAY {
unsigned long size;
unsigned long reserved;
ORPC_EXTENT **extent;
} ORPC_EXTENT_ARRAY;
typedef struct tagORPCTHIS {
COMVERSION version;
unsigned long flags;
unsigned long reserved1;
CID cid;
ORPC_EXTENT_ARRAY *extensions;
} ORPCTHIS;
typedef struct tagORPCTHAT {
unsigned long flags;
ORPC_EXTENT_ARRAY *extensions;
} ORPCTHAT;
#define NCADG_IP_UDP (0x8)
#define NCACN_IP_TCP (0x7)
#define NCADG_IPX (0xe)
#define NCACN_SPX (0xc)
#define NCACN_NB_NB (0x12)
#define NCACN_NB_IPX (0xd)
#define NCACN_DNET_NSP (0x4)
#define NCACN_HTTP (0x1f)
typedef struct tagSTRINGBINDING {
unsigned short wTowerId;
unsigned short aNetworkAddr[1];
} STRINGBINDING;
#define COM_C_AUTHZ_NONE (0xffff)
typedef struct tagSECURITYBINDING {
unsigned short wAuthnSvc;
unsigned short wAuthzSvc;
unsigned short aPrincName[1];
} SECURITYBINDING;
typedef struct tagDUALSTRINGARRAY {
unsigned short wNumEntries;
unsigned short wSecurityOffset;
unsigned short aStringArray[1];
} DUALSTRINGARRAY;
#define OBJREF_SIGNATURE (0x574f454d)
#define OBJREF_STANDARD (0x1)
#define OBJREF_HANDLER (0x2)
#define OBJREF_CUSTOM (0x4)
#define SORF_OXRES1 (0x1)
#define SORF_OXRES2 (0x20)
#define SORF_OXRES3 (0x40)
#define SORF_OXRES4 (0x80)
#define SORF_OXRES5 (0x100)
#define SORF_OXRES6 (0x200)
#define SORF_OXRES7 (0x400)
#define SORF_OXRES8 (0x800)
#define SORF_NULL (0x0)
#define SORF_NOPING (0x1000)
typedef struct tagSTDOBJREF {
unsigned long flags;
unsigned long cPublicRefs;
OXID oxid;
OID oid;
IPID ipid;
} STDOBJREF;
typedef struct tagOBJREF {
unsigned long signature;
unsigned long flags;
GUID iid;
union {
struct OR_STANDARD {
STDOBJREF std;
DUALSTRINGARRAY saResAddr;
} u_standard;
struct OR_HANDLER {
STDOBJREF std;
CLSID clsid;
DUALSTRINGARRAY saResAddr;
} u_handler;
struct OR_CUSTOM {
CLSID clsid;
unsigned long cbExtension;
unsigned long size;
byte *pData;
} u_custom;
} u_objref;
} OBJREF;
typedef struct tagMInterfacePointer {
ULONG ulCntData;
BYTE abData[1];
} MInterfacePointer;
typedef MInterfacePointer *PMInterfacePointer;
#ifndef __IRemUnknown_FWD_DEFINED__
#define __IRemUnknown_FWD_DEFINED__
typedef struct IRemUnknown IRemUnknown;
#endif
typedef IRemUnknown *LPREMUNKNOWN;
typedef struct tagREMQIRESULT {
HRESULT hResult;
STDOBJREF std;
} REMQIRESULT;
typedef struct tagREMINTERFACEREF {
IPID ipid;
unsigned long cPublicRefs;
unsigned long cPrivateRefs;
} REMINTERFACEREF;
/*****************************************************************************
* IRemUnknown interface
*/
#ifndef __IRemUnknown_INTERFACE_DEFINED__
#define __IRemUnknown_INTERFACE_DEFINED__
DEFINE_GUID(IID_IRemUnknown, 0x00000131, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
#if defined(__cplusplus) && !defined(CINTERFACE)
struct IRemUnknown : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE RemQueryInterface(
REFIPID ripid,
unsigned long cRefs,
unsigned short cIids,
IID* iids,
REMQIRESULT** ppQIResults) = 0;
virtual HRESULT STDMETHODCALLTYPE RemAddRef(
unsigned short cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs,
HRESULT* pResults) = 0;
virtual HRESULT STDMETHODCALLTYPE RemRelease(
unsigned short cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs) = 0;
};
#else
typedef struct IRemUnknownVtbl IRemUnknownVtbl;
struct IRemUnknown {
const IRemUnknownVtbl* lpVtbl;
};
struct IRemUnknownVtbl {
BEGIN_INTERFACE
/*** IUnknown methods ***/
HRESULT (STDMETHODCALLTYPE *QueryInterface)(
IRemUnknown* This,
REFIID riid,
void** ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef)(
IRemUnknown* This);
ULONG (STDMETHODCALLTYPE *Release)(
IRemUnknown* This);
/*** IRemUnknown methods ***/
HRESULT (STDMETHODCALLTYPE *RemQueryInterface)(
IRemUnknown* This,
REFIPID ripid,
unsigned long cRefs,
unsigned short cIids,
IID* iids,
REMQIRESULT** ppQIResults);
HRESULT (STDMETHODCALLTYPE *RemAddRef)(
IRemUnknown* This,
unsigned short cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs,
HRESULT* pResults);
HRESULT (STDMETHODCALLTYPE *RemRelease)(
IRemUnknown* This,
unsigned short cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs);
END_INTERFACE
};
#ifdef COBJMACROS
/*** IUnknown methods ***/
#define IRemUnknown_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IRemUnknown_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IRemUnknown_Release(p) (p)->lpVtbl->Release(p)
/*** IRemUnknown methods ***/
#define IRemUnknown_RemQueryInterface(p,a,b,c,d,e) (p)->lpVtbl->RemQueryInterface(p,a,b,c,d,e)
#define IRemUnknown_RemAddRef(p,a,b,c) (p)->lpVtbl->RemAddRef(p,a,b,c)
#define IRemUnknown_RemRelease(p,a,b) (p)->lpVtbl->RemRelease(p,a,b)
#endif
#endif
#define IRemUnknown_METHODS \
/*** IUnknown methods ***/ \
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; \
STDMETHOD_(ULONG,AddRef)(THIS) PURE; \
STDMETHOD_(ULONG,Release)(THIS) PURE; \
/*** IRemUnknown methods ***/ \
STDMETHOD_(HRESULT,RemQueryInterface)(THIS_ REFIPID ripid, unsigned long cRefs, unsigned short cIids, IID* iids, REMQIRESULT** ppQIResults) PURE; \
STDMETHOD_(HRESULT,RemAddRef)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs, HRESULT* pResults) PURE; \
STDMETHOD_(HRESULT,RemRelease)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs) PURE;
HRESULT CALLBACK IRemUnknown_RemQueryInterface_Proxy(
IRemUnknown* This,
REFIPID ripid,
unsigned long cRefs,
unsigned short cIids,
IID* iids,
REMQIRESULT** ppQIResults);
void __RPC_STUB IRemUnknown_RemQueryInterface_Stub(
struct IRpcStubBuffer* This,
struct IRpcChannelBuffer* pRpcChannelBuffer,
PRPC_MESSAGE pRpcMessage,
DWORD* pdwStubPhase);
HRESULT CALLBACK IRemUnknown_RemAddRef_Proxy(
IRemUnknown* This,
unsigned short cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs,
HRESULT* pResults);
void __RPC_STUB IRemUnknown_RemAddRef_Stub(
struct IRpcStubBuffer* This,
struct IRpcChannelBuffer* pRpcChannelBuffer,
PRPC_MESSAGE pRpcMessage,
DWORD* pdwStubPhase);
HRESULT CALLBACK IRemUnknown_RemRelease_Proxy(
IRemUnknown* This,
unsigned short cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs);
void __RPC_STUB IRemUnknown_RemRelease_Stub(
struct IRpcStubBuffer* This,
struct IRpcChannelBuffer* pRpcChannelBuffer,
PRPC_MESSAGE pRpcMessage,
DWORD* pdwStubPhase);
#endif /* __IRemUnknown_INTERFACE_DEFINED__ */
#ifndef __IRemUnknown2_FWD_DEFINED__
#define __IRemUnknown2_FWD_DEFINED__
typedef struct IRemUnknown2 IRemUnknown2;
#endif
typedef IRemUnknown2 *LPREMUNKNOWN2;
/*****************************************************************************
* IRemUnknown2 interface
*/
#ifndef __IRemUnknown2_INTERFACE_DEFINED__
#define __IRemUnknown2_INTERFACE_DEFINED__
DEFINE_GUID(IID_IRemUnknown2, 0x00000142, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
#if defined(__cplusplus) && !defined(CINTERFACE)
struct IRemUnknown2 : public IRemUnknown
{
virtual HRESULT STDMETHODCALLTYPE RemQueryInterface2(
REFIPID ripid,
unsigned short cIids,
IID* iids,
HRESULT* phr,
MInterfacePointer** ppMIF) = 0;
};
#else
typedef struct IRemUnknown2Vtbl IRemUnknown2Vtbl;
struct IRemUnknown2 {
const IRemUnknown2Vtbl* lpVtbl;
};
struct IRemUnknown2Vtbl {
BEGIN_INTERFACE
/*** IUnknown methods ***/
HRESULT (STDMETHODCALLTYPE *QueryInterface)(
IRemUnknown2* This,
REFIID riid,
void** ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef)(
IRemUnknown2* This);
ULONG (STDMETHODCALLTYPE *Release)(
IRemUnknown2* This);
/*** IRemUnknown methods ***/
HRESULT (STDMETHODCALLTYPE *RemQueryInterface)(
IRemUnknown2* This,
REFIPID ripid,
unsigned long cRefs,
unsigned short cIids,
IID* iids,
REMQIRESULT** ppQIResults);
HRESULT (STDMETHODCALLTYPE *RemAddRef)(
IRemUnknown2* This,
unsigned short cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs,
HRESULT* pResults);
HRESULT (STDMETHODCALLTYPE *RemRelease)(
IRemUnknown2* This,
unsigned short cInterfaceRefs,
REMINTERFACEREF* InterfaceRefs);
/*** IRemUnknown2 methods ***/
HRESULT (STDMETHODCALLTYPE *RemQueryInterface2)(
IRemUnknown2* This,
REFIPID ripid,
unsigned short cIids,
IID* iids,
HRESULT* phr,
MInterfacePointer** ppMIF);
END_INTERFACE
};
#ifdef COBJMACROS
/*** IUnknown methods ***/
#define IRemUnknown2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IRemUnknown2_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IRemUnknown2_Release(p) (p)->lpVtbl->Release(p)
/*** IRemUnknown methods ***/
#define IRemUnknown2_RemQueryInterface(p,a,b,c,d,e) (p)->lpVtbl->RemQueryInterface(p,a,b,c,d,e)
#define IRemUnknown2_RemAddRef(p,a,b,c) (p)->lpVtbl->RemAddRef(p,a,b,c)
#define IRemUnknown2_RemRelease(p,a,b) (p)->lpVtbl->RemRelease(p,a,b)
/*** IRemUnknown2 methods ***/
#define IRemUnknown2_RemQueryInterface2(p,a,b,c,d,e) (p)->lpVtbl->RemQueryInterface2(p,a,b,c,d,e)
#endif
#endif
#define IRemUnknown2_METHODS \
/*** IUnknown methods ***/ \
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; \
STDMETHOD_(ULONG,AddRef)(THIS) PURE; \
STDMETHOD_(ULONG,Release)(THIS) PURE; \
/*** IRemUnknown methods ***/ \
STDMETHOD_(HRESULT,RemQueryInterface)(THIS_ REFIPID ripid, unsigned long cRefs, unsigned short cIids, IID* iids, REMQIRESULT** ppQIResults) PURE; \
STDMETHOD_(HRESULT,RemAddRef)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs, HRESULT* pResults) PURE; \
STDMETHOD_(HRESULT,RemRelease)(THIS_ unsigned short cInterfaceRefs, REMINTERFACEREF* InterfaceRefs) PURE; \
/*** IRemUnknown2 methods ***/ \
STDMETHOD_(HRESULT,RemQueryInterface2)(THIS_ REFIPID ripid, unsigned short cIids, IID* iids, HRESULT* phr, MInterfacePointer** ppMIF) PURE;
HRESULT CALLBACK IRemUnknown2_RemQueryInterface2_Proxy(
IRemUnknown2* This,
REFIPID ripid,
unsigned short cIids,
IID* iids,
HRESULT* phr,
MInterfacePointer** ppMIF);
void __RPC_STUB IRemUnknown2_RemQueryInterface2_Stub(
struct IRpcStubBuffer* This,
struct IRpcChannelBuffer* pRpcChannelBuffer,
PRPC_MESSAGE pRpcMessage,
DWORD* pdwStubPhase);
#endif /* __IRemUnknown2_INTERFACE_DEFINED__ */
#if 0
/*****************************************************************************
* IOXIDResolver interface (v0.0)
*/
DEFINE_GUID(IID_IOXIDResolver, 0x99fcfec4, 0x5260, 0x101b, 0xbb,0xcb, 0x00,0xaa,0x00,0x21,0x34,0x7a);
extern RPC_IF_HANDLE IOXIDResolver_v0_0_c_ifspec;
extern RPC_IF_HANDLE IOXIDResolver_v0_0_s_ifspec;
error_status_t ResolveOxid(
handle_t hRpc,
OXID* pOxid,
unsigned short cRequestedProtseqs,
unsigned short arRequestedProtseqs[],
DUALSTRINGARRAY** ppdsaOxidBindings,
IPID* pipidRemUnknown,
DWORD* pAuthnHint);
error_status_t SimplePing(
handle_t hRpc,
SETID* pSetId);
error_status_t ComplexPing(
handle_t hRpc,
SETID* pSetId,
unsigned short SequenceNum,
unsigned short cAddToSet,
unsigned short cDelFromSet,
OID AddToSet[],
OID DelFromSet[],
unsigned short* pPingBackoffFactor);
error_status_t ServerAlive(
handle_t hRpc);
error_status_t ResolveOxid2(
handle_t hRpc,
OXID* pOxid,
unsigned short cRequestedProtseqs,
unsigned short arRequestedProtseqs[],
DUALSTRINGARRAY** ppdsaOxidBindings,
IPID* pipidRemUnknown,
DWORD* pAuthnHint,
COMVERSION* pComVersion);
#define MODE_GET_CLASS_OBJECT (0xffffffff)
/*****************************************************************************
* IRemoteActivation interface (v0.0)
*/
DEFINE_GUID(IID_IRemoteActivation, 0x4d9f4ab8, 0x7d1c, 0x11cf, 0x86,0x1e, 0x00,0x20,0xaf,0x6e,0x7c,0x57);
extern RPC_IF_HANDLE IRemoteActivation_v0_0_c_ifspec;
extern RPC_IF_HANDLE IRemoteActivation_v0_0_s_ifspec;
HRESULT RemoteActivation(
handle_t hRpc,
ORPCTHIS* ORPCthis,
ORPCTHAT* ORPCthat,
GUID* Clsid,
WCHAR* pwszObjectName,
MInterfacePointer* pObjectStorage,
DWORD ClientImpLevel,
DWORD Mode,
DWORD Interfaces,
IID* pIIDs,
unsigned short cRequestedProtseqs,
unsigned short RequestedProtseqs[],
OXID* pOxid,
DUALSTRINGARRAY** ppdsaOxidBindings,
IPID* pipidRemUnknown,
DWORD* pAuthnHint,
COMVERSION* pServerVersion,
HRESULT* phr,
MInterfacePointer** ppInterfaceData,
HRESULT* pResults);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __WIDL_DCOM_H */

View File

@ -13,7 +13,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* see http://www.microsoft.com/msj/0398/dcom.htm */
@ -108,6 +108,14 @@ interface ObjectRpcBaseTypes
[size_is(wNumEntries)] unsigned short aStringArray[];
} DUALSTRINGARRAY;
typedef struct tagOXID_INFO {
DWORD dwTid;
DWORD dwPid;
IPID ipidRemUnknown;
DWORD dwAuthnHint;
DUALSTRINGARRAY *psa;
} OXID_INFO;
const unsigned long OBJREF_SIGNATURE = 0x574f454d; /* "MEOW" */
const unsigned long OBJREF_STANDARD = 0x1;
const unsigned long OBJREF_HANDLER = 0x2;
@ -148,7 +156,7 @@ interface ObjectRpcBaseTypes
[case(OBJREF_CUSTOM)] struct OR_CUSTOM {
CLSID clsid;
unsigned long cbExtension;
unsigned long size;
ULONG size;
[size_is(size), ref] byte *pData;
} u_custom;
} u_objref;
@ -184,7 +192,7 @@ interface IRemUnknown : IUnknown
HRESULT RemQueryInterface(
[in] REFIPID ripid,
[in] unsigned long cRefs,
[in] ULONG cRefs,
[in] unsigned short cIids,
[in, size_is(cIids)] IID *iids,
[out, size_is(,cIids)] REMQIRESULT **ppQIResults);
@ -215,7 +223,6 @@ interface IRemUnknown2 : IRemUnknown
[out, size_is(cIids)] MInterfacePointer **ppMIF);
}
cpp_quote("#if 0")
[
uuid(99fcfec4-5260-101b-bbcb-00aa0021347a),
pointer_default(unique)
@ -289,4 +296,3 @@ interface IRemoteActivation
[out,size_is(Interfaces)] MInterfacePointer **ppInterfaceData,
[out,size_is(Interfaces)] HRESULT *pResults);
}
cpp_quote("#endif")

View File

@ -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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
* The OLE2 default object handler supports a whole whack of
@ -416,7 +416,8 @@ static void WINAPI DefaultHandler_Stop(DefaultHandler *This)
/* FIXME: call IOleCache_OnStop */
DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
if (This->dataAdviseHolder)
DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
if (This->pDataDelegate)
{
IDataObject_Release(This->pDataDelegate);
@ -446,7 +447,7 @@ static HRESULT WINAPI DefaultHandler_Close(
DefaultHandler *This = impl_from_IOleObject(iface);
HRESULT hr;
TRACE("(%ld)\n", dwSaveOption);
TRACE("(%d)\n", dwSaveOption);
if (!This->pOleDelegate)
return S_OK;
@ -472,7 +473,7 @@ static HRESULT WINAPI DefaultHandler_SetMoniker(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld, %p)\n",
TRACE("(%p, %d, %p)\n",
iface,
dwWhichMoniker,
pmk);
@ -498,7 +499,7 @@ static HRESULT WINAPI DefaultHandler_GetMoniker(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld, %ld, %p)\n",
TRACE("(%p, %d, %d, %p)\n",
iface, dwAssign, dwWhichMoniker, ppmk);
if (This->pOleDelegate)
@ -533,7 +534,7 @@ static HRESULT WINAPI DefaultHandler_InitFromData(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %p, %d, %ld)\n",
TRACE("(%p, %p, %d, %d)\n",
iface, pDataObject, fCreation, dwReserved);
if (This->pOleDelegate)
@ -556,7 +557,7 @@ static HRESULT WINAPI DefaultHandler_GetClipboardData(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld, %p)\n",
TRACE("(%p, %d, %p)\n",
iface, dwReserved, ppDataObject);
if (This->pOleDelegate)
@ -579,7 +580,7 @@ static HRESULT WINAPI DefaultHandler_DoVerb(
IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
HRESULT hr;
TRACE("(%ld, %p, %p, %ld, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
hr = IRunnableObject_Run(pRunnableObj, NULL);
if (FAILED(hr)) return hr;
@ -651,9 +652,6 @@ static HRESULT WINAPI DefaultHandler_GetUserClassID(
TRACE("(%p, %p)\n", iface, pClsid);
if (This->pOleDelegate)
return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
if (This->pOleDelegate)
return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
@ -681,7 +679,7 @@ static HRESULT WINAPI DefaultHandler_GetUserType(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld, %p)\n", iface, dwFormOfType, pszUserType);
TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
}
@ -700,7 +698,7 @@ static HRESULT WINAPI DefaultHandler_SetExtent(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %lx, (%ld x %ld))\n", iface,
TRACE("(%p, %x, (%d x %d))\n", iface,
dwDrawAspect, psizel->cx, psizel->cy);
if (This->pOleDelegate)
@ -728,7 +726,7 @@ static HRESULT WINAPI DefaultHandler_GetExtent(
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %lx, %p)\n", iface, dwDrawAspect, psizel);
TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
if (This->pOleDelegate)
return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
@ -805,7 +803,7 @@ static HRESULT WINAPI DefaultHandler_Unadvise(
{
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %ld)\n", iface, dwConnection);
TRACE("(%p, %d)\n", iface, dwConnection);
/*
* If we don't have an advise holder yet, it means we don't have
@ -841,10 +839,9 @@ static HRESULT WINAPI DefaultHandler_EnumAdvise(
*ppenumAdvise = NULL;
if (!This->oleAdviseHolder)
return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder,
ppenumAdvise);
return S_OK;
return S_OK;
return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
}
/************************************************************************
@ -863,10 +860,7 @@ static HRESULT WINAPI DefaultHandler_GetMiscStatus(
HRESULT hres;
DefaultHandler *This = impl_from_IOleObject(iface);
TRACE("(%p, %lx, %p)\n", iface, dwAspect, pdwStatus);
if (This->pOleDelegate)
return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
if (This->pOleDelegate)
return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
@ -978,6 +972,9 @@ static HRESULT WINAPI DefaultHandler_GetData(
IDataObject_Release(cacheDataObject);
if (FAILED(hres) && This->pDataDelegate)
hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
return hres;
}
@ -1021,6 +1018,9 @@ static HRESULT WINAPI DefaultHandler_QueryGetData(
IDataObject_Release(cacheDataObject);
if (FAILED(hres) && This->pDataDelegate)
hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
return hres;
}
@ -1037,16 +1037,13 @@ static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
LPFORMATETC pformatetcOut)
{
DefaultHandler *This = impl_from_IDataObject(iface);
IDataObject *pDataObject;
HRESULT hr;
TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
if (!This->pOleDelegate)
if (!This->pDataDelegate)
return OLE_E_NOTRUNNING;
hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&pDataObject);
return IDataObject_GetCanonicalFormatEtc(pDataObject, pformatetcIn, pformatetcOut);
return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
}
/************************************************************************
@ -1102,7 +1099,7 @@ static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
HRESULT hres;
DefaultHandler *This = impl_from_IDataObject(iface);
TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
@ -1127,12 +1124,16 @@ static HRESULT WINAPI DefaultHandler_DAdvise(
HRESULT hres = S_OK;
DefaultHandler *This = impl_from_IDataObject(iface);
TRACE("(%p, %p, %ld, %p, %p)\n",
TRACE("(%p, %p, %d, %p, %p)\n",
iface, pformatetc, advf, pAdvSink, pdwConnection);
/* Make sure we have a data advise holder before we start. */
if (!This->dataAdviseHolder)
{
hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
if (SUCCEEDED(hres) && This->pDataDelegate)
DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
}
if (SUCCEEDED(hres))
hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
@ -1159,7 +1160,7 @@ static HRESULT WINAPI DefaultHandler_DUnadvise(
{
DefaultHandler *This = impl_from_IDataObject(iface);
TRACE("(%p, %ld)\n", iface, dwConnection);
TRACE("(%p, %d)\n", iface, dwConnection);
/*
* If we don't have a data advise holder yet, it means that

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>

View File

@ -17,7 +17,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __DICTIONARY_H__
#define __DICTIONARY_H__

View File

@ -0,0 +1,202 @@
/*
* IEnum* implementation
*
* Copyright 2006 Mike McCormack
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
typedef struct tagEnumSTATPROPSETSTG_impl
{
const void *vtbl;
LONG ref;
struct list elements;
struct list *current;
ULONG elem_size;
GUID riid;
} enumx_impl;
/************************************************************************
* enumx_QueryInterface
*/
HRESULT WINAPI enumx_QueryInterface(
enumx_impl *This,
REFIID riid,
void** ppvObject)
{
if ( (This==0) || (ppvObject==0) )
return E_INVALIDARG;
*ppvObject = 0;
if (IsEqualGUID(&IID_IUnknown, riid) ||
IsEqualGUID(&This->riid, riid))
{
IUnknown_AddRef(((IUnknown*)This));
*ppvObject = This;
return S_OK;
}
return E_NOINTERFACE;
}
/************************************************************************
* enumx_AddRef
*/
ULONG WINAPI enumx_AddRef(enumx_impl *This)
{
return InterlockedIncrement(&This->ref);
}
/************************************************************************
* enumx_Release
*/
ULONG WINAPI enumx_Release(enumx_impl *This)
{
ULONG ref;
ref = InterlockedDecrement(&This->ref);
if (ref == 0)
{
while (!list_empty(&This->elements))
{
struct list *x = list_head(&This->elements);
list_remove(x);
HeapFree(GetProcessHeap(), 0, x);
}
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
/************************************************************************
* enumx_Next
*/
HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt,
void *rgelt, ULONG *pceltFetched)
{
unsigned char *p;
ULONG count = 0;
TRACE("%p %u %p\n", This, celt, pceltFetched);
if (This->current == NULL)
This->current = list_head(&This->elements);
p = rgelt;
while (count < celt && This->current && This->current != &This->elements)
{
memcpy(p, &This->current[1], This->elem_size);
p += This->elem_size;
This->current = This->current->next;
count++;
}
if (pceltFetched)
*pceltFetched = count;
if (count < celt)
return S_FALSE;
return S_OK;
}
/************************************************************************
* enumx_Skip
*/
HRESULT WINAPI enumx_Skip(enumx_impl *This, ULONG celt)
{
ULONG count = 0;
TRACE("%p %u\n", This, celt);
if (This->current == NULL)
This->current = list_head(&This->elements);
while (count < celt && This->current && This->current != &This->elements)
count++;
return S_OK;
}
/************************************************************************
* enumx_Reset
*/
HRESULT WINAPI enumx_Reset(enumx_impl *This)
{
TRACE("\n");
This->current = NULL;
return S_OK;
}
/************************************************************************
* enumx_fnClone
*/
HRESULT WINAPI enumx_Clone(
enumx_impl *iface,
enumx_impl **ppenum)
{
FIXME("\n");
return E_NOTIMPL;
}
/************************************************************************
* enumx_allocate
*
* Allocate a generic enumerator
*/
enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size)
{
enumx_impl *enumx;
enumx = HeapAlloc(GetProcessHeap(), 0, sizeof *enumx);
if (enumx)
{
enumx->vtbl = vtbl;
enumx->ref = 1;
enumx->current = NULL;
enumx->elem_size = elem_size;
memcpy(&enumx->riid, riid, sizeof *riid);
list_init(&enumx->elements);
}
return enumx;
}
/************************************************************************
* enumx_add_element
*
* Add an element to the enumeration.
*/
void *enumx_add_element(enumx_impl *enumx, void *data)
{
struct list *element;
element = HeapAlloc(GetProcessHeap(), 0, sizeof *element + enumx->elem_size);
if (!element)
return NULL;
memcpy(&element[1], data, enumx->elem_size);
list_add_tail(&enumx->elements, element);
return &element[1];
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2006 Mike McCormack
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __OLE_ENUM_H__
#define __OLE_ENUM_H__
typedef struct tagEnumSTATPROPSETSTG_impl enumx_impl;
extern HRESULT WINAPI enumx_QueryInterface(enumx_impl *, REFIID, void**);
extern ULONG WINAPI enumx_AddRef(enumx_impl *);
extern ULONG WINAPI enumx_Release(enumx_impl *);
extern HRESULT WINAPI enumx_Next(enumx_impl *, ULONG, void *, ULONG *);
extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG);
extern HRESULT WINAPI enumx_Reset(enumx_impl *);
extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **);
extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG);
extern void *enumx_add_element(enumx_impl *, void *);
#endif

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
*
@ -52,7 +52,7 @@ static BSTR WINAPI ERRORINFO_SysAllocString(const OLECHAR* in)
if (in == NULL)
return NULL;
/*
* Find the lenth of the buffer passed-in in bytes.
* Find the length of the buffer passed-in, in bytes.
*/
len = strlenW(in);
bufferSize = len * sizeof (WCHAR);
@ -83,14 +83,10 @@ static BSTR WINAPI ERRORINFO_SysAllocString(const OLECHAR* in)
newBuffer++;
/*
* Copy the information in the buffer.
* Since it is valid to pass a NULL pointer here, we'll initialize the
* buffer to nul if it is the case.
* Copy the information in the buffer. It is not possible to pass
* a NULL pointer here.
*/
if (in != 0)
memcpy(newBuffer, in, bufferSize);
else
memset(newBuffer, 0, bufferSize);
memcpy(newBuffer, in, bufferSize);
/*
* Make sure that there is a nul character at the end of the
@ -171,7 +167,7 @@ static inline ErrorInfoImpl *impl_from_ISupportErrorInfo( ISupportErrorInfo *ifa
#define _ICreateErrorInfo_(This) (ICreateErrorInfo*)&(This->lpvtcei)
#define _ISupportErrorInfo_(This) (ISupportErrorInfo*)&(This->lpvtsei)
IErrorInfo * IErrorInfoImpl_Constructor(void)
static IErrorInfo * IErrorInfoImpl_Constructor(void)
{
ErrorInfoImpl * ei = HeapAlloc(GetProcessHeap(), 0, sizeof(ErrorInfoImpl));
if (ei)
@ -226,7 +222,7 @@ static ULONG WINAPI IErrorInfoImpl_AddRef(
IErrorInfo* iface)
{
ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
TRACE("(%p)->(count=%lu)\n",This,This->ref);
TRACE("(%p)->(count=%u)\n",This,This->ref);
return InterlockedIncrement(&This->ref);
}
@ -236,7 +232,7 @@ static ULONG WINAPI IErrorInfoImpl_Release(
ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(count=%lu)\n",This,ref+1);
TRACE("(%p)->(count=%u)\n",This,ref+1);
if (!ref)
{
@ -252,7 +248,7 @@ static HRESULT WINAPI IErrorInfoImpl_GetGUID(
GUID * pGUID)
{
ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
TRACE("(%p)->(count=%lu)\n",This,This->ref);
TRACE("(%p)->(count=%u)\n",This,This->ref);
if(!pGUID )return E_INVALIDARG;
memcpy(pGUID, &This->m_Guid, sizeof(GUID));
return S_OK;
@ -405,7 +401,7 @@ static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpContext(
DWORD dwHelpContext)
{
ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface);
TRACE("(%p,%ld)\n",This,dwHelpContext);
TRACE("(%p,%d)\n",This,dwHelpContext);
This->m_dwHelpContext = dwHelpContext;
return S_OK;
}
@ -490,10 +486,16 @@ HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
*/
HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
{
TRACE("(%ld, %p, %p)\n", dwReserved, pperrinfo, COM_CurrentInfo()->errorinfo);
TRACE("(%d, %p, %p)\n", dwReserved, pperrinfo, COM_CurrentInfo()->errorinfo);
if (dwReserved)
{
ERR("dwReserved (0x%x) != 0\n", dwReserved);
return E_INVALIDARG;
}
if(!pperrinfo) return E_INVALIDARG;
if (!COM_CurrentInfo()->errorinfo)
{
*pperrinfo = NULL;
@ -514,8 +516,14 @@ HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo)
{
IErrorInfo * pei;
TRACE("(%ld, %p)\n", dwReserved, perrinfo);
TRACE("(%d, %p)\n", dwReserved, perrinfo);
if (dwReserved)
{
ERR("dwReserved (0x%x) != 0\n", dwReserved);
return E_INVALIDARG;
}
/* release old errorinfo */
pei = COM_CurrentInfo()->errorinfo;
if (pei) IErrorInfo_Release(pei);

View File

@ -2,6 +2,7 @@
* FileMonikers implementation
*
* Copyright 1999 Noomen Hamza
* Copyright 2007 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
@ -39,10 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
const CLSID CLSID_FileMoniker = {
0x303, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
};
/* filemoniker data structure */
typedef struct FileMonikerImpl{
@ -530,7 +527,7 @@ FileMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft
}
if (pcf!=NULL){
IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)ppf);
IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)&ppf);
res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
@ -643,7 +640,7 @@ 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);
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
@ -1249,7 +1246,7 @@ FileMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
int i;
LPWSTR pszFileName;
TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID) + len * sizeof(WCHAR);
if (cbMax < *pcbData)
@ -1409,6 +1406,105 @@ HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk)
return hr;
}
/* find a character from a set in reverse without the string having to be null-terminated */
static inline WCHAR *memrpbrkW(const WCHAR *ptr, size_t n, const WCHAR *accept)
{
const WCHAR *end, *ret = NULL;
for (end = ptr + n; ptr < end; ptr++) if (strchrW(accept, *ptr)) ret = ptr;
return (WCHAR *)ret;
}
HRESULT FileMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk)
{
LPCWSTR end;
static const WCHAR wszSeparators[] = {':','\\','/','!',0};
for (end = szDisplayName + strlenW(szDisplayName);
end && (end != szDisplayName);
end = memrpbrkW(szDisplayName, end - szDisplayName, wszSeparators))
{
HRESULT hr;
IRunningObjectTable *rot;
IMoniker *file_moniker;
LPWSTR file_display_name;
LPWSTR full_path_name;
DWORD full_path_name_len;
int len = end - szDisplayName;
file_display_name = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (!file_display_name) return E_OUTOFMEMORY;
memcpy(file_display_name, szDisplayName, len * sizeof(WCHAR));
file_display_name[len] = '\0';
hr = CreateFileMoniker(file_display_name, &file_moniker);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, file_display_name);
return hr;
}
hr = IBindCtx_GetRunningObjectTable(pbc, &rot);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return hr;
}
hr = IRunningObjectTable_IsRunning(rot, file_moniker);
IRunningObjectTable_Release(rot);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return hr;
}
if (hr == S_OK)
{
TRACE("found running file moniker for %s\n", debugstr_w(file_display_name));
*pchEaten = len;
*ppmk = file_moniker;
HeapFree(GetProcessHeap(), 0, file_display_name);
return S_OK;
}
full_path_name_len = GetFullPathNameW(file_display_name, 0, NULL, NULL);
if (!full_path_name_len)
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return MK_E_SYNTAX;
}
full_path_name = HeapAlloc(GetProcessHeap(), 0, full_path_name_len * sizeof(WCHAR));
if (!full_path_name)
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return E_OUTOFMEMORY;
}
GetFullPathNameW(file_display_name, full_path_name_len, full_path_name, NULL);
if (GetFileAttributesW(full_path_name) == INVALID_FILE_ATTRIBUTES)
TRACE("couldn't open file %s\n", debugstr_w(full_path_name));
else
{
TRACE("got file moniker for %s\n", debugstr_w(szDisplayName));
*pchEaten = len;
*ppmk = file_moniker;
HeapFree(GetProcessHeap(), 0, file_display_name);
HeapFree(GetProcessHeap(), 0, full_path_name);
return S_OK;
}
HeapFree(GetProcessHeap(), 0, file_display_name);
HeapFree(GetProcessHeap(), 0, full_path_name);
IMoniker_Release(file_moniker);
}
return MK_E_CANTOPENFILE;
}
static HRESULT WINAPI FileMonikerCF_QueryInterface(LPCLASSFACTORY iface,
REFIID riid, LPVOID *ppv)
{

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -34,6 +34,8 @@
#include "wine/debug.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
typedef struct _FTMarshalImpl {
@ -136,7 +138,12 @@ static HRESULT WINAPI
FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
void *pvDestContext, DWORD mshlflags, CLSID * pCid)
{
FIXME ("(), stub!\n");
TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pCid);
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX)
memcpy(pCid, &CLSID_InProcFreeMarshaler, sizeof(CLSID_InProcFreeMarshaler));
else
memcpy(pCid, &CLSID_DfMarshal, sizeof(CLSID_InProcFreeMarshaler));
return S_OK;
}
@ -148,15 +155,14 @@ FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD d
IMarshal *pMarshal = NULL;
HRESULT hres;
FTMarshalImpl *This = impl_from_IMarshal(iface);
FIXME ("(), stub!\n");
TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pSize);
/* if the marshalling happens inside the same process the interface pointer is
copied between the apartments */
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
*pSize = sizeof (This);
return S_OK;
*pSize = sizeof (mshlflags) + sizeof (pv) + sizeof (DWORD) + sizeof (GUID);
return S_OK;
}
/* use the standard marshaller to handle all other cases */
@ -174,14 +180,37 @@ FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, vo
IMarshal *pMarshal = NULL;
HRESULT hres;
FTMarshalImpl *This = impl_from_IMarshal(iface);
FIXME ("(), stub!\n");
TRACE("(%p, %s, %p, 0x%x, %p, 0x%x)\n", pStm, debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags);
/* if the marshalling happens inside the same process the interface pointer is
copied between the apartments */
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
return IStream_Write (pStm, This, sizeof (This), 0);
void *object;
DWORD constant = 0;
GUID unknown_guid = { 0 };
hres = IUnknown_QueryInterface((IUnknown *)pv, riid, &object);
if (FAILED(hres))
return hres;
/* don't hold a reference to table-weak marshaled interfaces */
if (mshlflags & MSHLFLAGS_TABLEWEAK)
IUnknown_Release((IUnknown *)object);
hres = IStream_Write (pStm, &mshlflags, sizeof (mshlflags), NULL);
if (hres != S_OK) return STG_E_MEDIUMFULL;
hres = IStream_Write (pStm, &object, sizeof (object), NULL);
if (hres != S_OK) return STG_E_MEDIUMFULL;
hres = IStream_Write (pStm, &constant, sizeof (constant), NULL);
if (hres != S_OK) return STG_E_MEDIUMFULL;
hres = IStream_Write (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
if (hres != S_OK) return STG_E_MEDIUMFULL;
return S_OK;
}
/* use the standard marshaler to handle all other cases */
@ -194,19 +223,66 @@ FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, vo
static HRESULT WINAPI
FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
{
FIXME ("(), stub!\n");
return S_OK;
DWORD mshlflags;
IUnknown *object;
DWORD constant;
GUID unknown_guid;
HRESULT hres;
TRACE ("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IStream_Read (pStm, &object, sizeof (object), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
if (hres != S_OK) return STG_E_READFAULT;
if (constant != 0)
FIXME("constant is 0x%x instead of 0\n", constant);
hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IUnknown_QueryInterface(object, riid, ppv);
if (!(mshlflags & (MSHLFLAGS_TABLEWEAK|MSHLFLAGS_TABLESTRONG)))
IUnknown_Release(object);
return hres;
}
static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
{
FIXME ("(), stub!\n");
DWORD mshlflags;
IUnknown *object;
DWORD constant;
GUID unknown_guid;
HRESULT hres;
TRACE ("(%p)\n", pStm);
hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IStream_Read (pStm, &object, sizeof (object), NULL);
if (hres != S_OK) return STG_E_READFAULT;
hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
if (hres != S_OK) return STG_E_READFAULT;
if (constant != 0)
FIXME("constant is 0x%x instead of 0\n", constant);
hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
if (hres != S_OK) return STG_E_READFAULT;
IUnknown_Release(object);
return S_OK;
}
static HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
{
FIXME ("(), stub!\n");
TRACE ("()\n");
/* nothing to do */
return S_OK;
}
@ -226,6 +302,23 @@ static const IMarshalVtbl ftmvtbl =
/***********************************************************************
* CoCreateFreeThreadedMarshaler [OLE32.@]
*
* Creates a free-threaded marshaler.
*
* PARAMS
* punkOuter [I] Optional. Outer unknown.
* ppunkMarshal [O] On return, the inner unknown of the created free-threaded marshaler.
*
* RETURNS
* Success: S_OK
* Failure: E_OUTOFMEMORY if no memory available to create object.
*
* NOTES
* Objects that ensure their state is maintained consistent when used by
* multiple threads and reference no single-threaded objects are known as
* free-threaded. The free-threaded marshaler enables these objects to be
* efficiently marshaled within the same process, by not creating proxies
* (as they aren't needed for the object to be safely used), whilst still
* allowing the object to be used in inter-process and inter-machine contexts.
*/
HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
{
@ -241,8 +334,73 @@ HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * p
ftm->lpVtbl = &iunkvt;
ftm->lpvtblFTM = &ftmvtbl;
ftm->ref = 1;
ftm->pUnkOuter = punkOuter;
ftm->pUnkOuter = punkOuter ? punkOuter : _IFTMUnknown_(ftm);
*ppunkMarshal = _IFTMUnknown_ (ftm);
return S_OK;
}
static HRESULT WINAPI FTMarshalCF_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 FTMarshalCF_AddRef(LPCLASSFACTORY iface)
{
return 2; /* non-heap based object */
}
static ULONG WINAPI FTMarshalCF_Release(LPCLASSFACTORY iface)
{
return 1; /* non-heap based object */
}
static HRESULT WINAPI FTMarshalCF_CreateInstance(LPCLASSFACTORY iface,
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
IUnknown *pUnknown;
HRESULT hr;
TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
*ppv = NULL;
hr = CoCreateFreeThreadedMarshaler(pUnk, &pUnknown);
if (SUCCEEDED(hr))
{
hr = IUnknown_QueryInterface(pUnknown, riid, ppv);
IUnknown_Release(pUnknown);
}
return hr;
}
static HRESULT WINAPI FTMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
FIXME("(%d), stub!\n",fLock);
return S_OK;
}
static const IClassFactoryVtbl FTMarshalCFVtbl =
{
FTMarshalCF_QueryInterface,
FTMarshalCF_AddRef,
FTMarshalCF_Release,
FTMarshalCF_CreateInstance,
FTMarshalCF_LockServer
};
static const IClassFactoryVtbl *FTMarshalCF = &FTMarshalCFVtbl;
HRESULT FTMarshalCF_Create(REFIID riid, LPVOID *ppv)
{
return IClassFactory_QueryInterface((IClassFactory *)&FTMarshalCF, riid, ppv);
}

View File

@ -21,16 +21,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
@ -42,11 +36,10 @@
#include "objbase.h"
#include "ole2.h"
#include "winerror.h"
#include "winreg.h"
#include "winternl.h"
#include "compobj_private.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@ -65,8 +58,7 @@ typedef struct StdGITEntry
IID iid; /* IID of the interface */
IStream* stream; /* Holds the marshalled interface */
struct StdGITEntry* next;
struct StdGITEntry* prev;
struct list entry;
} StdGITEntry;
/* Class data */
@ -75,8 +67,7 @@ typedef struct StdGlobalInterfaceTableImpl
const IGlobalInterfaceTableVtbl *lpVtbl;
ULONG ref;
struct StdGITEntry* firstEntry;
struct StdGITEntry* lastEntry;
struct list list;
ULONG nextCookie;
} StdGlobalInterfaceTableImpl;
@ -94,7 +85,8 @@ static CRITICAL_SECTION git_section = { &critsect_debug, -1, 0, 0, 0, 0 };
/** This destroys it again. It should revoke all the held interfaces first **/
void StdGlobalInterfaceTable_Destroy(void* self) {
static void StdGlobalInterfaceTable_Destroy(void* self)
{
TRACE("(%p)\n", self);
FIXME("Revoke held interfaces here\n");
@ -115,13 +107,11 @@ StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie)
TRACE("iface=%p, cookie=0x%x\n", iface, (UINT)cookie);
EnterCriticalSection(&git_section);
e = self->firstEntry;
while (e != NULL) {
LIST_FOR_EACH_ENTRY(e, &self->list, StdGITEntry, entry) {
if (e->cookie == cookie) {
LeaveCriticalSection(&git_section);
return e;
}
e = e->next;
}
LeaveCriticalSection(&git_section);
@ -210,7 +200,7 @@ StdGlobalInterfaceTable_RegisterInterfaceInGlobal(
}
zero.QuadPart = 0;
IStream_Seek(stream, zero, SEEK_SET, NULL);
IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
if (entry == NULL) return E_OUTOFMEMORY;
@ -223,18 +213,14 @@ StdGlobalInterfaceTable_RegisterInterfaceInGlobal(
self->nextCookie++; /* inc the cookie count */
/* insert the new entry at the end of the list */
entry->next = NULL;
entry->prev = self->lastEntry;
if (entry->prev) entry->prev->next = entry;
else self->firstEntry = entry;
self->lastEntry = entry;
list_add_tail(&self->list, &entry->entry);
/* and return the cookie */
*pdwCookie = entry->cookie;
LeaveCriticalSection(&git_section);
TRACE("Cookie is 0x%lx\n", entry->cookie);
TRACE("Cookie is 0x%x\n", entry->cookie);
return S_OK;
}
@ -242,7 +228,6 @@ static HRESULT WINAPI
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
IGlobalInterfaceTable* iface, DWORD dwCookie)
{
StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
StdGITEntry* entry;
HRESULT hr;
@ -258,17 +243,14 @@ StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
hr = CoReleaseMarshalData(entry->stream);
if (hr != S_OK)
{
WARN("Failed to release marshal data, hr = 0x%08lx\n", hr);
WARN("Failed to release marshal data, hr = 0x%08x\n", hr);
return hr;
}
IStream_Release(entry->stream);
/* chop entry out of the list, and free the memory */
EnterCriticalSection(&git_section);
if (entry->prev) entry->prev->next = entry->next;
else self->firstEntry = entry->next;
if (entry->next) entry->next->prev = entry->prev;
else self->lastEntry = entry->prev;
list_remove(&entry->entry);
LeaveCriticalSection(&git_section);
HeapFree(GetProcessHeap(), 0, entry);
@ -285,7 +267,7 @@ StdGlobalInterfaceTable_GetInterfaceFromGlobal(
LARGE_INTEGER move;
LPUNKNOWN lpUnk;
TRACE("dwCookie=0x%lx, riid=%s, ppv=%p\n", dwCookie, debugstr_guid(riid), ppv);
TRACE("dwCookie=0x%x, riid=%s, ppv=%p\n", dwCookie, debugstr_guid(riid), ppv);
entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
if (entry == NULL) return E_INVALIDARG;
@ -298,16 +280,17 @@ StdGlobalInterfaceTable_GetInterfaceFromGlobal(
/* unmarshal the interface */
hres = CoUnmarshalInterface(entry->stream, riid, ppv);
if (hres) {
WARN("Failed to unmarshal stream\n");
return hres;
}
/* rewind stream, in case it's used again */
move.u.LowPart = 0;
move.u.HighPart = 0;
IStream_Seek(entry->stream, move, STREAM_SEEK_SET, NULL);
if (hres) {
WARN("Failed to unmarshal stream\n");
return hres;
}
/* addref it */
lpUnk = *ppv;
IUnknown_AddRef(lpUnk);
@ -389,7 +372,7 @@ static const IGlobalInterfaceTableVtbl StdGlobalInterfaceTableImpl_Vtbl =
};
/** This function constructs the GIT. It should only be called once **/
void* StdGlobalInterfaceTable_Construct()
void* StdGlobalInterfaceTable_Construct(void)
{
StdGlobalInterfaceTableImpl* newGIT;
@ -398,8 +381,7 @@ void* StdGlobalInterfaceTable_Construct()
newGIT->lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl;
newGIT->ref = 1; /* Initialise the reference count */
newGIT->firstEntry = NULL; /* we start with an empty table */
newGIT->lastEntry = NULL;
list_init(&newGIT->list);
newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */
TRACE("Created the GIT at %p\n", newGIT);

View File

@ -18,7 +18,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -49,7 +49,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage);
/****************************************************************************
* HGLOBALStreamImpl definition.
*
* This class imlements the IStream inteface and represents a stream
* This class implements the IStream interface and represents a stream
* supported by an HGLOBAL pointer.
*/
struct HGLOBALStreamImpl
@ -148,11 +148,9 @@ static HRESULT WINAPI HGLOBALStreamImpl_QueryInterface(
/*
* Compare the riid with the interface IDs implemented by this object.
*/
if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
{
*ppvObject = (IStream*)This;
}
else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0)
if (IsEqualIID(&IID_IUnknown, riid) ||
IsEqualIID(&IID_ISequentialStream, riid) ||
IsEqualIID(&IID_IStream, riid))
{
*ppvObject = (IStream*)This;
}
@ -216,7 +214,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
TRACE("(%p, %p, %ld, %p)\n", iface,
TRACE("(%p, %p, %d, %p)\n", iface,
pv, cb, pcbRead);
/*
@ -255,14 +253,11 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
GlobalUnlock(This->supportHandle);
/*
* The function returns S_OK if the buffer was filled completely
* it returns S_FALSE if the end of the stream is reached before the
* Always returns S_OK even if the end of the stream is reached before the
* buffer is filled
*/
if(*pcbRead == cb)
return S_OK;
return S_FALSE;
return S_OK;
}
/***
@ -287,8 +282,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
TRACE("(%p, %p, %ld, %p)\n", iface,
pv, cb, pcbWritten);
TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbWritten);
/*
* If the caller is not interested in the number of bytes written,
@ -298,14 +292,10 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
pcbWritten = &bytesWritten;
if (cb == 0)
{
return S_OK;
}
else
{
newSize.u.HighPart = 0;
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
}
goto out;
newSize.u.HighPart = 0;
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
/*
* Verify if we need to grow the stream
@ -316,7 +306,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
HRESULT hr = IStream_SetSize(iface, newSize);
if (FAILED(hr))
{
ERR("IStream_SetSize failed with error 0x%08lx\n", hr);
ERR("IStream_SetSize failed with error 0x%08x\n", hr);
return hr;
}
}
@ -333,16 +323,17 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
*/
This->currentPosition.u.LowPart+=cb;
/*
* Return the number of bytes read.
*/
*pcbWritten = cb;
/*
* Cleanup
*/
GlobalUnlock(This->supportHandle);
out:
/*
* Return the number of bytes read.
*/
*pcbWritten = cb;
return S_OK;
}
@ -364,7 +355,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
ULARGE_INTEGER newPosition;
TRACE("(%p, %lx%08lx, %ld, %p)\n", iface, dlibMove.u.HighPart,
TRACE("(%p, %x%08x, %d, %p)\n", iface, dlibMove.u.HighPart,
dlibMove.u.LowPart, dwOrigin, plibNewPosition);
/*
@ -418,13 +409,11 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
HGLOBAL supportHandle;
TRACE("(%p, %ld)\n", iface, libNewSize.u.LowPart);
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
/*
* As documented.
* HighPart is ignored as shown in tests
*/
if (libNewSize.u.HighPart != 0)
return STG_E_INVALIDFUNCTION;
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
return S_OK;
@ -435,7 +424,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
if (supportHandle == 0)
return STG_E_MEDIUMFULL;
return E_OUTOFMEMORY;
This->supportHandle = supportHandle;
This->streamSize.u.LowPart = libNewSize.u.LowPart;
@ -463,7 +452,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
ULARGE_INTEGER totalBytesRead;
ULARGE_INTEGER totalBytesWritten;
TRACE("(%p, %p, %ld, %p, %p)\n", iface, pstm,
TRACE("(%p, %p, %d, %p, %p)\n", iface, pstm,
cb.u.LowPart, pcbRead, pcbWritten);
/*
@ -487,21 +476,19 @@ static HRESULT WINAPI HGLOBALStreamImpl_CopyTo(
else
copySize = cb.u.LowPart;
IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
hr = IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
if (FAILED(hr))
break;
totalBytesRead.u.LowPart += bytesRead;
IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
totalBytesWritten.u.LowPart += bytesWritten;
/*
* Check that read & write operations were succesfull
*/
if (bytesRead != bytesWritten)
if (bytesRead)
{
hr = STG_E_MEDIUMFULL;
break;
hr = IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
if (FAILED(hr))
break;
totalBytesWritten.u.LowPart += bytesWritten;
}
if (bytesRead!=copySize)
@ -570,7 +557,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_LockRegion(
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType) /* [in] */
{
return S_OK;
return STG_E_INVALIDFUNCTION;
}
/*
@ -664,7 +651,7 @@ static const IStreamVtbl HGLOBALStreamImpl_Vtbl =
* fDeleteOnRelease - Flag set to TRUE if the HGLOBAL will be released
* when the IStream object is destroyed.
*/
HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
static HGLOBALStreamImpl* HGLOBALStreamImpl_Construct(
HGLOBAL hGlobal,
BOOL fDeleteOnRelease)
{

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -166,7 +166,7 @@ static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, DWORD cb) {
LPVOID addr;
TRACE("(%ld)\n",cb);
TRACE("(%d)\n",cb);
if(Malloc32.pSpy) {
DWORD preAllocResult;
@ -200,7 +200,7 @@ static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) {
LPVOID pNewMemory;
TRACE("(%p,%ld)\n",pv,cb);
TRACE("(%p,%d)\n",pv,cb);
if(Malloc32.pSpy) {
LPVOID pRealMemory;
@ -396,7 +396,7 @@ static ULONG WINAPI IMallocSpy_fnAddRef (LPMALLOCSPY iface)
_MallocSpy *This = (_MallocSpy *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE ("(%p)->(count=%lu)\n", This, ref - 1);
TRACE ("(%p)->(count=%u)\n", This, ref - 1);
return ref;
}
@ -413,7 +413,7 @@ static ULONG WINAPI IMallocSpy_fnRelease (LPMALLOCSPY iface)
_MallocSpy *This = (_MallocSpy *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE ("(%p)->(count=%lu)\n", This, ref + 1);
TRACE ("(%p)->(count=%u)\n", This, ref + 1);
if (!ref) {
/* our allocation list MUST be empty here */
@ -424,7 +424,7 @@ static ULONG WINAPI IMallocSpy_fnRelease (LPMALLOCSPY iface)
static ULONG WINAPI IMallocSpy_fnPreAlloc(LPMALLOCSPY iface, ULONG cbRequest)
{
_MallocSpy *This = (_MallocSpy *)iface;
TRACE ("(%p)->(%lu)\n", This, cbRequest);
TRACE ("(%p)->(%u)\n", This, cbRequest);
return cbRequest;
}
static PVOID WINAPI IMallocSpy_fnPostAlloc(LPMALLOCSPY iface, void* pActual)
@ -449,7 +449,7 @@ static void WINAPI IMallocSpy_fnPostFree(LPMALLOCSPY iface, BOOL fSpyed)
static ULONG WINAPI IMallocSpy_fnPreRealloc(LPMALLOCSPY iface, void* pRequest, ULONG cbRequest, void** ppNewRequest, BOOL fSpyed)
{
_MallocSpy *This = (_MallocSpy *)iface;
TRACE ("(%p)->(%p %lu %u)\n", This, pRequest, cbRequest, fSpyed);
TRACE ("(%p)->(%p %u %u)\n", This, pRequest, cbRequest, fSpyed);
*ppNewRequest = pRequest;
return cbRequest;
}
@ -471,7 +471,7 @@ static PVOID WINAPI IMallocSpy_fnPreGetSize(LPMALLOCSPY iface, void* pRequest, B
static ULONG WINAPI IMallocSpy_fnPostGetSize(LPMALLOCSPY iface, ULONG cbActual, BOOL fSpyed)
{
_MallocSpy *This = (_MallocSpy *)iface;
TRACE ("(%p)->(%lu %u)\n", This, cbActual, fSpyed);
TRACE ("(%p)->(%u %u)\n", This, cbActual, fSpyed);
return cbActual;
}
@ -502,7 +502,7 @@ static void WINAPI IMallocSpy_fnPostHeapMinimize(LPMALLOCSPY iface)
}
static void MallocSpyDumpLeaks(void) {
TRACE("leaks: %lu\n", Malloc32.SpyedAllocationsLeft);
TRACE("leaks: %u\n", Malloc32.SpyedAllocationsLeft);
}
static const IMallocSpyVtbl VT_IMallocSpy =
@ -665,7 +665,7 @@ HRESULT WINAPI CoRevokeMallocSpy(void)
}
if (Malloc32.SpyedAllocationsLeft) {
TRACE("SpyReleasePending with %lu allocations left\n", Malloc32.SpyedAllocationsLeft);
TRACE("SpyReleasePending with %u allocations left\n", Malloc32.SpyedAllocationsLeft);
Malloc32.SpyReleasePending = TRUE;
hres = E_ACCESSDENIED;
} else {

View File

@ -13,7 +13,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_OLE_IFS_H
@ -38,7 +38,6 @@ typedef LPCSTR LPCOLESTR16;
* IMalloc16 interface
*/
#undef INTERFACE
typedef struct IMalloc16 *LPMALLOC16;
#define INTERFACE IMalloc16
@ -58,8 +57,6 @@ DECLARE_INTERFACE_(IMalloc16,IUnknown)
};
#undef INTERFACE
typedef struct IMalloc16 *LPMALLOC16;
/**********************************************************************/
extern LPMALLOC16 IMalloc16_Constructor(void);

View File

@ -1,4 +1,4 @@
/***************************************************************************************
/*
* ItemMonikers implementation
*
* Copyright 1999 Noomen Hamza
@ -15,8 +15,8 @@
*
* 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
***************************************************************************************/
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
@ -38,10 +38,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
const CLSID CLSID_ItemMoniker = {
0x304, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
};
/* ItemMoniker data structure */
typedef struct ItemMonikerImpl{
@ -101,8 +97,8 @@ static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx*
static HRESULT WINAPI ItemMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
/* Local function used by ItemMoniker implementation */
HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
static HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* iface, LPCOLESTR lpszDelim,LPCOLESTR lpszPathName);
static HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* iface);
/********************************************************************************/
/* IROTData prototype functions */
@ -392,7 +388,7 @@ HRESULT WINAPI ItemMonikerImpl_GetSizeMax(IMoniker* iface,
/******************************************************************************
* ItemMoniker_Construct (local function)
*******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
static HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDelim,LPCOLESTR lpszItem)
{
int sizeStr1=lstrlenW(lpszItem), sizeStr2;
@ -430,7 +426,7 @@ HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDe
/******************************************************************************
* ItemMoniker_Destroy (local function)
*******************************************************************************/
HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
static HRESULT WINAPI ItemMonikerImpl_Destroy(ItemMonikerImpl* This)
{
TRACE("(%p)\n",This);
@ -521,7 +517,7 @@ HRESULT WINAPI ItemMonikerImpl_Reduce(IMoniker* iface,
IMoniker** ppmkToLeft,
IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
@ -661,8 +657,8 @@ HRESULT WINAPI ItemMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker
HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
int h = 0,i,skip,len;
DWORD h = 0;
int i,len;
int off = 0;
LPOLESTR val;
@ -672,17 +668,8 @@ HRESULT WINAPI ItemMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
val = This->itemName;
len = lstrlenW(val);
if (len < 16) {
for (i = len ; i > 0; i--) {
h = (h * 37) + val[off++];
}
} else {
/* only sample some characters */
skip = len / 8;
for (i = len ; i > 0; i -= skip, off += skip) {
h = (h * 39) + val[off];
}
}
for (i = len ; i > 0; i--)
h = (h * 3) ^ toupperW(val[off++]);
*pdwHash=h;
@ -980,7 +967,7 @@ HRESULT WINAPI ItemMonikerROTDataImpl_GetComparisonData(IROTData* iface,
LPWSTR pszItemName;
LPWSTR pszItemDelimiter;
TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);
TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
*pcbData = sizeof(CLSID) + sizeof(WCHAR) + len * sizeof(WCHAR);
if (cbMax < *pcbData)

View File

@ -17,14 +17,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
@ -35,10 +31,7 @@
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "rpc.h"
#include "winerror.h"
#include "winreg.h"
#include "wtypes.h"
#include "wine/unicode.h"
#include "compobj_private.h"
@ -50,13 +43,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
extern const CLSID CLSID_DfMarshal;
/* number of refs given out for normal marshaling */
#define NORMALEXTREFS 1 /* FIXME: this should be 5, but we have to wait for IRemUnknown support first */
#define NORMALEXTREFS 5
/* private flag indicating that the caller does not want to notify the stub
* when the proxy disconnects or is destroyed */
#define SORFP_NOLIFETIMEMGMT SORF_OXRES1
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFIID riid, void **object);
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
MSHCTX dest_context, void *dest_context_data,
REFIID riid, const OXID_INFO *oxid_info,
void **object);
/* Marshalling just passes a unique identifier to the remote client,
* that makes it possible to find the passed interface again.
@ -73,7 +69,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
* IPIDs identify an interface stub and are apartment scoped
*/
inline static HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
{
HRESULT hr;
CLSID clsid;
@ -98,10 +94,14 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
if (hr != S_OK)
return hr;
hr = apartment_createwindowifneeded(apt);
if (hr != S_OK)
return hr;
hr = IUnknown_QueryInterface(object, riid, (void **)&iobject);
if (hr != S_OK)
{
ERR("object doesn't expose interface %s, failing with error 0x%08lx\n",
ERR("object doesn't expose interface %s, failing with error 0x%08x\n",
debugstr_guid(riid), hr);
return E_NOINTERFACE;
}
@ -124,7 +124,8 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
IPSFactoryBuffer_Release(psfb);
if (hr != S_OK)
{
ERR("Failed to create an IRpcStubBuffer from IPSFactory for %s\n", debugstr_guid(riid));
ERR("Failed to create an IRpcStubBuffer from IPSFactory for %s with error 0x%08x\n",
debugstr_guid(riid), hr);
IUnknown_Release(iobject);
return hr;
}
@ -156,17 +157,18 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
/* make sure ifstub that we are creating is unique */
ifstub = stub_manager_find_ifstub(manager, riid, mshlflags);
if (!ifstub)
{
ifstub = stub_manager_new_ifstub(manager, stub, iobject, riid, mshlflags);
IUnknown_Release(iobject);
if (stub) IRpcStubBuffer_Release(stub);
if (!ifstub)
{
stub_manager_int_release(manager);
/* FIXME: should we do another release to completely destroy the
* stub manager? */
return E_OUTOFMEMORY;
}
if (stub) IRpcStubBuffer_Release(stub);
IUnknown_Release(iobject);
if (!ifstub)
{
stub_manager_int_release(manager);
/* destroy the stub manager if it has no ifstubs by releasing
* zero external references */
stub_manager_ext_release(manager, 0, TRUE);
return E_OUTOFMEMORY;
}
if (!tablemarshal)
@ -216,7 +218,7 @@ static HRESULT WINAPI ClientIdentity_QueryInterface(IMultiQI * iface, REFIID rii
static ULONG WINAPI ClientIdentity_AddRef(IMultiQI * iface)
{
struct proxy_manager * This = (struct proxy_manager *)iface;
TRACE("%p - before %ld\n", iface, This->refs);
TRACE("%p - before %d\n", iface, This->refs);
return InterlockedIncrement(&This->refs);
}
@ -224,7 +226,7 @@ static ULONG WINAPI ClientIdentity_Release(IMultiQI * iface)
{
struct proxy_manager * This = (struct proxy_manager *)iface;
ULONG refs = InterlockedDecrement(&This->refs);
TRACE("%p - after %ld\n", iface, refs);
TRACE("%p - after %d\n", iface, refs);
if (!refs)
proxy_manager_destroy(This);
return refs;
@ -241,13 +243,13 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
/* mapping of RemQueryInterface index to QueryMultipleInterfaces index */
ULONG *mapping = HeapAlloc(GetProcessHeap(), 0, cMQIs * sizeof(*mapping));
TRACE("cMQIs: %ld\n", cMQIs);
TRACE("cMQIs: %d\n", cMQIs);
/* try to get a local interface - this includes already active proxy
* interfaces and also interfaces exposed by the proxy manager */
for (i = 0; i < cMQIs; i++)
{
TRACE("iid[%ld] = %s\n", i, debugstr_guid(pMQIs[i].pIID));
TRACE("iid[%d] = %s\n", i, debugstr_guid(pMQIs[i].pIID));
pMQIs[i].hr = proxy_manager_query_local_interface(This, pMQIs[i].pIID, (void **)&pMQIs[i].pItf);
if (pMQIs[i].hr == S_OK)
successful_mqis++;
@ -259,7 +261,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
}
}
TRACE("%ld interfaces not found locally\n", nonlocal_mqis);
TRACE("%d interfaces not found locally\n", nonlocal_mqis);
/* if we have more than one interface not found locally then we must try
* to query the remote object for it */
@ -282,7 +284,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
hr = IRemUnknown_RemQueryInterface(remunk, ipid, NORMALEXTREFS,
nonlocal_mqis, iids, &qiresults);
if (FAILED(hr))
ERR("IRemUnknown_RemQueryInterface failed with error 0x%08lx\n", hr);
ERR("IRemUnknown_RemQueryInterface failed with error 0x%08x\n", hr);
}
/* IRemUnknown_RemQueryInterface can return S_FALSE if only some of
@ -296,7 +298,9 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
HRESULT hrobj = qiresults[i].hResult;
if (hrobj == S_OK)
hrobj = unmarshal_object(&qiresults[i].std, This->parent,
pMQIs[index].pIID,
This->dest_context,
This->dest_context_data,
pMQIs[index].pIID, &This->oxid_info,
(void **)&pMQIs[index].pItf);
if (hrobj == S_OK)
@ -311,7 +315,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
CoTaskMemFree(qiresults);
}
TRACE("%ld/%ld successfully queried\n", successful_mqis, cMQIs);
TRACE("%d/%d successfully queried\n", successful_mqis, cMQIs);
HeapFree(GetProcessHeap(), 0, iids);
HeapFree(GetProcessHeap(), 0, mapping);
@ -332,6 +336,13 @@ static const IMultiQIVtbl ClientIdentity_Vtbl =
ClientIdentity_QueryMultipleInterfaces
};
/* FIXME: remove these */
static HRESULT WINAPI StdMarshalImpl_GetUnmarshalClass(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid);
static HRESULT WINAPI StdMarshalImpl_GetMarshalSizeMax(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize);
static HRESULT WINAPI StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv);
static HRESULT WINAPI StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm);
static HRESULT WINAPI StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved);
static HRESULT WINAPI Proxy_QueryInterface(IMarshal *iface, REFIID riid, void **ppvObject)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblMarshal, iface);
@ -344,13 +355,6 @@ static ULONG WINAPI Proxy_AddRef(IMarshal *iface)
return IMultiQI_AddRef((IMultiQI *)&This->lpVtbl);
}
/* FIXME: remove these */
static HRESULT WINAPI StdMarshalImpl_GetUnmarshalClass(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid);
static HRESULT WINAPI StdMarshalImpl_GetMarshalSizeMax(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize);
static HRESULT WINAPI StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv);
static HRESULT WINAPI StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm);
static HRESULT WINAPI StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved);
static ULONG WINAPI Proxy_Release(IMarshal *iface)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblMarshal, iface);
@ -362,25 +366,97 @@ static HRESULT WINAPI Proxy_MarshalInterface(
void* pvDestContext, DWORD mshlflags)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblMarshal, iface);
ULONG res;
HRESULT hr;
STDOBJREF stdobjref;
struct ifproxy *ifproxy;
TRACE("(...,%s,...)\n", debugstr_guid(riid));
hr = proxy_manager_find_ifproxy(This, riid, &ifproxy);
if (FAILED(hr))
if (SUCCEEDED(hr))
{
ERR("couldn't find proxy for interface %s, error 0x%08lx\n", debugstr_guid(riid), hr);
return hr;
}
STDOBJREF stdobjref = ifproxy->stdobjref;
ULONG cPublicRefs = ifproxy->refs;
ULONG cPublicRefsOld;
stdobjref = ifproxy->stdobjref;
/* FIXME: optimization - share out proxy's public references if possible
* instead of making new proxy do a roundtrip through the server */
stdobjref.cPublicRefs = 0; /* InterlockedDecrement(&This->stdobjref.cPublicRefs) >= 0 ? 1 : 0 */
hr = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res);
/* optimization - share out proxy's public references if possible
* instead of making new proxy do a roundtrip through the server */
do
{
ULONG cPublicRefsNew;
cPublicRefsOld = cPublicRefs;
stdobjref.cPublicRefs = cPublicRefs / 2;
cPublicRefsNew = cPublicRefs - stdobjref.cPublicRefs;
cPublicRefs = InterlockedCompareExchange(
(LONG *)&ifproxy->refs, cPublicRefsNew, cPublicRefsOld);
} while (cPublicRefs != cPublicRefsOld);
if (!stdobjref.cPublicRefs)
{
IRemUnknown *remunk;
hr = proxy_manager_get_remunknown(This, &remunk);
if (hr == S_OK)
{
HRESULT hrref = S_OK;
REMINTERFACEREF rif;
rif.ipid = ifproxy->stdobjref.ipid;
rif.cPublicRefs = NORMALEXTREFS;
rif.cPrivateRefs = 0;
hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
if (hr == S_OK && hrref == S_OK)
stdobjref.cPublicRefs = rif.cPublicRefs;
else
ERR("IRemUnknown_RemAddRef returned with 0x%08x, hrref = 0x%08x\n", hr, hrref);
}
}
if (SUCCEEDED(hr))
{
TRACE("writing stdobjref:\n\tflags = %04lx\n\tcPublicRefs = %ld\n\toxid = %s\n\toid = %s\n\tipid = %s\n",
stdobjref.flags, stdobjref.cPublicRefs,
wine_dbgstr_longlong(stdobjref.oxid),
wine_dbgstr_longlong(stdobjref.oid),
debugstr_guid(&stdobjref.ipid));
hr = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), NULL);
}
}
else
{
/* we don't have the interface already unmarshaled so we have to
* request the object from the server */
IRemUnknown *remunk;
IPID *ipid;
REMQIRESULT *qiresults = NULL;
IID iid = *riid;
/* get the ipid of the first entry */
/* FIXME: should we implement ClientIdentity on the ifproxies instead
* of the proxy_manager so we use the correct ipid here? */
ipid = &LIST_ENTRY(list_head(&This->interfaces), struct ifproxy, entry)->stdobjref.ipid;
/* get IRemUnknown proxy so we can communicate with the remote object */
hr = proxy_manager_get_remunknown(This, &remunk);
if (hr == S_OK)
{
hr = IRemUnknown_RemQueryInterface(remunk, ipid, NORMALEXTREFS,
1, &iid, &qiresults);
if (SUCCEEDED(hr))
{
hr = IStream_Write(pStm, &qiresults->std, sizeof(qiresults->std), NULL);
if (FAILED(hr))
{
REMINTERFACEREF rif;
rif.ipid = qiresults->std.ipid;
rif.cPublicRefs = qiresults->std.cPublicRefs;
rif.cPrivateRefs = 0;
IRemUnknown_RemRelease(remunk, 1, &rif);
}
CoTaskMemFree(qiresults);
}
else
ERR("IRemUnknown_RemQueryInterface failed with error 0x%08x\n", hr);
}
}
return hr;
}
@ -398,6 +474,72 @@ static const IMarshalVtbl ProxyMarshal_Vtbl =
StdMarshalImpl_DisconnectObject
};
static HRESULT WINAPI ProxyCliSec_QueryInterface(IClientSecurity *iface, REFIID riid, void **ppvObject)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblCliSec, iface);
return IMultiQI_QueryInterface((IMultiQI *)&This->lpVtbl, riid, ppvObject);
}
static ULONG WINAPI ProxyCliSec_AddRef(IClientSecurity *iface)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblCliSec, iface);
return IMultiQI_AddRef((IMultiQI *)&This->lpVtbl);
}
static ULONG WINAPI ProxyCliSec_Release(IClientSecurity *iface)
{
ICOM_THIS_MULTI(struct proxy_manager, lpVtblCliSec, iface);
return IMultiQI_Release((IMultiQI *)&This->lpVtbl);
}
static HRESULT WINAPI ProxyCliSec_QueryBlanket(IClientSecurity *iface,
IUnknown *pProxy,
DWORD *pAuthnSvc,
DWORD *pAuthzSvc,
OLECHAR **pServerPrincName,
DWORD *pAuthnLevel,
DWORD *pImpLevel,
void **pAuthInfo,
DWORD *pCapabilities)
{
FIXME("(%p, %p, %p, %p, %p, %p, %p, %p): stub\n", pProxy, pAuthnSvc,
pAuthzSvc, pServerPrincName, pAuthnLevel, pImpLevel, pAuthInfo,
pCapabilities);
return E_NOTIMPL;
}
static HRESULT WINAPI ProxyCliSec_SetBlanket(IClientSecurity *iface,
IUnknown *pProxy, DWORD AuthnSvc,
DWORD AuthzSvc,
OLECHAR *pServerPrincName,
DWORD AuthnLevel, DWORD ImpLevel,
void *pAuthInfo,
DWORD Capabilities)
{
FIXME("(%p, %d, %d, %s, %d, %d, %p, 0x%x): stub\n", pProxy, AuthnSvc,
AuthzSvc, debugstr_w(pServerPrincName), AuthnLevel, ImpLevel,
pAuthInfo, Capabilities);
return E_NOTIMPL;
}
static HRESULT WINAPI ProxyCliSec_CopyProxy(IClientSecurity *iface,
IUnknown *pProxy, IUnknown **ppCopy)
{
FIXME("(%p, %p): stub\n", pProxy, ppCopy);
*ppCopy = NULL;
return E_NOTIMPL;
}
static const IClientSecurityVtbl ProxyCliSec_Vtbl =
{
ProxyCliSec_QueryInterface,
ProxyCliSec_AddRef,
ProxyCliSec_Release,
ProxyCliSec_QueryBlanket,
ProxyCliSec_SetBlanket,
ProxyCliSec_CopyProxy
};
static HRESULT ifproxy_get_public_ref(struct ifproxy * This)
{
HRESULT hr = S_OK;
@ -417,16 +559,16 @@ static HRESULT ifproxy_get_public_ref(struct ifproxy * This)
hr = proxy_manager_get_remunknown(This->parent, &remunk);
if (hr == S_OK)
{
HRESULT hrref;
HRESULT hrref = S_OK;
REMINTERFACEREF rif;
rif.ipid = This->stdobjref.ipid;
rif.cPublicRefs = NORMALEXTREFS;
rif.cPrivateRefs = 0;
hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
if (hr == S_OK && hrref == S_OK)
This->refs += NORMALEXTREFS;
InterlockedExchangeAdd((LONG *)&This->refs, NORMALEXTREFS);
else
ERR("IRemUnknown_RemAddRef returned with 0x%08lx, hrref = 0x%08lx\n", hr, hrref);
ERR("IRemUnknown_RemAddRef returned with 0x%08x, hrref = 0x%08x\n", hr, hrref);
}
}
ReleaseMutex(This->parent->remoting_mutex);
@ -437,6 +579,7 @@ static HRESULT ifproxy_get_public_ref(struct ifproxy * This)
static HRESULT ifproxy_release_public_refs(struct ifproxy * This)
{
HRESULT hr = S_OK;
LONG public_refs;
if (WAIT_OBJECT_0 != WaitForSingleObject(This->parent->remoting_mutex, INFINITE))
{
@ -444,29 +587,30 @@ static HRESULT ifproxy_release_public_refs(struct ifproxy * This)
return E_UNEXPECTED;
}
if (This->refs > 0)
public_refs = This->refs;
if (public_refs > 0)
{
IRemUnknown *remunk = NULL;
TRACE("releasing %ld refs\n", This->refs);
TRACE("releasing %d refs\n", public_refs);
hr = proxy_manager_get_remunknown(This->parent, &remunk);
if (hr == S_OK)
{
REMINTERFACEREF rif;
rif.ipid = This->stdobjref.ipid;
rif.cPublicRefs = This->refs;
rif.cPublicRefs = public_refs;
rif.cPrivateRefs = 0;
hr = IRemUnknown_RemRelease(remunk, 1, &rif);
if (hr == S_OK)
This->refs = 0;
InterlockedExchangeAdd((LONG *)&This->refs, -public_refs);
else if (hr == RPC_E_DISCONNECTED)
WARN("couldn't release references because object was "
"disconnected: oxid = %s, oid = %s\n",
wine_dbgstr_longlong(This->parent->oxid),
wine_dbgstr_longlong(This->parent->oid));
else
ERR("IRemUnknown_RemRelease failed with error 0x%08lx\n", hr);
ERR("IRemUnknown_RemRelease failed with error 0x%08x\n", hr);
}
}
ReleaseMutex(This->parent->remoting_mutex);
@ -501,16 +645,14 @@ static void ifproxy_destroy(struct ifproxy * This)
This->chan = NULL;
}
/* note: we don't call Release for This->proxy because its lifetime is
* controlled by the return value from ClientIdentity_Release, which this
* function is always called from */
if (This->proxy) IRpcProxyBuffer_Release(This->proxy);
HeapFree(GetProcessHeap(), 0, This);
}
static HRESULT proxy_manager_construct(
APARTMENT * apt, ULONG sorflags, OXID oxid, OID oid,
struct proxy_manager ** proxy_manager)
const OXID_INFO *oxid_info, struct proxy_manager ** proxy_manager)
{
struct proxy_manager * This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This) return E_OUTOFMEMORY;
@ -522,8 +664,28 @@ static HRESULT proxy_manager_construct(
return HRESULT_FROM_WIN32(GetLastError());
}
if (oxid_info)
{
This->oxid_info.dwPid = oxid_info->dwPid;
This->oxid_info.dwTid = oxid_info->dwTid;
This->oxid_info.ipidRemUnknown = oxid_info->ipidRemUnknown;
This->oxid_info.dwAuthnHint = oxid_info->dwAuthnHint;
This->oxid_info.psa = NULL /* FIXME: copy from oxid_info */;
}
else
{
HRESULT hr = RPC_ResolveOxid(oxid, &This->oxid_info);
if (FAILED(hr))
{
CloseHandle(This->remoting_mutex);
HeapFree(GetProcessHeap(), 0, This);
return hr;
}
}
This->lpVtbl = &ClientIdentity_Vtbl;
This->lpVtblMarshal = &ProxyMarshal_Vtbl;
This->lpVtblCliSec = &ProxyCliSec_Vtbl;
list_init(&This->entry);
list_init(&This->interfaces);
@ -548,6 +710,11 @@ static HRESULT proxy_manager_construct(
/* we create the IRemUnknown proxy on demand */
This->remunk = NULL;
/* initialise these values to the weakest values and they will be
* overwritten in proxy_manager_set_context */
This->dest_context = MSHCTX_INPROC;
This->dest_context_data = NULL;
EnterCriticalSection(&apt->cs);
/* FIXME: we are dependent on the ordering in here to make sure a proxy's
* IRemUnknown proxy doesn't get destroyed before the regual proxy does
@ -564,6 +731,63 @@ static HRESULT proxy_manager_construct(
return S_OK;
}
static inline void proxy_manager_set_context(struct proxy_manager *This, MSHCTX dest_context, void *dest_context_data)
{
MSHCTX old_dest_context = This->dest_context;
MSHCTX new_dest_context;
do
{
new_dest_context = old_dest_context;
/* "stronger" values overwrite "weaker" values. stronger values are
* ones that disable more optimisations */
switch (old_dest_context)
{
case MSHCTX_INPROC:
new_dest_context = dest_context;
break;
case MSHCTX_CROSSCTX:
switch (dest_context)
{
case MSHCTX_INPROC:
break;
default:
new_dest_context = dest_context;
}
break;
case MSHCTX_LOCAL:
switch (dest_context)
{
case MSHCTX_INPROC:
case MSHCTX_CROSSCTX:
break;
default:
new_dest_context = dest_context;
}
break;
case MSHCTX_NOSHAREDMEM:
switch (dest_context)
{
case MSHCTX_DIFFERENTMACHINE:
new_dest_context = dest_context;
break;
default:
break;
}
break;
default:
break;
}
if (old_dest_context == new_dest_context) break;
old_dest_context = InterlockedCompareExchange((PLONG)&This->dest_context, new_dest_context, old_dest_context);
} while (new_dest_context != old_dest_context);
if (dest_context_data)
InterlockedExchangePointer(&This->dest_context_data, dest_context_data);
}
static HRESULT proxy_manager_query_local_interface(struct proxy_manager * This, REFIID riid, void ** ppv)
{
HRESULT hr;
@ -586,9 +810,9 @@ static HRESULT proxy_manager_query_local_interface(struct proxy_manager * This,
}
if (IsEqualIID(riid, &IID_IClientSecurity))
{
FIXME("requesting IClientSecurity, but it is unimplemented\n");
*ppv = NULL;
return E_NOINTERFACE;
*ppv = (void *)&This->lpVtblCliSec;
IUnknown_AddRef((IUnknown *)*ppv);
return S_OK;
}
hr = proxy_manager_find_ifproxy(This, riid, &ifproxy);
@ -617,7 +841,7 @@ static HRESULT proxy_manager_create_ifproxy(
ifproxy->parent = This;
ifproxy->stdobjref = *stdobjref;
ifproxy->iid = *riid;
ifproxy->refs = stdobjref->cPublicRefs;
ifproxy->refs = 0;
ifproxy->proxy = NULL;
assert(channel);
@ -644,21 +868,17 @@ static HRESULT proxy_manager_create_ifproxy(
&ifproxy->proxy, &ifproxy->iface);
IPSFactoryBuffer_Release(psfb);
if (hr != S_OK)
ERR("Could not create proxy for interface %s, error 0x%08lx\n",
ERR("Could not create proxy for interface %s, error 0x%08x\n",
debugstr_guid(riid), hr);
}
else
ERR("Could not get IPSFactoryBuffer for interface %s, error 0x%08lx\n",
ERR("Could not get IPSFactoryBuffer for interface %s, error 0x%08x\n",
debugstr_guid(riid), hr);
if (hr == S_OK)
hr = IRpcProxyBuffer_Connect(ifproxy->proxy, ifproxy->chan);
}
/* get at least one external reference to the object to keep it alive */
if (hr == S_OK)
hr = ifproxy_get_public_ref(ifproxy);
if (hr == S_OK)
{
EnterCriticalSection(&This->cs);
@ -751,23 +971,18 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk
stdobjref.oxid = This->oxid;
/* FIXME: what should be used for the oid? The DCOM draft doesn't say */
stdobjref.oid = (OID)-1;
/* FIXME: this is a hack around not having an OXID resolver yet -
* the OXID resolver should give us the IPID of the IRemUnknown
* interface */
stdobjref.ipid.Data1 = 0xffffffff;
stdobjref.ipid.Data2 = 0xffff;
stdobjref.ipid.Data3 = 0xffff;
assert(sizeof(stdobjref.ipid.Data4) == sizeof(stdobjref.oxid));
memcpy(&stdobjref.ipid.Data4, &stdobjref.oxid, sizeof(OXID));
stdobjref.ipid = This->oxid_info.ipidRemUnknown;
/* do the unmarshal */
hr = unmarshal_object(&stdobjref, This->parent, &IID_IRemUnknown, (void**)&This->remunk);
hr = unmarshal_object(&stdobjref, This->parent, This->dest_context,
This->dest_context_data, &IID_IRemUnknown,
&This->oxid_info, (void**)&This->remunk);
if (hr == S_OK)
*remunk = This->remunk;
}
LeaveCriticalSection(&This->cs);
TRACE("got IRemUnknown* pointer %p, hr = 0x%08lx\n", *remunk, hr);
TRACE("got IRemUnknown* pointer %p, hr = 0x%08x\n", *remunk, hr);
return hr;
}
@ -808,6 +1023,7 @@ static void proxy_manager_destroy(struct proxy_manager * This)
}
if (This->remunk) IRemUnknown_Release(This->remunk);
CoTaskMemFree(This->oxid_info.psa);
DEBUG_CLEAR_CRITSEC_NAME(&This->cs);
DeleteCriticalSection(&This->cs);
@ -939,7 +1155,7 @@ StdMarshalImpl_MarshalInterface(
hres = marshal_object(apt, &stdobjref, riid, (IUnknown *)pv, mshlflags);
if (hres)
{
ERR("Failed to create ifstub, hres=0x%lx\n", hres);
ERR("Failed to create ifstub, hres=0x%x\n", hres);
return hres;
}
@ -952,7 +1168,10 @@ StdMarshalImpl_MarshalInterface(
/* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
* no questions asked about the rules surrounding same-apartment unmarshals
* and table marshaling */
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFIID riid, void **object)
static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
MSHCTX dest_context, void *dest_context_data,
REFIID riid, const OXID_INFO *oxid_info,
void **object)
{
struct proxy_manager *proxy_manager = NULL;
HRESULT hr = S_OK;
@ -965,12 +1184,12 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
wine_dbgstr_longlong(stdobjref->oid),
debugstr_guid(&stdobjref->ipid));
/* create an a new proxy manager if one doesn't already exist for the
/* create a new proxy manager if one doesn't already exist for the
* object */
if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))
{
hr = proxy_manager_construct(apt, stdobjref->flags,
stdobjref->oxid, stdobjref->oid,
stdobjref->oxid, stdobjref->oid, oxid_info,
&proxy_manager);
}
else
@ -979,11 +1198,18 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
if (hr == S_OK)
{
struct ifproxy * ifproxy;
proxy_manager_set_context(proxy_manager, dest_context, dest_context_data);
hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy);
if (hr == E_NOINTERFACE)
{
IRpcChannelBuffer *chanbuf;
hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid, &chanbuf);
hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid,
&proxy_manager->oxid_info,
proxy_manager->dest_context,
proxy_manager->dest_context_data,
&chanbuf);
if (hr == S_OK)
hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref,
riid, chanbuf, &ifproxy);
@ -991,6 +1217,15 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
else
IUnknown_AddRef((IUnknown *)ifproxy->iface);
if (hr == S_OK)
{
InterlockedExchangeAdd((LONG *)&ifproxy->refs, stdobjref->cPublicRefs);
/* get at least one external reference to the object to keep it alive */
hr = ifproxy_get_public_ref(ifproxy);
if (FAILED(hr))
ifproxy_destroy(ifproxy);
}
if (hr == S_OK)
*object = ifproxy->iface;
}
@ -1005,7 +1240,8 @@ 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;
StdMarshalImpl *This = (StdMarshalImpl *)iface;
struct stub_manager *stubmgr = NULL;
STDOBJREF stdobjref;
ULONG res;
HRESULT hres;
@ -1039,7 +1275,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
/* unref the ifstub. FIXME: only do this on success? */
if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid))
stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs);
stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, TRUE);
stub_manager_int_release(stubmgr);
return hres;
@ -1056,8 +1292,6 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
{
if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid))
hres = CO_E_OBJNOTCONNECTED;
stub_manager_int_release(stubmgr);
}
else
{
@ -1066,17 +1300,20 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
wine_dbgstr_longlong(stdobjref.oid));
hres = CO_E_OBJNOTCONNECTED;
}
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);
hres = unmarshal_object(&stdobjref, apt, This->dwDestContext,
This->pvDestContext, riid,
stubmgr ? &stubmgr->oxid_info : NULL, ppv);
if (hres) WARN("Failed with error 0x%08lx\n", hres);
if (stubmgr) stub_manager_int_release(stubmgr);
if (stub_apt) apartment_release(stub_apt);
if (hres) WARN("Failed with error 0x%08x\n", hres);
else TRACE("Successfully created proxy %p\n", *ppv);
return hres;
@ -1185,11 +1422,11 @@ HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk,
if (pUnk == NULL)
{
FIXME("(%s,NULL,%lx,%p,%lx,%p), unimplemented yet.\n",
FIXME("(%s,NULL,%x,%p,%x,%p), unimplemented yet.\n",
debugstr_guid(riid),dwDestContext,pvDestContext,mshlflags,ppMarshal);
return E_NOTIMPL;
}
TRACE("(%s,%p,%lx,%p,%lx,%p)\n",
TRACE("(%s,%p,%x,%p,%x,%p)\n",
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal);
*ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
dm = (StdMarshalImpl*) *ppMarshal;
@ -1241,7 +1478,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
hr = IStream_Read(stream, &objref, FIELD_OFFSET(OBJREF, u_objref), &res);
if (hr || (res != FIELD_OFFSET(OBJREF, u_objref)))
{
ERR("Failed to read common OBJREF header, 0x%08lx\n", hr);
ERR("Failed to read common OBJREF header, 0x%08x\n", hr);
return STG_E_READFAULT;
}
@ -1270,7 +1507,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
custom_header_size, &res);
if (hr || (res != custom_header_size))
{
ERR("Failed to read OR_CUSTOM header, 0x%08lx\n", hr);
ERR("Failed to read OR_CUSTOM header, 0x%08x\n", hr);
return STG_E_READFAULT;
}
/* now create the marshaler specified in the stream */
@ -1286,7 +1523,7 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
}
if (hr)
ERR("Failed to create marshal, 0x%08lx\n", hr);
ERR("Failed to create marshal, 0x%08x\n", hr);
return hr;
}
@ -1327,20 +1564,20 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk,
pvDestContext, mshlFlags, &marshaler_clsid);
if (hr)
{
ERR("IMarshal::GetUnmarshalClass failed, 0x%08lx\n", hr);
ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr);
IMarshal_Release(pMarshal);
return hr;
}
hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext,
pvDestContext, mshlFlags, pulSize);
/* add on the size of the common header */
*pulSize += FIELD_OFFSET(OBJREF, u_objref);
/* if custom marshaling, add on size of custom header */
if (!IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal))
*pulSize += FIELD_OFFSET(OBJREF, u_objref.u_custom.pData) -
FIELD_OFFSET(OBJREF, u_objref.u_custom);
if (IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal))
/* add on the size of the common header */
*pulSize += FIELD_OFFSET(OBJREF, u_objref);
else
/* custom marshaling: add on the size of the whole OBJREF structure
* like native does */
*pulSize += sizeof(OBJREF);
IMarshal_Release(pMarshal);
return hr;
@ -1400,12 +1637,12 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
OBJREF objref;
LPMARSHAL pMarshal;
TRACE("(%p, %s, %p, %lx, %p,", pStream, debugstr_guid(riid), pUnk,
TRACE("(%p, %s, %p, %x, %p,", pStream, debugstr_guid(riid), pUnk,
dwDestContext, pvDestContext);
dump_MSHLFLAGS(mshlFlags);
TRACE(")\n");
if (pUnk == NULL)
if (!pUnk || !pStream)
return E_INVALIDARG;
objref.signature = OBJREF_SIGNATURE;
@ -1415,7 +1652,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal);
if (hr)
{
ERR("Failed to get marshaller, 0x%08lx\n", hr);
ERR("Failed to get marshaller, 0x%08x\n", hr);
return hr;
}
@ -1423,7 +1660,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
pvDestContext, mshlFlags, &marshaler_clsid);
if (hr)
{
ERR("IMarshal::GetUnmarshalClass failed, 0x%08lx\n", hr);
ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr);
goto cleanup;
}
@ -1437,7 +1674,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
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);
ERR("Failed to write OBJREF header to stream, 0x%08x\n", hr);
goto cleanup;
}
}
@ -1453,7 +1690,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
&objref.u_objref.u_custom.size);
if (hr)
{
ERR("Failed to get max size of marshal data, error 0x%08lx\n", hr);
ERR("Failed to get max size of marshal data, error 0x%08x\n", hr);
goto cleanup;
}
/* write constant sized common header and OR_CUSTOM data into stream */
@ -1461,7 +1698,7 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
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);
ERR("Failed to write OR_CUSTOM header to stream with 0x%08x\n", hr);
goto cleanup;
}
}
@ -1473,14 +1710,14 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
if (hr)
{
ERR("Failed to marshal the interface %s, %lx\n", debugstr_guid(riid), hr);
ERR("Failed to marshal the interface %s, %x\n", debugstr_guid(riid), hr);
goto cleanup;
}
cleanup:
IMarshal_Release(pMarshal);
TRACE("completed with hr 0x%08lx\n", hr);
TRACE("completed with hr 0x%08x\n", hr);
return hr;
}
@ -1514,6 +1751,9 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
TRACE("(%p, %s, %p)\n", pStream, debugstr_guid(riid), ppv);
if (!pStream || !ppv)
return E_INVALIDARG;
hr = get_unmarshaler_from_stream(pStream, &pMarshal, &iid);
if (hr != S_OK)
return hr;
@ -1521,20 +1761,17 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
/* call the helper object to do the actual unmarshaling */
hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object);
if (hr)
ERR("IMarshal::UnmarshalInterface failed, 0x%08lx\n", hr);
/* IID_NULL means use the interface ID of the marshaled object */
if (!IsEqualIID(riid, &IID_NULL))
iid = *riid;
ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr);
if (hr == S_OK)
{
if (!IsEqualIID(riid, &iid))
/* IID_NULL means use the interface ID of the marshaled object */
if (!IsEqualIID(riid, &IID_NULL) && !IsEqualIID(riid, &iid))
{
TRACE("requested interface != marshalled interface, additional QI needed\n");
hr = IUnknown_QueryInterface(object, &iid, ppv);
hr = IUnknown_QueryInterface(object, riid, ppv);
if (hr)
ERR("Couldn't query for interface %s, hr = 0x%08lx\n",
ERR("Couldn't query for interface %s, hr = 0x%08x\n",
debugstr_guid(riid), hr);
IUnknown_Release(object);
}
@ -1546,7 +1783,7 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
IMarshal_Release(pMarshal);
TRACE("completed with hr 0x%lx\n", hr);
TRACE("completed with hr 0x%x\n", hr);
return hr;
}
@ -1588,7 +1825,7 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
/* call the helper object to do the releasing of marshal data */
hr = IMarshal_ReleaseMarshalData(pMarshal, pStream);
if (hr)
ERR("IMarshal::ReleaseMarshalData failed with error 0x%08lx\n", hr);
ERR("IMarshal::ReleaseMarshalData failed with error 0x%08x\n", hr);
IMarshal_Release(pMarshal);
return hr;
@ -1603,7 +1840,7 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
* PARAMS
* riid [I] Identifier of the interface to be marshalled.
* pUnk [I] Pointer to IUnknown-derived interface that will be marshalled.
* ppStm [O] Pointer to IStream object that is created and then used to store the marshalled inteface.
* ppStm [O] Pointer to IStream object that is created and then used to store the marshalled interface.
*
* RETURNS
* Success: S_OK
@ -1628,7 +1865,7 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(
if (SUCCEEDED(hres))
{
memset(&seekto, 0, sizeof(seekto));
IStream_Seek(*ppStm, seekto, SEEK_SET, &xpos);
IStream_Seek(*ppStm, seekto, STREAM_SEEK_SET, &xpos);
}
else
{
@ -1642,10 +1879,10 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(
/***********************************************************************
* CoGetInterfaceAndReleaseStream [OLE32.@]
*
* Unmarshalls an inteface from a stream and then releases the stream.
* Unmarshalls an interface from a stream and then releases the stream.
*
* PARAMS
* pStm [I] Stream that contains the marshalled inteface.
* pStm [I] Stream that contains the marshalled interface.
* riid [I] Interface identifier of the object to unmarshall.
* ppv [O] Address of pointer where the requested interface object will be stored.
*
@ -1654,7 +1891,7 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(
* Failure: A COM error code
*
* SEE ALSO
* CoMarshalInterThreadInterfaceInStream() and CoUnmarshalInteface()
* CoMarshalInterThreadInterfaceInStream() and CoUnmarshalInterface()
*/
HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID riid,
LPVOID *ppv)
@ -1663,6 +1900,7 @@ HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID riid,
TRACE("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
if(!pStm) return E_INVALIDARG;
hres = CoUnmarshalInterface(pStm, riid, ppv);
IStream_Release(pStm);
return hres;

View File

@ -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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -43,7 +43,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
/******************************************************************************
* HGLOBALLockBytesImpl definition.
*
* This class imlements the ILockBytes inteface and represents a byte array
* This class implements the ILockBytes interface and represents a byte array
* object supported by an HGLOBAL pointer.
*/
struct HGLOBALLockBytesImpl
@ -81,77 +81,15 @@ typedef struct HGLOBALLockBytesImpl HGLOBALLockBytesImpl;
/*
* Method definition for the HGLOBALLockBytesImpl class.
*/
HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(
static HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(
HGLOBAL hGlobal,
BOOL fDeleteOnRelease);
void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This);
static void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This);
HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
ILockBytes* iface,
REFIID riid, /* [in] */
void** ppvObject); /* [iid_is][out] */
static HRESULT WINAPI HGLOBALLockBytesImpl_SetSize( ILockBytes* iface, ULARGE_INTEGER libNewSize );
ULONG WINAPI HGLOBALLockBytesImpl_AddRef(
ILockBytes* iface);
ULONG WINAPI HGLOBALLockBytesImpl_Release(
ILockBytes* iface);
HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */
void* pv, /* [length_is][size_is][out] */
ULONG cb, /* [in] */
ULONG* pcbRead); /* [out] */
HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */
const void* pv, /* [size_is][in] */
ULONG cb, /* [in] */
ULONG* pcbWritten); /* [out] */
HRESULT WINAPI HGLOBALLockBytesImpl_Flush(
ILockBytes* iface);
HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
ILockBytes* iface,
ULARGE_INTEGER libNewSize); /* [in] */
HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
ILockBytes* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType); /* [in] */
HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
ILockBytes* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType); /* [in] */
HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
ILockBytes* iface,
STATSTG* pstatstg, /* [out] */
DWORD grfStatFlag); /* [in] */
/*
* Virtual function table for the HGLOBALLockBytesImpl class.
*/
static const ILockBytesVtbl HGLOBALLockBytesImpl_Vtbl =
{
HGLOBALLockBytesImpl_QueryInterface,
HGLOBALLockBytesImpl_AddRef,
HGLOBALLockBytesImpl_Release,
HGLOBALLockBytesImpl_ReadAt,
HGLOBALLockBytesImpl_WriteAt,
HGLOBALLockBytesImpl_Flush,
HGLOBALLockBytesImpl_SetSize,
HGLOBALLockBytesImpl_LockRegion,
HGLOBALLockBytesImpl_UnlockRegion,
HGLOBALLockBytesImpl_Stat,
};
static const ILockBytesVtbl HGLOBALLockBytesImpl_Vtbl;
/******************************************************************************
* CreateILockBytesOnHGlobal [OLE32.@]
@ -224,10 +162,10 @@ HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal)
/* It is not our lockbytes implementation, so use a more generic way */
hres = ILockBytes_Stat(plkbyt,&stbuf,0);
if (hres != S_OK) {
ERR("Cannot ILockBytes_Stat, %lx\n",hres);
ERR("Cannot ILockBytes_Stat, %x\n",hres);
return hres;
}
FIXME("cbSize is %ld\n",stbuf.cbSize.u.LowPart);
FIXME("cbSize is %d\n",stbuf.cbSize.u.LowPart);
*phglobal = GlobalAlloc( GMEM_MOVEABLE|GMEM_SHARE, stbuf.cbSize.u.LowPart);
if (!*phglobal)
return E_INVALIDARG;
@ -235,11 +173,11 @@ HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal)
hres = ILockBytes_ReadAt(plkbyt, start, GlobalLock(*phglobal), stbuf.cbSize.u.LowPart, &xread);
GlobalUnlock(*phglobal);
if (hres != S_OK) {
FIXME("%p->ReadAt failed with %lx\n",plkbyt,hres);
FIXME("%p->ReadAt failed with %x\n",plkbyt,hres);
return hres;
}
if (stbuf.cbSize.u.LowPart != xread) {
FIXME("Read size is not requested size %ld vs %ld?\n",stbuf.cbSize.u.LowPart, xread);
FIXME("Read size is not requested size %d vs %d?\n",stbuf.cbSize.u.LowPart, xread);
}
return S_OK;
}
@ -258,8 +196,8 @@ HRESULT WINAPI GetHGlobalFromILockBytes(ILockBytes* plkbyt, HGLOBAL* phglobal)
* fDeleteOnRelease [ I] Flag set to TRUE if the HGLOBAL will be released
* when the IStream object is destroyed.
*/
HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal,
BOOL fDeleteOnRelease)
static HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal,
BOOL fDeleteOnRelease)
{
HGLOBALLockBytesImpl* newLockBytes;
newLockBytes = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALLockBytesImpl));
@ -306,7 +244,7 @@ HGLOBALLockBytesImpl* HGLOBALLockBytesImpl_Construct(HGLOBAL hGlobal,
* HGLOBALLockBytesImpl class. The pointer passed-in to this function will be
* freed and will not be valid anymore.
*/
void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This)
static void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This)
{
/*
* Release the HGlobal if the constructor asked for that.
@ -327,7 +265,7 @@ void HGLOBALLockBytesImpl_Destroy(HGLOBALLockBytesImpl* This)
* This implements the IUnknown method QueryInterface for this
* class
*/
HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
static HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
ILockBytes* iface,
REFIID riid, /* [in] */
void** ppvObject) /* [iid_is][out] */
@ -348,11 +286,8 @@ HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
/*
* Compare the riid with the interface IDs implemented by this object.
*/
if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
{
*ppvObject = (ILockBytes*)This;
}
else if (memcmp(&IID_ILockBytes, riid, sizeof(IID_ILockBytes)) == 0)
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_ILockBytes))
{
*ppvObject = (ILockBytes*)This;
}
@ -367,7 +302,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
* Query Interface always increases the reference count by one when it is
* successful
*/
HGLOBALLockBytesImpl_AddRef(iface);
IUnknown_AddRef(iface);
return S_OK;
}
@ -376,7 +311,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_QueryInterface(
* This implements the IUnknown method AddRef for this
* class
*/
ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface)
static ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface)
{
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
return InterlockedIncrement(&This->ref);
@ -386,7 +321,7 @@ ULONG WINAPI HGLOBALLockBytesImpl_AddRef(ILockBytes* iface)
* This implements the IUnknown method Release for this
* class
*/
ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface)
static ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface)
{
HGLOBALLockBytesImpl* const This=(HGLOBALLockBytesImpl*)iface;
ULONG ref;
@ -412,7 +347,7 @@ ULONG WINAPI HGLOBALLockBytesImpl_Release(ILockBytes* iface)
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
static HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */
void* pv, /* [length_is][size_is][out] */
@ -484,7 +419,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_ReadAt(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
static HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */
const void* pv, /* [size_is][in] */
@ -549,7 +484,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_WriteAt(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface)
static HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface)
{
return S_OK;
}
@ -561,7 +496,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_Flush(ILockBytes* iface)
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
static HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
ILockBytes* iface,
ULARGE_INTEGER libNewSize) /* [in] */
{
@ -598,7 +533,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_SetSize(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
static HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
ILockBytes* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@ -614,7 +549,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_LockRegion(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
static HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
ILockBytes* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@ -631,7 +566,7 @@ HRESULT WINAPI HGLOBALLockBytesImpl_UnlockRegion(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
static HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
ILockBytes* iface,
STATSTG* pstatstg, /* [out] */
DWORD grfStatFlag) /* [in] */
@ -646,3 +581,20 @@ HRESULT WINAPI HGLOBALLockBytesImpl_Stat(
return S_OK;
}
/*
* Virtual function table for the HGLOBALLockBytesImpl class.
*/
static const ILockBytesVtbl HGLOBALLockBytesImpl_Vtbl =
{
HGLOBALLockBytesImpl_QueryInterface,
HGLOBALLockBytesImpl_AddRef,
HGLOBALLockBytesImpl_Release,
HGLOBALLockBytesImpl_ReadAt,
HGLOBALLockBytesImpl_WriteAt,
HGLOBALLockBytesImpl_Flush,
HGLOBALLockBytesImpl_SetSize,
HGLOBALLockBytesImpl_LockRegion,
HGLOBALLockBytesImpl_UnlockRegion,
HGLOBALLockBytesImpl_Stat,
};

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -43,7 +43,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
/******************************************************************************
* HGLOBALLockBytesImpl16 definition.
*
* This class imlements the ILockBytes inteface and represents a byte array
* This class implements the ILockBytes interface and represents a byte array
* object supported by an HGLOBAL pointer.
*/
struct HGLOBALLockBytesImpl16
@ -174,7 +174,7 @@ static void HGLOBALLockBytesImpl16_Destroy(HGLOBALLockBytesImpl16* This)
* This implements the IUnknown method AddRef for this
* class
*/
ULONG HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface)
ULONG CDECL HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface)
{
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
@ -188,7 +188,7 @@ ULONG HGLOBALLockBytesImpl16_AddRef(ILockBytes16* iface)
* This implements the IUnknown method QueryInterface for this
* class
*/
HRESULT HGLOBALLockBytesImpl16_QueryInterface(
HRESULT CDECL HGLOBALLockBytesImpl16_QueryInterface(
ILockBytes16* iface, /* [in] SEGPTR */
REFIID riid, /* [in] */
void** ppvObject) /* [out][iid_is] (ptr to SEGPTR!) */
@ -235,7 +235,7 @@ HRESULT HGLOBALLockBytesImpl16_QueryInterface(
* This implements the IUnknown method Release for this
* class
*/
ULONG HGLOBALLockBytesImpl16_Release(ILockBytes16* iface)
ULONG CDECL HGLOBALLockBytesImpl16_Release(ILockBytes16* iface)
{
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
ULONG ref;
@ -260,7 +260,7 @@ ULONG HGLOBALLockBytesImpl16_Release(ILockBytes16* iface)
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_ReadAt(
HRESULT CDECL HGLOBALLockBytesImpl16_ReadAt(
ILockBytes16* iface,
ULARGE_INTEGER ulOffset, /* [in] */
void* pv, /* [out][length_is][size_is] */
@ -273,7 +273,7 @@ HRESULT HGLOBALLockBytesImpl16_ReadAt(
ULONG bytesReadBuffer = 0;
ULONG bytesToReadFromBuffer;
TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.u.LowPart,pv,cb,pcbRead);
TRACE("(%p,%d,%p,%d,%p)\n",This,ulOffset.u.LowPart,pv,cb,pcbRead);
/*
* If the caller is not interested in the number of bytes read,
* we use another buffer to avoid "if" statements in the code.
@ -332,14 +332,14 @@ HRESULT HGLOBALLockBytesImpl16_ReadAt(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_SetSize(
HRESULT CDECL HGLOBALLockBytesImpl16_SetSize(
ILockBytes16* iface,
ULARGE_INTEGER libNewSize) /* [in] */
{
HGLOBALLockBytesImpl16* const This=(HGLOBALLockBytesImpl16*)iface;
HGLOBAL16 supportHandle;
TRACE("(%p,%ld)\n",This,libNewSize.u.LowPart);
TRACE("(%p,%d)\n",This,libNewSize.u.LowPart);
/*
* As documented.
*/
@ -371,7 +371,7 @@ HRESULT HGLOBALLockBytesImpl16_SetSize(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_WriteAt(
HRESULT CDECL HGLOBALLockBytesImpl16_WriteAt(
ILockBytes16* iface,
ULARGE_INTEGER ulOffset, /* [in] */
const void* pv, /* [in][size_is] */
@ -384,7 +384,7 @@ HRESULT HGLOBALLockBytesImpl16_WriteAt(
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
TRACE("(%p,%ld,%p,%ld,%p)\n",This,ulOffset.u.LowPart,pv,cb,pcbWritten);
TRACE("(%p,%d,%p,%d,%p)\n",This,ulOffset.u.LowPart,pv,cb,pcbWritten);
/*
* If the caller is not interested in the number of bytes written,
* we use another buffer to avoid "if" statements in the code.
@ -433,7 +433,7 @@ HRESULT HGLOBALLockBytesImpl16_WriteAt(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface)
HRESULT CDECL HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface)
{
TRACE("(%p)\n",iface);
return S_OK;
@ -446,7 +446,7 @@ HRESULT HGLOBALLockBytesImpl16_Flush(ILockBytes16* iface)
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_LockRegion(
HRESULT CDECL HGLOBALLockBytesImpl16_LockRegion(
ILockBytes16* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@ -462,7 +462,7 @@ HRESULT HGLOBALLockBytesImpl16_LockRegion(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_UnlockRegion(
HRESULT CDECL HGLOBALLockBytesImpl16_UnlockRegion(
ILockBytes16* iface,
ULARGE_INTEGER libOffset, /* [in] */
ULARGE_INTEGER cb, /* [in] */
@ -479,7 +479,7 @@ HRESULT HGLOBALLockBytesImpl16_UnlockRegion(
*
* See the documentation of ILockBytes for more info.
*/
HRESULT HGLOBALLockBytesImpl16_Stat(
HRESULT CDECL HGLOBALLockBytesImpl16_Stat(
ILockBytes16*iface,
STATSTG16* pstatstg, /* [out] */
DWORD grfStatFlag) /* [in] */

View File

@ -4,6 +4,7 @@
* Copyright 1998 Marcus Meissner
* Copyright 1999 Noomen Hamza
* Copyright 2005 Robert Shearman (for CodeWeavers)
* Copyright 2007 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -17,7 +18,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* TODO:
* - IRunningObjectTable should work interprocess, but currently doesn't.
@ -40,11 +41,17 @@
#include "wine/list.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "compobj_private.h"
#include "moniker.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
/* see MSDN docs for IROTData::GetComparisonData, which states what this
* constant is (http://msdn2.microsoft.com/en-us/library/ms693773.aspx) */
#define MAX_COMPARISON_DATA 2048
/* define the structure of the running object table elements */
struct rot_entry
{
@ -139,26 +146,77 @@ static HRESULT get_moniker_comparison_data(IMoniker *pMoniker, MInterfacePointer
{
HRESULT hr;
IROTData *pROTData = NULL;
ULONG size = 0;
hr = IMoniker_QueryInterface(pMoniker, &IID_IROTData, (void *)&pROTData);
if (hr != S_OK)
if (SUCCEEDED(hr))
{
ERR("Failed to query moniker for IROTData interface, hr = 0x%08lx\n", hr);
return hr;
ULONG size = MAX_COMPARISON_DATA;
*moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer, abData[size]));
hr = IROTData_GetComparisonData(pROTData, (*moniker_data)->abData, size, &size);
if (hr != S_OK)
{
ERR("Failed to copy comparison data into buffer, hr = 0x%08x\n", hr);
HeapFree(GetProcessHeap(), 0, *moniker_data);
return hr;
}
(*moniker_data)->ulCntData = size;
}
IROTData_GetComparisonData(pROTData, NULL, 0, &size);
*moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer, abData[size]));
(*moniker_data)->ulCntData = size;
hr = IROTData_GetComparisonData(pROTData, (*moniker_data)->abData, size, &size);
if (hr != S_OK)
else
{
ERR("Failed to copy comparison data into buffer, hr = 0x%08lx\n", hr);
HeapFree(GetProcessHeap(), 0, *moniker_data);
return hr;
IBindCtx *pbc;
LPOLESTR pszDisplayName;
CLSID clsid;
int len;
TRACE("generating comparison data from display name\n");
hr = CreateBindCtx(0, &pbc);
if (FAILED(hr))
return hr;
hr = IMoniker_GetDisplayName(pMoniker, pbc, NULL, &pszDisplayName);
IBindCtx_Release(pbc);
if (FAILED(hr))
return hr;
hr = IMoniker_GetClassID(pMoniker, &clsid);
if (FAILED(hr))
{
CoTaskMemFree(pszDisplayName);
return hr;
}
len = strlenW(pszDisplayName);
*moniker_data = HeapAlloc(GetProcessHeap(), 0,
FIELD_OFFSET(MInterfacePointer, abData[sizeof(CLSID) + (len+1)*sizeof(WCHAR)]));
if (!*moniker_data)
{
CoTaskMemFree(pszDisplayName);
return E_OUTOFMEMORY;
}
(*moniker_data)->ulCntData = sizeof(CLSID) + (len+1)*sizeof(WCHAR);
memcpy(&(*moniker_data)->abData[0], &clsid, sizeof(clsid));
memcpy(&(*moniker_data)->abData[sizeof(clsid)], pszDisplayName, (len+1)*sizeof(WCHAR));
}
return S_OK;
}
static HRESULT reduce_moniker(IMoniker *pmk, IBindCtx *pbc, IMoniker **pmkReduced)
{
IBindCtx *pbcNew = NULL;
HRESULT hr;
if (!pbc)
{
hr = CreateBindCtx(0, &pbcNew);
if (FAILED(hr))
return hr;
pbc = pbcNew;
}
hr = IMoniker_Reduce(pmk, pbc, MKRREDUCE_ALL, NULL, pmkReduced);
if (FAILED(hr))
ERR("reducing moniker failed with error 0x%08x\n", hr);
if (pbcNew) IBindCtx_Release(pbcNew);
return hr;
}
/***********************************************************************
* RunningObjectTable_QueryInterface
*/
@ -223,6 +281,9 @@ RunningObjectTableImpl_Destroy(void)
rot_entry_delete(rot_entry);
}
DEBUG_CLEAR_CRITSEC_NAME(&runningObjectTableInstance->lock);
DeleteCriticalSection(&runningObjectTableInstance->lock);
/* free the ROT structure memory */
HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
runningObjectTableInstance = NULL;
@ -279,18 +340,13 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
HRESULT hr = S_OK;
IStream *pStream = NULL;
DWORD mshlflags;
IBindCtx *pbc;
TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
TRACE("(%p,%d,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
/*
* there's only two types of register : strong and or weak registration
* (only one must be passed on parameter)
*/
if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
(!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
(grfFlags) )
if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT))
{
ERR("Invalid combination of ROTFLAGS: %lx\n", grfFlags);
ERR("Invalid grfFlags: 0x%08x\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT));
return E_INVALIDARG;
}
@ -301,8 +357,6 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
if (!rot_entry)
return E_OUTOFMEMORY;
CoFileTimeNow(&rot_entry->last_modified);
/* marshal object */
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
if (hr != S_OK)
@ -335,10 +389,36 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
return hr;
}
hr = get_moniker_comparison_data(pmkObjectName, &rot_entry->moniker_data);
hr = CreateBindCtx(0, &pbc);
if (FAILED(hr))
{
rot_entry_delete(rot_entry);
return hr;
}
hr = reduce_moniker(pmkObjectName, pbc, &pmkObjectName);
if (FAILED(hr))
{
rot_entry_delete(rot_entry);
IBindCtx_Release(pbc);
return hr;
}
hr = IMoniker_GetTimeOfLastChange(pmkObjectName, pbc, NULL,
&rot_entry->last_modified);
IBindCtx_Release(pbc);
if (FAILED(hr))
{
CoFileTimeNow(&rot_entry->last_modified);
hr = S_OK;
}
hr = get_moniker_comparison_data(pmkObjectName,
&rot_entry->moniker_data);
if (hr != S_OK)
{
rot_entry_delete(rot_entry);
IMoniker_Release(pmkObjectName);
return hr;
}
@ -346,10 +426,12 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
if (hr != S_OK)
{
rot_entry_delete(rot_entry);
IMoniker_Release(pmkObjectName);
return hr;
}
/* marshal moniker */
hr = CoMarshalInterface(pStream, &IID_IMoniker, (IUnknown *)pmkObjectName, MSHCTX_LOCAL | MSHCTX_NOSHAREDMEM, NULL, MSHLFLAGS_TABLESTRONG);
hr = CoMarshalInterface(pStream, &IID_IMoniker, (IUnknown *)pmkObjectName,
MSHCTX_LOCAL | MSHCTX_NOSHAREDMEM, NULL, MSHLFLAGS_TABLESTRONG);
/* FIXME: a cleaner way would be to create an IStream class that writes
* directly to an MInterfacePointer */
if (hr == S_OK)
@ -367,6 +449,7 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
}
}
IStream_Release(pStream);
IMoniker_Release(pmkObjectName);
if (hr != S_OK)
{
rot_entry_delete(rot_entry);
@ -404,7 +487,7 @@ RunningObjectTableImpl_Revoke( IRunningObjectTable* iface, DWORD dwRegister)
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
struct rot_entry *rot_entry;
TRACE("(%p,%ld)\n",This,dwRegister);
TRACE("(%p,%d)\n",This,dwRegister);
EnterCriticalSection(&This->lock);
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
@ -439,7 +522,11 @@ RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface, IMoniker *pmkObjec
TRACE("(%p,%p)\n",This,pmkObjectName);
hr = reduce_moniker(pmkObjectName, NULL, &pmkObjectName);
if (FAILED(hr))
return hr;
hr = get_moniker_comparison_data(pmkObjectName, &moniker_data);
IMoniker_Release(pmkObjectName);
if (hr != S_OK)
return hr;
@ -448,7 +535,7 @@ RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface, IMoniker *pmkObjec
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
{
if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
!memcmp(moniker_data, rot_entry->moniker_data, moniker_data->ulCntData))
!memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
{
hr = S_OK;
break;
@ -486,7 +573,11 @@ RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
*ppunkObject = NULL;
hr = reduce_moniker(pmkObjectName, NULL, &pmkObjectName);
if (FAILED(hr))
return hr;
hr = get_moniker_comparison_data(pmkObjectName, &moniker_data);
IMoniker_Release(pmkObjectName);
if (hr != S_OK)
return hr;
@ -494,7 +585,7 @@ RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
{
if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
!memcmp(moniker_data, rot_entry->moniker_data, moniker_data->ulCntData))
!memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
{
IStream *pStream;
hr = create_stream_on_mip_ro(rot_entry->object, &pStream);
@ -535,7 +626,7 @@ RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
struct rot_entry *rot_entry;
TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
TRACE("(%p,%d,%p)\n",This,dwRegister,pfiletime);
EnterCriticalSection(&This->lock);
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
@ -575,7 +666,11 @@ RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
if (pmkObjectName==NULL || pfiletime==NULL)
return E_INVALIDARG;
hr = reduce_moniker(pmkObjectName, NULL, &pmkObjectName);
if (FAILED(hr))
return hr;
hr = get_moniker_comparison_data(pmkObjectName, &moniker_data);
IMoniker_Release(pmkObjectName);
if (hr != S_OK)
return hr;
@ -585,7 +680,7 @@ RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
LIST_FOR_EACH_ENTRY(rot_entry, &This->rot, struct rot_entry, entry)
{
if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
!memcmp(moniker_data, rot_entry->moniker_data, moniker_data->ulCntData))
!memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
{
*pfiletime = rot_entry->last_modified;
hr = S_OK;
@ -641,70 +736,6 @@ RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
return hr;
}
/***********************************************************************
* GetRunningObjectTable (OLE32.@)
*/
HRESULT WINAPI
GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
{
IID riid=IID_IRunningObjectTable;
HRESULT res;
TRACE("()\n");
if (reserved!=0)
return E_UNEXPECTED;
if(runningObjectTableInstance==NULL)
return CO_E_NOTINITIALIZED;
res = IRunningObjectTable_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
return res;
}
/******************************************************************************
* OleRun [OLE32.@]
*/
HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
{
IRunnableObject *runable;
IRunnableObject *This = (IRunnableObject *)pUnknown;
LRESULT ret;
ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
if (ret)
return 0; /* Appears to return no error. */
ret = IRunnableObject_Run(runable,NULL);
IRunnableObject_Release(runable);
return ret;
}
/******************************************************************************
* MkParseDisplayName [OLE32.@]
*/
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
LPDWORD pchEaten, LPMONIKER *ppmk)
{
FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
if (!(IsValidInterface((LPUNKNOWN) pbc)))
return E_INVALIDARG;
return MK_E_SYNTAX;
}
/******************************************************************************
* CreateClassMoniker [OLE32.@]
*/
HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker ** ppmk)
{
FIXME("%s\n", debugstr_guid( rclsid ));
if( ppmk )
*ppmk = NULL;
return E_NOTIMPL;
}
/* Virtual function table for the IRunningObjectTable class. */
static const IRunningObjectTableVtbl VT_RunningObjectTableImpl =
{
@ -743,6 +774,7 @@ HRESULT WINAPI RunningObjectTableImpl_Initialize(void)
list_init(&runningObjectTableInstance->rot);
InitializeCriticalSection(&runningObjectTableInstance->lock);
DEBUG_SET_CRITSEC_NAME(&runningObjectTableInstance->lock, "RunningObjectTableImpl.lock");
return S_OK;
}
@ -750,7 +782,7 @@ HRESULT WINAPI RunningObjectTableImpl_Initialize(void)
/***********************************************************************
* RunningObjectTable_UnInitialize
*/
HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
HRESULT WINAPI RunningObjectTableImpl_UnInitialize(void)
{
TRACE("\n");
@ -764,6 +796,265 @@ HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
return S_OK;
}
/***********************************************************************
* GetRunningObjectTable (OLE32.@)
*
* Retrieves the global running object table.
*
* PARAMS
* reserved [I] Reserved. Set to 0.
* pprot [O] Address that receives the pointer to the running object table.
*
* RETURNS
* Success: S_OK.
* Failure: Any HRESULT code.
*/
HRESULT WINAPI
GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
{
IID riid=IID_IRunningObjectTable;
HRESULT res;
TRACE("()\n");
if (reserved!=0)
return E_UNEXPECTED;
if(runningObjectTableInstance==NULL)
return CO_E_NOTINITIALIZED;
res = IRunningObjectTable_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
return res;
}
static HRESULT get_moniker_for_progid_display_name(LPBC pbc,
LPCOLESTR szDisplayName,
LPDWORD pchEaten,
LPMONIKER *ppmk)
{
CLSID clsid;
HRESULT hr;
LPWSTR progid;
LPCWSTR start = szDisplayName;
LPCWSTR end;
int len;
IMoniker *class_moniker;
if (*start == '@')
start++;
/* find end delimiter */
for (end = start; *end; end++)
if (*end == ':')
break;
len = end - start;
/* must start with '@' or have a ':' somewhere and mustn't be one character
* long (since that looks like an absolute path) */
if (((start == szDisplayName) && (*end == '\0')) || (len <= 1))
return MK_E_SYNTAX;
progid = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (progid)
{
memcpy(progid, start, len * sizeof(WCHAR));
progid[len] = '\0';
}
hr = CLSIDFromProgID(progid, &clsid);
HeapFree(GetProcessHeap(), 0, progid);
if (FAILED(hr))
return MK_E_SYNTAX;
hr = CreateClassMoniker(&clsid, &class_moniker);
if (SUCCEEDED(hr))
{
IParseDisplayName *pdn;
hr = IMoniker_BindToObject(class_moniker, pbc, NULL,
&IID_IParseDisplayName, (void **)&pdn);
IMoniker_Release(class_moniker);
if (SUCCEEDED(hr))
{
hr = IParseDisplayName_ParseDisplayName(pdn, pbc,
(LPOLESTR)szDisplayName,
pchEaten, ppmk);
IParseDisplayName_Release(pdn);
}
}
return hr;
}
/******************************************************************************
* MkParseDisplayName [OLE32.@]
*/
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk)
{
HRESULT hr = MK_E_SYNTAX;
static const WCHAR wszClsidColon[] = {'c','l','s','i','d',':'};
IMoniker *moniker;
DWORD chEaten;
TRACE("(%p, %s, %p, %p)\n", pbc, debugstr_w(szDisplayName), pchEaten, ppmk);
if (!(IsValidInterface((LPUNKNOWN) pbc)))
return E_INVALIDARG;
*pchEaten = 0;
*ppmk = NULL;
if (!strncmpiW(szDisplayName, wszClsidColon, sizeof(wszClsidColon)/sizeof(wszClsidColon[0])))
{
hr = ClassMoniker_CreateFromDisplayName(pbc, szDisplayName, &chEaten, &moniker);
if (FAILED(hr) && (hr != MK_E_SYNTAX))
return hr;
}
else
{
hr = get_moniker_for_progid_display_name(pbc, szDisplayName, &chEaten, &moniker);
if (FAILED(hr) && (hr != MK_E_SYNTAX))
return hr;
}
if (FAILED(hr))
{
hr = FileMoniker_CreateFromDisplayName(pbc, szDisplayName, &chEaten, &moniker);
if (FAILED(hr) && (hr != MK_E_SYNTAX))
return hr;
}
if (SUCCEEDED(hr))
{
while (TRUE)
{
IMoniker *next_moniker;
*pchEaten += chEaten;
szDisplayName += chEaten;
if (!*szDisplayName)
{
*ppmk = moniker;
return S_OK;
}
chEaten = 0;
hr = IMoniker_ParseDisplayName(moniker, pbc, NULL,
(LPOLESTR)szDisplayName, &chEaten,
&next_moniker);
IMoniker_Release(moniker);
if (FAILED(hr))
{
*pchEaten = 0;
break;
}
moniker = next_moniker;
}
}
return hr;
}
/***********************************************************************
* GetClassFile (OLE32.@)
*
* Retrieves the class ID associated with the given filename.
*
* PARAMS
* filePathName [I] Filename to retrieve the class ID for.
* pclsid [O] Address that receives the class ID for the file.
*
* RETURNS
* Success: S_OK.
* Failure: Any HRESULT code.
*/
HRESULT WINAPI GetClassFile(LPCOLESTR filePathName,CLSID *pclsid)
{
IStorage *pstg=0;
HRESULT res;
int nbElm, length, i;
LONG sizeProgId;
LPOLESTR *pathDec=0,absFile=0,progId=0;
LPWSTR extension;
static const WCHAR bkslashW[] = {'\\',0};
static const WCHAR dotW[] = {'.',0};
TRACE("%s, %p\n", debugstr_w(filePathName), pclsid);
/* if the file contain a storage object the return the CLSID written by IStorage_SetClass method*/
if((StgIsStorageFile(filePathName))==S_OK){
res=StgOpenStorage(filePathName,NULL,STGM_READ | STGM_SHARE_DENY_WRITE,NULL,0,&pstg);
if (SUCCEEDED(res))
res=ReadClassStg(pstg,pclsid);
IStorage_Release(pstg);
return res;
}
/* if the file is not a storage object then attemps to match various bits in the file against a
pattern in the registry. this case is not frequently used ! so I present only the psodocode for
this case
for(i=0;i<nFileTypes;i++)
for(i=0;j<nPatternsForType;j++){
PATTERN pat;
HANDLE hFile;
pat=ReadPatternFromRegistry(i,j);
hFile=CreateFileW(filePathName,,,,,,hFile);
SetFilePosition(hFile,pat.offset);
ReadFile(hFile,buf,pat.size,&r,NULL);
if (memcmp(buf&pat.mask,pat.pattern.pat.size)==0){
*pclsid=ReadCLSIDFromRegistry(i);
return S_OK;
}
}
*/
/* if the above strategies fail then search for the extension key in the registry */
/* get the last element (absolute file) in the path name */
nbElm=FileMonikerImpl_DecomposePath(filePathName,&pathDec);
absFile=pathDec[nbElm-1];
/* failed if the path represente a directory and not an absolute file name*/
if (!lstrcmpW(absFile, bkslashW))
return MK_E_INVALIDEXTENSION;
/* get the extension of the file */
extension = NULL;
length=lstrlenW(absFile);
for(i = length-1; (i >= 0) && *(extension = &absFile[i]) != '.'; i--)
/* nothing */;
if (!extension || !lstrcmpW(extension, dotW))
return MK_E_INVALIDEXTENSION;
res=RegQueryValueW(HKEY_CLASSES_ROOT, extension, NULL, &sizeProgId);
/* get the progId associated to the extension */
progId = CoTaskMemAlloc(sizeProgId);
res = RegQueryValueW(HKEY_CLASSES_ROOT, extension, progId, &sizeProgId);
if (res==ERROR_SUCCESS)
/* return the clsid associated to the progId */
res= CLSIDFromProgID(progId,pclsid);
for(i=0; pathDec[i]!=NULL;i++)
CoTaskMemFree(pathDec[i]);
CoTaskMemFree(pathDec);
CoTaskMemFree(progId);
if (res==ERROR_SUCCESS)
return res;
return MK_E_INVALIDEXTENSION;
}
/***********************************************************************
* EnumMoniker_QueryInterface
*/
@ -817,7 +1108,7 @@ static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface)
ref = InterlockedDecrement(&This->ref);
/* unitialize rot structure if there's no more reference to it*/
/* uninitialize rot structure if there's no more reference to it*/
if (ref == 0)
{
ULONG i;
@ -841,7 +1132,7 @@ static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface, ULONG celt, IM
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
HRESULT hr = S_OK;
TRACE("(%p) TabCurrentPos %ld Tablastindx %ld\n", This, This->pos, This->moniker_count);
TRACE("(%p) TabCurrentPos %d Tablastindx %d\n", This, This->pos, This->moniker_count);
/* retrieve the requested number of moniker from the current position */
for(i = 0; (This->pos < This->moniker_count) && (i < celt); i++)
@ -1046,7 +1337,7 @@ static HRESULT WINAPI MonikerMarshal_GetUnmarshalClass(
{
MonikerMarshal *This = impl_from_IMarshal(iface);
TRACE("(%s, %p, %lx, %p, %lx, %p)\n", debugstr_guid(riid), pv,
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pCid);
return IMoniker_GetClassID(This->moniker, pCid);
@ -1060,7 +1351,7 @@ static HRESULT WINAPI MonikerMarshal_GetMarshalSizeMax(
HRESULT hr;
ULARGE_INTEGER size;
TRACE("(%s, %p, %lx, %p, %lx, %p)\n", debugstr_guid(riid), pv,
TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pSize);
hr = IMoniker_GetSizeMax(This->moniker, &size);
@ -1075,7 +1366,7 @@ static HRESULT WINAPI MonikerMarshal_MarshalInterface(LPMARSHAL iface, IStream *
{
MonikerMarshal *This = impl_from_IMarshal(iface);
TRACE("(%p, %s, %p, %lx, %p, %lx)\n", pStm, debugstr_guid(riid), pv,
TRACE("(%p, %s, %p, %x, %p, %x)\n", pStm, debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags);
return IMoniker_Save(This->moniker, pStm, FALSE);

View File

@ -1,12 +1,47 @@
/*
* Monikers
*
* Copyright 1998 Marcus Meissner
* Copyright 1999 Noomen Hamza
* Copyright 2005 Robert Shearman (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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_MONIKER_H__
#define __WINE_MONIKER_H__
extern const CLSID CLSID_FileMoniker;
extern const CLSID CLSID_ItemMoniker;
extern const CLSID CLSID_AntiMoniker;
DEFINE_OLEGUID( CLSID_FileMoniker, 0x303, 0, 0 );
DEFINE_OLEGUID( CLSID_ItemMoniker, 0x304, 0, 0 );
DEFINE_OLEGUID( CLSID_AntiMoniker, 0x305, 0, 0 );
DEFINE_OLEGUID( CLSID_CompositeMoniker, 0x309, 0, 0 );
DEFINE_OLEGUID( CLSID_ClassMoniker, 0x31a, 0, 0 );
HRESULT FileMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT ItemMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT AntiMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT CompositeMonikerCF_Create(REFIID riid, LPVOID *ppv);
HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv);
/* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
HRESULT FileMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk);
HRESULT ClassMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk);
HRESULT MonikerMarshal_Create(IMoniker *inner, IUnknown **outer);

View File

@ -19,7 +19,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -69,7 +69,7 @@ typedef struct
/******************************************************************************
* IMalloc16_QueryInterface [COMPOBJ.500]
*/
HRESULT IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
HRESULT CDECL IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
@ -85,7 +85,7 @@ HRESULT IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
/******************************************************************************
* IMalloc16_AddRef [COMPOBJ.501]
*/
ULONG IMalloc16_fnAddRef(IMalloc16* iface) {
ULONG CDECL IMalloc16_fnAddRef(IMalloc16* iface) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->AddRef()\n",This);
return 1; /* cannot be freed */
@ -94,7 +94,7 @@ ULONG IMalloc16_fnAddRef(IMalloc16* iface) {
/******************************************************************************
* IMalloc16_Release [COMPOBJ.502]
*/
ULONG IMalloc16_fnRelease(IMalloc16* iface) {
ULONG CDECL IMalloc16_fnRelease(IMalloc16* iface) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->Release()\n",This);
return 1; /* cannot be freed */
@ -103,20 +103,20 @@ ULONG IMalloc16_fnRelease(IMalloc16* iface) {
/******************************************************************************
* IMalloc16_Alloc [COMPOBJ.503]
*/
SEGPTR IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
SEGPTR CDECL IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->Alloc(%ld)\n",This,cb);
TRACE("(%p)->Alloc(%d)\n",This,cb);
return MapLS( HeapAlloc( GetProcessHeap(), 0, cb ) );
}
/******************************************************************************
* IMalloc16_Free [COMPOBJ.505]
*/
VOID IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
VOID CDECL IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
{
void *ptr = MapSL(pv);
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->Free(%08lx)\n",This,pv);
TRACE("(%p)->Free(%08x)\n",This,pv);
UnMapLS(pv);
HeapFree( GetProcessHeap(), 0, ptr );
}
@ -124,11 +124,11 @@ VOID IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
/******************************************************************************
* IMalloc16_Realloc [COMPOBJ.504]
*/
SEGPTR IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
SEGPTR CDECL IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
{
SEGPTR ret;
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->Realloc(%08lx,%ld)\n",This,pv,cb);
TRACE("(%p)->Realloc(%08x,%d)\n",This,pv,cb);
if (!pv)
ret = IMalloc16_fnAlloc(iface, cb);
else if (cb) {
@ -144,17 +144,17 @@ SEGPTR IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
/******************************************************************************
* IMalloc16_GetSize [COMPOBJ.506]
*/
DWORD IMalloc16_fnGetSize(IMalloc16* iface,SEGPTR pv)
DWORD CDECL IMalloc16_fnGetSize(IMalloc16* iface,SEGPTR pv)
{
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->GetSize(%08lx)\n",This,pv);
TRACE("(%p)->GetSize(%08x)\n",This,pv);
return HeapSize( GetProcessHeap(), 0, MapSL(pv) );
}
/******************************************************************************
* IMalloc16_DidAlloc [COMPOBJ.507]
*/
INT16 IMalloc16_fnDidAlloc(IMalloc16* iface,LPVOID pv) {
INT16 CDECL IMalloc16_fnDidAlloc(IMalloc16* iface,LPVOID pv) {
IMalloc16 *This = (IMalloc16 *)iface;
TRACE("(%p)->DidAlloc(%p)\n",This,pv);
return (INT16)-1;
@ -163,7 +163,7 @@ INT16 IMalloc16_fnDidAlloc(IMalloc16* iface,LPVOID pv) {
/******************************************************************************
* IMalloc16_HeapMinimize [COMPOBJ.508]
*/
LPVOID IMalloc16_fnHeapMinimize(IMalloc16* iface) {
LPVOID CDECL IMalloc16_fnHeapMinimize(IMalloc16* iface) {
IMalloc16Impl *This = (IMalloc16Impl *)iface;
TRACE("(%p)->HeapMinimize()\n",This);
return NULL;
@ -284,8 +284,62 @@ HRESULT WINAPI CLSIDFromString16(
LPCOLESTR16 idstr, /* [in] string representation of guid */
CLSID *id) /* [out] GUID converted from string */
{
const BYTE *s;
int i;
BYTE table[256];
return __CLSIDFromStringA(idstr,id);
if (!idstr) {
memset( id, 0, sizeof (CLSID) );
return S_OK;
}
/* validate the CLSID string */
if (strlen(idstr) != 38)
return CO_E_CLASSSTRING;
s = (const BYTE *) idstr;
if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}'))
return CO_E_CLASSSTRING;
for (i=1; i<37; i++) {
if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
if (!(((s[i] >= '0') && (s[i] <= '9')) ||
((s[i] >= 'a') && (s[i] <= 'f')) ||
((s[i] >= 'A') && (s[i] <= 'F'))))
return CO_E_CLASSSTRING;
}
TRACE("%s -> %p\n", s, id);
/* quick lookup table */
memset(table, 0, 256);
for (i = 0; i < 10; i++) {
table['0' + i] = i;
}
for (i = 0; i < 6; i++) {
table['A' + i] = i+10;
table['a' + i] = i+10;
}
/* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
id->Data1 = (table[s[1]] << 28 | table[s[2]] << 24 | table[s[3]] << 20 | table[s[4]] << 16 |
table[s[5]] << 12 | table[s[6]] << 8 | table[s[7]] << 4 | table[s[8]]);
id->Data2 = table[s[10]] << 12 | table[s[11]] << 8 | table[s[12]] << 4 | table[s[13]];
id->Data3 = table[s[15]] << 12 | table[s[16]] << 8 | table[s[17]] << 4 | table[s[18]];
/* these are just sequential bytes */
id->Data4[0] = table[s[20]] << 4 | table[s[21]];
id->Data4[1] = table[s[22]] << 4 | table[s[23]];
id->Data4[2] = table[s[25]] << 4 | table[s[26]];
id->Data4[3] = table[s[27]] << 4 | table[s[28]];
id->Data4[4] = table[s[29]] << 4 | table[s[30]];
id->Data4[5] = table[s[31]] << 4 | table[s[32]];
id->Data4[6] = table[s[33]] << 4 | table[s[34]];
id->Data4[7] = table[s[35]] << 4 | table[s[36]];
return S_OK;
}
/******************************************************************************
@ -317,7 +371,7 @@ _xmalloc16(DWORD size, SEGPTR *ptr) {
(LPVOID)args,
(LPDWORD)ptr
)) {
ERR("CallTo16 IMalloc16 (%ld) failed\n",size);
ERR("CallTo16 IMalloc16 (%d) failed\n",size);
return E_FAIL;
}
return S_OK;
@ -429,7 +483,7 @@ HRESULT WINAPI CoRegisterClassObject16(
DWORD flags, /* [in] REGCLS flags indicating how connections are made */
LPDWORD lpdwRegister
) {
FIXME("(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
FIXME("(%s,%p,0x%08x,0x%08x,%p),stub\n",
debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister
);
return 0;
@ -441,7 +495,7 @@ HRESULT WINAPI CoRegisterClassObject16(
*/
HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
{
FIXME("(0x%08lx),stub!\n", dwRegister);
FIXME("(0x%08x),stub!\n", dwRegister);
return 0;
}
@ -504,7 +558,7 @@ 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);
TRACE("(%08x, %04x, %04x, %04x, %08x, %04x)\n", Reason, hInst, ds, HeapSize, res1, res2);
return TRUE;
}
@ -516,7 +570,7 @@ SEGPTR WINAPI CoMemAlloc(DWORD size, DWORD dwMemContext, DWORD x) {
SEGPTR segptr;
/* FIXME: check context handling */
TRACE("(%ld, 0x%08lx, 0x%08lx)\n", size, dwMemContext, x);
TRACE("(%d, 0x%08x, 0x%08x)\n", size, dwMemContext, x);
hres = _xmalloc16(size, &segptr);
if (hres != S_OK)
return (SEGPTR)0;
@ -556,7 +610,7 @@ HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid)
return CO_E_CLASSSTRING;
}
RegCloseKey(xhkey);
return __CLSIDFromStringA(buf2,riid);
return CLSIDFromString16(buf2,riid);
}
/***********************************************************************
@ -586,13 +640,22 @@ HRESULT WINAPI CoCreateInstance16(
REFIID iid,
LPVOID *ppv)
{
FIXME("(%s, %p, %lx, %s, %p), stub!\n",
FIXME("(%s, %p, %x, %s, %p), stub!\n",
debugstr_guid(rclsid), pUnkOuter, dwClsContext, debugstr_guid(iid),
ppv
);
return E_NOTIMPL;
}
/***********************************************************************
* CoDisconnectObject [COMPOBJ.15]
*/
HRESULT WINAPI CoDisconnectObject16( LPUNKNOWN lpUnk, DWORD reserved )
{
FIXME("(%p, 0x%08x): stub!\n", lpUnk, reserved);
return E_NOTIMPL;
}
/***********************************************************************
* DllGetClassObject [OLE2.4]
*/
@ -608,6 +671,6 @@ HRESULT WINAPI DllGetClassObject16(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
HRESULT WINAPI
GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
{
FIXME("(%ld,%p),stub!\n",reserved,pprot);
FIXME("(%d,%p),stub!\n",reserved,pprot);
return E_NOTIMPL;
}

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -120,7 +120,7 @@ HGLOBAL16 WINAPI OleMetaFilePictFromIconAndLabel16(
mf16 = (METAFILEPICT16 *)GlobalLock16(hmf16);
mf16->mm = MM_ANISOTROPIC;
mf16->xExt = 20; /* FIXME: bogus */
mf16->yExt = 20; /* dito */
mf16->yExt = 20; /* ditto */
mfSize = GetMetaFileBitsEx(hmf, 0, 0);
mf16->hMF = GlobalAlloc16(GMEM_MOVEABLE, mfSize);
if(mf16->hMF)
@ -154,9 +154,12 @@ HRESULT WINAPI CreateFileMoniker16(LPCOLESTR16 lpszPathName,LPMONIKER* ppmk)
/******************************************************************************
* OleSetMenuDescriptor (OLE2.41)
*
* PARAMS
* hOleMenu FIXME: Should probably be an HOLEMENU16.
*/
HRESULT WINAPI OleSetMenuDescriptor16(
HOLEMENU hOleMenu, /* FIXME: HOLEMENU16 likely */
HOLEMENU hOleMenu,
HWND16 hwndFrame,
HWND16 hwndActiveObject,
LPOLEINPLACEFRAME lpFrame,
@ -205,7 +208,7 @@ HRESULT WINAPI OleLoad16(
SEGPTR pClientSite,
LPVOID* ppvObj)
{
FIXME("(%lx,%s,%lx,%p), stub!\n", pStg, debugstr_guid(riid), pClientSite, ppvObj);
FIXME("(%x,%s,%x,%p), stub!\n", pStg, debugstr_guid(riid), pClientSite, ppvObj);
return E_NOTIMPL;
}

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>

View File

@ -17,7 +17,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"

View File

@ -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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define NONAMELESSUNION
@ -39,7 +39,7 @@ HRESULT WINAPI OleCreateLinkToFile(LPCOLESTR lpszFileName, REFIID riid,
DWORD renderopt, LPFORMATETC lpFormatEtc,
LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID* ppvObj)
{
FIXME("(%p,%p,%li,%p,%p,%p,%p), stub!\n",lpszFileName, riid, renderopt, lpFormatEtc, pClientSite, pStg, ppvObj);
FIXME("(%p,%p,%i,%p,%p,%p,%p), stub!\n",lpszFileName, riid, renderopt, lpFormatEtc, pClientSite, pStg, ppvObj);
return E_NOTIMPL;
}
@ -115,7 +115,7 @@ HRESULT WINAPI OleRegEnumFormatEtc (
DWORD dwDirection,
LPENUMFORMATETC* ppenumFormatetc)
{
FIXME("(%p, %ld, %p), stub!\n", clsid, dwDirection, ppenumFormatetc);
FIXME("(%p, %d, %p), stub!\n", clsid, dwDirection, ppenumFormatetc);
return E_NOTIMPL;
}

View File

@ -4,11 +4,12 @@
<include base="ole32">.</include>
<include base="ReactOS">include/reactos/wine</include>
<define name="__REACTOS__" />
<define name="__USE_W32API" />
<define name="__WINESRC__" />
<define name="_WIN32_IE">0x600</define>
<define name="_WIN32_WINNT">0x501</define>
<define name="WINVER">0x501</define>
<define name="_STDDEF_H" />
<define name="COM_NO_WINDOWS_H" />
<define name="NOGDI" />
<library>wine</library>
<library>uuid</library>
<library>ntdll</library>
@ -17,8 +18,10 @@
<library>gdi32</library>
<library>user32</library>
<library>rpcrt4</library>
<file>dcom.idl</file>
<file>antimoniker.c</file>
<file>bindctx.c</file>
<file>classmoniker.c</file>
<file>clipboard.c</file>
<file>compobj.c</file>
<file>compositemoniker.c</file>
@ -49,6 +52,7 @@
<file>storage32.c</file>
<file>stubmanager.c</file>
<file>usrmarshal.c</file>
<file>enumx.c</file>
<file>ole32res.rc</file>
<file>ole32.spec</file>
</module>

View File

@ -20,7 +20,7 @@
@ stdcall CoFreeAllLibraries()
@ stdcall CoFreeLibrary(long)
@ stdcall CoFreeUnusedLibraries()
@ stub CoGetCallContext #@ stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
@ stdcall CoGetCallContext(ptr ptr)
@ stub CoGetCallerTID
@ stdcall CoGetClassObject(ptr long ptr ptr ptr)
@ stub CoGetCurrentLogicalThreadId
@ -30,13 +30,13 @@
@ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr)
@ stdcall CoGetMalloc(long ptr)
@ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long)
@ stub CoGetObject
@ stdcall CoGetObject(wstr ptr ptr ptr)
@ stdcall CoGetPSClsid(ptr ptr)
@ stdcall CoGetStandardMarshal(ptr ptr long ptr long ptr)
@ stdcall CoGetState(ptr)
@ stub CoGetTIDFromIPID
@ stdcall CoGetTreatAsClass(ptr ptr)
@ stub CoImpersonateClient
@ stdcall CoImpersonateClient()
@ stdcall CoInitialize(ptr)
@ stdcall CoInitializeEx(ptr long)
@ stdcall CoInitializeSecurity(ptr long ptr ptr long long ptr long ptr)
@ -49,19 +49,19 @@
@ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr)
@ stdcall CoMarshalInterface(ptr ptr ptr long ptr long)
@ stub CoQueryAuthenticationServices
@ stub CoQueryClientBlanket
@ stdcall CoQueryClientBlanket(ptr ptr ptr ptr ptr ptr ptr)
@ stdcall CoQueryProxyBlanket(ptr ptr ptr ptr ptr ptr ptr ptr)
@ stub CoQueryReleaseObject
@ stub CoRegisterChannelHook
@ stdcall CoRegisterChannelHook(ptr ptr)
@ stdcall CoRegisterClassObject(ptr ptr long long ptr)
@ stdcall CoRegisterMallocSpy (ptr)
@ stdcall CoRegisterMessageFilter(ptr ptr)
@ stub CoRegisterPSClsid #@ stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
@ stdcall CoRegisterPSClsid(ptr ptr)
@ stub CoRegisterSurrogate
@ stdcall CoReleaseMarshalData(ptr)
@ stdcall CoReleaseServerProcess()
@ stdcall CoResumeClassObjects()
@ stub CoRevertToSelf #@ stdcall () return 0,ERR_NOTIMPLEMENTED
@ stdcall CoRevertToSelf()
@ stdcall CoRevokeClassObject(long)
@ stdcall CoRevokeMallocSpy()
@ stdcall CoSetProxyBlanket(ptr long long wstr long long ptr long)
@ -76,6 +76,7 @@
@ stub CoUnloadingWOW
@ stdcall CoUnmarshalHresult(ptr ptr)
@ stdcall CoUnmarshalInterface(ptr ptr ptr)
@ stdcall CoWaitForMultipleHandles(long long long ptr ptr)
@ stdcall CreateAntiMoniker(ptr)
@ stdcall CreateBindCtx(long ptr)
@ stdcall CreateClassMoniker(ptr ptr)
@ -135,14 +136,14 @@
@ stdcall HMENU_UserMarshal(ptr ptr ptr)
@ stdcall HMENU_UserSize(ptr long ptr)
@ stdcall HMENU_UserUnmarshal(ptr ptr ptr)
@ stub HMETAFILEPICT_UserFree
@ stub HMETAFILEPICT_UserMarshal
@ stub HMETAFILEPICT_UserSize
@ stub HMETAFILEPICT_UserUnmarshal
@ stub HMETAFILE_UserFree
@ stub HMETAFILE_UserMarshal
@ stub HMETAFILE_UserSize
@ stub HMETAFILE_UserUnmarshal
@ stdcall HMETAFILEPICT_UserFree(ptr ptr)
@ stdcall HMETAFILEPICT_UserMarshal(ptr ptr ptr)
@ stdcall HMETAFILEPICT_UserSize(ptr long ptr)
@ stdcall HMETAFILEPICT_UserUnmarshal(ptr ptr ptr)
@ stdcall HMETAFILE_UserFree(ptr ptr)
@ stdcall HMETAFILE_UserMarshal(ptr ptr ptr)
@ stdcall HMETAFILE_UserSize(ptr long ptr)
@ stdcall HMETAFILE_UserUnmarshal(ptr ptr ptr)
@ stdcall HPALETTE_UserFree(ptr ptr)
@ stdcall HPALETTE_UserMarshal(ptr ptr ptr)
@ stdcall HPALETTE_UserSize(ptr long ptr)
@ -200,7 +201,7 @@
@ stdcall OleLoadFromStream(ptr ptr ptr)
@ stdcall OleLockRunning(ptr long long)
@ stdcall OleMetafilePictFromIconAndLabel(long ptr ptr long)
@ stub OleNoteObjectVisible
@ stdcall OleNoteObjectVisible(ptr long)
@ stdcall OleQueryCreateFromData(ptr)
@ stdcall OleQueryLinkFromData(ptr)
@ stdcall OleRegEnumFormatEtc(ptr long ptr)

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
@ -32,6 +32,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
#define HIMETRIC_INCHES 2540
/***********************************************************************
* OleMetafilePictFromIconAndLabel (OLE32.@)
*/
@ -40,27 +42,70 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
{
METAFILEPICT mfp;
HDC hdc;
UINT dy;
HGLOBAL hmem = NULL;
LPVOID mfdata;
static const char szIconOnly[] = "IconOnly";
SIZE text_size = { 0, 0 };
INT width;
INT icon_width;
INT icon_height;
INT label_offset;
HDC hdcScreen;
LOGFONTW lf;
HFONT font;
TRACE("%p %p %s %d\n", hIcon, lpszLabel, debugstr_w(lpszSourceFile), iIconIndex);
if( !hIcon )
return NULL;
if (!SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
return NULL;
font = CreateFontIndirectW(&lf);
if (!font)
return NULL;
hdc = CreateMetaFileW(NULL);
if( !hdc )
{
DeleteObject(font);
return NULL;
}
SelectObject(hdc, font);
ExtEscape(hdc, MFCOMMENT, sizeof(szIconOnly), szIconOnly, 0, NULL);
/* FIXME: things are drawn in the wrong place */
DrawIcon(hdc, 0, 0, hIcon);
dy = GetSystemMetrics(SM_CXICON);
icon_width = GetSystemMetrics(SM_CXICON);
icon_height = GetSystemMetrics(SM_CYICON);
/* FIXME: should we give the label a bit of padding here? */
label_offset = icon_height;
if (lpszLabel)
{
HFONT screen_old_font;
/* metafile DCs don't support GetTextExtentPoint32, so size the font
* using the desktop window DC */
hdcScreen = GetDC(NULL);
screen_old_font = SelectObject(hdcScreen, font);
GetTextExtentPoint32W(hdcScreen, lpszLabel, lstrlenW(lpszLabel), &text_size);
SelectObject(hdcScreen, screen_old_font);
ReleaseDC(NULL, hdcScreen);
width = 3 * icon_width;
}
else
width = icon_width;
SetMapMode(hdc, MM_ANISOTROPIC);
SetWindowOrgEx(hdc, 0, 0, NULL);
SetWindowExtEx(hdc, width, label_offset + text_size.cy, NULL);
/* draw the icon centred */
DrawIcon(hdc, (width-icon_width) / 2, 0, hIcon);
if(lpszLabel)
TextOutW(hdc, 0, dy, lpszLabel, lstrlenW(lpszLabel));
/* draw the label centred too, if provided */
TextOutW(hdc, (width-text_size.cx) / 2, label_offset, lpszLabel, lstrlenW(lpszLabel));
if (lpszSourceFile)
{
@ -80,9 +125,13 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
ExtEscape(hdc, MFCOMMENT, strlen(szIconIndex)+1, szIconIndex, 0, NULL);
}
mfp.mm = MM_ISOTROPIC;
mfp.xExt = mfp.yExt = 0; /* FIXME ? */
mfp.mm = MM_ANISOTROPIC;
hdcScreen = GetDC(NULL);
mfp.xExt = MulDiv(width, HIMETRIC_INCHES, GetDeviceCaps(hdcScreen, LOGPIXELSX));
mfp.yExt = MulDiv(label_offset + text_size.cy, HIMETRIC_INCHES, GetDeviceCaps(hdcScreen, LOGPIXELSY));
ReleaseDC(NULL, hdcScreen);
mfp.hMF = CloseMetaFile(hdc);
DeleteObject(font);
if( !mfp.hMF )
return NULL;

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "windef.h"

View File

@ -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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
@ -50,6 +50,156 @@ typedef struct OleAdviseHolderImpl
} OleAdviseHolderImpl;
static HRESULT EnumOleSTATDATA_Construct(OleAdviseHolderImpl *pOleAdviseHolder, ULONG index, IEnumSTATDATA **ppenum);
typedef struct
{
const IEnumSTATDATAVtbl *lpvtbl;
LONG ref;
ULONG index;
OleAdviseHolderImpl *pOleAdviseHolder;
} EnumOleSTATDATA;
static HRESULT WINAPI EnumOleSTATDATA_QueryInterface(
IEnumSTATDATA *iface, REFIID riid, void **ppv)
{
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IEnumSTATDATA))
{
IUnknown_AddRef(iface);
*ppv = iface;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI EnumOleSTATDATA_AddRef(
IEnumSTATDATA *iface)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
TRACE("()\n");
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI EnumOleSTATDATA_Release(
IEnumSTATDATA *iface)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
LONG refs = InterlockedDecrement(&This->ref);
TRACE("()\n");
if (!refs)
{
IOleAdviseHolder_Release((IOleAdviseHolder *)This->pOleAdviseHolder);
HeapFree(GetProcessHeap(), 0, This);
}
return refs;
}
static HRESULT WINAPI EnumOleSTATDATA_Next(
IEnumSTATDATA *iface, ULONG celt, LPSTATDATA rgelt,
ULONG *pceltFetched)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
HRESULT hr = S_OK;
TRACE("(%d, %p, %p)\n", celt, rgelt, pceltFetched);
if (pceltFetched)
*pceltFetched = 0;
for (; celt; celt--, rgelt++)
{
while ((This->index < This->pOleAdviseHolder->maxSinks) &&
!This->pOleAdviseHolder->arrayOfSinks[This->index])
{
This->index++;
}
if (This->index >= This->pOleAdviseHolder->maxSinks)
{
hr = S_FALSE;
break;
}
memset(&rgelt->formatetc, 0, sizeof(rgelt->formatetc));
rgelt->advf = 0;
rgelt->pAdvSink = This->pOleAdviseHolder->arrayOfSinks[This->index];
IAdviseSink_AddRef(rgelt->pAdvSink);
rgelt->dwConnection = This->index;
if (pceltFetched)
(*pceltFetched)++;
This->index++;
}
return hr;
}
static HRESULT WINAPI EnumOleSTATDATA_Skip(
IEnumSTATDATA *iface, ULONG celt)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
TRACE("(%d)\n", celt);
for (; celt; celt--)
{
while ((This->index < This->pOleAdviseHolder->maxSinks) &&
!This->pOleAdviseHolder->arrayOfSinks[This->index])
{
This->index++;
}
if (This->index >= This->pOleAdviseHolder->maxSinks)
return S_FALSE;
This->index++;
}
return S_OK;
}
static HRESULT WINAPI EnumOleSTATDATA_Reset(
IEnumSTATDATA *iface)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
TRACE("()\n");
This->index = 0;
return S_OK;
}
static HRESULT WINAPI EnumOleSTATDATA_Clone(
IEnumSTATDATA *iface,
IEnumSTATDATA **ppenum)
{
EnumOleSTATDATA *This = (EnumOleSTATDATA *)iface;
return EnumOleSTATDATA_Construct(This->pOleAdviseHolder, This->index, ppenum);
}
static const IEnumSTATDATAVtbl EnumOleSTATDATA_VTable =
{
EnumOleSTATDATA_QueryInterface,
EnumOleSTATDATA_AddRef,
EnumOleSTATDATA_Release,
EnumOleSTATDATA_Next,
EnumOleSTATDATA_Skip,
EnumOleSTATDATA_Reset,
EnumOleSTATDATA_Clone
};
static HRESULT EnumOleSTATDATA_Construct(OleAdviseHolderImpl *pOleAdviseHolder, ULONG index, IEnumSTATDATA **ppenum)
{
EnumOleSTATDATA *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (!This)
return E_OUTOFMEMORY;
This->lpvtbl = &EnumOleSTATDATA_VTable;
This->ref = 1;
This->index = index;
This->pOleAdviseHolder = pOleAdviseHolder;
IOleAdviseHolder_AddRef((IOleAdviseHolder *)pOleAdviseHolder);
*ppenum = (IEnumSTATDATA *)&This->lpvtbl;
return S_OK;
}
/**************************************************************************
* OleAdviseHolderImpl_Destructor
*/
@ -127,7 +277,7 @@ static ULONG WINAPI OleAdviseHolderImpl_AddRef(
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p)->(ref=%ld)\n", This, ref - 1);
TRACE("(%p)->(ref=%d)\n", This, ref - 1);
return ref;
}
@ -140,7 +290,7 @@ static ULONG WINAPI OleAdviseHolderImpl_Release(
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
ULONG ref;
TRACE("(%p)->(ref=%ld)\n", This, This->ref);
TRACE("(%p)->(ref=%d)\n", This, This->ref);
ref = InterlockedDecrement(&This->ref);
if (ref == 0) OleAdviseHolderImpl_Destructor(This);
@ -224,7 +374,7 @@ static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
TRACE("(%p)->(%lu)\n", This, dwConnection);
TRACE("(%p)->(%u)\n", This, dwConnection);
/*
* So we don't return 0 as a cookie, the index was
@ -258,11 +408,12 @@ static HRESULT WINAPI
OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
FIXME("(%p)->(%p)\n", This, ppenumAdvise);
TRACE("(%p)->(%p)\n", This, ppenumAdvise);
*ppenumAdvise = NULL;
return S_OK;
return EnumOleSTATDATA_Construct(This, 0, ppenumAdvise);
}
/******************************************************************************
@ -271,11 +422,25 @@ OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumA
static HRESULT WINAPI
OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
FIXME("(%p)->(%p)\n", This, pmk);
IEnumSTATDATA *pEnum;
HRESULT hr;
TRACE("(%p)->(%p)\n", iface, pmk);
return S_OK;
hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
if (SUCCEEDED(hr))
{
STATDATA statdata;
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
{
IAdviseSink_OnRename(statdata.pAdvSink, pmk);
IAdviseSink_Release(statdata.pAdvSink);
}
IEnumSTATDATA_Release(pEnum);
}
return hr;
}
/******************************************************************************
@ -284,10 +449,25 @@ OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
static HRESULT WINAPI
OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
FIXME("(%p)\n", This);
IEnumSTATDATA *pEnum;
HRESULT hr;
return S_OK;
TRACE("(%p)->()\n", iface);
hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
if (SUCCEEDED(hr))
{
STATDATA statdata;
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
{
IAdviseSink_OnSave(statdata.pAdvSink);
IAdviseSink_Release(statdata.pAdvSink);
}
IEnumSTATDATA_Release(pEnum);
}
return hr;
}
/******************************************************************************
@ -296,11 +476,25 @@ OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
static HRESULT WINAPI
OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
{
OleAdviseHolderImpl *This = (OleAdviseHolderImpl *)iface;
FIXME("(%p)\n", This);
IEnumSTATDATA *pEnum;
HRESULT hr;
TRACE("(%p)->()\n", iface);
return S_OK;
hr = IOleAdviseHolder_EnumAdvise(iface, &pEnum);
if (SUCCEEDED(hr))
{
STATDATA statdata;
while (IEnumSTATDATA_Next(pEnum, 1, &statdata, NULL) == S_OK)
{
IAdviseSink_OnClose(statdata.pAdvSink);
IAdviseSink_Release(statdata.pAdvSink);
}
IEnumSTATDATA_Release(pEnum);
}
return hr;
}
/**************************************************************************
@ -361,6 +555,7 @@ typedef struct DataAdviseHolder
LONG ref;
DWORD maxCons;
DataAdviseConnection* Connections;
IDataObject* delegate;
} DataAdviseHolder;
/* this connection has also has been advised to the delegate data object */
@ -378,6 +573,11 @@ static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy)
{
if (ptrToDestroy->Connections[index].sink != NULL)
{
if (ptrToDestroy->delegate &&
(ptrToDestroy->Connections[index].advf & WINE_ADVF_REMOTE))
IDataObject_DUnadvise(ptrToDestroy->delegate,
ptrToDestroy->Connections[index].remote_connection);
IAdviseSink_Release(ptrToDestroy->Connections[index].sink);
ptrToDestroy->Connections[index].sink = NULL;
}
@ -445,7 +645,7 @@ static ULONG WINAPI DataAdviseHolder_AddRef(
IDataAdviseHolder* iface)
{
DataAdviseHolder *This = (DataAdviseHolder *)iface;
TRACE("(%p) (ref=%ld)\n", This, This->ref);
TRACE("(%p) (ref=%d)\n", This, This->ref);
return InterlockedIncrement(&This->ref);
}
@ -459,7 +659,7 @@ static ULONG WINAPI DataAdviseHolder_Release(
{
DataAdviseHolder *This = (DataAdviseHolder *)iface;
ULONG ref;
TRACE("(%p) (ref=%ld)\n", This, This->ref);
TRACE("(%p) (ref=%d)\n", This, This->ref);
/*
* Decrease the reference count on this object.
@ -490,7 +690,7 @@ static HRESULT WINAPI DataAdviseHolder_Advise(
DataAdviseHolder *This = (DataAdviseHolder *)iface;
TRACE("(%p)->(%p, %p, %08lx, %p, %p)\n", This, pDataObject, pFetc, advf,
TRACE("(%p)->(%p, %p, %08x, %p, %p)\n", This, pDataObject, pFetc, advf,
pAdvise, pdwConnection);
/*
* Sanity check
@ -523,14 +723,42 @@ static HRESULT WINAPI DataAdviseHolder_Advise(
* Store the new sink
*/
This->Connections[index].sink = pAdvise;
memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
This->Connections[index].advf = advf & ~WINE_ADVF_REMOTE;
memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
if (pFetc->ptd)
{
This->Connections[index].fmat.ptd = CoTaskMemAlloc(pFetc->ptd->tdSize);
if (!This->Connections[index].fmat.ptd)
{
IDataAdviseHolder_Unadvise(iface, index + 1);
return E_OUTOFMEMORY;
}
memcpy(This->Connections[index].fmat.ptd, pFetc->ptd, pFetc->ptd->tdSize);
}
if (This->Connections[index].sink != NULL) {
IAdviseSink_AddRef(This->Connections[index].sink);
if(advf & ADVF_PRIMEFIRST) {
IDataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
/* if we are already connected advise the remote object */
if (This->delegate)
{
HRESULT hr;
hr = IDataObject_DAdvise(This->delegate, &This->Connections[index].fmat,
This->Connections[index].advf,
This->Connections[index].sink,
&This->Connections[index].remote_connection);
if (FAILED(hr))
{
IDataAdviseHolder_Unadvise(iface, index + 1);
return hr;
}
This->Connections[index].advf |= WINE_ADVF_REMOTE;
}
else if(advf & ADVF_PRIMEFIRST)
/* only do this if we have no delegate, since in the above case the
* delegate will do the priming for us */
IDataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
}
/*
* Return the index as the cookie.
@ -551,7 +779,7 @@ static HRESULT WINAPI DataAdviseHolder_Unadvise(
{
DataAdviseHolder *This = (DataAdviseHolder *)iface;
TRACE("(%p)->(%lu)\n", This, dwConnection);
TRACE("(%p)->(%u)\n", This, dwConnection);
/*
* So we don't return 0 as a cookie, the index was
@ -569,11 +797,16 @@ static HRESULT WINAPI DataAdviseHolder_Unadvise(
if (This->Connections[dwConnection].sink == NULL)
return OLE_E_NOCONNECTION;
if (This->delegate && This->Connections[dwConnection].advf & WINE_ADVF_REMOTE)
IDataObject_DUnadvise(This->delegate,
This->Connections[dwConnection].remote_connection);
/*
* Release the sink and mark the spot in the list as free.
*/
IAdviseSink_Release(This->Connections[dwConnection].sink);
memset(&(This->Connections[dwConnection]), 0, sizeof(DataAdviseConnection));
return S_OK;
}
@ -601,16 +834,17 @@ static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
STGMEDIUM stg;
HRESULT res;
TRACE("(%p)->(%p,%08lx,%08lx)\n", This, pDataObject, dwReserved, advf);
TRACE("(%p)->(%p,%08x,%08x)\n", This, pDataObject, dwReserved, advf);
for(index = 0; index < This->maxCons; index++) {
if(This->Connections[index].sink != NULL) {
memset(&stg, 0, sizeof(stg));
if(!(This->Connections[index].advf & ADVF_NODATA)) {
TRACE("Calling IDataObject_GetData\n");
res = IDataObject_GetData(pDataObject,
&(This->Connections[index].fmat),
&stg);
TRACE("returns %08lx\n", res);
TRACE("returns %08x\n", res);
}
TRACE("Calling IAdviseSink_OnDataChange\n");
IAdviseSink_OnDataChange(This->Connections[index].sink,
@ -658,13 +892,26 @@ HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDeleg
This->Connections[index].advf |= WINE_ADVF_REMOTE;
}
}
/* FIXME: store pDelegate somewhere */
This->delegate = pDelegate;
return hr;
}
void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface)
{
/* FIXME: Unadvise all remote interfaces */
DataAdviseHolder *This = (DataAdviseHolder *)iface;
DWORD index;
for(index = 0; index < This->maxCons; index++)
{
if((This->Connections[index].sink != NULL) &&
(This->Connections[index].advf & WINE_ADVF_REMOTE))
{
IDataObject_DUnadvise(This->delegate,
This->Connections[index].remote_connection);
This->Connections[index].advf &= ~WINE_ADVF_REMOTE;
}
}
This->delegate = NULL;
}
/******************************************************************************
@ -683,6 +930,7 @@ static IDataAdviseHolder* DataAdviseHolder_Constructor(void)
HEAP_ZERO_MEMORY,
newHolder->maxCons *
sizeof(DataAdviseConnection));
newHolder->delegate = NULL;
TRACE("returning %p\n", newHolder);
return (IDataAdviseHolder*)newHolder;

View File

@ -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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Documentation on MSDN:
@ -39,7 +39,6 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
@ -64,8 +63,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
const CLSID CLSID_DfMarshal = { 0x0000030b, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
const CLSID CLSID_PSFactoryBuffer = { 0x00000320, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
static ULONG WINAPI RURpcProxyBufferImpl_Release(LPRPCPROXYBUFFER iface);
/* From: http://msdn.microsoft.com/library/en-us/com/cmi_m_4lda.asp
*
@ -161,7 +159,7 @@ CFStub_Invoke(
ULONG res;
if (msg->cbBuffer < sizeof(IID)) {
FIXME("Not enough bytes in buffer (%ld instead of %d)?\n",msg->cbBuffer,sizeof(IID));
FIXME("Not enough bytes in buffer (%d)?\n",msg->cbBuffer);
return E_FAIL;
}
memcpy(&iid,msg->Buffer,sizeof(iid));
@ -173,51 +171,58 @@ CFStub_Invoke(
}
hres = IClassFactory_CreateInstance(classfac,NULL,&iid,(LPVOID*)&ppv);
IClassFactory_Release(classfac);
msg->cbBuffer = 0;
if (hres) {
msg->cbBuffer = 0;
FIXME("Failed to create an instance of %s\n",debugstr_guid(&iid));
return hres;
goto getbuffer;
}
hres = CreateStreamOnHGlobal(0,TRUE,&pStm);
if (hres) {
FIXME("Failed to create stream on hglobal\n");
return hres;
goto getbuffer;
}
hres = CoMarshalInterface(pStm,&iid,ppv,0,NULL,0);
IUnknown_Release((IUnknown*)ppv);
hres = IStream_Write(pStm, &ppv, sizeof(ppv), NULL);
if (hres) {
FIXME("CoMarshalInterface failed, %lx!\n",hres);
msg->cbBuffer = 0;
return hres;
ERR("IStream_Write failed, 0x%08x\n", hres);
goto getbuffer;
}
if (ppv) {
hres = CoMarshalInterface(pStm,&iid,ppv,0,NULL,0);
IUnknown_Release(ppv);
if (hres) {
FIXME("CoMarshalInterface failed, %x!\n",hres);
goto getbuffer;
}
}
hres = IStream_Stat(pStm,&ststg,0);
if (hres) {
FIXME("Stat failed.\n");
return hres;
goto getbuffer;
}
msg->cbBuffer = ststg.cbSize.u.LowPart;
I_RpcGetBuffer((RPC_MESSAGE *)msg);
getbuffer:
IRpcChannelBuffer_GetBuffer(chanbuf, msg, &IID_IClassFactory);
if (hres) return hres;
seekto.u.LowPart = 0;seekto.u.HighPart = 0;
hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
if (hres) {
FIXME("IStream_Seek failed, %lx\n",hres);
FIXME("IStream_Seek failed, %x\n",hres);
return hres;
}
hres = IStream_Read(pStm,msg->Buffer,msg->cbBuffer,&res);
if (hres) {
FIXME("Stream Read failed, %lx\n",hres);
FIXME("Stream Read failed, %x\n",hres);
return hres;
}
IStream_Release(pStm);
return S_OK;
}
FIXME("(%p,%p), stub!\n",msg,chanbuf);
FIXME("iMethod is %ld\n",msg->iMethod);
FIXME("cbBuffer is %ld\n",msg->cbBuffer);
FIXME("iMethod is %d\n",msg->iMethod);
FIXME("cbBuffer is %d\n",msg->cbBuffer);
return E_FAIL;
}
@ -346,18 +351,11 @@ static ULONG WINAPI CFProxy_AddRef(LPCLASSFACTORY iface) {
}
static ULONG WINAPI CFProxy_Release(LPCLASSFACTORY iface) {
ULONG ref;
ICOM_THIS_MULTI(CFProxy,lpvtbl_cf,iface);
if (This->outer_unknown)
ref = IUnknown_Release(This->outer_unknown);
else
ref = InterlockedDecrement(&This->ref);
if (!ref) {
if (This->chanbuf) IRpcChannelBuffer_Release(This->chanbuf);
HeapFree(GetProcessHeap(),0,This);
}
return ref;
return IUnknown_Release(This->outer_unknown);
else
return IRpcProxyBufferImpl_Release((IRpcProxyBuffer *)&This->lpvtbl_proxy);
}
static HRESULT WINAPI CFProxy_CreateInstance(
@ -384,36 +382,48 @@ static HRESULT WINAPI CFProxy_CreateInstance(
msg.Buffer = NULL;
hres = IRpcChannelBuffer_GetBuffer(This->chanbuf,&msg,&IID_IClassFactory);
if (hres) {
FIXME("IRpcChannelBuffer_GetBuffer failed with %lx?\n",hres);
FIXME("IRpcChannelBuffer_GetBuffer failed with %x?\n",hres);
return hres;
}
memcpy(msg.Buffer,riid,sizeof(*riid));
hres = IRpcChannelBuffer_SendReceive(This->chanbuf,&msg,&srstatus);
if (hres) {
FIXME("IRpcChannelBuffer_SendReceive failed with %lx?\n",hres);
FIXME("IRpcChannelBuffer_SendReceive failed with %x?\n",hres);
IRpcChannelBuffer_FreeBuffer(This->chanbuf,&msg);
return hres;
}
if (!msg.cbBuffer) /* interface not found on remote */
if (!msg.cbBuffer) { /* interface not found on remote */
IRpcChannelBuffer_FreeBuffer(This->chanbuf,&msg);
return srstatus;
}
/* We got back: [Marshalled Interface data] */
TRACE("got %ld bytes data.\n",msg.cbBuffer);
TRACE("got %d bytes data.\n",msg.cbBuffer);
hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE,msg.cbBuffer);
memcpy(GlobalLock(hGlobal),msg.Buffer,msg.cbBuffer);
hres = CreateStreamOnHGlobal(hGlobal,TRUE,&pStream);
if (hres) {
FIXME("CreateStreamOnHGlobal failed with %lx\n",hres);
FIXME("CreateStreamOnHGlobal failed with %x\n",hres);
IRpcChannelBuffer_FreeBuffer(This->chanbuf,&msg);
return hres;
}
hres = CoUnmarshalInterface(
pStream,
riid,
ppv
);
hres = IStream_Read(pStream, ppv, sizeof(*ppv), NULL);
if (hres != S_OK)
hres = E_FAIL;
else if (*ppv) {
hres = CoUnmarshalInterface(
pStream,
riid,
ppv
);
}
IStream_Release(pStream); /* Does GlobalFree hGlobal too. */
IRpcChannelBuffer_FreeBuffer(This->chanbuf,&msg);
if (hres) {
FIXME("CoMarshalInterface failed, %lx\n",hres);
FIXME("CoMarshalInterface failed, %x\n",hres);
return hres;
}
return S_OK;
@ -530,7 +540,7 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
LPBYTE buf = pMsg->Buffer;
HRESULT hr = RPC_E_INVALIDMETHOD;
TRACE("(%p)->Invoke(%p,%p) method %ld\n", This, pMsg, pChannel, iMethod);
TRACE("(%p)->Invoke(%p,%p) method %d\n", This, pMsg, pChannel, iMethod);
switch (iMethod)
{
case 3: /* RemQueryInterface */
@ -555,7 +565,7 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
/* out */
pMsg->cbBuffer = cIids * sizeof(REMQIRESULT) + sizeof(HRESULT);
I_RpcGetBuffer((RPC_MESSAGE *)pMsg);
IRpcChannelBuffer_GetBuffer(pChannel, pMsg, &IID_IRemUnknown);
buf = pMsg->Buffer;
*(HRESULT *)buf = hr;
@ -585,7 +595,7 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
/* out */
pMsg->cbBuffer = cIids * sizeof(HRESULT);
I_RpcGetBuffer((RPC_MESSAGE *)pMsg);
IRpcChannelBuffer_GetBuffer(pChannel, pMsg, &IID_IRemUnknown);
if (!hr)
{
buf = pMsg->Buffer;
@ -610,6 +620,7 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
/* out */
pMsg->cbBuffer = 0;
IRpcChannelBuffer_GetBuffer(pChannel, pMsg, &IID_IRemUnknown);
break;
}
}
@ -713,19 +724,12 @@ static ULONG WINAPI RemUnkProxy_AddRef(LPREMUNKNOWN iface)
static ULONG WINAPI RemUnkProxy_Release(LPREMUNKNOWN iface)
{
RemUnkProxy *This = (RemUnkProxy *)iface;
ULONG refs;
TRACE("(%p)->Release()\n",This);
if (This->outer_unknown)
refs = IUnknown_Release(This->outer_unknown);
else
refs = InterlockedDecrement(&This->refs);
if (!refs) {
if (This->chan) IRpcChannelBuffer_Release(This->chan);
HeapFree(GetProcessHeap(),0,This);
}
return refs;
return IUnknown_Release(This->outer_unknown);
else
return IRpcProxyBufferImpl_Release((IRpcProxyBuffer *)&This->lpvtbl_proxy);
}
static HRESULT WINAPI RemUnkProxy_RemQueryInterface(LPREMUNKNOWN iface,
@ -740,7 +744,7 @@ static HRESULT WINAPI RemUnkProxy_RemQueryInterface(LPREMUNKNOWN iface,
HRESULT hr = S_OK;
ULONG status;
TRACE("(%p)->(%s,%ld,%d,%p,%p)\n",This,
TRACE("(%p)->(%s,%d,%d,%p,%p)\n",This,
debugstr_guid(ripid),cRefs,cIids,iids,ppQIResults);
*ppQIResults = NULL;
@ -869,14 +873,14 @@ static HRESULT WINAPI RURpcProxyBufferImpl_QueryInterface(LPRPCPROXYBUFFER iface
static ULONG WINAPI RURpcProxyBufferImpl_AddRef(LPRPCPROXYBUFFER iface) {
ICOM_THIS_MULTI(RemUnkProxy,lpvtbl_proxy,iface);
TRACE("%p, %ld\n", iface, This->refs + 1);
TRACE("%p, %d\n", iface, This->refs + 1);
return InterlockedIncrement(&This->refs);
}
static ULONG WINAPI RURpcProxyBufferImpl_Release(LPRPCPROXYBUFFER iface) {
ICOM_THIS_MULTI(RemUnkProxy,lpvtbl_proxy,iface);
ULONG ref = InterlockedDecrement(&This->refs);
TRACE("%p, %ld\n", iface, ref);
TRACE("%p, %d\n", iface, ref);
if (!ref) {
IRpcProxyBuffer_Disconnect(iface);
HeapFree(GetProcessHeap(),0,This);
@ -1015,6 +1019,12 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
return FileMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ItemMoniker))
return ItemMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_AntiMoniker))
return AntiMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_CompositeMoniker))
return CompositeMonikerCF_Create(iid, ppv);
if (IsEqualCLSID(rclsid, &CLSID_ClassMoniker))
return ClassMonikerCF_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

@ -13,7 +13,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if !defined( __WINE_OLESTD_H_ )

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -30,9 +30,11 @@
#include "winerror.h"
#include "objbase.h"
#include "compobj_private.h"
#include "ole2.h"
#include "olectl.h"
#include "initguid.h"
#include "compobj_private.h"
#include "moniker.h"
#include "wine/debug.h"
@ -66,6 +68,7 @@ struct regsvr_coclass
LPCSTR ips; /* can be NULL to omit */
LPCSTR ips32; /* can be NULL to omit */
LPCSTR ips32_tmodel; /* can be NULL to omit */
LPCSTR progid; /* can be NULL to omit */
};
static HRESULT register_coclasses(struct regsvr_coclass const *list);
@ -95,6 +98,8 @@ static WCHAR const ips_keyname[13] = {
static WCHAR const ips32_keyname[15] = {
'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
'3', '2', 0 };
static WCHAR const progid_keyname[7] = {
'P', 'r', 'o', 'g', 'I', 'D', 0 };
static char const tmodel_valuename[] = "ThreadingModel";
/***********************************************************************
@ -105,7 +110,10 @@ static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
WCHAR const *value);
static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
char const *value);
static LONG register_progid(WCHAR const *clsid, char const *progid,
char const *name);
static LONG recursive_delete_key(HKEY key);
static LONG recursive_delete_keyA(HKEY base, char const *name);
/***********************************************************************
@ -137,7 +145,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
}
if (list->base_iid) {
register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
@ -159,12 +167,12 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
}
if (list->ps_clsid) {
register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
if (list->ps_clsid32) {
register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
@ -266,6 +274,15 @@ static HRESULT register_coclasses(struct regsvr_coclass const *list)
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->progid) {
res = register_key_defvalueA(clsid_key, progid_keyname,
list->progid);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = register_progid(buf, list->progid, list->name);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
error_close_clsid_key:
RegCloseKey(clsid_key);
}
@ -304,6 +321,11 @@ static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
res = recursive_delete_key(clsid_key);
RegCloseKey(clsid_key);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
if (list->progid) {
res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
}
error_close_coclass_key:
@ -363,6 +385,38 @@ static LONG register_key_defvalueA(
return res;
}
/***********************************************************************
* regsvr_progid
*/
static LONG register_progid(
WCHAR const *clsid,
char const *progid,
char const *name)
{
LONG res;
HKEY progid_key;
res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL,
&progid_key, NULL);
if (res != ERROR_SUCCESS) return res;
if (name) {
res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
(CONST BYTE*)name, strlen(name) + 1);
if (res != ERROR_SUCCESS) goto error_close_progid_key;
}
if (clsid) {
res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
if (res != ERROR_SUCCESS) goto error_close_progid_key;
}
error_close_progid_key:
RegCloseKey(progid_key);
return res;
}
/***********************************************************************
* recursive_delete_key
*/
@ -395,29 +449,50 @@ static LONG recursive_delete_key(HKEY key)
return res;
}
/***********************************************************************
* recursive_delete_keyA
*/
static LONG recursive_delete_keyA(HKEY base, char const *name)
{
LONG res;
HKEY key;
res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
if (res != ERROR_SUCCESS) return res;
res = recursive_delete_key(key);
RegCloseKey(key);
return res;
}
/***********************************************************************
* coclass list
*/
static GUID const CLSID_FileMoniker = {
0x00000303, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
static GUID const CLSID_StdOleLink = {
0x00000300, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
static GUID const CLSID_ItemMoniker = {
0x00000304, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
static GUID const CLSID_PointerMoniker = {
0x00000306, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
/* FIXME: DfMarshal and PSFactoryBuffer are defined elsewhere too */
static GUID const CLSID_PackagerMoniker = {
0x00000308, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
static GUID const CLSID_DfMarshal = {
0x0000030B, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
static GUID const CLSID_PSFactoryBuffer = {
0x00000320, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
extern GUID const CLSID_Picture_Metafile;
extern GUID const CLSID_Picture_Dib;
static struct regsvr_coclass const coclass_list[] = {
{ &CLSID_StdOleLink,
"StdOleLink",
NULL,
"ole32.dll",
NULL
},
{ &CLSID_FileMoniker,
"FileMoniker",
NULL,
"ole32.dll",
"Both"
"Both",
"file"
},
{ &CLSID_ItemMoniker,
"ItemMoniker",
@ -425,12 +500,57 @@ static struct regsvr_coclass const coclass_list[] = {
"ole32.dll",
"Both"
},
{ &CLSID_AntiMoniker,
"AntiMoniker",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_PointerMoniker,
"PointerMoniker",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_PackagerMoniker,
"PackagerMoniker",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_CompositeMoniker,
"CompositeMoniker",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_DfMarshal,
"DfMarshal",
NULL,
"ole32.dll",
"Both"
},
{ &CLSID_Picture_Metafile,
"Picture (Metafile)",
NULL,
"ole32.dll",
NULL,
"StaticMetafile"
},
{ &CLSID_Picture_Dib,
"Picture (Device Independent Bitmap)",
NULL,
"ole32.dll",
NULL,
"StaticDib"
},
{ &CLSID_ClassMoniker,
"ClassMoniker",
NULL,
"ole32.dll",
"Both",
"CLSID"
},
{ &CLSID_PSFactoryBuffer,
"PSFactoryBuffer",
NULL,
@ -451,6 +571,7 @@ static struct regsvr_coclass const coclass_list[] = {
*/
#define INTERFACE_ENTRY(interface, base, clsid32, clsid16) { &IID_##interface, #interface, base, sizeof(interface##Vtbl)/sizeof(void*), clsid16, clsid32 }
#define BAS_INTERFACE_ENTRY(interface, base) INTERFACE_ENTRY(interface, &IID_##base, &CLSID_PSFactoryBuffer, NULL)
#define STD_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, &CLSID_PSFactoryBuffer, NULL)
#define LCL_INTERFACE_ENTRY(interface) INTERFACE_ENTRY(interface, NULL, NULL, NULL)
@ -459,31 +580,65 @@ static const struct regsvr_interface interface_list[] = {
STD_INTERFACE_ENTRY(IClassFactory),
LCL_INTERFACE_ENTRY(IMalloc),
LCL_INTERFACE_ENTRY(IMarshal),
STD_INTERFACE_ENTRY(ILockBytes),
STD_INTERFACE_ENTRY(IStorage),
STD_INTERFACE_ENTRY(IStream),
STD_INTERFACE_ENTRY(IEnumSTATSTG),
STD_INTERFACE_ENTRY(IBindCtx),
BAS_INTERFACE_ENTRY(IMoniker, IPersistStream),
STD_INTERFACE_ENTRY(IRunningObjectTable),
STD_INTERFACE_ENTRY(IRootStorage),
LCL_INTERFACE_ENTRY(IMessageFilter),
LCL_INTERFACE_ENTRY(IStdMarshalInfo),
LCL_INTERFACE_ENTRY(IExternalConnection),
LCL_INTERFACE_ENTRY(IMallocSpy),
LCL_INTERFACE_ENTRY(IMultiQI),
STD_INTERFACE_ENTRY(IStream),
STD_INTERFACE_ENTRY(IPersistStorage),
STD_INTERFACE_ENTRY(IEnumUnknown),
STD_INTERFACE_ENTRY(IEnumString),
STD_INTERFACE_ENTRY(IEnumMoniker),
STD_INTERFACE_ENTRY(IEnumFORMATETC),
STD_INTERFACE_ENTRY(IEnumOLEVERB),
STD_INTERFACE_ENTRY(IEnumSTATDATA),
BAS_INTERFACE_ENTRY(IPersistStream, IPersist),
BAS_INTERFACE_ENTRY(IPersistStorage, IPersist),
BAS_INTERFACE_ENTRY(IPersistFile, IPersist),
STD_INTERFACE_ENTRY(IPersist),
STD_INTERFACE_ENTRY(IViewObject),
STD_INTERFACE_ENTRY(IDataObject),
STD_INTERFACE_ENTRY(IAdviseSink),
LCL_INTERFACE_ENTRY(IDataAdviseHolder),
LCL_INTERFACE_ENTRY(IOleAdviseHolder),
STD_INTERFACE_ENTRY(IOleObject),
BAS_INTERFACE_ENTRY(IOleInPlaceObject, IOleWindow),
STD_INTERFACE_ENTRY(IOleWindow),
BAS_INTERFACE_ENTRY(IOleInPlaceUIWindow, IOleWindow),
STD_INTERFACE_ENTRY(IOleInPlaceFrame),
BAS_INTERFACE_ENTRY(IOleInPlaceActiveObject, IOleWindow),
STD_INTERFACE_ENTRY(IOleClientSite),
BAS_INTERFACE_ENTRY(IOleInPlaceSite, IOleWindow),
STD_INTERFACE_ENTRY(IParseDisplayName),
BAS_INTERFACE_ENTRY(IOleContainer, IParseDisplayName),
BAS_INTERFACE_ENTRY(IOleItemContainer, IOleContainer),
STD_INTERFACE_ENTRY(IOleLink),
STD_INTERFACE_ENTRY(IOleCache),
LCL_INTERFACE_ENTRY(IDropSource),
STD_INTERFACE_ENTRY(IDropTarget),
BAS_INTERFACE_ENTRY(IAdviseSink2, IAdviseSink),
STD_INTERFACE_ENTRY(IRunnableObject),
BAS_INTERFACE_ENTRY(IViewObject2, IViewObject),
BAS_INTERFACE_ENTRY(IOleCache2, IOleCache),
STD_INTERFACE_ENTRY(IOleCacheControl),
STD_INTERFACE_ENTRY(IRemUnknown),
LCL_INTERFACE_ENTRY(IClientSecurity),
LCL_INTERFACE_ENTRY(IServerSecurity),
STD_INTERFACE_ENTRY(ISequentialStream),
{ NULL } /* list terminator */
};
/***********************************************************************
* DllRegisterServer (OLE32.@)
*/
HRESULT WINAPI DllRegisterServer()
HRESULT WINAPI DllRegisterServer(void)
{
HRESULT hr;
@ -498,7 +653,7 @@ HRESULT WINAPI DllRegisterServer()
/***********************************************************************
* DllUnregisterServer (OLE32.@)
*/
HRESULT WINAPI DllUnregisterServer()
HRESULT WINAPI DllUnregisterServer(void)
{
HRESULT hr;

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
@ -91,6 +91,7 @@ struct MappedPage
MappedPage *prev;
DWORD page_index;
DWORD mapped_bytes;
LPVOID lpBytes;
LONG refcnt;
@ -108,16 +109,12 @@ static void BIGBLOCKFILE_ReleaseMappedPage(LPBIGBLOCKFILE This,
static void BIGBLOCKFILE_FreeAllMappedPages(LPBIGBLOCKFILE This);
static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This);
static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This);
static void* BIGBLOCKFILE_GetBigBlockPointer(LPBIGBLOCKFILE This,
ULONG index,
DWORD desired_access);
static MappedPage* BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This,
void* pBlock);
static MappedPage* BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
ULONG page_index);
static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags);
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile);
static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt);
static void BIGBLOCKFILE_DeleteList(LPBIGBLOCKFILE This, MappedPage *list);
/* Note that this evaluates a and b multiple times, so don't
* pass expressions with side effects. */
@ -248,7 +245,7 @@ static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
This->maplist = NULL;
TRACE("file len %lu\n", This->filesize.u.LowPart);
TRACE("file len %u\n", This->filesize.u.LowPart);
return TRUE;
}
@ -285,7 +282,7 @@ static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
This->pbytearray = GlobalLock(This->hbytearray);
TRACE("mem on %p len %lu\n", This->pbytearray, This->filesize.u.LowPart);
TRACE("mem on %p len %u\n", This->pbytearray, This->filesize.u.LowPart);
return TRUE;
}
@ -317,46 +314,11 @@ void BIGBLOCKFILE_Destructor(
}
/******************************************************************************
* BIGBLOCKFILE_GetROBigBlock
* BIGBLOCKFILE_EnsureExists
*
* Returns the specified block in read only mode.
* Will return NULL if the block doesn't exists.
* Grows the file if necessary to make sure the block is valid.
*/
void* BIGBLOCKFILE_GetROBigBlock(
LPBIGBLOCKFILE This,
ULONG index)
{
/*
* block index starts at -1
* translate to zero based index
*/
if (index == 0xffffffff)
index = 0;
else
index++;
/*
* validate the block index
*
*/
if (This->blocksize * (index + 1)
> ROUND_UP(This->filesize.u.LowPart, This->blocksize))
{
TRACE("out of range %lu vs %lu\n", This->blocksize * (index + 1),
This->filesize.u.LowPart);
return NULL;
}
return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_READ);
}
/******************************************************************************
* BIGBLOCKFILE_GetBigBlock
*
* Returns the specified block.
* Will grow the file if necessary.
*/
void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index)
void BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index)
{
/*
* block index starts at -1
@ -379,28 +341,6 @@ void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index)
BIGBLOCKFILE_SetSize(This, newSize);
}
return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_WRITE);
}
/******************************************************************************
* BIGBLOCKFILE_ReleaseBigBlock
*
* Releases the specified block.
*/
void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
{
MappedPage *page;
if (pBlock == NULL)
return;
page = BIGBLOCKFILE_GetPageFromPointer(This, pBlock);
if (page == NULL)
return;
BIGBLOCKFILE_ReleaseMappedPage(This, page);
}
/******************************************************************************
@ -414,57 +354,40 @@ void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
if (This->filesize.u.LowPart == newSize.u.LowPart)
return;
TRACE("from %lu to %lu\n", This->filesize.u.LowPart, newSize.u.LowPart);
TRACE("from %u to %u\n", This->filesize.u.LowPart, newSize.u.LowPart);
/*
* unmap all views, must be done before call to SetEndFile
*
* Just ditch the victim list because there is no guarentee we will need them
* and it is not worth the performance hit to unmap and remap them all.
*/
BIGBLOCKFILE_DeleteList(This, This->victimhead);
This->victimhead = NULL;
This->victimtail = NULL;
This->num_victim_pages = 0;
BIGBLOCKFILE_UnmapAllMappedPages(This);
if (This->fileBased)
{
char buf[10];
DWORD w;
LARGE_INTEGER newpos;
/*
* close file-mapping object, must be done before call to SetEndFile
*/
if( This->hfilemap )
CloseHandle(This->hfilemap);
This->hfilemap = 0;
newpos.QuadPart = newSize.QuadPart;
if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN))
{
if( This->hfilemap ) CloseHandle(This->hfilemap);
/*
* BEGIN HACK
* This fixes a bug when saving through smbfs.
* smbmount a Windows shared directory, save a structured storage file
* to that dir: crash.
*
* The problem is that the SetFilePointer-SetEndOfFile combo below
* doesn't always succeed. The file is not grown. It seems like the
* operation is cached. By doing the WriteFile, the file is actually
* grown on disk.
* This hack is only needed when saving to smbfs.
*/
memset(buf, '0', 10);
SetFilePointer(This->hfile, newSize.u.LowPart, NULL, FILE_BEGIN);
WriteFile(This->hfile, buf, 10, &w, NULL);
/*
* END HACK
*/
SetEndOfFile(This->hfile);
/*
* set the new end of file
*/
SetFilePointer(This->hfile, newSize.u.LowPart, NULL, FILE_BEGIN);
SetEndOfFile(This->hfile);
/*
* re-create the file mapping object
*/
This->hfilemap = CreateFileMappingA(This->hfile,
NULL,
This->flProtect,
0, 0,
NULL);
/*
* re-create the file mapping object
*/
This->hfilemap = CreateFileMappingA(This->hfile,
NULL,
This->flProtect,
0, 0,
NULL);
}
}
else
{
@ -499,85 +422,6 @@ ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This)
return This->filesize;
}
/******************************************************************************
* BIGBLOCKFILE_AccessCheck [PRIVATE]
*
* block_index is the index within the page.
*/
static BOOL BIGBLOCKFILE_AccessCheck(MappedPage *page, ULONG block_index,
DWORD desired_access)
{
assert(block_index < BLOCKS_PER_PAGE);
if (desired_access == FILE_MAP_READ)
{
if (BIGBLOCKFILE_TestBit(&page->writable_blocks, block_index))
return FALSE;
BIGBLOCKFILE_SetBit(&page->readable_blocks, block_index);
}
else
{
assert(desired_access == FILE_MAP_WRITE);
if (BIGBLOCKFILE_TestBit(&page->readable_blocks, block_index))
return FALSE;
BIGBLOCKFILE_SetBit(&page->writable_blocks, block_index);
}
return TRUE;
}
/******************************************************************************
* BIGBLOCKFILE_GetBigBlockPointer [PRIVATE]
*
* Returns a pointer to the specified block.
*/
static void* BIGBLOCKFILE_GetBigBlockPointer(
LPBIGBLOCKFILE This,
ULONG block_index,
DWORD desired_access)
{
DWORD page_index = block_index / BLOCKS_PER_PAGE;
DWORD block_on_page = block_index % BLOCKS_PER_PAGE;
MappedPage *page = BIGBLOCKFILE_GetMappedView(This, page_index);
if (!page || !page->lpBytes) return NULL;
if (!BIGBLOCKFILE_AccessCheck(page, block_on_page, desired_access))
{
BIGBLOCKFILE_ReleaseMappedPage(This, page);
return NULL;
}
return (LPBYTE)page->lpBytes + (block_on_page * This->blocksize);
}
/******************************************************************************
* BIGBLOCKFILE_GetMappedPageFromPointer [PRIVATE]
*
* pBlock is a pointer to a block on a page.
* The page has to be on the in-use list. (As oppsed to the victim list.)
*
* Does not increment the usage count.
*/
static MappedPage *BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This,
void *pBlock)
{
MappedPage *page;
for (page = This->maplist; page != NULL; page = page->next)
{
if ((LPBYTE)pBlock >= (LPBYTE)page->lpBytes
&& (LPBYTE)pBlock <= (LPBYTE)page->lpBytes + PAGE_SIZE)
break;
}
return page;
}
/******************************************************************************
* BIGBLOCKFILE_FindPageInList [PRIVATE]
*
@ -686,13 +530,15 @@ static BOOL BIGBLOCKFILE_MapPage(LPBIGBLOCKFILE This, MappedPage *page)
page->lpBytes = MapViewOfFile(This->hfilemap, desired_access, 0,
lowoffset, numBytesToMap);
page->mapped_bytes = numBytesToMap;
}
else
{
page->lpBytes = (LPBYTE)This->pbytearray + lowoffset;
page->mapped_bytes = PAGE_SIZE;
}
TRACE("mapped page %lu to %p\n", page->page_index, page->lpBytes);
TRACE("mapped page %u to %p\n", page->page_index, page->lpBytes);
return page->lpBytes != NULL;
}
@ -712,7 +558,11 @@ static MappedPage *BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
page->next = NULL;
page->prev = NULL;
BIGBLOCKFILE_MapPage(This, page);
if (!BIGBLOCKFILE_MapPage(This, page))
{
HeapFree(GetProcessHeap(),0,page);
return NULL;
}
BIGBLOCKFILE_Zero(&page->readable_blocks);
BIGBLOCKFILE_Zero(&page->writable_blocks);
@ -722,7 +572,7 @@ static MappedPage *BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
static void BIGBLOCKFILE_UnmapPage(LPBIGBLOCKFILE This, MappedPage *page)
{
TRACE("%ld at %p\n", page->page_index, page->lpBytes);
TRACE("%d at %p\n", page->page_index, page->lpBytes);
if (page->refcnt > 0)
ERR("unmapping inuse page %p\n", page->lpBytes);
@ -836,7 +686,7 @@ static void BIGBLOCKFILE_RemapList(LPBIGBLOCKFILE This, MappedPage *list)
if (list->page_index * PAGE_SIZE > This->filesize.u.LowPart)
{
TRACE("discarding %lu\n", list->page_index);
TRACE("discarding %u\n", list->page_index);
/* page is entirely outside of the file, delete it */
BIGBLOCKFILE_UnlinkPage(list);
@ -874,3 +724,206 @@ static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)
}
return PAGE_READONLY;
}
/* ILockByte Interfaces */
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* It reads a block of information from the byte array at the specified
* offset.
*
* See the documentation of ILockBytes for more info.
*/
static HRESULT WINAPI ImplBIGBLOCKFILE_ReadAt(
BigBlockFile* const This,
ULARGE_INTEGER ulOffset, /* [in] */
void* pv, /* [length_is][size_is][out] */
ULONG cb, /* [in] */
ULONG* pcbRead) /* [out] */
{
ULONG first_page = ulOffset.u.LowPart / PAGE_SIZE;
ULONG offset_in_page = ulOffset.u.LowPart % PAGE_SIZE;
ULONG bytes_left = cb;
ULONG page_index = first_page;
ULONG bytes_from_page;
LPVOID writePtr = pv;
HRESULT rc = S_OK;
TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbRead);
/* verify a sane environment */
if (!This) return E_FAIL;
if (offset_in_page + bytes_left > PAGE_SIZE)
bytes_from_page = PAGE_SIZE - offset_in_page;
else
bytes_from_page = bytes_left;
if (pcbRead)
*pcbRead = 0;
while (bytes_left)
{
LPBYTE readPtr;
BOOL eof = FALSE;
MappedPage *page = BIGBLOCKFILE_GetMappedView(This, page_index);
if (!page || !page->lpBytes)
{
rc = STG_E_READFAULT;
break;
}
TRACE("page %i, offset %u, bytes_from_page %u, bytes_left %u\n",
page->page_index, offset_in_page, bytes_from_page, bytes_left);
if (page->mapped_bytes < bytes_from_page)
{
eof = TRUE;
bytes_from_page = page->mapped_bytes;
}
readPtr = (BYTE*)page->lpBytes + offset_in_page;
memcpy(writePtr,readPtr,bytes_from_page);
BIGBLOCKFILE_ReleaseMappedPage(This, page);
if (pcbRead)
*pcbRead += bytes_from_page;
bytes_left -= bytes_from_page;
if (bytes_left && !eof)
{
writePtr = (LPBYTE)writePtr + bytes_from_page;
page_index ++;
offset_in_page = 0;
if (bytes_left > PAGE_SIZE)
bytes_from_page = PAGE_SIZE;
else
bytes_from_page = bytes_left;
}
if (eof)
{
rc = STG_E_READFAULT;
break;
}
}
TRACE("finished\n");
return rc;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
* It writes the specified bytes at the specified offset.
* position. If the file is too small, it will be resized.
*
* See the documentation of ILockBytes for more info.
*/
static HRESULT WINAPI ImplBIGBLOCKFILE_WriteAt(
BigBlockFile* const This,
ULARGE_INTEGER ulOffset, /* [in] */
const void* pv, /* [size_is][in] */
ULONG cb, /* [in] */
ULONG* pcbWritten) /* [out] */
{
ULONG size_needed = ulOffset.u.LowPart + cb;
ULONG first_page = ulOffset.u.LowPart / PAGE_SIZE;
ULONG offset_in_page = ulOffset.u.LowPart % PAGE_SIZE;
ULONG bytes_left = cb;
ULONG page_index = first_page;
ULONG bytes_to_page;
LPCVOID readPtr = pv;
HRESULT rc = S_OK;
TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbWritten);
/* verify a sane environment */
if (!This) return E_FAIL;
if (This->flProtect != PAGE_READWRITE)
return STG_E_ACCESSDENIED;
if (size_needed > This->filesize.u.LowPart)
{
ULARGE_INTEGER newSize;
newSize.u.HighPart = 0;
newSize.u.LowPart = size_needed;
BIGBLOCKFILE_SetSize(This, newSize);
}
if (offset_in_page + bytes_left > PAGE_SIZE)
bytes_to_page = PAGE_SIZE - offset_in_page;
else
bytes_to_page = bytes_left;
if (pcbWritten)
*pcbWritten = 0;
while (bytes_left)
{
LPBYTE writePtr;
MappedPage *page = BIGBLOCKFILE_GetMappedView(This, page_index);
TRACE("page %i, offset %u, bytes_to_page %u, bytes_left %u\n",
page ? page->page_index : 0, offset_in_page, bytes_to_page, bytes_left);
if (!page)
{
ERR("Unable to get a page to write. This should never happen\n");
rc = E_FAIL;
break;
}
if (page->mapped_bytes < bytes_to_page)
{
ERR("Not enough bytes mapped to the page. This should never happen\n");
rc = E_FAIL;
break;
}
writePtr = (BYTE*)page->lpBytes + offset_in_page;
memcpy(writePtr,readPtr,bytes_to_page);
BIGBLOCKFILE_ReleaseMappedPage(This, page);
if (pcbWritten)
*pcbWritten += bytes_to_page;
bytes_left -= bytes_to_page;
if (bytes_left)
{
readPtr = (LPBYTE)readPtr + bytes_to_page;
page_index ++;
offset_in_page = 0;
if (bytes_left > PAGE_SIZE)
bytes_to_page = PAGE_SIZE;
else
bytes_to_page = bytes_left;
}
}
return rc;
}
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, ULONG size, ULONG* bytesRead)
{
if (This->fileBased)
return ImplBIGBLOCKFILE_ReadAt(This,offset,buffer,size,bytesRead);
else
return ILockBytes_ReadAt(This->pLkbyt,offset,buffer,size,bytesRead);
}
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, const ULONG size, ULONG* bytesRead)
{
if (This->fileBased)
return ImplBIGBLOCKFILE_WriteAt(This,offset,buffer,size,bytesRead);
else
return ILockBytes_WriteAt(This->pLkbyt,offset,buffer,size,bytesRead);
}

View File

@ -23,7 +23,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* There's a decent overview of property set storage here:
* http://msdn.microsoft.com/archive/en-us/dnarolegen/html/msdn_propset.asp
@ -39,7 +39,6 @@
* - Not all PROPVARIANT types are supported.
* - User defined properties are not supported, see comment in
* PropertyStorage_ReadFromStream
* - IPropertyStorage::Enum is unimplemented
*/
#include <assert.h>
@ -60,6 +59,7 @@
#include "wine/debug.h"
#include "dictionary.h"
#include "storage32.h"
#include "enumx.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage);
@ -82,6 +82,11 @@ static inline StorageImpl *impl_from_IPropertySetStorage( IPropertySetStorage *i
#define MAX_VERSION_0_PROP_NAME_LENGTH 256
#define CFTAG_WINDOWS (-1L)
#define CFTAG_MACINTOSH (-2L)
#define CFTAG_FMTID (-3L)
#define CFTAG_NODATA 0L
/* The format version (and what it implies) is described here:
* http://msdn.microsoft.com/library/en-us/stg/stg/format_version.asp
*/
@ -112,25 +117,23 @@ typedef struct tagPROPERTYIDOFFSET
DWORD dwOffset; /* from beginning of section */
} PROPERTYIDOFFSET;
struct tagPropertyStorage_impl;
typedef struct tagPropertyStorage_impl PropertyStorage_impl;
/* Initializes the property storage from the stream (and undoes any uncommitted
* changes in the process.) Returns an error if there is an error reading or
* if the stream format doesn't match what's expected.
*/
static HRESULT PropertyStorage_ReadFromStream(struct tagPropertyStorage_impl *);
static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *);
static HRESULT PropertyStorage_WriteToStream(struct tagPropertyStorage_impl *);
static HRESULT PropertyStorage_WriteToStream(PropertyStorage_impl *);
/* Creates the dictionaries used by the property storage. If successful, all
* the dictionaries have been created. If failed, none has been. (This makes
* it a bit easier to deal with destroying them.)
*/
static HRESULT PropertyStorage_CreateDictionaries(
struct tagPropertyStorage_impl *);
static HRESULT PropertyStorage_CreateDictionaries(PropertyStorage_impl *);
static void PropertyStorage_DestroyDictionaries(
struct tagPropertyStorage_impl *);
static void PropertyStorage_DestroyDictionaries(PropertyStorage_impl *);
/* Copies from propvar to prop. If propvar's type is VT_LPSTR, copies the
* string using PropertyStorage_StringCopy.
@ -149,11 +152,15 @@ static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
LCID targetCP);
static const IPropertyStorageVtbl IPropertyStorage_Vtbl;
static const IEnumSTATPROPSETSTGVtbl IEnumSTATPROPSETSTG_Vtbl;
static const IEnumSTATPROPSTGVtbl IEnumSTATPROPSTG_Vtbl;
static HRESULT create_EnumSTATPROPSETSTG(StorageImpl *, IEnumSTATPROPSETSTG**);
static HRESULT create_EnumSTATPROPSTG(PropertyStorage_impl *, IEnumSTATPROPSTG**);
/***********************************************************************
* Implementation of IPropertyStorage
*/
typedef struct tagPropertyStorage_impl
struct tagPropertyStorage_impl
{
const IPropertyStorageVtbl *vtbl;
LONG ref;
@ -172,7 +179,7 @@ typedef struct tagPropertyStorage_impl
struct dictionary *name_to_propid;
struct dictionary *propid_to_name;
struct dictionary *propid_to_prop;
} PropertyStorage_impl;
};
/************************************************************************
* IPropertyStorage_fnQueryInterface (IPropertyStorage)
@ -226,6 +233,7 @@ static ULONG WINAPI IPropertyStorage_fnRelease(
if (This->dirty)
IPropertyStorage_Commit(iface, STGC_DEFAULT);
IStream_Release(This->stm);
This->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->cs);
PropertyStorage_DestroyDictionaries(This);
HeapFree(GetProcessHeap(), 0, This);
@ -238,7 +246,6 @@ static PROPVARIANT *PropertyStorage_FindProperty(PropertyStorage_impl *This,
{
PROPVARIANT *ret = NULL;
assert(This);
dictionary_find(This->propid_to_prop, (void *)propid, (void **)&ret);
TRACE("returning %p\n", ret);
return ret;
@ -251,7 +258,6 @@ static PROPVARIANT *PropertyStorage_FindPropertyByName(
PROPVARIANT *ret = NULL;
PROPID propid;
assert(This);
if (!name)
return NULL;
if (This->codePage == CP_UNICODE)
@ -282,7 +288,6 @@ static LPWSTR PropertyStorage_FindPropertyNameById(PropertyStorage_impl *This,
{
LPWSTR ret = NULL;
assert(This);
dictionary_find(This->propid_to_name, (void *)propid, (void **)&ret);
TRACE("returning %p\n", ret);
return ret;
@ -298,13 +303,14 @@ static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
PROPVARIANT rgpropvar[])
{
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
HRESULT hr = S_FALSE;
HRESULT hr = S_OK;
ULONG i;
TRACE("(%p, %ld, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
if (!This)
return E_INVALIDARG;
if (cpspec && (!rgpspec || !rgpropvar))
TRACE("(%p, %d, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
if (!cpspec)
return S_FALSE;
if (!rgpspec || !rgpropvar)
return E_INVALIDARG;
EnterCriticalSection(&This->cs);
for (i = 0; i < cpspec; i++)
@ -339,6 +345,8 @@ static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
if (prop)
PropertyStorage_PropVariantCopy(&rgpropvar[i], prop,
GetACP(), This->codePage);
else
hr = S_FALSE;
}
}
}
@ -353,7 +361,7 @@ static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
HRESULT hr = S_OK;
int len;
TRACE("%s, %p, %ld, %ld\n",
TRACE("%s, %p, %d, %d\n",
srcCP == CP_UNICODE ? debugstr_w((LPCWSTR)src) : debugstr_a(src), dst,
dstCP, srcCP);
assert(src);
@ -386,16 +394,20 @@ static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
}
else
{
LPWSTR wideStr;
LPCWSTR wideStr = NULL;
LPWSTR wideStr_tmp = NULL;
if (srcCP == CP_UNICODE)
wideStr = (LPWSTR)src;
wideStr = (LPCWSTR)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);
wideStr_tmp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (wideStr_tmp)
{
MultiByteToWideChar(srcCP, 0, src, -1, wideStr_tmp, len);
wideStr = wideStr_tmp;
}
else
hr = STG_E_INSUFFICIENTMEMORY;
}
@ -419,11 +431,10 @@ static HRESULT PropertyStorage_StringCopy(LPCSTR src, LCID srcCP, LPSTR *dst,
}
}
}
if (wideStr != (LPWSTR)src)
HeapFree(GetProcessHeap(), 0, wideStr);
HeapFree(GetProcessHeap(), 0, wideStr_tmp);
}
}
TRACE("returning 0x%08lx (%s)\n", hr,
TRACE("returning 0x%08x (%s)\n", hr,
dstCP == CP_UNICODE ? debugstr_w((LPCWSTR)*dst) : debugstr_a(*dst));
return hr;
}
@ -460,7 +471,6 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
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;
@ -473,7 +483,7 @@ static HRESULT PropertyStorage_StorePropWithId(PropertyStorage_impl *This,
case VT_VECTOR|VT_I1:
This->format = 1;
}
TRACE("Setting 0x%08lx to type %d\n", propid, propvar->vt);
TRACE("Setting 0x%08x to type %d\n", propid, propvar->vt);
if (prop)
{
PropVariantClear(prop);
@ -531,7 +541,7 @@ static HRESULT PropertyStorage_StoreNameWithId(PropertyStorage_impl *This,
if (strlen(name) >= MAX_VERSION_0_PROP_NAME_LENGTH)
This->format = 1;
}
TRACE("Adding prop name %s, propid %ld\n",
TRACE("Adding prop name %s, propid %d\n",
This->codePage == CP_UNICODE ? debugstr_w((LPCWSTR)name) :
debugstr_a(name), id);
dictionary_insert(This->name_to_propid, name, (void *)id);
@ -554,9 +564,8 @@ static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
HRESULT hr = S_OK;
ULONG i;
TRACE("(%p, %ld, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p, %p)\n", iface, cpspec, rgpspec, rgpropvar);
if (cpspec && (!rgpspec || !rgpropvar))
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
@ -654,9 +663,8 @@ static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(
ULONG i;
HRESULT hr;
TRACE("(%p, %ld, %p)\n", iface, cpspec, rgpspec);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p)\n", iface, cpspec, rgpspec);
if (cpspec && !rgpspec)
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
@ -703,9 +711,8 @@ static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(
ULONG i;
HRESULT hr = S_FALSE;
TRACE("(%p, %ld, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
if (cpropid && (!rgpropid || !rglpwstrName))
return E_INVALIDARG;
EnterCriticalSection(&This->cs);
@ -744,9 +751,8 @@ static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
ULONG i;
HRESULT hr;
TRACE("(%p, %ld, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p, %p)\n", iface, cpropid, rgpropid, rglpwstrName);
if (cpropid && (!rgpropid || !rglpwstrName))
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
@ -778,9 +784,8 @@ static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(
ULONG i;
HRESULT hr;
TRACE("(%p, %ld, %p)\n", iface, cpropid, rgpropid);
if (!This)
return E_INVALIDARG;
TRACE("(%p, %d, %p)\n", iface, cpropid, rgpropid);
if (cpropid && !rgpropid)
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
@ -815,9 +820,8 @@ static HRESULT WINAPI IPropertyStorage_fnCommit(
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
HRESULT hr;
TRACE("(%p, 0x%08lx)\n", iface, grfCommitFlags);
if (!This)
return E_INVALIDARG;
TRACE("(%p, 0x%08x)\n", iface, grfCommitFlags);
if (!(This->grfMode & STGM_READWRITE))
return STG_E_ACCESSDENIED;
EnterCriticalSection(&This->cs);
@ -839,8 +843,6 @@ static HRESULT WINAPI IPropertyStorage_fnRevert(
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
TRACE("%p\n", iface);
if (!This)
return E_INVALIDARG;
EnterCriticalSection(&This->cs);
if (This->dirty)
@ -863,8 +865,8 @@ static HRESULT WINAPI IPropertyStorage_fnEnum(
IPropertyStorage* iface,
IEnumSTATPROPSTG** ppenum)
{
FIXME("\n");
return E_NOTIMPL;
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
return create_EnumSTATPROPSTG(This, ppenum);
}
/************************************************************************
@ -890,7 +892,8 @@ static HRESULT WINAPI IPropertyStorage_fnSetClass(
PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
TRACE("%p, %s\n", iface, debugstr_guid(clsid));
if (!This || !clsid)
if (!clsid)
return E_INVALIDARG;
if (!(This->grfMode & STGM_READWRITE))
return STG_E_ACCESSDENIED;
@ -913,7 +916,8 @@ static HRESULT WINAPI IPropertyStorage_fnStat(
HRESULT hr;
TRACE("%p, %p\n", iface, statpsstg);
if (!This || !statpsstg)
if (!statpsstg)
return E_INVALIDARG;
hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
@ -961,7 +965,7 @@ static void PropertyStorage_PropNameDestroy(void *k, void *d, void *extra)
static int PropertyStorage_PropCompare(const void *a, const void *b,
void *extra)
{
TRACE("(%ld, %ld)\n", (PROPID)a, (PROPID)b);
TRACE("(%d, %d)\n", (PROPID)a, (PROPID)b);
return (PROPID)a - (PROPID)b;
}
@ -1000,12 +1004,11 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
DWORD numEntries, i;
HRESULT hr = S_OK;
assert(This);
assert(This->name_to_propid);
assert(This->propid_to_name);
StorageUtl_ReadDWord(ptr, 0, &numEntries);
TRACE("Reading %ld entries:\n", numEntries);
TRACE("Reading %d entries:\n", numEntries);
ptr += sizeof(DWORD);
for (i = 0; SUCCEEDED(hr) && i < numEntries; i++)
{
@ -1016,7 +1019,7 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
ptr += sizeof(PROPID);
StorageUtl_ReadDWord(ptr, 0, &cbEntry);
ptr += sizeof(DWORD);
TRACE("Reading entry with ID 0x%08lx, %ld bytes\n", propid, cbEntry);
TRACE("Reading entry with ID 0x%08x, %d bytes\n", propid, cbEntry);
/* Make sure the source string is NULL-terminated */
if (This->codePage != CP_UNICODE)
ptr[cbEntry - 1] = '\0';
@ -1075,7 +1078,7 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
case VT_UINT:
case VT_UI4:
StorageUtl_ReadDWord(data, 0, &prop->u.ulVal);
TRACE("Read ulong %ld\n", prop->u.ulVal);
TRACE("Read ulong %d\n", prop->u.ulVal);
break;
case VT_LPSTR:
{
@ -1138,6 +1141,25 @@ static HRESULT PropertyStorage_ReadProperty(PropertyStorage_impl *This,
StorageUtl_ReadULargeInteger(data, 0,
(ULARGE_INTEGER *)&prop->u.filetime);
break;
case VT_CF:
{
DWORD len = 0, tag = 0;
StorageUtl_ReadDWord(data, 0, &len);
StorageUtl_ReadDWord(data, 4, &tag);
if (len > 8)
{
len -= 8;
prop->u.pclipdata = CoTaskMemAlloc(sizeof (CLIPDATA));
prop->u.pclipdata->cbSize = len;
prop->u.pclipdata->ulClipFmt = tag;
prop->u.pclipdata->pClipData = CoTaskMemAlloc(len);
memcpy(prop->u.pclipdata->pClipData, data+8, len);
}
else
hr = STG_E_INVALIDPARAMETER;
}
break;
default:
FIXME("unsupported type %d\n", prop->vt);
hr = STG_E_INVALIDPARAMETER;
@ -1159,7 +1181,7 @@ static HRESULT PropertyStorage_ReadHeaderFromStream(IStream *stm,
{
if (count != sizeof(buf))
{
WARN("read %ld, expected %d\n", count, sizeof(buf));
WARN("read only %d\n", count);
hr = STG_E_INVALIDHEADER;
}
else
@ -1176,7 +1198,7 @@ static HRESULT PropertyStorage_ReadHeaderFromStream(IStream *stm,
&hdr->reserved);
}
}
TRACE("returning 0x%08lx\n", hr);
TRACE("returning 0x%08x\n", hr);
return hr;
}
@ -1194,7 +1216,7 @@ static HRESULT PropertyStorage_ReadFmtIdOffsetFromStream(IStream *stm,
{
if (count != sizeof(buf))
{
WARN("read %ld, expected %d\n", count, sizeof(buf));
WARN("read only %d\n", count);
hr = STG_E_INVALIDHEADER;
}
else
@ -1205,7 +1227,7 @@ static HRESULT PropertyStorage_ReadFmtIdOffsetFromStream(IStream *stm,
&fmt->dwOffset);
}
}
TRACE("returning 0x%08lx\n", hr);
TRACE("returning 0x%08x\n", hr);
return hr;
}
@ -1223,7 +1245,7 @@ static HRESULT PropertyStorage_ReadSectionHeaderFromStream(IStream *stm,
{
if (count != sizeof(buf))
{
WARN("read %ld, expected %d\n", count, sizeof(buf));
WARN("read only %d\n", count);
hr = STG_E_INVALIDHEADER;
}
else
@ -1234,7 +1256,7 @@ static HRESULT PropertyStorage_ReadSectionHeaderFromStream(IStream *stm,
cProperties), &hdr->cProperties);
}
}
TRACE("returning 0x%08lx\n", hr);
TRACE("returning 0x%08x\n", hr);
return hr;
}
@ -1251,7 +1273,6 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
ULONG count = 0;
DWORD dictOffset = 0;
assert(This);
This->dirty = FALSE;
This->highestProp = 0;
hr = IStream_Stat(This->stm, &stat, STATFLAG_NONAME);
@ -1307,7 +1328,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
goto end;
if (fmtOffset.dwOffset > stat.cbSize.u.LowPart)
{
WARN("invalid offset %ld (stream length is %ld)\n", fmtOffset.dwOffset,
WARN("invalid offset %d (stream length is %d)\n", fmtOffset.dwOffset,
stat.cbSize.u.LowPart);
hr = STG_E_INVALIDHEADER;
goto end;
@ -1325,8 +1346,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
/* The section size includes the section header, so check it */
if (sectionHdr.cbSection < sizeof(PROPERTYSECTIONHEADER))
{
WARN("section header too small, got %ld, expected at least %d\n",
sectionHdr.cbSection, sizeof(PROPERTYSECTIONHEADER));
WARN("section header too small, got %d\n", sectionHdr.cbSection);
hr = STG_E_INVALIDHEADER;
goto end;
}
@ -1341,7 +1361,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
sizeof(PROPERTYSECTIONHEADER), &count);
if (FAILED(hr))
goto end;
TRACE("Reading %ld properties:\n", sectionHdr.cProperties);
TRACE("Reading %d properties:\n", sectionHdr.cProperties);
for (i = 0; SUCCEEDED(hr) && i < sectionHdr.cProperties; i++)
{
PROPERTYIDOFFSET *idOffset = (PROPERTYIDOFFSET *)(buf +
@ -1363,16 +1383,17 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
* later.
*/
dictOffset = idOffset->dwOffset;
TRACE("Dictionary offset is %ld\n", dictOffset);
TRACE("Dictionary offset is %d\n", dictOffset);
}
else
{
PROPVARIANT prop;
PropVariantInit(&prop);
if (SUCCEEDED(PropertyStorage_ReadProperty(This, &prop,
buf + idOffset->dwOffset - sizeof(PROPERTYSECTIONHEADER))))
{
TRACE("Read property with ID 0x%08lx, type %d\n",
TRACE("Read property with ID 0x%08x, type %d\n",
idOffset->propid, prop.vt);
switch(idOffset->propid)
{
@ -1410,7 +1431,7 @@ static HRESULT PropertyStorage_ReadFromStream(PropertyStorage_impl *This)
}
if (!This->locale)
This->locale = LOCALE_SYSTEM_DEFAULT;
TRACE("Code page is %d, locale is %ld\n", This->codePage, This->locale);
TRACE("Code page is %d, locale is %d\n", This->codePage, This->locale);
if (dictOffset)
hr = PropertyStorage_ReadDictionary(This,
buf + dictOffset - sizeof(PROPERTYSECTIONHEADER));
@ -1432,7 +1453,6 @@ end:
static void PropertyStorage_MakeHeader(PropertyStorage_impl *This,
PROPERTYSETHEADER *hdr)
{
assert(This);
assert(hdr);
StorageUtl_WriteWord((BYTE *)&hdr->wByteOrder, 0,
PROPSETHDR_BYTEORDER_MAGIC);
@ -1445,7 +1465,6 @@ static void PropertyStorage_MakeHeader(PropertyStorage_impl *This,
static void PropertyStorage_MakeFmtIdOffset(PropertyStorage_impl *This,
FORMATIDOFFSET *fmtOffset)
{
assert(This);
assert(fmtOffset);
StorageUtl_WriteGUID((BYTE *)fmtOffset, 0, &This->fmtid);
StorageUtl_WriteDWord((BYTE *)fmtOffset, offsetof(FORMATIDOFFSET, dwOffset),
@ -1485,7 +1504,6 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
ULONG count;
assert(key);
assert(This);
assert(closure);
StorageUtl_WriteDWord((LPBYTE)&propid, 0, (DWORD)value);
c->hr = IStream_Write(This->stm, &propid, sizeof(propid), &count);
@ -1497,7 +1515,7 @@ static BOOL PropertyStorage_DictionaryWriter(const void *key,
DWORD keyLen, pad = 0;
StorageUtl_WriteDWord((LPBYTE)&keyLen, 0,
(lstrlenW((LPWSTR)key) + 1) * sizeof(WCHAR));
(lstrlenW((LPCWSTR)key) + 1) * sizeof(WCHAR));
c->hr = IStream_Write(This->stm, &keyLen, sizeof(keyLen), &count);
if (FAILED(c->hr))
goto end;
@ -1553,7 +1571,6 @@ static HRESULT PropertyStorage_WriteDictionaryToStream(
DWORD dwTemp;
struct DictionaryClosure closure;
assert(This);
assert(sectionOffset);
/* The dictionary's always the first property written, so seek to its
@ -1590,9 +1607,9 @@ static HRESULT PropertyStorage_WriteDictionaryToStream(
*sectionOffset += closure.bytesWritten;
if (closure.bytesWritten % sizeof(DWORD))
{
TRACE("adding %ld bytes of padding\n", sizeof(DWORD) -
closure.bytesWritten % sizeof(DWORD));
*sectionOffset += sizeof(DWORD) - closure.bytesWritten % sizeof(DWORD);
DWORD padding = sizeof(DWORD) - closure.bytesWritten % sizeof(DWORD);
TRACE("adding %d bytes of padding\n", padding);
*sectionOffset += padding;
}
end:
@ -1608,11 +1625,10 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
ULONG count;
DWORD dwType, bytesWritten;
assert(This);
assert(var);
assert(sectionOffset);
TRACE("%p, %ld, 0x%08lx, (%d), (%ld)\n", This, propNum, propid, var->vt,
TRACE("%p, %d, 0x%08x, (%d), (%d)\n", This, propNum, propid, var->vt,
*sectionOffset);
seek.QuadPart = SECTIONHEADER_OFFSET + sizeof(PROPERTYSECTIONHEADER) +
@ -1706,6 +1722,22 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
bytesWritten = count;
break;
}
case VT_CF:
{
DWORD cf_hdr[2], len;
len = var->u.pclipdata->cbSize;
StorageUtl_WriteDWord((LPBYTE)&cf_hdr[0], 0, len + 8);
StorageUtl_WriteDWord((LPBYTE)&cf_hdr[1], 0, var->u.pclipdata->ulClipFmt);
hr = IStream_Write(This->stm, &cf_hdr, sizeof(cf_hdr), &count);
if (FAILED(hr))
goto end;
hr = IStream_Write(This->stm, &var->u.pclipdata->pClipData, len, &count);
if (FAILED(hr))
goto end;
bytesWritten = count + sizeof cf_hdr;
break;
}
default:
FIXME("unsupported type: %d\n", var->vt);
return STG_E_INVALIDPARAMETER;
@ -1716,9 +1748,9 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
*sectionOffset += bytesWritten;
if (bytesWritten % sizeof(DWORD))
{
TRACE("adding %ld bytes of padding\n", sizeof(DWORD) -
bytesWritten % sizeof(DWORD));
*sectionOffset += sizeof(DWORD) - bytesWritten % sizeof(DWORD);
DWORD padding = sizeof(DWORD) - bytesWritten % sizeof(DWORD);
TRACE("adding %d bytes of padding\n", padding);
*sectionOffset += padding;
}
}
@ -1753,7 +1785,6 @@ static HRESULT PropertyStorage_WritePropertiesToStream(
{
struct PropertyClosure closure;
assert(This);
assert(sectionOffset);
closure.hr = S_OK;
closure.propNum = startingPropNum;
@ -1771,7 +1802,6 @@ static HRESULT PropertyStorage_WriteHeadersToStream(PropertyStorage_impl *This)
PROPERTYSETHEADER hdr;
FORMATIDOFFSET fmtOffset;
assert(This);
hr = IStream_Seek(This->stm, seek, STREAM_SEEK_SET, NULL);
if (FAILED(hr))
goto end;
@ -1809,8 +1839,6 @@ static HRESULT PropertyStorage_WriteToStream(PropertyStorage_impl *This)
DWORD numProps, prop, sectionOffset, dwTemp;
PROPVARIANT var;
assert(This);
PropertyStorage_WriteHeadersToStream(This);
/* Count properties. Always at least one property, the code page */
@ -1897,7 +1925,6 @@ end:
*/
static void PropertyStorage_DestroyDictionaries(PropertyStorage_impl *This)
{
assert(This);
dictionary_destroy(This->name_to_propid);
This->name_to_propid = NULL;
dictionary_destroy(This->propid_to_name);
@ -1910,7 +1937,6 @@ static HRESULT PropertyStorage_CreateDictionaries(PropertyStorage_impl *This)
{
HRESULT hr = S_OK;
assert(This);
This->name_to_propid = dictionary_create(
PropertyStorage_PropNameCompare, PropertyStorage_PropNameDestroy,
This);
@ -1953,6 +1979,7 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
(*pps)->vtbl = &IPropertyStorage_Vtbl;
(*pps)->ref = 1;
InitializeCriticalSection(&(*pps)->cs);
(*pps)->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStorage_impl.cs");
(*pps)->stm = stm;
memcpy(&(*pps)->fmtid, rfmtid, sizeof((*pps)->fmtid));
(*pps)->grfMode = grfMode;
@ -1961,6 +1988,7 @@ static HRESULT PropertyStorage_BaseConstruct(IStream *stm,
if (FAILED(hr))
{
IStream_Release(stm);
(*pps)->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&(*pps)->cs);
HeapFree(GetProcessHeap(), 0, *pps);
*pps = NULL;
@ -2017,7 +2045,7 @@ static HRESULT PropertyStorage_ConstructEmpty(IStream *stm,
else
ps->codePage = CP_UNICODE;
ps->locale = LOCALE_SYSTEM_DEFAULT;
TRACE("Code page is %d, locale is %ld\n", ps->codePage, ps->locale);
TRACE("Code page is %d, locale is %d\n", ps->codePage, ps->locale);
*pps = (IPropertyStorage *)ps;
TRACE("PropertyStorage %p constructed\n", ps);
hr = S_OK;
@ -2084,7 +2112,7 @@ static HRESULT WINAPI IPropertySetStorage_fnCreate(
IStream *stm = NULL;
HRESULT r;
TRACE("%p %s %08lx %08lx %p\n", This, debugstr_guid(rfmtid), grfFlags,
TRACE("%p %s %08x %08x %p\n", This, debugstr_guid(rfmtid), grfFlags,
grfMode, ppprstg);
/* be picky */
@ -2121,7 +2149,7 @@ static HRESULT WINAPI IPropertySetStorage_fnCreate(
r = PropertyStorage_ConstructEmpty(stm, rfmtid, grfFlags, grfMode, ppprstg);
end:
TRACE("returning 0x%08lx\n", r);
TRACE("returning 0x%08x\n", r);
return r;
}
@ -2139,7 +2167,7 @@ static HRESULT WINAPI IPropertySetStorage_fnOpen(
WCHAR name[CCH_MAX_PROPSTG_NAME];
HRESULT r;
TRACE("%p %s %08lx %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
TRACE("%p %s %08x %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
/* be picky */
if (grfMode != (STGM_READWRITE|STGM_SHARE_EXCLUSIVE) &&
@ -2166,7 +2194,7 @@ static HRESULT WINAPI IPropertySetStorage_fnOpen(
r = PropertyStorage_ConstructFromStream(stm, rfmtid, grfMode, ppprstg);
end:
TRACE("returning 0x%08lx\n", r);
TRACE("returning 0x%08x\n", r);
return r;
}
@ -2203,10 +2231,201 @@ static HRESULT WINAPI IPropertySetStorage_fnEnum(
IEnumSTATPROPSETSTG** ppenum)
{
StorageImpl *This = impl_from_IPropertySetStorage(ppstg);
FIXME("%p\n", This);
return E_NOTIMPL;
return create_EnumSTATPROPSETSTG(This, ppenum);
}
/************************************************************************
* Implement IEnumSTATPROPSETSTG using enumx
*/
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnQueryInterface(
IEnumSTATPROPSETSTG *iface,
REFIID riid,
void** ppvObject)
{
return enumx_QueryInterface((enumx_impl*)iface, riid, ppvObject);
}
static ULONG WINAPI IEnumSTATPROPSETSTG_fnAddRef(
IEnumSTATPROPSETSTG *iface)
{
return enumx_AddRef((enumx_impl*)iface);
}
static ULONG WINAPI IEnumSTATPROPSETSTG_fnRelease(
IEnumSTATPROPSETSTG *iface)
{
return enumx_Release((enumx_impl*)iface);
}
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnNext(
IEnumSTATPROPSETSTG *iface,
ULONG celt,
STATPROPSETSTG *rgelt,
ULONG *pceltFetched)
{
return enumx_Next((enumx_impl*)iface, celt, rgelt, pceltFetched);
}
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnSkip(
IEnumSTATPROPSETSTG *iface,
ULONG celt)
{
return enumx_Skip((enumx_impl*)iface, celt);
}
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnReset(
IEnumSTATPROPSETSTG *iface)
{
return enumx_Reset((enumx_impl*)iface);
}
static HRESULT WINAPI IEnumSTATPROPSETSTG_fnClone(
IEnumSTATPROPSETSTG *iface,
IEnumSTATPROPSETSTG **ppenum)
{
return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum);
}
static HRESULT create_EnumSTATPROPSETSTG(
StorageImpl *This,
IEnumSTATPROPSETSTG** ppenum)
{
IStorage *stg = (IStorage*) &This->base.lpVtbl;
IEnumSTATSTG *penum = NULL;
STATSTG stat;
ULONG count;
HRESULT r;
STATPROPSETSTG statpss;
enumx_impl *enumx;
TRACE("%p %p\n", This, ppenum);
enumx = enumx_allocate(&IID_IEnumSTATPROPSETSTG,
&IEnumSTATPROPSETSTG_Vtbl,
sizeof (STATPROPSETSTG));
/* add all the property set elements into a list */
r = IStorage_EnumElements(stg, 0, NULL, 0, &penum);
if (FAILED(r))
return E_OUTOFMEMORY;
while (1)
{
count = 0;
r = IEnumSTATSTG_Next(penum, 1, &stat, &count);
if (FAILED(r))
break;
if (!count)
break;
if (!stat.pwcsName)
continue;
if (stat.pwcsName[0] == 5 && stat.type == STGTY_STREAM)
{
PropStgNameToFmtId(stat.pwcsName, &statpss.fmtid);
TRACE("adding %s (%s)\n", debugstr_w(stat.pwcsName),
debugstr_guid(&statpss.fmtid));
statpss.mtime = stat.mtime;
statpss.atime = stat.atime;
statpss.ctime = stat.ctime;
statpss.grfFlags = stat.grfMode;
memcpy(&statpss.clsid, &stat.clsid, sizeof stat.clsid);
enumx_add_element(enumx, &statpss);
}
CoTaskMemFree(stat.pwcsName);
}
IEnumSTATSTG_Release(penum);
*ppenum = (IEnumSTATPROPSETSTG*) enumx;
return S_OK;
}
/************************************************************************
* Implement IEnumSTATPROPSTG using enumx
*/
static HRESULT WINAPI IEnumSTATPROPSTG_fnQueryInterface(
IEnumSTATPROPSTG *iface,
REFIID riid,
void** ppvObject)
{
return enumx_QueryInterface((enumx_impl*)iface, riid, ppvObject);
}
static ULONG WINAPI IEnumSTATPROPSTG_fnAddRef(
IEnumSTATPROPSTG *iface)
{
return enumx_AddRef((enumx_impl*)iface);
}
static ULONG WINAPI IEnumSTATPROPSTG_fnRelease(
IEnumSTATPROPSTG *iface)
{
return enumx_Release((enumx_impl*)iface);
}
static HRESULT WINAPI IEnumSTATPROPSTG_fnNext(
IEnumSTATPROPSTG *iface,
ULONG celt,
STATPROPSTG *rgelt,
ULONG *pceltFetched)
{
return enumx_Next((enumx_impl*)iface, celt, rgelt, pceltFetched);
}
static HRESULT WINAPI IEnumSTATPROPSTG_fnSkip(
IEnumSTATPROPSTG *iface,
ULONG celt)
{
return enumx_Skip((enumx_impl*)iface, celt);
}
static HRESULT WINAPI IEnumSTATPROPSTG_fnReset(
IEnumSTATPROPSTG *iface)
{
return enumx_Reset((enumx_impl*)iface);
}
static HRESULT WINAPI IEnumSTATPROPSTG_fnClone(
IEnumSTATPROPSTG *iface,
IEnumSTATPROPSTG **ppenum)
{
return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum);
}
static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
{
enumx_impl *enumx = arg;
PROPID propid = (PROPID) k;
const PROPVARIANT *prop = v;
STATPROPSTG stat;
stat.lpwstrName = NULL;
stat.propid = propid;
stat.vt = prop->vt;
enumx_add_element(enumx, &stat);
return TRUE;
}
static HRESULT create_EnumSTATPROPSTG(
PropertyStorage_impl *This,
IEnumSTATPROPSTG** ppenum)
{
enumx_impl *enumx;
TRACE("%p %p\n", This, ppenum);
enumx = enumx_allocate(&IID_IEnumSTATPROPSTG,
&IEnumSTATPROPSTG_Vtbl,
sizeof (STATPROPSTG));
dictionary_enumerate(This->propid_to_prop, prop_enum_stat, enumx);
*ppenum = (IEnumSTATPROPSTG*) enumx;
return S_OK;
}
/***********************************************************************
* vtables
@ -2241,6 +2460,28 @@ static const IPropertyStorageVtbl IPropertyStorage_Vtbl =
IPropertyStorage_fnStat,
};
static const IEnumSTATPROPSETSTGVtbl IEnumSTATPROPSETSTG_Vtbl =
{
IEnumSTATPROPSETSTG_fnQueryInterface,
IEnumSTATPROPSETSTG_fnAddRef,
IEnumSTATPROPSETSTG_fnRelease,
IEnumSTATPROPSETSTG_fnNext,
IEnumSTATPROPSETSTG_fnSkip,
IEnumSTATPROPSETSTG_fnReset,
IEnumSTATPROPSETSTG_fnClone,
};
static const IEnumSTATPROPSTGVtbl IEnumSTATPROPSTG_Vtbl =
{
IEnumSTATPROPSTG_fnQueryInterface,
IEnumSTATPROPSTG_fnAddRef,
IEnumSTATPROPSTG_fnRelease,
IEnumSTATPROPSTG_fnNext,
IEnumSTATPROPSTG_fnSkip,
IEnumSTATPROPSTG_fnReset,
IEnumSTATPROPSTG_fnClone,
};
/***********************************************************************
* Format ID <-> name conversion
*/
@ -2286,12 +2527,12 @@ HRESULT WINAPI FmtIdToPropStgName(const FMTID *rfmtid, LPOLESTR str)
lstrcpyW(str, szDocSummaryInfo);
else
{
BYTE *fmtptr;
const BYTE *fmtptr;
WCHAR *pstr = str;
ULONG bitsRemaining = BITS_PER_BYTE;
*pstr++ = 5;
for (fmtptr = (BYTE *)rfmtid; fmtptr < (BYTE *)rfmtid + sizeof(FMTID); )
for (fmtptr = (const BYTE *)rfmtid; fmtptr < (const BYTE *)rfmtid + sizeof(FMTID); )
{
ULONG i = *fmtptr >> (BITS_PER_BYTE - bitsRemaining);

View File

@ -20,7 +20,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
@ -58,8 +58,21 @@ static void StgStreamImpl_Destroy(StgStreamImpl* This)
/*
* Release the reference we are holding on the parent storage.
* IStorage_Release((IStorage*)This->parentStorage);
*
* No, don't do this. Some apps call IStorage_Release without
* calling IStream_Release first. If we grab a reference the
* file is not closed, and the app fails when it tries to
* reopen the file (Easy-PC, for example). Just inform the
* storage that we have closed the stream
*/
IStorage_Release((IStorage*)This->parentStorage);
if(This->parentStorage) {
StorageBaseImpl_RemoveStream(This->parentStorage, This);
}
This->parentStorage = 0;
/*
@ -108,8 +121,11 @@ static HRESULT WINAPI StgStreamImpl_QueryInterface(
/*
* Compare the riid with the interface IDs implemented by this object.
*/
if (IsEqualGUID(&IID_IUnknown, riid)||
IsEqualGUID(&IID_IStream, riid))
if (IsEqualIID(&IID_IUnknown, riid) ||
IsEqualIID(&IID_IPersist, riid) ||
IsEqualIID(&IID_IPersistStream, riid) ||
IsEqualIID(&IID_ISequentialStream, riid) ||
IsEqualIID(&IID_IStream, riid))
{
*ppvObject = (IStream*)This;
}
@ -173,7 +189,7 @@ static void StgStreamImpl_OpenBlockChain(
StgStreamImpl* This)
{
StgProperty curProperty;
BOOL readSucessful;
BOOL readSuccessful;
/*
* Make sure no old object is left over.
@ -193,11 +209,11 @@ static void StgStreamImpl_OpenBlockChain(
/*
* Read the information from the property.
*/
readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
readSuccessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
This->ownerProperty,
&curProperty);
if (readSucessful)
if (readSuccessful)
{
This->streamSize = curProperty.size;
@ -251,9 +267,15 @@ static HRESULT WINAPI StgStreamImpl_Read(
ULONG bytesToReadFromBuffer;
HRESULT res;
TRACE("(%p, %p, %ld, %p)\n",
TRACE("(%p, %p, %d, %p)\n",
iface, pv, cb, pcbRead);
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* If the caller is not interested in the number of bytes read,
* we use another buffer to avoid "if" statements in the code.
@ -282,15 +304,11 @@ static HRESULT WINAPI StgStreamImpl_Read(
}
else if (This->bigBlockChain!=0)
{
BOOL success = BlockChainStream_ReadAt(This->bigBlockChain,
This->currentPosition,
bytesToReadFromBuffer,
pv,
pcbRead);
if (success)
res = S_OK;
else
res = STG_E_READFAULT;
res = BlockChainStream_ReadAt(This->bigBlockChain,
This->currentPosition,
bytesToReadFromBuffer,
pv,
pcbRead);
}
else
{
@ -319,7 +337,7 @@ static HRESULT WINAPI StgStreamImpl_Read(
}
end:
TRACE("<-- %08lx\n", res);
TRACE("<-- %08x\n", res);
return res;
}
@ -343,8 +361,9 @@ static HRESULT WINAPI StgStreamImpl_Write(
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
HRESULT res;
TRACE("(%p, %p, %ld, %p)\n",
TRACE("(%p, %p, %d, %p)\n",
iface, pv, cb, pcbWritten);
/*
@ -356,12 +375,19 @@ static HRESULT WINAPI StgStreamImpl_Write(
case STGM_READWRITE:
break;
default:
WARN("access denied by flags: 0x%x\n", STGM_ACCESS_MODE(This->grfMode));
return STG_E_ACCESSDENIED;
}
if (!pv)
return STG_E_INVALIDPOINTER;
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* If the caller is not interested in the number of bytes written,
* we use another buffer to avoid "if" statements in the code.
@ -376,6 +402,7 @@ static HRESULT WINAPI StgStreamImpl_Write(
if (cb == 0)
{
TRACE("<-- S_OK, written 0\n");
return S_OK;
}
else
@ -390,7 +417,9 @@ static HRESULT WINAPI StgStreamImpl_Write(
if (newSize.u.LowPart > This->streamSize.u.LowPart)
{
/* grow stream */
IStream_SetSize(iface, newSize);
res = IStream_SetSize(iface, newSize);
if (FAILED(res))
return res;
}
/*
@ -399,7 +428,7 @@ static HRESULT WINAPI StgStreamImpl_Write(
*/
if (This->smallBlockChain!=0)
{
SmallBlockChainStream_WriteAt(This->smallBlockChain,
res = SmallBlockChainStream_WriteAt(This->smallBlockChain,
This->currentPosition,
cb,
pv,
@ -408,21 +437,27 @@ static HRESULT WINAPI StgStreamImpl_Write(
}
else if (This->bigBlockChain!=0)
{
BlockChainStream_WriteAt(This->bigBlockChain,
res = BlockChainStream_WriteAt(This->bigBlockChain,
This->currentPosition,
cb,
pv,
pcbWritten);
}
else
{
/* this should never happen because the IStream_SetSize call above will
* make sure a big or small block chain is created */
assert(FALSE);
res = 0;
}
/*
* Advance the position pointer for the number of positions written.
*/
This->currentPosition.u.LowPart += *pcbWritten;
return S_OK;
TRACE("<-- S_OK, written %u\n", *pcbWritten);
return res;
}
/***
@ -443,9 +478,19 @@ static HRESULT WINAPI StgStreamImpl_Seek(
ULARGE_INTEGER newPosition;
TRACE("(%p, %ld, %ld, %p)\n",
TRACE("(%p, %d, %d, %p)\n",
iface, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
/*
* fail if the stream has no parent (as does windows)
*/
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* The caller is allowed to pass in NULL as the new position return value.
* If it happens, we assign it to a dynamic variable to avoid special cases
@ -473,6 +518,7 @@ static HRESULT WINAPI StgStreamImpl_Seek(
*plibNewPosition = This->streamSize;
break;
default:
WARN("invalid dwOrigin %d\n", dwOrigin);
return STG_E_INVALIDFUNCTION;
}
@ -504,19 +550,31 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
StgProperty curProperty;
BOOL Success;
TRACE("(%p, %ld)\n", iface, libNewSize.u.LowPart);
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
if(!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* As documented.
*/
if (libNewSize.u.HighPart != 0)
{
WARN("invalid value for libNewSize.u.HighPart %d\n", libNewSize.u.HighPart);
return STG_E_INVALIDFUNCTION;
}
/*
* Do we have permission?
*/
if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE)))
{
WARN("access denied\n");
return STG_E_ACCESSDENIED;
}
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
return S_OK;
@ -609,18 +667,26 @@ static HRESULT WINAPI StgStreamImpl_CopyTo(
ULARGE_INTEGER* pcbRead, /* [out] */
ULARGE_INTEGER* pcbWritten) /* [out] */
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
HRESULT hr = S_OK;
BYTE tmpBuffer[128];
ULONG bytesRead, bytesWritten, copySize;
ULARGE_INTEGER totalBytesRead;
ULARGE_INTEGER totalBytesWritten;
TRACE("(%p, %p, %ld, %p, %p)\n",
TRACE("(%p, %p, %d, %p, %p)\n",
iface, pstm, cb.u.LowPart, pcbRead, pcbWritten);
/*
* Sanity check
*/
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
if ( pstm == 0 )
return STG_E_INVALIDPOINTER;
@ -653,6 +719,7 @@ static HRESULT WINAPI StgStreamImpl_CopyTo(
if (bytesRead != bytesWritten)
{
hr = STG_E_MEDIUMFULL;
WARN("medium full\n");
break;
}
@ -691,6 +758,14 @@ static HRESULT WINAPI StgStreamImpl_Commit(
IStream* iface,
DWORD grfCommitFlags) /* [in] */
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
return S_OK;
}
@ -714,6 +789,14 @@ static HRESULT WINAPI StgStreamImpl_LockRegion(
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType) /* [in] */
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
FIXME("not implemented!\n");
return E_NOTIMPL;
}
@ -724,6 +807,14 @@ static HRESULT WINAPI StgStreamImpl_UnlockRegion(
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType) /* [in] */
{
StgStreamImpl* const This=(StgStreamImpl*)iface;
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
FIXME("not implemented!\n");
return E_NOTIMPL;
}
@ -744,16 +835,28 @@ static HRESULT WINAPI StgStreamImpl_Stat(
StgStreamImpl* const This=(StgStreamImpl*)iface;
StgProperty curProperty;
BOOL readSucessful;
BOOL readSuccessful;
TRACE("%p %p %d\n", This, pstatstg, grfStatFlag);
/*
* if stream has no parent, return STG_E_REVERTED
*/
if (!This->parentStorage)
{
WARN("storage reverted\n");
return STG_E_REVERTED;
}
/*
* Read the information from the property.
*/
readSucessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
readSuccessful = StorageImpl_ReadProperty(This->parentStorage->ancestorStorage,
This->ownerProperty,
&curProperty);
if (readSucessful)
if (readSuccessful)
{
StorageUtl_CopyPropertyToSTATSTG(pstatstg,
&curProperty,
@ -764,6 +867,7 @@ static HRESULT WINAPI StgStreamImpl_Stat(
return S_OK;
}
WARN("failed to read properties\n");
return E_FAIL;
}
@ -788,9 +892,15 @@ static HRESULT WINAPI StgStreamImpl_Clone(
StgStreamImpl* new_stream;
LARGE_INTEGER seek_pos;
TRACE("%p %p\n", This, ppstm);
/*
* Sanity check
*/
if (!This->parentStorage)
return STG_E_REVERTED;
if ( ppstm == 0 )
return STG_E_INVALIDPOINTER;
@ -800,6 +910,8 @@ static HRESULT WINAPI StgStreamImpl_Clone(
return STG_E_INSUFFICIENTMEMORY; /* Currently the only reason for new_stream=0 */
*ppstm = (IStream*) new_stream;
IStream_AddRef(*ppstm);
seek_pos.QuadPart = This->currentPosition.QuadPart;
hres=StgStreamImpl_Seek (*ppstm, seek_pos, STREAM_SEEK_SET, NULL);
@ -858,12 +970,19 @@ StgStreamImpl* StgStreamImpl_Construct(
newStream->lpVtbl = &StgStreamImpl_Vtbl;
newStream->ref = 0;
newStream->parentStorage = parentStorage;
/*
* We want to nail-down the reference to the storage in case the
* stream out-lives the storage in the client application.
*
* -- IStorage_AddRef((IStorage*)newStream->parentStorage);
*
* No, don't do this. Some apps call IStorage_Release without
* calling IStream_Release first. If we grab a reference the
* file is not closed, and the app fails when it tries to
* reopen the file (Easy-PC, for example)
*/
newStream->parentStorage = parentStorage;
IStorage_AddRef((IStorage*)newStream->parentStorage);
newStream->grfMode = grfMode;
newStream->ownerProperty = ownerProperty;
@ -887,6 +1006,9 @@ StgStreamImpl* StgStreamImpl_Construct(
* this stream are large or small.
*/
StgStreamImpl_OpenBlockChain(newStream);
/* add us to the storage's list of active streams */
StorageBaseImpl_AddStream(parentStorage, newStream);
}
return newStream;

View File

@ -18,7 +18,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -353,12 +353,12 @@ STORAGE_get_big_block(stream_access16 *str,int n,BYTE *block)
if ((SetFilePointer( str->hf, (n+1)*BIGSIZE, NULL,
SEEK_SET ) == INVALID_SET_FILE_POINTER) && GetLastError())
{
WARN("(%p,%d,%p), seek failed (%ld)\n",str->hf, n, block, GetLastError());
WARN("(%p,%d,%p), seek failed (%d)\n",str->hf, n, block, GetLastError());
return FALSE;
}
if (!ReadFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE)
{
WARN("(hf=%p, block size %d): read didn't read (%ld)\n",str->hf,n,GetLastError());
WARN("(hf=%p, block size %d): read didn't read (%d)\n",str->hf,n,GetLastError());
return FALSE;
}
} else {
@ -382,7 +382,7 @@ STORAGE_get_big_block(stream_access16 *str,int n,BYTE *block)
(LPVOID)args,
(LPDWORD)&hres
)) {
ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %x\n",hres);
return FALSE;
}
memcpy(block, MapSL(args[3]), BIGSIZE);
@ -414,7 +414,7 @@ _ilockbytes16_writeat(SEGPTR lockbytes, DWORD offset, DWORD length, void *buffer
(LPVOID)args,
(LPDWORD)&hres
)) {
ERR("CallTo16 ILockBytes16::WriteAt() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::WriteAt() failed, hres %x\n",hres);
return FALSE;
}
UnMapLS(args[3]);
@ -434,12 +434,12 @@ STORAGE_put_big_block(stream_access16 *str,int n,BYTE *block)
if ((SetFilePointer( str->hf, (n+1)*BIGSIZE, NULL,
SEEK_SET ) == INVALID_SET_FILE_POINTER) && GetLastError())
{
WARN("seek failed (%ld)\n",GetLastError());
WARN("seek failed (%d)\n",GetLastError());
return FALSE;
}
if (!WriteFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE)
{
WARN(" write failed (%ld)\n",GetLastError());
WARN(" write failed (%d)\n",GetLastError());
return FALSE;
}
return TRUE;
@ -719,9 +719,9 @@ STORAGE_dump_pps_entry(struct storage_pps_entry *stde) {
return;
DPRINTF("name: %s\n",name);
DPRINTF("type: %d\n",stde->pps_type);
DPRINTF("prev pps: %ld\n",stde->pps_prev);
DPRINTF("next pps: %ld\n",stde->pps_next);
DPRINTF("dir pps: %ld\n",stde->pps_dir);
DPRINTF("prev pps: %d\n",stde->pps_prev);
DPRINTF("next pps: %d\n",stde->pps_next);
DPRINTF("dir pps: %d\n",stde->pps_dir);
DPRINTF("guid: %s\n",debugstr_guid(&(stde->pps_guid)));
if (stde->pps_type !=2) {
time_t t;
@ -733,8 +733,8 @@ STORAGE_dump_pps_entry(struct storage_pps_entry *stde) {
t = dw;
DPRINTF("ts2: %s\n",ctime(&t));
}
DPRINTF("startblock: %ld\n",stde->pps_sb);
DPRINTF("size: %ld\n",stde->pps_size);
DPRINTF("startblock: %d\n",stde->pps_sb);
DPRINTF("size: %d\n",stde->pps_size);
}
/******************************************************************************
@ -1071,7 +1071,7 @@ typedef struct
/******************************************************************************
* IStream16_QueryInterface [STORAGE.518]
*/
HRESULT IStream16_fnQueryInterface(
HRESULT CDECL IStream16_fnQueryInterface(
IStream16* iface,REFIID refiid,LPVOID *obj
) {
IStream16Impl *This = (IStream16Impl *)iface;
@ -1087,7 +1087,7 @@ HRESULT IStream16_fnQueryInterface(
/******************************************************************************
* IStream16_AddRef [STORAGE.519]
*/
ULONG IStream16_fnAddRef(IStream16* iface) {
ULONG CDECL IStream16_fnAddRef(IStream16* iface) {
IStream16Impl *This = (IStream16Impl *)iface;
return InterlockedIncrement(&This->ref);
}
@ -1107,7 +1107,7 @@ _ilockbytes16_addref(SEGPTR lockbytes) {
(LPVOID)args,
(LPDWORD)&hres
))
ERR("CallTo16 ILockBytes16::AddRef() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::AddRef() failed, hres %x\n",hres);
}
static void
@ -1125,7 +1125,7 @@ _ilockbytes16_release(SEGPTR lockbytes) {
(LPVOID)args,
(LPDWORD)&hres
))
ERR("CallTo16 ILockBytes16::Release() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::Release() failed, hres %x\n",hres);
}
static void
@ -1143,13 +1143,13 @@ _ilockbytes16_flush(SEGPTR lockbytes) {
(LPVOID)args,
(LPDWORD)&hres
))
ERR("CallTo16 ILockBytes16::Flush() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::Flush() failed, hres %x\n",hres);
}
/******************************************************************************
* IStream16_Release [STORAGE.520]
*/
ULONG IStream16_fnRelease(IStream16* iface) {
ULONG CDECL IStream16_fnRelease(IStream16* iface) {
IStream16Impl *This = (IStream16Impl *)iface;
ULONG ref;
@ -1176,11 +1176,11 @@ ULONG IStream16_fnRelease(IStream16* iface) {
* FIXME
* Does not handle 64 bits
*/
HRESULT IStream16_fnSeek(
HRESULT CDECL IStream16_fnSeek(
IStream16* iface,LARGE_INTEGER offset,DWORD whence,ULARGE_INTEGER *newpos
) {
IStream16Impl *This = (IStream16Impl *)iface;
TRACE_(relay)("(%p)->([%ld.%ld],%ld,%p)\n",This,offset.u.HighPart,offset.u.LowPart,whence,newpos);
TRACE_(relay)("(%p)->([%d.%d],%d,%p)\n",This,offset.u.HighPart,offset.u.LowPart,whence,newpos);
switch (whence) {
/* unix SEEK_xx should be the same as win95 ones */
@ -1220,7 +1220,7 @@ HRESULT IStream16_fnSeek(
/******************************************************************************
* IStream16_Read [STORAGE.521]
*/
HRESULT IStream16_fnRead(
HRESULT CDECL IStream16_fnRead(
IStream16* iface,void *pv,ULONG cb,ULONG *pcbRead
) {
IStream16Impl *This = (IStream16Impl *)iface;
@ -1229,7 +1229,7 @@ HRESULT IStream16_fnRead(
int blocknr;
LPBYTE pbv = pv;
TRACE_(relay)("(%p)->(%p,%ld,%p)\n",This,pv,cb,pcbRead);
TRACE_(relay)("(%p)->(%p,%d,%p)\n",This,pv,cb,pcbRead);
if (!pcbRead) bytesread=&xxread;
*bytesread = 0;
@ -1282,7 +1282,7 @@ HRESULT IStream16_fnRead(
/******************************************************************************
* IStream16_Write [STORAGE.522]
*/
HRESULT IStream16_fnWrite(
HRESULT CDECL IStream16_fnWrite(
IStream16* iface,const void *pv,ULONG cb,ULONG *pcbWrite
) {
IStream16Impl *This = (IStream16Impl *)iface;
@ -1294,7 +1294,7 @@ HRESULT IStream16_fnWrite(
if (!pcbWrite) byteswritten=&xxwritten;
*byteswritten = 0;
TRACE_(relay)("(%p)->(%p,%ld,%p)\n",This,pv,cb,pcbWrite);
TRACE_(relay)("(%p)->(%p,%d,%p)\n",This,pv,cb,pcbWrite);
/* do we need to junk some blocks? */
newsize = This->offset.u.LowPart+cb;
oldsize = This->stde.pps_size;
@ -1667,7 +1667,7 @@ ULONG WINAPI IStream_fnRelease(IStream* iface) {
/******************************************************************************
* IStorage16_QueryInterface [STORAGE.500]
*/
HRESULT IStorage16_fnQueryInterface(
HRESULT CDECL IStorage16_fnQueryInterface(
IStorage16* iface,REFIID refiid,LPVOID *obj
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@ -1684,7 +1684,7 @@ HRESULT IStorage16_fnQueryInterface(
/******************************************************************************
* IStorage16_AddRef [STORAGE.501]
*/
ULONG IStorage16_fnAddRef(IStorage16* iface) {
ULONG CDECL IStorage16_fnAddRef(IStorage16* iface) {
IStorage16Impl *This = (IStorage16Impl *)iface;
return InterlockedIncrement(&This->ref);
}
@ -1692,7 +1692,7 @@ ULONG IStorage16_fnAddRef(IStorage16* iface) {
/******************************************************************************
* IStorage16_Release [STORAGE.502]
*/
ULONG IStorage16_fnRelease(IStorage16* iface) {
ULONG CDECL IStorage16_fnRelease(IStorage16* iface) {
IStorage16Impl *This = (IStorage16Impl *)iface;
ULONG ref;
ref = InterlockedDecrement(&This->ref);
@ -1707,14 +1707,14 @@ ULONG IStorage16_fnRelease(IStorage16* iface) {
/******************************************************************************
* IStorage16_Stat [STORAGE.517]
*/
HRESULT IStorage16_fnStat(
HRESULT CDECL IStorage16_fnStat(
LPSTORAGE16 iface,STATSTG16 *pstatstg, DWORD grfStatFlag
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
DWORD len = WideCharToMultiByte( CP_ACP, 0, This->stde.pps_rawname, -1, NULL, 0, NULL, NULL );
LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, len );
TRACE("(%p)->(%p,0x%08lx)\n",
TRACE("(%p)->(%p,0x%08x)\n",
This,pstatstg,grfStatFlag
);
WideCharToMultiByte( CP_ACP, 0, This->stde.pps_rawname, -1, nameA, len, NULL, NULL );
@ -1735,11 +1735,11 @@ HRESULT IStorage16_fnStat(
/******************************************************************************
* IStorage16_Commit [STORAGE.509]
*/
HRESULT IStorage16_fnCommit(
HRESULT CDECL IStorage16_fnCommit(
LPSTORAGE16 iface,DWORD commitflags
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
FIXME("(%p)->(0x%08lx),STUB!\n",
FIXME("(%p)->(0x%08x),STUB!\n",
This,commitflags
);
return S_OK;
@ -1748,9 +1748,9 @@ HRESULT IStorage16_fnCommit(
/******************************************************************************
* IStorage16_CopyTo [STORAGE.507]
*/
HRESULT IStorage16_fnCopyTo(LPSTORAGE16 iface,DWORD ciidExclude,const IID *rgiidExclude,SNB16 SNB16Exclude,IStorage16 *pstgDest) {
HRESULT CDECL IStorage16_fnCopyTo(LPSTORAGE16 iface,DWORD ciidExclude,const IID *rgiidExclude,SNB16 SNB16Exclude,IStorage16 *pstgDest) {
IStorage16Impl *This = (IStorage16Impl *)iface;
FIXME("IStorage16(%p)->(0x%08lx,%s,%p,%p),stub!\n",
FIXME("IStorage16(%p)->(0x%08x,%s,%p,%p),stub!\n",
This,ciidExclude,debugstr_guid(rgiidExclude),SNB16Exclude,pstgDest
);
return S_OK;
@ -1760,7 +1760,7 @@ HRESULT IStorage16_fnCopyTo(LPSTORAGE16 iface,DWORD ciidExclude,const IID *rgiid
/******************************************************************************
* IStorage16_CreateStorage [STORAGE.505]
*/
HRESULT IStorage16_fnCreateStorage(
HRESULT CDECL IStorage16_fnCreateStorage(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName,DWORD grfMode,DWORD dwStgFormat,DWORD reserved2, IStorage16 **ppstg
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@ -1772,7 +1772,7 @@ HRESULT IStorage16_fnCreateStorage(
int nPPSEntries;
READ_HEADER(&This->str);
TRACE("(%p)->(%s,0x%08lx,0x%08lx,0x%08lx,%p)\n",
TRACE("(%p)->(%s,0x%08x,0x%08x,0x%08x,%p)\n",
This,pwcsName,grfMode,dwStgFormat,reserved2,ppstg
);
if (grfMode & STGM_TRANSACTED)
@ -1829,7 +1829,7 @@ HRESULT IStorage16_fnCreateStorage(
/******************************************************************************
* IStorage16_CreateStream [STORAGE.503]
*/
HRESULT IStorage16_fnCreateStream(
HRESULT CDECL IStorage16_fnCreateStream(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName,DWORD grfMode,DWORD reserved1,DWORD reserved2, IStream16 **ppstm
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@ -1839,7 +1839,7 @@ HRESULT IStorage16_fnCreateStream(
BOOL ret;
int nPPSEntries;
TRACE("(%p)->(%s,0x%08lx,0x%08lx,0x%08lx,%p)\n",
TRACE("(%p)->(%s,0x%08x,0x%08x,0x%08x,%p)\n",
This,pwcsName,grfMode,reserved1,reserved2,ppstm
);
if (grfMode & STGM_TRANSACTED)
@ -1893,7 +1893,7 @@ HRESULT IStorage16_fnCreateStream(
/******************************************************************************
* IStorage16_OpenStorage [STORAGE.506]
*/
HRESULT IStorage16_fnOpenStorage(
HRESULT CDECL IStorage16_fnOpenStorage(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName, IStorage16 *pstgPrio, DWORD grfMode, SNB16 snbExclude, DWORD reserved, IStorage16 **ppstg
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@ -1901,7 +1901,7 @@ HRESULT IStorage16_fnOpenStorage(
WCHAR name[33];
int newpps;
TRACE("(%p)->(%s,%p,0x%08lx,%p,0x%08lx,%p)\n",
TRACE("(%p)->(%s,%p,0x%08x,%p,0x%08x,%p)\n",
This,pwcsName,pstgPrio,grfMode,snbExclude,reserved,ppstg
);
if (grfMode & STGM_TRANSACTED)
@ -1933,7 +1933,7 @@ HRESULT IStorage16_fnOpenStorage(
/******************************************************************************
* IStorage16_OpenStream [STORAGE.504]
*/
HRESULT IStorage16_fnOpenStream(
HRESULT CDECL IStorage16_fnOpenStream(
LPSTORAGE16 iface,LPCOLESTR16 pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream16 **ppstm
) {
IStorage16Impl *This = (IStorage16Impl *)iface;
@ -1941,7 +1941,7 @@ HRESULT IStorage16_fnOpenStream(
WCHAR name[33];
int newpps;
TRACE("(%p)->(%s,%p,0x%08lx,0x%08lx,%p)\n",
TRACE("(%p)->(%s,%p,0x%08x,0x%08x,%p)\n",
This,pwcsName,reserved1,grfMode,reserved2,ppstm
);
if (grfMode & STGM_TRANSACTED)
@ -2052,13 +2052,13 @@ HRESULT WINAPI StgCreateDocFile16(
IStorage16Impl* lpstg;
struct storage_pps_entry stde;
TRACE("(%s,0x%08lx,0x%08lx,%p)\n",
TRACE("(%s,0x%08x,0x%08x,%p)\n",
pwcsName,grfMode,reserved,ppstgOpen
);
_create_istorage16(ppstgOpen);
hf = CreateFileA(pwcsName,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,0,0);
if (hf==INVALID_HANDLE_VALUE) {
WARN("couldn't open file for storage:%ld\n",GetLastError());
WARN("couldn't open file for storage:%d\n",GetLastError());
return E_FAIL;
}
lpstg = MapSL((SEGPTR)*ppstgOpen);
@ -2113,7 +2113,7 @@ HRESULT WINAPI StgOpenStorage16(
IStorage16Impl* lpstg;
struct storage_pps_entry stde;
TRACE("(%s,%p,0x%08lx,%p,%ld,%p)\n",
TRACE("(%s,%p,0x%08x,%p,%d,%p)\n",
pwcsName,pstgPriority,grfMode,snbExclude,reserved,ppstgOpen
);
_create_istorage16(ppstgOpen);
@ -2168,7 +2168,7 @@ HRESULT WINAPI StgIsStorageILockBytes16(SEGPTR plkbyt)
(LPVOID)args,
(LPDWORD)&hres
)) {
ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %lx\n",hres);
ERR("CallTo16 ILockBytes16::ReadAt() failed, hres %x\n",hres);
return hres;
}
if (memcmp(MapSL(args[3]), STORAGE_magic, sizeof(STORAGE_magic)) == 0) {
@ -2181,9 +2181,12 @@ HRESULT WINAPI StgIsStorageILockBytes16(SEGPTR plkbyt)
/******************************************************************************
* StgOpenStorageOnILockBytes [STORAGE.4]
*
* PARAMS
* plkbyt FIXME: Should probably be an ILockBytes16 *.
*/
HRESULT WINAPI StgOpenStorageOnILockBytes16(
SEGPTR /*ILockBytes16 **/plkbyt,
SEGPTR plkbyt,
IStorage16 *pstgPriority,
DWORD grfMode,
SNB16 snbExclude,
@ -2194,7 +2197,7 @@ HRESULT WINAPI StgOpenStorageOnILockBytes16(
int i,ret;
struct storage_pps_entry stde;
FIXME("(%lx, %p, 0x%08lx, %d, %lx, %p)\n", plkbyt, pstgPriority, grfMode, (int)snbExclude, reserved, ppstgOpen);
FIXME("(%x, %p, 0x%08x, %d, %x, %p)\n", plkbyt, pstgPriority, grfMode, (int)snbExclude, reserved, ppstgOpen);
if ((plkbyt == 0) || (ppstgOpen == 0))
return STG_E_INVALIDPOINTER;
@ -2241,7 +2244,7 @@ HRESULT WINAPI ReadClassStg16(SEGPTR pstg, CLSID *pclsid)
HRESULT hres;
DWORD args[3];
TRACE("(%lx, %p)\n", pstg, pclsid);
TRACE("(%x, %p)\n", pstg, pclsid);
if(pclsid==NULL)
return E_POINTER;
@ -2262,7 +2265,7 @@ HRESULT WINAPI ReadClassStg16(SEGPTR pstg, CLSID *pclsid)
(LPDWORD)&hres
)) {
WOWGlobalUnlockFree16(args[1]);
ERR("CallTo16 IStorage16::Stat() failed, hres %lx\n",hres);
ERR("CallTo16 IStorage16::Stat() failed, hres %x\n",hres);
return hres;
}
memcpy(&statstg, MapSL(args[1]), sizeof(STATSTG16));

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __STORAGE32_H__
#define __STORAGE32_H__
@ -37,6 +37,7 @@
#include "objbase.h"
#include "winreg.h"
#include "winternl.h"
#include "wine/list.h"
/*
* Definitions for the file format offsets.
@ -110,19 +111,12 @@ static const ULONG PROPERTY_NULL = 0xFFFFFFFF;
STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \
STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE)
/*
* These are signatures to detect the type of Document file.
*/
static const BYTE STORAGE_magic[8] ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1};
static const BYTE STORAGE_oldmagic[8] ={0xd0,0xcf,0x11,0xe0,0x0e,0x11,0xfc,0x0d};
/*
* Forward declarations of all the structures used by the storage
* module.
*/
typedef struct StorageBaseImpl StorageBaseImpl;
typedef struct StorageImpl StorageImpl;
typedef struct StorageInternalImpl StorageInternalImpl;
typedef struct BlockChainStream BlockChainStream;
typedef struct SmallBlockChainStream SmallBlockChainStream;
typedef struct IEnumSTATSTGImpl IEnumSTATSTGImpl;
@ -190,11 +184,12 @@ BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile,
ULONG blocksize,
BOOL fileBased);
void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index);
void* BIGBLOCKFILE_GetROBigBlock(LPBIGBLOCKFILE This, ULONG index);
void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock);
void BIGBLOCKFILE_EnsureExists(LPBIGBLOCKFILE This, ULONG index);
void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This);
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, ULONG size, ULONG* bytesRead);
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, const ULONG size, ULONG* bytesRead);
/*************************************************************************
* Ole Convert support
@ -219,6 +214,12 @@ struct StorageBaseImpl
const IPropertySetStorageVtbl *pssVtbl; /* interface for adding a properties stream */
/*
* Stream tracking list
*/
struct list strmHead;
/*
* Reference count of this object
*/
@ -246,6 +247,12 @@ struct StorageBaseImpl
DWORD openFlags;
};
/****************************************************************************
* StorageBaseImpl stream list handlers
*/
void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm);
void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm);
/****************************************************************************
* Storage32Impl definitions.
@ -298,63 +305,6 @@ struct StorageImpl
BigBlockFile* bigBlockFile;
};
void StorageImpl_Destroy(
StorageBaseImpl* This);
HRESULT StorageImpl_Construct(
StorageImpl* This,
HANDLE hFile,
LPCOLESTR pwcsName,
ILockBytes* pLkbyt,
DWORD openFlags,
BOOL fileBased,
BOOL fileCreate);
BOOL StorageImpl_ReadBigBlock(
StorageImpl* This,
ULONG blockIndex,
void* buffer);
BOOL StorageImpl_WriteBigBlock(
StorageImpl* This,
ULONG blockIndex,
void* buffer);
void* StorageImpl_GetROBigBlock(
StorageImpl* This,
ULONG blockIndex);
void* StorageImpl_GetBigBlock(
StorageImpl* This,
ULONG blockIndex);
void StorageImpl_ReleaseBigBlock(
StorageImpl* This,
void* pBigBlock);
ULONG StorageImpl_GetNextFreeBigBlock(
StorageImpl* This);
void StorageImpl_FreeBigBlock(
StorageImpl* This,
ULONG blockIndex);
HRESULT StorageImpl_GetNextBlockInChain(
StorageImpl* This,
ULONG blockIndex,
ULONG* nextBlockIndex);
void StorageImpl_SetNextBlockInChain(
StorageImpl* This,
ULONG blockIndex,
ULONG nextBlock);
HRESULT StorageImpl_LoadFileHeader(
StorageImpl* This);
void StorageImpl_SaveFileHeader(
StorageImpl* This);
BOOL StorageImpl_ReadProperty(
StorageImpl* This,
ULONG index,
@ -369,114 +319,10 @@ BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
StorageImpl* This,
SmallBlockChainStream** ppsbChain);
ULONG Storage32Impl_GetNextExtendedBlock(StorageImpl* This,
ULONG blockIndex);
void Storage32Impl_AddBlockDepot(StorageImpl* This,
ULONG blockIndex);
ULONG Storage32Impl_AddExtBlockDepot(StorageImpl* This);
ULONG Storage32Impl_GetExtDepotBlock(StorageImpl* This,
ULONG depotIndex);
void Storage32Impl_SetExtDepotBlock(StorageImpl* This,
ULONG depotIndex,
ULONG blockIndex);
/****************************************************************************
* Storage32InternalImpl definitions.
*
* Definition of the implementation structure for the IStorage32 interface.
* This one implements the IStorage32 interface for storage that are
* inside another storage.
*/
struct StorageInternalImpl
{
struct StorageBaseImpl base;
/*
* There is no specific data for this class.
*/
};
/*
* Method definitions for the Storage32InternalImpl class.
*/
StorageInternalImpl* StorageInternalImpl_Construct(
StorageImpl* ancestorStorage,
DWORD openFlags,
ULONG rootTropertyIndex);
void StorageInternalImpl_Destroy(
StorageBaseImpl* This);
HRESULT WINAPI StorageInternalImpl_Commit(
IStorage* iface,
DWORD grfCommitFlags); /* [in] */
HRESULT WINAPI StorageInternalImpl_Revert(
IStorage* iface);
/****************************************************************************
* IEnumSTATSTGImpl definitions.
*
* Definition of the implementation structure for the IEnumSTATSTGImpl interface.
* This class allows iterating through the content of a storage and to find
* specific items inside it.
*/
struct IEnumSTATSTGImpl
{
const IEnumSTATSTGVtbl *lpVtbl; /* Needs to be the first item in the struct
* since we want to cast this in an IEnumSTATSTG pointer */
LONG ref; /* Reference count */
StorageImpl* parentStorage; /* Reference to the parent storage */
ULONG firstPropertyNode; /* Index of the root of the storage to enumerate */
/*
* The current implementation of the IEnumSTATSTGImpl class uses a stack
* to walk the property sets to get the content of a storage. This stack
* is implemented by the following 3 data members
*/
ULONG stackSize;
ULONG stackMaxSize;
ULONG* stackToVisit;
#define ENUMSTATSGT_SIZE_INCREMENT 10
};
IEnumSTATSTGImpl* IEnumSTATSTGImpl_Construct(
StorageImpl* This,
ULONG firstPropertyNode);
void IEnumSTATSTGImpl_Destroy(
IEnumSTATSTGImpl* This);
void IEnumSTATSTGImpl_PushSearchNode(
IEnumSTATSTGImpl* This,
ULONG nodeToPush);
ULONG IEnumSTATSTGImpl_PopSearchNode(
IEnumSTATSTGImpl* This,
BOOL remove);
ULONG IEnumSTATSTGImpl_FindProperty(
IEnumSTATSTGImpl* This,
const OLECHAR* lpszPropName,
StgProperty* buffer);
INT IEnumSTATSTGImpl_FindParentProperty(
IEnumSTATSTGImpl *This,
ULONG childProperty,
StgProperty *currentProperty,
ULONG *propertyId);
/****************************************************************************
* StgStreamImpl definitions.
*
* This class imlements the IStream32 inteface and represents a stream
* This class implements the IStream32 interface and represents a stream
* located inside a storage object.
*/
struct StgStreamImpl
@ -484,6 +330,12 @@ struct StgStreamImpl
const IStreamVtbl *lpVtbl; /* Needs to be the first item in the struct
* since we want to cast this to an IStream pointer */
/*
* We are an entry in the storage object's stream handler list
*/
struct list StrmListEntry;
/*
* Reference count
*/
@ -598,17 +450,14 @@ BlockChainStream* BlockChainStream_Construct(
void BlockChainStream_Destroy(
BlockChainStream* This);
ULONG BlockChainStream_GetHeadOfChain(
BlockChainStream* This);
BOOL BlockChainStream_ReadAt(
HRESULT BlockChainStream_ReadAt(
BlockChainStream* This,
ULARGE_INTEGER offset,
ULONG size,
void* buffer,
ULONG* bytesRead);
BOOL BlockChainStream_WriteAt(
HRESULT BlockChainStream_WriteAt(
BlockChainStream* This,
ULARGE_INTEGER offset,
ULONG size,
@ -619,12 +468,6 @@ BOOL BlockChainStream_SetSize(
BlockChainStream* This,
ULARGE_INTEGER newSize);
ULARGE_INTEGER BlockChainStream_GetSize(
BlockChainStream* This);
ULONG BlockChainStream_GetCount(
BlockChainStream* This);
/****************************************************************************
* SmallBlockChainStream definitions.
*
@ -647,26 +490,6 @@ SmallBlockChainStream* SmallBlockChainStream_Construct(
void SmallBlockChainStream_Destroy(
SmallBlockChainStream* This);
ULONG SmallBlockChainStream_GetHeadOfChain(
SmallBlockChainStream* This);
HRESULT SmallBlockChainStream_GetNextBlockInChain(
SmallBlockChainStream* This,
ULONG blockIndex,
ULONG* nextBlockIndex);
void SmallBlockChainStream_SetNextBlockInChain(
SmallBlockChainStream* This,
ULONG blockIndex,
ULONG nextBlock);
void SmallBlockChainStream_FreeBlock(
SmallBlockChainStream* This,
ULONG blockIndex);
ULONG SmallBlockChainStream_GetNextFreeBlock(
SmallBlockChainStream* This);
HRESULT SmallBlockChainStream_ReadAt(
SmallBlockChainStream* This,
ULARGE_INTEGER offset,
@ -674,7 +497,7 @@ HRESULT SmallBlockChainStream_ReadAt(
void* buffer,
ULONG* bytesRead);
BOOL SmallBlockChainStream_WriteAt(
HRESULT SmallBlockChainStream_WriteAt(
SmallBlockChainStream* This,
ULARGE_INTEGER offset,
ULONG size,
@ -685,11 +508,5 @@ BOOL SmallBlockChainStream_SetSize(
SmallBlockChainStream* This,
ULARGE_INTEGER newSize);
ULARGE_INTEGER SmallBlockChainStream_GetSize(
SmallBlockChainStream* This);
ULONG SmallBlockChainStream_GetCount(
SmallBlockChainStream* This);
#endif /* __STORAGE32_H__ */

View File

@ -20,7 +20,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
@ -35,9 +35,8 @@
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "ole2ver.h"
#include "rpc.h"
#include "wine/debug.h"
#include "compobj_private.h"
@ -71,6 +70,23 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
* and the caller will also hold a reference */
sm->refs = 2;
sm->oxid_info.dwPid = GetCurrentProcessId();
sm->oxid_info.dwTid = GetCurrentThreadId();
/*
* FIXME: this is a hack for marshalling IRemUnknown. In real
* DCOM, the IPID of the IRemUnknown interface is generated like
* any other and passed to the OXID resolver which then returns it
* when queried. We don't have an OXID resolver yet so instead we
* use a magic IPID reserved for IRemUnknown.
*/
sm->oxid_info.ipidRemUnknown.Data1 = 0xffffffff;
sm->oxid_info.ipidRemUnknown.Data2 = 0xffff;
sm->oxid_info.ipidRemUnknown.Data3 = 0xffff;
assert(sizeof(sm->oxid_info.ipidRemUnknown.Data4) == sizeof(apt->oxid));
memcpy(&sm->oxid_info.ipidRemUnknown.Data4, &apt->oxid, sizeof(OXID));
sm->oxid_info.dwAuthnHint = RPC_C_AUTHN_LEVEL_NONE;
sm->oxid_info.psa = NULL /* FIXME */;
/* yes, that's right, this starts at zero. that's zero EXTERNAL
* refs, ie nobody has unmarshalled anything yet. we can't have
* negative refs because the stub manager cannot be explicitly
@ -103,6 +119,7 @@ static void stub_manager_delete(struct stub_manager *m)
stub_manager_delete_ifstub(m, ifstub);
}
CoTaskMemFree(m->oxid_info.psa);
IUnknown_Release(m->object);
DEBUG_CLEAR_CRITSEC_NAME(&m->lock);
@ -205,7 +222,7 @@ ULONG stub_manager_int_addref(struct stub_manager *This)
refs = ++This->refs;
LeaveCriticalSection(&This->apt->cs);
TRACE("before %ld\n", refs - 1);
TRACE("before %d\n", refs - 1);
return refs;
}
@ -219,7 +236,7 @@ ULONG stub_manager_int_release(struct stub_manager *This)
EnterCriticalSection(&apt->cs);
refs = --This->refs;
TRACE("after %ld\n", refs);
TRACE("after %d\n", refs);
/* remove from apartment so no other thread can access it... */
if (!refs)
@ -247,13 +264,13 @@ ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs)
LeaveCriticalSection(&m->lock);
TRACE("added %lu refs to %p (oid %s), rc is now %lu\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
TRACE("added %u refs to %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
return rc;
}
/* remove some external references */
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs)
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL last_unlock_releases)
{
ULONG rc;
@ -265,9 +282,9 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs)
LeaveCriticalSection(&m->lock);
TRACE("removed %lu refs from %p (oid %s), rc is now %lu\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
if (rc == 0)
if (rc == 0 && last_unlock_releases)
stub_manager_int_release(m);
return rc;
@ -365,29 +382,41 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
return S_OK;
}
/* gets the apartment and IRpcStubBuffer from an object. the caller must
* release the references to both objects */
IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt)
/* gets the apartment, stub and channel of an object. the caller must
* release the references to all objects (except iface) if the function
* returned success, otherwise no references are returned. */
HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt,
IRpcStubBuffer **stub, IRpcChannelBuffer **chan,
IID *iid, IUnknown **iface)
{
IRpcStubBuffer *ret = NULL;
struct stub_manager *stubmgr;
struct ifstub *ifstub;
APARTMENT *apt;
HRESULT hr;
*stub_apt = NULL;
hr = ipid_to_stub_manager(ipid, stub_apt, &stubmgr);
if (hr != S_OK) return NULL;
hr = ipid_to_stub_manager(ipid, &apt, &stubmgr);
if (hr != S_OK) return RPC_E_DISCONNECTED;
ifstub = stub_manager_ipid_to_ifstub(stubmgr, ipid);
if (ifstub)
ret = ifstub->stubbuffer;
{
*stub = ifstub->stubbuffer;
IRpcStubBuffer_AddRef(*stub);
*chan = ifstub->chan;
IRpcChannelBuffer_AddRef(*chan);
*stub_apt = apt;
*iid = ifstub->iid;
*iface = ifstub->iface;
if (ret) IRpcStubBuffer_AddRef(ret);
stub_manager_int_release(stubmgr);
return ret;
stub_manager_int_release(stubmgr);
return S_OK;
}
else
{
stub_manager_int_release(stubmgr);
apartment_release(apt);
return RPC_E_DISCONNECTED;
}
}
/* generates an ipid in the following format (similar to native version):
@ -417,6 +446,7 @@ static inline HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, MSHLFLAGS flags)
{
struct ifstub *stub;
HRESULT hr;
TRACE("oid=%s, stubbuffer=%p, iptr=%p, iid=%s\n",
wine_dbgstr_longlong(m->oid), sb, iptr, debugstr_guid(iid));
@ -424,6 +454,13 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
stub = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ifstub));
if (!stub) return NULL;
hr = RPC_CreateServerChannel(&stub->chan);
if (hr != S_OK)
{
HeapFree(GetProcessHeap(), 0, stub);
return NULL;
}
stub->stubbuffer = sb;
if (sb) IRpcStubBuffer_AddRef(sb);
@ -432,21 +469,10 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
stub->flags = flags;
stub->iid = *iid;
/*
* FIXME: this is a hack for marshalling IRemUnknown. In real
* DCOM, the IPID of the IRemUnknown interface is generated like
* any other and passed to the OXID resolver which then returns it
* when queried. We don't have an OXID resolver yet so instead we
* use a magic IPID reserved for IRemUnknown.
*/
if (IsEqualIID(iid, &IID_IRemUnknown))
{
stub->ipid.Data1 = 0xffffffff;
stub->ipid.Data2 = 0xffff;
stub->ipid.Data3 = 0xffff;
assert(sizeof(stub->ipid.Data4) == sizeof(m->apt->oxid));
memcpy(&stub->ipid.Data4, &m->apt->oxid, sizeof(OXID));
}
/* FIXME: find a cleaner way of identifying that we are creating an ifstub
* for the remunknown interface */
if (flags & MSHLFLAGSP_REMUNKNOWN)
stub->ipid = m->oxid_info.ipidRemUnknown;
else
generate_ipid(m, &stub->ipid);
@ -468,9 +494,10 @@ static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *if
list_remove(&ifstub->entry);
RPC_UnregisterInterface(&ifstub->iid);
if (ifstub->stubbuffer) IUnknown_Release(ifstub->stubbuffer);
IUnknown_Release(ifstub->iface);
IRpcChannelBuffer_Release(ifstub->chan);
HeapFree(GetProcessHeap(), 0, ifstub);
}
@ -516,10 +543,10 @@ void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const
if (ifstub->flags & MSHLFLAGS_TABLEWEAK)
refs = 0;
else
else if (ifstub->flags & MSHLFLAGS_TABLESTRONG)
refs = 1;
stub_manager_ext_release(m, refs);
stub_manager_ext_release(m, refs, TRUE);
}
/* is an ifstub table marshaled? */
@ -542,8 +569,6 @@ BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid)
* interacts with stub managers.
*/
const IID IID_IRemUnknown = { 0x00000131, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
typedef struct rem_unknown
{
const IRemUnknownVtbl *lpVtbl;
@ -592,7 +617,7 @@ static ULONG WINAPI RemUnknown_AddRef(IRemUnknown *iface)
refs = InterlockedIncrement(&This->refs);
TRACE("%p before: %ld\n", iface, refs-1);
TRACE("%p before: %d\n", iface, refs-1);
return refs;
}
@ -605,7 +630,7 @@ static ULONG WINAPI RemUnknown_Release(IRemUnknown *iface)
if (!refs)
HeapFree(GetProcessHeap(), 0, This);
TRACE("%p after: %ld\n", iface, refs);
TRACE("%p after: %d\n", iface, refs);
return refs;
}
@ -619,7 +644,7 @@ static HRESULT WINAPI RemUnknown_RemQueryInterface(IRemUnknown *iface,
APARTMENT *apt;
struct stub_manager *stubmgr;
TRACE("(%p)->(%s, %ld, %d, %p, %p)\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults);
TRACE("(%p)->(%s, %d, %d, %p, %p)\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults);
hr = ipid_to_stub_manager(ripid, &apt, &stubmgr);
if (hr != S_OK) return hr;
@ -701,7 +726,7 @@ static HRESULT WINAPI RemUnknown_RemRelease(IRemUnknown *iface,
break;
}
stub_manager_ext_release(stubmgr, InterfaceRefs[i].cPublicRefs);
stub_manager_ext_release(stubmgr, InterfaceRefs[i].cPublicRefs, TRUE);
if (InterfaceRefs[i].cPrivateRefs)
FIXME("Releasing %ld refs securely not implemented\n", InterfaceRefs[i].cPrivateRefs);
@ -723,7 +748,7 @@ static const IRemUnknownVtbl RemUnknown_Vtbl =
};
/* starts the IRemUnknown listener for the current apartment */
HRESULT start_apartment_remote_unknown()
HRESULT start_apartment_remote_unknown(void)
{
IRemUnknown *pRemUnknown;
HRESULT hr = S_OK;
@ -738,7 +763,7 @@ HRESULT start_apartment_remote_unknown()
{
STDOBJREF stdobjref; /* dummy - not used */
/* register it with the stub manager */
hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHLFLAGS_NORMAL);
hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHLFLAGS_NORMAL|MSHLFLAGSP_REMUNKNOWN);
/* release our reference to the object as the stub manager will manage the life cycle for us */
IRemUnknown_Release(pRemUnknown);
if (hr == S_OK)

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define WINE_OLESELFREGISTER

View File

@ -7,7 +7,7 @@ MODULE = oleaut32.dll
IMPORTLIB = liboleaut32.$(IMPLIBEXT)
IMPORTS = ole32 rpcrt4 user32 gdi32 advapi32 kernel32 ntdll
DELAYIMPORTS = comctl32 urlmon
EXTRALIBS = $(LIBUNICODE) -luuid
EXTRALIBS = -luuid
C_SRCS = \
connpt.c \
@ -24,6 +24,7 @@ C_SRCS = \
tmarshal.c \
typelib.c \
typelib2.c \
ungif.c \
usrmarshal.c \
varformat.c \
variant.c \
@ -39,8 +40,6 @@ SPEC_SRCS16 = \
RC_SRCS = oleaut32.rc
SUBDIRS = tests
@MAKE_DLL_RULES@
### Dependencies:
@DEPENDENCIES@ # everything below this line is overwritten by make depend

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES:
* See one exported function here is CreateConnectionPoint, see
@ -194,7 +194,7 @@ static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint* iface)
ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
TRACE("(%p)->(ref before=%ld)\n", This, refCount - 1);
TRACE("(%p)->(ref before=%d)\n", This, refCount - 1);
return refCount;
}
@ -210,7 +210,7 @@ static ULONG WINAPI ConnectionPointImpl_Release(
ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->ref);
TRACE("(%p)->(ref before=%ld)\n", This, refCount + 1);
TRACE("(%p)->(ref before=%d)\n", This, refCount + 1);
/*
* If the reference count goes down to 0, perform suicide.
@ -291,7 +291,7 @@ static HRESULT WINAPI ConnectionPointImpl_Unadvise(IConnectionPoint *iface,
DWORD dwCookie)
{
ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
TRACE("(%p)->(%ld)\n", This, dwCookie);
TRACE("(%p)->(%d)\n", This, dwCookie);
if(dwCookie == 0 || dwCookie > This->maxSinks) return E_INVALIDARG;
@ -463,7 +463,7 @@ static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface)
EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
TRACE("(%p)->(ref before=%ld)\n", This, refCount - 1);
TRACE("(%p)->(ref before=%d)\n", This, refCount - 1);
IUnknown_AddRef(This->pUnk);
return refCount;
@ -479,7 +479,7 @@ static ULONG WINAPI EnumConnectionsImpl_Release(IEnumConnections* iface)
EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->ref);
TRACE("(%p)->(ref before=%ld)\n", This, refCount + 1);
TRACE("(%p)->(ref before=%d)\n", This, refCount + 1);
IUnknown_Release(This->pUnk);
@ -501,7 +501,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections* iface,
{
EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
DWORD nRet = 0;
TRACE("(%p)->(%ld, %p, %p)\n", This, cConn, pCD, pEnum);
TRACE("(%p)->(%d, %p, %p)\n", This, cConn, pCD, pEnum);
if(pEnum == NULL) {
if(cConn != 1)
@ -535,7 +535,7 @@ static HRESULT WINAPI EnumConnectionsImpl_Skip(IEnumConnections* iface,
ULONG cSkip)
{
EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
TRACE("(%p)->(%ld)\n", This, cSkip);
TRACE("(%p)->(%d)\n", This, cSkip);
if(This->nCur + cSkip >= This->nConns)
return S_FALSE;

View File

@ -13,7 +13,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _CONNPT_H

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
@ -85,7 +85,7 @@ HRESULT WINAPI DispInvoke(
/******************************************************************************
* DispGetIDsOfNames (OLEAUT32.29)
*
* Convert a set of parameter names to DISPID's for DispInvoke().
* Convert a set of parameter names to DISPIDs for DispInvoke().
*
* RETURNS
* Success: S_OK.
@ -93,13 +93,13 @@ HRESULT WINAPI DispInvoke(
*
* NOTES
* This call defers to ITypeInfo_GetIDsOfNames(). The ITypeInfo interface passed
* as ptinfo contains the information to map names to DISPID's.
* as ptinfo contains the information to map names to DISPIDs.
*/
HRESULT WINAPI DispGetIDsOfNames(
ITypeInfo *ptinfo, /* [in] Object's type info */
OLECHAR **rgszNames, /* [in] Array of names to get DISPID's for */
OLECHAR **rgszNames, /* [in] Array of names to get DISPIDs for */
UINT cNames, /* [in] Number of names in rgszNames */
DISPID *rgdispid) /* [out] Destination for converted DISPID's */
DISPID *rgdispid) /* [out] Destination for converted DISPIDs */
{
return ITypeInfo_GetIDsOfNames(ptinfo, rgszNames, cNames, rgdispid);
}
@ -107,7 +107,7 @@ HRESULT WINAPI DispGetIDsOfNames(
/******************************************************************************
* DispGetParam (OLEAUT32.28)
*
* Retrive a parameter from a DISPPARAMS structure and coerce it to the
* Retrieve a parameter from a DISPPARAMS structure and coerce it to the
* specified variant type.
*
* NOTES
@ -203,10 +203,10 @@ HRESULT WINAPI CreateStdDispatch(
* to simplify the process of calling an objects methods through IDispatch.
*
* A standard implementation of an IDispatch object is created by calling
* CreateStdDispatch(). Numeric Id values for the parameters and methods (DISPID's)
* CreateStdDispatch(). Numeric Id values for the parameters and methods (DISPIDs)
* of an object of interest are retrieved by calling DispGetIDsOfNames(). DispGetParam()
* retrieves information about a particular parameter. Finally the DispInvoke()
* function is responsable for actually calling methods on an object.
* function is responsible for actually calling methods on an object.
*
* METHODS
*/
@ -252,7 +252,7 @@ static ULONG WINAPI StdDispatch_AddRef(LPDISPATCH iface)
StdDispatch *This = (StdDispatch *)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
TRACE("(%p)->(ref before=%lu)\n",This, refCount - 1);
TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);
return refCount;
}
@ -267,7 +267,7 @@ static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface)
StdDispatch *This = (StdDispatch *)iface;
ULONG refCount = InterlockedDecrement(&This->ref);
TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1);
TRACE("(%p)->(ref before=%u)\n", This, refCount + 1);
if (!refCount)
{
@ -325,7 +325,7 @@ static HRESULT WINAPI StdDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pcti
static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
{
StdDispatch *This = (StdDispatch *)iface;
TRACE("(%d, %lx, %p)\n", iTInfo, lcid, ppTInfo);
TRACE("(%d, %x, %p)\n", iTInfo, lcid, ppTInfo);
*ppTInfo = NULL;
if (iTInfo != 0)
@ -342,7 +342,7 @@ static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCI
/******************************************************************************
* IDispatch_GetIDsOfNames {OLEAUT32}
*
* Convert a methods name and an optional set of parameter names into DISPID's
* Convert a methods name and an optional set of parameter names into DISPIDs
* for passing to IDispatch_Invoke().
*
* PARAMS
@ -351,13 +351,13 @@ static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCI
* rgszNames [I] Name to convert
* cNames [I] Number of names in rgszNames
* lcid [I] Locale of the type information to convert from
* rgDispId [O] Destination for converted DISPID's.
* rgDispId [O] Destination for converted DISPIDs.
*
* RETURNS
* Success: S_OK.
* Failure: DISP_E_UNKNOWNNAME, if any of the names is invalid.
* DISP_E_UNKNOWNLCID if lcid is invalid.
* Otherwise, an An HRESULT error code.
* Otherwise, an HRESULT error code.
*
* NOTES
* This call defers to ITypeInfo_GetIDsOfNames(), using the ITypeInfo object
@ -368,7 +368,7 @@ static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCI
static HRESULT WINAPI StdDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId)
{
StdDispatch *This = (StdDispatch *)iface;
TRACE("(%s, %p, %d, 0x%lx, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
TRACE("(%s, %p, %d, 0x%x, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
if (!IsEqualGUID(riid, &IID_NULL))
{
@ -406,7 +406,7 @@ static HRESULT WINAPI StdDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember,
EXCEPINFO * pExcepInfo, UINT * puArgErr)
{
StdDispatch *This = (StdDispatch *)iface;
TRACE("(%ld, %s, 0x%lx, 0x%x, %p, %p, %p, %p)\n", dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
TRACE("(%d, %s, 0x%x, 0x%x, %p, %p, %p, %p)\n", dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
if (!IsEqualGUID(riid, &IID_NULL))
{

View File

@ -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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
@ -517,7 +517,7 @@ ULONG WINAPI LHashValOfNameSysA( SYSKIND skind, LCID lcid, LPCSTR lpStr)
switch (PRIMARYLANGID(LANGIDFROMLCID(lcid)))
{
default:
ERR("Unknown lcid %lx, treating as latin-based, please report\n", lcid);
ERR("Unknown lcid %x, treating as latin-based, please report\n", lcid);
/* .. Fall Through .. */
case LANG_AFRIKAANS: case LANG_ALBANIAN: case LANG_ARMENIAN:
case LANG_ASSAMESE: case LANG_AZERI: case LANG_BASQUE:
@ -608,13 +608,7 @@ ULONG WINAPI LHashValOfNameSysA( SYSKIND skind, LCID lcid, LPCSTR lpStr)
while (*str)
{
ULONG newLoWord = 0, i;
/* Cumulative prime multiplication (*37) with modulo 2^32 wrap-around */
for (i = 0; i < 37; i++)
newLoWord += nLoWord;
nLoWord = newLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str];
nLoWord = 37 * nLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str];
str++;
}
/* Constrain to a prime modulo and sizeof(WORD) */

View File

@ -13702,7 +13702,7 @@ static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =
}
};
static const CInterfaceProxyVtbl * _oaidl_ProxyVtblList[] =
static const CInterfaceProxyVtbl * const _oaidl_ProxyVtblList[] =
{
( const CInterfaceProxyVtbl *) &_IDispatchProxyVtbl,
( const CInterfaceProxyVtbl *) &_ITypeInfoProxyVtbl,
@ -13718,7 +13718,7 @@ static const CInterfaceProxyVtbl * _oaidl_ProxyVtblList[] =
0
};
static const CInterfaceStubVtbl * _oaidl_StubVtblList[] =
static const CInterfaceStubVtbl * const _oaidl_StubVtblList[] =
{
( const CInterfaceStubVtbl *) &_IDispatchStubVtbl,
( const CInterfaceStubVtbl *) &_ITypeInfoStubVtbl,

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -220,7 +220,7 @@ HRESULT WINAPI CreateDispTypeInfo16(
LCID lcid,
ITypeInfo **pptinfo)
{
FIXME("(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
FIXME("(%p,%d,%p),stub\n",pidata,lcid,pptinfo);
return E_NOTIMPL;
}
@ -244,6 +244,6 @@ HRESULT WINAPI CreateStdDispatch16(
HRESULT WINAPI RegisterActiveObject16(
IUnknown *punk, REFCLSID rclsid, DWORD dwFlags, unsigned long *pdwRegister
) {
FIXME("(%p,%s,0x%08lx,%p):stub\n",punk,debugstr_guid(rclsid),dwFlags,pdwRegister);
FIXME("(%p,%s,0x%08x,%p):stub\n",punk,debugstr_guid(rclsid),dwFlags,pdwRegister);
return E_NOTIMPL;
}

View File

@ -13,7 +13,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_OLEAUT32_OLE2DISP_H

View File

@ -15,11 +15,12 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include <limits.h>
#define COBJMACROS
@ -38,15 +39,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
extern const GUID CLSID_PSOAInterface;
extern const GUID CLSID_PSDispatch;
extern const GUID CLSID_PSEnumVariant;
extern const GUID CLSID_PSTypeInfo;
extern const GUID CLSID_PSTypeLib;
extern const GUID CLSID_PSTypeComp;
static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
HMODULE OLEAUT32_hModule = NULL;
@ -226,8 +218,11 @@ BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
DWORD* newBuffer;
WCHAR* stringBuffer;
/* Detect integer overflow. */
if (len >= ((UINT_MAX-sizeof(WCHAR)-sizeof(DWORD))/sizeof(WCHAR)))
return NULL;
/*
* Find the length of the buffer passed-in in bytes.
* Find the length of the buffer passed-in, in bytes.
*/
bufferSize = len * sizeof (WCHAR);
@ -243,8 +238,8 @@ BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
/*
* If the memory allocation failed, return a null pointer.
*/
if (newBuffer==0)
return 0;
if (!newBuffer)
return NULL;
/*
* Copy the length of the string in the placeholder.
@ -629,7 +624,7 @@ HRESULT WINAPI OleTranslateColor(
COLORREF colorref;
BYTE b = HIBYTE(HIWORD(clr));
TRACE("(%08lx, %p, %p)\n", clr, hpal, pColorRef);
TRACE("(%08x, %p, %p)\n", clr, hpal, pColorRef);
/*
* In case pColorRef is NULL, provide our own to simplify the code.
@ -829,7 +824,7 @@ HRESULT WINAPI DllCanUnloadNow(void)
*/
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
TRACE("(%p,%ld,%p)\n", hInstDll, fdwReason, lpvReserved);
TRACE("(%p,%d,%p)\n", hInstDll, fdwReason, lpvReserved);
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
@ -842,3 +837,13 @@ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
return TRUE;
}
/***********************************************************************
* OleIconToCursor (OLEAUT32.415)
*/
HCURSOR WINAPI OleIconToCursor( HINSTANCE hinstExe, HICON hIcon)
{
FIXME("(%p,%p), partially implemented.\n",hinstExe,hIcon);
/* FIXME: make a extended conversation from HICON to HCURSOR */
return CopyCursor(hIcon);
}

View File

@ -39,6 +39,7 @@
<file>usrmarshal.c</file>
<file>varformat.c</file>
<file>variant.c</file>
<file>ungif.c</file>
<file>vartype.c</file>
<file>oleaut32.spec</file>
</module>

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "windef.h"
@ -28,13 +28,12 @@
#include "oleaut32_De.rc"
#include "oleaut32_Dk.rc"
#include "oleaut32_En.rc"
#include "oleaut32_Eo.rc"
#include "oleaut32_Es.rc"
#include "oleaut32_Cz.rc"
#include "oleaut32_Fr.rc"
#include "oleaut32_Gr.rc"
#include "oleaut32_Hu.rc"
#include "oleaut32_It.rc"
#include "oleaut32_Ja.rc"
#include "oleaut32_Ko.rc"
#include "oleaut32_Nl.rc"
#include "oleaut32_No.rc"
@ -44,7 +43,6 @@
#include "oleaut32_Sv.rc"
#include "oleaut32_Th.rc"
#include "oleaut32_Tr.rc"
#include "oleaut32_Uk.rc"
/*
* FIXME:

View File

@ -148,7 +148,7 @@
150 stdcall SysAllocStringByteLen(ptr long)
152 stdcall VarEqv(ptr ptr ptr)
153 stdcall VarIdiv(ptr ptr ptr)
154 stub VarImp # stdcall (ptr ptr ptr)
154 stdcall VarImp(ptr ptr ptr)
155 stdcall VarMod(ptr ptr ptr)
156 stdcall VarMul(ptr ptr ptr)
157 stdcall VarOr(ptr ptr ptr)

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT

View File

@ -15,10 +15,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_DANISH, SUBLANG_DEFAULT

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT

View File

@ -1,7 +1,7 @@
/*
* Declarations for OLE2
* Oleaut32 - Esperanto Language Support
*
* Copyright (C) the Wine project
* Copyright 2006 Antonio Codazzi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -15,23 +15,17 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include_next <ole2.h>
#include <unknwn.h> /* for LPUNKNOWN */
LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT
#ifndef __WINE_OLE2_H
#define __WINE_OLE2_H
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
BOOL WINAPI IsValidInterface(LPUNKNOWN punk);
#ifdef __cplusplus
} /* extern "C" */
#endif /* defined(__cplusplus) */
#endif /* __WINE_OLE2_H */
STRINGTABLE DISCARDABLE
{
IDS_TRUE "Vere"
IDS_FALSE "False"
IDS_YES "Jes"
IDS_NO "Ne"
IDS_ON "Kondukta"
IDS_OFF "Elkluda"
}

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL

View File

@ -2,7 +2,6 @@
* Hungarian resources for oleaut32
*
* Copyright 2003 Jon Griffiths
* Hungarian translation by ???
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -16,10 +15,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_HUNGARIAN, SUBLANG_NEUTRAL
LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
{

View File

@ -15,10 +15,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{

View File

@ -15,10 +15,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{

View File

@ -15,10 +15,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT
LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{

View File

@ -15,10 +15,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_NORWEGIAN, SUBLANG_DEFAULT
LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
STRINGTABLE DISCARDABLE
{

View File

@ -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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT

View File

@ -15,10 +15,10 @@
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT
LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
STRINGTABLE DISCARDABLE
{

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
@ -26,6 +26,6 @@ STRINGTABLE DISCARDABLE
IDS_FALSE "Falskt"
IDS_YES "Ja"
IDS_NO "Nej"
IDS_ON "På"
IDS_ON "PÕ"
IDS_OFF "Av"
}

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_THAI, SUBLANG_DEFAULT

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* BUGS
*
@ -48,16 +48,6 @@
/* Must be before wine includes, the header has things conflicting with
* WINE headers.
*/
#ifdef HAVE_GIF_LIB_H
# include <gif_lib.h>
# ifndef SONAME_LIBUNGIF
# define SONAME_LIBUNGIF "libungif.so"
# endif
# ifndef SONAME_LIBGIF
# define SONAME_LIBGIF "libgif.so"
# endif
#endif
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
@ -83,13 +73,17 @@
#define UINT8 JPEG_UINT8
#define UINT16 JPEG_UINT16
#undef FAR
#define boolean jpeg_boolean
# include <jpeglib.h>
#undef jpeg_boolean
#undef UINT16
#ifndef SONAME_LIBJPEG
#define SONAME_LIBJPEG "libjpeg.so"
#endif
#endif
#include "ungif.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
#include "pshpack1.h"
@ -306,12 +300,8 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
newObject->bIsDirty = FALSE;
if (pictDesc) {
if(pictDesc->cbSizeofstruct != sizeof(PICTDESC)) {
FIXME("struct size = %d\n", pictDesc->cbSizeofstruct);
}
memcpy(&newObject->desc, pictDesc, sizeof(PICTDESC));
switch(pictDesc->picType) {
case PICTYPE_BITMAP:
OLEPictureImpl_SetBitmap(newObject);
@ -398,7 +388,7 @@ static ULONG WINAPI OLEPictureImpl_AddRef(
OLEPictureImpl *This = (OLEPictureImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
TRACE("(%p)->(ref before=%ld)\n", This, refCount - 1);
TRACE("(%p)->(ref before=%d)\n", This, refCount - 1);
return refCount;
}
@ -414,7 +404,7 @@ static ULONG WINAPI OLEPictureImpl_Release(
OLEPictureImpl *This = (OLEPictureImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->ref);
TRACE("(%p)->(ref before=%ld)\n", This, refCount + 1);
TRACE("(%p)->(ref before=%d)\n", This, refCount + 1);
/*
* If the reference count goes down to 0, perform suicide.
@ -451,30 +441,17 @@ static HRESULT WINAPI OLEPictureImpl_QueryInterface(
/*
* Compare the riid with the interface IDs implemented by this object.
*/
if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
{
if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IPicture, riid))
*ppvObject = (IPicture*)This;
}
else if (memcmp(&IID_IPicture, riid, sizeof(IID_IPicture)) == 0)
{
*ppvObject = (IPicture*)This;
}
else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
{
else if (IsEqualIID(&IID_IDispatch, riid))
*ppvObject = (IDispatch*)&(This->lpvtblIDispatch);
}
else if (memcmp(&IID_IPictureDisp, riid, sizeof(IID_IPictureDisp)) == 0)
{
else if (IsEqualIID(&IID_IPictureDisp, riid))
*ppvObject = (IDispatch*)&(This->lpvtblIDispatch);
}
else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
{
*ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
}
else if (memcmp(&IID_IConnectionPointContainer, riid, sizeof(IID_IConnectionPointContainer)) == 0)
{
*ppvObject = (IConnectionPointContainer*)&(This->lpvtblIConnectionPointContainer);
}
else if (IsEqualIID(&IID_IPersist, riid) || IsEqualIID(&IID_IPersistStream, riid))
*ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
else if (IsEqualIID(&IID_IConnectionPointContainer, riid))
*ppvObject = (IConnectionPointContainer*)&(This->lpvtblIConnectionPointContainer);
/*
* Check that we obtained an interface.
*/
@ -583,7 +560,7 @@ static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
hres = S_OK;
}
TRACE("returning 0x%08lx, palette handle %08x\n", hres, *phandle);
TRACE("returning 0x%08x, palette handle %08x\n", hres, *phandle);
return hres;
}
@ -606,7 +583,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface,
OLE_XSIZE_HIMETRIC *pwidth)
{
OLEPictureImpl *This = (OLEPictureImpl *)iface;
TRACE("(%p)->(%p): width is %ld\n", This, pwidth, This->himetricWidth);
TRACE("(%p)->(%p): width is %d\n", This, pwidth, This->himetricWidth);
*pwidth = This->himetricWidth;
return S_OK;
}
@ -618,7 +595,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface,
OLE_YSIZE_HIMETRIC *pheight)
{
OLEPictureImpl *This = (OLEPictureImpl *)iface;
TRACE("(%p)->(%p): height is %ld\n", This, pheight, This->himetricHeight);
TRACE("(%p)->(%p): height is %d\n", This, pheight, This->himetricHeight);
*pheight = This->himetricHeight;
return S_OK;
}
@ -635,10 +612,10 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
LPCRECT prcWBounds)
{
OLEPictureImpl *This = (OLEPictureImpl *)iface;
TRACE("(%p)->(%p, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
TRACE("(%p)->(%p, (%d,%d), (%d,%d) <- (%d,%d), (%d,%d), %p)\n",
This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, prcWBounds);
if(prcWBounds)
TRACE("prcWBounds (%ld,%ld) - (%ld,%ld)\n", prcWBounds->left, prcWBounds->top,
TRACE("prcWBounds (%d,%d) - (%d,%d)\n", prcWBounds->left, prcWBounds->top,
prcWBounds->right, prcWBounds->bottom);
/*
@ -932,9 +909,9 @@ static ULONG WINAPI OLEPictureImpl_IPersistStream_Release(
static HRESULT WINAPI OLEPictureImpl_GetClassID(
IPersistStream* iface,CLSID* pClassID)
{
OLEPictureImpl *This = impl_from_IPersistStream(iface);
FIXME("(%p),stub!\n",This);
return E_FAIL;
TRACE("(%p)\n", pClassID);
memcpy(pClassID, &CLSID_StdPicture, sizeof(*pClassID));
return S_OK;
}
/************************************************************************
@ -1004,41 +981,12 @@ static boolean _jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired) {
static void _jpeg_term_source(j_decompress_ptr cinfo) { }
#endif /* HAVE_JPEGLIB_H */
#ifdef HAVE_GIF_LIB_H
static void *libungif_handle;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR(DGifOpen);
MAKE_FUNCPTR(DGifSlurp);
MAKE_FUNCPTR(DGifCloseFile);
#undef MAKE_FUNCPTR
struct gifdata {
unsigned char *data;
unsigned int curoff;
unsigned int len;
};
static void *load_libungif(void)
{
if(((libungif_handle = wine_dlopen(SONAME_LIBUNGIF, RTLD_NOW, NULL, 0)) != NULL) ||
((libungif_handle = wine_dlopen(SONAME_LIBGIF , RTLD_NOW, NULL, 0)) != NULL)
) {
#define LOAD_FUNCPTR(f) \
if((p##f = wine_dlsym(libungif_handle, #f, NULL, 0)) == NULL) { \
libungif_handle = NULL; \
return NULL; \
}
LOAD_FUNCPTR(DGifOpen);
LOAD_FUNCPTR(DGifSlurp);
LOAD_FUNCPTR(DGifCloseFile);
#undef LOAD_FUNCPTR
}
return libungif_handle;
}
static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len) {
struct gifdata *gd = (struct gifdata*)gif->UserData;
@ -1051,12 +999,9 @@ static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len) {
return len;
}
#endif /* HAVE_GIF_LIB_H */
static HRESULT OLEPictureImpl_LoadGif(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
{
#ifdef HAVE_GIF_LIB_H
struct gifdata gd;
GifFileType *gif;
BITMAPINFO *bmi;
@ -1070,18 +1015,11 @@ static HRESULT OLEPictureImpl_LoadGif(OLEPictureImpl *This, BYTE *xbuf, ULONG xr
ExtensionBlock *eb;
int padding;
if(!libungif_handle) {
if(!load_libungif()) {
FIXME("Failed reading GIF because unable to find %s/%s\n", SONAME_LIBUNGIF, SONAME_LIBGIF);
return E_FAIL;
}
}
gd.data = xbuf;
gd.curoff = 0;
gd.len = xread;
gif = pDGifOpen((void*)&gd, _gif_inputfunc);
ret = pDGifSlurp(gif);
gif = DGifOpen((void*)&gd, _gif_inputfunc);
ret = DGifSlurp(gif);
if (ret == GIF_ERROR) {
FIXME("Failed reading GIF using libgif.\n");
return E_FAIL;
@ -1253,13 +1191,9 @@ static HRESULT OLEPictureImpl_LoadGif(OLEPictureImpl *This, BYTE *xbuf, ULONG xr
DeleteDC(hdcref);
This->desc.picType = PICTYPE_BITMAP;
OLEPictureImpl_SetBitmap(This);
pDGifCloseFile(gif);
DGifCloseFile(gif);
HeapFree(GetProcessHeap(),0,bytes);
return S_OK;
#else
FIXME("Trying to load GIF, but no support for libgif/libungif compiled in.\n");
return E_FAIL;
#endif
}
static HRESULT OLEPictureImpl_LoadJpeg(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
@ -1466,6 +1400,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
BOOL headerisdata = FALSE;
BOOL statfailed = FALSE;
ULONG xread, toread;
ULONG headerread;
BYTE *xbuf;
DWORD header[2];
WORD magic;
@ -1492,36 +1427,48 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
*/
hr=IStream_Stat(pStm,&statstg,STATFLAG_NONAME);
if (hr) {
TRACE("stat failed with hres %lx, proceeding to read all data.\n",hr);
TRACE("stat failed with hres %x, proceeding to read all data.\n",hr);
statfailed = TRUE;
/* we will read at least 8 byte ... just right below */
statstg.cbSize.QuadPart = 8;
}
hr=IStream_Read(pStm,header,8,&xread);
if (hr || xread!=8) {
FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr,xread);
return hr;
}
toread = 0;
headerread = 0;
headerisdata = FALSE;
xread = 0;
if (!memcmp(&(header[0]),"lt\0\0", 4) && (header[1] <= statstg.cbSize.QuadPart-8)) {
toread = header[1];
} else {
if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */
!memcmp(&(header[0]), "BM", 2) || /* BMP header */
!memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */
(header[1] > statstg.cbSize.QuadPart)|| /* invalid size */
(header[1]==0)
) {/* Incorrect header, assume none. */
headerisdata = TRUE;
toread = statstg.cbSize.QuadPart-8;
xread = 8;
} else {
FIXME("Unknown stream header magic: %08lx\n", header[0]);
toread = header[1];
do {
hr=IStream_Read(pStm,header,8,&xread);
if (hr || xread!=8) {
FIXME("Failure while reading picture header (hr is %x, nread is %d).\n",hr,xread);
return hr;
}
}
headerread += xread;
xread = 0;
if (!memcmp(&(header[0]),"lt\0\0", 4) && (statfailed || (header[1] + headerread <= statstg.cbSize.QuadPart))) {
if (toread != 0 && toread != header[1])
FIXME("varying lengths of image data (prev=%u curr=%u), only last one will be used\n",
toread, header[1]);
toread = header[1];
if (toread == 0) break;
} else {
if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */
!memcmp(&(header[0]), "BM", 2) || /* BMP header */
!memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */
(header[1] > statstg.cbSize.QuadPart)|| /* invalid size */
(header[1]==0)
) {/* Found start of bitmap data */
headerisdata = TRUE;
if (toread == 0)
toread = statstg.cbSize.QuadPart-8;
else toread -= 8;
xread = 8;
} else {
FIXME("Unknown stream header magic: %08x\n", header[0]);
toread = header[1];
}
}
} while (!headerisdata);
if (statfailed) { /* we don't know the size ... read all we get */
int sizeinc = 4096;
@ -1548,8 +1495,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
}
}
if (hr)
TRACE("hr in no-stat loader case is %08lx\n", hr);
TRACE("loaded %ld bytes.\n", xread);
TRACE("hr in no-stat loader case is %08x\n", hr);
TRACE("loaded %d bytes.\n", xread);
This->datalen = xread;
This->data = xbuf;
} else {
@ -1567,7 +1514,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
break;
}
if (xread != This->datalen)
FIXME("Could only read %ld of %d bytes out of stream?\n",xread,This->datalen);
FIXME("Could only read %d of %d bytes out of stream?\n",xread,This->datalen);
}
if (This->datalen == 0) { /* Marks the "NONE" picture */
This->desc.picType = PICTYPE_NONE;
@ -1597,7 +1544,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
default:
{
unsigned int i;
FIXME("Unknown magic %04x, %ld read bytes:\n",magic,xread);
FIXME("Unknown magic %04x, %d read bytes:\n",magic,xread);
hr=E_FAIL;
for (i=0;i<xread+8;i++) {
if (i<8) MESSAGE("%02x ",((unsigned char*)&header)[i]);
@ -1722,7 +1669,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
pInfoBitmap->bmiHeader.biBitCount);
FIXME("DEBUG: bitmap nplanes is %d\n",
pInfoBitmap->bmiHeader.biPlanes);
FIXME("DEBUG: bitmap biSizeImage is %lu\n",
FIXME("DEBUG: bitmap biSizeImage is %u\n",
pInfoBitmap->bmiHeader.biSizeImage);
*/
/* Let's start with one CURSORICONFILEDIR and one CURSORICONFILEDIRENTRY */
@ -1797,7 +1744,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
&& GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight,
pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS))) {
printf("ERROR: unable to get bitmap mask (error %lu)\n",
printf("ERROR: unable to get bitmap mask (error %u)\n",
GetLastError());
}
@ -1810,7 +1757,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
iSuccess = 1;
} else {
/*
printf("ERROR: unable to get bitmap information via GetDIBits() (error %lu)\n",
printf("ERROR: unable to get bitmap information via GetDIBits() (error %u)\n",
GetLastError());
*/
}
@ -1827,7 +1774,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
if (infoIcon.hbmColor) DeleteObject(infoIcon.hbmColor);
HeapFree(GetProcessHeap(), 0, pInfoBitmap);
} else {
printf("ERROR: Unable to get icon information (error %lu)\n",
printf("ERROR: Unable to get icon information (error %u)\n",
GetLastError());
}
return iSuccess;
@ -1841,41 +1788,32 @@ static HRESULT WINAPI OLEPictureImpl_Save(
unsigned int iDataSize;
ULONG dummy;
int iSerializeResult = 0;
OLEPictureImpl *This = impl_from_IPersistStream(iface);
OLEPictureImpl *This = impl_from_IPersistStream(iface);
TRACE("%p %p %d\n", This, pStm, fClearDirty);
switch (This->desc.picType) {
case PICTYPE_ICON:
if (This->bIsDirty) {
if (serializeIcon(This->desc.u.icon.hicon, &pIconData, &iDataSize)) {
if (This->loadtime_magic != 0xdeadbeef) {
DWORD header[2];
header[0] = This->loadtime_magic;
header[1] = iDataSize;
IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
}
IStream_Write(pStm, pIconData, iDataSize, &dummy);
HeapFree(GetProcessHeap(), 0, This->data);
This->data = pIconData;
This->datalen = iDataSize;
hResult = S_OK;
} else {
FIXME("(%p,%p,%d), unable to serializeIcon()!\n",This,pStm,fClearDirty);
if (This->bIsDirty || !This->data) {
if (!serializeIcon(This->desc.u.icon.hicon, &pIconData, &iDataSize)) {
ERR("(%p,%p,%d), serializeIcon() failed\n", This, pStm, fClearDirty);
hResult = E_FAIL;
break;
}
} else {
if (This->loadtime_magic != 0xdeadbeef) {
DWORD header[2];
header[0] = This->loadtime_magic;
header[1] = This->datalen;
IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
}
IStream_Write(pStm, This->data, This->datalen, &dummy);
hResult = S_OK;
HeapFree(GetProcessHeap(), 0, This->data);
This->data = pIconData;
This->datalen = iDataSize;
}
if (This->loadtime_magic != 0xdeadbeef) {
DWORD header[2];
header[0] = This->loadtime_magic;
header[1] = This->datalen;
IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
}
IStream_Write(pStm, This->data, This->datalen, &dummy);
hResult = S_OK;
break;
case PICTYPE_BITMAP:
if (This->bIsDirty) {
@ -2003,9 +1941,11 @@ static HRESULT WINAPI OLEPictureImpl_GetTypeInfoCount(
IDispatch* iface,
unsigned int* pctinfo)
{
FIXME("():Stub\n");
TRACE("(%p)\n", pctinfo);
return E_NOTIMPL;
*pctinfo = 1;
return S_OK;
}
/************************************************************************
@ -2019,9 +1959,27 @@ static HRESULT WINAPI OLEPictureImpl_GetTypeInfo(
LCID lcid,
ITypeInfo** ppTInfo)
{
FIXME("():Stub\n");
static const WCHAR stdole2tlb[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
ITypeLib *tl;
HRESULT hres;
return E_NOTIMPL;
TRACE("(iTInfo=%d, lcid=%04x, %p)\n", iTInfo, (int)lcid, ppTInfo);
if (iTInfo != 0)
return E_FAIL;
hres = LoadTypeLib(stdole2tlb, &tl);
if (FAILED(hres))
{
ERR("Could not load stdole2.tlb\n");
return hres;
}
hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IPictureDisp, ppTInfo);
if (FAILED(hres))
ERR("Did not get IPictureDisp typeinfo from typelib, hres %x\n", hres);
return hres;
}
/************************************************************************
@ -2059,30 +2017,105 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
UINT* puArgErr)
{
OLEPictureImpl *This = impl_from_IDispatch(iface);
if (dispIdMember == DISPID_PICT_TYPE)
{
TRACE("DISPID_PICT_TYPE\n");
if (!(wFlags & INVOKE_PROPERTYGET))
return DISP_E_PARAMNOTFOUND;
if (pDispParams->cArgs != 0)
return DISP_E_BADPARAMCOUNT;
if (pVarResult)
{
VariantInit(pVarResult);
V_VT(pVarResult) = VT_I2;
return OLEPictureImpl_get_Type((IPicture *)&This->lpVtbl, &V_I2(pVarResult));
}
return S_OK;
}
else
{
FIXME("(dispid: %ld):Stub\n",dispIdMember);
VariantInit(pVarResult);
V_VT(pVarResult) = VT_BOOL;
V_BOOL(pVarResult) = FALSE;
return S_OK;
/* validate parameters */
if (!IsEqualIID(riid, &IID_NULL))
{
ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid));
return DISP_E_UNKNOWNNAME;
}
if (!pDispParams)
{
ERR("null pDispParams not allowed\n");
return DISP_E_PARAMNOTOPTIONAL;
}
if (wFlags & DISPATCH_PROPERTYGET)
{
if (pDispParams->cArgs != 0)
{
ERR("param count for DISPATCH_PROPERTYGET was %d instead of 0\n", pDispParams->cArgs);
return DISP_E_BADPARAMCOUNT;
}
if (!pVarResult)
{
ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
return DISP_E_PARAMNOTOPTIONAL;
}
}
else if (wFlags & DISPATCH_PROPERTYPUT)
{
if (pDispParams->cArgs != 1)
{
ERR("param count for DISPATCH_PROPERTYPUT was %d instead of 1\n", pDispParams->cArgs);
return DISP_E_BADPARAMCOUNT;
}
}
switch (dispIdMember)
{
case DISPID_PICT_HANDLE:
if (wFlags & DISPATCH_PROPERTYGET)
{
TRACE("DISPID_PICT_HANDLE\n");
V_VT(pVarResult) = VT_I4;
return IPicture_get_Handle((IPicture *)&This->lpVtbl, &V_UINT(pVarResult));
}
break;
case DISPID_PICT_HPAL:
if (wFlags & DISPATCH_PROPERTYGET)
{
TRACE("DISPID_PICT_HPAL\n");
V_VT(pVarResult) = VT_I4;
return IPicture_get_hPal((IPicture *)&This->lpVtbl, &V_UINT(pVarResult));
}
else if (wFlags & DISPATCH_PROPERTYPUT)
{
VARIANTARG vararg;
HRESULT hr;
TRACE("DISPID_PICT_HPAL\n");
VariantInit(&vararg);
hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I4);
if (FAILED(hr))
return hr;
hr = IPicture_set_hPal((IPicture *)&This->lpVtbl, V_I4(&vararg));
VariantClear(&vararg);
return hr;
}
break;
case DISPID_PICT_TYPE:
if (wFlags & DISPATCH_PROPERTYGET)
{
TRACE("DISPID_PICT_TYPE\n");
V_VT(pVarResult) = VT_I2;
return OLEPictureImpl_get_Type((IPicture *)&This->lpVtbl, &V_I2(pVarResult));
}
break;
case DISPID_PICT_WIDTH:
if (wFlags & DISPATCH_PROPERTYGET)
{
TRACE("DISPID_PICT_WIDTH\n");
V_VT(pVarResult) = VT_I4;
return IPicture_get_Width((IPicture *)&This->lpVtbl, &V_I4(pVarResult));
}
break;
case DISPID_PICT_HEIGHT:
if (wFlags & DISPATCH_PROPERTYGET)
{
TRACE("DISPID_PICT_HEIGHT\n");
V_VT(pVarResult) = VT_I4;
return IPicture_get_Height((IPicture *)&This->lpVtbl, &V_I4(pVarResult));
}
break;
}
ERR("invalid dispid 0x%x or wFlags 0x%x\n", dispIdMember, wFlags);
return DISP_E_MEMBERNOTFOUND;
}
@ -2148,7 +2181,7 @@ HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid,
OLEPictureImpl* newPict = NULL;
HRESULT hr = S_OK;
TRACE("(%p,%p,%d,%p)\n", lpPictDesc, riid, fOwn, ppvObj);
TRACE("(%p,%s,%d,%p)\n", lpPictDesc, debugstr_guid(riid), fOwn, ppvObj);
/*
* Sanity check
@ -2191,7 +2224,7 @@ HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
IPicture *newpic;
HRESULT hr;
TRACE("(%p,%ld,%d,%s,%p), partially implemented.\n",
TRACE("(%p,%d,%d,%s,%p), partially implemented.\n",
lpstream, lSize, fRunmode, debugstr_guid(riid), ppvObj);
hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
@ -2223,7 +2256,7 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
IPicture *newpic;
HRESULT hr;
FIXME("(%p,%ld,%d,%s,x=%ld,y=%ld,f=%lx,%p), partially implemented.\n",
FIXME("(%p,%d,%d,%s,x=%d,y=%d,f=%x,%p), partially implemented.\n",
lpstream, lSize, fRunmode, debugstr_guid(riid), xsiz, ysiz, flags, ppvObj);
hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
@ -2263,7 +2296,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
IPersistStream *pStream;
HRESULT hRes;
TRACE("(%s,%p,%ld,%08lx,%s,%p): stub\n",
TRACE("(%s,%p,%d,%08x,%s,%p): stub\n",
debugstr_w(szURLorPath), punkCaller, dwReserved, clrReserved,
debugstr_guid(riid), ppvRet);

View File

@ -13,7 +13,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
@ -157,7 +157,7 @@ static ULONG WINAPI IRecordInfoImpl_AddRef(IRecordInfo *iface)
{
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) -> %ld\n", This, ref);
TRACE("(%p) -> %d\n", This, ref);
return ref;
}
@ -166,7 +166,7 @@ static ULONG WINAPI IRecordInfoImpl_Release(IRecordInfo *iface)
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) -> %ld\n", This, ref);
TRACE("(%p) -> %d\n", This, ref);
if(!ref) {
int i;
@ -365,7 +365,7 @@ static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags,
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
int i;
TRACE("(%p)->(%08lx %p %s %p)\n", This, wFlags, pvData, debugstr_w(szFieldName),
TRACE("(%p)->(%08x %p %s %p)\n", This, wFlags, pvData, debugstr_w(szFieldName),
pvarField);
if(!pvData || !szFieldName || !pvarField
@ -393,7 +393,7 @@ static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG w
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
int i;
FIXME("(%p)->(%08lx %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField);
FIXME("(%p)->(%08x %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField);
if(!pvData || !szFieldName || !pvarField
|| (wFlags != INVOKE_PROPERTYPUTREF && wFlags != INVOKE_PROPERTYPUT))
@ -512,7 +512,7 @@ HRESULT WINAPI GetRecordInfoFromGuids(REFGUID rGuidTypeLib, ULONG uVerMajor,
ITypeLib *pTypeLib;
HRESULT hres;
TRACE("(%p,%ld,%ld,%ld,%p,%p)\n", rGuidTypeLib, uVerMajor, uVerMinor,
TRACE("(%p,%d,%d,%d,%p,%p)\n", rGuidTypeLib, uVerMajor, uVerMinor,
lcid, rGuidTypeInfo, ppRecInfo);
hres = LoadRegTypeLib(rGuidTypeLib, uVerMajor, uVerMinor, lcid, &pTypeLib);
@ -551,7 +551,7 @@ HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo
hres = ITypeInfo_GetTypeAttr(pTI, &typeattr);
if(FAILED(hres) || !typeattr) {
WARN("GetTypeAttr failed: %08lx\n", hres);
WARN("GetTypeAttr failed: %08x\n", hres);
return hres;
}
@ -560,7 +560,7 @@ HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo
memcpy(&guid, &typeattr->guid, sizeof(GUID));
ITypeInfo_ReleaseTypeAttr(pTI, typeattr);
if(FAILED(hres)) {
WARN("GetRefTypeInfo failed: %08lx\n", hres);
WARN("GetRefTypeInfo failed: %08x\n", hres);
return hres;
}
ITypeInfo_GetTypeAttr(pTypeInfo, &typeattr);
@ -611,7 +611,7 @@ HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo
hres = ITypeInfo_GetDocumentation(pTypeInfo, vardesc->memid, &ret->fields[i].name,
NULL, NULL, NULL);
if(FAILED(hres))
WARN("GetDocumentation failed: %08lx\n", hres);
WARN("GetDocumentation failed: %08x\n", hres);
ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc);
}

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
@ -30,6 +30,8 @@
#include "ole2.h"
#include "olectl.h"
#include "oleauto.h"
#include "initguid.h"
#include "typelib.h"
#include "wine/debug.h"
@ -139,7 +141,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
}
if (list->base_iid) {
register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
@ -161,12 +163,12 @@ static HRESULT register_interfaces(struct regsvr_interface const *list)
}
if (list->ps_clsid) {
register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
if (list->ps_clsid32) {
register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
@ -443,22 +445,6 @@ static LONG recursive_delete_keyW(HKEY base, WCHAR const *name)
static GUID const CLSID_RecordInfo = {
0x0000002F, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
extern GUID const CLSID_PSDispatch;
GUID const CLSID_PSEnumVariant = {
0x00020421, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
GUID const CLSID_PSTypeInfo = {
0x00020422, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
GUID const CLSID_PSTypeLib = {
0x00020423, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
GUID const CLSID_PSTypeComp = {
0x00020425, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
extern GUID const CLSID_PSOAInterface;
static GUID const CLSID_OldFont = {
0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} };
@ -556,28 +542,28 @@ static struct regsvr_interface const interface_list[] = {
"ITypeInfo",
NULL,
22,
NULL,
&CLSID_PSTypeInfo,
&CLSID_PSTypeInfo
},
{ &IID_ITypeLib,
"ITypeLib",
NULL,
13,
NULL,
&CLSID_PSTypeLib,
&CLSID_PSTypeLib
},
{ &IID_ITypeComp,
"ITypeComp",
NULL,
5,
NULL,
&CLSID_PSTypeComp,
&CLSID_PSTypeComp
},
{ &IID_IEnumVARIANT,
"IEnumVARIANT",
NULL,
15,
NULL,
&CLSID_PSEnumVariant,
&CLSID_PSEnumVariant
},
{ &IID_ICreateTypeInfo,

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef WINE_OLEAUT32_RESOURCE_H
#define WINE_OLEAUT32_RESOURCE_H

View File

@ -19,7 +19,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Memory Layout of a SafeArray:
*
@ -169,25 +169,6 @@ static ULONG SAFEARRAY_GetCellCount(const SAFEARRAY *psa)
return ulNumCells;
}
/* Get the 0 based index of an index into a dimension */
static inline ULONG SAFEARRAY_GetDimensionIndex(SAFEARRAYBOUND *psab, ULONG ulIndex)
{
return ulIndex - psab->lLbound;
}
/* Get the size of a dimension in cells */
static inline ULONG SAFEARRAY_GetDimensionCells(SAFEARRAY *psa, ULONG ulDim)
{
ULONG size = psa->rgsabound[0].cElements;
while (ulDim)
{
size *= psa->rgsabound[ulDim].cElements;
ulDim--;
}
return size;
}
/* Allocate a descriptor for an array */
static HRESULT SAFEARRAY_AllocDescriptor(ULONG ulSize, SAFEARRAY **ppsaOut)
{
@ -226,6 +207,7 @@ static void SAFEARRAY_SetFeatures(VARTYPE vt, SAFEARRAY *psa)
static SAFEARRAY* SAFEARRAY_Create(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound, ULONG ulSize)
{
SAFEARRAY *psa = NULL;
int i;
if (!rgsabound)
return NULL;
@ -240,12 +222,13 @@ static SAFEARRAY* SAFEARRAY_Create(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsab
case VT_VARIANT: psa->fFeatures |= FADF_VARIANT; break;
}
memcpy(psa->rgsabound, rgsabound, cDims * sizeof(SAFEARRAYBOUND));
for (i = 0; i < cDims; i++)
memcpy(psa->rgsabound + i, rgsabound + cDims - 1 - i, sizeof(SAFEARRAYBOUND));
if (ulSize)
psa->cbElements = ulSize;
if (FAILED(SafeArrayAllocData(psa)))
if (!psa->cbElements || FAILED(SafeArrayAllocData(psa)))
{
SafeArrayDestroyDescriptor(psa);
psa = NULL;
@ -293,7 +276,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell)
ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
if (ulStartCell > ulCellCount) {
FIXME("unexpted ulcellcount %ld, start %ld\n",ulCellCount,ulStartCell);
FIXME("unexpted ulcellcount %d, start %d\n",ulCellCount,ulStartCell);
return E_UNEXPECTED;
}
@ -301,7 +284,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell)
if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH))
{
LPUNKNOWN *lpUnknown = (LPUNKNOWN *)psa->pvData + ulStartCell * psa->cbElements;
LPUNKNOWN *lpUnknown = (LPUNKNOWN *)psa->pvData + ulStartCell;
while(ulCellCount--)
{
@ -327,7 +310,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell)
}
else if (psa->fFeatures & FADF_BSTR)
{
BSTR* lpBstr = (BSTR*)psa->pvData + ulStartCell * psa->cbElements;
BSTR* lpBstr = (BSTR*)psa->pvData + ulStartCell;
while(ulCellCount--)
{
@ -338,7 +321,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell)
}
else if (psa->fFeatures & FADF_VARIANT)
{
VARIANT* lpVariant = (VARIANT*)psa->pvData + ulStartCell * psa->cbElements;
VARIANT* lpVariant = (VARIANT*)psa->pvData + ulStartCell;
while(ulCellCount--)
{
@ -376,7 +359,7 @@ static HRESULT SAFEARRAY_CopyData(SAFEARRAY *psa, SAFEARRAY *dest)
HRESULT hRet;
hRet = VariantCopy(lpDest, lpVariant);
if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%lx\n", hRet);
if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet);
lpVariant++;
lpDest++;
}
@ -481,7 +464,7 @@ HRESULT WINAPI SafeArrayAllocDescriptor(UINT cDims, SAFEARRAY **ppsaOut)
(*ppsaOut)->cDims = cDims;
TRACE("(%d): %lu bytes allocated for descriptor.\n", cDims, allocSize);
TRACE("(%d): %u bytes allocated for descriptor.\n", cDims, allocSize);
return S_OK;
}
@ -550,19 +533,16 @@ HRESULT WINAPI SafeArrayAllocData(SAFEARRAY *psa)
{
ULONG ulSize = SAFEARRAY_GetCellCount(psa);
hRet = E_OUTOFMEMORY;
psa->pvData = SAFEARRAY_Malloc(ulSize * psa->cbElements);
if (psa->cbElements)
if (psa->pvData)
{
psa->pvData = SAFEARRAY_Malloc(ulSize * psa->cbElements);
if (psa->pvData)
{
hRet = S_OK;
TRACE("%lu bytes allocated for data at %p (%lu objects).\n",
ulSize * psa->cbElements, psa->pvData, ulSize);
}
hRet = S_OK;
TRACE("%u bytes allocated for data at %p (%u objects).\n",
ulSize * psa->cbElements, psa->pvData, ulSize);
}
else
hRet = E_OUTOFMEMORY;
}
return hRet;
}
@ -665,7 +645,7 @@ SAFEARRAY* WINAPI SafeArrayCreateEx(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsa
*/
SAFEARRAY* WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
{
TRACE("(%d->%s,%ld,%ld\n", vt, debugstr_vt(vt), lLbound, cElements);
TRACE("(%d->%s,%d,%d\n", vt, debugstr_vt(vt), lLbound, cElements);
if (vt == VT_RECORD)
return NULL;
@ -697,7 +677,7 @@ SAFEARRAY* WINAPI SafeArrayCreateVectorEx(VARTYPE vt, LONG lLbound, ULONG cEleme
IRecordInfo* iRecInfo = (IRecordInfo*)pvExtra;
SAFEARRAY* psa;
TRACE("(%d->%s,%ld,%ld,%p\n", vt, debugstr_vt(vt), lLbound, cElements, pvExtra);
TRACE("(%d->%s,%d,%d,%p\n", vt, debugstr_vt(vt), lLbound, cElements, pvExtra);
if (vt == VT_RECORD)
{
@ -860,12 +840,6 @@ HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData
if (!psa || !rgIndices)
return E_INVALIDARG;
if (!pvData)
{
ERR("Invalid pvData would crash under Win32!\n");
return E_INVALIDARG;
}
hRet = SafeArrayLock(psa);
if (SUCCEEDED(hRet))
@ -882,9 +856,9 @@ HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData
VARIANT* lpDest = (VARIANT*)lpvDest;
hRet = VariantClear(lpDest);
if (FAILED(hRet)) FIXME("VariantClear failed with 0x%lx\n", hRet);
if (FAILED(hRet)) FIXME("VariantClear failed with 0x%x\n", hRet);
hRet = VariantCopy(lpDest, lpVariant);
if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%lx\n", hRet);
if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet);
}
else if (psa->fFeatures & FADF_BSTR)
{
@ -894,14 +868,9 @@ HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData
if (*lpDest)
SysFreeString(*lpDest);
if (lpBstr)
{
*lpDest = SysAllocStringByteLen((char*)lpBstr, SysStringByteLen(lpBstr));
if (!*lpDest)
hRet = E_OUTOFMEMORY;
}
else
*lpDest = NULL;
*lpDest = SysAllocStringByteLen((char*)lpBstr, SysStringByteLen(lpBstr));
if (!*lpDest)
hRet = E_OUTOFMEMORY;
}
else
{
@ -971,7 +940,7 @@ HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData
/* The original content of pvData is ignored. */
V_VT(lpDest) = VT_EMPTY;
hRet = VariantCopy(lpDest, lpVariant);
if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%lx\n", hRet);
if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet);
}
else if (psa->fFeatures & FADF_BSTR)
{
@ -1032,8 +1001,8 @@ HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
if(!nDim || nDim > psa->cDims)
return DISP_E_BADINDEX;
*plUbound = psa->rgsabound[nDim - 1].lLbound +
psa->rgsabound[nDim - 1].cElements - 1;
*plUbound = psa->rgsabound[psa->cDims - nDim].lLbound +
psa->rgsabound[psa->cDims - nDim].cElements - 1;
return S_OK;
}
@ -1065,7 +1034,7 @@ HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound)
if(!nDim || nDim > psa->cDims)
return DISP_E_BADINDEX;
*plLbound = psa->rgsabound[nDim - 1].lLbound;
*plLbound = psa->rgsabound[psa->cDims - nDim].lLbound;
return S_OK;
}
@ -1085,7 +1054,7 @@ HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound)
*/
UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa)
{
TRACE("(%p) returning %ld\n", psa, psa ? psa->cDims : 0ul);
TRACE("(%p) returning %d\n", psa, psa ? psa->cDims : 0u);
return psa ? psa->cDims : 0;
}
@ -1105,7 +1074,7 @@ UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa)
*/
UINT WINAPI SafeArrayGetElemsize(SAFEARRAY *psa)
{
TRACE("(%p) returning %ld\n", psa, psa ? psa->cbElements : 0ul);
TRACE("(%p) returning %d\n", psa, psa ? psa->cbElements : 0u);
return psa ? psa->cbElements : 0;
}
@ -1204,7 +1173,7 @@ HRESULT WINAPI SafeArrayPtrOfIndex(SAFEARRAY *psa, LONG *rgIndices, void **ppvDa
if (!psa || !rgIndices || !ppvData)
return E_INVALIDARG;
psab = psa->rgsabound;
psab = psa->rgsabound + psa->cDims - 1;
c1 = *rgIndices++;
if (c1 < psab->lLbound || c1 >= psab->lLbound + (LONG)psab->cElements)
@ -1214,7 +1183,7 @@ HRESULT WINAPI SafeArrayPtrOfIndex(SAFEARRAY *psa, LONG *rgIndices, void **ppvDa
{
dimensionSize *= psab->cElements;
psab++;
psab--;
if (!psab->cElements ||
*rgIndices < psab->lLbound ||
@ -1225,7 +1194,7 @@ HRESULT WINAPI SafeArrayPtrOfIndex(SAFEARRAY *psa, LONG *rgIndices, void **ppvDa
rgIndices++;
}
cell += (c1 - psa->rgsabound[0].lLbound);
cell += (c1 - psa->rgsabound[psa->cDims - 1].lLbound);
*ppvData = (char*)psa->pvData + cell * psa->cbElements;
return S_OK;
@ -1256,13 +1225,17 @@ HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa)
if (psa->cLocks)
return DISP_E_ARRAYISLOCKED; /* Can't delete a locked array */
/* If static, keep pvData and don't free */
if (psa->pvData && !(psa->fFeatures & FADF_STATIC))
{
/* Delete the actual item data */
if (FAILED(SAFEARRAY_DestroyData(psa, 0)))
return E_UNEXPECTED;
/* Delete the actual item data */
if (FAILED(SAFEARRAY_DestroyData(psa, 0)))
return E_UNEXPECTED;
if (psa->pvData)
{
if (psa->fFeatures & FADF_STATIC)
{
ZeroMemory(psa->pvData, SAFEARRAY_GetCellCount(psa) * psa->cbElements);
return S_OK;
}
/* If this is not a vector, free the data memory block */
if (!(psa->fFeatures & FADF_CREATEVECTOR))
{
@ -1457,7 +1430,7 @@ HRESULT WINAPI SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psabound)
if (FAILED(SafeArrayLock(psa)))
return E_UNEXPECTED;
oldBounds = &psa->rgsabound[psa->cDims - 1];
oldBounds = psa->rgsabound;
oldBounds->lLbound = psabound->lLbound;
if (psabound->cElements != oldBounds->cElements)
@ -1465,9 +1438,8 @@ HRESULT WINAPI SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psabound)
if (psabound->cElements < oldBounds->cElements)
{
/* Shorten the final dimension. */
ULONG ulStartCell = psa->cDims == 1 ? 0 : SAFEARRAY_GetDimensionCells(psa, psa->cDims - 1);
ulStartCell += psabound->cElements;
ULONG ulStartCell = psabound->cElements *
(SAFEARRAY_GetCellCount(psa) / oldBounds->cElements);
SAFEARRAY_DestroyData(psa, ulStartCell);
}
else

View File

@ -17,7 +17,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
@ -32,15 +32,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole);
/***********************************************************************
* OleIconToCursor (OLEAUT32.415)
*/
HCURSOR WINAPI OleIconToCursor( HINSTANCE hinstExe, HICON hicon)
{
FIXME("(%p,%p), not implemented (olepro32.dll)\n",hinstExe,hicon);
return S_OK;
}
/***********************************************************************
* OleCreatePropertyFrameIndirect (OLEAUT32.416)
*/
@ -58,9 +49,8 @@ HRESULT WINAPI OleCreatePropertyFrame(
LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid,
DWORD dwReserved, LPVOID pvReserved )
{
FIXME("(%p,%d,%d,%s,%ld,%p,%ld,%p,%x,%ld,%p), not implemented (olepro32.dll)\n",
FIXME("(%p,%d,%d,%s,%d,%p,%d,%p,%x,%d,%p), not implemented (olepro32.dll)\n",
hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,ppUnk,cPages,
pPageClsID, (int)lcid,dwReserved,pvReserved);
return S_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _WINE_TYPELIB_H
#define _WINE_TYPELIB_H
@ -79,7 +79,7 @@ typedef struct tagMSFT_Header {
INT res44; /* unknown always: 0x20 (guid hash size?) */
INT res48; /* unknown always: 0x80 (name hash size?) */
INT dispatchpos; /* HREFTYPE to IDispatch, or -1 if no IDispatch */
/*0x50*/INT res50; /* is zero becomes one when an interface is derived */
/*0x50*/INT nimpinfos; /* number of impinfos */
} MSFT_Header;
/* segments in the type lib file have a structure like this: */
@ -149,7 +149,7 @@ typedef struct tagMSFT_TypeInfoBase {
/*050*/ INT size; /* size in bytes, at least for structures */
/* FIXME: name of this field */
INT datatype1; /* position in type description table */
/* or in base intefaces */
/* or in base interfaces */
/* if coclass: offset in reftable */
/* if interface: reference to inherited if */
/* if module: offset to dllname in name table */
@ -285,7 +285,7 @@ typedef struct {
lower-middle 8 bits are unknown (flags?),
upper 16 bits are hash code */
} MSFT_NameIntro;
/* the custom data table directory has enties like this */
/* the custom data table directory has entries like this */
typedef struct {
INT GuidOffset;
INT DataOffset;
@ -428,28 +428,28 @@ typedef struct {
/*00*/ WORD cFuncs;
/*02*/ WORD cVars;
/*04*/ WORD cImplTypes;
/*06*/ WORD res06;
/*08*/ WORD res08;
/*0a*/ WORD res0a;
/*0c*/ WORD res0c;
/*0e*/ WORD res0e;
/*10*/ WORD res10;
/*12*/ WORD res12;
/*06*/ WORD res06; /* always 0000 */
/*08*/ WORD funcs_off; /* offset to functions (starting from the member header) */
/*0a*/ WORD vars_off; /* offset to vars (starting from the member header) */
/*0c*/ WORD impls_off; /* offset to implemented types (starting from the member header) */
/*0e*/ WORD funcs_bytes; /* bytes used by function data */
/*10*/ WORD vars_bytes; /* bytes used by var data */
/*12*/ WORD impls_bytes; /* bytes used by implemented type data */
/*14*/ WORD tdescalias_vt; /* for TKIND_ALIAS */
/*16*/ WORD res16;
/*18*/ WORD res18;
/*1a*/ WORD res1a;
/*1c*/ WORD res1c;
/*1e*/ WORD res1e;
/*16*/ WORD res16; /* always ffff */
/*18*/ WORD res18; /* always 0000 */
/*1a*/ WORD res1a; /* always 0000 */
/*1c*/ WORD simple_alias; /* tdescalias_vt is a vt rather than an offset? */
/*1e*/ WORD res1e; /* always 0000 */
/*20*/ WORD cbSizeInstance;
/*22*/ WORD cbAlignment;
/*24*/ WORD res24;
/*26*/ WORD res26;
/*28*/ WORD cbSizeVft;
/*2a*/ WORD res2a;
/*2c*/ WORD res2c;
/*2e*/ WORD res2e;
/*30*/ WORD res30;
/*2a*/ WORD res2a; /* always ffff */
/*2c*/ WORD res2c; /* always ffff */
/*2e*/ WORD res2e; /* always ffff */
/*30*/ WORD res30; /* always ffff */
/*32*/ WORD res32;
/*34*/ WORD res34;
} SLTG_TypeInfoTail;
@ -477,15 +477,7 @@ typedef struct {
#define SLTG_ENUMITEM_MAGIC 0x120a
typedef struct {
/*00*/ WORD vt; /* vartype, 0xffff marks end. */
/*02*/ WORD res02; /* ?, 0xffff marks end */
} SLTG_AliasItem;
#define SLTG_ALIASITEM_MAGIC 0x001d
typedef struct {
BYTE magic; /* 0x4c or 0x6c */
BYTE magic; /* 0x4c, 0xcb or 0x8b with optional SLTG_FUNCTION_FLAGS_PRESENT flag */
BYTE inv; /* high nibble is INVOKE_KIND, low nibble = 2 */
WORD next; /* byte offset from beginning of group to next fn */
WORD name; /* Offset within name table to name */
@ -499,7 +491,7 @@ typedef struct {
middle 6 bits */
WORD rettype; /* return type VT_?? or offset to ret type */
WORD vtblpos; /* position in vtbl? */
WORD funcflags; /* present if magic == 0x6c */
WORD funcflags; /* present if magic & 0x20 */
/* Param list starts, repeat next two as required */
#if 0
WORD name; /* offset to 2nd letter of name */
@ -507,8 +499,10 @@ typedef struct {
#endif
} SLTG_Function;
#define SLTG_FUNCTION_FLAGS_PRESENT 0x20
#define SLTG_FUNCTION_MAGIC 0x4c
#define SLTG_FUNCTION_WITH_FLAGS_MAGIC 0x6c
#define SLTG_DISPATCH_FUNCTION_MAGIC 0xcb
#define SLTG_STATIC_FUNCTION_MAGIC 0x8b
typedef struct {
/*00*/ BYTE magic; /* 0xdf */
@ -579,17 +573,19 @@ typedef struct {
typedef struct {
BYTE magic; /* 0x0a */
BYTE typepos;
BYTE flags;
WORD next;
WORD name;
WORD byte_offs; /* pos in struct */
WORD type; /* if typepos == 0x02 this is the type, else offset to type */
WORD byte_offs; /* pos in struct, or offset to const type */
WORD type; /* if flags & 0x02 this is the type, else offset to type */
DWORD memid;
WORD helpcontext; /* ?? */
WORD helpstring; /* ?? */
} SLTG_RecordItem;
WORD varflags; /* only present if magic & 0x02 */
} SLTG_Variable;
#define SLTG_RECORD_MAGIC 0x0a
#define SLTG_VAR_MAGIC 0x0a
#define SLTG_VAR_WITH_FLAGS_MAGIC 0x2a
/* CARRAYs look like this
@ -603,9 +599,16 @@ WORD typeofarray
HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc );
extern DWORD _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args);
extern void dump_Variant(const VARIANT * pvar);
HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv);
/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
DEFINE_OLEGUID( CLSID_PSDispatch, 0x00020420, 0x0000, 0x0000 );
DEFINE_OLEGUID( CLSID_PSEnumVariant, 0x00020421, 0x0000, 0x0000 );
DEFINE_OLEGUID( CLSID_PSTypeInfo, 0x00020422, 0x0000, 0x0000 );
DEFINE_OLEGUID( CLSID_PSTypeLib, 0x00020423, 0x0000, 0x0000 );
DEFINE_OLEGUID( CLSID_PSOAInterface, 0x00020424, 0x0000, 0x0000 );
DEFINE_OLEGUID( CLSID_PSTypeComp, 0x00020425, 0x0000, 0x0000 );
/*---------------------------END--------------------------------------------*/
#endif

View File

@ -18,7 +18,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
@ -85,14 +85,14 @@ QueryPathOfRegTypeLib16(
TRACE("\n");
if (HIWORD(guid)) {
sprintf( typelibkey, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win16",
sprintf( typelibkey, "SOFTWARE\\Classes\\Typelib\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%x\\win16",
guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
wMaj,wMin,lcid);
} else {
sprintf(xguid,"<guid 0x%08lx>",(DWORD)guid);
FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
sprintf(xguid,"<guid 0x%08x>",(DWORD)guid);
FIXME("(%s,%d,%d,0x%04x,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path);
return E_FAIL;
}
plen = sizeof(pathname);
@ -120,10 +120,10 @@ QueryPathOfRegTypeLib16(
* Both parameters are FAR pointers.
*/
HRESULT WINAPI LoadTypeLib16(
LPOLESTR szFile, /* [in] Name of file to load from */
LPSTR szFile, /* [in] Name of file to load from */
ITypeLib** pptLib) /* [out] Destination for loaded ITypeLib interface */
{
FIXME("(%s,%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib);
FIXME("(%s,%p): stub\n",debugstr_a(szFile),pptLib);
if (pptLib!=0)
*pptLib=0;

View File

@ -15,7 +15,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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* --------------------------------------------------------------------------------------
* Known problems:
@ -232,7 +232,7 @@ static void ctl2_init_header(
This->typelib_header.res44 = 0x20;
This->typelib_header.res48 = 0x80;
This->typelib_header.dispatchpos = -1;
This->typelib_header.res50 = 0;
This->typelib_header.nimpinfos = 0;
}
/****************************************************************************
@ -276,7 +276,7 @@ static int ctl2_hash_guid(
hash ^= ((const short *)guid)[i];
}
return (hash & 0xf) | ((hash & 0x10) & (0 - !!(hash & 0xe0)));
return hash & 0x1f;
}
/****************************************************************************
@ -677,6 +677,8 @@ static int ctl2_alloc_importinfo(
}
}
impinfo->flags |= This->typelib_header.nimpinfos++;
offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0);
if (offset == -1) return -1;
@ -1148,7 +1150,7 @@ static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface)
ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p)->ref was %lu\n",This, ref - 1);
TRACE("(%p)->ref was %u\n",This, ref - 1);
return ref;
}
@ -1163,7 +1165,7 @@ static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(%lu)\n",This, ref);
TRACE("(%p)->(%u)\n",This, ref);
if (!ref) {
if (This->typelib) {
@ -1252,7 +1254,6 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U
ctl2_alloc_importinfo(This->typelib, &impinfo);
This->typelib->typelib_header.dispatchpos = 1;
This->typelib->typelib_header.res50 = 1;
This->typeinfo->typekind |= 0x10;
This->typeinfo->typekind &= ~0x0f;
@ -1294,7 +1295,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(
{
ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
TRACE("(%p,%ld)\n", iface, dwHelpContext);
TRACE("(%p,%d)\n", iface, dwHelpContext);
This->typeinfo->helpcontext = dwHelpContext;
@ -1379,7 +1380,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
int decoded_size;
FIXME("(%p,%d,%p), stub!\n", iface, index, pFuncDesc);
FIXME("{%ld,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind, pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams, pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
FIXME("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind, pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams, pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
/* FIXME("{%d, %d}\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt, pFuncDesc->lprgelemdescParam[1].tdesc.vt); */
/* return E_OUTOFMEMORY; */
@ -1457,7 +1458,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(
{
ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
TRACE("(%p,%d,%ld)\n", iface, index, hRefType);
TRACE("(%p,%d,%d)\n", iface, index, hRefType);
if ((This->typeinfo->typekind & 15) == TKIND_COCLASS) {
int offset;
@ -1619,7 +1620,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(
int alignment;
TRACE("(%p,%d,%p), stub!\n", iface, index, pVarDesc);
TRACE("%ld, %p, %ld, {{%lx, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst,
TRACE("%d, %p, %d, {{%x, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst,
pVarDesc->elemdescVar.tdesc.u.hreftype, pVarDesc->elemdescVar.tdesc.vt,
pVarDesc->elemdescVar.u.paramdesc.pparamdescex, pVarDesc->elemdescVar.u.paramdesc.wParamFlags,
pVarDesc->wVarFlags, pVarDesc->varkind);
@ -1856,7 +1857,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext(
UINT index,
DWORD dwHelpContext)
{
FIXME("(%p,%d,%ld), stub!\n", iface, index, dwHelpContext);
FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpContext);
return E_OUTOFMEMORY;
}
@ -1870,7 +1871,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext(
UINT index,
DWORD dwHelpContext)
{
FIXME("(%p,%d,%ld), stub!\n", iface, index, dwHelpContext);
FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpContext);
return E_OUTOFMEMORY;
}
@ -1947,7 +1948,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(
MEMBERID memid, /* [I] The member id of the function to delete. */
INVOKEKIND invKind) /* [I] The invocation type of the function to delete. (?) */
{
FIXME("(%p,%ld,%d), stub!\n", iface, memid, invKind);
FIXME("(%p,%d,%d), stub!\n", iface, memid, invKind);
return E_OUTOFMEMORY;
}
@ -1985,7 +1986,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId(
ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */
MEMBERID memid) /* [I] The member id of the variable description to delete. */
{
FIXME("(%p,%ld), stub!\n", iface, memid);
FIXME("(%p,%d), stub!\n", iface, memid);
return E_OUTOFMEMORY;
}
@ -2121,7 +2122,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext(
ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the help string context. */
ULONG dwHelpStringContext) /* [I] The help string context. */
{
FIXME("(%p,%ld), stub!\n", iface, dwHelpStringContext);
FIXME("(%p,%d), stub!\n", iface, dwHelpStringContext);
return E_OUTOFMEMORY;
}
@ -2140,7 +2141,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext(
UINT index, /* [I] The index for the function on which to set the help string context. */
ULONG dwHelpStringContext) /* [I] The help string context. */
{
FIXME("(%p,%d,%ld), stub!\n", iface, index, dwHelpStringContext);
FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
return E_OUTOFMEMORY;
}
@ -2159,7 +2160,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext(
UINT index, /* [I] The index of the variable on which to set the help string context. */
ULONG dwHelpStringContext) /* [I] The help string context */
{
FIXME("(%p,%d,%ld), stub!\n", iface, index, dwHelpStringContext);
FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
return E_OUTOFMEMORY;
}
@ -2297,7 +2298,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetNames(
UINT cMaxNames,
UINT* pcNames)
{
FIXME("(%p,%ld,%p,%d,%p), stub!\n", iface, memid, rgBstrNames, cMaxNames, pcNames);
FIXME("(%p,%d,%p,%d,%p), stub!\n", iface, memid, rgBstrNames, cMaxNames, pcNames);
return E_OUTOFMEMORY;
}
@ -2359,7 +2360,7 @@ static HRESULT WINAPI ITypeInfo2_fnInvoke(
EXCEPINFO* pExcepInfo,
UINT* puArgErr)
{
FIXME("(%p,%p,%ld,%x,%p,%p,%p,%p), stub!\n", iface, pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
FIXME("(%p,%p,%d,%x,%p,%p,%p,%p), stub!\n", iface, pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
return E_OUTOFMEMORY;
}
@ -2376,7 +2377,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetDocumentation(
DWORD* pdwHelpContext,
BSTR* pBstrHelpFile)
{
FIXME("(%p,%ld,%p,%p,%p,%p), stub!\n", iface, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
FIXME("(%p,%d,%p,%p,%p,%p), stub!\n", iface, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
return E_OUTOFMEMORY;
}
@ -2393,7 +2394,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetDllEntry(
BSTR* pBstrName,
WORD* pwOrdinal)
{
FIXME("(%p,%ld,%d,%p,%p,%p), stub!\n", iface, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
return E_OUTOFMEMORY;
}
@ -2407,7 +2408,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo(
HREFTYPE hRefType,
ITypeInfo** ppTInfo)
{
FIXME("(%p,%ld,%p), stub!\n", iface, hRefType, ppTInfo);
FIXME("(%p,%d,%p), stub!\n", iface, hRefType, ppTInfo);
return E_OUTOFMEMORY;
}
@ -2422,7 +2423,7 @@ static HRESULT WINAPI ITypeInfo2_fnAddressOfMember(
INVOKEKIND invKind,
PVOID* ppv)
{
FIXME("(%p,%ld,%d,%p), stub!\n", iface, memid, invKind, ppv);
FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, ppv);
return E_OUTOFMEMORY;
}
@ -2451,7 +2452,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetMops(
MEMBERID memid,
BSTR* pBstrMops)
{
FIXME("(%p,%ld,%p), stub!\n", iface, memid, pBstrMops);
FIXME("(%p,%d,%p), stub!\n", iface, memid, pBstrMops);
return E_OUTOFMEMORY;
}
@ -2564,7 +2565,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId(
INVOKEKIND invKind, /* [I] The invocation kind for the function. */
UINT* pFuncIndex) /* [O] The index of the function. */
{
FIXME("(%p,%ld,%d,%p), stub!\n", iface, memid, invKind, pFuncIndex);
FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, pFuncIndex);
return E_OUTOFMEMORY;
}
@ -2583,7 +2584,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId(
MEMBERID memid, /* [I] The member id for the variable. */
UINT* pVarIndex) /* [O] The index of the variable. */
{
FIXME("(%p,%ld,%p), stub!\n", iface, memid, pVarIndex);
FIXME("(%p,%d,%p), stub!\n", iface, memid, pVarIndex);
return E_OUTOFMEMORY;
}
@ -2705,7 +2706,7 @@ static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
DWORD* pdwHelpStringContext, /* [O] The help string context. */
BSTR* pbstrHelpStringDll) /* [O] The help file name. */
{
FIXME("(%p,%ld,%ld,%p,%p,%p), stub!\n", iface, memid, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
return E_OUTOFMEMORY;
}
@ -3015,7 +3016,7 @@ static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface)
ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p)->ref was %lu\n",This, ref - 1);
TRACE("(%p)->ref was %u\n",This, ref - 1);
return ref;
}
@ -3030,7 +3031,7 @@ static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(%lu)\n",This, ref);
TRACE("(%p)->(%u)\n",This, ref);
if (!ref) {
int i;
@ -3189,7 +3190,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface,
*/
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, DWORD dwHelpContext)
{
FIXME("(%p,%ld), stub!\n", iface, dwHelpContext);
FIXME("(%p,%d), stub!\n", iface, dwHelpContext);
return E_OUTOFMEMORY;
}
@ -3202,7 +3203,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lc
{
ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
TRACE("(%p,%ld)\n", iface, lcid);
TRACE("(%p,%d)\n", iface, lcid);
This->typelib_header.lcid2 = lcid;
@ -3404,7 +3405,7 @@ static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(
ICreateTypeLib2 * iface, /* [I] The type library to set the help string context for. */
ULONG dwHelpStringContext) /* [I] The help string context. */
{
FIXME("(%p,%ld), stub!\n", iface, dwHelpStringContext);
FIXME("(%p,%d), stub!\n", iface, dwHelpStringContext);
return E_OUTOFMEMORY;
}
@ -3618,7 +3619,7 @@ static HRESULT WINAPI ITypeLib2_fnIsName(
int nameoffset;
MSFT_NameIntro *nameintro;
TRACE("(%p,%s,%lx,%p)\n", iface, debugstr_w(szNameBuf), lHashVal, pfName);
TRACE("(%p,%s,%x,%p)\n", iface, debugstr_w(szNameBuf), lHashVal, pfName);
ctl2_encode_name(This, szNameBuf, &encoded_name);
nameoffset = ctl2_find_name(This, encoded_name);
@ -3652,7 +3653,7 @@ static HRESULT WINAPI ITypeLib2_fnFindName(
{
ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
FIXME("(%p,%s,%lx,%p,%p,%p), stub!\n", This, debugstr_w(szNameBuf), lHashVal, ppTInfo, rgMemId, pcFound);
FIXME("(%p,%s,%x,%p,%p,%p), stub!\n", This, debugstr_w(szNameBuf), lHashVal, ppTInfo, rgMemId, pcFound);
return E_OUTOFMEMORY;
}
@ -3736,7 +3737,7 @@ static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
{
ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
FIXME("(%p,%d,%ld,%p,%p,%p), stub!\n", This, index, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", This, index, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
return E_OUTOFMEMORY;
}

View File

@ -0,0 +1,994 @@
/*
* Gif extracting routines - derived from libungif
*
* Portions Copyright 2006 Mike McCormack
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* Original copyright notice:
*
* The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
/******************************************************************************
* "Gif-Lib" - Yet another gif library.
*
* Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990
******************************************************************************
* The kernel of the GIF Decoding process can be found here.
******************************************************************************
* History:
* 16 Jun 89 - Version 1.0 by Gershon Elber.
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names).
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "ungif.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
static void *ungif_alloc( size_t sz )
{
return HeapAlloc( GetProcessHeap(), 0, sz );
}
static void *ungif_calloc( size_t num, size_t sz )
{
return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, num*sz );
}
static void ungif_free( void *ptr )
{
HeapFree( GetProcessHeap(), 0, ptr );
}
#define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */
#define LZ_BITS 12
#define NO_SUCH_CODE 4098 /* Impossible code, to signal empty. */
typedef struct GifFilePrivateType {
GifWord BitsPerPixel, /* Bits per pixel (Codes uses at least this + 1). */
ClearCode, /* The CLEAR LZ code. */
EOFCode, /* The EOF LZ code. */
RunningCode, /* The next code algorithm can generate. */
RunningBits, /* The number of bits required to represent RunningCode. */
MaxCode1, /* 1 bigger than max. possible code, in RunningBits bits. */
LastCode, /* The code before the current code. */
CrntCode, /* Current algorithm code. */
StackPtr, /* For character stack (see below). */
CrntShiftState; /* Number of bits in CrntShiftDWord. */
unsigned long CrntShiftDWord; /* For bytes decomposition into codes. */
unsigned long PixelCount; /* Number of pixels in image. */
InputFunc Read; /* function to read gif input (TVT) */
GifByteType Buf[256]; /* Compressed input is buffered here. */
GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
GifByteType Suffix[LZ_MAX_CODE + 1]; /* So we can trace the codes. */
GifPrefixType Prefix[LZ_MAX_CODE + 1];
} GifFilePrivateType;
/* avoid extra function call in case we use fread (TVT) */
#define READ(_gif,_buf,_len) \
((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len)
static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
static int DGifSetupDecompress(GifFileType *GifFile);
static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen);
static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
static int DGifDecompressInput(GifFileType *GifFile, int *Code);
static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
GifByteType *NextByte);
static int DGifGetExtensionNext(GifFileType * GifFile, GifByteType ** GifExtension);
static int DGifGetCodeNext(GifFileType * GifFile, GifByteType ** GifCodeBlock);
/******************************************************************************
* Miscellaneous utility functions
*****************************************************************************/
/* return smallest bitfield size n will fit in */
static int
BitSize(int n) {
register int i;
for (i = 1; i <= 8; i++)
if ((1 << i) >= n)
break;
return (i);
}
/******************************************************************************
* Color map object functions
*****************************************************************************/
/*
* Allocate a color map of given size; initialize with contents of
* ColorMap if that pointer is non-NULL.
*/
static ColorMapObject *
MakeMapObject(int ColorCount,
const GifColorType * ColorMap) {
ColorMapObject *Object;
/*** FIXME: Our ColorCount has to be a power of two. Is it necessary to
* make the user know that or should we automatically round up instead? */
if (ColorCount != (1 << BitSize(ColorCount))) {
return ((ColorMapObject *) NULL);
}
Object = ungif_alloc(sizeof(ColorMapObject));
if (Object == (ColorMapObject *) NULL) {
return ((ColorMapObject *) NULL);
}
Object->Colors = ungif_calloc(ColorCount, sizeof(GifColorType));
if (Object->Colors == (GifColorType *) NULL) {
return NULL;
}
Object->ColorCount = ColorCount;
Object->BitsPerPixel = BitSize(ColorCount);
if (ColorMap) {
memcpy(Object->Colors, ColorMap, ColorCount * sizeof(GifColorType));
}
return (Object);
}
/*
* Free a color map object
*/
static void
FreeMapObject(ColorMapObject * Object) {
if (Object != NULL) {
ungif_free(Object->Colors);
ungif_free(Object);
/*** FIXME:
* When we are willing to break API we need to make this function
* FreeMapObject(ColorMapObject **Object)
* and do this assignment to NULL here:
* *Object = NULL;
*/
}
}
static int
AddExtensionBlock(SavedImage * New,
int Len,
unsigned char ExtData[]) {
ExtensionBlock *ep;
if (New->ExtensionBlocks == NULL)
New->ExtensionBlocks = ungif_alloc(sizeof(ExtensionBlock));
else
New->ExtensionBlocks = realloc(New->ExtensionBlocks,
sizeof(ExtensionBlock) *
(New->ExtensionBlockCount + 1));
if (New->ExtensionBlocks == NULL)
return (GIF_ERROR);
ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
ep->ByteCount=Len;
ep->Bytes = ungif_alloc(ep->ByteCount);
if (ep->Bytes == NULL)
return (GIF_ERROR);
if (ExtData) {
memcpy(ep->Bytes, ExtData, Len);
ep->Function = New->Function;
}
return (GIF_OK);
}
static void
FreeExtension(SavedImage * Image)
{
ExtensionBlock *ep;
if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) {
return;
}
for (ep = Image->ExtensionBlocks;
ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++)
ungif_free(ep->Bytes);
ungif_free(Image->ExtensionBlocks);
Image->ExtensionBlocks = NULL;
}
/******************************************************************************
* Image block allocation functions
******************************************************************************/
static void
FreeSavedImages(GifFileType * GifFile) {
SavedImage *sp;
if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
return;
}
for (sp = GifFile->SavedImages;
sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
if (sp->ImageDesc.ColorMap) {
FreeMapObject(sp->ImageDesc.ColorMap);
sp->ImageDesc.ColorMap = NULL;
}
ungif_free(sp->RasterBits);
if (sp->ExtensionBlocks)
FreeExtension(sp);
}
ungif_free(GifFile->SavedImages);
GifFile->SavedImages=NULL;
}
/******************************************************************************
* This routine should be called before any other DGif calls. Note that
* this routine is called automatically from DGif file open routines.
*****************************************************************************/
static int
DGifGetScreenDesc(GifFileType * GifFile) {
int i, BitsPerPixel;
GifByteType Buf[3];
/* Put the screen descriptor into the file: */
if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
return GIF_ERROR;
if (READ(GifFile, Buf, 3) != 3) {
return GIF_ERROR;
}
GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
BitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile->SBackGroundColor = Buf[1];
if (Buf[0] & 0x80) { /* Do we have global color map? */
GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
if (GifFile->SColorMap == NULL) {
return GIF_ERROR;
}
/* Get the global color map: */
for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
if (READ(GifFile, Buf, 3) != 3) {
FreeMapObject(GifFile->SColorMap);
GifFile->SColorMap = NULL;
return GIF_ERROR;
}
GifFile->SColorMap->Colors[i].Red = Buf[0];
GifFile->SColorMap->Colors[i].Green = Buf[1];
GifFile->SColorMap->Colors[i].Blue = Buf[2];
}
} else {
GifFile->SColorMap = NULL;
}
return GIF_OK;
}
/******************************************************************************
* This routine should be called before any attempt to read an image.
*****************************************************************************/
static int
DGifGetRecordType(GifFileType * GifFile,
GifRecordType * Type) {
GifByteType Buf;
if (READ(GifFile, &Buf, 1) != 1) {
return GIF_ERROR;
}
switch (Buf) {
case ',':
*Type = IMAGE_DESC_RECORD_TYPE;
break;
case '!':
*Type = EXTENSION_RECORD_TYPE;
break;
case ';':
*Type = TERMINATE_RECORD_TYPE;
break;
default:
*Type = UNDEFINED_RECORD_TYPE;
return GIF_ERROR;
}
return GIF_OK;
}
/******************************************************************************
* This routine should be called before any attempt to read an image.
* Note it is assumed the Image desc. header (',') has been read.
*****************************************************************************/
static int
DGifGetImageDesc(GifFileType * GifFile) {
int i, BitsPerPixel;
GifByteType Buf[3];
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
SavedImage *sp;
if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
return GIF_ERROR;
if (READ(GifFile, Buf, 1) != 1) {
return GIF_ERROR;
}
BitsPerPixel = (Buf[0] & 0x07) + 1;
GifFile->Image.Interlace = (Buf[0] & 0x40);
if (Buf[0] & 0x80) { /* Does this image have local color map? */
/*** FIXME: Why do we check both of these in order to do this?
* Why do we have both Image and SavedImages? */
if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL)
FreeMapObject(GifFile->Image.ColorMap);
GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
if (GifFile->Image.ColorMap == NULL) {
return GIF_ERROR;
}
/* Get the image local color map: */
for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
if (READ(GifFile, Buf, 3) != 3) {
FreeMapObject(GifFile->Image.ColorMap);
GifFile->Image.ColorMap = NULL;
return GIF_ERROR;
}
GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
}
} else if (GifFile->Image.ColorMap) {
FreeMapObject(GifFile->Image.ColorMap);
GifFile->Image.ColorMap = NULL;
}
if (GifFile->SavedImages) {
if ((GifFile->SavedImages = realloc(GifFile->SavedImages,
sizeof(SavedImage) *
(GifFile->ImageCount + 1))) == NULL) {
return GIF_ERROR;
}
} else {
if ((GifFile->SavedImages = ungif_alloc(sizeof(SavedImage))) == NULL) {
return GIF_ERROR;
}
}
sp = &GifFile->SavedImages[GifFile->ImageCount];
memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
if (GifFile->Image.ColorMap != NULL) {
sp->ImageDesc.ColorMap = MakeMapObject(
GifFile->Image.ColorMap->ColorCount,
GifFile->Image.ColorMap->Colors);
if (sp->ImageDesc.ColorMap == NULL) {
return GIF_ERROR;
}
}
sp->RasterBits = (unsigned char *)NULL;
sp->ExtensionBlockCount = 0;
sp->ExtensionBlocks = (ExtensionBlock *) NULL;
GifFile->ImageCount++;
Private->PixelCount = (long)GifFile->Image.Width *
(long)GifFile->Image.Height;
DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */
return GIF_OK;
}
/******************************************************************************
* Get one full scanned line (Line) of length LineLen from GIF file.
*****************************************************************************/
static int
DGifGetLine(GifFileType * GifFile,
GifPixelType * Line,
int LineLen) {
GifByteType *Dummy;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
if (!LineLen)
LineLen = GifFile->Image.Width;
if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
return GIF_ERROR;
}
if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
if (Private->PixelCount == 0) {
/* We probably would not be called any more, so lets clean
* everything before we return: need to flush out all rest of
* image until empty block (size 0) detected. We use GetCodeNext. */
do
if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
return GIF_ERROR;
while (Dummy != NULL) ;
}
return GIF_OK;
} else
return GIF_ERROR;
}
/******************************************************************************
* Get an extension block (see GIF manual) from gif file. This routine only
* returns the first data block, and DGifGetExtensionNext should be called
* after this one until NULL extension is returned.
* The Extension should NOT be freed by the user (not dynamically allocated).
* Note it is assumed the Extension desc. header ('!') has been read.
*****************************************************************************/
static int
DGifGetExtension(GifFileType * GifFile,
int *ExtCode,
GifByteType ** Extension) {
GifByteType Buf;
if (READ(GifFile, &Buf, 1) != 1) {
return GIF_ERROR;
}
*ExtCode = Buf;
return DGifGetExtensionNext(GifFile, Extension);
}
/******************************************************************************
* Get a following extension block (see GIF manual) from gif file. This
* routine should be called until NULL Extension is returned.
* The Extension should NOT be freed by the user (not dynamically allocated).
*****************************************************************************/
static int
DGifGetExtensionNext(GifFileType * GifFile,
GifByteType ** Extension) {
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (READ(GifFile, &Buf, 1) != 1) {
return GIF_ERROR;
}
if (Buf > 0) {
*Extension = Private->Buf; /* Use private unused buffer. */
(*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
return GIF_ERROR;
}
} else
*Extension = NULL;
return GIF_OK;
}
/******************************************************************************
* Get 2 bytes (word) from the given file:
*****************************************************************************/
static int
DGifGetWord(GifFileType * GifFile,
GifWord *Word) {
unsigned char c[2];
if (READ(GifFile, c, 2) != 2) {
return GIF_ERROR;
}
*Word = (((unsigned int)c[1]) << 8) + c[0];
return GIF_OK;
}
/******************************************************************************
* Continue to get the image code in compressed form. This routine should be
* called until NULL block is returned.
* The block should NOT be freed by the user (not dynamically allocated).
*****************************************************************************/
static int
DGifGetCodeNext(GifFileType * GifFile,
GifByteType ** CodeBlock) {
GifByteType Buf;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
if (READ(GifFile, &Buf, 1) != 1) {
return GIF_ERROR;
}
if (Buf > 0) {
*CodeBlock = Private->Buf; /* Use private unused buffer. */
(*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
return GIF_ERROR;
}
} else {
*CodeBlock = NULL;
Private->Buf[0] = 0; /* Make sure the buffer is empty! */
Private->PixelCount = 0; /* And local info. indicate image read. */
}
return GIF_OK;
}
/******************************************************************************
* Setup the LZ decompression for this image:
*****************************************************************************/
static int
DGifSetupDecompress(GifFileType * GifFile) {
int i, BitsPerPixel;
GifByteType CodeSize;
GifPrefixType *Prefix;
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
BitsPerPixel = CodeSize;
Private->Buf[0] = 0; /* Input Buffer empty. */
Private->BitsPerPixel = BitsPerPixel;
Private->ClearCode = (1 << BitsPerPixel);
Private->EOFCode = Private->ClearCode + 1;
Private->RunningCode = Private->EOFCode + 1;
Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
Private->StackPtr = 0; /* No pixels on the pixel stack. */
Private->LastCode = NO_SUCH_CODE;
Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
Private->CrntShiftDWord = 0;
Prefix = Private->Prefix;
for (i = 0; i <= LZ_MAX_CODE; i++)
Prefix[i] = NO_SUCH_CODE;
return GIF_OK;
}
/******************************************************************************
* The LZ decompression routine:
* This version decompress the given gif file into Line of length LineLen.
* This routine can be called few times (one per scan line, for example), in
* order the complete the whole image.
*****************************************************************************/
static int
DGifDecompressLine(GifFileType * GifFile,
GifPixelType * Line,
int LineLen) {
int i = 0;
int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
GifByteType *Stack, *Suffix;
GifPrefixType *Prefix;
GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
StackPtr = Private->StackPtr;
Prefix = Private->Prefix;
Suffix = Private->Suffix;
Stack = Private->Stack;
EOFCode = Private->EOFCode;
ClearCode = Private->ClearCode;
LastCode = Private->LastCode;
if (StackPtr != 0) {
/* Let pop the stack off before continueing to read the gif file: */
while (StackPtr != 0 && i < LineLen)
Line[i++] = Stack[--StackPtr];
}
while (i < LineLen) { /* Decode LineLen items. */
if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
return GIF_ERROR;
if (CrntCode == EOFCode) {
/* Note however that usually we will not be here as we will stop
* decoding as soon as we got all the pixel, or EOF code will
* not be read at all, and DGifGetLine/Pixel clean everything. */
if (i != LineLen - 1 || Private->PixelCount != 0) {
return GIF_ERROR;
}
i++;
} else if (CrntCode == ClearCode) {
/* We need to start over again: */
for (j = 0; j <= LZ_MAX_CODE; j++)
Prefix[j] = NO_SUCH_CODE;
Private->RunningCode = Private->EOFCode + 1;
Private->RunningBits = Private->BitsPerPixel + 1;
Private->MaxCode1 = 1 << Private->RunningBits;
LastCode = Private->LastCode = NO_SUCH_CODE;
} else {
/* Its regular code - if in pixel range simply add it to output
* stream, otherwise trace to codes linked list until the prefix
* is in pixel range: */
if (CrntCode < ClearCode) {
/* This is simple - its pixel scalar, so add it to output: */
Line[i++] = CrntCode;
} else {
/* Its a code to needed to be traced: trace the linked list
* until the prefix is a pixel, while pushing the suffix
* pixels on our stack. If we done, pop the stack in reverse
* (thats what stack is good for!) order to output. */
if (Prefix[CrntCode] == NO_SUCH_CODE) {
/* Only allowed if CrntCode is exactly the running code:
* In that case CrntCode = XXXCode, CrntCode or the
* prefix code is last code and the suffix char is
* exactly the prefix of last code! */
if (CrntCode == Private->RunningCode - 2) {
CrntPrefix = LastCode;
Suffix[Private->RunningCode - 2] =
Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
LastCode,
ClearCode);
} else {
return GIF_ERROR;
}
} else
CrntPrefix = CrntCode;
/* Now (if image is O.K.) we should not get a NO_SUCH_CODE
* during the trace. As we might loop forever, in case of
* defective image, we count the number of loops we trace
* and stop if we got LZ_MAX_CODE. Obviously we cannot
* loop more than that. */
j = 0;
while (j++ <= LZ_MAX_CODE &&
CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
Stack[StackPtr++] = Suffix[CrntPrefix];
CrntPrefix = Prefix[CrntPrefix];
}
if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
return GIF_ERROR;
}
/* Push the last character on stack: */
Stack[StackPtr++] = CrntPrefix;
/* Now lets pop all the stack into output: */
while (StackPtr != 0 && i < LineLen)
Line[i++] = Stack[--StackPtr];
}
if (LastCode != NO_SUCH_CODE) {
Prefix[Private->RunningCode - 2] = LastCode;
if (CrntCode == Private->RunningCode - 2) {
/* Only allowed if CrntCode is exactly the running code:
* In that case CrntCode = XXXCode, CrntCode or the
* prefix code is last code and the suffix char is
* exactly the prefix of last code! */
Suffix[Private->RunningCode - 2] =
DGifGetPrefixChar(Prefix, LastCode, ClearCode);
} else {
Suffix[Private->RunningCode - 2] =
DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
}
}
LastCode = CrntCode;
}
}
Private->LastCode = LastCode;
Private->StackPtr = StackPtr;
return GIF_OK;
}
/******************************************************************************
* Routine to trace the Prefixes linked list until we get a prefix which is
* not code, but a pixel value (less than ClearCode). Returns that pixel value.
* If image is defective, we might loop here forever, so we limit the loops to
* the maximum possible if image O.k. - LZ_MAX_CODE times.
*****************************************************************************/
static int
DGifGetPrefixChar(GifPrefixType *Prefix,
int Code,
int ClearCode) {
int i = 0;
while (Code > ClearCode && i++ <= LZ_MAX_CODE)
Code = Prefix[Code];
return Code;
}
/******************************************************************************
* The LZ decompression input routine:
* This routine is responsible for the decompression of the bit stream from
* 8 bits (bytes) packets, into the real codes.
* Returns GIF_OK if read successfully.
*****************************************************************************/
static int
DGifDecompressInput(GifFileType * GifFile,
int *Code) {
GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
GifByteType NextByte;
static const unsigned short CodeMasks[] = {
0x0000, 0x0001, 0x0003, 0x0007,
0x000f, 0x001f, 0x003f, 0x007f,
0x00ff, 0x01ff, 0x03ff, 0x07ff,
0x0fff
};
/* The image can't contain more than LZ_BITS per code. */
if (Private->RunningBits > LZ_BITS) {
return GIF_ERROR;
}
while (Private->CrntShiftState < Private->RunningBits) {
/* Needs to get more bytes from input stream for next code: */
if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
return GIF_ERROR;
}
Private->CrntShiftDWord |=
((unsigned long)NextByte) << Private->CrntShiftState;
Private->CrntShiftState += 8;
}
*Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
Private->CrntShiftDWord >>= Private->RunningBits;
Private->CrntShiftState -= Private->RunningBits;
/* If code cannot fit into RunningBits bits, must raise its size. Note
* however that codes above 4095 are used for special signaling.
* If we're using LZ_BITS bits already and we're at the max code, just
* keep using the table as it is, don't increment Private->RunningCode.
*/
if (Private->RunningCode < LZ_MAX_CODE + 2 &&
++Private->RunningCode > Private->MaxCode1 &&
Private->RunningBits < LZ_BITS) {
Private->MaxCode1 <<= 1;
Private->RunningBits++;
}
return GIF_OK;
}
/******************************************************************************
* This routines read one gif data block at a time and buffers it internally
* so that the decompression routine could access it.
* The routine returns the next byte from its internal buffer (or read next
* block in if buffer empty) and returns GIF_OK if successful.
*****************************************************************************/
static int
DGifBufferedInput(GifFileType * GifFile,
GifByteType * Buf,
GifByteType * NextByte) {
if (Buf[0] == 0) {
/* Needs to read the next buffer - this one is empty: */
if (READ(GifFile, Buf, 1) != 1) {
return GIF_ERROR;
}
/* There shouldn't be any empty data blocks here as the LZW spec
* says the LZW termination code should come first. Therefore we
* shouldn't be inside this routine at that point.
*/
if (Buf[0] == 0) {
return GIF_ERROR;
}
if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
return GIF_ERROR;
}
*NextByte = Buf[1];
Buf[1] = 2; /* We use now the second place as last char read! */
Buf[0]--;
} else {
*NextByte = Buf[Buf[1]++];
Buf[0]--;
}
return GIF_OK;
}
/******************************************************************************
* This routine reads an entire GIF into core, hanging all its state info off
* the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
* first to initialize I/O. Its inverse is EGifSpew().
******************************************************************************/
int
DGifSlurp(GifFileType * GifFile) {
int ImageSize;
GifRecordType RecordType;
SavedImage *sp;
GifByteType *ExtData;
SavedImage temp_save;
temp_save.ExtensionBlocks = NULL;
temp_save.ExtensionBlockCount = 0;
do {
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
return (GIF_ERROR);
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFile) == GIF_ERROR)
return (GIF_ERROR);
sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
sp->RasterBits = ungif_alloc(ImageSize * sizeof(GifPixelType));
if (sp->RasterBits == NULL) {
return GIF_ERROR;
}
if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) ==
GIF_ERROR)
return (GIF_ERROR);
if (temp_save.ExtensionBlocks) {
sp->ExtensionBlocks = temp_save.ExtensionBlocks;
sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;
temp_save.ExtensionBlocks = NULL;
temp_save.ExtensionBlockCount = 0;
/* FIXME: The following is wrong. It is left in only for
* backwards compatibility. Someday it should go away. Use
* the sp->ExtensionBlocks->Function variable instead. */
sp->Function = sp->ExtensionBlocks[0].Function;
}
break;
case EXTENSION_RECORD_TYPE:
if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) ==
GIF_ERROR)
return (GIF_ERROR);
while (ExtData != NULL) {
/* Create an extension block with our data */
if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1])
== GIF_ERROR)
return (GIF_ERROR);
if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
return (GIF_ERROR);
temp_save.Function = 0;
}
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be trapped by DGifGetRecordType */
break;
}
} while (RecordType != TERMINATE_RECORD_TYPE);
/* Just in case the Gif has an extension block without an associated
* image... (Should we save this into a savefile structure with no image
* instead? Have to check if the present writing code can handle that as
* well.... */
if (temp_save.ExtensionBlocks)
FreeExtension(&temp_save);
return (GIF_OK);
}
/******************************************************************************
* GifFileType constructor with user supplied input function (TVT)
*****************************************************************************/
GifFileType *
DGifOpen(void *userData,
InputFunc readFunc) {
unsigned char Buf[GIF_STAMP_LEN + 1];
GifFileType *GifFile;
GifFilePrivateType *Private;
GifFile = ungif_alloc(sizeof(GifFileType));
if (GifFile == NULL) {
return NULL;
}
memset(GifFile, '\0', sizeof(GifFileType));
Private = ungif_alloc(sizeof(GifFilePrivateType));
if (!Private) {
ungif_free(GifFile);
return NULL;
}
GifFile->Private = (void*)Private;
Private->Read = readFunc; /* TVT */
GifFile->UserData = userData; /* TVT */
/* Lets see if this is a GIF file: */
if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
ungif_free(Private);
ungif_free(GifFile);
return NULL;
}
/* The GIF Version number is ignored at this time. Maybe we should do
* something more useful with it. */
Buf[GIF_STAMP_LEN] = 0;
if (memcmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
ungif_free(Private);
ungif_free(GifFile);
return NULL;
}
if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
ungif_free(Private);
ungif_free(GifFile);
return NULL;
}
return GifFile;
}
/******************************************************************************
* This routine should be called last, to close the GIF file.
*****************************************************************************/
int
DGifCloseFile(GifFileType * GifFile) {
GifFilePrivateType *Private;
if (GifFile == NULL)
return GIF_ERROR;
Private = (GifFilePrivateType *) GifFile->Private;
if (GifFile->Image.ColorMap) {
FreeMapObject(GifFile->Image.ColorMap);
GifFile->Image.ColorMap = NULL;
}
if (GifFile->SColorMap) {
FreeMapObject(GifFile->SColorMap);
GifFile->SColorMap = NULL;
}
ungif_free(Private);
Private = NULL;
if (GifFile->SavedImages) {
FreeSavedImages(GifFile);
GifFile->SavedImages = NULL;
}
ungif_free(GifFile);
return GIF_OK;
}

View File

@ -0,0 +1,169 @@
/*
* Gif extracting routines - derived from libungif
*
* Portions Copyright 2006 Mike McCormack
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* Original copyright notice:
*
* The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
/******************************************************************************
* In order to make life a little bit easier when using the GIF file format,
* this library was written, and which does all the dirty work...
*
* Written by Gershon Elber, Jun. 1989
* Hacks by Eric S. Raymond, Sep. 1992
******************************************************************************
* History:
* 14 Jun 89 - Version 1.0 by Gershon Elber.
* 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names)
* 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to suoport GIF slurp)
* 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support)
* 17 Dec 98 - Version 4.0 by Toshio Kuratomi (Fix extension writing code)
*****************************************************************************/
#ifndef _UNGIF_H_
#define _UNGIF_H_ 1
#define GIF_ERROR 0
#define GIF_OK 1
#ifndef TRUE
#define TRUE 1
#endif /* TRUE */
#ifndef FALSE
#define FALSE 0
#endif /* FALSE */
#ifndef NULL
#define NULL 0
#endif /* NULL */
#define GIF_STAMP "GIFVER" /* First chars in file - GIF stamp. */
#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
#define GIF_VERSION_POS 3 /* Version first character in stamp. */
#define GIF87_STAMP "GIF87a" /* First chars in file - GIF stamp. */
#define GIF89_STAMP "GIF89a" /* First chars in file - GIF stamp. */
#define GIF_FILE_BUFFER_SIZE 16384 /* Files uses bigger buffers than usual. */
typedef int GifBooleanType;
typedef unsigned char GifPixelType;
typedef unsigned char *GifRowType;
typedef unsigned char GifByteType;
typedef unsigned int GifPrefixType;
typedef int GifWord;
typedef struct GifColorType {
GifByteType Red, Green, Blue;
} GifColorType;
typedef struct ColorMapObject {
int ColorCount;
int BitsPerPixel;
GifColorType *Colors;
} ColorMapObject;
typedef struct GifImageDesc {
GifWord Left, Top, Width, Height, /* Current image dimensions. */
Interlace; /* Sequential/Interlaced lines. */
ColorMapObject *ColorMap; /* The local color map */
} GifImageDesc;
typedef struct GifFileType {
GifWord SWidth, SHeight, /* Screen dimensions. */
SColorResolution, /* How many colors can we generate? */
SBackGroundColor; /* I hope you understand this one... */
ColorMapObject *SColorMap; /* NULL if not exists. */
int ImageCount; /* Number of current image */
GifImageDesc Image; /* Block describing current image */
struct SavedImage *SavedImages; /* Use this to accumulate file state */
void *UserData; /* hook to attach user data (TVT) */
void *Private; /* Don't mess with this! */
} GifFileType;
typedef enum {
UNDEFINED_RECORD_TYPE,
SCREEN_DESC_RECORD_TYPE,
IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
EXTENSION_RECORD_TYPE, /* Begin with '!' */
TERMINATE_RECORD_TYPE /* Begin with ';' */
} GifRecordType;
/* func type to read gif data from arbitrary sources (TVT) */
typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
/* GIF89 extension function codes */
#define COMMENT_EXT_FUNC_CODE 0xfe /* comment */
#define GRAPHICS_EXT_FUNC_CODE 0xf9 /* graphics control */
#define PLAINTEXT_EXT_FUNC_CODE 0x01 /* plaintext */
#define APPLICATION_EXT_FUNC_CODE 0xff /* application block */
/* public interface to ungif.c */
int DGifSlurp(GifFileType * GifFile);
GifFileType *DGifOpen(void *userPtr, InputFunc readFunc);
int DGifCloseFile(GifFileType * GifFile);
#define D_GIF_ERR_OPEN_FAILED 101 /* And DGif possible errors. */
#define D_GIF_ERR_READ_FAILED 102
#define D_GIF_ERR_NOT_GIF_FILE 103
#define D_GIF_ERR_NO_SCRN_DSCR 104
#define D_GIF_ERR_NO_IMAG_DSCR 105
#define D_GIF_ERR_NO_COLOR_MAP 106
#define D_GIF_ERR_WRONG_RECORD 107
#define D_GIF_ERR_DATA_TOO_BIG 108
#define D_GIF_ERR_NOT_ENOUGH_MEM 109
#define D_GIF_ERR_CLOSE_FAILED 110
#define D_GIF_ERR_NOT_READABLE 111
#define D_GIF_ERR_IMAGE_DEFECT 112
#define D_GIF_ERR_EOF_TOO_SOON 113
/******************************************************************************
* Support for the in-core structures allocation (slurp mode).
*****************************************************************************/
/* This is the in-core version of an extension record */
typedef struct {
int ByteCount;
char *Bytes;
int Function; /* Holds the type of the Extension block. */
} ExtensionBlock;
/* This holds an image header, its unpacked raster bits, and extensions */
typedef struct SavedImage {
GifImageDesc ImageDesc;
unsigned char *RasterBits;
int Function; /* DEPRECATED: Use ExtensionBlocks[x].Function instead */
int ExtensionBlockCount;
ExtensionBlock *ExtensionBlocks;
} SavedImage;
#endif /* _UNGIF_H_ */

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More