//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995. // // File: cnetftp.cxx // // Contents: // // Classes: // // Functions: // // History: 2-06-96 JohannP (Johann Posch) Created // //---------------------------------------------------------------------------- #include #ifdef unix #include #endif /* unix */ #include static DWORD dwLstError; PerfDbgTag(tagCINetFile, "Urlmon", "Log CINetFile", DEB_PROT); DbgTag(tagCINetFileErr, "Urlmon", "Log CINetFile Errors", DEB_PROT|DEB_ERROR); PerfDbgTag(tagCINetSimple, "Urlmon", "Log CINetSimple", DEB_PROT); #ifdef unix extern "C" void unixForceAutoProxSync(); #endif /* unix */ LPWSTR FindFileExtensionW(LPWSTR pwzFileName) { DEBUG_ENTER((DBG_APP, Pointer, "FindFileExtensionW", "%.80wq", pwzFileName )); LPWSTR pStr = NULL; LPWSTR lpF = pwzFileName + wcslen(pwzFileName); //Point to null if (lpF) { //Strip all trailing dots. for (lpF--; lpF >= pwzFileName && (*lpF == L'.' || *lpF == L' '); lpF --) *lpF = 0; for (; lpF >= pwzFileName && *lpF != L'.'; lpF --) if (*lpF == L'\\') return NULL; } if (lpF > pwzFileName) { pStr = lpF; } DEBUG_LEAVE(pStr); return pStr; } //+--------------------------------------------------------------------------- // // Method: CINetFile::CINetFile // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- CINetFile::CINetFile(REFCLSID rclsid, IUnknown *pUnkOuter) : CINet(rclsid,pUnkOuter) { DEBUG_ENTER((DBG_APP, None, "CINetFile::CINetFile", "this=%#x, %#x, %#x", this, &rclsid, pUnkOuter )); PerfDbgLog(tagCINetFile, this, "+CINetFile::CINetFile"); _dwIsA = DLD_PROTOCOL_FILE; _wzFileName[0] = '\0'; PerfDbgLog(tagCINetFile, this, "-CINetFile::CINetFile"); DEBUG_LEAVE(0); } //+--------------------------------------------------------------------------- // // Method: CINetFile::~CINetFile // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- CINetFile::~CINetFile() { DEBUG_ENTER((DBG_APP, None, "CINetFile::~CINetFile", "this=%#x", this )); PerfDbgLog(tagCINetFile, this, "+CINetFile::~CINetFile"); if (_hFile && (_hFile != INVALID_HANDLE_VALUE)) { CloseHandle(_hFile); } _wzFileName[0] = '\0'; PerfDbgLog(tagCINetFile, this, "-CINetFile::~CINetFile"); DEBUG_LEAVE(0); } //+--------------------------------------------------------------------------- // // Method: CINetFile::INetAsyncOpen // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetFile::INetAsyncOpen() { DEBUG_ENTER((DBG_APP, Hresult, "CINetFile::INetAsyncOpen", "this=%#x", this )); HRESULT hr = NOERROR; DWORD dwAttr; PerfDbgLog1(tagCINetFile, this, "+CINetFile::INetAsyncOpen(szObject:%ws)", GetObjectNameW()); ReportNotification(BINDSTATUS_SENDINGREQUEST, GetServerName()); // nothing to do - just call dwAttr = GetFileAttributesWrapW(GetObjectNameW()); #ifdef unix unixForceAutoProxSync(); if(access(GetObjectName(),R_OK) == -1) { SetLastError(ERROR_ACCESS_DENIED); dwAttr = 0xffffffff; } #endif /* unix */ if ( (dwAttr != 0xffffffff) && !(dwAttr & FILE_ATTRIBUTE_DIRECTORY) ) { HANDLE htemp = 0; DWORD dwSize = 0; { WIN32_FIND_DATAW finddata; htemp = FindFirstFileWrapW(GetObjectNameW(), &finddata); dwSize = finddata.nFileSizeLow; } _cbTotalBytesRead = dwSize; _cbDataSize = dwSize; if (htemp && (htemp != INVALID_HANDLE_VALUE)) { ReportNotificationW(BINDSTATUS_CACHEFILENAMEAVAILABLE, GetObjectNameW()); // if the file has a file extension, try to // determine the MIME type that way... // LPWSTR pwsz = GetObjectNameW(); pwsz = FindFileExtensionW(pwsz); if (pwsz) { char psz[MAX_PATH]; psz[0] = '\0'; W2A(pwsz, psz, MAX_PATH); char szMime[MAX_PATH]; DWORD cb = MAX_PATH; if (SUCCEEDED(GetMimeFromExt(psz,szMime,&cb))) { if( _grfBindF & BINDF_FROMURLMON ) { ReportNotification(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, szMime); } else { ReportNotification(BINDSTATUS_MIMETYPEAVAILABLE, szMime); } } } if (_pCTrans) { _bscf |= BSCF_LASTDATANOTIFICATION; _pCTrans->ReportData(_bscf, _cbTotalBytesRead, _cbDataSize); ReportResultAndStop(NOERROR, _cbTotalBytesRead, _cbDataSize ); } _hrError = INET_E_DONE; hr = NOERROR; FindClose(htemp); } else { SetCNetBindResult(GetLastError()); hr = _hrError = INET_E_DATA_NOT_AVAILABLE; } } else if( (dwAttr != 0xffffffff) && (dwAttr & FILE_ATTRIBUTE_DIRECTORY) ) { hr = _hrError = INET_E_REDIRECT_TO_DIR; } else { // BUGBUG do authentication if this call failed due to // net permission being denied DbgLog2(tagCINetFileErr, this, "-CINetFile::INetAsyncOpen failed (dwAttr:%ld,filename:%ws)",dwAttr,GetObjectNameW()); // If you pass \\servername to GetFileAttributesWrap, on NT4 it will return ERROR_FILE_NOT_FOUND // but ERROR_INVALID_NAME on all other platforms. // We remap this error so that iframes can navigate to \\servername on NT4 // Reference: IE5/102590 DWORD dwError = GetLastError(); if ((dwError==ERROR_FILE_NOT_FOUND) && PathIsUNCServer(GetObjectName())) { dwError = ERROR_INVALID_NAME; } // set the exact error for GetBindResult SetCNetBindResult(dwError); hr = _hrError = INET_E_RESOURCE_NOT_FOUND; } PerfDbgLog1(tagCINetFile, this, "-CINetFile::INetAsyncOpen (hr:%lx)", hr); DEBUG_LEAVE(hr); return hr; } //+--------------------------------------------------------------------------- // // Method: CINetFile::Read // // Synopsis: // // Arguments: [pBuffer] -- // [cbBytes] -- // [pcbBytes] -- // // Returns: // // History: 2-13-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- STDMETHODIMP CINetFile::Read(void *pBuffer, DWORD cbBytes, DWORD *pcbBytes) { DEBUG_ENTER((DBG_APP, Hresult, "CINetFile::IInternetProtocol::Read", "this=%#x, %#x, %#x, %#x", this, pBuffer, cbBytes, pcbBytes )); PerfDbgLog(tagCINetFile, this, "+CINetFile::Read"); HRESULT hr = NOERROR; PProtAssert((cbBytes && pcbBytes)); if (!_hFile) { LPWSTR wszFile = GetObjectNameW(); PProtAssert((wszFile)); if (wszFile) { // fill the internal buffer for data sniffing _hFile = CreateFileWrapW(wszFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } } if (_hFile != INVALID_HANDLE_VALUE) { DWORD dwRead; if (ReadFile(_hFile, pBuffer, cbBytes, &dwRead, NULL)) { *pcbBytes = dwRead; if (cbBytes != dwRead) { hr = S_FALSE; } } else { DbgLog2(tagCINetFileErr, this, " -CINetFile::Read could not read file (sniffing:%ld) (hr:%lx)", dwRead, hr); SetCNetBindResult(GetLastError()); hr = _hrError = INET_E_DATA_NOT_AVAILABLE; ReportResultAndStop(hr); } } else { SetCNetBindResult(GetLastError()); hr = _hrError = INET_E_DATA_NOT_AVAILABLE; ReportResultAndStop(hr); DbgLog2(tagCINetFileErr, this, "-CINetFile::Read could not open (file:%ws, hr:%lx)", GetObjectNameW(), hr); } PerfDbgLog4(tagCINetFile, this, "-CINetFile::Read (_hrError:%lx, [hr:%lx,cbBytesAsked:%ld,cbBytesReturned:%ld])", _hrError, hr, cbBytes, *pcbBytes); DEBUG_LEAVE(hr); return hr; } //+--------------------------------------------------------------------------- // // Method: CINetFile::LockFile // // Synopsis: // // Arguments: // // Returns: // // History: 8-13-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetFile::LockFile(BOOL fRetrieve) { DEBUG_ENTER((DBG_APP, Hresult, "CINetFile::LockFile", "this=%#x, %B", this, fRetrieve )); PerfDbgLog(tagCINetFile, this, "+CINetFile::LockFile"); HRESULT hr = NOERROR; if (!_hFile ) { _hFile = CreateFileWrapW( GetObjectNameW(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } if (_hFile != INVALID_HANDLE_VALUE) { _fLocked = TRUE; } PerfDbgLog1(tagCINetFile, this, "-CINetFile::LockFile (hr:%lx,)", hr); DEBUG_LEAVE(hr); return hr; } //+--------------------------------------------------------------------------- // // Method: CINetFile::UnlockFile // // Synopsis: // // Arguments: (none) // // Returns: // // History: 8-13-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetFile::UnlockFile() { DEBUG_ENTER((DBG_APP, Hresult, "CINetFile::UnlockFile", "this=%#x", this )); PerfDbgLog(tagCINetFile, this, "IN CINetFile::UnlockFile"); HRESULT hr = NOERROR; if (_fLocked) { PProtAssert((_hFile)); CloseHandle(_hFile); _hFile = NULL; _fLocked = FALSE; } PerfDbgLog1(tagCINetFile, this, "-CINetFile::UnlockFile (hr:%lx)", hr); DEBUG_LEAVE(hr); return hr; } //+--------------------------------------------------------------------------- // // Method: CINetSimple::CINetSimple // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- CINetSimple::CINetSimple(REFCLSID rclsid, IUnknown *pUnkOuter) : CINet(rclsid,pUnkOuter) { DEBUG_ENTER((DBG_APP, None, "CINetSimple::CINetSimple", "this=%#x, %#x, %#x", this, &rclsid, pUnkOuter )); PerfDbgLog(tagCINetSimple, this, "+CINetSimple::CINetSimple"); _dwState = INetState_START; _dwIsA = DLD_PROTOCOL_NONE; PerfDbgLog(tagCINetSimple, this, "-CINetSimple::CINetSimple"); DEBUG_LEAVE(0); } //+--------------------------------------------------------------------------- // // Method: CINetSimple::~CINetSimple // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- CINetSimple::~CINetSimple() { DEBUG_ENTER((DBG_APP, None, "CINetSimple::~CINetSimple", "this=%#x", this )); DEBUG_LEAVE(0); } //+--------------------------------------------------------------------------- // // Method: CINetSimple::INetAsyncOpenRequest // // Synopsis: // // Arguments: (none) // // Returns: // // History: 1-27-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetSimple::INetAsyncOpenRequest() { DEBUG_ENTER((DBG_APP, Hresult, "CINetSimple::INetAsyncOpenRequest", "this=%#x", this )); PerfDbgLog(tagCINetSimple, this, "+CINetSimple::INetAsyncOpenRequest"); HRESULT hr = NOERROR; DWORD dwBindF = 0; SetINetState(INetState_PROTOPEN_REQUEST); PProtAssert((g_hSession != NULL)); if (_hRequest && _fDoSimpleRetry) { // Abort the previous request if needed. // Note: This is CINetSimple, so the behavior of closing the previous // handle and retrying only applies to FTP and gopher requests. _fDoSimpleRetry = FALSE; _fHandlesRecycled = TRUE; TerminateRequest(); } // get the open flags dwBindF = GetBindFlags(); if (dwBindF & BINDF_GETNEWESTVERSION) { _dwOpenFlags |= INTERNET_FLAG_RELOAD; } if ( (dwBindF & BINDF_NOWRITECACHE) //BUG-WORK //&& !_pCTransData->IsFileRequired() ) { _dwOpenFlags |= INTERNET_FLAG_DONT_CACHE ; } // BUGBUG OFFLINE, RELOAD, RESYNCHRONIZE and HYPERLINK are mutually // exclusive. But inside wininet there is priority, so // the priority is OFFLINE, RELOAD, RESYNCHRONIZE, HYPERLINK in that order if (dwBindF & BINDF_RESYNCHRONIZE) { // caller asking to do if-modified-since _dwOpenFlags |= INTERNET_FLAG_RESYNCHRONIZE; } if (dwBindF & BINDF_HYPERLINK) { // caller syas this is a hyperlink access _dwOpenFlags |= INTERNET_FLAG_HYPERLINK; } PrivAddRef(); _HandleStateRequest = HandleState_Pending; // we always request keep-alive, use an existing connection (FTP) and // passive mode transfers (also FTP) _dwOpenFlags |= INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_PASSIVE; HINTERNET hRequestTmp = InternetOpenUrl(g_hSession, _pszFullURL, NULL, 0, _dwOpenFlags, (DWORD_PTR) this); if ( hRequestTmp == 0) { dwLstError = GetLastError(); if (dwLstError == ERROR_IO_PENDING) { // wait async for the handle hr = E_PENDING; SetStatePending(E_PENDING); } else { _hrError = INET_E_CANNOT_CONNECT; hr = E_FAIL; } } else { _hRequest = hRequestTmp; _HandleStateRequest = HandleState_Initialized; hr = INetAsyncSendRequest(); } if (_hrError != INET_E_OK) { // we need to terminate here ReportResultAndStop(NOERROR); } PerfDbgLog1(tagCINetSimple, this, "-CINetSimple::INetAsyncOpenRequest (hr:%lx)", hr); DEBUG_LEAVE(hr); return hr; } //+--------------------------------------------------------------------------- // // Method: CINetSimple::INetAsyncSendRequest // // Synopsis: // // Arguments: (none) // // Returns: // // History: 1-27-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetSimple::INetAsyncSendRequest() { DEBUG_ENTER((DBG_APP, Hresult, "CINetSimple::INetAsyncSendRequest", "this=%#x", this )); PerfDbgLog(tagCINetSimple, this, "+CINetSimple::INetAsyncSendRequest"); HRESULT hr = NOERROR; hr = QueryStatusOnResponse(); if (! _fDoSimpleRetry && hr == NOERROR) { SetINetState(INetState_SEND_REQUEST); if (OperationOnAparmentThread(INetState_SEND_REQUEST)) { TransitState(INetState_READ); } else { hr = INetRead(); } } if (_hrError != INET_E_OK) { // we need to terminate here ReportResultAndStop(NOERROR); } PerfDbgLog1(tagCINetSimple, this, "-CINetSimple::INetAsyncSendRequest (hr:%lx)", hr); DEBUG_LEAVE(hr); return hr; } //+--------------------------------------------------------------------------- // // Method: CINetSimple::INetAsyncConnect // // Synopsis: // // Arguments: (none) // // Returns: // // History: 1-27-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetSimple::INetAsyncConnect() { DEBUG_ENTER((DBG_APP, Hresult, "CINetSimple::INetAsyncConnect", "this=%#x", this )); PerfDbgLog(tagCINetSimple, this, "+CINetSimple::INetAsyncConnect"); HRESULT hr = NOERROR; //just go into OpenRequest state hr = INetAsyncOpenRequest(); PerfDbgLog1(tagCINetSimple, this, "-CINetSimple::INetAsyncConnect (hr:%lx)", hr); DEBUG_LEAVE(hr); return hr; } //+--------------------------------------------------------------------------- // // Method: CINetSimple::QueryStatusOnResponse // // Synopsis: // // Arguments: (none) // // Returns: // // History: 11-14-97 OliverW (Oliver Wallace) Created // 09-18-98 MeadH (Mead Himelstein) copy over to shipping code // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetSimple::QueryStatusOnResponse() { DEBUG_ENTER((DBG_APP, Hresult, "CINetSimple::QueryStatusOnResponse", "this=%#x", this )); PerfDbgLog(tagCINetSimple, this, "+CINetSimple::QueryStatusOnResponse"); HRESULT hr = NOERROR; DWORD dwStatus = 0; DWORD cbLen = sizeof(DWORD); if (HttpQueryInfo( _hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, (LPVOID) &dwStatus, &cbLen, NULL )) { if (dwStatus == HTTP_STATUS_PROXY_AUTH_REQ) { _hrINet = INET_E_AUTHENTICATION_REQUIRED; TransitState(INetState_AUTHENTICATE, TRUE); hr = E_PENDING; } } PerfDbgLog1(tagCINetSimple, this, "-CINetSimple::QueryStatusOnResponse (hr:%lx)", hr); DEBUG_LEAVE(hr); return hr; } //+--------------------------------------------------------------------------- // // Method: CINetSimple::QueryStatusOnResponseDefault // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-02-98 OliverW Created // 09-18-98 MeadH (Mead Himelstein) copy over to shipping code // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetSimple::QueryStatusOnResponseDefault(DWORD dwStat) { DEBUG_ENTER((DBG_APP, Hresult, "CINetSimple::QueryStatusOnResponseDefault", "this=%#x, %#x", this, dwStat )); PerfDbgLog(tagCINetSimple, this, "+CINetSimple::QueryStatusOnResponseDefault"); PerfDbgLog1(tagCINetSimple, this, "-CINetSimple::QueryStatusOnResponseDefault (hr:%lx)", NOERROR); DEBUG_LEAVE(NOERROR); return NOERROR; } //+--------------------------------------------------------------------------- // // Method: CINetSimple::QueryHeaderOnResponse // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-02-98 OliverW Created // 09-18-98 MeadH (Mead Himelstein) copy over to shipping code // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetSimple::QueryHeaderOnResponse() { DEBUG_ENTER((DBG_APP, Hresult, "CINetSimple::QueryHeaderOnResponse", "this=%#x", this )); PerfDbgLog(tagCINetSimple, this, "+CINetSimple::QueryHeaderOnResponse"); PerfDbgLog1(tagCINetSimple, this, "-CINetSimple::QueryHeaderOnResponse (hr:%lx)", NOERROR); DEBUG_LEAVE(NOERROR); return NOERROR; } //+--------------------------------------------------------------------------- // // Method: CINetFtp::CINetFtp // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- CINetFtp::CINetFtp(REFCLSID rclsid, IUnknown *pUnkOuter) : CINetSimple(rclsid, pUnkOuter) { DEBUG_ENTER((DBG_APP, None, "CINetFtp::CINetFtp", "this=%#x, %#x, %#x", this, &rclsid, pUnkOuter )); PerfDbgLog(tagCINetSimple, this, "+CINetFtp::CINetFtp"); _dwIsA = DLD_PROTOCOL_FTP; PerfDbgLog(tagCINetSimple, this, "-CINetFtp::CINetFtp"); DEBUG_LEAVE(0); } //+--------------------------------------------------------------------------- // // Method: CINetFtp::INetAsyncSendRequest // // Synopsis: // // Arguments: (none) // // Returns: // // History: 3-13-98 VincentR Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CINetFtp::INetAsyncSendRequest() { DEBUG_ENTER((DBG_APP, Hresult, "CINetFtp::INetAsyncSendRequest", "this=%#x", this )); HRESULT hr = NOERROR; DWORD dwLowSize = 0; DWORD dwHighSize = 0; dwLowSize = FtpGetFileSize(_hRequest, &dwHighSize); if(dwLowSize != 0xffffffff) _cbDataSize = dwLowSize; hr = CINetSimple::INetAsyncSendRequest(); DEBUG_LEAVE(hr); return(hr); } //+--------------------------------------------------------------------------- // // Method: CINetFtp::~CINetFtp // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- CINetFtp::~CINetFtp() { DEBUG_ENTER((DBG_APP, None, "CINetFtp::~CINetFtp", "this=%#x", this )); DEBUG_LEAVE(0); } //+--------------------------------------------------------------------------- // // Method: CINetGopher::CINetGopher // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- CINetGopher::CINetGopher(REFCLSID rclsid, IUnknown *pUnkOuter) : CINetSimple(rclsid,pUnkOuter) { DEBUG_ENTER((DBG_APP, None, "CINetGopher::CINetGopher", "this=%#x, %#x, %#x", this, &rclsid, pUnkOuter )); PerfDbgLog(tagCINetSimple, this, "+CINetGopher::CINetGopher"); _dwIsA = DLD_PROTOCOL_GOPHER; PerfDbgLog(tagCINetSimple, this, "-CINetGopher::CINetGopher"); DEBUG_LEAVE(0); } //+--------------------------------------------------------------------------- // // Method: CINetGopher::~CINetGopher // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-96 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- CINetGopher::~CINetGopher() { DEBUG_ENTER((DBG_APP, None, "CINetGopher::~CINetGopher", "this=%#x", this )); DEBUG_LEAVE(0); }