Microsoft KB Archive/172551

From BetaArchive Wiki
< Microsoft KB Archive
Revision as of 11:30, 21 July 2020 by X010 (talk | contribs) (Text replacement - "&" to "&")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Knowledge Base

PRB: CInternetSession::OpenURL() Fails with File Protocol

Article ID: 172551

Article Last Modified on 3/7/2005


  • Microsoft Foundation Class Library 4.2, when used with:
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++ 6.0 Standard Edition

This article was previously published under Q172551


CInternetSession::OpenURL() fails if you use a URL that specifies a file that contains spaces or other unsafe characters. For example, the following will fail:

   CMyInternetSession s("");
   CStdioFile* p = s.OpenURL("file://c:/temp/Text Document.txt");

As a result, a File Exception is thrown and the following message appears:

c:\temp\Text%20Document.txt was not found.


The specifications for a URL designate certain characters that must be escaped when they are present in a URL. The space character is one of the characters that must be escaped.

The function CInternetSession::OpenURL() calls a function that converts unsafe characters in the URL to their escape sequences before processing the URL further. If the URL is using the file protocol it creates a CStdioFile and returns a pointer to this object. However, CStdioFile does not understand the escaped path and, as a result, an exception is thrown.


When you use the file protocol, you must not convert unsafe characters to their escape sequences. The following code demonstrates how to do this by writing a CInternetSession derived class to override OpenURL().

   // class definition
   class CMyInternetSession : CInternetSession
      CMyInternetSession::CMyInternetSession(LPCTSTR pstrAgent = NULL,
         DWORD dwContext = 1, DWORD dwAccessType =
         LPCTSTR pstrProxyBypass = NULL, DWORD dwFlags = 0);

      CStdioFile* CMyInternetSession::OpenURL(LPCTSTR pstrURL,
         DWORD dwContext = 1, DWORD dwFlags =
         DWORD dwHeadersLength = 0);

   // CMyInternetSession constructor
   CMyInternetSession::CMyInternetSession(LPCTSTR pstrAgent,
      DWORD dwContext, DWORD dwAccessType, LPCTSTR pstrProxyName,
      LPCTSTR pstrProxyBypass, DWORD dwFlags)
      CInternetSession(pstrAgent, dwContext, dwAccessType, pstrProxyName,
         pstrProxyBypass, dwFlags);

   CStdioFile* CMyInternetSession::OpenURL(LPCTSTR pstrURL,
      DWORD dwContext, DWORD dwFlags, LPCTSTR pstrHeaders,
      DWORD dwHeadersLength)
      ASSERT(pstrURL != NULL);
      ASSERT(dwHeadersLength == 0 || pstrHeaders != NULL);

      // must have TRANSFER_BINARY or TRANSFER_ASCII but not both

      ASSERT((dwFlags & _AFX_TRANSFER_MASK) != 0);

      DWORD dwServiceType;
      CString strServer;
      CString strObject;
      INTERNET_PORT nPort;

      BOOL bParsed = AfxParseURL(pstrURL, dwServiceType,
         strServer, strObject, nPort);

      // if it turns out to be a file...
      if (bParsed && dwServiceType == AFX_INET_SERVICE_FILE)
         CString userName;
         CString password;

         // Get the normalized file name with out converting
         // unsafe characters to escape sequence.

         AfxParseURLEx(pstrURL, dwServiceType, strServer,
            strObject, nPort, userName, password, ICU_NO_ENCODE);

         int nMode = CFile::modeRead | CFile::shareCompat;
            nMode |= CFile::typeBinary;
            nMode |= CFile::typeText;

         return new CStdioFile(strObject, nMode);

      return CInternetSession::OpenURL(pstrURL,   dwContext, dwFlags,
         pstrHeaders, dwHeadersLength);


The specification for URL's are published by The World Wide Web Consortium (W3C). The specifications define the escape sequences and unsafe characters. Its URL is:

NOTE: Web links may change without notice.

Additional query words: 4.20b space file OpenURL filename

Keywords: kbprb KB172551