urlmon: Added Uri IMarshal implementation.

This commit is contained in:
Piotr Caban 2012-01-16 15:13:03 +01:00 committed by Alexandre Julliard
parent 50480c72f3
commit 991061e461
1 changed files with 271 additions and 24 deletions

View File

@ -53,6 +53,7 @@ typedef struct {
IUri IUri_iface; IUri IUri_iface;
IUriBuilderFactory IUriBuilderFactory_iface; IUriBuilderFactory IUriBuilderFactory_iface;
IPersistStream IPersistStream_iface; IPersistStream IPersistStream_iface;
IMarshal IMarshal_iface;
LONG ref; LONG ref;
@ -4221,6 +4222,9 @@ static HRESULT WINAPI Uri_QueryInterface(IUri *iface, REFIID riid, void **ppv)
}else if(IsEqualGUID(&IID_IPersistStream, riid)) { }else if(IsEqualGUID(&IID_IPersistStream, riid)) {
TRACE("(%p)->(IID_IPersistStream %p)\n", This, ppv); TRACE("(%p)->(IID_IPersistStream %p)\n", This, ppv);
*ppv = &This->IPersistStream_iface; *ppv = &This->IPersistStream_iface;
}else if(IsEqualGUID(&IID_IMarshal, riid)) {
TRACE("(%p)->(IID_IMarshal %p)\n", This, ppv);
*ppv = &This->IMarshal_iface;
}else if(IsEqualGUID(&IID_IUriObj, riid)) { }else if(IsEqualGUID(&IID_IUriObj, riid)) {
TRACE("(%p)->(IID_IUriObj %p)\n", This, ppv); TRACE("(%p)->(IID_IUriObj %p)\n", This, ppv);
*ppv = This; *ppv = This;
@ -5238,28 +5242,10 @@ static inline BYTE* persist_stream_add_strprop(Uri *This, BYTE *p, DWORD type, D
return p+sizeof(WCHAR); return p+sizeof(WCHAR);
} }
static HRESULT WINAPI PersistStream_Save(IPersistStream *iface, IStream *pStm, BOOL fClearDirty) static inline void persist_stream_save(Uri *This, IStream *pStm, BOOL marshal, struct persist_uri *data)
{ {
Uri *This = impl_from_IPersistStream(iface);
ULARGE_INTEGER size;
struct persist_uri *data;
BYTE *p = NULL; BYTE *p = NULL;
HRESULT hres;
TRACE("(%p)->(%p %x)\n", This, pStm, fClearDirty);
if(!pStm)
return E_INVALIDARG;
hres = IPersistStream_GetSizeMax(&This->IPersistStream_iface, &size);
if(FAILED(hres))
return hres;
data = heap_alloc_zero(size.u.LowPart);
if(!data)
return E_OUTOFMEMORY;
data->size = size.u.LowPart;
data->create_flags = This->create_flags; data->create_flags = This->create_flags;
if(This->create_flags) { if(This->create_flags) {
@ -5268,11 +5254,8 @@ static HRESULT WINAPI PersistStream_Save(IPersistStream *iface, IStream *pStm, B
SysStringLen(This->raw_uri), This->raw_uri); SysStringLen(This->raw_uri), This->raw_uri);
} }
if(This->scheme_type!=URL_SCHEME_HTTP && This->scheme_type!=URL_SCHEME_HTTPS if(This->scheme_type!=URL_SCHEME_HTTP && This->scheme_type!=URL_SCHEME_HTTPS
&& This->scheme_type!=URL_SCHEME_FTP) { && This->scheme_type!=URL_SCHEME_FTP)
hres = IStream_Write(pStm, data, data->size-2, NULL); return;
heap_free(data);
return hres;
}
if(This->fragment_len) { if(This->fragment_len) {
data->fields_no++; data->fields_no++;
@ -5301,6 +5284,10 @@ static HRESULT WINAPI PersistStream_Save(IPersistStream *iface, IStream *pStm, B
data->fields_no++; data->fields_no++;
p = persist_stream_add_strprop(This, p, Uri_PROPERTY_PATH, p = persist_stream_add_strprop(This, p, Uri_PROPERTY_PATH,
This->path_len, This->canon_uri+This->path_start); This->path_len, This->canon_uri+This->path_start);
} else if(marshal) {
WCHAR no_path = '/';
data->fields_no++;
p = persist_stream_add_strprop(This, p, Uri_PROPERTY_PATH, 1, &no_path);
} }
if(This->has_port) { if(This->has_port) {
@ -5334,6 +5321,29 @@ static HRESULT WINAPI PersistStream_Save(IPersistStream *iface, IStream *pStm, B
p = persist_stream_add_strprop(This, p, Uri_PROPERTY_USER_NAME, p = persist_stream_add_strprop(This, p, Uri_PROPERTY_USER_NAME,
This->userinfo_len, This->canon_uri+This->userinfo_start); This->userinfo_len, This->canon_uri+This->userinfo_start);
} }
}
static HRESULT WINAPI PersistStream_Save(IPersistStream *iface, IStream *pStm, BOOL fClearDirty)
{
Uri *This = impl_from_IPersistStream(iface);
struct persist_uri *data;
ULARGE_INTEGER size;
HRESULT hres;
TRACE("(%p)->(%p %x)\n", This, pStm, fClearDirty);
if(!pStm)
return E_INVALIDARG;
hres = IPersistStream_GetSizeMax(&This->IPersistStream_iface, &size);
if(FAILED(hres))
return hres;
data = heap_alloc_zero(size.u.LowPart);
if(!data)
return E_OUTOFMEMORY;
data->size = size.u.LowPart;
persist_stream_save(This, pStm, FALSE, data);
hres = IStream_Write(pStm, data, data->size-2, NULL); hres = IStream_Write(pStm, data, data->size-2, NULL);
heap_free(data); heap_free(data);
@ -5396,6 +5406,242 @@ static const IPersistStreamVtbl PersistStreamVtbl = {
PersistStream_GetSizeMax PersistStream_GetSizeMax
}; };
static inline Uri* impl_from_IMarshal(IMarshal *iface)
{
return CONTAINING_RECORD(iface, Uri, IMarshal_iface);
}
static HRESULT WINAPI Marshal_QueryInterface(IMarshal *iface, REFIID riid, void **ppvObject)
{
Uri *This = impl_from_IMarshal(iface);
return IUri_QueryInterface(&This->IUri_iface, riid, ppvObject);
}
static ULONG WINAPI Marshal_AddRef(IMarshal *iface)
{
Uri *This = impl_from_IMarshal(iface);
return IUri_AddRef(&This->IUri_iface);
}
static ULONG WINAPI Marshal_Release(IMarshal *iface)
{
Uri *This = impl_from_IMarshal(iface);
return IUri_Release(&This->IUri_iface);
}
static HRESULT WINAPI Marshal_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv,
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid)
{
Uri *This = impl_from_IMarshal(iface);
TRACE("(%p)->(%s %p %x %p %x %p)\n", This, debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pCid);
if(!pCid || (dwDestContext!=MSHCTX_LOCAL && dwDestContext!=MSHCTX_NOSHAREDMEM
&& dwDestContext!=MSHCTX_INPROC))
return E_INVALIDARG;
*pCid = CLSID_CUri;
return S_OK;
}
struct inproc_marshal_uri {
DWORD size;
DWORD mshlflags;
DWORD unk[4]; /* process identifier? */
Uri *uri;
};
static HRESULT WINAPI Marshal_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv,
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *pSize)
{
Uri *This = impl_from_IMarshal(iface);
ULARGE_INTEGER size;
HRESULT hres;
TRACE("(%p)->(%s %p %x %p %x %p)\n", This, debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags, pSize);
if(!pSize || (dwDestContext!=MSHCTX_LOCAL && dwDestContext!=MSHCTX_NOSHAREDMEM
&& dwDestContext!=MSHCTX_INPROC))
return E_INVALIDARG;
if(dwDestContext == MSHCTX_INPROC) {
*pSize = sizeof(struct inproc_marshal_uri);
return S_OK;
}
hres = IPersistStream_GetSizeMax(&This->IPersistStream_iface, &size);
if(FAILED(hres))
return hres;
if(!This->path_len && (This->scheme_type==URL_SCHEME_HTTP
|| This->scheme_type==URL_SCHEME_HTTPS
|| This->scheme_type==URL_SCHEME_FTP))
size.u.LowPart += 3*sizeof(DWORD);
*pSize = size.u.LowPart+2*sizeof(DWORD);
return S_OK;
}
static HRESULT WINAPI Marshal_MarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid,
void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
{
Uri *This = impl_from_IMarshal(iface);
DWORD *data;
DWORD size;
HRESULT hres;
TRACE("(%p)->(%p %s %p %x %p %x)\n", This, pStm, debugstr_guid(riid), pv,
dwDestContext, pvDestContext, mshlflags);
if(!pStm || mshlflags!=MSHLFLAGS_NORMAL || (dwDestContext!=MSHCTX_LOCAL
&& dwDestContext!=MSHCTX_NOSHAREDMEM && dwDestContext!=MSHCTX_INPROC))
return E_INVALIDARG;
if(dwDestContext == MSHCTX_INPROC) {
struct inproc_marshal_uri data;
data.size = sizeof(data);
data.mshlflags = MSHCTX_INPROC;
data.unk[0] = 0;
data.unk[1] = 0;
data.unk[2] = 0;
data.unk[3] = 0;
data.uri = This;
hres = IStream_Write(pStm, &data, data.size, NULL);
if(FAILED(hres))
return hres;
IUri_AddRef(&This->IUri_iface);
return S_OK;
}
hres = IMarshal_GetMarshalSizeMax(iface, riid, pv, dwDestContext,
pvDestContext, mshlflags, &size);
if(FAILED(hres))
return hres;
data = heap_alloc_zero(size);
if(!data)
return E_OUTOFMEMORY;
data[0] = size;
data[1] = dwDestContext;
data[2] = size-2*sizeof(DWORD);
persist_stream_save(This, pStm, TRUE, (struct persist_uri*)(data+2));
hres = IStream_Write(pStm, data, data[0]-2, NULL);
heap_free(data);
return hres;
}
static HRESULT WINAPI Marshal_UnmarshalInterface(IMarshal *iface,
IStream *pStm, REFIID riid, void **ppv)
{
Uri *This = impl_from_IMarshal(iface);
DWORD header[2];
HRESULT hres;
TRACE("(%p)->(%p %s %p)\n", This, pStm, debugstr_guid(riid), ppv);
if(This->create_flags)
return E_UNEXPECTED;
if(!pStm || !riid || !ppv)
return E_INVALIDARG;
hres = IStream_Read(pStm, header, sizeof(header), NULL);
if(FAILED(hres))
return hres;
if(header[1]!=MSHCTX_LOCAL && header[1]!=MSHCTX_NOSHAREDMEM
&& header[1]!=MSHCTX_INPROC)
return E_UNEXPECTED;
if(header[1] == MSHCTX_INPROC) {
struct inproc_marshal_uri data;
parse_data parse;
hres = IStream_Read(pStm, data.unk, sizeof(data)-2*sizeof(DWORD), NULL);
if(FAILED(hres))
return hres;
This->raw_uri = SysAllocString(data.uri->raw_uri);
if(!This->raw_uri) {
return E_OUTOFMEMORY;
}
memset(&parse, 0, sizeof(parse_data));
parse.uri = This->raw_uri;
if(!parse_uri(&parse, data.uri->create_flags))
return E_INVALIDARG;
hres = canonicalize_uri(&parse, This, data.uri->create_flags);
if(FAILED(hres))
return hres;
This->create_flags = data.uri->create_flags;
IUri_Release(&data.uri->IUri_iface);
return IUri_QueryInterface(&This->IUri_iface, riid, ppv);
}
hres = IPersistStream_Load(&This->IPersistStream_iface, pStm);
if(FAILED(hres))
return hres;
return IUri_QueryInterface(&This->IUri_iface, riid, ppv);
}
static HRESULT WINAPI Marshal_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
{
Uri *This = impl_from_IMarshal(iface);
LARGE_INTEGER off;
DWORD header[2];
HRESULT hres;
TRACE("(%p)->(%p)\n", This, pStm);
if(!pStm)
return E_INVALIDARG;
hres = IStream_Read(pStm, header, 2*sizeof(DWORD), NULL);
if(FAILED(hres))
return hres;
if(header[1] == MSHCTX_INPROC) {
struct inproc_marshal_uri data;
hres = IStream_Read(pStm, data.unk, sizeof(data)-2*sizeof(DWORD), NULL);
if(FAILED(hres))
return hres;
IUri_Release(&data.uri->IUri_iface);
return S_OK;
}
off.u.LowPart = header[0]-sizeof(header)-2;
off.u.HighPart = 0;
return IStream_Seek(pStm, off, STREAM_SEEK_CUR, NULL);
}
static HRESULT WINAPI Marshal_DisconnectObject(IMarshal *iface, DWORD dwReserved)
{
Uri *This = impl_from_IMarshal(iface);
TRACE("(%p)->(%x)\n", This, dwReserved);
return S_OK;
}
static const IMarshalVtbl MarshalVtbl = {
Marshal_QueryInterface,
Marshal_AddRef,
Marshal_Release,
Marshal_GetUnmarshalClass,
Marshal_GetMarshalSizeMax,
Marshal_MarshalInterface,
Marshal_UnmarshalInterface,
Marshal_ReleaseMarshalData,
Marshal_DisconnectObject
};
HRESULT Uri_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) HRESULT Uri_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{ {
Uri *ret = heap_alloc_zero(sizeof(Uri)); Uri *ret = heap_alloc_zero(sizeof(Uri));
@ -5409,6 +5655,7 @@ HRESULT Uri_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
ret->IUri_iface.lpVtbl = &UriVtbl; ret->IUri_iface.lpVtbl = &UriVtbl;
ret->IUriBuilderFactory_iface.lpVtbl = &UriBuilderFactoryVtbl; ret->IUriBuilderFactory_iface.lpVtbl = &UriBuilderFactoryVtbl;
ret->IPersistStream_iface.lpVtbl = &PersistStreamVtbl; ret->IPersistStream_iface.lpVtbl = &PersistStreamVtbl;
ret->IMarshal_iface.lpVtbl = &MarshalVtbl;
ret->ref = 1; ret->ref = 1;
*ppobj = &ret->IUri_iface; *ppobj = &ret->IUri_iface;