Alexandre Julliard wrote:

Robert Shearman <[EMAIL PROTECTED]> 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

>From beda0132fda8f06b11e305f5a56c491f4a310260 Mon Sep 17 00:00:00 2001
From: Robert Shearman <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
---
 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



Reply via email to