static HRESULT WINAPI CFProxy_CreateInstance( LPCLASSFACTORY iface, LPUNKNOWN pUnkOuter,/* [in] */ REFIID riid, /* [in] */ LPVOID *ppv /* [out] */ ) { ICOM_THIS_MULTI(CFProxy,lpvtbl_cf,iface); HRESULT hres; LPSTREAM pStream; HGLOBAL hGlobal; ULONG srstatus; RPCOLEMESSAGE msg; TRACE("(%p,%s,%p)\n",pUnkOuter,debugstr_guid(riid),ppv); /* Send CreateInstance to the remote classfactory. * * Data: Only the 'IID'. */ msg.iMethod = 3; msg.cbBuffer = sizeof(*riid); msg.Buffer = NULL; hres = IRpcChannelBuffer_GetBuffer(This->chanbuf,&msg,&IID_IClassFactory); if (hres) { FIXME("IRpcChannelBuffer_GetBuffer failed with %lx?\n",hres); return hres; } memcpy(msg.Buffer,riid,sizeof(*riid)); hres = IRpcChannelBuffer_SendReceive(This->chanbuf,&msg,&srstatus); if (hres) { FIXME("IRpcChannelBuffer_SendReceive failed with %lx?\n",hres); return hres; } if (!msg.cbBuffer) /* interface not found on remote */ return srstatus; /* We got back: [Marshalled Interface data] */ TRACE("got %ld bytes data.\n",msg.cbBuffer); hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE,msg.cbBuffer); memcpy(GlobalLock(hGlobal),msg.Buffer,msg.cbBuffer); hres = CreateStreamOnHGlobal(hGlobal,TRUE,&pStream); if (hres) { FIXME("CreateStreamOnHGlobal failed with %lx\n",hres); return hres; } hres = CoUnmarshalInterface( pStream, riid, ppv ); IStream_Release(pStream); /* Does GlobalFree hGlobal too. */ if (hres) { FIXME("CoMarshalInterface failed, %lx\n",hres); return hres; } return S_OK; }
/* helper: called for VT_DISPATCH / VT_UNKNOWN variants to unmarshal the buffer. returns Buffer on failure, new position otherwise */ static unsigned char *interface_variant_unmarshal(unsigned long *pFlags, unsigned char *Buffer, REFIID riid, VARIANT *pvar) { IStream *working; HGLOBAL working_mem; void *working_memlocked; unsigned char *oldpos; ULONG size; HRESULT hr; TRACE("pFlags=%ld, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar); oldpos = Buffer; /* get the buffersize */ memcpy(&size, Buffer, sizeof(ULONG)); TRACE("buffersize=%ld\n", size); working_mem = GlobalAlloc(0, size); if (!working_mem) return oldpos; hr = CreateStreamOnHGlobal(working_mem, TRUE, &working); if (hr != S_OK) { GlobalFree(working_mem); return oldpos; } working_memlocked = GlobalLock(working_mem); /* now we copy the contents of the marshalling buffer to working_memlocked, unlock it, and demarshal the stream */ memcpy(working_memlocked, Buffer + sizeof(ULONG), size); GlobalUnlock(working_mem); hr = CoUnmarshalInterface(working, riid, (void**)&V_UNKNOWN(pvar)); if (hr != S_OK) { IStream_Release(working); return oldpos; } IStream_Release(working); /* this also frees the underlying hglobal */ /* size includes the ULONG for the size written above */ TRACE("done, processed=%ld bytes\n", size); return Buffer + size; }
HRESULT WINAPI ObjectFromLresult( LRESULT result, REFIID riid, WPARAM wParam, void **ppObject ) { WCHAR atom_str[sizeof(lresult_atom_prefix)/sizeof(WCHAR)+3*8+3]; HANDLE server_proc, server_mapping, mapping; DWORD proc_id, size; IStream *stream; HGLOBAL data; void *view; HRESULT hr; WCHAR *p; TRACE("%ld %s %ld %p\n", result, debugstr_guid(riid), wParam, ppObject ); if(wParam) FIXME("unsupported wParam = %lx\n", wParam); if(!ppObject) return E_INVALIDARG; *ppObject = NULL; if(result != (ATOM)result) return E_FAIL; if(!GlobalGetAtomNameW(result, atom_str, sizeof(atom_str)/sizeof(WCHAR))) return E_FAIL; if(memcmp(atom_str, lresult_atom_prefix, sizeof(lresult_atom_prefix))) return E_FAIL; p = atom_str + sizeof(lresult_atom_prefix)/sizeof(WCHAR); proc_id = strtoulW(p, &p, 16); if(*p != ':') return E_FAIL; server_mapping = ULongToHandle( strtoulW(p+1, &p, 16) ); if(*p != ':') return E_FAIL; size = strtoulW(p+1, &p, 16); if(*p != 0) return E_FAIL; server_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, proc_id); if(!server_proc) return E_FAIL; if(!DuplicateHandle(server_proc, server_mapping, GetCurrentProcess(), &mapping, 0, FALSE, DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS)) return E_FAIL; CloseHandle(server_proc); GlobalDeleteAtom(result); view = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); CloseHandle(mapping); if(!view) return E_FAIL; data = GlobalAlloc(GMEM_FIXED, size); if(!data) { UnmapViewOfFile(view); return E_OUTOFMEMORY; } memcpy(data, view, size); UnmapViewOfFile(view); hr = CreateStreamOnHGlobal(data, TRUE, &stream); if(FAILED(hr)) { GlobalFree(data); return hr; } hr = CoUnmarshalInterface(stream, riid, ppObject); IStream_Release(stream); return hr; }
static void test_marshal(void) { IStream *pStream; IAudioClient *ac, *acDest; IAudioCaptureClient *cc, *ccDest; WAVEFORMATEX *pwfx; HRESULT hr; hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); ok(hr == S_OK, "Activation failed with %08x\n", hr); if(hr != S_OK) return; hr = IAudioClient_GetMixFormat(ac, &pwfx); ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr); hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL); ok(hr == S_OK, "Initialize failed: %08x\n", hr); CoTaskMemFree(pwfx); hr = IAudioClient_GetService(ac, &IID_IAudioCaptureClient, (void**)&cc); ok(hr == S_OK, "GetService failed: %08x\n", hr); if(hr != S_OK) { IAudioClient_Release(ac); return; } hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream); ok(hr == S_OK, "CreateStreamOnHGlobal failed 0x%08x\n", hr); /* marshal IAudioClient */ hr = CoMarshalInterface(pStream, &IID_IAudioClient, (IUnknown*)ac, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); ok(hr == S_OK, "CoMarshalInterface IAudioClient failed 0x%08x\n", hr); IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL); hr = CoUnmarshalInterface(pStream, &IID_IAudioClient, (void **)&acDest); ok(hr == S_OK, "CoUnmarshalInterface IAudioClient failed 0x%08x\n", hr); if (hr == S_OK) IAudioClient_Release(acDest); IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL); /* marshal IAudioCaptureClient */ hr = CoMarshalInterface(pStream, &IID_IAudioCaptureClient, (IUnknown*)cc, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); ok(hr == S_OK, "CoMarshalInterface IAudioCaptureClient failed 0x%08x\n", hr); IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL); hr = CoUnmarshalInterface(pStream, &IID_IAudioCaptureClient, (void **)&ccDest); ok(hr == S_OK, "CoUnmarshalInterface IAudioCaptureClient failed 0x%08x\n", hr); if (hr == S_OK) IAudioCaptureClient_Release(ccDest); IStream_Release(pStream); IAudioClient_Release(ac); IAudioCaptureClient_Release(cc); }