// 返答 HRESULT CCustomBindStatusCallBack::OnResponse( DWORD dwResponseCode, LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders ) { TRACEIN(_T("CCustomBindStatusCallBack::OnResponse()")); std::wstring strRespons = szResponseHeaders; { // ファイル名を取得 std::wregex regex(L"Content-Disposition:.*?; filename=\"(.*?)\""); std::wsmatch smatch; if (std::regex_search(strRespons, smatch, regex)) { CString strBuffer = smatch[1].str().c_str(); vector<char> filename = Misc::urlstr_decode(strBuffer); m_pDLItem->strFileName = Misc::UnknownToCString(filename); TRACEIN(_T(" filename : %s"), (LPCTSTR)m_pDLItem->strFileName); } else { m_pDLItem->strFileName = m_pDLItem->strURL; m_pDLItem->strFileName = Misc::GetFileBaseName(m_pDLItem->strFileName); int nQuestion = m_pDLItem->strFileName.ReverseFind(_T('?')); if (nQuestion != -1) { m_pDLItem->strFileName = m_pDLItem->strFileName.Left(nQuestion); } } } return S_OK; }
// 接続 HRESULT CCustomBindStatusCallBack::BeginningTransaction( LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders ) { TRACEIN(_T("CCustomBindStatusCallBack::BeginningTransaction()")); m_pDLItem->strURL = szURL; if (pszAdditionalHeaders == NULL) return E_POINTER; *pszAdditionalHeaders = NULL; if (m_pDLItem->strReferer.IsEmpty() == FALSE) { // リファラーを追加する CString strBuffer; strBuffer.Format(_T("Referer: %s\r\n"), m_pDLItem->strReferer); TRACEIN(_T(" Referer : %s"), m_pDLItem->strReferer); int nstrSize = (strBuffer.GetLength() + 1) * sizeof(WCHAR); LPWSTR wszAdditionalHeaders = (LPWSTR)CoTaskMemAlloc(nstrSize); if (wszAdditionalHeaders == NULL) return E_OUTOFMEMORY; wcscpy(wszAdditionalHeaders, (LPCTSTR)strBuffer); *pszAdditionalHeaders = wszAdditionalHeaders; } return S_OK; }
int cistlv_isData(unsigned char *buf, int len) { struct cisco_tlvhdr_201501_s *hp = (struct cisco_tlvhdr_201501_s*)buf; unsigned short hdrlen, pktlen; // payloadlen; TRACEIN(); if (len < (int) sizeof(struct cisco_tlvhdr_201501_s)) { DEBUGMSG(ERROR, "cistlv header not large enough"); return -1; } hdrlen = hp->hlen; // ntohs(hp->hdrlen); pktlen = ntohs(hp->pktlen); // payloadlen = ntohs(hp->payloadlen); if (hp->version != CISCO_TLV_V1) { DEBUGMSG(ERROR, "cistlv version %d not supported\n", hp->version); return -1; } if (pktlen < len) { DEBUGMSG(ERROR, "cistlv packet too small (%d instead of %d bytes)\n", pktlen, len); return -1; } buf += hdrlen; len -= hdrlen; TRACEOUT(); if(hp->pkttype == CISCO_PT_Content) return 1; else return 0; }
// バインド終了 HRESULT CCustomBindStatusCallBack::OnStopBinding( /* [in] */ HRESULT hresult, /* [unique][in] */ LPCWSTR szError) { if (m_spBinding) m_spBinding.Release(); if (m_spBSCBPrev && m_spBindCtx) { HRESULT hr = m_spBindCtx->RegisterObjectParam(L"_BSCB_Holder_", m_spBSCBPrev); m_spBSCBPrev.Release(); m_spBindCtx.Release(); } /* 外部にDL終了通知 */ if (m_hWndNotify) { UINT uMsg = ::RegisterWindowMessage(REGISTERMESSAGE_DLCOMPLETE); ::SendMessage(m_hWndNotify, uMsg, (WPARAM)(LPCTSTR)m_pDLItem->strText, 0); } /* DLリストから削除 */ ::PostMessage(m_hWndDLing, WM_USER_REMOVEFROMDOWNLIST, (WPARAM)m_pDLItem, (LPARAM)this); // お片付け if (m_hFile != INVALID_HANDLE_VALUE) { ::CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; if (m_pDLItem->nProgress != m_pDLItem->nProgressMax && m_pDLItem->nProgressMax != 0) { m_pDLItem->bAbort = true; if (::PathFileExists(m_pDLItem->strIncompleteFilePath)) { ::DeleteFile(m_pDLItem->strIncompleteFilePath); ::SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, static_cast<LPCTSTR>(m_pDLItem->strIncompleteFilePath), nullptr); TRACEIN(_T("不完全ファイルを削除しました。: %s"), (LPCTSTR)m_pDLItem->strIncompleteFilePath); } } else { TRACEIN(_T("OnStopBinding() : 正常終了しました(%s)"), (LPCTSTR)m_pDLItem->strFileName); ::MoveFileEx(m_pDLItem->strIncompleteFilePath, m_pDLItem->strFilePath, MOVEFILE_REPLACE_EXISTING); /* エクスプローラーにファイルの変更通知 */ ::SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATH, static_cast<LPCTSTR>(m_pDLItem->strIncompleteFilePath), static_cast<LPCTSTR>(m_pDLItem->strFilePath)); } } return S_OK; }
int ccnl_nfn_RX_result(struct ccnl_relay_s *relay, struct ccnl_face_s *from, struct ccnl_content_s *c) { struct ccnl_interest_s *i_it = NULL; int found = 0; DEBUGMSG_CFWD(INFO, "data in rx result %.*s\n", c->pkt->contlen, c->pkt->content); TRACEIN(); #ifdef USE_NACK if (ccnl_nfnprefix_contentIsNACK(c)) { ccnl_nfn_nack_local_computation(relay, c->pkt->buf, c->pkt->pfx, from, c->pkt->pfx->suite); return -1; } #endif // USE_NACK for (i_it = relay->pit; i_it;/* i_it = i_it->next*/) { //Check if prefix match and it is a nfn request if (!ccnl_prefix_cmp(c->pkt->pfx, NULL, i_it->pkt->pfx, CMP_EXACT) && i_it->from && i_it->from->faceid < 0) { struct ccnl_face_s *from = i_it->from; int faceid = - from->faceid; DEBUGMSG(TRACE, " interest faceid=%d\n", i_it->from->faceid); ccnl_content_add2cache(relay, c); DEBUGMSG_CFWD(INFO, "data in rx resulti after add to cache %.*s\n", c->pkt->contlen, c->pkt->content); DEBUGMSG(DEBUG, "Continue configuration for configid: %d with prefix: %s\n", faceid, ccnl_prefix_to_path(c->pkt->pfx)); i_it->flags |= CCNL_PIT_COREPROPAGATES; i_it->from = NULL; ccnl_nfn_continue_computation(relay, faceid, 0); i_it = ccnl_interest_remove(relay, i_it); //ccnl_face_remove(relay, from); ++found; //goto Done; } else i_it = i_it->next; } TRACEOUT(); return found > 0; }
bool CCustomBindStatusCallBack::_GetFileName() { HRESULT hr = S_OK; CComQIPtr<IWinInetHttpInfo> spInfo = m_spBinding; if (spInfo) { char buff[1024]; DWORD dwBuffSize = 1024; hr = spInfo->QueryInfo(HTTP_QUERY_CONTENT_DISPOSITION, (LPVOID)buff, &dwBuffSize, 0, NULL); if (hr == S_OK) { // CONTENT_DISPOSITIONからファイル名を取得する std::string strbuff = buff; std::regex rx("filename\\*=(?: |)UTF-8''(.+)"); std::regex rx1("filename=(?:\"|)([^\";]+)"); std::smatch result; if (std::regex_search(strbuff, result, rx)) { CString strtemp = result.str(1).c_str(); vector<char> strurldecoded = Misc::urlstr_decode(strtemp); m_pDLItem->strFileName = Misc::utf8_to_CString(strurldecoded); // } else if (std::regex_search(strbuff, result, rx1)) { std::string strtemp1 = result.str(1); int nPerCount = 0; std::for_each(strtemp1.begin(), strtemp1.end(), [&nPerCount](char c) { if (c == '%') ++nPerCount; }); vector<char> strUrlDecoded; bool bShiftJis = false; if (nPerCount != 0) { double dRate = double(strtemp1.length()) / double(nPerCount); if (dRate >= 2.4) { // '%'が多いならURLDecode char tempdecoded[INTERNET_MAX_PATH_LENGTH] = "\0"; DWORD dwBufferLength = INTERNET_MAX_PATH_LENGTH; hr = ::UrlUnescapeA(const_cast<LPSTR>(strtemp1.c_str()), tempdecoded, &dwBufferLength, 0); if (FAILED(hr)) { TRACEIN(_T("UrlUnescapeA 失敗 : Error「%s」\n (%s)"), (LPCTSTR)GetLastErrorString(hr), (LPCTSTR)CString(strtemp1.c_str())); ::strcpy_s(tempdecoded, strtemp1.c_str()); // 失敗したので元に戻しておく } else { strtemp1 = tempdecoded; for (auto it = strtemp1.begin(); it != strtemp1.end(); ++it) { // '+'を空白に置換する if (*it == '+') *it = ' '; } } } } else { if (Misc::IsShiftJIS(strtemp1.c_str(), (int)strtemp1.length())) { bShiftJis = true; m_pDLItem->strFileName = strtemp1.c_str(); TRACEIN(_T("Shift-JIS文字列でした : %s"), (LPCTSTR)m_pDLItem->strFileName); } } if (bShiftJis == false) { strUrlDecoded.resize(strtemp1.length() + 1, '\0'); ::strcpy_s(strUrlDecoded.data(), strtemp1.length() + 1, strtemp1.c_str()); m_pDLItem->strFileName = Misc::utf8_to_CString(strUrlDecoded); } } else { TRACEIN(_T("CONTENT_DISPOSITIONが見つからない? 内容: %s"), (LPCTSTR)CString(buff)); } } if (m_pDLItem->strFileName.IsEmpty()) { dwBuffSize = 1024; hr = spInfo->QueryOption(INTERNET_OPTION_DATAFILE_NAME, (LPVOID)buff, &dwBuffSize); if (hr == S_OK) { // ファイル名の部分を取得する([?]部分を除く) CString strBaseName = Misc::GetFileBaseName(buff); int nIndex = strBaseName.ReverseFind(_T('[')); if (nIndex != -1) { m_pDLItem->strFileName = strBaseName.Left(nIndex); CString strExt = Misc::GetFileExt(strBaseName); if (strExt.IsEmpty() == FALSE) { m_pDLItem->strFileName += _T('.') + strExt; } } else { m_pDLItem->strFileName = strBaseName; } } } } else { ATLASSERT(m_strDLFolder.IsEmpty() == FALSE); // これ以外で失敗すると困る m_pDLItem->strFileName = Misc::GetFileBaseName(m_pDLItem->strURL); // [?]がつくかも int nQIndex = m_pDLItem->strFileName.ReverseFind(_T('?')); if (nQIndex != -1) { m_pDLItem->strFileName = m_pDLItem->strFileName.Left(nQIndex); } if (m_pDLItem->strFileName.IsEmpty()) m_pDLItem->strFileName = _T("index"); // めったにないと思うけど一応 if (m_pDLItem->strFileName.Find(_T('%')) != -1) { // URLデコードする //vector<char> filename = Misc::urlstr_decode(m_pDLItem->strFileName); m_pDLItem->strFileName = Misc::urlstr_decodeJpn(m_pDLItem->strFileName, 3);//Misc::UnknownToCString(filename); } } // リンク抽出ダイアログより(画像を保存も) if (m_strDLFolder.IsEmpty() == FALSE) { // 拡張子がなければ Content-Type から拡張子を得る if (Misc::GetFileExt(m_pDLItem->strFileName).IsEmpty() && m_pDLItem->strExtention.GetLength() > 0) m_pDLItem->strFileName += _T(".") + m_pDLItem->strExtention; m_pDLItem->strFilePath = m_strDLFolder + m_pDLItem->strFileName; if (::PathFileExists(m_pDLItem->strFilePath)) { if (m_dwDLOption & DLO_OVERWRITEPROMPT) { CString strMessage; strMessage.Format(_T("%s は既に存在します。\n上書きしますか?\n"), (LPCTSTR)m_pDLItem->strFileName);; if (MessageBox(NULL, strMessage, _T("確認"), MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL) { return false; } } else if (m_dwDLOption & DLO_USEUNIQUENUMBER) { // 連番を付ける int nCount = 0; CString strOriginalFileName = m_pDLItem->strFileName; while (TRUE) { CString strAppend; strAppend.Format(_T("_[%d]"), nCount); int nExt = m_pDLItem->strFileName.Find(_T('.')); if (nExt != -1) { m_pDLItem->strFileName.Insert(nExt, strAppend); } else { m_pDLItem->strFileName += strAppend; } m_pDLItem->strFilePath = m_strDLFolder + m_pDLItem->strFileName; if (::PathFileExists(m_pDLItem->strFilePath) == FALSE) break; m_pDLItem->strFileName = strOriginalFileName; ++nCount; } } } m_pDLItem->strIncompleteFilePath = m_pDLItem->strFilePath + _T(".incomplete"); return true; } return GetFileName(m_pDLItem); }
HRESULT CCustomBindStatusCallBack::OnDataAvailable( /* [in] */ DWORD grfBSCF, /* [in] */ DWORD dwSize, /* [in] */ FORMATETC *pformatetc, /* [in] */ STGMEDIUM *pstgmed ) { HRESULT hr = S_OK; // Get the Stream passed if (BSCF_FIRSTDATANOTIFICATION & grfBSCF) { if (m_spStream == NULL && pstgmed->tymed == TYMED_ISTREAM) { m_spStream = pstgmed->pstm; // ファイル名を取得する if (_GetFileName() == false) { // キャンセルされたので帰る Cancel(); if (m_dwThreadId) ::PostThreadMessage(m_dwThreadId, WM_DECREMENTTHREADREFCOUNT, 0, 0); return E_ABORT; } // フォルダが存在しなければ作成 CString strDir = MtlGetDirectoryPath(m_pDLItem->strFilePath); if (::PathIsDirectory(strDir) == FALSE) ::SHCreateDirectory(NULL, strDir); m_hFile = ::CreateFile(m_pDLItem->strIncompleteFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (m_hFile == INVALID_HANDLE_VALUE) { //ATLASSERT(FALSE); CString strError = _T("ファイルの作成に失敗しました\n"); strError += GetLastErrorString(); MessageBox(NULL, strError, NULL, MB_OK | MB_ICONWARNING); Cancel(); return E_ABORT; } /* DLリストに追加 */ ::PostMessage(m_hWndDLing, WM_USER_ADDTODOWNLOADLIST, (WPARAM)m_pDLItem, 0); } } if (m_spStream && dwSize > m_dwTotalRead) { DWORD dwRead = dwSize - m_dwTotalRead; // まだ読まれていないデータ量 DWORD dwActuallyRead = 0; if (dwRead > 0) { do { BYTE* pBytes = NULL; ATLTRY(pBytes = new BYTE[dwRead + 1]); if (pBytes == NULL) { hr = E_OUTOFMEMORY; } else { hr = m_spStream->Read(pBytes, dwRead, &dwActuallyRead); pBytes[dwActuallyRead] = 0; if (dwActuallyRead > 0) { DWORD dwWritten = 0; m_dwTotalRead += dwActuallyRead; ::WriteFile(m_hFile, (LPCVOID)pBytes, dwActuallyRead, &dwWritten, NULL); ATLASSERT(dwWritten == dwActuallyRead); } delete[] pBytes; } //} while (!(hr == E_PENDING || hr == S_FALSE)/* && SUCCEEDED(hr)*/); } while (hr == S_OK); } } // Clean up if (BSCF_LASTDATANOTIFICATION & grfBSCF) { m_spStream.Release(); if (m_hFile != INVALID_HANDLE_VALUE) { ::CloseHandle(m_hFile); m_hFile = INVALID_HANDLE_VALUE; if (m_pDLItem->nProgress != m_pDLItem->nProgressMax && m_pDLItem->nProgressMax != 0) { m_pDLItem->bAbort = true; ::DeleteFile(m_pDLItem->strIncompleteFilePath); ::SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, static_cast<LPCTSTR>(m_pDLItem->strIncompleteFilePath), nullptr); TRACEIN(_T("BSCF_LASTDATANOTIFICATION (%s): サイズが一致しません!"), (LPCTSTR)m_pDLItem->strFileName); } else { TRACEIN(_T("BSCF_LASTDATANOTIFICATION : 正常終了しました(%s)"), (LPCTSTR)m_pDLItem->strFileName); ::MoveFileEx(m_pDLItem->strIncompleteFilePath, m_pDLItem->strFilePath, MOVEFILE_REPLACE_EXISTING); /* エクスプローラーにファイルの変更通知 */ ::SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATH, static_cast<LPCTSTR>(m_pDLItem->strIncompleteFilePath), static_cast<LPCTSTR>(m_pDLItem->strFilePath)); } } } return S_OK; }
//-------------------------------------------- /// DLが開始されるときに呼ばれる STDMETHODIMP CDownloadManager::Download( IMoniker* pmk, IBindCtx* pbc, DWORD dwBindVerb, LONG grfBINDF, BINDINFO* pBindInfo, LPCOLESTR pszHeaders, LPCOLESTR pszRedir, UINT uiCP ) { if (CDLControlOption::s_bUseDLManager == false) return E_FAIL; if (::GetKeyState(VK_MENU) < 0) return E_FAIL; // Altを押しているとデフォルトに任せる if (CDLOptions::bShowWindowOnDL) OnShowDLManager(0, 0, NULL); CCustomBindStatusCallBack* pCBSCB = _CreateCustomBindStatusCallBack(); IBindStatusCallback* pbscbPrev; HRESULT hr = ::RegisterBindStatusCallback(pbc, (IBindStatusCallback*)pCBSCB, &pbscbPrev, 0); if (FAILED(hr) && pbscbPrev) { hr = pbc->RevokeObjectParam(L"_BSCB_Holder_"); if (SUCCEEDED(hr)) { TRACEIN(_T("Download() : _BSCB_Holder_")); // 今度は成功する hr = ::RegisterBindStatusCallback(pbc, (IBindStatusCallback*)pCBSCB, NULL, 0); if (SUCCEEDED(hr)) { pCBSCB->SetReferer(s_strReferer); s_strReferer.Empty(); pCBSCB->SetBSCB(pbscbPrev); pCBSCB->SetBindCtx(pbc); } } } else { #if 0 //\\ 自前でやっちゃうとまずいっぽい // pbscbPrevがNULLだったときの場合 LPOLESTR strUrl; hr = pmk->GetDisplayName(pbc, NULL, &strUrl); if (SUCCEEDED(hr)) { DownloadStart(strUrl); ::CoTaskMemFree(strUrl); return S_OK; } #endif if (pszHeaders == nullptr) { TRACEIN(_T("Download() : Referer : %s"), (LPCTSTR)s_strReferer); pCBSCB->SetReferer(s_strReferer); s_strReferer.Empty(); IBindCtx* pBC; hr = ::CreateAsyncBindCtx(0, pCBSCB, NULL, &pBC); pbc = pBC; } } if (SUCCEEDED(hr)) { CComPtr<IStream> spStream; hr = pmk->BindToStorage(pbc, NULL, IID_IStream, (void**)&spStream); } else { delete pCBSCB; } return hr; }