📄 http.c
字号:
if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
!(content_type = HeapAlloc(GetProcessHeap(), 0, len)) ||
!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type, &len, NULL))
{
WARN("HttpQueryInfo failed: %d\n", GetLastError());
IInternetProtocolSink_ReportProgress(This->protocol_sink,
(This->grfBINDF & BINDF_FROMURLMON) ?
BINDSTATUS_MIMETYPEAVAILABLE :
BINDSTATUS_RAWMIMETYPE,
wszDefaultContentType);
}
else
{
IInternetProtocolSink_ReportProgress(This->protocol_sink,
(This->grfBINDF & BINDF_FROMURLMON) ?
BINDSTATUS_MIMETYPEAVAILABLE :
BINDSTATUS_RAWMIMETYPE,
content_type);
}
len = 0;
if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
!(content_length = HeapAlloc(GetProcessHeap(), 0, len)) ||
!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length, &len, NULL))
{
WARN("HttpQueryInfo failed: %d\n", GetLastError());
This->content_length = 0;
}
else
{
This->content_length = atoiW(content_length);
}
This->flags |= FLAG_FIRST_CONTINUE_COMPLETE;
}
if (pProtocolData->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA)
{
if (!InternetQueryDataAvailable(This->request, &This->available_bytes, 0, 0))
{
if (GetLastError() == ERROR_IO_PENDING)
{
This->flags &= ~FLAG_REQUEST_COMPLETE;
}
else
{
WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
HTTPPROTOCOL_ReportResult(This, INET_E_DATA_NOT_AVAILABLE);
}
}
else
{
HTTPPROTOCOL_ReportData(This);
}
}
done:
HeapFree(GetProcessHeap(), 0, response_headers);
HeapFree(GetProcessHeap(), 0, content_type);
HeapFree(GetProcessHeap(), 0, content_length);
/* Returns S_OK on native */
return S_OK;
}
static HRESULT WINAPI HttpProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
DWORD dwOptions)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
return E_NOTIMPL;
}
static HRESULT WINAPI HttpProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
TRACE("(%p)->(%08x)\n", This, dwOptions);
HTTPPROTOCOL_Close(This);
return S_OK;
}
static HRESULT WINAPI HttpProtocol_Suspend(IInternetProtocol *iface)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI HttpProtocol_Resume(IInternetProtocol *iface)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI HttpProtocol_Read(IInternetProtocol *iface, void *pv,
ULONG cb, ULONG *pcbRead)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
ULONG read = 0, len = 0;
HRESULT hres = S_FALSE;
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
if (!(This->flags & FLAG_REQUEST_COMPLETE))
{
hres = E_PENDING;
}
else while (!(This->flags & FLAG_ALL_DATA_READ) &&
read < cb)
{
if (This->available_bytes == 0)
{
/* InternetQueryDataAvailable may immediately fork and perform its asynchronous
* read, so clear the flag _before_ calling so it does not incorrectly get cleared
* after the status callback is called */
This->flags &= ~FLAG_REQUEST_COMPLETE;
if (!InternetQueryDataAvailable(This->request, &This->available_bytes, 0, 0))
{
if (GetLastError() == ERROR_IO_PENDING)
{
hres = E_PENDING;
}
else
{
WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
hres = INET_E_DATA_NOT_AVAILABLE;
HTTPPROTOCOL_ReportResult(This, hres);
}
goto done;
}
else if (This->available_bytes == 0)
{
HTTPPROTOCOL_AllDataRead(This);
}
}
else
{
if (!InternetReadFile(This->request, ((BYTE *)pv)+read,
This->available_bytes > cb-read ?
cb-read : This->available_bytes, &len))
{
WARN("InternetReadFile failed: %d\n", GetLastError());
hres = INET_E_DOWNLOAD_FAILURE;
HTTPPROTOCOL_ReportResult(This, hres);
goto done;
}
else if (len == 0)
{
HTTPPROTOCOL_AllDataRead(This);
}
else
{
read += len;
This->current_position += len;
This->available_bytes -= len;
}
}
}
/* Per MSDN this should be if (read == cb), but native returns S_OK
* if any bytes were read, so we will too */
if (read)
hres = S_OK;
done:
if (pcbRead)
*pcbRead = read;
if (hres != E_PENDING)
This->flags |= FLAG_REQUEST_COMPLETE;
return hres;
}
static HRESULT WINAPI HttpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
return E_NOTIMPL;
}
static HRESULT WINAPI HttpProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
TRACE("(%p)->(%08x)\n", This, dwOptions);
if (!InternetLockRequestFile(This->request, &This->lock))
WARN("InternetLockRequest failed: %d\n", GetLastError());
return S_OK;
}
static HRESULT WINAPI HttpProtocol_UnlockRequest(IInternetProtocol *iface)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
TRACE("(%p)\n", This);
if (This->lock)
{
if (!InternetUnlockRequestFile(This->lock))
WARN("InternetUnlockRequest failed: %d\n", GetLastError());
This->lock = 0;
}
return S_OK;
}
#undef PROTOCOL_THIS
#define PRIORITY_THIS(iface) DEFINE_THIS(HttpProtocol, InternetPriority, iface)
static HRESULT WINAPI HttpPriority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv)
{
HttpProtocol *This = PRIORITY_THIS(iface);
return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
}
static ULONG WINAPI HttpPriority_AddRef(IInternetPriority *iface)
{
HttpProtocol *This = PRIORITY_THIS(iface);
return IInternetProtocol_AddRef(PROTOCOL(This));
}
static ULONG WINAPI HttpPriority_Release(IInternetPriority *iface)
{
HttpProtocol *This = PRIORITY_THIS(iface);
return IInternetProtocol_Release(PROTOCOL(This));
}
static HRESULT WINAPI HttpPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
{
HttpProtocol *This = PRIORITY_THIS(iface);
TRACE("(%p)->(%d)\n", This, nPriority);
This->priority = nPriority;
return S_OK;
}
static HRESULT WINAPI HttpPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
{
HttpProtocol *This = PRIORITY_THIS(iface);
TRACE("(%p)->(%p)\n", This, pnPriority);
*pnPriority = This->priority;
return S_OK;
}
#undef PRIORITY_THIS
static const IInternetPriorityVtbl HttpPriorityVtbl = {
HttpPriority_QueryInterface,
HttpPriority_AddRef,
HttpPriority_Release,
HttpPriority_SetPriority,
HttpPriority_GetPriority
};
static const IInternetProtocolVtbl HttpProtocolVtbl = {
HttpProtocol_QueryInterface,
HttpProtocol_AddRef,
HttpProtocol_Release,
HttpProtocol_Start,
HttpProtocol_Continue,
HttpProtocol_Abort,
HttpProtocol_Terminate,
HttpProtocol_Suspend,
HttpProtocol_Resume,
HttpProtocol_Read,
HttpProtocol_Seek,
HttpProtocol_LockRequest,
HttpProtocol_UnlockRequest
};
HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{
HttpProtocol *ret;
TRACE("(%p %p)\n", pUnkOuter, ppobj);
URLMON_LockModule();
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HttpProtocol));
ret->lpInternetProtocolVtbl = &HttpProtocolVtbl;
ret->lpInternetPriorityVtbl = &HttpPriorityVtbl;
ret->flags = ret->grfBINDF = 0;
memset(&ret->bind_info, 0, sizeof(ret->bind_info));
ret->protocol_sink = 0;
ret->http_negotiate = 0;
ret->internet = ret->connect = ret->request = 0;
ret->full_header = 0;
ret->lock = 0;
ret->current_position = ret->content_length = ret->available_bytes = 0;
ret->priority = 0;
ret->ref = 1;
*ppobj = PROTOCOL(ret);
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -