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?…
==============================================================================
--- 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_pr…
==============================================================================
--- 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/compositem…
==============================================================================
--- 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.…
==============================================================================
--- 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=…
==============================================================================
--- 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=…
==============================================================================
--- 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?…
==============================================================================
--- 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=…
==============================================================================
--- 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.…
==============================================================================
--- 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.…
==============================================================================
--- 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/stubmanage…
==============================================================================
--- 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=…
==============================================================================
--- 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