/* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer. returns Buffer on failure, new position otherwise */ static unsigned char* interface_variant_marshal(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; /* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers. * We create a stream on an HGLOBAL, so we can simply do a memcpy to move it to the buffer. * in rpcrt4/ndr_ole.c, a simple IStream implementation is wrapped around the buffer object, * but that would be overkill here, hence this implementation. We save the size because the unmarshal * code has no way to know how long the marshalled buffer is. */ size = wire_extra_user_size(pFlags, 0, pvar); 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; } hr = CoMarshalInterface(working, riid, V_UNKNOWN(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL); if (hr != S_OK) { IStream_Release(working); /* this also releases the hglobal */ return oldpos; } working_memlocked = GlobalLock(working_mem); memcpy(Buffer, &size, sizeof(ULONG)); /* copy the buffersize */ memcpy(Buffer + sizeof(ULONG), working_memlocked, size - sizeof(ULONG)); GlobalUnlock(working_mem); IStream_Release(working); /* size includes the ULONG for the size written above */ TRACE("done, size=%ld\n", size); return Buffer + size; }
static DWORD CALLBACK host_object_proc(LPVOID p) { struct host_object_data *data = p; HRESULT hr; MSG msg; CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (data->filter) { IMessageFilter * prev_filter = NULL; hr = CoRegisterMessageFilter(data->filter, &prev_filter); if (prev_filter) IMessageFilter_Release(prev_filter); ok_ole_success(hr, CoRegisterMessageFilter); } hr = CoMarshalInterface(data->stream, &data->iid, data->object, MSHCTX_INPROC, NULL, data->marshal_flags); ok_ole_success(hr, CoMarshalInterface); /* force the message queue to be created before signaling parent thread */ PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); SetEvent(data->marshal_event); while (GetMessage(&msg, NULL, 0, 0)) { if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA) { trace("releasing marshal data\n"); CoReleaseMarshalData(data->stream); SetEvent((HANDLE)msg.lParam); } else DispatchMessage(&msg); } HeapFree(GetProcessHeap(), 0, data); CoUninitialize(); return hr; }
static void test_CoRegisterPSClsid(void) { HRESULT hr; DWORD dwRegistrationKey; IStream *stream; CLSID clsid; hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer); ok(hr == CO_E_NOTINITIALIZED, "CoRegisterPSClsid should have returened CO_E_NOTINITIALIZED instead of 0x%08lx\n", hr); pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); hr = CoRegisterClassObject(&CLSID_WineTestPSFactoryBuffer, (IUnknown *)&PSFactoryBuffer, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegistrationKey); ok_ole_success(hr, "CoRegisterClassObject"); hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer); ok_ole_success(hr, "CoRegisterPSClsid"); hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); ok_ole_success(hr, "CreateStreamOnHGlobal"); hr = CoMarshalInterface(stream, &IID_IWineTest, (IUnknown *)&Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); ok(hr == E_NOTIMPL, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08lx\n", hr); IStream_Release(stream); hr = CoRevokeClassObject(dwRegistrationKey); ok_ole_success(hr, "CoRevokeClassObject"); CoUninitialize(); pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); hr = CoGetPSClsid(&IID_IWineTest, &clsid); ok(hr == REGDB_E_IIDNOTREG, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08lx\n", hr); CoUninitialize(); }
LRESULT WINAPI LresultFromObject( REFIID riid, WPARAM wParam, LPUNKNOWN pAcc ) { static const WCHAR atom_fmt[] = {'%','0','8','x',':','%','0','8','x',':','%','0','8','x',0}; static const LARGE_INTEGER seek_zero = {{0}}; WCHAR atom_str[sizeof(lresult_atom_prefix)/sizeof(WCHAR)+3*8+3]; IStream *stream; HANDLE mapping; STATSTG stat; HRESULT hr; ATOM atom; void *view; TRACE("%s %ld %p\n", debugstr_guid(riid), wParam, pAcc); if(wParam) FIXME("unsupported wParam = %lx\n", wParam); if(!pAcc) return E_INVALIDARG; hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); if(FAILED(hr)) return hr; hr = CoMarshalInterface(stream, riid, pAcc, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL); if(FAILED(hr)) { IStream_Release(stream); return hr; } hr = IStream_Seek(stream, seek_zero, STREAM_SEEK_SET, NULL); if(FAILED(hr)) { IStream_Release(stream); return hr; } hr = IStream_Stat(stream, &stat, STATFLAG_NONAME); if(FAILED(hr)) { CoReleaseMarshalData(stream); IStream_Release(stream); return hr; }else if(stat.cbSize.u.HighPart) { FIXME("stream size to big\n"); CoReleaseMarshalData(stream); IStream_Release(stream); return E_NOTIMPL; } mapping = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, stat.cbSize.u.HighPart, stat.cbSize.u.LowPart, NULL); if(!mapping) { CoReleaseMarshalData(stream); IStream_Release(stream); return hr; } view = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0); if(!view) { CloseHandle(mapping); CoReleaseMarshalData(stream); IStream_Release(stream); return E_FAIL; } hr = IStream_Read(stream, view, stat.cbSize.u.LowPart, NULL); UnmapViewOfFile(view); if(FAILED(hr)) { CloseHandle(mapping); hr = IStream_Seek(stream, seek_zero, STREAM_SEEK_SET, NULL); if(SUCCEEDED(hr)) CoReleaseMarshalData(stream); IStream_Release(stream); return hr; } memcpy(atom_str, lresult_atom_prefix, sizeof(lresult_atom_prefix)); sprintfW(atom_str+sizeof(lresult_atom_prefix)/sizeof(WCHAR), atom_fmt, GetCurrentProcessId(), HandleToUlong(mapping), stat.cbSize.u.LowPart); atom = GlobalAddAtomW(atom_str); if(!atom) { CloseHandle(mapping); hr = IStream_Seek(stream, seek_zero, STREAM_SEEK_SET, NULL); if(SUCCEEDED(hr)) CoReleaseMarshalData(stream); IStream_Release(stream); return E_FAIL; } IStream_Release(stream); return atom; }
static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx) { USER_MARSHAL_CB umcb; MIDL_STUB_MESSAGE stub_msg; RPC_MESSAGE rpc_msg; unsigned char *buffer, *buffer_end; ULONG size; IUnknown *unk; IUnknown *unk2; unsigned char *wireip; HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0); IStream *stm; void *marshal_data; LARGE_INTEGER zero; ULARGE_INTEGER pos; DWORD marshal_size; /* shows that the WdtpInterfacePointer functions don't marshal anything for * NULL pointers, so code using these functions must handle that case * itself */ unk = NULL; init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, umcb_ctx); size = WdtpInterfacePointer_UserSize(&umcb.Flags, ctx, 0, unk, &IID_IUnknown); ok(size == 0, "size should be 0 bytes, not %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown); HeapFree(GetProcessHeap(), 0, buffer); /* Now for a non-NULL pointer. The marshalled data are two size DWORDS and then the result of CoMarshalInterface called with the LOWORD of the ctx */ unk = &Test_Unknown; CreateStreamOnHGlobal(h, TRUE, &stm); CoMarshalInterface(stm, &IID_IUnknown, unk, LOWORD(ctx), NULL, MSHLFLAGS_NORMAL); zero.QuadPart = 0; IStream_Seek(stm, zero, STREAM_SEEK_CUR, &pos); marshal_size = pos.u.LowPart; marshal_data = GlobalLock(h); trace("marshal_size %x\n", marshal_size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, umcb_ctx); size = WdtpInterfacePointer_UserSize(&umcb.Flags, ctx, 0, unk, &IID_IUnknown); ok(size >= marshal_size + 2 * sizeof(DWORD), "marshal size %x got %x\n", marshal_size, size); trace("WdtpInterfacePointer_UserSize returned %x\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx); buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown); wireip = buffer; ok(buffer_end == buffer + marshal_size + 2 * sizeof(DWORD), "buffer_end %p buffer %p\n", buffer_end, buffer); ok(*(DWORD *)wireip == marshal_size, "wireip + 0x0 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip); wireip += sizeof(DWORD); ok(*(DWORD *)wireip == marshal_size, "wireip + 0x4 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip); wireip += sizeof(DWORD); ok(!memcmp(marshal_data, wireip, marshal_size), "buffer mismatch\n"); GlobalUnlock(h); zero.QuadPart = 0; IStream_Seek(stm, zero, STREAM_SEEK_SET, NULL); CoReleaseMarshalData(stm); IStream_Release(stm); unk2 = NULL; init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, umcb_ctx); WdtpInterfacePointer_UserUnmarshal(&umcb.Flags, buffer, &unk2, &IID_IUnknown); ok(unk2 != NULL, "IUnknown object didn't unmarshal properly\n"); HeapFree(GetProcessHeap(), 0, buffer); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_INPROC); IUnknown_Release(unk2); }
static HRESULT WINAPI CFStub_Invoke( LPRPCSTUBBUFFER iface,RPCOLEMESSAGE* msg,IRpcChannelBuffer* chanbuf ) { CFStub *This = (CFStub *)iface; HRESULT hres; if (msg->iMethod == 3) { /* CreateInstance */ IID iid; IClassFactory *classfac; IUnknown *ppv; IStream *pStm; STATSTG ststg; ULARGE_INTEGER newpos; LARGE_INTEGER seekto; ULONG res; if (msg->cbBuffer < sizeof(IID)) { FIXME("Not enough bytes in buffer (%ld)?\n",msg->cbBuffer); return E_FAIL; } memcpy(&iid,msg->Buffer,sizeof(iid)); TRACE("->CreateInstance(%s)\n",debugstr_guid(&iid)); hres = IUnknown_QueryInterface(This->pUnkServer,&IID_IClassFactory,(LPVOID*)&classfac); if (hres) { FIXME("Ole server does not provide an IClassFactory?\n"); return hres; } hres = IClassFactory_CreateInstance(classfac,NULL,&iid,(LPVOID*)&ppv); IClassFactory_Release(classfac); if (hres) { msg->cbBuffer = 0; FIXME("Failed to create an instance of %s\n",debugstr_guid(&iid)); return hres; } hres = CreateStreamOnHGlobal(0,TRUE,&pStm); if (hres) { FIXME("Failed to create stream on hglobal\n"); return hres; } hres = CoMarshalInterface(pStm,&iid,ppv,0,NULL,0); IUnknown_Release((IUnknown*)ppv); if (hres) { FIXME("CoMarshalInterface failed, %lx!\n",hres); msg->cbBuffer = 0; return hres; } hres = IStream_Stat(pStm,&ststg,0); if (hres) { FIXME("Stat failed.\n"); return hres; } msg->cbBuffer = ststg.cbSize.u.LowPart; I_RpcGetBuffer((RPC_MESSAGE *)msg); if (hres) return hres; seekto.u.LowPart = 0;seekto.u.HighPart = 0; hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); if (hres) { FIXME("IStream_Seek failed, %lx\n",hres); return hres; } hres = IStream_Read(pStm,msg->Buffer,msg->cbBuffer,&res); if (hres) { FIXME("Stream Read failed, %lx\n",hres); return hres; } IStream_Release(pStm); return S_OK; } FIXME("(%p,%p), stub!\n",msg,chanbuf); FIXME("iMethod is %ld\n",msg->iMethod); FIXME("cbBuffer is %ld\n",msg->cbBuffer); return E_FAIL; }
unsigned int __stdcall CreateBrokerThreadEntry(void *data) { TRY_CATCH CoInitialize(0); SBrokerThreadEntryData* inData = reinterpret_cast<SBrokerThreadEntryData*>(data); SStartBroker *startBroker = reinterpret_cast<SStartBroker*>(inData->buf); if (NULL == startBroker->buf || 0 == startBroker->bufSize) throw MCException("NULL == startBroker->buf || 0 == startBroker->bufSize"); CComPtr<IDispatch> broker; HRESULT hr; if((hr=broker.CoCreateInstance(L"Broker.CoBroker",NULL,CLSCTX_LOCAL_SERVER))!=S_OK) throw CExceptionBase(__LINE__,_T(__FILE__),_T(__DATE__),tstring(_T("CoBroker creation failed")),hr); CScopedTracker<HGLOBAL> globalMem; globalMem.reset(GlobalAlloc(GMEM_MOVEABLE, startBroker->bufSize), GlobalFree); if (NULL == globalMem) throw MCException_Win("Failed to GlobalAlloc"); CComPtr<IStream> stream; hr = CreateStreamOnHGlobal(globalMem, FALSE, &stream); if (S_OK != hr) throw MCException_Win(Format(_T("Failed to GlobalAlloc; result = %X"),hr)); ULARGE_INTEGER size; size.QuadPart = startBroker->bufSize; hr = stream->SetSize(size); if (S_OK != hr) throw MCException_Win(Format(_T("Failed to stream->SetSize; result = %X"),hr)); hr = CoMarshalInterface(stream, IID_IDispatch, broker, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL); if (S_OK != hr) throw MCException_Win(Format(_T("Failed to CoMarshalInterface; result = %X"),hr)); ULARGE_INTEGER uLi; LARGE_INTEGER li; li.QuadPart = 0; /// Writing stream to client process memory stream->Seek(li, STREAM_SEEK_SET, NULL); boost::scoped_array<char> localBuf; ULONG readCount; localBuf.reset(new char[startBroker->bufSize]); hr = stream->Read(localBuf.get(), startBroker->bufSize, &readCount); if (S_OK != hr) throw MCException_Win(Format(_T("stream->Read; result = %X"),hr)); /// Writing stream date into client process memory ULONG writtenCount; if (FALSE == WriteProcessMemory(inData->clientProcess, startBroker->buf, localBuf.get(), readCount, &writtenCount)) throw MCException_Win("Failed to WriteProcessMemory "); CoUninitialize(); Log.Add(_MESSAGE_,_T("Broker created and marshaled to BrokerProxy process")); return TRUE; CATCH_LOG() CoUninitialize(); return FALSE; }
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); }