Commit 9b634b97 authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

- More tests.

- Change return code of CoGetPSClsid to match test result. - Do a slight hack to make IRemUnknown proxies be added after the proxy that uses them to stop them being used after they are destroyed. - Fix multiple local server connections.
parent 2a0df4bd
......@@ -1060,8 +1060,8 @@ HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid)
/*****************************************************************************
* CoGetPSClsid [OLE32.@]
*
* This function returns the CLSID of the proxy/stub factory that
* implements IPSFactoryBuffer for the specified interface.
* Retrieves the CLSID of the proxy/stub factory that implements
* IPSFactoryBuffer for the specified interface.
*
* PARAMS
* riid [I] Interface whose proxy/stub CLSID is to be returned.
......@@ -1070,7 +1070,7 @@ HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid)
* RETURNS
* S_OK
* E_OUTOFMEMORY
* E_INVALIDARG if no PSFactoryBuffer is associated with the IID, or it could not be parsed
* REGDB_E_IIDNOTREG if no PSFactoryBuffer is associated with the IID, or it could not be parsed
*
* NOTES
*
......@@ -1088,6 +1088,9 @@ HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid)
*
* We only search the registry, not ids registered with
* CoRegisterPSClsid.
* Also, native returns S_OK for interfaces with an key in HKCR\Interface, but
* without a ProxyStubClsid32 key and leaves garbage in pclsid. This should be
* considered a bug in native unless an application depends on this (unlikely).
*/
HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
{
......@@ -1103,9 +1106,7 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
(length of iid string plus constant length of static text */
buf = HeapAlloc(GetProcessHeap(), 0, strlen(buf2)+27);
if (buf == NULL)
{
return (E_OUTOFMEMORY);
}
return E_OUTOFMEMORY;
/* Construct the registry key we want */
sprintf(buf,"Interface\\%s\\ProxyStubClsid32", buf2);
......@@ -1113,9 +1114,9 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
/* Open the key.. */
if (RegOpenKeyA(HKEY_CLASSES_ROOT, buf, &xhkey))
{
WARN("No PSFactoryBuffer object is registered for this IID\n");
HeapFree(GetProcessHeap(),0,buf);
return (E_INVALIDARG);
WARN("No PSFactoryBuffer object is registered for IID %s\n", debugstr_guid(riid));
HeapFree(GetProcessHeap(),0,buf);
return REGDB_E_IIDNOTREG;
}
HeapFree(GetProcessHeap(),0,buf);
......@@ -1125,19 +1126,18 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
buf2len = sizeof(buf2);
if ( (RegQueryValueA(xhkey,NULL,buf2,&buf2len)) )
{
RegCloseKey(xhkey);
return E_INVALIDARG;
RegCloseKey(xhkey);
return REGDB_E_IIDNOTREG;
}
RegCloseKey(xhkey);
/* We have the CLSid we want back from the registry as a string, so
lets convert it into a CLSID structure */
if ( (__CLSIDFromStringA(buf2,pclsid)) != NOERROR) {
return E_INVALIDARG;
}
if ( (__CLSIDFromStringA(buf2,pclsid)) != NOERROR)
return REGDB_E_IIDNOTREG;
TRACE ("() Returning CLSID=%s\n", debugstr_guid(pclsid));
return (S_OK);
return S_OK;
}
......
......@@ -423,13 +423,19 @@ static HRESULT proxy_manager_construct(
* should store the STDOBJREF flags in the proxy manager. */
This->sorflags = sorflags;
assert(channel);
This->chan = channel; /* FIXME: we should take the binding strings and construct the channel in this function */
/* we create the IRemUnknown proxy on demand */
This->remunk = NULL;
EnterCriticalSection(&apt->cs);
list_add_head(&apt->proxies, &This->entry);
/* FIXME: we are dependent on the ordering in here to make sure a proxy's
* IRemUnknown proxy doesn't get destroyed before the regual proxy does
* because we need the IRemUnknown proxy during the destruction of the
* regular proxy. Ideally, we should maintain a separate list for the
* IRemUnknown proxies that need late destruction */
list_add_tail(&apt->proxies, &This->entry);
LeaveCriticalSection(&apt->cs);
TRACE("%p created for OXID %s, OID %s\n", This,
......@@ -790,7 +796,13 @@ StdMarshalImpl_MarshalInterface(
start_apartment_listener_thread(); /* just to be sure we have one running. */
start_apartment_remote_unknown();
IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
if (hres != S_OK)
{
ERR("object doesn't expose interface %s, failing with error 0x%08lx\n",
debugstr_guid(riid), hres);
return E_NOINTERFACE;
}
if ((manager = get_stub_manager_from_object(apt, pUnk)))
{
......
......@@ -991,8 +991,6 @@ static DWORD WINAPI local_server_thread(LPVOID param)
return hres;
}
IStream_Release(pStm);
WriteFile(hPipe,buffer,buflen,&res,NULL);
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
......@@ -1000,6 +998,7 @@ static DWORD WINAPI local_server_thread(LPVOID param)
TRACE("done marshalling IClassFactory\n");
}
CloseHandle(hPipe);
IStream_Release(pStm);
return 0;
}
......
......@@ -26,6 +26,7 @@
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "comcat.h"
#include "wine/test.h"
......@@ -58,12 +59,93 @@ static void test_MkParseDisplayName()
IBindCtx_Release(pbc);
}
static const BYTE expected_moniker_data[] =
{
0x4d,0x45,0x4f,0x57,0x04,0x00,0x00,0x00,
0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
0x1a,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
0x05,0xe0,0x02,0x00,0x00,0x00,0x00,0x00,
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,
0x00,0x00,0x00,0x00,
};
static const LARGE_INTEGER llZero;
static void test_class_moniker()
{
IStream * stream;
IMoniker * moniker;
HRESULT hr;
HGLOBAL hglobal;
LPBYTE moniker_data;
DWORD moniker_size;
DWORD i;
BOOL same = TRUE;
hr = CreateClassMoniker(&CLSID_StdComponentCategoriesMgr, &moniker);
todo_wine { ok_ole_success(hr, CreateClassMoniker); }
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
todo_wine { ok_ole_success(hr, CoMarshalInterface); }
hr = GetHGlobalFromStream(stream, &hglobal);
ok_ole_success(hr, GetHGlobalFromStream);
moniker_size = GlobalSize(hglobal);
moniker_data = GlobalLock(hglobal);
/* first check we have the right amount of data */
todo_wine {
ok(moniker_size == sizeof(expected_moniker_data),
"Size of marshaled data differs (expected %d, actual %ld)\n",
sizeof(expected_moniker_data), moniker_size);
}
/* then do a byte-by-byte comparison */
for (i = 0; i < min(moniker_size, sizeof(expected_moniker_data)); i++)
{
if (expected_moniker_data[i] != moniker_data[i])
{
same = FALSE;
break;
}
}
ok(same, "Marshaled data differs\n");
if (!same)
{
trace("Dumping marshaled moniker data:\n");
for (i = 0; i < moniker_size; i++)
{
trace("0x%02x,", moniker_data[i]);
if (i % 8 == 7) trace("\n");
if (i % 8 == 0) trace(" ");
}
}
GlobalUnlock(hglobal);
IStream_Seek(stream, llZero, STREAM_SEEK_SET, NULL);
hr = CoReleaseMarshalData(stream);
todo_wine { ok_ole_success(hr, CoReleaseMarshalData); }
IStream_Release(stream);
if (moniker) IMoniker_Release(moniker);
}
START_TEST(moniker)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
/* FIXME: test moniker creation funcs and parsing other moniker formats */
test_MkParseDisplayName();
test_class_moniker();
/* FIXME: test moniker creation funcs and parsing other moniker formats */
CoUninitialize();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment