ole32: Get the threading model value for inproc classes and output a fixme if we should create it in an apartment of another type.

Robert Shearman rob at codeweavers.com
Fri Jul 7 10:57:35 CDT 2006


Alexandre Julliard wrote:

>Robert Shearman <rob at codeweavers.com> writes:
>
>  
>
>> dlls/ole32/compobj.c |   45 +++++++++++++++++++++++++++++++++++++++++++++
>> 1 files changed, 45 insertions(+), 0 deletions(-)
>>    
>>
>
>This one crashes the urlmon tests:
>
>../../../tools/runtest -q -P wine -M urlmon.dll -T ../../.. -p urlmon_test.exe.so url.c && touch url.ok
>wine: Unhandled page fault on read access to 0x0000000c at address 0x407536a9 (thread 0323), starting debugger...
>WineDbg starting on pid 0x322
>Unhandled exception: page fault on read access to 0x0000000c in 32-bit code (0x407536a9).
>Register dump:
> CS:0073 SS:007b DS:007b ES:007b FS:003b GS:0033
> EIP:407536a9 ESP:406cf6b0 EBP:406cfb58 EFLAGS:00010202(   - 00      - -RI1)
> EAX:00000000 EBX:407ab11c ECX:40380020 EDX:40380024
> ESI:40034000 EDI:0000005c
>Stack dump:
>0x406cf6b0:  40380000 00000008 00000010 406cfb44
>0x406cf6c0:  406cfb2c 406cfb48 406cf6d8 406cf71c
>0x406cf6d0:  00000040 406cf82c 0000004a 401cdc5e
>0x406cf6e0:  403ce208 406cf704 406cf718 00000498
>0x406cf6f0:  406cfb48 406cfb44 401ed0eb 406f9df0
>0x406cf700:  406cfc80 406cf75c 406cf798 401f18ed
>Backtrace:
>=>1 0x407536a9 get_inproc_class_object+0xa9(hkeydll=0x5c, rclsid=0x406cfc80, riid=0x406f9df0, ppv=0x406cfd64) [/home/julliard/wine/wine/dlls/ole32/compobj.c:1593] in ole32 (0x407536a9)
>  2 0x4075407e CoGetClassObject+0x1fe(rclsid=0x406cfc80, dwClsContext=0x1, pServerInfo=0x0, iid=0x406f9df0, ppv=0x406cfd64) [/home/julliard/wine/wine/dlls/ole32/compobj.c:1710] in ole32 (0x4075407e)
>  3 0x406ed5b6 get_protocol_iface+0x1a6(schema=0x406cfce0, schema_len=<register not in topmost frame>, ret=0x406cfd64) [/home/julliard/wine/wine/dlls/urlmon/session.c:95] in urlmon (0x406ed5b6)
>  4 0x406ed88f get_protocol_info+0xff(url=0x403ce460) [/home/julliard/wine/wine/dlls/urlmon/session.c:124] in urlmon (0x406ed88f)
>  5 0x406e9c12 CoInternetCombineUrl+0x32(pwzBaseUrl=0x403ce460, pwzRelativeUrl=0x405b8cf6, dwCombineFlags=0x0, pwzResult=0x403ce3a0, cchResult=0x3d, pcchResult=0x406cfe10, dwReserved=0x0) [/home/julliard/wine/wine/dlls/urlmon/internet.c:197] in urlmon (0x406e9c12)
>  6 0x406f1ef6 CreateURLMoniker+0x166(pmkContext=0x403ce320, szURL=0x405b8cf6, ppmk=0x406cfe94) [/home/julliard/wine/wine/dlls/urlmon/umon.c:1077] in urlmon (0x406f1ef6)
>  7 0x405b4881 func_url+0xa1 [/home/julliard/wine/wine/dlls/urlmon/tests/url.c:109] in urlmon_test (0x405b4881)
>  8 0x405b58c1 run_test+0x121(name=0x403804a7) [/home/julliard/wine/wine/dlls/urlmon/tests/../../../include/wine/test.h:365] in urlmon_test (0x405b58c1)
>  9 0x405b5be9 __wine_spec_exe_entry+0x99(peb=0x40219820) [/home/julliard/wine/wine/dlls/winecrt0/exe_entry.c:37] in urlmon_test (0x405b5be9)
>  10 0x405000bb start_process+0xeb(arg=0x0) [/home/julliard/wine/wine/dlls/kernel/process.c:832] in kernel32 (0x405000bb)
>  11 0x4001da77 wine_switch_to_stack+0x17 in libwine.so.1 (0x4001da77)
>0x407536a9 get_inproc_class_object+0xa9 [/home/julliard/wine/wine/dlls/ole32/compobj.c:1593] in ole32: movl	0xc(%eax),%eax
>1593	        if (apt->multi_threaded)
>Wine-dbg>
>

Jacek,

I have a patch that fixes the crash by validating the conditions on 
entry to CoGetClassObject (attached). However, this test still fails:

err:ole:CoGetClassObject apartment not initialised
url.c:768:http test...
url.c:424: Test failed: unexpexted code 34
fixme:wininet:CommitUrlCacheEntryInternal entry already in cache - don't 
know what to do!
url.c:667: Test failed: istr should be NULL
url.c:690: Test failed: expected OnProgress_MIMETYPEAVAILABLE
url.c:773:about test...
fixme:win:WIN_CreateWindowEx Parent is HWND_MESSAGE
url.c:779:emulated about test...
url.c:784:file test...
err:ole:CoGetClassObject apartment not initialised
url.c:662: Test failed: IMoniker_BindToStorage failed: 800401f0
url.c:791:emulated file test...
url: 253 tests executed, 0 marked as todo, 4 failures.

It looks to me as though CoGetClassObject should be called by urlmon in 
certain circumstances (hence the CoInitialize calls in some of the 
tests), but not in this case.  The test fails with the same error when 
run with native ole32 and rpcrt4.

Thanks,

-- 
Rob Shearman

-------------- next part --------------
>From beda0132fda8f06b11e305f5a56c491f4a310260 Mon Sep 17 00:00:00 2001
From: Robert Shearman <rob at codeweavers.com>
Date: Fri, 7 Jul 2006 16:34:59 +0100
Subject: [PATCH] Add validation of parameters to CoGetClassObject and make sure to initialise ppv to NULL.
To: wine-patches <wine-patches at winehq.org>
---
 dlls/ole32/compobj.c       |   54 ++++++++++++++++++++++++++++++++++++++++++--
 dlls/ole32/tests/compobj.c |   12 ++++++++++
 2 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index f115658..06f4936 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -1736,6 +1736,17 @@ HRESULT WINAPI CoGetClassObject(
 
     TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
 
+    if (!ppv)
+        return E_INVALIDARG;
+
+    *ppv = NULL;
+
+    if (!COM_CurrentApt())
+    {
+        ERR("apartment not initialised\n");
+        return CO_E_NOTINITIALIZED;
+    }
+
     if (pServerInfo) {
 	FIXME("\tpServerInfo: name=%s\n",debugstr_w(pServerInfo->pwszName));
 	FIXME("\t\tpAuthInfo=%p\n",pServerInfo->pAuthInfo);
@@ -2517,15 +2528,52 @@ DWORD WINAPI CoGetCurrentProcess(void)
  * RETURNS
  *  Success: S_OK.
  *  Failure: HRESULT code.
+ *
+ * NOTES
+ *  Both lpMessageFilter and lplpMessageFilter are optional. Passing in a NULL
+ *  lpMessageFilter removes the message filter.
+ *
+ *  If lplpMessageFilter is not NULL the previous message filter will be
+ *  returned in the memory pointer to this parameter and the caller is
+ *  responsible for releasing the object.
+ *
+ *  The current thread be in an apartment otherwise the function will crash.
  */
 HRESULT WINAPI CoRegisterMessageFilter(
     LPMESSAGEFILTER lpMessageFilter,
     LPMESSAGEFILTER *lplpMessageFilter)
 {
-    FIXME("stub\n");
-    if (lplpMessageFilter) {
-        *lplpMessageFilter = NULL;
+    struct apartment *apt;
+    IMessageFilter *lpOldMessageFilter;
+
+    TRACE("(%p, %p)\n", lpMessageFilter, lplpMessageFilter);
+
+    apt = COM_CurrentApt();
+
+    /* can't set a message filter in a multi-threaded apartment */
+    if (apt->multi_threaded)
+    {
+        ERR("can't set message filter in MTA\n");
+        return CO_E_NOT_SUPPORTED;
     }
+
+    if (lpMessageFilter)
+        IMessageFilter_AddRef(lpMessageFilter);
+
+    EnterCriticalSection(&apt->cs);
+
+    lpOldMessageFilter = apt->filter;
+    apt->filter = lpMessageFilter;
+
+    LeaveCriticalSection(&apt->cs);
+
+    if (lplpMessageFilter)
+        *lplpMessageFilter = lpOldMessageFilter;
+    else
+        IMessageFilter_Release(lpOldMessageFilter);
+
+    FIXME("message filter has been registered, but will not be used\n");
+
     return S_OK;
 }
 
diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c
index 06bf381..9164be8 100644
--- a/dlls/ole32/tests/compobj.c
+++ b/dlls/ole32/tests/compobj.c
@@ -100,6 +100,17 @@ static void test_CoCreateInstance(void)
     ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08lx\n", hr);
 }
 
+static void test_CoGetClassObject(void)
+{
+    IUnknown *pUnk = (IUnknown *)0xdeadbeef;
+    HRESULT hr = CoGetClassObject(&CLSID_MyComputer, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
+    ok(hr == CO_E_NOTINITIALIZED, "CoGetClassObject should have returned CO_E_NOTINITIALIZED instead of 0x%08lx\n", hr);
+    ok(pUnk == NULL, "CoGetClassObject should have changed the passed in pointer to NULL, instead of %p\n", pUnk);
+
+    hr = CoGetClassObject(&CLSID_MyComputer, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, NULL);
+    ok(hr == E_INVALIDARG, "CoGetClassObject should have returned E_INVALIDARG instead of 0x%08lx\n", hr);
+}
+
 static ATOM register_dummy_class(void)
 {
     WNDCLASS wc =
@@ -138,4 +149,5 @@ START_TEST(compobj)
     test_CLSIDFromString();
     test_CoCreateInstance();
     test_ole_menu();
+    test_CoGetClassObject();
 }
-- 
1.3.1.gac83a



More information about the wine-devel mailing list