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