urlmon: Use cache file to read in synchronous binding.
This commit is contained in:
parent
41db8e5910
commit
7708097d7b
|
@ -47,6 +47,7 @@ typedef struct {
|
|||
BYTE buf[1024*8];
|
||||
DWORD size;
|
||||
BOOL init;
|
||||
HANDLE file;
|
||||
HRESULT hres;
|
||||
|
||||
LPWSTR cache_file;
|
||||
|
@ -101,6 +102,7 @@ struct Binding {
|
|||
LPWSTR redirect_url;
|
||||
IID iid;
|
||||
BOOL report_mime;
|
||||
BOOL use_cache_file;
|
||||
DWORD state;
|
||||
HRESULT hres;
|
||||
download_state_t download_state;
|
||||
|
@ -134,6 +136,20 @@ static void fill_stgmed_buffer(stgmed_buf_t *buf)
|
|||
buf->init = TRUE;
|
||||
}
|
||||
|
||||
static void read_protocol_data(stgmed_buf_t *stgmed_buf)
|
||||
{
|
||||
BYTE buf[8192];
|
||||
DWORD read;
|
||||
HRESULT hres;
|
||||
|
||||
fill_stgmed_buffer(stgmed_buf);
|
||||
if(stgmed_buf->size < sizeof(stgmed_buf->buf))
|
||||
return;
|
||||
|
||||
do hres = IInternetProtocol_Read(stgmed_buf->protocol, buf, sizeof(buf), &read);
|
||||
while(hres == S_OK);
|
||||
}
|
||||
|
||||
static void dump_BINDINFO(BINDINFO *bi)
|
||||
{
|
||||
static const char * const BINDINFOF_str[] = {
|
||||
|
@ -339,6 +355,19 @@ static void create_object(Binding *binding)
|
|||
IInternetProtocol_Terminate(binding->protocol, 0);
|
||||
}
|
||||
|
||||
static void cache_file_available(Binding *This, const WCHAR *file_name)
|
||||
{
|
||||
heap_free(This->stgmed_buf->cache_file);
|
||||
This->stgmed_buf->cache_file = heap_strdupW(file_name);
|
||||
|
||||
if(This->use_cache_file) {
|
||||
This->stgmed_buf->file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(This->stgmed_buf->file == INVALID_HANDLE_VALUE)
|
||||
WARN("CreateFile failed: %u\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
#define STGMEDUNK_THIS(iface) DEFINE_THIS(stgmed_buf_t, Unknown, iface)
|
||||
|
||||
static HRESULT WINAPI StgMedUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||
|
@ -377,6 +406,8 @@ static ULONG WINAPI StgMedUnk_Release(IUnknown *iface)
|
|||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
if(This->file != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(This->file);
|
||||
IInternetProtocol_Release(This->protocol);
|
||||
heap_free(This->cache_file);
|
||||
heap_free(This);
|
||||
|
@ -403,6 +434,7 @@ static stgmed_buf_t *create_stgmed_buf(IInternetProtocol *protocol)
|
|||
ret->ref = 1;
|
||||
ret->size = 0;
|
||||
ret->init = FALSE;
|
||||
ret->file = INVALID_HANDLE_VALUE;
|
||||
ret->hres = S_OK;
|
||||
ret->cache_file = NULL;
|
||||
|
||||
|
@ -488,6 +520,15 @@ static HRESULT WINAPI ProtocolStream_Read(IStream *iface, void *pv,
|
|||
|
||||
TRACE("(%p)->(%p %d %p)\n", This, pv, cb, pcbRead);
|
||||
|
||||
if(This->buf->file != INVALID_HANDLE_VALUE) {
|
||||
if (!ReadFile(This->buf->file, pv, cb, &read, NULL))
|
||||
return INET_E_DOWNLOAD_FAILURE;
|
||||
|
||||
if(pcbRead)
|
||||
*pcbRead = read;
|
||||
return read ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
if(This->buf->size) {
|
||||
read = cb;
|
||||
|
||||
|
@ -690,16 +731,7 @@ static HRESULT stgmed_file_fill_stgmed(stgmed_obj_t *obj, STGMEDIUM *stgmed)
|
|||
return INET_E_DATA_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
fill_stgmed_buffer(file_obj->buf);
|
||||
if(file_obj->buf->size == sizeof(file_obj->buf->buf)) {
|
||||
BYTE buf[1024];
|
||||
DWORD read;
|
||||
HRESULT hres;
|
||||
|
||||
do {
|
||||
hres = IInternetProtocol_Read(file_obj->buf->protocol, buf, sizeof(buf), &read);
|
||||
}while(hres == S_OK);
|
||||
}
|
||||
read_protocol_data(file_obj->buf);
|
||||
|
||||
stgmed->tymed = TYMED_FILE;
|
||||
stgmed->u.lpszFileName = file_obj->buf->cache_file;
|
||||
|
@ -988,8 +1020,7 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink
|
|||
mime_available(This, szStatusText);
|
||||
break;
|
||||
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
|
||||
heap_free(This->stgmed_buf->cache_file);
|
||||
This->stgmed_buf->cache_file = heap_strdupW(szStatusText);
|
||||
cache_file_available(This, szStatusText);
|
||||
break;
|
||||
case BINDSTATUS_DECODING:
|
||||
IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_DECODING, szStatusText);
|
||||
|
@ -1020,9 +1051,12 @@ static void report_data(Binding *This, DWORD bscf, ULONG progress, ULONG progres
|
|||
if(This->download_state == END_DOWNLOAD || (This->state & BINDING_STOPPED))
|
||||
return;
|
||||
|
||||
if(This->download_state == BEFORE_DOWNLOAD) {
|
||||
if(This->stgmed_buf->file != INVALID_HANDLE_VALUE)
|
||||
read_protocol_data(This->stgmed_buf);
|
||||
else if(This->download_state == BEFORE_DOWNLOAD)
|
||||
fill_stgmed_buffer(This->stgmed_buf);
|
||||
|
||||
if(This->download_state == BEFORE_DOWNLOAD) {
|
||||
This->download_state = DOWNLOADING;
|
||||
sent_begindownloaddata = TRUE;
|
||||
IBindStatusCallback_OnProgress(This->callback, progress, progress_max,
|
||||
|
@ -1431,8 +1465,12 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url,
|
|||
if(to_obj)
|
||||
ret->bindinfo.dwOptions |= 0x100000;
|
||||
|
||||
if(!(ret->bindf & BINDF_ASYNCHRONOUS) || !is_urlmon_protocol(url))
|
||||
if(!(ret->bindf & BINDF_ASYNCHRONOUS)) {
|
||||
ret->bindf |= BINDF_NEEDFILE;
|
||||
ret->use_cache_file = TRUE;
|
||||
}else if(!is_urlmon_protocol(url)) {
|
||||
ret->bindf |= BINDF_NEEDFILE;
|
||||
}
|
||||
|
||||
ret->url = heap_strdupW(url);
|
||||
|
||||
|
|
Loading…
Reference in New Issue