1*1230fdc1SLionel Sambuc #include "expat.h"
2*1230fdc1SLionel Sambuc #ifdef XML_UNICODE
3*1230fdc1SLionel Sambuc #define UNICODE
4*1230fdc1SLionel Sambuc #endif
5*1230fdc1SLionel Sambuc #include <windows.h>
6*1230fdc1SLionel Sambuc #include <urlmon.h>
7*1230fdc1SLionel Sambuc #include <wininet.h>
8*1230fdc1SLionel Sambuc #include <stdio.h>
9*1230fdc1SLionel Sambuc #include <tchar.h>
10*1230fdc1SLionel Sambuc #include "xmlurl.h"
11*1230fdc1SLionel Sambuc #include "xmlmime.h"
12*1230fdc1SLionel Sambuc
13*1230fdc1SLionel Sambuc static int
14*1230fdc1SLionel Sambuc processURL(XML_Parser parser, IMoniker *baseMoniker, const XML_Char *url);
15*1230fdc1SLionel Sambuc
16*1230fdc1SLionel Sambuc typedef void (*StopHandler)(void *, HRESULT);
17*1230fdc1SLionel Sambuc
18*1230fdc1SLionel Sambuc class Callback : public IBindStatusCallback {
19*1230fdc1SLionel Sambuc public:
20*1230fdc1SLionel Sambuc // IUnknown methods
21*1230fdc1SLionel Sambuc STDMETHODIMP QueryInterface(REFIID,void **);
22*1230fdc1SLionel Sambuc STDMETHODIMP_(ULONG) AddRef();
23*1230fdc1SLionel Sambuc STDMETHODIMP_(ULONG) Release();
24*1230fdc1SLionel Sambuc // IBindStatusCallback methods
25*1230fdc1SLionel Sambuc STDMETHODIMP OnStartBinding(DWORD, IBinding *);
26*1230fdc1SLionel Sambuc STDMETHODIMP GetPriority(LONG *);
27*1230fdc1SLionel Sambuc STDMETHODIMP OnLowResource(DWORD);
28*1230fdc1SLionel Sambuc STDMETHODIMP OnProgress(ULONG, ULONG, ULONG, LPCWSTR);
29*1230fdc1SLionel Sambuc STDMETHODIMP OnStopBinding(HRESULT, LPCWSTR);
30*1230fdc1SLionel Sambuc STDMETHODIMP GetBindInfo(DWORD *, BINDINFO *);
31*1230fdc1SLionel Sambuc STDMETHODIMP OnDataAvailable(DWORD, DWORD, FORMATETC *, STGMEDIUM *);
32*1230fdc1SLionel Sambuc STDMETHODIMP OnObjectAvailable(REFIID, IUnknown *);
33*1230fdc1SLionel Sambuc Callback(XML_Parser, IMoniker *, StopHandler, void *);
34*1230fdc1SLionel Sambuc ~Callback();
35*1230fdc1SLionel Sambuc int externalEntityRef(const XML_Char *context,
36*1230fdc1SLionel Sambuc const XML_Char *systemId, const XML_Char *publicId);
37*1230fdc1SLionel Sambuc private:
38*1230fdc1SLionel Sambuc XML_Parser parser_;
39*1230fdc1SLionel Sambuc IMoniker *baseMoniker_;
40*1230fdc1SLionel Sambuc DWORD totalRead_;
41*1230fdc1SLionel Sambuc ULONG ref_;
42*1230fdc1SLionel Sambuc IBinding *pBinding_;
43*1230fdc1SLionel Sambuc StopHandler stopHandler_;
44*1230fdc1SLionel Sambuc void *stopArg_;
45*1230fdc1SLionel Sambuc };
46*1230fdc1SLionel Sambuc
STDMETHODIMP_(ULONG)47*1230fdc1SLionel Sambuc STDMETHODIMP_(ULONG)
48*1230fdc1SLionel Sambuc Callback::AddRef()
49*1230fdc1SLionel Sambuc {
50*1230fdc1SLionel Sambuc return ref_++;
51*1230fdc1SLionel Sambuc }
52*1230fdc1SLionel Sambuc
STDMETHODIMP_(ULONG)53*1230fdc1SLionel Sambuc STDMETHODIMP_(ULONG)
54*1230fdc1SLionel Sambuc Callback::Release()
55*1230fdc1SLionel Sambuc {
56*1230fdc1SLionel Sambuc if (--ref_ == 0) {
57*1230fdc1SLionel Sambuc delete this;
58*1230fdc1SLionel Sambuc return 0;
59*1230fdc1SLionel Sambuc }
60*1230fdc1SLionel Sambuc return ref_;
61*1230fdc1SLionel Sambuc }
62*1230fdc1SLionel Sambuc
63*1230fdc1SLionel Sambuc STDMETHODIMP
QueryInterface(REFIID riid,void ** ppv)64*1230fdc1SLionel Sambuc Callback::QueryInterface(REFIID riid, void** ppv)
65*1230fdc1SLionel Sambuc {
66*1230fdc1SLionel Sambuc if (IsEqualGUID(riid, IID_IUnknown))
67*1230fdc1SLionel Sambuc *ppv = (IUnknown *)this;
68*1230fdc1SLionel Sambuc else if (IsEqualGUID(riid, IID_IBindStatusCallback))
69*1230fdc1SLionel Sambuc *ppv = (IBindStatusCallback *)this;
70*1230fdc1SLionel Sambuc else
71*1230fdc1SLionel Sambuc return E_NOINTERFACE;
72*1230fdc1SLionel Sambuc ((LPUNKNOWN)*ppv)->AddRef();
73*1230fdc1SLionel Sambuc return S_OK;
74*1230fdc1SLionel Sambuc }
75*1230fdc1SLionel Sambuc
76*1230fdc1SLionel Sambuc STDMETHODIMP
OnStartBinding(DWORD,IBinding * pBinding)77*1230fdc1SLionel Sambuc Callback::OnStartBinding(DWORD, IBinding* pBinding)
78*1230fdc1SLionel Sambuc {
79*1230fdc1SLionel Sambuc pBinding_ = pBinding;
80*1230fdc1SLionel Sambuc pBinding->AddRef();
81*1230fdc1SLionel Sambuc return S_OK;
82*1230fdc1SLionel Sambuc }
83*1230fdc1SLionel Sambuc
84*1230fdc1SLionel Sambuc STDMETHODIMP
GetPriority(LONG *)85*1230fdc1SLionel Sambuc Callback::GetPriority(LONG *)
86*1230fdc1SLionel Sambuc {
87*1230fdc1SLionel Sambuc return E_NOTIMPL;
88*1230fdc1SLionel Sambuc }
89*1230fdc1SLionel Sambuc
90*1230fdc1SLionel Sambuc STDMETHODIMP
OnLowResource(DWORD)91*1230fdc1SLionel Sambuc Callback::OnLowResource(DWORD)
92*1230fdc1SLionel Sambuc {
93*1230fdc1SLionel Sambuc return E_NOTIMPL;
94*1230fdc1SLionel Sambuc }
95*1230fdc1SLionel Sambuc
96*1230fdc1SLionel Sambuc STDMETHODIMP
OnProgress(ULONG,ULONG,ULONG,LPCWSTR)97*1230fdc1SLionel Sambuc Callback::OnProgress(ULONG, ULONG, ULONG, LPCWSTR)
98*1230fdc1SLionel Sambuc {
99*1230fdc1SLionel Sambuc return S_OK;
100*1230fdc1SLionel Sambuc }
101*1230fdc1SLionel Sambuc
102*1230fdc1SLionel Sambuc STDMETHODIMP
OnStopBinding(HRESULT hr,LPCWSTR szError)103*1230fdc1SLionel Sambuc Callback::OnStopBinding(HRESULT hr, LPCWSTR szError)
104*1230fdc1SLionel Sambuc {
105*1230fdc1SLionel Sambuc if (pBinding_) {
106*1230fdc1SLionel Sambuc pBinding_->Release();
107*1230fdc1SLionel Sambuc pBinding_ = 0;
108*1230fdc1SLionel Sambuc }
109*1230fdc1SLionel Sambuc if (baseMoniker_) {
110*1230fdc1SLionel Sambuc baseMoniker_->Release();
111*1230fdc1SLionel Sambuc baseMoniker_ = 0;
112*1230fdc1SLionel Sambuc }
113*1230fdc1SLionel Sambuc stopHandler_(stopArg_, hr);
114*1230fdc1SLionel Sambuc return S_OK;
115*1230fdc1SLionel Sambuc }
116*1230fdc1SLionel Sambuc
117*1230fdc1SLionel Sambuc STDMETHODIMP
GetBindInfo(DWORD * pgrfBINDF,BINDINFO * pbindinfo)118*1230fdc1SLionel Sambuc Callback::GetBindInfo(DWORD* pgrfBINDF, BINDINFO* pbindinfo)
119*1230fdc1SLionel Sambuc {
120*1230fdc1SLionel Sambuc *pgrfBINDF = BINDF_ASYNCHRONOUS;
121*1230fdc1SLionel Sambuc return S_OK;
122*1230fdc1SLionel Sambuc }
123*1230fdc1SLionel Sambuc
124*1230fdc1SLionel Sambuc static void
reportError(XML_Parser parser)125*1230fdc1SLionel Sambuc reportError(XML_Parser parser)
126*1230fdc1SLionel Sambuc {
127*1230fdc1SLionel Sambuc int code = XML_GetErrorCode(parser);
128*1230fdc1SLionel Sambuc const XML_Char *message = XML_ErrorString(code);
129*1230fdc1SLionel Sambuc if (message)
130*1230fdc1SLionel Sambuc _ftprintf(stderr, _T("%s:%d:%ld: %s\n"),
131*1230fdc1SLionel Sambuc XML_GetBase(parser),
132*1230fdc1SLionel Sambuc XML_GetErrorLineNumber(parser),
133*1230fdc1SLionel Sambuc XML_GetErrorColumnNumber(parser),
134*1230fdc1SLionel Sambuc message);
135*1230fdc1SLionel Sambuc else
136*1230fdc1SLionel Sambuc _ftprintf(stderr, _T("%s: (unknown message %d)\n"),
137*1230fdc1SLionel Sambuc XML_GetBase(parser), code);
138*1230fdc1SLionel Sambuc }
139*1230fdc1SLionel Sambuc
140*1230fdc1SLionel Sambuc STDMETHODIMP
OnDataAvailable(DWORD grfBSCF,DWORD dwSize,FORMATETC * pfmtetc,STGMEDIUM * pstgmed)141*1230fdc1SLionel Sambuc Callback::OnDataAvailable(DWORD grfBSCF,
142*1230fdc1SLionel Sambuc DWORD dwSize,
143*1230fdc1SLionel Sambuc FORMATETC *pfmtetc,
144*1230fdc1SLionel Sambuc STGMEDIUM* pstgmed)
145*1230fdc1SLionel Sambuc {
146*1230fdc1SLionel Sambuc if (grfBSCF & BSCF_FIRSTDATANOTIFICATION) {
147*1230fdc1SLionel Sambuc IWinInetHttpInfo *hp;
148*1230fdc1SLionel Sambuc HRESULT hr = pBinding_->QueryInterface(IID_IWinInetHttpInfo,
149*1230fdc1SLionel Sambuc (void **)&hp);
150*1230fdc1SLionel Sambuc if (SUCCEEDED(hr)) {
151*1230fdc1SLionel Sambuc char contentType[1024];
152*1230fdc1SLionel Sambuc DWORD bufSize = sizeof(contentType);
153*1230fdc1SLionel Sambuc DWORD flags = 0;
154*1230fdc1SLionel Sambuc contentType[0] = 0;
155*1230fdc1SLionel Sambuc hr = hp->QueryInfo(HTTP_QUERY_CONTENT_TYPE, contentType,
156*1230fdc1SLionel Sambuc &bufSize, 0, NULL);
157*1230fdc1SLionel Sambuc if (SUCCEEDED(hr)) {
158*1230fdc1SLionel Sambuc char charset[CHARSET_MAX];
159*1230fdc1SLionel Sambuc getXMLCharset(contentType, charset);
160*1230fdc1SLionel Sambuc if (charset[0]) {
161*1230fdc1SLionel Sambuc #ifdef XML_UNICODE
162*1230fdc1SLionel Sambuc XML_Char wcharset[CHARSET_MAX];
163*1230fdc1SLionel Sambuc XML_Char *p1 = wcharset;
164*1230fdc1SLionel Sambuc const char *p2 = charset;
165*1230fdc1SLionel Sambuc while ((*p1++ = (unsigned char)*p2++) != 0)
166*1230fdc1SLionel Sambuc ;
167*1230fdc1SLionel Sambuc XML_SetEncoding(parser_, wcharset);
168*1230fdc1SLionel Sambuc #else
169*1230fdc1SLionel Sambuc XML_SetEncoding(parser_, charset);
170*1230fdc1SLionel Sambuc #endif
171*1230fdc1SLionel Sambuc }
172*1230fdc1SLionel Sambuc }
173*1230fdc1SLionel Sambuc hp->Release();
174*1230fdc1SLionel Sambuc }
175*1230fdc1SLionel Sambuc }
176*1230fdc1SLionel Sambuc if (!parser_)
177*1230fdc1SLionel Sambuc return E_ABORT;
178*1230fdc1SLionel Sambuc if (pstgmed->tymed == TYMED_ISTREAM) {
179*1230fdc1SLionel Sambuc while (totalRead_ < dwSize) {
180*1230fdc1SLionel Sambuc #define READ_MAX (64*1024)
181*1230fdc1SLionel Sambuc DWORD nToRead = dwSize - totalRead_;
182*1230fdc1SLionel Sambuc if (nToRead > READ_MAX)
183*1230fdc1SLionel Sambuc nToRead = READ_MAX;
184*1230fdc1SLionel Sambuc void *buf = XML_GetBuffer(parser_, nToRead);
185*1230fdc1SLionel Sambuc if (!buf) {
186*1230fdc1SLionel Sambuc _ftprintf(stderr, _T("out of memory\n"));
187*1230fdc1SLionel Sambuc return E_ABORT;
188*1230fdc1SLionel Sambuc }
189*1230fdc1SLionel Sambuc DWORD nRead;
190*1230fdc1SLionel Sambuc HRESULT hr = pstgmed->pstm->Read(buf, nToRead, &nRead);
191*1230fdc1SLionel Sambuc if (SUCCEEDED(hr)) {
192*1230fdc1SLionel Sambuc totalRead_ += nRead;
193*1230fdc1SLionel Sambuc if (!XML_ParseBuffer(parser_,
194*1230fdc1SLionel Sambuc nRead,
195*1230fdc1SLionel Sambuc (grfBSCF & BSCF_LASTDATANOTIFICATION) != 0
196*1230fdc1SLionel Sambuc && totalRead_ == dwSize)) {
197*1230fdc1SLionel Sambuc reportError(parser_);
198*1230fdc1SLionel Sambuc return E_ABORT;
199*1230fdc1SLionel Sambuc }
200*1230fdc1SLionel Sambuc }
201*1230fdc1SLionel Sambuc }
202*1230fdc1SLionel Sambuc }
203*1230fdc1SLionel Sambuc return S_OK;
204*1230fdc1SLionel Sambuc }
205*1230fdc1SLionel Sambuc
206*1230fdc1SLionel Sambuc STDMETHODIMP
OnObjectAvailable(REFIID,IUnknown *)207*1230fdc1SLionel Sambuc Callback::OnObjectAvailable(REFIID, IUnknown *)
208*1230fdc1SLionel Sambuc {
209*1230fdc1SLionel Sambuc return S_OK;
210*1230fdc1SLionel Sambuc }
211*1230fdc1SLionel Sambuc
212*1230fdc1SLionel Sambuc int
externalEntityRef(const XML_Char * context,const XML_Char * systemId,const XML_Char * publicId)213*1230fdc1SLionel Sambuc Callback::externalEntityRef(const XML_Char *context,
214*1230fdc1SLionel Sambuc const XML_Char *systemId,
215*1230fdc1SLionel Sambuc const XML_Char *publicId)
216*1230fdc1SLionel Sambuc {
217*1230fdc1SLionel Sambuc XML_Parser entParser = XML_ExternalEntityParserCreate(parser_, context, 0);
218*1230fdc1SLionel Sambuc XML_SetBase(entParser, systemId);
219*1230fdc1SLionel Sambuc int ret = processURL(entParser, baseMoniker_, systemId);
220*1230fdc1SLionel Sambuc XML_ParserFree(entParser);
221*1230fdc1SLionel Sambuc return ret;
222*1230fdc1SLionel Sambuc }
223*1230fdc1SLionel Sambuc
Callback(XML_Parser parser,IMoniker * baseMoniker,StopHandler stopHandler,void * stopArg)224*1230fdc1SLionel Sambuc Callback::Callback(XML_Parser parser, IMoniker *baseMoniker,
225*1230fdc1SLionel Sambuc StopHandler stopHandler, void *stopArg)
226*1230fdc1SLionel Sambuc : parser_(parser),
227*1230fdc1SLionel Sambuc baseMoniker_(baseMoniker),
228*1230fdc1SLionel Sambuc ref_(0),
229*1230fdc1SLionel Sambuc pBinding_(0),
230*1230fdc1SLionel Sambuc totalRead_(0),
231*1230fdc1SLionel Sambuc stopHandler_(stopHandler),
232*1230fdc1SLionel Sambuc stopArg_(stopArg)
233*1230fdc1SLionel Sambuc {
234*1230fdc1SLionel Sambuc if (baseMoniker_)
235*1230fdc1SLionel Sambuc baseMoniker_->AddRef();
236*1230fdc1SLionel Sambuc }
237*1230fdc1SLionel Sambuc
~Callback()238*1230fdc1SLionel Sambuc Callback::~Callback()
239*1230fdc1SLionel Sambuc {
240*1230fdc1SLionel Sambuc if (pBinding_)
241*1230fdc1SLionel Sambuc pBinding_->Release();
242*1230fdc1SLionel Sambuc if (baseMoniker_)
243*1230fdc1SLionel Sambuc baseMoniker_->Release();
244*1230fdc1SLionel Sambuc }
245*1230fdc1SLionel Sambuc
246*1230fdc1SLionel Sambuc static int
externalEntityRef(void * arg,const XML_Char * context,const XML_Char * base,const XML_Char * systemId,const XML_Char * publicId)247*1230fdc1SLionel Sambuc externalEntityRef(void *arg,
248*1230fdc1SLionel Sambuc const XML_Char *context,
249*1230fdc1SLionel Sambuc const XML_Char *base,
250*1230fdc1SLionel Sambuc const XML_Char *systemId,
251*1230fdc1SLionel Sambuc const XML_Char *publicId)
252*1230fdc1SLionel Sambuc {
253*1230fdc1SLionel Sambuc return ((Callback *)arg)->externalEntityRef(context, systemId, publicId);
254*1230fdc1SLionel Sambuc }
255*1230fdc1SLionel Sambuc
256*1230fdc1SLionel Sambuc
257*1230fdc1SLionel Sambuc static HRESULT
openStream(XML_Parser parser,IMoniker * baseMoniker,const XML_Char * uri,StopHandler stopHandler,void * stopArg)258*1230fdc1SLionel Sambuc openStream(XML_Parser parser,
259*1230fdc1SLionel Sambuc IMoniker *baseMoniker,
260*1230fdc1SLionel Sambuc const XML_Char *uri,
261*1230fdc1SLionel Sambuc StopHandler stopHandler, void *stopArg)
262*1230fdc1SLionel Sambuc {
263*1230fdc1SLionel Sambuc if (!XML_SetBase(parser, uri))
264*1230fdc1SLionel Sambuc return E_OUTOFMEMORY;
265*1230fdc1SLionel Sambuc HRESULT hr;
266*1230fdc1SLionel Sambuc IMoniker *m;
267*1230fdc1SLionel Sambuc #ifdef XML_UNICODE
268*1230fdc1SLionel Sambuc hr = CreateURLMoniker(0, uri, &m);
269*1230fdc1SLionel Sambuc #else
270*1230fdc1SLionel Sambuc LPWSTR uriw = new wchar_t[strlen(uri) + 1];
271*1230fdc1SLionel Sambuc for (int i = 0;; i++) {
272*1230fdc1SLionel Sambuc uriw[i] = uri[i];
273*1230fdc1SLionel Sambuc if (uriw[i] == 0)
274*1230fdc1SLionel Sambuc break;
275*1230fdc1SLionel Sambuc }
276*1230fdc1SLionel Sambuc hr = CreateURLMoniker(baseMoniker, uriw, &m);
277*1230fdc1SLionel Sambuc delete [] uriw;
278*1230fdc1SLionel Sambuc #endif
279*1230fdc1SLionel Sambuc if (FAILED(hr))
280*1230fdc1SLionel Sambuc return hr;
281*1230fdc1SLionel Sambuc IBindStatusCallback *cb = new Callback(parser, m, stopHandler, stopArg);
282*1230fdc1SLionel Sambuc XML_SetExternalEntityRefHandler(parser, externalEntityRef);
283*1230fdc1SLionel Sambuc XML_SetExternalEntityRefHandlerArg(parser, cb);
284*1230fdc1SLionel Sambuc cb->AddRef();
285*1230fdc1SLionel Sambuc IBindCtx *b;
286*1230fdc1SLionel Sambuc if (FAILED(hr = CreateAsyncBindCtx(0, cb, 0, &b))) {
287*1230fdc1SLionel Sambuc cb->Release();
288*1230fdc1SLionel Sambuc m->Release();
289*1230fdc1SLionel Sambuc return hr;
290*1230fdc1SLionel Sambuc }
291*1230fdc1SLionel Sambuc cb->Release();
292*1230fdc1SLionel Sambuc IStream *pStream;
293*1230fdc1SLionel Sambuc hr = m->BindToStorage(b, 0, IID_IStream, (void **)&pStream);
294*1230fdc1SLionel Sambuc if (SUCCEEDED(hr)) {
295*1230fdc1SLionel Sambuc if (pStream)
296*1230fdc1SLionel Sambuc pStream->Release();
297*1230fdc1SLionel Sambuc }
298*1230fdc1SLionel Sambuc if (hr == MK_S_ASYNCHRONOUS)
299*1230fdc1SLionel Sambuc hr = S_OK;
300*1230fdc1SLionel Sambuc m->Release();
301*1230fdc1SLionel Sambuc b->Release();
302*1230fdc1SLionel Sambuc return hr;
303*1230fdc1SLionel Sambuc }
304*1230fdc1SLionel Sambuc
305*1230fdc1SLionel Sambuc struct QuitInfo {
306*1230fdc1SLionel Sambuc const XML_Char *url;
307*1230fdc1SLionel Sambuc HRESULT hr;
308*1230fdc1SLionel Sambuc int stop;
309*1230fdc1SLionel Sambuc };
310*1230fdc1SLionel Sambuc
311*1230fdc1SLionel Sambuc static void
winPerror(const XML_Char * url,HRESULT hr)312*1230fdc1SLionel Sambuc winPerror(const XML_Char *url, HRESULT hr)
313*1230fdc1SLionel Sambuc {
314*1230fdc1SLionel Sambuc LPVOID buf;
315*1230fdc1SLionel Sambuc if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
316*1230fdc1SLionel Sambuc | FORMAT_MESSAGE_FROM_HMODULE,
317*1230fdc1SLionel Sambuc GetModuleHandleA("urlmon.dll"),
318*1230fdc1SLionel Sambuc hr,
319*1230fdc1SLionel Sambuc MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
320*1230fdc1SLionel Sambuc (LPTSTR) &buf,
321*1230fdc1SLionel Sambuc 0,
322*1230fdc1SLionel Sambuc NULL)
323*1230fdc1SLionel Sambuc || FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
324*1230fdc1SLionel Sambuc | FORMAT_MESSAGE_FROM_SYSTEM,
325*1230fdc1SLionel Sambuc 0,
326*1230fdc1SLionel Sambuc hr,
327*1230fdc1SLionel Sambuc MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
328*1230fdc1SLionel Sambuc (LPTSTR) &buf,
329*1230fdc1SLionel Sambuc 0,
330*1230fdc1SLionel Sambuc NULL)) {
331*1230fdc1SLionel Sambuc /* The system error messages seem to end with a newline. */
332*1230fdc1SLionel Sambuc _ftprintf(stderr, _T("%s: %s"), url, buf);
333*1230fdc1SLionel Sambuc fflush(stderr);
334*1230fdc1SLionel Sambuc LocalFree(buf);
335*1230fdc1SLionel Sambuc }
336*1230fdc1SLionel Sambuc else
337*1230fdc1SLionel Sambuc _ftprintf(stderr, _T("%s: error %x\n"), url, hr);
338*1230fdc1SLionel Sambuc }
339*1230fdc1SLionel Sambuc
340*1230fdc1SLionel Sambuc static void
threadQuit(void * p,HRESULT hr)341*1230fdc1SLionel Sambuc threadQuit(void *p, HRESULT hr)
342*1230fdc1SLionel Sambuc {
343*1230fdc1SLionel Sambuc QuitInfo *qi = (QuitInfo *)p;
344*1230fdc1SLionel Sambuc qi->hr = hr;
345*1230fdc1SLionel Sambuc qi->stop = 1;
346*1230fdc1SLionel Sambuc }
347*1230fdc1SLionel Sambuc
348*1230fdc1SLionel Sambuc extern "C"
349*1230fdc1SLionel Sambuc int
XML_URLInit(void)350*1230fdc1SLionel Sambuc XML_URLInit(void)
351*1230fdc1SLionel Sambuc {
352*1230fdc1SLionel Sambuc return SUCCEEDED(CoInitialize(0));
353*1230fdc1SLionel Sambuc }
354*1230fdc1SLionel Sambuc
355*1230fdc1SLionel Sambuc extern "C"
356*1230fdc1SLionel Sambuc void
XML_URLUninit(void)357*1230fdc1SLionel Sambuc XML_URLUninit(void)
358*1230fdc1SLionel Sambuc {
359*1230fdc1SLionel Sambuc CoUninitialize();
360*1230fdc1SLionel Sambuc }
361*1230fdc1SLionel Sambuc
362*1230fdc1SLionel Sambuc static int
processURL(XML_Parser parser,IMoniker * baseMoniker,const XML_Char * url)363*1230fdc1SLionel Sambuc processURL(XML_Parser parser, IMoniker *baseMoniker,
364*1230fdc1SLionel Sambuc const XML_Char *url)
365*1230fdc1SLionel Sambuc {
366*1230fdc1SLionel Sambuc QuitInfo qi;
367*1230fdc1SLionel Sambuc qi.stop = 0;
368*1230fdc1SLionel Sambuc qi.url = url;
369*1230fdc1SLionel Sambuc
370*1230fdc1SLionel Sambuc XML_SetBase(parser, url);
371*1230fdc1SLionel Sambuc HRESULT hr = openStream(parser, baseMoniker, url, threadQuit, &qi);
372*1230fdc1SLionel Sambuc if (FAILED(hr)) {
373*1230fdc1SLionel Sambuc winPerror(url, hr);
374*1230fdc1SLionel Sambuc return 0;
375*1230fdc1SLionel Sambuc }
376*1230fdc1SLionel Sambuc else if (FAILED(qi.hr)) {
377*1230fdc1SLionel Sambuc winPerror(url, qi.hr);
378*1230fdc1SLionel Sambuc return 0;
379*1230fdc1SLionel Sambuc }
380*1230fdc1SLionel Sambuc MSG msg;
381*1230fdc1SLionel Sambuc while (!qi.stop && GetMessage (&msg, NULL, 0, 0)) {
382*1230fdc1SLionel Sambuc TranslateMessage (&msg);
383*1230fdc1SLionel Sambuc DispatchMessage (&msg);
384*1230fdc1SLionel Sambuc }
385*1230fdc1SLionel Sambuc return 1;
386*1230fdc1SLionel Sambuc }
387*1230fdc1SLionel Sambuc
388*1230fdc1SLionel Sambuc extern "C"
389*1230fdc1SLionel Sambuc int
XML_ProcessURL(XML_Parser parser,const XML_Char * url,unsigned flags)390*1230fdc1SLionel Sambuc XML_ProcessURL(XML_Parser parser,
391*1230fdc1SLionel Sambuc const XML_Char *url,
392*1230fdc1SLionel Sambuc unsigned flags)
393*1230fdc1SLionel Sambuc {
394*1230fdc1SLionel Sambuc return processURL(parser, 0, url);
395*1230fdc1SLionel Sambuc }
396