Author: akhaldi Date: Thu Sep 26 13:58:03 2013 New Revision: 60354
URL: http://svn.reactos.org/svn/reactos?rev=60354&view=rev Log: [OLE32] * Sync with Wine 1.7.1. CORE-7469
Modified: trunk/reactos/dll/win32/ole32/CMakeLists.txt trunk/reactos/dll/win32/ole32/compobj.c trunk/reactos/dll/win32/ole32/compobj_private.h trunk/reactos/dll/win32/ole32/compositemoniker.c trunk/reactos/dll/win32/ole32/errorinfo.c trunk/reactos/dll/win32/ole32/git.c trunk/reactos/dll/win32/ole32/ifs.c trunk/reactos/dll/win32/ole32/marshal.c trunk/reactos/dll/win32/ole32/ole2.c trunk/reactos/dll/win32/ole32/ole32.spec trunk/reactos/dll/win32/ole32/rpc.c trunk/reactos/dll/win32/ole32/stg_stream.c trunk/reactos/dll/win32/ole32/storage32.c trunk/reactos/dll/win32/ole32/storage32.h trunk/reactos/dll/win32/ole32/stubmanager.c trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/win32/ole32/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/CMakeLists.... ============================================================================== --- trunk/reactos/dll/win32/ole32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/CMakeLists.txt [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -1,7 +1,3 @@ - -spec2def(ole32.dll ole32.spec ADD_IMPORTLIB) -generate_idl_iids(dcom.idl) -add_idl_headers(ole32idl dcom.idl irot.idl)
remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) @@ -16,6 +12,9 @@
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
+spec2def(ole32.dll ole32.spec ADD_IMPORTLIB) +generate_idl_iids(dcom.idl) +add_idl_headers(ole32idl dcom.idl irot.idl) add_rpc_files(client irot.idl)
add_rpcproxy_files( @@ -60,13 +59,12 @@ storage32.c stubmanager.c usrmarshal.c - ole32res.rc ${CMAKE_CURRENT_BINARY_DIR}/dcom_i.c ${CMAKE_CURRENT_BINARY_DIR}/dcom_p.c ${CMAKE_CURRENT_BINARY_DIR}/irot_c.c - ${CMAKE_CURRENT_BINARY_DIR}/ole32_unknwn_p.c ${CMAKE_CURRENT_BINARY_DIR}/ole32_objidl_p.c ${CMAKE_CURRENT_BINARY_DIR}/ole32_oleidl_p.c + ${CMAKE_CURRENT_BINARY_DIR}/ole32_unknwn_p.c ${CMAKE_CURRENT_BINARY_DIR}/ole32_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/proxy.dlldata.c ${CMAKE_CURRENT_BINARY_DIR}/ole32.def) @@ -78,7 +76,7 @@ set_source_files_properties(stg_prop.c PROPERTIES COMPILE_FLAGS "/FImsvc.h") endif()
-add_library(ole32 SHARED ${SOURCE}) +add_library(ole32 SHARED ${SOURCE} ole32res.rc) set_module_type(ole32 win32dll) target_link_libraries(ole32 wine uuid ${PSEH_LIB}) add_importlibs(ole32 advapi32 user32 gdi32 rpcrt4 msvcrt kernel32 ntdll)
Modified: trunk/reactos/dll/win32/ole32/compobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/compobj.c?r... ============================================================================== --- trunk/reactos/dll/win32/ole32/compobj.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/compobj.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -61,6 +61,7 @@ #include <ole2ver.h> #include <ctxtcall.h> #include <dde.h> +#include <servprov.h>
#include <initguid.h> #include "compobj_private.h" @@ -95,6 +96,20 @@ struct list entry; IID iid; CLSID clsid; +}; + +/* + * This is a marshallable object exposing registered local servers. + * IServiceProvider is used only because it happens meet requirements + * and already has proxy/stub code. If more functionality is needed, + * a custom interface may be used instead. + */ +struct LocalServer +{ + IServiceProvider IServiceProvider_iface; + LONG ref; + APARTMENT *apt; + IStream *marshal_stream; };
/* @@ -123,7 +138,6 @@ DWORD runContext; DWORD connectFlags; DWORD dwCookie; - LPSTREAM pMarshaledData; /* FIXME: only really need to store OXID and IPID */ void *RpcRegistration; } RegisteredClass;
@@ -384,6 +398,7 @@ entry->DllCanUnloadNow = DllCanUnloadNow; entry->DllGetClassObject = DllGetClassObject; list_add_tail(&openDllList, &entry->entry); + *ret = entry; } else { @@ -391,7 +406,6 @@ hr = E_OUTOFMEMORY; FreeLibrary(hLibrary); } - *ret = entry; }
LeaveCriticalSection( &csOpenDllList ); @@ -549,20 +563,7 @@ if (curClass->runContext & CLSCTX_LOCAL_SERVER) RPC_StopLocalServer(curClass->RpcRegistration);
- /* - * Release the reference to the class object. - */ IUnknown_Release(curClass->classObject); - - if (curClass->pMarshaledData) - { - LARGE_INTEGER zero; - memset(&zero, 0, sizeof(zero)); - IStream_Seek(curClass->pMarshaledData, zero, STREAM_SEEK_SET, NULL); - CoReleaseMarshalData(curClass->pMarshaledData); - IStream_Release(curClass->pMarshaledData); - } - HeapFree(GetProcessHeap(), 0, curClass); }
@@ -728,6 +729,130 @@ hr = ISynchronize_QueryInterface(&This->ISynchronize_iface, iid, ppv); ISynchronize_Release(&This->ISynchronize_iface); return hr; +} + +static inline LocalServer *impl_from_IServiceProvider(IServiceProvider *iface) +{ + return CONTAINING_RECORD(iface, LocalServer, IServiceProvider_iface); +} + +static HRESULT WINAPI LocalServer_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv) +{ + LocalServer *This = impl_from_IServiceProvider(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + + if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IServiceProvider)) { + *ppv = &This->IServiceProvider_iface; + }else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI LocalServer_AddRef(IServiceProvider *iface) +{ + LocalServer *This = impl_from_IServiceProvider(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI LocalServer_Release(IServiceProvider *iface) +{ + LocalServer *This = impl_from_IServiceProvider(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + assert(!This->apt); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI LocalServer_QueryService(IServiceProvider *iface, REFGUID guid, REFIID riid, void **ppv) +{ + LocalServer *This = impl_from_IServiceProvider(iface); + APARTMENT *apt = COM_CurrentApt(); + RegisteredClass *iter; + HRESULT hres = E_FAIL; + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guid), debugstr_guid(riid), ppv); + + if(!This->apt) + return E_UNEXPECTED; + + EnterCriticalSection(&csRegisteredClassList); + + LIST_FOR_EACH_ENTRY(iter, &RegisteredClassList, RegisteredClass, entry) { + if(iter->apartment_id == apt->oxid + && (iter->runContext & CLSCTX_LOCAL_SERVER) + && IsEqualGUID(&iter->classIdentifier, guid)) { + hres = IUnknown_QueryInterface(iter->classObject, riid, ppv); + break; + } + } + + LeaveCriticalSection( &csRegisteredClassList ); + + return hres; +} + +static const IServiceProviderVtbl LocalServerVtbl = { + LocalServer_QueryInterface, + LocalServer_AddRef, + LocalServer_Release, + LocalServer_QueryService +}; + +static HRESULT get_local_server_stream(APARTMENT *apt, IStream **ret) +{ + HRESULT hres = S_OK; + + EnterCriticalSection(&apt->cs); + + if(!apt->local_server) { + LocalServer *obj; + + obj = heap_alloc(sizeof(*obj)); + if(obj) { + obj->IServiceProvider_iface.lpVtbl = &LocalServerVtbl; + obj->ref = 1; + obj->apt = apt; + + hres = CreateStreamOnHGlobal(0, TRUE, &obj->marshal_stream); + if(SUCCEEDED(hres)) { + hres = CoMarshalInterface(obj->marshal_stream, &IID_IServiceProvider, (IUnknown*)&obj->IServiceProvider_iface, + MSHCTX_LOCAL, NULL, MSHLFLAGS_TABLESTRONG); + if(FAILED(hres)) + IStream_Release(obj->marshal_stream); + } + + if(SUCCEEDED(hres)) + apt->local_server = obj; + else + heap_free(obj); + }else { + hres = E_OUTOFMEMORY; + } + } + + if(SUCCEEDED(hres)) + hres = IStream_Clone(apt->local_server->marshal_stream, ret); + + LeaveCriticalSection(&apt->cs); + + if(FAILED(hres)) + ERR("Failed: %08x\n", hres); + return hres; }
/*********************************************************************** @@ -859,6 +984,21 @@ struct list *cursor, *cursor2;
TRACE("destroying apartment %p, oxid %s\n", apt, wine_dbgstr_longlong(apt->oxid)); + + if(apt->local_server) { + LocalServer *local_server = apt->local_server; + LARGE_INTEGER zero; + + memset(&zero, 0, sizeof(zero)); + IStream_Seek(local_server->marshal_stream, zero, STREAM_SEEK_SET, NULL); + CoReleaseMarshalData(local_server->marshal_stream); + IStream_Release(local_server->marshal_stream); + local_server->marshal_stream = NULL; + + apt->local_server = NULL; + local_server->apt = NULL; + IServiceProvider_Release(&local_server->IServiceProvider_iface); + }
/* Release the references to the registered class objects */ COM_RevokeAllClasses(apt); @@ -2103,6 +2243,15 @@ return __CLSIDFromString(buf2,clsid); }
+/****************************************************************************** + * CLSIDFromProgIDEx [OLE32.@] + */ +HRESULT WINAPI CLSIDFromProgIDEx(LPCOLESTR progid, LPCLSID clsid) +{ + FIXME("%s,%p: semi-stub\n", debugstr_w(progid), clsid); + + return CLSIDFromProgID(progid, clsid); +}
/***************************************************************************** * CoGetPSClsid [OLE32.@] @@ -2407,7 +2556,6 @@ newClass->apartment_id = apt->oxid; newClass->runContext = dwClsContext; newClass->connectFlags = flags; - newClass->pMarshaledData = NULL; newClass->RpcRegistration = NULL;
if (!(newClass->dwCookie = InterlockedIncrement( &next_cookie ))) @@ -2427,23 +2575,17 @@ *lpdwRegister = newClass->dwCookie;
if (dwClsContext & CLSCTX_LOCAL_SERVER) { - hr = CreateStreamOnHGlobal(0, TRUE, &newClass->pMarshaledData); - if (hr) { - FIXME("Failed to create stream on hglobal, %x\n", hr); + IStream *marshal_stream; + + hr = get_local_server_stream(apt, &marshal_stream); + if(FAILED(hr)) return hr; - } - hr = CoMarshalInterface(newClass->pMarshaledData, &IID_IUnknown, - newClass->classObject, MSHCTX_LOCAL, NULL, - MSHLFLAGS_TABLESTRONG); - if (hr) { - FIXME("CoMarshalInterface failed, %x!\n",hr); - return hr; - }
hr = RPC_StartLocalServer(&newClass->classIdentifier, - newClass->pMarshaledData, + marshal_stream, flags & (REGCLS_MULTIPLEUSE|REGCLS_MULTI_SEPARATE), &newClass->RpcRegistration); + IStream_Release(marshal_stream); } return S_OK; } @@ -2768,16 +2910,12 @@
/* * The Standard Global Interface Table (GIT) object is a process-wide singleton. - * Rather than create a class factory, we can just check for it here */ if (IsEqualIID(rclsid, &CLSID_StdGlobalInterfaceTable)) { - if (StdGlobalInterfaceTableInstance == NULL) - StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct(); - hres = IGlobalInterfaceTable_QueryInterface((IGlobalInterfaceTable*)StdGlobalInterfaceTableInstance, - iid, - ppv); - if (hres) return hres; + IGlobalInterfaceTable *git = get_std_git(); + hres = IGlobalInterfaceTable_QueryInterface(git, iid, ppv); + if (hres != S_OK) return hres;
TRACE("Retrieved GIT (%p)\n", *ppv); return S_OK; @@ -2859,7 +2997,7 @@ &IID_IUnknown, (VOID**)&pUnk);
- if (hr) + if (hr != S_OK) return hr;
/* @@ -4445,9 +4583,9 @@ /*********************************************************************** * DllMain (OLE32.@) */ -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) -{ - TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad); +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved) +{ + TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, reserved);
switch(fdwReason) { case DLL_PROCESS_ATTACH: @@ -4456,6 +4594,8 @@ break;
case DLL_PROCESS_DETACH: + if (reserved) break; + release_std_git(); COMPOBJ_UninitProcess(); RPC_UnregisterAllChannelHooks(); COMPOBJ_DllList_Free();
Modified: trunk/reactos/dll/win32/ole32/compobj_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/compobj_pri... ============================================================================== --- trunk/reactos/dll/win32/ole32/compobj_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/compobj_private.h [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -40,6 +40,7 @@
struct apartment; typedef struct apartment APARTMENT; +typedef struct LocalServer LocalServer;
DEFINE_OLEGUID( CLSID_DfMarshal, 0x0000030b, 0, 0 );
@@ -96,6 +97,8 @@ 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) */ + + IExternalConnection *extern_conn;
/* 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 @@ -137,6 +140,7 @@ struct list loaded_dlls; /* list of dlls loaded by this apartment (CS cs) */ DWORD host_apt_tid; /* thread ID of apartment hosting objects of differing threading model (CS cs) */ HWND host_apt_hwnd; /* handle to apartment window of host apartment (CS cs) */ + LocalServer *local_server; /* A marshallable object exposing local servers (CS cs) */
/* FIXME: OIDs should be given out by RPCSS */ OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */ @@ -169,10 +173,9 @@
/* Global Interface Table Functions */ - -extern void* StdGlobalInterfaceTable_Construct(void) DECLSPEC_HIDDEN; +extern IGlobalInterfaceTable *get_std_git(void) DECLSPEC_HIDDEN; +extern void release_std_git(void) DECLSPEC_HIDDEN; extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) DECLSPEC_HIDDEN; -extern void* StdGlobalInterfaceTableInstance DECLSPEC_HIDDEN;
HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *key) DECLSPEC_HIDDEN; HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey) DECLSPEC_HIDDEN; @@ -312,4 +315,14 @@ extern LSTATUS create_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN; extern LSTATUS open_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN;
+static inline void *heap_alloc(size_t len) +{ + return HeapAlloc(GetProcessHeap(), 0, len); +} + +static inline BOOL heap_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +} + #endif /* __WINE_OLE_COMPOBJ_H */
Modified: trunk/reactos/dll/win32/ole32/compositemoniker.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/compositemo... ============================================================================== --- trunk/reactos/dll/win32/ole32/compositemoniker.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/compositemoniker.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -239,7 +239,7 @@ if (++This->tabLastIndex==This->tabSize){
This->tabSize+=BLOCK_TAB_SIZE; - This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); + This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
if (This->tabMoniker==NULL) return E_OUTOFMEMORY; @@ -1446,7 +1446,7 @@ if (This->tabLastIndex + 2 > This->tabSize) { This->tabSize += max(BLOCK_TAB_SIZE, 2); - This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); + This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
if (This->tabMoniker==NULL) return E_OUTOFMEMORY; @@ -1661,7 +1661,7 @@ newEnumMoniker->tabSize=tabSize; newEnumMoniker->currentPos=currentPos;
- newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(IMoniker)); + newEnumMoniker->tabMoniker=HeapAlloc(GetProcessHeap(),0,tabSize*sizeof(newEnumMoniker->tabMoniker[0]));
if (newEnumMoniker->tabMoniker==NULL) { HeapFree(GetProcessHeap(), 0, newEnumMoniker); @@ -1768,7 +1768,7 @@ This->tabSize=BLOCK_TAB_SIZE; This->tabLastIndex=0;
- This->tabMoniker=HeapAlloc(GetProcessHeap(),0,This->tabSize*sizeof(IMoniker)); + This->tabMoniker=HeapAlloc(GetProcessHeap(),0,This->tabSize*sizeof(This->tabMoniker[0])); if (This->tabMoniker==NULL) { HeapFree(GetProcessHeap(), 0, This); return E_OUTOFMEMORY; @@ -1896,7 +1896,7 @@
This->tabSize+=BLOCK_TAB_SIZE;
- This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(IMoniker)); + This->tabMoniker=HeapReAlloc(GetProcessHeap(),0,This->tabMoniker,This->tabSize*sizeof(This->tabMoniker[0]));
if (This->tabMoniker==NULL){ HeapFree(GetProcessHeap(), 0, tab_moniker);
Modified: trunk/reactos/dll/win32/ole32/errorinfo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/errorinfo.c... ============================================================================== --- trunk/reactos/dll/win32/ole32/errorinfo.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/errorinfo.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -43,16 +43,6 @@ #include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(ole); - -static inline void *heap_alloc(size_t len) -{ - return HeapAlloc(GetProcessHeap(), 0, len); -} - -static inline BOOL heap_free(void *mem) -{ - return HeapFree(GetProcessHeap(), 0, mem); -}
static inline WCHAR *heap_strdupW(const WCHAR *str) {
Modified: trunk/reactos/dll/win32/ole32/git.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/git.c?rev=6... ============================================================================== --- trunk/reactos/dll/win32/ole32/git.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/git.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -69,13 +69,12 @@ { IGlobalInterfaceTable IGlobalInterfaceTable_iface;
- ULONG ref; struct list list; ULONG nextCookie;
} StdGlobalInterfaceTableImpl;
-void* StdGlobalInterfaceTableInstance; +static IGlobalInterfaceTable *std_git;
static CRITICAL_SECTION git_section; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -90,16 +89,6 @@ static inline StdGlobalInterfaceTableImpl *impl_from_IGlobalInterfaceTable(IGlobalInterfaceTable *iface) { return CONTAINING_RECORD(iface, StdGlobalInterfaceTableImpl, IGlobalInterfaceTable_iface); -} - -/** This destroys it again. It should revoke all the held interfaces first **/ -static void StdGlobalInterfaceTable_Destroy(void* This) -{ - TRACE("(%p)\n", This); - FIXME("Revoke held interfaces here\n"); - - HeapFree(GetProcessHeap(), 0, This); - StdGlobalInterfaceTableInstance = NULL; }
/*** @@ -150,25 +139,13 @@ static ULONG WINAPI StdGlobalInterfaceTable_AddRef(IGlobalInterfaceTable* iface) { - StdGlobalInterfaceTableImpl* const This = impl_from_IGlobalInterfaceTable(iface); - - /* InterlockedIncrement(&This->ref); */ - return This->ref; + return 1; }
static ULONG WINAPI StdGlobalInterfaceTable_Release(IGlobalInterfaceTable* iface) { - StdGlobalInterfaceTableImpl* const This = impl_from_IGlobalInterfaceTable(iface); - - /* InterlockedDecrement(&This->ref); */ - if (This->ref == 0) { - /* Hey ho, it's time to go, so long again 'till next weeks show! */ - StdGlobalInterfaceTable_Destroy(This); - return 0; - } - - return This->ref; + return 1; }
/*** @@ -206,7 +183,12 @@ IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry)); - if (entry == NULL) return E_OUTOFMEMORY; + if (!entry) + { + CoReleaseMarshalData(stream); + IStream_Release(stream); + return E_OUTOFMEMORY; + }
EnterCriticalSection(&git_section);
@@ -299,7 +281,7 @@ hres = CoUnmarshalInterface(stream, riid, ppv); IStream_Release(stream);
- if (hres) { + if (hres != S_OK) { WARN("Failed to unmarshal stream\n"); return hres; } @@ -314,8 +296,8 @@ GITCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) { *ppv = NULL; - if (IsEqualIID(riid,&IID_IUnknown) || - IsEqualIID(riid,&IID_IGlobalInterfaceTable)) + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IClassFactory)) { *ppv = iface; return S_OK; @@ -338,9 +320,8 @@ REFIID riid, LPVOID *ppv) { if (IsEqualIID(riid,&IID_IGlobalInterfaceTable)) { - if (StdGlobalInterfaceTableInstance == NULL) - StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct(); - return IGlobalInterfaceTable_QueryInterface( (IGlobalInterfaceTable*) StdGlobalInterfaceTableInstance, riid, ppv); + IGlobalInterfaceTable *git = get_std_git(); + return IGlobalInterfaceTable_QueryInterface(git, riid, ppv); }
FIXME("(%s), not supported.\n",debugstr_guid(riid)); @@ -361,11 +342,11 @@ GITCF_LockServer };
-static const IClassFactoryVtbl *PGITClassFactoryVtbl = &GITClassFactoryVtbl; +static IClassFactory git_classfactory = { &GITClassFactoryVtbl };
HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv) { - *ppv = &PGITClassFactoryVtbl; + *ppv = &git_classfactory; TRACE("Returning GIT classfactory\n"); return S_OK; } @@ -381,19 +362,46 @@ StdGlobalInterfaceTable_GetInterfaceFromGlobal };
-/** This function constructs the GIT. It should only be called once **/ -void* StdGlobalInterfaceTable_Construct(void) -{ - StdGlobalInterfaceTableImpl* newGIT; - - newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl)); - if (newGIT == 0) return newGIT; - - newGIT->IGlobalInterfaceTable_iface.lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl; - newGIT->ref = 1; /* Initialise the reference count */ - 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); - - return (void*)newGIT; -} +IGlobalInterfaceTable* get_std_git(void) +{ + if (!std_git) + { + StdGlobalInterfaceTableImpl* newGIT; + + newGIT = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGlobalInterfaceTableImpl)); + if (!newGIT) return NULL; + + newGIT->IGlobalInterfaceTable_iface.lpVtbl = &StdGlobalInterfaceTableImpl_Vtbl; + list_init(&newGIT->list); + newGIT->nextCookie = 0xf100; /* that's where windows starts, so that's where we start */ + + if (InterlockedCompareExchangePointer((void**)&std_git, &newGIT->IGlobalInterfaceTable_iface, NULL)) + { + HeapFree(GetProcessHeap(), 0, newGIT); + } + else + TRACE("Created the GIT at %p\n", newGIT); + } + + return std_git; +} + +void release_std_git(void) +{ + StdGlobalInterfaceTableImpl *git; + StdGITEntry *entry, *entry2; + + if (!std_git) return; + + git = impl_from_IGlobalInterfaceTable(std_git); + LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &git->list, StdGITEntry, entry) + { + list_remove(&entry->entry); + + CoReleaseMarshalData(entry->stream); + IStream_Release(entry->stream); + HeapFree(GetProcessHeap(), 0, entry); + } + + HeapFree(GetProcessHeap(), 0, git); +}
Modified: trunk/reactos/dll/win32/ole32/ifs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ifs.c?rev=6... ============================================================================== --- trunk/reactos/dll/win32/ole32/ifs.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ifs.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -81,7 +81,7 @@ LPVOID *NewSpyedBlocks;
if (!Malloc32.SpyedBlocks) NewSpyedBlocks = LocalAlloc(LMEM_ZEROINIT, NewLength * sizeof(PVOID)); - else NewSpyedBlocks = LocalReAlloc(Malloc32.SpyedBlocks, NewLength * sizeof(PVOID), LMEM_ZEROINIT); + else NewSpyedBlocks = LocalReAlloc(Malloc32.SpyedBlocks, NewLength * sizeof(PVOID), LMEM_ZEROINIT | LMEM_MOVEABLE); if (NewSpyedBlocks) { Malloc32.SpyedBlocks = NewSpyedBlocks; Malloc32.SpyedBlockTableLength = NewLength; @@ -220,13 +220,16 @@ IMallocSpy_Release(Malloc32.pSpy); Malloc32.SpyReleasePending = FALSE; Malloc32.pSpy = NULL; + LeaveCriticalSection(&IMalloc32_SpyCS); }
if (0==cb) { - /* PreRealloc can force Realloc to fail */ - LeaveCriticalSection(&IMalloc32_SpyCS); + /* PreRealloc can force Realloc to fail */ + if (Malloc32.pSpy) + LeaveCriticalSection(&IMalloc32_SpyCS); return NULL; } + pv = pRealMemory; }
Modified: trunk/reactos/dll/win32/ole32/marshal.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/marshal.c?r... ============================================================================== --- trunk/reactos/dll/win32/ole32/marshal.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/marshal.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -1440,6 +1440,7 @@
if (!(stubmgr = get_stub_manager(apt, stdobjref.oid))) { + apartment_release(apt); ERR("could not map object ID to stub manager, oxid=%s, oid=%s\n", wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(stdobjref.oid)); return RPC_E_INVALID_OBJREF;
Modified: trunk/reactos/dll/win32/ole32/ole2.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ole2.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/ole32/ole2.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ole2.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -885,11 +885,6 @@ LONG result;
/* - * Initialize the out parameter. - */ - *pdwStatus = 0; - - /* * Build the key name we're looking for */ sprintfW( keyName, clsidfmtW, @@ -899,6 +894,10 @@
TRACE("(%s, %d, %p)\n", debugstr_w(keyName), dwAspect, pdwStatus);
+ if (!pdwStatus) return E_INVALIDARG; + + *pdwStatus = 0; + /* * Open the class id Key */ @@ -913,7 +912,7 @@ if (result != ERROR_SUCCESS) { RegCloseKey(clsidKey); - return REGDB_E_READREGDB; + return S_OK; }
/*
Modified: trunk/reactos/dll/win32/ole32/ole32.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ole32.spec?... ============================================================================== --- trunk/reactos/dll/win32/ole32/ole32.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ole32.spec [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -4,6 +4,7 @@ @ stdcall CLIPFORMAT_UserSize(ptr long ptr) @ stdcall CLIPFORMAT_UserUnmarshal(ptr ptr ptr) @ stdcall CLSIDFromProgID(wstr ptr) +@ stdcall CLSIDFromProgIDEx(wstr ptr) @ stdcall CLSIDFromString(wstr ptr) @ stdcall CoAddRefServerProcess() @ stdcall CoAllowSetForegroundWindow(ptr ptr)
Modified: trunk/reactos/dll/win32/ole32/rpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/rpc.c?rev=6... ============================================================================== --- trunk/reactos/dll/win32/ole32/rpc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/rpc.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -42,6 +42,7 @@ //#include "rpc.h" //#include "winerror.h" //#include "winreg.h" +#include <servprov.h> #include <wine/unicode.h>
#include "compobj_private.h" @@ -1521,7 +1522,7 @@
/* if IRpcStubBuffer_Invoke fails, we should raise an exception to tell * the RPC runtime that the call failed */ - if (hr) RpcRaiseException(hr); + if (hr != S_OK) RpcRaiseException(hr); }
/* stub registration */ @@ -1658,6 +1659,7 @@ DWORD size = (MAX_PATH+1) * sizeof(WCHAR); STARTUPINFOW sinfo; PROCESS_INFORMATION pinfo; + LONG ret;
hres = COM_OpenKeyForCLSID(rclsid, wszLocalServer32, KEY_READ, &key); if (FAILED(hres)) { @@ -1665,9 +1667,9 @@ return hres; }
- hres = RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)command, &size); + ret = RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)command, &size); RegCloseKey(key); - if (hres) { + if (ret) { WARN("No default value for LocalServer32 key\n"); return REGDB_E_CLASSNOTREG; /* FIXME: check retval */ } @@ -1809,6 +1811,7 @@ LARGE_INTEGER seekto; ULARGE_INTEGER newpos; int tries = 0; + IServiceProvider *local_server;
static const int MAXTRIES = 30; /* 30 seconds */
@@ -1862,14 +1865,17 @@ return E_NOINTERFACE;
hres = CreateStreamOnHGlobal(0,TRUE,&pStm); - if (hres) return hres; + if (hres != S_OK) return hres; hres = IStream_Write(pStm,marshalbuffer,bufferlen,&res); - if (hres) goto out; + if (hres != S_OK) goto out; seekto.u.LowPart = 0;seekto.u.HighPart = 0; hres = IStream_Seek(pStm,seekto,STREAM_SEEK_SET,&newpos);
- TRACE("unmarshalling classfactory\n"); - hres = CoUnmarshalInterface(pStm,&IID_IClassFactory,ppv); + TRACE("unmarshalling local server\n"); + hres = CoUnmarshalInterface(pStm, &IID_IServiceProvider, (void**)&local_server); + if(SUCCEEDED(hres)) + hres = IServiceProvider_QueryService(local_server, rclsid, iid, ppv); + IServiceProvider_Release(local_server); out: IStream_Release(pStm); return hres; @@ -1920,50 +1926,38 @@ DWORD ret; ret = WaitForMultipleObjects(2, handles, FALSE, INFINITE); if (ret != WAIT_OBJECT_0) - { - CloseHandle(hPipe); break; - } } /* client already connected isn't an error */ else if (error != ERROR_PIPE_CONNECTED) { ERR("ConnectNamedPipe failed with error %d\n", GetLastError()); - CloseHandle(hPipe); break; } }
- TRACE("marshalling IClassFactory to client\n"); + TRACE("marshalling LocalServer to client\n");
hres = IStream_Stat(pStm,&ststg,STATFLAG_NONAME); - if (hres) - { - CloseHandle(hPipe); - CloseHandle(pipe_event); - return hres; - } + if (hres != S_OK) + break;
seekto.u.LowPart = 0; seekto.u.HighPart = 0; hres = IStream_Seek(pStm,seekto,STREAM_SEEK_SET,&newpos); - if (hres) { + if (hres != S_OK) { FIXME("IStream_Seek failed, %x\n",hres); - CloseHandle(hPipe); - CloseHandle(pipe_event); - return hres; + break; }
buflen = ststg.cbSize.u.LowPart; buffer = HeapAlloc(GetProcessHeap(),0,buflen);
hres = IStream_Read(pStm,buffer,buflen,&res); - if (hres) { + if (hres != S_OK) { FIXME("Stream Read failed, %x\n",hres); - CloseHandle(hPipe); - CloseHandle(pipe_event); HeapFree(GetProcessHeap(),0,buffer); - return hres; + break; }
WriteFile(hPipe,buffer,buflen,&res,&ovl); @@ -1972,27 +1966,27 @@
FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); - TRACE("done marshalling IClassFactory\n"); + TRACE("done marshalling LocalServer\n");
if (!multi_use) { TRACE("single use object, shutting down pipe %s\n", debugstr_w(pipefn)); - CloseHandle(hPipe); break; } new_pipe = CreateNamedPipeW( pipefn, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 4096, 4096, 500 /* 0.5 second timeout */, NULL ); + if (new_pipe == INVALID_HANDLE_VALUE) + { + FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError()); + break; + } CloseHandle(hPipe); - if (new_pipe == INVALID_HANDLE_VALUE) - { - FIXME("pipe creation failed for %s, le is %u\n", debugstr_w(pipefn), GetLastError()); - CloseHandle(pipe_event); - return 1; - } hPipe = new_pipe; } + CloseHandle(pipe_event); + CloseHandle(hPipe); return 0; }
Modified: trunk/reactos/dll/win32/ole32/stg_stream.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/stg_stream.... ============================================================================== --- trunk/reactos/dll/win32/ole32/stg_stream.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/stg_stream.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -43,40 +43,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(storage);
- -/*** - * This is the destructor of the StgStreamImpl class. - * - * This method will clean-up all the resources used-up by the given StgStreamImpl - * class. The pointer passed-in to this function will be freed and will not - * be valid anymore. - */ -static void StgStreamImpl_Destroy(StgStreamImpl* This) -{ - TRACE("(%p)\n", This); - - /* - * Release the reference we are holding on the parent storage. - * IStorage_Release(&This->parentStorage->IStorage_iface); - * - * 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 - */ - - if(This->parentStorage) { - - StorageBaseImpl_RemoveStream(This->parentStorage, This); - - } - - This->parentStorage = 0; - - HeapFree(GetProcessHeap(), 0, This); -} - /*** * This implements the IUnknown method QueryInterface for this * class @@ -126,17 +92,27 @@ IStream* iface) { StgStreamImpl* This = impl_from_IStream(iface); - - ULONG ref; - - ref = InterlockedDecrement(&This->ref); - - /* - * If the reference count goes down to 0, perform suicide. - */ - if (ref==0) - { - StgStreamImpl_Destroy(This); + ULONG ref = InterlockedDecrement(&This->ref); + + if (!ref) + { + TRACE("(%p)\n", This); + + /* + * Release the reference we are holding on the parent storage. + * IStorage_Release(&This->parentStorage->IStorage_iface); + * + * 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 + */ + + if (This->parentStorage) + StorageBaseImpl_RemoveStream(This->parentStorage, This); + This->parentStorage = 0; + HeapFree(GetProcessHeap(), 0, This); }
return ref;
Modified: trunk/reactos/dll/win32/ole32/storage32.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/storage32.c... ============================================================================== --- trunk/reactos/dll/win32/ole32/storage32.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/storage32.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -71,6 +71,11 @@ return CONTAINING_RECORD(iface, StorageBaseImpl, IStorage_iface); }
+static inline StorageBaseImpl *impl_from_IDirectWriterLock( IDirectWriterLock *iface ) +{ + return CONTAINING_RECORD(iface, StorageBaseImpl, IDirectWriterLock_iface); +} + /**************************************************************************** * Storage32InternalImpl definitions. * @@ -100,7 +105,7 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface); static void StorageImpl_Invalidate(StorageBaseImpl* iface); static HRESULT StorageImpl_Flush(StorageBaseImpl* iface); -static BOOL StorageImpl_ReadBigBlock(StorageImpl* This, ULONG blockIndex, void* buffer); +static HRESULT StorageImpl_ReadBigBlock(StorageImpl* This, ULONG blockIndex, void* buffer, ULONG *read ); static BOOL StorageImpl_WriteBigBlock(StorageImpl* This, ULONG blockIndex, const void* buffer); static void StorageImpl_SetNextBlockInChain(StorageImpl* This, ULONG blockIndex, ULONG nextBlock); static HRESULT StorageImpl_LoadFileHeader(StorageImpl* This); @@ -380,6 +385,11 @@ { *ppvObject = &This->IPropertySetStorage_iface; } + /* locking interface is reported for writer only */ + else if (IsEqualGUID(&IID_IDirectWriterLock, riid) && This->lockingrole == SWMR_Writer) + { + *ppvObject = &This->IDirectWriterLock_iface; + } else return E_NOINTERFACE;
@@ -722,9 +732,6 @@ if (newEnum) { *ppenum = &newEnum->IEnumSTATSTG_iface; - - IEnumSTATSTG_AddRef(*ppenum); - return S_OK; }
@@ -2605,9 +2612,7 @@ stream = *StorageImpl_GetCachedBlockChainStream(This, index); if (!stream) return E_OUTOFMEMORY;
- hr = BlockChainStream_WriteAt(stream, offset, size, buffer, bytesWritten); - - return hr; + return BlockChainStream_WriteAt(stream, offset, size, buffer, bytesWritten); } }
@@ -2647,6 +2652,55 @@
return hr; } + +static HRESULT WINAPI directwriterlock_QueryInterface(IDirectWriterLock *iface, REFIID riid, void **obj) +{ + StorageBaseImpl *This = impl_from_IDirectWriterLock(iface); + return IStorage_QueryInterface(&This->IStorage_iface, riid, obj); +} + +static ULONG WINAPI directwriterlock_AddRef(IDirectWriterLock *iface) +{ + StorageBaseImpl *This = impl_from_IDirectWriterLock(iface); + return IStorage_AddRef(&This->IStorage_iface); +} + +static ULONG WINAPI directwriterlock_Release(IDirectWriterLock *iface) +{ + StorageBaseImpl *This = impl_from_IDirectWriterLock(iface); + return IStorage_Release(&This->IStorage_iface); +} + +static HRESULT WINAPI directwriterlock_WaitForWriteAccess(IDirectWriterLock *iface, DWORD timeout) +{ + StorageBaseImpl *This = impl_from_IDirectWriterLock(iface); + FIXME("(%p)->(%d): stub\n", This, timeout); + return E_NOTIMPL; +} + +static HRESULT WINAPI directwriterlock_ReleaseWriteAccess(IDirectWriterLock *iface) +{ + StorageBaseImpl *This = impl_from_IDirectWriterLock(iface); + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI directwriterlock_HaveWriteAccess(IDirectWriterLock *iface) +{ + StorageBaseImpl *This = impl_from_IDirectWriterLock(iface); + FIXME("(%p): stub\n", This); + return E_NOTIMPL; +} + +static const IDirectWriterLockVtbl DirectWriterLockVtbl = +{ + directwriterlock_QueryInterface, + directwriterlock_AddRef, + directwriterlock_Release, + directwriterlock_WaitForWriteAccess, + directwriterlock_ReleaseWriteAccess, + directwriterlock_HaveWriteAccess +};
/* * Virtual function table for the IStorage32Impl class. @@ -2719,10 +2773,18 @@
This->base.IStorage_iface.lpVtbl = &Storage32Impl_Vtbl; This->base.IPropertySetStorage_iface.lpVtbl = &IPropertySetStorage_Vtbl; + This->base.IDirectWriterLock_iface.lpVtbl = &DirectWriterLockVtbl; This->base.baseVtbl = &StorageImpl_BaseVtbl; This->base.openFlags = (openFlags & ~STGM_CREATE); This->base.ref = 1; This->base.create = create; + + if (openFlags == (STGM_DIRECT_SWMR|STGM_READWRITE|STGM_SHARE_DENY_WRITE)) + This->base.lockingrole = SWMR_Writer; + else if (openFlags == (STGM_DIRECT_SWMR|STGM_READ|STGM_SHARE_DENY_NONE)) + This->base.lockingrole = SWMR_Reader; + else + This->base.lockingrole = SWMR_None;
This->base.reverted = 0;
@@ -2941,7 +3003,7 @@ } else { - StorageImpl_Flush((StorageBaseImpl*)This); + StorageImpl_Flush(&This->base); *result = This; }
@@ -2981,9 +3043,9 @@ HeapFree(GetProcessHeap(), 0, This); }
-static HRESULT StorageImpl_Flush(StorageBaseImpl* iface) -{ - StorageImpl *This = (StorageImpl*) iface; +static HRESULT StorageImpl_Flush(StorageBaseImpl *storage) +{ + StorageImpl *This = (StorageImpl*)storage; int i; HRESULT hr; TRACE("(%p)\n", This); @@ -3018,12 +3080,12 @@ { ULONG depotBlockIndexPos; BYTE depotBuffer[MAX_BIG_BLOCK_SIZE]; - BOOL success; ULONG depotBlockOffset; ULONG blocksPerDepot = This->bigBlockSize / sizeof(ULONG); ULONG nextBlockIndex = BLOCK_SPECIAL; int depotIndex = 0; ULONG freeBlock = BLOCK_UNUSED; + ULONG read; ULARGE_INTEGER neededSize; STATSTG statstg;
@@ -3113,9 +3175,9 @@ } }
- success = StorageImpl_ReadBigBlock(This, depotBlockIndexPos, depotBuffer); - - if (success) + StorageImpl_ReadBigBlock(This, depotBlockIndexPos, depotBuffer, &read); + + if (read) { while ( ( (depotBlockOffset/sizeof(ULONG) ) < blocksPerDepot) && ( nextBlockIndex != BLOCK_UNUSED)) @@ -3195,7 +3257,7 @@ { extBlockIndex = This->extBigBlockDepotLocations[extBlockCount];
- StorageImpl_ReadBigBlock(This, extBlockIndex, depotBuffer); + StorageImpl_ReadBigBlock(This, extBlockIndex, depotBuffer, NULL);
num_blocks = This->bigBlockSize / 4;
@@ -3357,7 +3419,7 @@ ULONG depotBlockCount = offsetInDepot / This->bigBlockSize; ULONG depotBlockOffset = offsetInDepot % This->bigBlockSize; BYTE depotBuffer[MAX_BIG_BLOCK_SIZE]; - BOOL success; + ULONG read; ULONG depotBlockIndexPos; int index, num_blocks;
@@ -3389,9 +3451,9 @@ depotBlockIndexPos = Storage32Impl_GetExtDepotBlock(This, depotBlockCount); }
- success = StorageImpl_ReadBigBlock(This, depotBlockIndexPos, depotBuffer); - - if (!success) + StorageImpl_ReadBigBlock(This, depotBlockIndexPos, depotBuffer, &read); + + if (!read) return STG_E_READFAULT;
num_blocks = This->bigBlockSize / 4; @@ -3784,20 +3846,17 @@ HRESULT StorageImpl_WriteRawDirEntry(StorageImpl *This, ULONG index, const BYTE *buffer) { ULARGE_INTEGER offset; - HRESULT hr; ULONG bytesRead;
offset.u.HighPart = 0; offset.u.LowPart = index * RAW_DIRENTRY_SIZE;
- hr = BlockChainStream_WriteAt( + return BlockChainStream_WriteAt( This->rootBlockChain, offset, RAW_DIRENTRY_SIZE, buffer, &bytesRead); - - return hr; }
/****************************************************************************** @@ -3969,35 +4028,37 @@ DirRef index, const DirEntry* buffer) { - BYTE currentEntry[RAW_DIRENTRY_SIZE]; - HRESULT writeRes; + BYTE currentEntry[RAW_DIRENTRY_SIZE];
UpdateRawDirEntry(currentEntry, buffer);
- writeRes = StorageImpl_WriteRawDirEntry(This, index, currentEntry); - return writeRes; -} - -static BOOL StorageImpl_ReadBigBlock( + return StorageImpl_WriteRawDirEntry(This, index, currentEntry); +} + +static HRESULT StorageImpl_ReadBigBlock( StorageImpl* This, ULONG blockIndex, - void* buffer) + void* buffer, + ULONG* out_read) { ULARGE_INTEGER ulOffset; DWORD read=0; + HRESULT hr;
ulOffset.u.HighPart = 0; ulOffset.u.LowPart = StorageImpl_GetBigBlockOffset(This, blockIndex);
- StorageImpl_ReadAt(This, ulOffset, buffer, This->bigBlockSize, &read); - - if (read && read < This->bigBlockSize) + hr = StorageImpl_ReadAt(This, ulOffset, buffer, This->bigBlockSize, &read); + + if (SUCCEEDED(hr) && read < This->bigBlockSize) { /* File ends during this block; fill the rest with 0's. */ memset((LPBYTE)buffer+read, 0, This->bigBlockSize-read); }
- return (read != 0); + if (out_read) *out_read = read; + + return hr; }
static BOOL StorageImpl_ReadDWordFromBigBlock( @@ -5120,7 +5181,7 @@ /* parentStorage already has 1 reference, which we take over here. */ (*result)->transactedParent = parentStorage;
- parentStorage->transactedChild = (StorageBaseImpl*)*result; + parentStorage->transactedChild = &(*result)->base;
(*result)->base.storageDirEntry = TransactedSnapshotImpl_CreateStubEntry(*result, parentStorage->storageDirEntry); } @@ -5132,7 +5193,7 @@ } }
- if (FAILED(hr)) HeapFree(GetProcessHeap(), 0, (*result)); + if (FAILED(hr)) HeapFree(GetProcessHeap(), 0, *result);
return hr; } @@ -5539,35 +5600,29 @@ IEnumSTATSTG** ppenum) { IEnumSTATSTGImpl* const This = impl_from_IEnumSTATSTG(iface); - IEnumSTATSTGImpl* newClone;
if (This->parentStorage->reverted) return STG_E_REVERTED;
- /* - * Perform a sanity check on the parameters. - */ if (ppenum==0) return E_INVALIDARG;
newClone = IEnumSTATSTGImpl_Construct(This->parentStorage, This->storageDirEntry); - + if (!newClone) + { + *ppenum = NULL; + return E_OUTOFMEMORY; + }
/* * The new clone enumeration must point to the same current node as - * the ole one. + * the old one. */ memcpy(newClone->name, This->name, sizeof(newClone->name));
*ppenum = &newClone->IEnumSTATSTG_iface; - - /* - * Don't forget to nail down a reference to the clone before - * returning it. - */ - IEnumSTATSTGImpl_AddRef(*ppenum);
return S_OK; } @@ -5598,13 +5653,11 @@
newEnumeration = HeapAlloc(GetProcessHeap(), 0, sizeof(IEnumSTATSTGImpl));
- if (newEnumeration!=0) - { - /* - * Set-up the virtual function table and reference count. - */ + if (newEnumeration) + { newEnumeration->IEnumSTATSTG_iface.lpVtbl = &IEnumSTATSTGImpl_Vtbl; - newEnumeration->ref = 0; + newEnumeration->ref = 1; + newEnumeration->name[0] = 0;
/* * We want to nail-down the reference to the storage in case the @@ -5613,12 +5666,7 @@ newEnumeration->parentStorage = parentStorage; IStorage_AddRef(&newEnumeration->parentStorage->IStorage_iface);
- newEnumeration->storageDirEntry = storageDirEntry; - - /* - * Make sure the current node of the iterator is the first one. - */ - IEnumSTATSTGImpl_Reset(&newEnumeration->IEnumSTATSTG_iface); + newEnumeration->storageDirEntry = storageDirEntry; }
return newEnumeration; @@ -6178,7 +6226,8 @@ { if (!cachedBlock->read) { - if (!StorageImpl_ReadBigBlock(This->parentStorage, cachedBlock->sector, cachedBlock->data)) + ULONG read; + if (FAILED(StorageImpl_ReadBigBlock(This->parentStorage, cachedBlock->sector, cachedBlock->data, &read)) && !read) return STG_E_READFAULT;
cachedBlock->read = 1; @@ -6262,7 +6311,8 @@ { if (!cachedBlock->read && bytesToWrite != This->parentStorage->bigBlockSize) { - if (!StorageImpl_ReadBigBlock(This->parentStorage, cachedBlock->sector, cachedBlock->data)) + ULONG read; + if (FAILED(StorageImpl_ReadBigBlock(This->parentStorage, cachedBlock->sector, cachedBlock->data, &read)) && !read) return STG_E_READFAULT; }
@@ -7604,7 +7654,16 @@ /* * Validate the sharing mode */ - if (!(grfMode & (STGM_TRANSACTED|STGM_PRIORITY))) + if (grfMode & STGM_DIRECT_SWMR) + { + if ((STGM_SHARE_MODE(grfMode) != STGM_SHARE_DENY_WRITE) && + (STGM_SHARE_MODE(grfMode) != STGM_SHARE_DENY_NONE)) + { + hr = STG_E_INVALIDFLAG; + goto end; + } + } + else if (!(grfMode & (STGM_TRANSACTED|STGM_PRIORITY))) switch(STGM_SHARE_MODE(grfMode)) { case STGM_SHARE_EXCLUSIVE: @@ -7622,10 +7681,10 @@ goto end; }
- /* shared reading requires transacted mode */ + /* shared reading requires transacted or single writer mode */ if( STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE && STGM_ACCESS_MODE(grfMode) == STGM_READWRITE && - !(grfMode&STGM_TRANSACTED) ) + !(grfMode & STGM_TRANSACTED) && !(grfMode & STGM_DIRECT_SWMR)) { hr = STG_E_INVALIDFLAG; goto end;
Modified: trunk/reactos/dll/win32/ole32/storage32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/storage32.h... ============================================================================== --- trunk/reactos/dll/win32/ole32/storage32.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/storage32.h [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -166,6 +166,12 @@ HRESULT STORAGE_CreateOleStream(IStorage*, DWORD) DECLSPEC_HIDDEN; HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName) DECLSPEC_HIDDEN;
+enum swmr_mode +{ + SWMR_None, + SWMR_Writer, + SWMR_Reader +};
/**************************************************************************** * StorageBaseImpl definitions. @@ -180,6 +186,7 @@ { IStorage IStorage_iface; IPropertySetStorage IPropertySetStorage_iface; /* interface for adding a properties stream */ + IDirectWriterLock IDirectWriterLock_iface; LONG ref;
/* @@ -225,6 +232,7 @@ * the transacted snapshot or cache. */ StorageBaseImpl *transactedChild; + enum swmr_mode lockingrole; };
/* virtual methods for StorageBaseImpl objects */
Modified: trunk/reactos/dll/win32/ole32/stubmanager.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/stubmanager... ============================================================================== --- trunk/reactos/dll/win32/ole32/stubmanager.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/stubmanager.c [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -176,6 +176,7 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object) { struct stub_manager *sm; + HRESULT hres;
assert( apt );
@@ -221,6 +222,10 @@ */ sm->extrefs = 0;
+ hres = IUnknown_QueryInterface(object, &IID_IExternalConnection, (void**)&sm->extern_conn); + if(FAILED(hres)) + sm->extern_conn = NULL; + EnterCriticalSection(&apt->cs); sm->oid = apt->oidc++; list_add_head(&apt->stubmgrs, &sm->entry); @@ -245,6 +250,9 @@ stub_manager_delete_ifstub(m, ifstub); }
+ if(m->extern_conn) + IExternalConnection_Release(m->extern_conn); + CoTaskMemFree(m->oxid_info.psa); IUnknown_Release(m->object);
@@ -380,9 +388,12 @@ /* add some external references (ie from a client that unmarshaled an ifptr) */ ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak) { + BOOL first_extern_ref; ULONG rc;
EnterCriticalSection(&m->lock); + + first_extern_ref = refs && !m->extrefs;
/* make sure we don't overflow extrefs */ refs = min(refs, (ULONG_MAX-1 - m->extrefs)); @@ -395,12 +406,20 @@
TRACE("added %u refs to %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
+ /* + * NOTE: According to tests, creating a stub causes two AddConnection calls followed by + * one ReleaseConnection call (with fLastReleaseCloses=FALSE). + */ + if(first_extern_ref && m->extern_conn) + IExternalConnection_AddConnection(m->extern_conn, EXTCONN_STRONG, 0); + return rc; }
/* remove some external references */ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases) { + BOOL last_extern_ref; ULONG rc;
EnterCriticalSection(&m->lock); @@ -414,9 +433,14 @@ if (!last_unlock_releases) rc += m->weakrefs;
+ last_extern_ref = refs && !m->extrefs; + LeaveCriticalSection(&m->lock);
TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc); + + if (last_extern_ref && m->extern_conn) + IExternalConnection_ReleaseConnection(m->extern_conn, EXTCONN_STRONG, 0, TRUE /* FIXME: Use last_unlock releases? */);
if (rc == 0) stub_manager_int_release(m);
Modified: trunk/reactos/media/doc/README.WINE URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=6... ============================================================================== --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original) +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Thu Sep 26 13:58:03 2013 @@ -142,7 +142,7 @@ reactos/dll/win32/objsel # Synced to Wine-1.5.19 reactos/dll/win32/odbc32 # Out of sync. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to Wine-1.5.19 -reactos/dll/win32/ole32 # Synced to Wine-1.5.26 +reactos/dll/win32/ole32 # Synced to Wine-1.7.1 reactos/dll/win32/oleacc # Autosync reactos/dll/win32/oleaut32 # Synced to Wine-1.5.26 reactos/dll/win32/olecli32 # Synced to Wine-1.5.19