~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/toolkit/mozapps/installer/windows/wizard/setup/xpnetHook.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The contents of this file are subject to the Mozilla Public
 
3
 * License Version 1.1 (the "License"); you may not use this file
 
4
 * except in compliance with the License. You may obtain a copy of
 
5
 * the License at http://www.mozilla.org/MPL/
 
6
 * 
 
7
 * Software distributed under the License is distributed on an "AS
 
8
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
9
 * implied. See the License for the specific language governing
 
10
 * rights and limitations under the License.
 
11
 * 
 
12
 * The Original Code is Mozilla Navigator.
 
13
 * 
 
14
 * The Initial Developer of the Original Code is Netscape Communications
 
15
 * Corp.  Portions created by Netscape Communications Corp. are
 
16
 * Copyright (C) 1998, 1999, 2000, 2001 Netscape Communications Corp.  All
 
17
 * Rights Reserved.
 
18
 * 
 
19
 * Contributor(s): 
 
20
 *   Sean Su <ssu@netscape.com>
 
21
 */
 
22
 
 
23
#include <windows.h>
 
24
#include <string.h>
 
25
#include <time.h>
 
26
#include <sys/stat.h>
 
27
 
 
28
#ifdef __cplusplus
 
29
extern "C"
 
30
{
 
31
#endif /* __cplusplus */
 
32
 
 
33
#include "extern.h"
 
34
#include "extra.h"
 
35
#include "dialogs.h"
 
36
#include "xpnetHook.h"
 
37
 
 
38
#ifdef __cplusplus
 
39
}
 
40
#endif /* __cplusplus */
 
41
 
 
42
#include "nsFTPConn.h"
 
43
#include "nsHTTPConn.h"
 
44
#include "nsSocket.h"
 
45
 
 
46
#define UPDATE_INTERVAL_STATUS          1
 
47
#define UPDATE_INTERVAL_PROGRESS_BAR    1
 
48
 
 
49
/* Cancel Status */
 
50
#define CS_NONE         0x00000000
 
51
#define CS_CANCEL       0x00000001
 
52
#define CS_PAUSE        0x00000002
 
53
#define CS_RESUME       0x00000003
 
54
 
 
55
const int  kProxySrvrLen = 1024;
 
56
const char kHTTP[8]      = "http://";
 
57
const char kFTP[7]       = "ftp://";
 
58
const char kLoclFile[7]  = "zzzFTP";
 
59
const int  kModTimeOutValue = 3;
 
60
 
 
61
static nsHTTPConn       *connHTTP = NULL;
 
62
static nsFTPConn        *connFTP = NULL;
 
63
static long             glLastBytesSoFar;
 
64
static long             glAbsoluteBytesSoFar;
 
65
static long             glBytesResumedFrom;
 
66
static long             glTotalKb;
 
67
char                    gszStrCopyingFile[MAX_BUF_MEDIUM];
 
68
char                    gszCurrentDownloadPath[MAX_BUF];
 
69
char                    gszCurrentDownloadFilename[MAX_BUF_TINY];
 
70
char                    gszCurrentDownloadFileDescription[MAX_BUF_TINY];
 
71
char                    gszUrl[MAX_BUF];
 
72
char                    gszTo[MAX_BUF];
 
73
char                    gszFileInfo[MAX_BUF];
 
74
char                    *gszConfigIniFile;
 
75
BOOL                    gbDlgDownloadMinimized;
 
76
BOOL                    gbDlgDownloadJustMinimized;
 
77
BOOL                    gbUrlChanged;
 
78
BOOL                    gbShowDownloadRetryMsg;
 
79
DWORD                   gdwDownloadDialogStatus;
 
80
int                     giIndex;
 
81
int                     giTotalArchivesToDownload;
 
82
DWORD                   gdwTickStart;
 
83
BOOL                    gbStartTickCounter;
 
84
 
 
85
double GetPercentSoFar(void);
 
86
 
 
87
static void UpdateGaugeFileProgressBar(double value);
 
88
       int  ProgressCB(int aBytesSoFar, int aTotalFinalSize);
 
89
       void InitDownloadDlg(void);
 
90
       void DeInitDownloadDlg();
 
91
 
 
92
/* local prototypes */
 
93
siC *GetObjectFromArchiveName(char *szArchiveName);
 
94
 
 
95
struct DownloadFileInfo
 
96
{
 
97
  char szUrl[MAX_BUF];
 
98
  char szFile[MAX_BUF_TINY];
 
99
} dlFileInfo;
 
100
 
 
101
struct ExtractFilesDlgInfo
 
102
{
 
103
        HWND    hWndDlg;
 
104
        int             nMaxFileBars;       // maximum number of bars that can be displayed
 
105
        int             nMaxArchiveBars;        // maximum number of bars that can be displayed
 
106
        int   nFileBars;              // current number of bars to display
 
107
        int             nArchiveBars;             // current number of bars to display
 
108
} dlgInfo;
 
109
 
 
110
struct TickInfo
 
111
{
 
112
  DWORD dwTickBegin;
 
113
  DWORD dwTickEnd;
 
114
  DWORD dwTickDif;
 
115
  BOOL  bTickStarted;
 
116
  BOOL  bTickDownloadResumed;
 
117
} gtiPaused;
 
118
 
 
119
BOOL CheckInterval(long *lModLastValue, int iInterval)
 
120
{
 
121
  BOOL bRv = FALSE;
 
122
  long lModCurrentValue;
 
123
 
 
124
  if(iInterval == 1)
 
125
  {
 
126
    lModCurrentValue = time(NULL);
 
127
    if(lModCurrentValue != *lModLastValue)
 
128
      bRv = TRUE;
 
129
  }
 
130
  else
 
131
  {
 
132
    lModCurrentValue = time(NULL) % iInterval;
 
133
    if((lModCurrentValue == 0) && (*lModLastValue != 0))
 
134
      bRv = TRUE;
 
135
  }
 
136
 
 
137
  *lModLastValue = lModCurrentValue;
 
138
  return(bRv);
 
139
}
 
140
 
 
141
char *GetTimeLeft(DWORD dwTimeLeft,
 
142
                  char *szTimeString,
 
143
                  DWORD dwTimeStringBufSize)
 
144
{
 
145
  DWORD      dwTimeLeftPP;
 
146
  SYSTEMTIME stTime;
 
147
 
 
148
  ZeroMemory(&stTime, sizeof(stTime));
 
149
  dwTimeLeftPP         = dwTimeLeft + 1;
 
150
  stTime.wHour         = (unsigned)(dwTimeLeftPP / 60 / 60);
 
151
  stTime.wMinute       = (unsigned)((dwTimeLeftPP / 60) % 60);
 
152
  stTime.wSecond       = (unsigned)(dwTimeLeftPP % 60);
 
153
 
 
154
  ZeroMemory(szTimeString, dwTimeStringBufSize);
 
155
  /* format time string using user's local time format information */
 
156
  GetTimeFormat(LOCALE_USER_DEFAULT,
 
157
                TIME_NOTIMEMARKER|TIME_FORCE24HOURFORMAT,
 
158
                &stTime,
 
159
                NULL,
 
160
                szTimeString,
 
161
                dwTimeStringBufSize);
 
162
 
 
163
  return(szTimeString);
 
164
}
 
165
 
 
166
DWORD AddToTick(DWORD dwTick, DWORD dwTickMoreToAdd)
 
167
{
 
168
  DWORD dwTickLeftTillWrap = 0;
 
169
 
 
170
  /* Since GetTickCount() is the number of milliseconds since the system
 
171
   * has been on and the return value is a DWORD, this value will wrap
 
172
   * every 49.71 days or 0xFFFFFFFF milliseconds. */
 
173
  dwTickLeftTillWrap = 0xFFFFFFFF - dwTick;
 
174
  if(dwTickMoreToAdd > dwTickLeftTillWrap)
 
175
    dwTick = dwTickMoreToAdd - dwTickLeftTillWrap;
 
176
  else
 
177
    dwTick = dwTick + dwTickMoreToAdd;
 
178
 
 
179
  return(dwTick);
 
180
}
 
181
 
 
182
DWORD GetTickDif(DWORD dwTickEnd, DWORD dwTickStart)
 
183
{
 
184
  DWORD dwTickDif;
 
185
 
 
186
  /* Since GetTickCount() is the number of milliseconds since the system
 
187
   * has been on and the return value is a DWORD, this value will wrap
 
188
   * every 49.71 days or 0xFFFFFFFF milliseconds. 
 
189
   *
 
190
   * Assumption: dwTickEnd has not wrapped _and_ passed dwTickStart */
 
191
  if(dwTickEnd < dwTickStart)
 
192
    dwTickDif = 0xFFFFFFFF - dwTickStart + dwTickEnd;
 
193
  else
 
194
    dwTickDif = dwTickEnd - dwTickStart;
 
195
 
 
196
  return(dwTickDif);
 
197
}
 
198
 
 
199
void InitTickInfo(void)
 
200
{
 
201
  gtiPaused.dwTickBegin          = 0;
 
202
  gtiPaused.dwTickEnd            = 0;
 
203
  gtiPaused.dwTickDif            = 0;
 
204
  gtiPaused.bTickStarted         = FALSE;
 
205
  gtiPaused.bTickDownloadResumed = FALSE;
 
206
}
 
207
 
 
208
DWORD RoundDouble(double dValue)
 
209
{
 
210
  if(0.5 <= (dValue - (DWORD)dValue))
 
211
    return((DWORD)dValue + 1);
 
212
  else
 
213
    return((DWORD)dValue);
 
214
}
 
215
 
 
216
void SetStatusStatus(void)
 
217
{
 
218
  char        szStatusStatusLine[MAX_BUF_MEDIUM];
 
219
  char        szCurrentStatusInfo[MAX_BUF_MEDIUM];
 
220
  char        szPercentString[MAX_BUF_MEDIUM];
 
221
  char        szPercentageCompleted[MAX_BUF_MEDIUM];
 
222
  static long lModLastValue = 0;
 
223
  double        dRate;
 
224
  static double dRateCounter;
 
225
  DWORD         dwTickNow;
 
226
  DWORD         dwTickDif;
 
227
  DWORD         dwKBytesSoFar;
 
228
  DWORD         dwRoundedRate;
 
229
  char          szTimeLeft[MAX_BUF_TINY];
 
230
 
 
231
  /* If the user just clicked on the Resume button, then the time lapsed
 
232
   * between gdwTickStart and when the Resume button was clicked needs to
 
233
   * be subtracted taken into account when calculating dwTickDif.  So
 
234
   * "this" lapsed time needs to be added to gdwTickStart. */
 
235
  if(gtiPaused.bTickDownloadResumed)
 
236
  {
 
237
    gdwTickStart = AddToTick(gdwTickStart, gtiPaused.dwTickDif);
 
238
    InitTickInfo();
 
239
  }
 
240
 
 
241
  /* GetTickCount() returns time in milliseconds.  This is more accurate,
 
242
   * which will allow us to get at a 2 decimal precision value for the
 
243
   * download rate. */
 
244
  dwTickNow = GetTickCount();
 
245
  if((gdwTickStart == 0) && gbStartTickCounter)
 
246
    dwTickNow = gdwTickStart = GetTickCount();
 
247
 
 
248
  dwTickDif = GetTickDif(dwTickNow, gdwTickStart);
 
249
 
 
250
  /* Only update the UI every UPDATE_INTERVAL_STATUS interval,
 
251
   * which is currently set to 1 sec. */
 
252
  if(!CheckInterval(&lModLastValue, UPDATE_INTERVAL_STATUS))
 
253
    return;
 
254
 
 
255
  if(glAbsoluteBytesSoFar == 0)
 
256
    dRateCounter = 0.0;
 
257
  else
 
258
    dRateCounter = dwTickDif / 1000;
 
259
 
 
260
  if(dRateCounter == 0.0)
 
261
    dRate = 0.0;
 
262
  else
 
263
    dRate = (glAbsoluteBytesSoFar - glBytesResumedFrom) / dRateCounter / 1024;
 
264
 
 
265
  dwKBytesSoFar = glAbsoluteBytesSoFar / 1024;
 
266
 
 
267
  /* Use a rate that is rounded to the nearest integer.  If dRate used directly,
 
268
   * the "Time Left" will jump around quite a bit due to the rate usually 
 
269
   * varying up and down by quite a bit. The rounded rate give a "more linear"
 
270
   * count down of the "Time Left". */
 
271
  dwRoundedRate = RoundDouble(dRate);
 
272
  if(dwRoundedRate > 0)
 
273
    GetTimeLeft((glTotalKb - dwKBytesSoFar) / dwRoundedRate,
 
274
                 szTimeLeft,
 
275
                 sizeof(szTimeLeft));
 
276
  else
 
277
    lstrcpy(szTimeLeft, "00:00:00");
 
278
 
 
279
  if(!gbShowDownloadRetryMsg)
 
280
  {
 
281
    GetPrivateProfileString("Strings",
 
282
                            "Status Download",
 
283
                            "",
 
284
                            szStatusStatusLine,
 
285
                            sizeof(szStatusStatusLine),
 
286
                            szFileIniConfig);
 
287
    if(*szStatusStatusLine != '\0')
 
288
      sprintf(szCurrentStatusInfo,
 
289
              szStatusStatusLine,
 
290
              szTimeLeft,
 
291
              dRate,
 
292
              dwKBytesSoFar,
 
293
              glTotalKb);
 
294
    else
 
295
      sprintf(szCurrentStatusInfo,
 
296
              "%s at %.2fKB/sec (%uKB of %uKB downloaded)",
 
297
              szTimeLeft,
 
298
              dRate,
 
299
              dwKBytesSoFar,
 
300
              glTotalKb);
 
301
  }
 
302
  else
 
303
  {
 
304
    GetPrivateProfileString("Strings",
 
305
                            "Status Retry",
 
306
                            "",
 
307
                            szStatusStatusLine,
 
308
                            sizeof(szStatusStatusLine),
 
309
                            szFileIniConfig);
 
310
    if(*szStatusStatusLine != '\0')
 
311
      sprintf(szCurrentStatusInfo,
 
312
              szStatusStatusLine,
 
313
              szTimeLeft,
 
314
              dRate,
 
315
              dwKBytesSoFar,
 
316
              glTotalKb);
 
317
    else
 
318
      sprintf(szCurrentStatusInfo,
 
319
              "%s at %.2KB/sec (%uKB of %uKB downloaded)",
 
320
              szTimeLeft,
 
321
              dRate,
 
322
              dwKBytesSoFar,
 
323
              glTotalKb);
 
324
  }
 
325
 
 
326
  GetPrivateProfileString("Strings",
 
327
                          "Status Percentage Completed",
 
328
                          "",
 
329
                          szPercentageCompleted,
 
330
                          sizeof(szPercentageCompleted),
 
331
                          szFileIniConfig);
 
332
  wsprintf(szPercentString, szPercentageCompleted, (int)GetPercentSoFar());
 
333
 
 
334
  /* Set the download dialog title */
 
335
  SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS_STATUS, szCurrentStatusInfo);
 
336
  SetDlgItemText(dlgInfo.hWndDlg, IDC_PERCENTAGE, szPercentString);
 
337
}
 
338
 
 
339
void SetStatusFile(void)
 
340
{
 
341
  char szString[MAX_BUF];
 
342
 
 
343
  /* Set the download dialog status*/
 
344
  wsprintf(szString, gszFileInfo, gszCurrentDownloadFileDescription);
 
345
  SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS_FILE, szString);
 
346
  SetStatusStatus();
 
347
}
 
348
 
 
349
void SetStatusUrl(void)
 
350
{
 
351
  /* display the current url being processed */
 
352
  if(gbUrlChanged)
 
353
  {
 
354
    char szUrlPathBuf[MAX_BUF];
 
355
    char szToPathBuf[MAX_BUF];
 
356
    HWND hStatusUrl = NULL;
 
357
    HWND hStatusTo  = NULL;
 
358
 
 
359
    hStatusUrl = GetDlgItem(dlgInfo.hWndDlg, IDC_STATUS_URL);
 
360
    if(hStatusUrl)
 
361
      TruncateString(hStatusUrl, gszUrl, szUrlPathBuf, sizeof(szUrlPathBuf));
 
362
    else
 
363
      lstrcpy(szUrlPathBuf, gszUrl);
 
364
 
 
365
    hStatusTo = GetDlgItem(dlgInfo.hWndDlg, IDC_STATUS_TO);
 
366
    if(hStatusTo)
 
367
      TruncateString(hStatusTo, gszTo, szToPathBuf, sizeof(szToPathBuf));
 
368
    else
 
369
      lstrcpy(szToPathBuf, gszTo);
 
370
 
 
371
    SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS_URL, szUrlPathBuf);
 
372
    SetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS_TO,  szToPathBuf);
 
373
    SetStatusFile();
 
374
    gbUrlChanged = FALSE;
 
375
  }
 
376
}
 
377
 
 
378
double GetPercentSoFar(void)
 
379
{
 
380
  return((double)(((double)(glAbsoluteBytesSoFar / 1024) / (double)glTotalKb) * (double)100));
 
381
}
 
382
 
 
383
void SetMinimizedDownloadTitle(DWORD dwPercentSoFar)
 
384
{
 
385
  static DWORD dwLastPercentSoFar = 0;
 
386
  char szDownloadTitle[MAX_BUF_MEDIUM];
 
387
  char gszCurrentDownloadInfo[MAX_BUF_MEDIUM];
 
388
 
 
389
  GetPrivateProfileString("Strings", "Dialog Download Title Minimized", "", szDownloadTitle, sizeof(szDownloadTitle), szFileIniConfig);
 
390
 
 
391
  if(*szDownloadTitle != '\0')
 
392
    wsprintf(gszCurrentDownloadInfo, szDownloadTitle, dwPercentSoFar, gszCurrentDownloadFilename);
 
393
  else
 
394
    wsprintf(gszCurrentDownloadInfo, "%d%% for all files", dwPercentSoFar);
 
395
 
 
396
  /* check and save the current percent so far to minimize flickering */
 
397
  if((dwLastPercentSoFar != dwPercentSoFar) || gbDlgDownloadJustMinimized)
 
398
  {
 
399
    /* When the dialog is has just been minimized, the title is not set
 
400
     * until the percentage changes, which when downloading via modem,
 
401
     * could take several seconds.  This variable allows us to tell when
 
402
     * the dialog had *just* been minimized regardless if the percentage
 
403
     * had changed or not. */
 
404
    gbDlgDownloadJustMinimized = FALSE;
 
405
 
 
406
    /* Set the download dialog title */
 
407
    SetWindowText(dlgInfo.hWndDlg, gszCurrentDownloadInfo);
 
408
    dwLastPercentSoFar = dwPercentSoFar;
 
409
  }
 
410
}
 
411
 
 
412
void SetRestoredDownloadTitle(void)
 
413
{
 
414
  /* Set the download dialog title */
 
415
  SetWindowText(dlgInfo.hWndDlg, diDownload.szTitle);
 
416
}
 
417
 
 
418
void GetTotalArchivesToDownload(int *iTotalArchivesToDownload, DWORD *dwTotalEstDownloadSize)
 
419
{
 
420
  int  iIndex = 0;
 
421
  char szUrl[MAX_BUF];
 
422
  char szSection[MAX_INI_SK];
 
423
  char szDownloadSize[MAX_ITOA];
 
424
 
 
425
  *dwTotalEstDownloadSize = 0;
 
426
  iIndex = 0;
 
427
  wsprintf(szSection, "File%d", iIndex);
 
428
  GetPrivateProfileString(szSection,
 
429
                          "url0",
 
430
                          "",
 
431
                          szUrl,
 
432
                          sizeof(szUrl),
 
433
                          gszConfigIniFile);
 
434
  while(*szUrl != '\0')
 
435
  {
 
436
    GetPrivateProfileString(szSection, "size", "", szDownloadSize, sizeof(szDownloadSize), gszConfigIniFile);
 
437
    if((lstrlen(szDownloadSize) < 32) && (*szDownloadSize != '\0'))
 
438
      /* size will be in kb.  31 bits (int minus the signed bit) of precision should sufice */
 
439
      *dwTotalEstDownloadSize += atoi(szDownloadSize);
 
440
 
 
441
    ++iIndex;
 
442
    wsprintf(szSection, "File%d", iIndex);
 
443
    GetPrivateProfileString(szSection,
 
444
                            "url0",
 
445
                            "",
 
446
                            szUrl,
 
447
                            sizeof(szUrl),
 
448
                            gszConfigIniFile);
 
449
  }
 
450
  *iTotalArchivesToDownload = iIndex;
 
451
}
 
452
 
 
453
/* 
 
454
 * Name: ProcessWndMsgCB
 
455
 *
 
456
 * Arguments: None
 
457
 *
 
458
 * Description: Callback function invoked by socket code and by FTP and HTTP layers
 
459
 *                              to give the UI a chance to breath while we are in a look processing
 
460
 *                              incoming data, or looping in select()
 
461
 *
 
462
 * Author: syd@netscape.com 5/11/2001
 
463
 *
 
464
*/
 
465
 
 
466
int
 
467
ProcessWndMsgCB()
 
468
{
 
469
  int iRv = nsFTPConn::OK;
 
470
 
 
471
        ProcessWindowsMessages();
 
472
  if((gdwDownloadDialogStatus == CS_CANCEL) ||
 
473
     (gdwDownloadDialogStatus == CS_PAUSE))
 
474
    iRv = nsFTPConn::E_USER_CANCEL;
 
475
 
 
476
        return(iRv);
 
477
}
 
478
 
 
479
/* Function used only to send the message stream error */
 
480
int WGet(char *szUrl,
 
481
         char *szFile,
 
482
         char *szProxyServer,
 
483
         char *szProxyPort,
 
484
         char *szProxyUser,
 
485
         char *szProxyPasswd)
 
486
{
 
487
  int        rv;
 
488
  char       proxyURL[MAX_BUF];
 
489
  nsHTTPConn *conn = NULL;
 
490
 
 
491
  if((szProxyServer != NULL) && (szProxyPort != NULL) &&
 
492
     (*szProxyServer != '\0') && (*szProxyPort != '\0'))
 
493
  {
 
494
    /* detected proxy information, let's use it */
 
495
    memset(proxyURL, 0, sizeof(proxyURL));
 
496
    wsprintf(proxyURL, "http://%s:%s", szProxyServer, szProxyPort);
 
497
 
 
498
    conn = new nsHTTPConn(proxyURL);
 
499
    if(conn == NULL)
 
500
      return(WIZ_OUT_OF_MEMORY);
 
501
 
 
502
    if((szProxyUser != NULL) && (*szProxyUser != '\0') &&
 
503
       (szProxyPasswd != NULL) && (*szProxyPasswd != '\0'))
 
504
      /* detected user and password info */
 
505
      conn->SetProxyInfo(szUrl, szProxyUser, szProxyPasswd);
 
506
    else
 
507
      conn->SetProxyInfo(szUrl, NULL, NULL);
 
508
  }
 
509
  else
 
510
  {
 
511
    /* no proxy information supplied. set up normal http object */
 
512
    conn = new nsHTTPConn(szUrl, ProcessWndMsgCB);
 
513
    if(conn == NULL)
 
514
      return(WIZ_OUT_OF_MEMORY);
 
515
  }
 
516
  
 
517
  rv = conn->Open();
 
518
  if(rv == WIZ_OK)
 
519
  {
 
520
    rv = conn->Get(NULL, szFile);
 
521
    conn->Close();
 
522
  }
 
523
 
 
524
  if(conn)
 
525
    delete(conn);
 
526
 
 
527
  return(rv);
 
528
}
 
529
 
 
530
int DownloadViaProxyOpen(char *szUrl, char *szProxyServer, char *szProxyPort, char *szProxyUser, char *szProxyPasswd)
 
531
{
 
532
  int  rv;
 
533
  char proxyURL[kProxySrvrLen];
 
534
 
 
535
  if((!szUrl) || (*szUrl == '\0'))
 
536
    return nsHTTPConn::E_PARAM;
 
537
 
 
538
  rv = nsHTTPConn::OK;
 
539
  memset(proxyURL, 0, kProxySrvrLen);
 
540
  wsprintf(proxyURL, "http://%s:%s", szProxyServer, szProxyPort);
 
541
 
 
542
  connHTTP = new nsHTTPConn(proxyURL, ProcessWndMsgCB);
 
543
  if(connHTTP == NULL)
 
544
  {
 
545
    char szBuf[MAX_BUF_TINY];
 
546
 
 
547
    GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), szFileIniConfig);
 
548
    PrintError(szBuf, ERROR_CODE_HIDE);
 
549
 
 
550
    return(WIZ_OUT_OF_MEMORY);
 
551
  }
 
552
 
 
553
  if((szProxyUser != NULL) && (*szProxyUser != '\0') &&
 
554
     (szProxyPasswd != NULL) && (*szProxyPasswd != '\0'))
 
555
    connHTTP->SetProxyInfo(szUrl, szProxyUser, szProxyPasswd);
 
556
  else
 
557
    connHTTP->SetProxyInfo(szUrl, NULL, NULL);
 
558
 
 
559
  rv = connHTTP->Open();
 
560
  return(rv);
 
561
}
 
562
 
 
563
void DownloadViaProxyClose(void)
 
564
{
 
565
  gbStartTickCounter = FALSE;
 
566
  if(connHTTP)
 
567
  {
 
568
    connHTTP->Close();
 
569
    delete(connHTTP);
 
570
    connHTTP = NULL;
 
571
  }
 
572
}
 
573
 
 
574
int DownloadViaProxy(char *szUrl, char *szProxyServer, char *szProxyPort, char *szProxyUser, char *szProxyPasswd)
 
575
{
 
576
  int  rv;
 
577
  char *file = NULL;
 
578
 
 
579
  rv = nsHTTPConn::OK;
 
580
  if((!szUrl) || (*szUrl == '\0'))
 
581
    return nsHTTPConn::E_PARAM;
 
582
 
 
583
  if(connHTTP == NULL)
 
584
  {
 
585
    rv = DownloadViaProxyOpen(szUrl,
 
586
                              szProxyServer,
 
587
                              szProxyPort,
 
588
                              szProxyUser,
 
589
                              szProxyPasswd);
 
590
 
 
591
    if(rv != nsHTTPConn::OK)
 
592
    {
 
593
      DownloadViaProxyClose();
 
594
      return(rv);
 
595
    }
 
596
  }
 
597
 
 
598
  if(connHTTP == NULL)
 
599
  {
 
600
    char szBuf[MAX_BUF_TINY];
 
601
 
 
602
    GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), szFileIniConfig);
 
603
    PrintError(szBuf, ERROR_CODE_HIDE);
 
604
 
 
605
    return(WIZ_OUT_OF_MEMORY);
 
606
  }
 
607
 
 
608
  if(strrchr(szUrl, '/') != (szUrl + strlen(szUrl)))
 
609
    file = strrchr(szUrl, '/') + 1; // set to leaf name
 
610
 
 
611
  gbStartTickCounter = TRUE;
 
612
  rv = connHTTP->Get(ProgressCB, file); // use leaf from URL
 
613
  DownloadViaProxyClose();
 
614
  return(rv);
 
615
}
 
616
 
 
617
int DownloadViaHTTPOpen(char *szUrl)
 
618
{
 
619
  int  rv;
 
620
 
 
621
  if((!szUrl) || (*szUrl == '\0'))
 
622
    return nsHTTPConn::E_PARAM;
 
623
 
 
624
  rv = nsHTTPConn::OK;
 
625
  connHTTP = new nsHTTPConn(szUrl, ProcessWndMsgCB);
 
626
  if(connHTTP == NULL)
 
627
  {
 
628
    char szBuf[MAX_BUF_TINY];
 
629
 
 
630
    GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), gszConfigIniFile);
 
631
    PrintError(szBuf, ERROR_CODE_HIDE);
 
632
 
 
633
    return(WIZ_OUT_OF_MEMORY);
 
634
  }
 
635
  
 
636
  rv = connHTTP->Open();
 
637
  return(rv);
 
638
}
 
639
 
 
640
void DownloadViaHTTPClose(void)
 
641
{
 
642
  gbStartTickCounter = FALSE;
 
643
  if(connHTTP)
 
644
  {
 
645
    connHTTP->Close();
 
646
    delete(connHTTP);
 
647
    connHTTP = NULL;
 
648
  }
 
649
}
 
650
 
 
651
int DownloadViaHTTP(char *szUrl)
 
652
{
 
653
  int  rv;
 
654
  char *file = NULL;
 
655
 
 
656
  if((!szUrl) || (*szUrl == '\0'))
 
657
    return nsHTTPConn::E_PARAM;
 
658
 
 
659
  if(connHTTP == NULL)
 
660
  {
 
661
    rv = DownloadViaHTTPOpen(szUrl);
 
662
    if(rv != nsHTTPConn::OK)
 
663
    {
 
664
      DownloadViaHTTPClose();
 
665
      return(rv);
 
666
    }
 
667
  }
 
668
 
 
669
  if(connHTTP == NULL)
 
670
  {
 
671
    char szBuf[MAX_BUF_TINY];
 
672
 
 
673
    GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), gszConfigIniFile);
 
674
    PrintError(szBuf, ERROR_CODE_HIDE);
 
675
 
 
676
    return(WIZ_OUT_OF_MEMORY);
 
677
  }
 
678
  
 
679
  rv = nsHTTPConn::OK;
 
680
  if(strrchr(szUrl, '/') != (szUrl + strlen(szUrl)))
 
681
    file = strrchr(szUrl, '/') + 1; // set to leaf name
 
682
 
 
683
  gbStartTickCounter = TRUE;
 
684
  rv = connHTTP->Get(ProgressCB, file);
 
685
  DownloadViaHTTPClose();
 
686
  return(rv);
 
687
}
 
688
 
 
689
int DownloadViaFTPOpen(char *szUrl)
 
690
{
 
691
  char *host = 0, *path = 0, *file = (char*) kLoclFile;
 
692
  int port = 21;
 
693
  int rv;
 
694
 
 
695
  if((!szUrl) || (*szUrl == '\0'))
 
696
    return nsFTPConn::E_PARAM;
 
697
 
 
698
  rv = nsHTTPConn::ParseURL(kFTP, szUrl, &host, &port, &path);
 
699
 
 
700
  connFTP = new nsFTPConn(host, ProcessWndMsgCB);
 
701
  if(connFTP == NULL)
 
702
  {
 
703
    char szBuf[MAX_BUF_TINY];
 
704
 
 
705
    GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), szFileIniConfig);
 
706
    PrintError(szBuf, ERROR_CODE_HIDE);
 
707
 
 
708
    return(WIZ_OUT_OF_MEMORY);
 
709
  }
 
710
 
 
711
  rv = connFTP->Open();
 
712
  if(host)
 
713
    free(host);
 
714
  if(path)
 
715
    free(path);
 
716
 
 
717
  return(rv);
 
718
}
 
719
 
 
720
void DownloadViaFTPClose(void)
 
721
{
 
722
  gbStartTickCounter = FALSE;
 
723
  if(connFTP)
 
724
  {
 
725
    connFTP->Close();
 
726
    delete(connFTP);
 
727
    connFTP = NULL;
 
728
  }
 
729
}
 
730
 
 
731
int DownloadViaFTP(char *szUrl)
 
732
{
 
733
  char *host = 0, *path = 0, *file = (char*) kLoclFile;
 
734
  int port = 21;
 
735
  int rv;
 
736
 
 
737
  if((!szUrl) || (*szUrl == '\0'))
 
738
    return nsFTPConn::E_PARAM;
 
739
 
 
740
  if(connFTP == NULL)
 
741
  {
 
742
    rv = DownloadViaFTPOpen(szUrl);
 
743
    if(rv != nsFTPConn::OK)
 
744
    {
 
745
      DownloadViaFTPClose();
 
746
      return(rv);
 
747
    }
 
748
  }
 
749
 
 
750
  if(connFTP == NULL)
 
751
  {
 
752
    char szBuf[MAX_BUF_TINY];
 
753
 
 
754
    GetPrivateProfileString("Strings", "Error Out Of Memory", "", szBuf, sizeof(szBuf), szFileIniConfig);
 
755
    PrintError(szBuf, ERROR_CODE_HIDE);
 
756
 
 
757
    return(WIZ_OUT_OF_MEMORY);
 
758
  }
 
759
 
 
760
  rv = nsHTTPConn::ParseURL(kFTP, szUrl, &host, &port, &path);
 
761
 
 
762
  if(strrchr(path, '/') != (path + strlen(path)))
 
763
    file = strrchr(path, '/') + 1; // set to leaf name
 
764
 
 
765
  gbStartTickCounter = TRUE;
 
766
  rv = connFTP->Get(path, file, nsFTPConn::BINARY, TRUE, ProgressCB);
 
767
 
 
768
  if(host)
 
769
    free(host);
 
770
  if(path)
 
771
    free(path);
 
772
 
 
773
  return(rv);
 
774
}
 
775
 
 
776
void PauseTheDownload(int rv, int *iFileDownloadRetries)
 
777
{
 
778
  if(rv != nsFTPConn::E_USER_CANCEL)
 
779
  {
 
780
    SendMessage(dlgInfo.hWndDlg, WM_COMMAND, IDPAUSE, 0);
 
781
    --*iFileDownloadRetries;
 
782
  }
 
783
 
 
784
  while(gdwDownloadDialogStatus == CS_PAUSE)
 
785
  {
 
786
    SleepEx(200, FALSE);
 
787
    ProcessWindowsMessages();
 
788
  }
 
789
}
 
790
 
 
791
void CloseSocket(char *szProxyServer, char *szProxyPort)
 
792
{
 
793
  /* Close the socket connection from the first attempt. */
 
794
  if((szProxyServer != NULL) && (szProxyPort != NULL) &&
 
795
     (*szProxyServer != '\0') && (*szProxyPort != '\0'))
 
796
      DownloadViaProxyClose();
 
797
  else
 
798
  {
 
799
    /* is this an HTTP URL? */
 
800
    if(strncmp(gszUrl, kHTTP, lstrlen(kHTTP)) == 0)
 
801
      DownloadViaHTTPClose();
 
802
    /* or is this an FTP URL? */
 
803
    else if(strncmp(gszUrl, kFTP, lstrlen(kFTP)) == 0)
 
804
      DownloadViaFTPClose();
 
805
  }
 
806
}
 
807
 
 
808
siC *GetObjectFromArchiveName(char *szArchiveName)
 
809
{
 
810
  DWORD dwIndex;
 
811
  siC   *siCObject = NULL;
 
812
  siC   *siCNode   = NULL;
 
813
 
 
814
  dwIndex = 0;
 
815
  siCObject = SiCNodeGetObject(dwIndex, TRUE, AC_ALL);
 
816
  while(siCObject)
 
817
  {
 
818
    if(lstrcmpi(szArchiveName, siCObject->szArchiveName) == 0)
 
819
    {
 
820
      siCNode = siCObject;
 
821
      break;
 
822
    }
 
823
 
 
824
    ++dwIndex;
 
825
    siCObject = SiCNodeGetObject(dwIndex, TRUE, AC_ALL);
 
826
  }
 
827
 
 
828
  return(siCNode);
 
829
}
 
830
 
 
831
int DownloadFiles(char *szInputIniFile,
 
832
                  char *szDownloadDir,
 
833
                  char *szProxyServer,
 
834
                  char *szProxyPort,
 
835
                  char *szProxyUser,
 
836
                  char *szProxyPasswd,
 
837
                  BOOL bShowRetryMsg,
 
838
                  BOOL bIgnoreAllNetworkErrors,
 
839
                  char *szFailedFile,
 
840
                  DWORD dwFailedFileSize)
 
841
{
 
842
  char      szBuf[MAX_BUF];
 
843
  char      szCurrentFile[MAX_BUF];
 
844
  char      szSection[MAX_INI_SK];
 
845
  char      szKey[MAX_INI_SK];
 
846
  char      szSavedCwd[MAX_BUF_MEDIUM];
 
847
  int       iCounter;
 
848
  int       rv;
 
849
  int       iFileDownloadRetries;
 
850
  int       iIgnoreFileNetworkError;
 
851
  int       iLocalTimeOutCounter;
 
852
  DWORD     dwTotalEstDownloadSize;
 
853
  char      szPartiallyDownloadedFilename[MAX_BUF];
 
854
  BOOL      bDownloadInitiated;
 
855
  char      szTempURL[MAX_BUF];
 
856
  char      szWorkingURLPathOnly[MAX_BUF];
 
857
  siC       *siCCurrentFileObj = NULL;
 
858
 
 
859
  ZeroMemory(szTempURL, sizeof(szTempURL));
 
860
  ZeroMemory(szWorkingURLPathOnly, sizeof(szWorkingURLPathOnly));
 
861
  if(szInputIniFile == NULL)
 
862
    return(WIZ_ERROR_UNDEFINED);
 
863
 
 
864
  if(szFailedFile)
 
865
    ZeroMemory(szFailedFile, dwFailedFileSize);
 
866
 
 
867
  InitTickInfo();
 
868
  GetCurrentDirectory(sizeof(szSavedCwd), szSavedCwd);
 
869
  SetCurrentDirectory(szDownloadDir);
 
870
 
 
871
  rv                        = WIZ_OK;
 
872
  dwTotalEstDownloadSize    = 0;
 
873
  giTotalArchivesToDownload = 0;
 
874
  glLastBytesSoFar          = 0;
 
875
  glAbsoluteBytesSoFar      = 0;
 
876
  glBytesResumedFrom        = 0;
 
877
  gdwTickStart              = 0; /* Initialize the counter used to
 
878
                                  * calculate download rate */
 
879
  gbStartTickCounter        = FALSE; /* used to determine when to start
 
880
                                      * the tick counter used to calculate
 
881
                                      * the download rate */
 
882
  gbUrlChanged              = TRUE;
 
883
  gbDlgDownloadMinimized    = FALSE;
 
884
  gbDlgDownloadJustMinimized = FALSE;
 
885
  gdwDownloadDialogStatus   = CS_NONE;
 
886
  gbShowDownloadRetryMsg    = bShowRetryMsg;
 
887
  gszConfigIniFile          = szInputIniFile;
 
888
  bDownloadInitiated        = FALSE;
 
889
 
 
890
  GetTotalArchivesToDownload(&giTotalArchivesToDownload,
 
891
                             &dwTotalEstDownloadSize);
 
892
  glTotalKb                 = dwTotalEstDownloadSize;
 
893
  GetSetupCurrentDownloadFile(szPartiallyDownloadedFilename,
 
894
                              sizeof(szPartiallyDownloadedFilename));
 
895
 
 
896
  InitDownloadDlg();
 
897
 
 
898
  for(giIndex = 0; giIndex < giTotalArchivesToDownload; giIndex++)
 
899
  {
 
900
    /* set (or reset) the counter to 0 in order to read the
 
901
     * next files's 0'th url from the .idi file */
 
902
    iCounter     = 0;
 
903
    gbUrlChanged = TRUE; /* Update the download dialog with new URL */
 
904
    wsprintf(szSection, "File%d", giIndex);
 
905
    wsprintf(szKey,     "url%d",  iCounter);
 
906
    GetPrivateProfileString(szSection,
 
907
                            szKey,
 
908
                            "",
 
909
                            szTempURL,
 
910
                            sizeof(szTempURL),
 
911
                            gszConfigIniFile);
 
912
 
 
913
    if(*szTempURL == '\0')
 
914
      continue;
 
915
 
 
916
    if(!bDownloadInitiated)
 
917
    {
 
918
      ParsePath(szTempURL,
 
919
                szWorkingURLPathOnly,
 
920
                sizeof(szWorkingURLPathOnly),
 
921
                TRUE, //use '/' as the path delimiter
 
922
                PP_PATH_ONLY);
 
923
    }
 
924
 
 
925
    GetPrivateProfileString(szSection,
 
926
                            "desc",
 
927
                            "",
 
928
                            gszCurrentDownloadFileDescription,
 
929
                            sizeof(gszCurrentDownloadFileDescription),
 
930
                            gszConfigIniFile);
 
931
    iIgnoreFileNetworkError = GetPrivateProfileInt(szSection,
 
932
                            "Ignore File Network Error",
 
933
                            0,
 
934
                            gszConfigIniFile);
 
935
 
 
936
    /* save the file name to be downloaded */
 
937
    ParsePath(szTempURL,
 
938
              szCurrentFile,
 
939
              sizeof(szCurrentFile),
 
940
              TRUE, //use '/' as the path delimiter
 
941
              PP_FILENAME_ONLY);
 
942
 
 
943
    RemoveSlash(szWorkingURLPathOnly);
 
944
    wsprintf(gszUrl, "%s/%s", szWorkingURLPathOnly, szCurrentFile);
 
945
 
 
946
    /* retrieve the file's data structure */
 
947
    siCCurrentFileObj = GetObjectFromArchiveName(szCurrentFile);
 
948
 
 
949
    if((*szPartiallyDownloadedFilename != 0) &&
 
950
       (lstrcmpi(szPartiallyDownloadedFilename, szCurrentFile) == 0))
 
951
    {
 
952
      struct stat statBuf;
 
953
 
 
954
      if(stat(szPartiallyDownloadedFilename, &statBuf) != -1)
 
955
      {
 
956
        glAbsoluteBytesSoFar += statBuf.st_size;
 
957
        glBytesResumedFrom    = statBuf.st_size;
 
958
      }
 
959
    }
 
960
 
 
961
    lstrcpy(gszTo, szDownloadDir);
 
962
    AppendBackSlash(gszTo, sizeof(gszTo));
 
963
    lstrcat(gszTo, szCurrentFile);
 
964
 
 
965
    if(gbDlgDownloadMinimized)
 
966
      SetMinimizedDownloadTitle((int)GetPercentSoFar());
 
967
    else
 
968
    {
 
969
      SetStatusUrl();
 
970
      SetRestoredDownloadTitle();
 
971
    }
 
972
 
 
973
    SetSetupCurrentDownloadFile(szCurrentFile);
 
974
    iFileDownloadRetries = 0;
 
975
    iLocalTimeOutCounter = 0;
 
976
    do
 
977
    {
 
978
      ProcessWindowsMessages();
 
979
      /* Download starts here */
 
980
      if((szProxyServer != NULL) && (szProxyPort != NULL) &&
 
981
         (*szProxyServer != '\0') && (*szProxyPort != '\0'))
 
982
        /* If proxy info is provided, use HTTP proxy */
 
983
        rv = DownloadViaProxy(gszUrl,
 
984
                              szProxyServer,
 
985
                              szProxyPort,
 
986
                              szProxyUser,
 
987
                              szProxyPasswd);
 
988
      else
 
989
      {
 
990
        /* is this an HTTP URL? */
 
991
        if(strncmp(gszUrl, kHTTP, lstrlen(kHTTP)) == 0)
 
992
          rv = DownloadViaHTTP(gszUrl);
 
993
        /* or is this an FTP URL? */
 
994
        else if(strncmp(gszUrl, kFTP, lstrlen(kFTP)) == 0)
 
995
          rv = DownloadViaFTP(gszUrl);
 
996
      }
 
997
 
 
998
      bDownloadInitiated = TRUE;
 
999
      if((rv == nsFTPConn::E_USER_CANCEL) ||
 
1000
         (gdwDownloadDialogStatus == CS_PAUSE))
 
1001
      {
 
1002
        if(gdwDownloadDialogStatus == CS_PAUSE)
 
1003
        {
 
1004
          CloseSocket(szProxyServer, szProxyPort);
 
1005
 
 
1006
          /* rv needs to be set to something
 
1007
           * other than E_USER_CANCEL or E_OK */
 
1008
          rv = nsFTPConn::E_CMD_UNEXPECTED;
 
1009
 
 
1010
          PauseTheDownload(rv, &iFileDownloadRetries);
 
1011
          bDownloadInitiated = FALSE; /* restart the download using
 
1012
                                       * new socket connection */
 
1013
        }
 
1014
        else
 
1015
        {
 
1016
          /* user canceled; break out of the do loop */
 
1017
          break;
 
1018
        }
 
1019
      }
 
1020
      else if((rv != nsFTPConn::OK) &&
 
1021
              (rv != nsFTPConn::E_CMD_FAIL) &&
 
1022
              (rv != nsSocket::E_BIND) &&
 
1023
              (rv != nsHTTPConn::E_HTTP_RESPONSE) &&
 
1024
              (gdwDownloadDialogStatus != CS_CANCEL))
 
1025
      {
 
1026
        /* We timed out.  No response from the server, or 
 
1027
         * we somehow lost connection. */
 
1028
 
 
1029
        char szTitle[MAX_BUF_SMALL];
 
1030
        char szMsgDownloadPaused[MAX_BUF];
 
1031
 
 
1032
        /* Incrememt the time out counter on E_TIMEOUT */
 
1033
        if(rv == nsSocket::E_TIMEOUT)
 
1034
        {
 
1035
          ++siCCurrentFileObj->iNetTimeOuts;
 
1036
          ++iLocalTimeOutCounter;
 
1037
        }
 
1038
 
 
1039
        CloseSocket(szProxyServer, szProxyPort);
 
1040
 
 
1041
        /* If the number of timeouts is %3 == 0, then let's pause
 
1042
         * the download process.  Otherwise, just close the
 
1043
         * connection and open a new one to see if the download
 
1044
         * can be restarted automatically. */
 
1045
        if((rv != nsSocket::E_TIMEOUT) ||
 
1046
           (rv == nsSocket::E_TIMEOUT) && ((iLocalTimeOutCounter % kModTimeOutValue) == 0))
 
1047
        {
 
1048
          /* Start the pause tick counter here because we don't know how
 
1049
           * long before the user will dismiss the MessageBox() */
 
1050
          if(!gtiPaused.bTickStarted)
 
1051
          {
 
1052
            gtiPaused.dwTickBegin          = GetTickCount();
 
1053
            gtiPaused.bTickStarted         = TRUE;
 
1054
            gtiPaused.bTickDownloadResumed = FALSE;
 
1055
          }
 
1056
 
 
1057
          /* The connection unexepectedly dropped for some reason, so inform
 
1058
           * the user that the download will be Paused, and then update the
 
1059
           * Download dialog to show the Paused state. */
 
1060
          GetPrivateProfileString("Messages",
 
1061
                                  "MB_WARNING_STR",
 
1062
                                  "",
 
1063
                                  szTitle,
 
1064
                                  sizeof(szTitle),
 
1065
                                  szFileIniInstall);
 
1066
          GetPrivateProfileString("Strings",
 
1067
                                  "Message Download Paused",
 
1068
                                  "",
 
1069
                                  szMsgDownloadPaused,
 
1070
                                  sizeof(szMsgDownloadPaused),
 
1071
                                  szFileIniConfig);
 
1072
          MessageBox(dlgInfo.hWndDlg,
 
1073
                     szMsgDownloadPaused,
 
1074
                     szTitle,
 
1075
                     MB_ICONEXCLAMATION);
 
1076
 
 
1077
          /* Let's make sure we're in a paused state */
 
1078
          gdwDownloadDialogStatus = CS_PAUSE;
 
1079
          PauseTheDownload(rv, &iFileDownloadRetries);
 
1080
        }
 
1081
        else
 
1082
          /* Let's make sure we're _not_ in a paused state */
 
1083
          gdwDownloadDialogStatus = CS_NONE;
 
1084
      }
 
1085
 
 
1086
      /* We don't count time outs as normal failures.  We're
 
1087
       * keeping track of time outs differently. */
 
1088
      if(rv != nsSocket::E_TIMEOUT)
 
1089
        ++iFileDownloadRetries;
 
1090
 
 
1091
      if((iFileDownloadRetries > MAX_FILE_DOWNLOAD_RETRIES) &&
 
1092
         (rv != nsFTPConn::E_USER_CANCEL) &&
 
1093
         (gdwDownloadDialogStatus != CS_CANCEL))
 
1094
      {
 
1095
        /* since the download retries maxed out, increment the counter
 
1096
         * to read the next url for the current file */
 
1097
        ++iCounter;
 
1098
        wsprintf(szKey, "url%d",  iCounter);
 
1099
        GetPrivateProfileString(szSection,
 
1100
                                szKey,
 
1101
                                "",
 
1102
                                szTempURL,
 
1103
                                sizeof(szTempURL),
 
1104
                                gszConfigIniFile);
 
1105
        if(*szTempURL != '\0')
 
1106
        {
 
1107
          /* Found more urls to download from for the current file.
 
1108
           * Update the dialog to show the new url and reset the
 
1109
           * file download retries to 0 since it's a new url. */
 
1110
          gbUrlChanged = TRUE;
 
1111
          iFileDownloadRetries = 0;
 
1112
          bDownloadInitiated = FALSE; // restart the download using new socket connection
 
1113
          CloseSocket(szProxyServer, szProxyPort);
 
1114
          ParsePath(szTempURL,
 
1115
                    szWorkingURLPathOnly,
 
1116
                    sizeof(szWorkingURLPathOnly),
 
1117
                    TRUE, //use '/' as the path delimiter
 
1118
                    PP_PATH_ONLY);
 
1119
          RemoveSlash(szWorkingURLPathOnly);
 
1120
          wsprintf(gszUrl, "%s/%s", szWorkingURLPathOnly, szCurrentFile);
 
1121
          SetStatusUrl();
 
1122
        }
 
1123
      }
 
1124
    } while((rv != nsFTPConn::E_USER_CANCEL) &&
 
1125
            (rv != nsFTPConn::OK) &&
 
1126
            (gdwDownloadDialogStatus != CS_CANCEL) &&
 
1127
            (iFileDownloadRetries <= MAX_FILE_DOWNLOAD_RETRIES));
 
1128
 
 
1129
    /* Save the number of retries for each file */
 
1130
    siCCurrentFileObj->iNetRetries = iFileDownloadRetries < 1 ? 0:iFileDownloadRetries - 1;
 
1131
 
 
1132
    if((rv == nsFTPConn::E_USER_CANCEL) ||
 
1133
       (gdwDownloadDialogStatus == CS_CANCEL))
 
1134
    {
 
1135
      /* make sure rv is E_USER_CANCEL when gdwDownloadDialogStatus
 
1136
       * is CS_CANCEL */
 
1137
      rv = nsFTPConn::E_USER_CANCEL;
 
1138
 
 
1139
      if(szFailedFile && ((DWORD)lstrlen(szCurrentFile) <= dwFailedFileSize))
 
1140
        lstrcpy(szFailedFile, gszCurrentDownloadFileDescription);
 
1141
 
 
1142
      /* break out of for() loop */
 
1143
      break;
 
1144
    }
 
1145
 
 
1146
    if((rv != nsFTPConn::OK) &&
 
1147
       (iFileDownloadRetries > MAX_FILE_DOWNLOAD_RETRIES) &&
 
1148
       !bIgnoreAllNetworkErrors &&
 
1149
       !iIgnoreFileNetworkError)
 
1150
    {
 
1151
      /* too many retries from failed downloads */
 
1152
      char szMsg[MAX_BUF];
 
1153
 
 
1154
      if(szFailedFile && ((DWORD)lstrlen(szCurrentFile) <= dwFailedFileSize))
 
1155
        lstrcpy(szFailedFile, gszCurrentDownloadFileDescription);
 
1156
 
 
1157
      GetPrivateProfileString("Strings",
 
1158
                              "Error Too Many Network Errors",
 
1159
                              "",
 
1160
                              szMsg,
 
1161
                              sizeof(szMsg),
 
1162
                              szFileIniConfig);
 
1163
      if(*szMsg != '\0')
 
1164
      {
 
1165
        wsprintf(szBuf, szMsg, szCurrentFile);
 
1166
        PrintError(szBuf, ERROR_CODE_HIDE);
 
1167
      }
 
1168
 
 
1169
      iFileDownloadRetries = 0; // reset the file download retries counter since
 
1170
                                // we'll be restarting the download again.
 
1171
      bDownloadInitiated = FALSE; // restart the download using new socket connection
 
1172
      CloseSocket(szProxyServer, szProxyPort);
 
1173
      --giIndex; // Decrement the file index counter because we'll be trying to
 
1174
                 // download the same file again.  We don't want to go to the next
 
1175
                 // file just yet.
 
1176
 
 
1177
      /* Let's make sure we're in a paused state. */
 
1178
      /* The pause state will be unset by DownloadDlgProc(). */
 
1179
      gdwDownloadDialogStatus = CS_PAUSE;
 
1180
      PauseTheDownload(rv, &iFileDownloadRetries);
 
1181
    }
 
1182
    else if(bIgnoreAllNetworkErrors || iIgnoreFileNetworkError)
 
1183
      rv = nsFTPConn::OK;
 
1184
 
 
1185
    UnsetSetupCurrentDownloadFile();
 
1186
  }
 
1187
 
 
1188
  CloseSocket(szProxyServer, szProxyPort);
 
1189
  DeInitDownloadDlg();
 
1190
  SetCurrentDirectory(szSavedCwd);
 
1191
  return(rv);
 
1192
}
 
1193
 
 
1194
int ProgressCB(int aBytesSoFar, int aTotalFinalSize)
 
1195
{
 
1196
  long   lBytesDiffSoFar;
 
1197
  double dPercentSoFar;
 
1198
  int    iRv = nsFTPConn::OK;
 
1199
 
 
1200
  if(sgProduct.mode != SILENT)
 
1201
  {
 
1202
    SetStatusUrl();
 
1203
 
 
1204
    if(glTotalKb == 0)
 
1205
      glTotalKb = aTotalFinalSize;
 
1206
 
 
1207
    /* Calculate the difference between the last set of bytes read against
 
1208
     * the current set of bytes read.  If the value is negative, that means
 
1209
     * that it started a new file, so reset lBytesDiffSoFar to aBytesSoFar */
 
1210
    lBytesDiffSoFar = ((aBytesSoFar - glLastBytesSoFar) < 1) ? aBytesSoFar : (aBytesSoFar - glLastBytesSoFar);
 
1211
 
 
1212
    /* Save the current bytes read as the last set of bytes read */
 
1213
    glLastBytesSoFar = aBytesSoFar;
 
1214
    glAbsoluteBytesSoFar += lBytesDiffSoFar;
 
1215
 
 
1216
    dPercentSoFar = GetPercentSoFar();
 
1217
    if(gbDlgDownloadMinimized)
 
1218
      SetMinimizedDownloadTitle((int)dPercentSoFar);
 
1219
 
 
1220
    UpdateGaugeFileProgressBar(dPercentSoFar);
 
1221
    SetStatusStatus();
 
1222
 
 
1223
    if((gdwDownloadDialogStatus == CS_CANCEL) ||
 
1224
       (gdwDownloadDialogStatus == CS_PAUSE))
 
1225
      iRv = nsFTPConn::E_USER_CANCEL;
 
1226
  }
 
1227
 
 
1228
  ProcessWindowsMessages();
 
1229
  return(iRv);
 
1230
}
 
1231
 
 
1232
// Window proc for dialog
 
1233
LRESULT CALLBACK
 
1234
DownloadDlgProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 
1235
{
 
1236
  switch (msg)
 
1237
  {
 
1238
    case WM_INITDIALOG:
 
1239
      GetPrivateProfileString("Strings",
 
1240
                              "Status File Info",
 
1241
                              "",
 
1242
                              gszFileInfo,
 
1243
                              sizeof(gszFileInfo),
 
1244
                              szFileIniConfig);
 
1245
      if(gbShowDownloadRetryMsg)
 
1246
        SetDlgItemText(hWndDlg, IDC_MESSAGE0, diDownload.szMessageRetry0);
 
1247
      else
 
1248
        SetDlgItemText(hWndDlg, IDC_MESSAGE0, diDownload.szMessageDownload0);
 
1249
 
 
1250
      EnableWindow(GetDlgItem(hWndDlg, IDRESUME), FALSE);
 
1251
      SetDlgItemText(hWndDlg, IDC_STATIC1, sgInstallGui.szStatus);
 
1252
      SetDlgItemText(hWndDlg, IDC_STATIC2, sgInstallGui.szFile);
 
1253
      SetDlgItemText(hWndDlg, IDC_STATIC4, sgInstallGui.szTo);
 
1254
      SetDlgItemText(hWndDlg, IDC_STATIC3, sgInstallGui.szUrl);
 
1255
      SetDlgItemText(hWndDlg, IDCANCEL, sgInstallGui.szCancel_);
 
1256
      SetDlgItemText(hWndDlg, IDPAUSE, sgInstallGui.szPause_);
 
1257
      SetDlgItemText(hWndDlg, IDRESUME, sgInstallGui.szResume_);
 
1258
      SendDlgItemMessage (hWndDlg, IDC_STATIC1, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1259
      SendDlgItemMessage (hWndDlg, IDC_STATIC2, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1260
      SendDlgItemMessage (hWndDlg, IDC_STATIC3, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1261
      SendDlgItemMessage (hWndDlg, IDCANCEL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1262
      SendDlgItemMessage (hWndDlg, IDPAUSE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1263
      SendDlgItemMessage (hWndDlg, IDRESUME, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1264
      SendDlgItemMessage (hWndDlg, IDC_MESSAGE0, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1265
      SendDlgItemMessage (hWndDlg, IDC_STATUS_STATUS, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1266
      SendDlgItemMessage (hWndDlg, IDC_STATUS_FILE, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1267
      SendDlgItemMessage (hWndDlg, IDC_STATUS_URL, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1268
      SendDlgItemMessage (hWndDlg, IDC_STATUS_TO, WM_SETFONT, (WPARAM)sgInstallGui.definedFont, 0L);
 
1269
      return FALSE;
 
1270
 
 
1271
    case WM_SIZE:
 
1272
      switch(wParam)
 
1273
      {
 
1274
        case SIZE_MINIMIZED:
 
1275
          SetMinimizedDownloadTitle((int)GetPercentSoFar());
 
1276
          gbDlgDownloadMinimized = TRUE;
 
1277
          gbDlgDownloadJustMinimized = TRUE;
 
1278
          break;
 
1279
 
 
1280
        case SIZE_RESTORED:
 
1281
          SetStatusUrl();
 
1282
          SetRestoredDownloadTitle();
 
1283
          gbDlgDownloadMinimized = FALSE;
 
1284
          break;
 
1285
      }
 
1286
      return(FALSE);
 
1287
 
 
1288
    case WM_COMMAND:
 
1289
      switch(LOWORD(wParam))
 
1290
      {
 
1291
        case IDCANCEL:
 
1292
          if(ShouldExitSetup(hWndDlg))
 
1293
            gdwDownloadDialogStatus = CS_CANCEL;
 
1294
          break;
 
1295
 
 
1296
        case IDPAUSE:
 
1297
          if(!gtiPaused.bTickStarted)
 
1298
          {
 
1299
            gtiPaused.dwTickBegin          = GetTickCount();
 
1300
            gtiPaused.bTickStarted         = TRUE;
 
1301
            gtiPaused.bTickDownloadResumed = FALSE;
 
1302
          }
 
1303
 
 
1304
          EnableWindow(GetDlgItem(hWndDlg, IDPAUSE),  FALSE);
 
1305
          EnableWindow(GetDlgItem(hWndDlg, IDRESUME), TRUE);
 
1306
          gdwDownloadDialogStatus = CS_PAUSE;
 
1307
          break;
 
1308
 
 
1309
        case IDRESUME:
 
1310
          gtiPaused.dwTickEnd = GetTickCount();
 
1311
          gtiPaused.dwTickDif = GetTickDif(gtiPaused.dwTickEnd,
 
1312
                                           gtiPaused.dwTickBegin);
 
1313
          gtiPaused.bTickDownloadResumed = TRUE;
 
1314
 
 
1315
          EnableWindow(GetDlgItem(hWndDlg, IDRESUME), FALSE);
 
1316
          EnableWindow(GetDlgItem(hWndDlg, IDPAUSE),  TRUE);
 
1317
          gdwDownloadDialogStatus = CS_NONE;
 
1318
          break;
 
1319
 
 
1320
        default:
 
1321
          break;
 
1322
      }
 
1323
      return(TRUE);
 
1324
  }
 
1325
 
 
1326
  return(FALSE);  // didn't handle the message
 
1327
}
 
1328
 
 
1329
// This routine will update the File Gauge progress bar to the specified percentage
 
1330
// (value between 0 and 100)
 
1331
static void
 
1332
UpdateGaugeFileProgressBar(double value)
 
1333
{
 
1334
        int             nBars;
 
1335
  static long lModLastValue = 0;
 
1336
 
 
1337
  if(sgProduct.mode != SILENT)
 
1338
  {
 
1339
    if(!CheckInterval(&lModLastValue, UPDATE_INTERVAL_PROGRESS_BAR))
 
1340
      return;
 
1341
 
 
1342
    // Figure out how many bars should be displayed
 
1343
    nBars = (int)(dlgInfo.nMaxFileBars * value / 100);
 
1344
 
 
1345
    // Only paint if we need to display more bars
 
1346
    if((nBars > dlgInfo.nFileBars) || (dlgInfo.nFileBars == 0))
 
1347
    {
 
1348
      HWND      hWndGauge = GetDlgItem(dlgInfo.hWndDlg, IDC_PROGRESS_FILE);
 
1349
      RECT      rect;
 
1350
 
 
1351
      // Update the gauge state before painting
 
1352
      dlgInfo.nFileBars = nBars;
 
1353
 
 
1354
      // Only invalidate the part that needs updating
 
1355
      GetClientRect(hWndGauge, &rect);
 
1356
      InvalidateRect(hWndGauge, &rect, FALSE);
 
1357
    
 
1358
      // Update the whole extracting dialog. We do this because we don't
 
1359
      // have a message loop to process WM_PAINT messages in case the
 
1360
      // extracting dialog was exposed
 
1361
      UpdateWindow(dlgInfo.hWndDlg);
 
1362
    }
 
1363
  }
 
1364
}
 
1365
 
 
1366
// Draws a recessed border around the gauge
 
1367
static void
 
1368
DrawGaugeBorder(HWND hWnd)
 
1369
{
 
1370
        HDC             hDC = GetWindowDC(hWnd);
 
1371
        RECT    rect;
 
1372
        int             cx, cy;
 
1373
        HPEN    hShadowPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
 
1374
        HGDIOBJ hOldPen;
 
1375
 
 
1376
        GetWindowRect(hWnd, &rect);
 
1377
        cx = rect.right - rect.left;
 
1378
        cy = rect.bottom - rect.top;
 
1379
 
 
1380
        // Draw a dark gray line segment
 
1381
        hOldPen = SelectObject(hDC, (HGDIOBJ)hShadowPen);
 
1382
        MoveToEx(hDC, 0, cy - 1, NULL);
 
1383
        LineTo(hDC, 0, 0);
 
1384
        LineTo(hDC, cx - 1, 0);
 
1385
 
 
1386
        // Draw a white line segment
 
1387
        SelectObject(hDC, GetStockObject(WHITE_PEN));
 
1388
        MoveToEx(hDC, 0, cy - 1, NULL);
 
1389
        LineTo(hDC, cx - 1, cy - 1);
 
1390
        LineTo(hDC, cx - 1, 0);
 
1391
 
 
1392
        SelectObject(hDC, hOldPen);
 
1393
        DeleteObject(hShadowPen);
 
1394
        ReleaseDC(hWnd, hDC);
 
1395
}
 
1396
 
 
1397
// Draws the blue progress bar
 
1398
static void
 
1399
DrawProgressBar(HWND hWnd, int nBars)
 
1400
{
 
1401
  int         i;
 
1402
        PAINTSTRUCT     ps;
 
1403
        HDC         hDC;
 
1404
        RECT        rect;
 
1405
        HBRUSH      hBrush;
 
1406
 
 
1407
  hDC = BeginPaint(hWnd, &ps);
 
1408
        GetClientRect(hWnd, &rect);
 
1409
  if(nBars <= 0)
 
1410
  {
 
1411
    /* clear the bars */
 
1412
    hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
 
1413
    FillRect(hDC, &rect, hBrush);
 
1414
  }
 
1415
  else
 
1416
  {
 
1417
        // Draw the bars
 
1418
    hBrush = CreateSolidBrush(RGB(0, 0, 128));
 
1419
          rect.left     = rect.top = BAR_LIBXPNET_MARGIN;
 
1420
          rect.bottom  -= BAR_LIBXPNET_MARGIN;
 
1421
          rect.right    = rect.left + BAR_LIBXPNET_WIDTH;
 
1422
 
 
1423
          for(i = 0; i < nBars; i++)
 
1424
    {
 
1425
                  RECT  dest;
 
1426
 
 
1427
                  if(IntersectRect(&dest, &ps.rcPaint, &rect))
 
1428
                          FillRect(hDC, &rect, hBrush);
 
1429
 
 
1430
      OffsetRect(&rect, BAR_LIBXPNET_WIDTH + BAR_LIBXPNET_SPACING, 0);
 
1431
          }
 
1432
  }
 
1433
 
 
1434
        DeleteObject(hBrush);
 
1435
        EndPaint(hWnd, &ps);
 
1436
}
 
1437
 
 
1438
// Adjusts the width of the gauge based on the maximum number of bars
 
1439
static void
 
1440
SizeToFitGauge(HWND hWnd, int nMaxBars)
 
1441
{
 
1442
        RECT    rect;
 
1443
        int             cx;
 
1444
 
 
1445
        // Get the window size in pixels
 
1446
        GetWindowRect(hWnd, &rect);
 
1447
 
 
1448
        // Size the width to fit
 
1449
        cx = 2 * GetSystemMetrics(SM_CXBORDER) + 2 * BAR_LIBXPNET_MARGIN +
 
1450
                nMaxBars * BAR_LIBXPNET_WIDTH + (nMaxBars - 1) * BAR_LIBXPNET_SPACING;
 
1451
 
 
1452
        SetWindowPos(hWnd, NULL, -1, -1, cx, rect.bottom - rect.top,
 
1453
                SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
 
1454
}
 
1455
 
 
1456
// Window proc for Download gauge
 
1457
BOOL CALLBACK
 
1458
GaugeDownloadWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
1459
{
 
1460
        DWORD   dwStyle;
 
1461
        RECT    rect;
 
1462
 
 
1463
        switch(msg)
 
1464
  {
 
1465
                case WM_NCCREATE:
 
1466
                        dwStyle = GetWindowLong(hWnd, GWL_STYLE);
 
1467
                        SetWindowLong(hWnd, GWL_STYLE, dwStyle | WS_BORDER);
 
1468
                        return(TRUE);
 
1469
 
 
1470
                case WM_CREATE:
 
1471
                        // Figure out the maximum number of bars that can be displayed
 
1472
                        GetClientRect(hWnd, &rect);
 
1473
                        dlgInfo.nFileBars = 0;
 
1474
                        dlgInfo.nMaxFileBars = (rect.right - rect.left - 2 * BAR_LIBXPNET_MARGIN + BAR_LIBXPNET_SPACING) / (BAR_LIBXPNET_WIDTH + BAR_LIBXPNET_SPACING);
 
1475
 
 
1476
                        // Size the gauge to exactly fit the maximum number of bars
 
1477
                        SizeToFitGauge(hWnd, dlgInfo.nMaxFileBars);
 
1478
                        return(FALSE);
 
1479
 
 
1480
                case WM_NCPAINT:
 
1481
                        DrawGaugeBorder(hWnd);
 
1482
                        return(FALSE);
 
1483
 
 
1484
                case WM_PAINT:
 
1485
                        DrawProgressBar(hWnd, dlgInfo.nFileBars);
 
1486
                        return(FALSE);
 
1487
        }
 
1488
 
 
1489
        return(DefWindowProc(hWnd, msg, wParam, lParam));
 
1490
}
 
1491
 
 
1492
void InitDownloadDlg(void)
 
1493
{
 
1494
        WNDCLASS        wc;
 
1495
 
 
1496
  if(sgProduct.mode != SILENT)
 
1497
  {
 
1498
    memset(&wc, 0, sizeof(wc));
 
1499
    wc.style          = CS_GLOBALCLASS;
 
1500
    wc.hInstance      = hInst;
 
1501
    wc.hbrBackground  = (HBRUSH)(COLOR_BTNFACE + 1);
 
1502
    wc.lpfnWndProc    = (WNDPROC)GaugeDownloadWndProc;
 
1503
    wc.lpszClassName  = "GaugeFile";
 
1504
    RegisterClass(&wc);
 
1505
 
 
1506
    // Display the dialog box
 
1507
    dlgInfo.hWndDlg = CreateDialog(hSetupRscInst, MAKEINTRESOURCE(DLG_DOWNLOADING), hWndMain, (DLGPROC)DownloadDlgProc);
 
1508
    UpdateWindow(dlgInfo.hWndDlg);
 
1509
    UpdateGaugeFileProgressBar(0);
 
1510
  }
 
1511
}
 
1512
 
 
1513
void DeInitDownloadDlg()
 
1514
{
 
1515
  if(sgProduct.mode != SILENT)
 
1516
  {
 
1517
    DestroyWindow(dlgInfo.hWndDlg);
 
1518
    UnregisterClass("GaugeFile", hInst);
 
1519
  }
 
1520
}