Module: wine Branch: master Commit: 32671b1d2f7b1d92264abd76b67fbb0985f86607 URL: http://source.winehq.org/git/wine.git/?a=commit;h=32671b1d2f7b1d92264abd76b6...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Jan 25 11:52:59 2017 +0100
urlmon: Added Seek implementations for streams using cache file.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/urlmon/binding.c | 36 ++++++++++++++++++++++++++++++++-- dlls/urlmon/tests/url.c | 51 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 75 insertions(+), 12 deletions(-)
diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index 9b78582..88b3c1c 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -520,8 +520,40 @@ static HRESULT WINAPI ProtocolStream_Seek(IStream *iface, LARGE_INTEGER dlibMove DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { ProtocolStream *This = impl_from_IStream(iface); - FIXME("(%p)->(%d %08x %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); - return E_NOTIMPL; + LARGE_INTEGER new_pos; + DWORD method; + + TRACE("(%p)->(%d %08x %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); + + if(This->buf->file == INVALID_HANDLE_VALUE) { + /* We should probably call protocol handler's Seek. */ + FIXME("no cache file, not supported\n"); + return E_FAIL; + } + + switch(dwOrigin) { + case STREAM_SEEK_SET: + method = FILE_BEGIN; + break; + case STREAM_SEEK_CUR: + method = FILE_CURRENT; + break; + case STREAM_SEEK_END: + method = FILE_END; + break; + default: + WARN("Invalid origin %x\n", dwOrigin); + return E_FAIL; + } + + if(!SetFilePointerEx(This->buf->file, dlibMove, &new_pos, method)) { + FIXME("SetFilePointerEx failed: %u\n", GetLastError()); + return E_FAIL; + } + + if(plibNewPosition) + plibNewPosition->QuadPart = new_pos.QuadPart; + return S_OK; }
static HRESULT WINAPI ProtocolStream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize) diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c index 9ccd8ef..cd1d855 100644 --- a/dlls/urlmon/tests/url.c +++ b/dlls/urlmon/tests/url.c @@ -1949,6 +1949,31 @@ static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallbackEx *iface, DWORD return S_OK; }
+static void test_stream_seek(IStream *stream) +{ + ULARGE_INTEGER new_pos; + LARGE_INTEGER pos; + HRESULT hres; + + pos.QuadPart = 0; + new_pos.QuadPart = 0xdeadbeef; + hres = IStream_Seek(stream, pos, STREAM_SEEK_SET, &new_pos); + ok(hres == S_OK, "Seek failed: %08x\n", hres); + ok(!new_pos.QuadPart, "new_pos.QuadPart != 0\n"); + + pos.QuadPart = 0; + new_pos.QuadPart = 0xdeadbeef; + hres = IStream_Seek(stream, pos, STREAM_SEEK_END, &new_pos); + ok(hres == S_OK, "Seek failed: %08x\n", hres); + ok(new_pos.QuadPart, "new_pos.QuadPart = 0\n"); + + pos.QuadPart = 0; + new_pos.QuadPart = 0xdeadbeef; + hres = IStream_Seek(stream, pos, 100, &new_pos); + ok(hres == E_FAIL, "Seek failed: %08x\n", hres); + ok(new_pos.QuadPart == 0xdeadbeef, "unexpected new_pos.QuadPart\n"); +} + static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DWORD grfBSCF, DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed) { @@ -1995,24 +2020,28 @@ static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DW ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
switch(pstgmed->tymed) { - case TYMED_ISTREAM: + case TYMED_ISTREAM: { + IStream *stream = U(*pstgmed).pstm; + + ok(stream != NULL, "U(*pstgmed).pstm == NULL\n"); + if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) { STATSTG stat;
- hres = IStream_Write(U(*pstgmed).pstm, buf, 10, NULL); + hres = IStream_Write(stream, buf, 10, NULL); ok(hres == STG_E_ACCESSDENIED, "Write failed: %08x, expected STG_E_ACCESSDENIED\n", hres);
- hres = IStream_Commit(U(*pstgmed).pstm, 0); + hres = IStream_Commit(stream, 0); ok(hres == E_NOTIMPL, "Commit failed: %08x, expected E_NOTIMPL\n", hres);
- hres = IStream_Revert(U(*pstgmed).pstm); + hres = IStream_Revert(stream); ok(hres == E_NOTIMPL, "Revert failed: %08x, expected E_NOTIMPL\n", hres);
- hres = IStream_Stat(U(*pstgmed).pstm, NULL, STATFLAG_NONAME); + hres = IStream_Stat(stream, NULL, STATFLAG_NONAME); ok(hres == E_FAIL, "hres = %x\n", hres); if(use_cache_file && emulate_protocol) { - hres = IStream_Stat(U(*pstgmed).pstm, &stat, STATFLAG_DEFAULT); + hres = IStream_Stat(stream, &stat, STATFLAG_DEFAULT); ok(hres == S_OK, "hres = %x\n", hres); ok(!lstrcmpW(stat.pwcsName, cache_file_name), "stat.pwcsName = %s, cache_file_name = %s\n", @@ -2021,7 +2050,7 @@ static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DW ok(U(stat.cbSize).LowPart == (bindf&BINDF_ASYNCHRONOUS?0:6500), "stat.cbSize.LowPart = %u\n", U(stat.cbSize).LowPart); } else { - hres = IStream_Stat(U(*pstgmed).pstm, &stat, STATFLAG_NONAME); + hres = IStream_Stat(stream, &stat, STATFLAG_NONAME); ok(hres == S_OK, "hres = %x\n", hres); ok(!stat.pwcsName || broken(stat.pwcsName!=NULL), "stat.pwcsName = %s\n", wine_dbgstr_w(stat.pwcsName)); @@ -2034,17 +2063,19 @@ static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DW ok(stat.reserved == 0, "stat.reserved = %x\n", stat.reserved); }
- ok(U(*pstgmed).pstm != NULL, "U(*pstgmed).pstm == NULL\n"); if(callback_read) { do { - hres = IStream_Read(U(*pstgmed).pstm, buf, 512, &readed); + hres = IStream_Read(stream, buf, 512, &readed); if(test_protocol == HTTP_TEST && emulate_protocol && readed) ok(buf[0] == (use_cache_file && !(bindf&BINDF_ASYNCHRONOUS) ? 'X' : '?'), "buf[0] = '%c'\n", buf[0]); }while(hres == S_OK); ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres); } - break;
+ if(use_cache_file && (grfBSCF & BSCF_FIRSTDATANOTIFICATION) && !(bindf & BINDF_PULLDATA)) + test_stream_seek(stream); + break; + } case TYMED_FILE: if(test_protocol == FILE_TEST) ok(!lstrcmpW(pstgmed->u.lpszFileName, file_url+7),