static inline void rot_entry_delete(struct rot_entry *rot_entry) { if (rot_entry->cookie) { InterfaceData *object = NULL; InterfaceData *moniker = NULL; __TRY { IrotRevoke(get_irot_handle(), rot_entry->cookie, &rot_entry->ctxt_handle, &object, &moniker); } __EXCEPT(rpc_filter) { } __ENDTRY MIDL_user_free(object); if (moniker) { IStream *stream; HRESULT hr; hr = create_stream_on_mip_ro(moniker, &stream); if (hr == S_OK) { CoReleaseMarshalData(stream); IUnknown_Release(stream); } } MIDL_user_free(moniker); }
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; }
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); }