1
#include "StdAfx.h"
2
#include "HttpDown.h"
3
4
5
//*****************************************************************************
6
CBSCallbackImpl::CBSCallbackImpl(HWND hWnd, HANDLE hEventStop)
7

{
8
m_hWnd = hWnd; // the window handle to display status
9
10
m_hEventStop = hEventStop; // the event object to signal to stop
11
12
m_ulObjRefCount = 1;
13
}
14
15
// IUnknown
16
STDMETHODIMP CBSCallbackImpl::QueryInterface(REFIID riid, void **ppvObject)
17

{
18
TRACE(_T("IUnknown::QueryInterface\n"));
19
20
*ppvObject = NULL;
21
22
// IUnknown
23
if (::IsEqualIID(riid, __uuidof(IUnknown)))
24
{
25
TRACE(_T("IUnknown::QueryInterface(IUnknown)\n"));
26
27
*ppvObject = this;
28
}
29
// IBindStatusCallback
30
else if (::IsEqualIID(riid, __uuidof(IBindStatusCallback)))
31
{
32
TRACE(_T("IUnknown::QueryInterface(IBindStatusCallback)\n"));
33
34
*ppvObject = static_cast<IBindStatusCallback *>(this);
35
}
36
37
if (*ppvObject)
38
{
39
(*reinterpret_cast<LPUNKNOWN *>(ppvObject))->AddRef();
40
41
return S_OK;
42
}
43
44
return E_NOINTERFACE;
45
}
46
47
STDMETHODIMP_(ULONG) CBSCallbackImpl::AddRef()
48

{
49
return ++m_ulObjRefCount;
50
}
51
52
STDMETHODIMP_(ULONG) CBSCallbackImpl::Release()
53

{
54
return --m_ulObjRefCount;
55
}
56
57
// IBindStatusCallback
58
STDMETHODIMP CBSCallbackImpl::OnStartBinding(DWORD, IBinding *)
59

{
60
return S_OK;
61
}
62
STDMETHODIMP CBSCallbackImpl::GetPriority(LONG *)
63

{
64
return E_NOTIMPL;
65
}
66
STDMETHODIMP CBSCallbackImpl::OnLowResource(DWORD)
67

{
68
return S_OK;
69
}
70
STDMETHODIMP CBSCallbackImpl::OnStopBinding(HRESULT, LPCWSTR)
71

{
72
return S_OK;
73
}
74
STDMETHODIMP CBSCallbackImpl::GetBindInfo(DWORD *, BINDINFO *)
75

{
76
return S_OK;
77
}
78
STDMETHODIMP CBSCallbackImpl::OnDataAvailable(DWORD, DWORD,
79
FORMATETC *, STGMEDIUM *)
80

{
81
return S_OK;
82
}
83
STDMETHODIMP CBSCallbackImpl::OnObjectAvailable(REFIID, IUnknown *)
84

{
85
return S_OK;
86
}
87
88
89
//-----------------------------------------------------------------------------
90
STDMETHODIMP CBSCallbackImpl::OnProgress(ULONG ulProgress,
91
ULONG ulProgressMax,
92
ULONG ulStatusCode,
93
LPCWSTR szStatusText)
94

{
95
#ifdef _DEBUG
96
static const LPCTSTR plpszStatus[] =
97
{
98
_T("BINDSTATUS_FINDINGRESOURCE"), // 1
99
_T("BINDSTATUS_CONNECTING"),
100
_T("BINDSTATUS_REDIRECTING"),
101
_T("BINDSTATUS_BEGINDOWNLOADDATA"),
102
_T("BINDSTATUS_DOWNLOADINGDATA"),
103
_T("BINDSTATUS_ENDDOWNLOADDATA"),
104
_T("BINDSTATUS_BEGINDOWNLOADCOMPONENTS"),
105
_T("BINDSTATUS_INSTALLINGCOMPONENTS"),
106
_T("BINDSTATUS_ENDDOWNLOADCOMPONENTS"),
107
_T("BINDSTATUS_USINGCACHEDCOPY"),
108
_T("BINDSTATUS_SENDINGREQUEST"),
109
_T("BINDSTATUS_CLASSIDAVAILABLE"),
110
_T("BINDSTATUS_MIMETYPEAVAILABLE"),
111
_T("BINDSTATUS_CACHEFILENAMEAVAILABLE"),
112
_T("BINDSTATUS_BEGINSYNCOPERATION"),
113
_T("BINDSTATUS_ENDSYNCOPERATION"),
114
_T("BINDSTATUS_BEGINUPLOADDATA"),
115
_T("BINDSTATUS_UPLOADINGDATA"),
116
_T("BINDSTATUS_ENDUPLOADINGDATA"),
117
_T("BINDSTATUS_PROTOCOLCLASSID"),
118
_T("BINDSTATUS_ENCODING"),
119
_T("BINDSTATUS_VERFIEDMIMETYPEAVAILABLE"),
120
_T("BINDSTATUS_CLASSINSTALLLOCATION"),
121
_T("BINDSTATUS_DECODING"),
122
_T("BINDSTATUS_LOADINGMIMEHANDLER"),
123
_T("BINDSTATUS_CONTENTDISPOSITIONATTACH"),
124
_T("BINDSTATUS_FILTERREPORTMIMETYPE"),
125
_T("BINDSTATUS_CLSIDCANINSTANTIATE"),
126
_T("BINDSTATUS_IUNKNOWNAVAILABLE"),
127
_T("BINDSTATUS_DIRECTBIND"),
128
_T("BINDSTATUS_RAWMIMETYPE"),
129
_T("BINDSTATUS_PROXYDETECTING"),
130
_T("BINDSTATUS_ACCEPTRANGES"),
131
_T("???") // unknown
132
};
133
#endif
134
135
TRACE(_T("IBindStatusCallback::OnProgress\n"));
136
TRACE(_T("ulProgress: %lu, ulProgressMax: %lu\n"), ulProgress, ulProgressMax);
137
TRACE(_T("ulStatusCode: %lu "), ulStatusCode);
138
139
if (ulStatusCode < UF_BINDSTATUS_FIRST ||
140
ulStatusCode > UF_BINDSTATUS_LAST)
141
{
142
ulStatusCode = UF_BINDSTATUS_LAST + 1;
143
}
144
145
#ifdef _DEBUG
146
TRACE(_T("(%s), szStatusText: %ls\n"),
147
plpszStatus[ulStatusCode - UF_BINDSTATUS_FIRST],
148
szStatusText);
149
#endif
150
151
152
if (m_hWnd != NULL)
153
{
154
DOWNLOADSTATUS downloadStatus =
155
{ ulProgress, ulProgressMax, ulStatusCode, szStatusText };
156
::SendMessage(m_hWnd, WM_USER_DISPLAYSTATUS,
157
0, reinterpret_cast<LPARAM>(&downloadStatus));
158
}
159
160
if (m_hEventStop != NULL)
161
{
162
if (::WaitForSingleObject(m_hEventStop, 0) == WAIT_OBJECT_0)
163
{
164
165
TRACE(_T("Download to give up\n"));
166
167
::SendMessage(m_hWnd, WM_USER_CANCELDOWNLOAD, 0, 0);
168
return E_ABORT; // canceled by the user
169
}
170
}
171
172
return S_OK;
173
}
174
//*****************************************************************************
175
176
CHttpDown::CHttpDown(void)
177

{
178
m_hThread = NULL;
179
m_hEventStop = CreateEvent(NULL,TRUE, FALSE, NULL);
180
181
ASSERT(NULL != m_hEventStop);
182
}
183
184
CHttpDown::~CHttpDown(void)
185

{
186
EndDownLoad();
187
CloseHandle(m_hEventStop);
188
}
189
190
UINT CHttpDown::Download(LPVOID pParam)
191

{
192
CHttpDown *const pThis = static_cast<CHttpDown *>(pParam);
193
CString strURL, strFileName, strFilePath;
194
TCHAR lpCurrentPath[MAX_PATH];
195
::GetCurrentDirectory(MAX_PATH, lpCurrentPath);
196
197
if (pThis->m_DownList.size() <= 0)
198
return 0;
199
200
/**//*
201
URLDownloadToCacheFile is a blocking function. Even though the data is
202
downloaded asynchronously the function does not return until all the
203
data is downloaded
204
*/
205
206
CBSCallbackImpl bsc(pThis->m_hWnd, pThis->m_hEventStop);
207
208
std::map<CString, CString>::iterator iterIdx = pThis->m_DownList.begin();
209
210
while(iterIdx != pThis->m_DownList.end() && WaitForSingleObject(pThis->m_hEventStop, 0) == WAIT_TIMEOUT)
211
{
212
strURL = iterIdx->second;
213
strFilePath.Format(_T("%s\\%s"), lpCurrentPath, iterIdx->first);
214
215
const HRESULT hr = ::URLDownloadToCacheFile(NULL,
216
strURL,
217
strFileName.GetBuffer(MAX_PATH),
218
URLOSTRM_GETNEWESTVERSION,
219
0,
220
&bsc);
221
222
// empty the filename string if failed or canceled
223
if (!SUCCEEDED(hr))
224
{
225
strFileName.ReleaseBuffer(-1);
226
pThis->m_DownList.clear();
227
//如果下載失敗或是取消下載就關(guān)閉窗口
228
//::PostMessage(pThis->m_hWnd, WM_CLOSE, 0, 0);
229
230
return 0;
231
}
232
else
233
{
234
::CopyFile(strFileName, strFilePath, FALSE);
235
}
236
237
iterIdx++;
238
}
239
240
pThis->m_DownList.clear();
241
::PostMessage(pThis->m_hWnd, WM_USER_ENDDOWNLOAD, 0, 0);
242
243
return 0;
244
}
245
246
BOOL CHttpDown::AddFile(CString strURL, CString strPath)
247

{
248
if (strcmp(strURL, _T("")) == 0 || strcmp(strPath, _T("")) == 0)
249
return FALSE;
250
251
m_DownList[strPath] = strURL;
252
return TRUE;
253
}
254
255
void CHttpDown::DelFile(CString strPath)
256

{
257
if (strcmp(strPath, _T("")) == 0)
258
return;
259
260
std::map<CString, CString>::iterator iterIdx = m_DownList.find(strPath);
261
262
if (iterIdx != m_DownList.end())
263
m_DownList.erase(iterIdx);
264
}
265
266
BOOL CHttpDown::BeginDownLoad()
267

{
268
EndDownLoad();
269
ResetEvent(m_hEventStop);
270
271
DWORD ThreadID;
272
m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Download, this, 0, &ThreadID);
273
274
if (m_hThread == INVALID_HANDLE_VALUE)
275
{
276
return FALSE;
277
}
278
279
return TRUE;
280
}
281
282
void CHttpDown::EndDownLoad()
283

{
284
if (m_hThread == NULL)
285
return;
286
287
DWORD dwResult;
288
GetExitCodeThread(m_hThread, &dwResult);
289
290
if (dwResult == 259)
291
{
292
SetEvent(m_hEventStop);
293
::WaitForSingleObject(m_hThread, INFINITE);
294
CloseHandle(m_hThread);
295
m_hThread = NULL;
296
}
297
298
CloseHandle(m_hThread);
299
m_hThread = NULL;
300
}
301
302
//進(jìn)度消息處理示例
303
/**//*
304
LRESULT OnDisplayStatus(WPARAM wParam, LPARAM lParam)
305
{
306
const DOWNLOADSTATUS *const pDownloadStatus =
307
reinterpret_cast<DOWNLOADSTATUS *>(lParam);
308
309
// form the status text
310
CString strStatus;
311
312
if (pDownloadStatus != NULL)
313
{
314
315
VERIFY(strStatus.LoadString(pDownloadStatus->ulStatusCode -
316
UF_BINDSTATUS_FIRST +
317
_T("Finding resource
")));
318
strStatus += _T(" ");
319
strStatus += pDownloadStatus->szStatusText;
320
321
CString strProgress;
322
strProgress.Format(_T(" %lu of %lu"),
323
pDownloadStatus->ulProgress,
324
pDownloadStatus->ulProgressMax);
325
326
strStatus += strProgress + _T("\r\n");
327
}
328
329
return 0;
330
}*/

2

3

4

5

6

7



8

9

10

11

12

13

14

15

16

17



18

19

20

21

22

23

24



25

26

27

28

29

30

31



32

33

34

35

36

37

38



39

40

41

42

43

44

45

46

47

48



49

50

51

52

53



54

55

56

57

58

59



60

61

62

63



64

65

66

67



68

69

70

71



72

73

74

75



76

77

78

79

80



81

82

83

84



85

86

87

88

89

90

91

92

93

94



95

96

97



98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141



142

143

144

145

146

147

148

149

150

151

152

153



154

155



156

157

158

159

160

161



162

163



164

165

166

167

168

169

170

171

172

173

174

175

176

177



178

179

180

181

182

183

184

185



186

187

188

189

190

191



192

193

194

195

196

197

198

199

200


201

202

203

204

205

206

207

208

209

210

211



212

213

214

215

216

217

218

219

220

221

222

223

224



225

226

227

228

229

230

231

232

233



234

235

236

237

238

239

240

241

242

243

244

245

246

247



248

249

250

251

252

253

254

255

256



257

258

259

260

261

262

263

264

265

266

267



268

269

270

271

272

273

274

275



276

277

278

279

280

281

282

283



284

285

286

287

288

289

290

291



292

293

294

295

296

297

298

299

300

301

302

303


304

305

306

307

308

309

310

311

312

313

314

315

316

317


318

319

320

321

322

323

324

325

326

327

328

329

330

1
#pragma once
2
#include <map>
3
4
//The message of status update
5
#define WM_USER_DISPLAYSTATUS WM_USER + 1001
6
#define WM_USER_ENDDOWNLOAD WM_USER + 1002
7
#define WM_USER_CANCELDOWNLOAD WM_USER + 1003
8
9
enum
10

{
11
UF_BINDSTATUS_FIRST = BINDSTATUS_FINDINGRESOURCE,
12
UF_BINDSTATUS_LAST = BINDSTATUS_ACCEPTRANGES
13
};
14
15
16
//The status of Download
17
struct DOWNLOADSTATUS
18

{
19
ULONG ulProgress;
20
ULONG ulProgressMax;
21
ULONG ulStatusCode;
22
LPCWSTR szStatusText;
23
};
24
25
class CBSCallbackImpl : public IBindStatusCallback
26

{
27
public:
28
CBSCallbackImpl(HWND hWnd, HANDLE hEventStop);
29
30
// IUnknown methods
31
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject);
32
STDMETHOD_(ULONG, AddRef)();
33
STDMETHOD_(ULONG, Release)();
34
35
STDMETHOD(OnProgress)(ULONG ulProgress, ULONG ulProgressMax,
36
ULONG ulStatusCode,
37
LPCWSTR szStatusText);
38
39
// IBindStatusCallback methods
40
STDMETHOD(OnStartBinding)(DWORD, IBinding *);
41
STDMETHOD(GetPriority)(LONG *);
42
STDMETHOD(OnLowResource)(DWORD);
43
STDMETHOD(OnStopBinding)(HRESULT, LPCWSTR);
44
STDMETHOD(GetBindInfo)(DWORD *, BINDINFO *);
45
STDMETHOD(OnDataAvailable)(DWORD, DWORD, FORMATETC *, STGMEDIUM *);
46
STDMETHOD(OnObjectAvailable)(REFIID, IUnknown *);
47
48
protected:
49
ULONG m_ulObjRefCount;
50
51
private:
52
//Parent windows handle
53
HWND m_hWnd;
54
//The event of Stop
55
HANDLE m_hEventStop;
56
};
57
58
class CHttpDown
59

{
60
public:
61
CHttpDown(void);
62
virtual ~CHttpDown(void);
63
64
inline void SetParentWindow(HWND hwnd)
{m_hWnd = hwnd;}
65
66
BOOL BeginDownLoad();
67
void EndDownLoad();
68
69
BOOL AddFile(CString strURL, CString strPath);
70
void DelFile(CString strPath);
71
72
protected:
73
static UINT Download(LPVOID pParam);
74
75
private:
76
HWND m_hWnd;
77
HANDLE m_hEventStop;
78
HANDLE m_hThread;
79
80
std::map<CString, CString> m_DownList;
81
};
82
83
/**//*
84
資源聲明
85
#define IDS_BINDSTATUS01 106
86
#define IDS_BINDSTATUS02 107
87
#define IDS_BINDSTATUS03 108
88
#define IDS_BINDSTATUS04 109
89
#define IDS_BINDSTATUS05 110
90
#define IDS_BINDSTATUS06 111
91
#define IDS_BINDSTATUS07 112
92
#define IDS_BINDSTATUS08 113
93
#define IDS_BINDSTATUS09 114
94
#define IDS_BINDSTATUS10 115
95
#define IDS_BINDSTATUS11 116
96
#define IDS_BINDSTATUS12 117
97
#define IDS_BINDSTATUS13 118
98
#define IDS_BINDSTATUS14 119
99
#define IDS_BINDSTATUS15 120
100
#define IDS_BINDSTATUS16 121
101
#define IDS_BINDSTATUS17 122
102
#define IDS_BINDSTATUS18 123
103
#define IDS_BINDSTATUS19 124
104
#define IDS_BINDSTATUS20 125
105
#define IDS_BINDSTATUS21 126
106
#define IDS_BINDSTATUS22 127
107
#define IDS_BINDSTATUS23 128
108
#define IDS_BINDSTATUS24 129
109
#define IDS_BINDSTATUS25 130
110
#define IDS_BINDSTATUS26 131
111
#define IDS_BINDSTATUS27 132
112
#define IDS_BINDSTATUS28 133
113
#define IDS_BINDSTATUS29 134
114
#define IDS_BINDSTATUS30 135
115
#define IDS_BINDSTATUS31 136
116
#define IDS_BINDSTATUS32 137
117
#define IDS_BINDSTATUS33 138
118
#define IDS_BINDSTATUS34 139
119
IDS_BINDSTATUS01 "Finding resource
"
120
IDS_BINDSTATUS02 "Connecting
"
121
IDS_BINDSTATUS03 "Redirecting
"
122
IDS_BINDSTATUS04 "Begin download data"
123
IDS_BINDSTATUS05 "Downloading data
"
124
IDS_BINDSTATUS06 "End download data"
125
IDS_BINDSTATUS07 "Begin download components"
126
IDS_BINDSTATUS08 "Installing components
"
127
IDS_BINDSTATUS09 "End download components"
128
IDS_BINDSTATUS10 "Using cached copy
"
129
IDS_BINDSTATUS11 "Sending request
"
130
IDS_BINDSTATUS12 "Class ID available"
131
IDS_BINDSTATUS13 "MIME type available"
132
IDS_BINDSTATUS14 "Cache file name available"
133
IDS_BINDSTATUS15 "Begin synchronous operation"
134
IDS_BINDSTATUS16 "End synchronous operation"
135
IDS_BINDSTATUS17 "Begin upload data"
136
IDS_BINDSTATUS18 "Uploading data
"
137
IDS_BINDSTATUS19 "End upload data"
138
IDS_BINDSTATUS20 "Protocol class ID available"
139
IDS_BINDSTATUS21 "Encoding
"
140
IDS_BINDSTATUS22 "Verfied MIME type available"
141
IDS_BINDSTATUS23 "Class install location available"
142
IDS_BINDSTATUS24 "Decoding
"
143
IDS_BINDSTATUS25 "Loading MIME handler
"
144
IDS_BINDSTATUS26 "Content-Disposition attachment"
145
IDS_BINDSTATUS27 "MIME filter to report a change in MIME type"
146
IDS_BINDSTATUS28 "CLSID can instantiate"
147
IDS_BINDSTATUS29 "IUnknown released"
148
IDS_BINDSTATUS30 "Direct bind"
149
IDS_BINDSTATUS31 "Raw MIME type"
150
IDS_BINDSTATUS32 "Detecting proxy
"
151
IDS_BINDSTATUS33 "Accept ranges"
152
IDS_BINDSTATUS34 "???"
153
*/
154
155

2

3

4

5

6

7

8

9

10



11

12

13

14

15

16

17

18



19

20

21

22

23

24

25

26



27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59



60

61

62

63

64



65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83


84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119


120


121


122

123


124

125

126


127

128


129


130

131

132

133

134

135

136


137

138

139


140

141

142


143


144

145

146

147

148

149

150


151

152

153

154

155
