URLOpenStreamW获取http远程数据返回信息
int HttpGetData(std::vector<char> & vData, LPCWSTR lpURL)
{
HRESULT hResult = S_FALSE;
::CoInitializeEx(NULL, COINIT_MULTITHREADED);
::DeleteUrlCacheEntryW(lpURL);//清空缓存,否则服务器上的文件修改后,无法下载最新的文件
class CMyBindStatusCallback : public IBindStatusCallback
{
public:
std::vector<char> m_strData = {};
virtual HRESULT STDMETHODCALLTYPE QueryInterface(
/* [in] */ REFIID riid,
/* [iid_is][out] */ __RPC__deref_out void __RPC_FAR* __RPC_FAR* ppvObject) {
return E_NOTIMPL;
}
virtual ULONG STDMETHODCALLTYPE AddRef(void) {
return E_NOTIMPL;
}
virtual ULONG STDMETHODCALLTYPE Release(void) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnStartBinding(
/* [in] */ DWORD dwReserved,
/* [in] */ __RPC__in_opt IBinding* pib) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetPriority(
/* [out] */ __RPC__out LONG* pnPriority) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnLowResource(
/* [in] */ DWORD reserved) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnProgress(
/* [in] */ ULONG ulProgress,
/* [in] */ ULONG ulProgressMax,
/* [in] */ ULONG ulStatusCode,
/* [unique][in] */ __RPC__in_opt LPCWSTR szStatusText) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnStopBinding(
/* [in] */ HRESULT hresult,
/* [unique][in] */ __RPC__in_opt LPCWSTR szError) {
return E_NOTIMPL;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetBindInfo(
/* [out] */ DWORD* grfBINDF,
/* [unique][out][in] */ BINDINFO* pbindinfo) {
return E_NOTIMPL;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE OnDataAvailable(
/* [in] */ DWORD grfBSCF,
/* [in] */ DWORD dwSize,
/* [in] */ FORMATETC* pformatetc,
/* [in] */ STGMEDIUM* pstgmed) {
HRESULT hr = NOERROR;
DWORD dwNumberOfBytesRead = 0;
std::vector<char> vTemp(dwSize, '\0');
if (SUCCEEDED(pstgmed->pstm->Read(vTemp.data(), dwSize, &dwNumberOfBytesRead)))
{
if (dwNumberOfBytesRead < dwSize)
{
vTemp.resize(dwNumberOfBytesRead);
}
m_strData.insert(m_strData.end(), vTemp.begin(), vTemp.end());
}
//BSCF_FIRSTDATANOTIFICATION = 0x00000001,
//BSCF_INTERMEDIATEDATANOTIFICATION = 0x00000002,
//BSCF_LASTDATANOTIFICATION = 0x00000004,
//有可能为BSCF_FIRSTDATANOTIFICATION, BSCF_FIRSTDATANOTIFICATION & BSCF_LASTDATANOTIFICATION, BSCF_INTERMEDIATEDATANOTIFICATION, BSCF_LASTDATANOTIFICATION
//即可能为一个包、两个包或多个包
/*if (grfBSCF & BSCF_FIRSTDATANOTIFICATION)
{
if (SUCCEEDED(pstgmed->pstm->Read(vData.data(), dwSize, &dwNumberOfBytesRead)))
{
vData.resize(dwNumberOfBytesRead);
m_strData.insert(m_strData.end(), vData.begin(), vData.end());
}
}
else
{
if (SUCCEEDED(pstgmed->pstm->Read(vData.data(), dwSize, &dwNumberOfBytesRead)))
{
m_strData.append(vData.data(), dwNumberOfBytesRead);
}
}*/
/*std::string strData(dwSize, '\0');
while (TRUE) {
DWORD cbRead = 0;
hr = pstgmed->pstm->Read((void*)strData.data(), dwSize, &cbRead);
if (hr == E_PENDING) {
// we'll get notified again when more data comes
return(NOERROR);
}
if (SUCCEEDED(hr)) {
// ok, process bits and keep looping
m_strData.append(strData, cbRead);
}
else {
// we have an error...
return(hr);
}
}*/
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE OnObjectAvailable(
/* [in] */ __RPC__in REFIID riid,
/* [iid_is][in] */ __RPC__in_opt IUnknown* punk) {
return E_NOTIMPL;
}
} myBindStatusCallback = {};
hResult = ::URLOpenStreamW(0, lpURL, 0, (LPBINDSTATUSCALLBACK)&myBindStatusCallback);
::CoUninitialize();
vData.swap(myBindStatusCallback.m_strData);
return SUCCEEDED(hResult);
}