1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/urlmsw.cpp 
   3 // Purpose:     MS-Windows native URL support based on WinINet 
   4 // Author:      Hajo Kirchhoff 
   8 // Copyright:   (c) 2003 Hajo Kirchhoff 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  23     #include "wx/string.h" 
  25     #include "wx/module.h" 
  28 #if !wxUSE_PROTOCOL_HTTP 
  29 #include "wx/protocol/protocol.h" 
  31 // empty http protocol replacement (for now) 
  32 // so that wxUSE_URL_NATIVE can be used with 
  33 // wxSOCKETS==0 and wxUSE_PROTOCOL_HTTP==0 
  34 class wxHTTPDummyProto 
: public wxProtocol
 
  37     wxHTTPDummyProto() : wxProtocol() { } 
  39     wxProtocolError 
GetError() { return m_error
; } 
  41     virtual bool Abort() { return true; } 
  43     wxInputStream 
*GetInputStream(const wxString
& WXUNUSED(path
)) 
  45         return 0;   // input stream is returned by wxURLNativeImp 
  49     wxProtocolError m_error
; 
  51     DECLARE_DYNAMIC_CLASS_NO_COPY(wxHTTPDummyProto
) 
  52     DECLARE_PROTOCOL(wxHTTPDummyProto
) 
  55 // the only "reason for being" for this class is to tell 
  56 // wxURL that there is someone dealing with the http protocol 
  57 IMPLEMENT_DYNAMIC_CLASS(wxHTTPDummyProto
, wxProtocol
) 
  58 IMPLEMENT_PROTOCOL(wxHTTPDummyProto
, wxT("http"), NULL
, false) 
  59 USE_PROTOCOL(wxHTTPDummyProto
) 
  61 #endif // !wxUSE_PROTOCOL_HTTP 
  64 #ifdef __VISUALC__  // be conservative about this pragma 
  65     // tell the linker to include wininet.lib automatically 
  66     #pragma comment(lib, "wininet.lib") 
  75 // this class needn't be exported 
  76 class wxWinINetURL
:public wxURLNativeImp
 
  79     wxInputStream 
*GetInputStream(wxURL 
*owner
); 
  82     // return the WinINet session handle 
  83     static HINTERNET 
GetSessionHandle(); 
  86 HINTERNET 
wxWinINetURL::GetSessionHandle() 
  88     // this struct ensures that the session is opened when the 
  89     // first call to GetSessionHandle is made 
  90     // it also ensures that the session is closed when the program 
  92     static struct INetSession
 
  96             DWORD rc 
= InternetAttemptConnect(0); 
  98             m_handle 
= InternetOpen
 
 101                         INTERNET_OPEN_TYPE_PRECONFIG
, 
 104                         rc 
== ERROR_SUCCESS 
? 0 : INTERNET_FLAG_OFFLINE
 
 110             InternetCloseHandle(m_handle
); 
 116    return session
.m_handle
; 
 119 // this class needn't be exported 
 120 class /*WXDLLIMPEXP_NET */ wxWinINetInputStream 
: public wxInputStream
 
 123     wxWinINetInputStream(HINTERNET hFile
=0); 
 124     virtual ~wxWinINetInputStream(); 
 126     void Attach(HINTERNET hFile
); 
 128     wxFileOffset 
SeekI( wxFileOffset 
WXUNUSED(pos
), wxSeekMode 
WXUNUSED(mode
) ) 
 130     wxFileOffset 
TellI() const 
 134     void SetError(wxStreamError err
) { m_lasterror
=err
; } 
 136     size_t OnSysRead(void *buffer
, size_t bufsize
); 
 138     DECLARE_NO_COPY_CLASS(wxWinINetInputStream
) 
 141 size_t wxWinINetInputStream::OnSysRead(void *buffer
, size_t bufsize
) 
 144     if ( !InternetReadFile(m_hFile
, buffer
, bufsize
, &bytesread
) ) 
 146         DWORD lError 
= ::GetLastError(); 
 147         if ( lError 
!= ERROR_SUCCESS 
) 
 148             SetError(wxSTREAM_READ_ERROR
); 
 150         DWORD iError
, bLength
; 
 151         InternetGetLastResponseInfo(&iError
, NULL
, &bLength
); 
 154             wxString errorString
; 
 155             InternetGetLastResponseInfo
 
 158                 wxStringBuffer(errorString
, bLength
), 
 162             wxLogError(wxT("Read failed with error %d: %s"), 
 163                        iError
, errorString
); 
 167     if ( bytesread 
== 0 ) 
 169         SetError(wxSTREAM_EOF
); 
 175 wxWinINetInputStream::wxWinINetInputStream(HINTERNET hFile
) 
 180 void wxWinINetInputStream::Attach(HINTERNET newHFile
) 
 182     wxCHECK_RET(m_hFile
==NULL
, 
 183         wxT("cannot attach new stream when stream already exists")); 
 185     SetError(m_hFile
!=NULL 
? wxSTREAM_NO_ERROR 
: wxSTREAM_READ_ERROR
); 
 188 wxWinINetInputStream::~wxWinINetInputStream() 
 192         InternetCloseHandle(m_hFile
); 
 197 wxURLNativeImp 
*wxURL::CreateNativeImpObject() 
 199     return new wxWinINetURL
; 
 202 wxInputStream 
*wxWinINetURL::GetInputStream(wxURL 
*owner
) 
 205     if ( owner
->GetScheme() == wxT("http") ) 
 207         service 
= INTERNET_SERVICE_HTTP
; 
 209     else if ( owner
->GetScheme() == wxT("ftp") ) 
 211         service 
= INTERNET_SERVICE_FTP
; 
 215         // unknown protocol. Let wxURL try another method. 
 219     wxWinINetInputStream 
*newStream 
= new wxWinINetInputStream
; 
 220     HINTERNET newStreamHandle 
= InternetOpenUrl
 
 226                                     INTERNET_FLAG_KEEP_CONNECTION 
| 
 227                                     INTERNET_FLAG_PASSIVE
, 
 230     newStream
->Attach(newStreamHandle
); 
 235 #endif // wxUSE_URL_NATIVE