applied patch #1723131 - NSISdl doesn't handle files over 2GB and patch #1656076 - make NSISdl more "translator-friendly"
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@5175 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
165aa0b8dd
commit
acc4233b41
6 changed files with 220 additions and 46 deletions
|
@ -59,6 +59,22 @@ TRANSLATE
|
||||||
|
|
||||||
To translate NSISdl add the following values to the call line:
|
To translate NSISdl add the following values to the call line:
|
||||||
|
|
||||||
|
/TRANSLATE2 downloading connecting second minute hour seconds minutes hours progress
|
||||||
|
|
||||||
|
Default values are:
|
||||||
|
|
||||||
|
downloading - "Downloading %s"
|
||||||
|
connecting - "Connecting ..."
|
||||||
|
second - " (1 second remaining)"
|
||||||
|
minute - " (1 minute remaining)"
|
||||||
|
hour - " (1 hour remaining)"
|
||||||
|
seconds - " (%u seconds remaining)"
|
||||||
|
minutes - " (%u minutes remaining)"
|
||||||
|
hours - " (%u hours remaining)"
|
||||||
|
progress - "%skB (%d%%) of %skB @ %u.%01ukB/s"
|
||||||
|
|
||||||
|
The old /TRANSLATE method still works for backward compatibility.
|
||||||
|
|
||||||
/TRANSLATE downloading connecting second minute hour plural progress remianing
|
/TRANSLATE downloading connecting second minute hour plural progress remianing
|
||||||
|
|
||||||
Default values are:
|
Default values are:
|
||||||
|
@ -69,7 +85,7 @@ Default values are:
|
||||||
minute - "minute"
|
minute - "minute"
|
||||||
hour - "hour"
|
hour - "hour"
|
||||||
plural - "s"
|
plural - "s"
|
||||||
progress - "%dkB (%d%%) of %dkB @ %d.%01dkB/s"
|
progress - "%dkB (%d%%) of %ukB @ %d.%01dkB/s"
|
||||||
remaining - " (%d %s%s remaining)"
|
remaining - " (%d %s%s remaining)"
|
||||||
|
|
||||||
/TRANSLATE must come before /TIMEOUT.
|
/TRANSLATE and /TRANSLATE2 must come before /TIMEOUT.
|
||||||
|
|
|
@ -22,4 +22,9 @@ docs = Split("""
|
||||||
|
|
||||||
Import('BuildPlugin')
|
Import('BuildPlugin')
|
||||||
|
|
||||||
BuildPlugin(target, files, libs, docs = docs, cppused = True)
|
BuildPlugin(
|
||||||
|
target, files, libs,
|
||||||
|
docs = docs,
|
||||||
|
cppused = True,
|
||||||
|
nodeflib = False,
|
||||||
|
)
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#define _HTTPGET_H_
|
#define _HTTPGET_H_
|
||||||
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
class JNL_HTTPGet
|
class JNL_HTTPGet
|
||||||
{
|
{
|
||||||
|
@ -70,7 +71,7 @@ class JNL_HTTPGet
|
||||||
int get_bytes(char *buf, int len);
|
int get_bytes(char *buf, int len);
|
||||||
int peek_bytes(char *buf, int len);
|
int peek_bytes(char *buf, int len);
|
||||||
|
|
||||||
int content_length() { char *p=getheader("content-length:"); if (p) return my_atoi(p); return 0; }
|
__int64 content_length() { char *p=getheader("content-length:"); if (p) return myatoi64(p); return 0; }
|
||||||
|
|
||||||
JNL_Connection *get_con() { return m_con; }
|
JNL_Connection *get_con() { return m_con; }
|
||||||
|
|
||||||
|
|
|
@ -196,9 +196,24 @@ extern "C" BOOL APIENTRY DllMain(HINSTANCE _hModule, DWORD ul_reason_for_call,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int g_file_size;
|
#define INT32_MAX 0x7fffffff
|
||||||
|
|
||||||
|
int MulDiv64(int nNumber, __int64 nNumerator, __int64 nDenominator)
|
||||||
|
{
|
||||||
|
// ok, a complete implementation would handle negatives too,
|
||||||
|
// but this method is probably not generally useful.
|
||||||
|
while (nNumerator > INT32_MAX || nDenominator > INT32_MAX)
|
||||||
|
{
|
||||||
|
nNumerator = Int64ShraMod32(nNumerator, 1);
|
||||||
|
nDenominator = Int64ShraMod32(nDenominator, 1);
|
||||||
|
}
|
||||||
|
return MulDiv(nNumber, (int)nNumerator, (int)nDenominator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __int64 g_file_size;
|
||||||
static DWORD g_dwLastTick = 0;
|
static DWORD g_dwLastTick = 0;
|
||||||
void progress_callback(char *msg, int read_bytes)
|
void progress_callback(char *msg, __int64 read_bytes)
|
||||||
{
|
{
|
||||||
// flicker reduction by A. Schiffler
|
// flicker reduction by A. Schiffler
|
||||||
DWORD dwLastTick = g_dwLastTick;
|
DWORD dwLastTick = g_dwLastTick;
|
||||||
|
@ -211,7 +226,7 @@ void progress_callback(char *msg, int read_bytes)
|
||||||
dwLastTick = dwThisTick;
|
dwLastTick = dwThisTick;
|
||||||
}
|
}
|
||||||
if (g_file_size)
|
if (g_file_size)
|
||||||
SendMessage(g_hwndProgressBar, PBM_SETPOS, (WPARAM) MulDiv(read_bytes, 30000, g_file_size), 0);
|
SendMessage(g_hwndProgressBar, PBM_SETPOS, (WPARAM) MulDiv64(30000, read_bytes, g_file_size), 0);
|
||||||
g_dwLastTick = dwLastTick;
|
g_dwLastTick = dwLastTick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,22 +250,47 @@ __declspec(dllexport) void download (HWND parent,
|
||||||
int timeout_ms=30000;
|
int timeout_ms=30000;
|
||||||
int getieproxy=1;
|
int getieproxy=1;
|
||||||
int manualproxy=0;
|
int manualproxy=0;
|
||||||
|
int translation_version;
|
||||||
|
|
||||||
char *error=NULL;
|
char *error=NULL;
|
||||||
|
|
||||||
static char szDownloading[1024];//= "Downloading %s";
|
// translation version 2 & 1
|
||||||
static char szConnecting[1024];//= "Connecting ...";
|
static char szDownloading[1024]; // "Downloading %s"
|
||||||
static char szSecond[1024];//= "second";
|
static char szConnecting[1024]; // "Connecting ..."
|
||||||
static char szMinute[1024];//= "minute";
|
static char szSecond[1024]; // " (1 second remaining)" for v2
|
||||||
static char szHour[1024];//= "hour";
|
// "second" for v1
|
||||||
static char szPlural[1024];//= "s";
|
static char szMinute[1024]; // " (1 minute remaining)" for v2
|
||||||
static char szProgress[1024];//= "%dkB (%d%%) of %dkB @ %d.%01dkB/s";
|
// "minute" for v1
|
||||||
static char szRemaining[1024];//= " (%d %s%s remaining)";
|
static char szHour[1024]; // " (1 hour remaining)" for v2
|
||||||
|
// "hour" for v1
|
||||||
|
static char szProgress[1024]; // "%skB (%d%%) of %skB at %u.%01ukB/s" for v2
|
||||||
|
// "%dkB (%d%%) of %dkB at %d.%01dkB/s" for v1
|
||||||
|
|
||||||
|
// translation version 2 only
|
||||||
|
static char szSeconds[1024]; // " (%u seconds remaining)"
|
||||||
|
static char szMinutes[1024]; // " (%u minutes remaining)"
|
||||||
|
static char szHours[1024]; // " (%u hours remaining)"
|
||||||
|
|
||||||
|
// translation version 1 only
|
||||||
|
static char szPlural[1024]; // "s";
|
||||||
|
static char szRemaining[1024]; // " (%d %s%s remaining)";
|
||||||
|
|
||||||
EXDLL_INIT();
|
EXDLL_INIT();
|
||||||
|
|
||||||
popstring(url);
|
popstring(url);
|
||||||
if (!lstrcmpi(url, "/TRANSLATE")) {
|
if (!lstrcmpi(url, "/TRANSLATE2")) {
|
||||||
|
popstring(szDownloading);
|
||||||
|
popstring(szConnecting);
|
||||||
|
popstring(szSecond);
|
||||||
|
popstring(szMinute);
|
||||||
|
popstring(szHour);
|
||||||
|
popstring(szSeconds);
|
||||||
|
popstring(szMinutes);
|
||||||
|
popstring(szHours);
|
||||||
|
popstring(szProgress);
|
||||||
|
popstring(url);
|
||||||
|
translation_version=2;
|
||||||
|
} else if (!lstrcmpi(url, "/TRANSLATE")) {
|
||||||
popstring(szDownloading);
|
popstring(szDownloading);
|
||||||
popstring(szConnecting);
|
popstring(szConnecting);
|
||||||
popstring(szSecond);
|
popstring(szSecond);
|
||||||
|
@ -260,16 +300,18 @@ __declspec(dllexport) void download (HWND parent,
|
||||||
popstring(szProgress);
|
popstring(szProgress);
|
||||||
popstring(szRemaining);
|
popstring(szRemaining);
|
||||||
popstring(url);
|
popstring(url);
|
||||||
}
|
translation_version=1;
|
||||||
else {
|
} else {
|
||||||
lstrcpy(szDownloading, "Downloading %s");
|
lstrcpy(szDownloading, "Downloading %s");
|
||||||
lstrcpy(szConnecting, "Connecting ...");
|
lstrcpy(szConnecting, "Connecting ...");
|
||||||
lstrcpy(szSecond, "second");
|
lstrcpy(szSecond, " (1 second remaining)");
|
||||||
lstrcpy(szMinute, "minute");
|
lstrcpy(szMinute, " (1 minute remaining)");
|
||||||
lstrcpy(szHour, "hour");
|
lstrcpy(szHour, " (1 hour remaining)");
|
||||||
lstrcpy(szPlural, "s");
|
lstrcpy(szSeconds, " (%u seconds remaining)");
|
||||||
lstrcpy(szProgress, "%dkB (%d%%) of %dkB @ %d.%01dkB/s");
|
lstrcpy(szMinutes, " (%u minutes remaining)");
|
||||||
lstrcpy(szRemaining, " (%d %s%s remaining)");
|
lstrcpy(szHours, " (%u hours remaining)");
|
||||||
|
lstrcpy(szProgress, "%skB (%d%%) of %skB at %u.%01ukB/s");
|
||||||
|
translation_version=2;
|
||||||
}
|
}
|
||||||
lstrcpyn(buf, url, 10);
|
lstrcpyn(buf, url, 10);
|
||||||
if (!lstrcmpi(buf, "/TIMEOUT=")) {
|
if (!lstrcmpi(buf, "/TIMEOUT=")) {
|
||||||
|
@ -356,9 +398,9 @@ __declspec(dllexport) void download (HWND parent,
|
||||||
get=new JNL_HTTPGet(JNL_CONNECTION_AUTODNS,16384,(p&&p[0])?p:NULL);
|
get=new JNL_HTTPGet(JNL_CONNECTION_AUTODNS,16384,(p&&p[0])?p:NULL);
|
||||||
int st;
|
int st;
|
||||||
int has_printed_headers = 0;
|
int has_printed_headers = 0;
|
||||||
int cl = 0;
|
__int64 cl = 0;
|
||||||
int len;
|
int len;
|
||||||
int sofar = 0;
|
__int64 sofar = 0;
|
||||||
DWORD last_recv_time=start_time;
|
DWORD last_recv_time=start_time;
|
||||||
|
|
||||||
get->addheader ("User-Agent: NSISDL/1.2 (Mozilla)");
|
get->addheader ("User-Agent: NSISDL/1.2 (Mozilla)");
|
||||||
|
@ -437,31 +479,63 @@ __declspec(dllexport) void download (HWND parent,
|
||||||
WriteFile(hFile,buf,len,&dw,NULL);
|
WriteFile(hFile,buf,len,&dw,NULL);
|
||||||
sofar += len;
|
sofar += len;
|
||||||
int time_sofar=(GetTickCount()-start_time)/1000;
|
int time_sofar=(GetTickCount()-start_time)/1000;
|
||||||
int bps=sofar/(time_sofar?time_sofar:1);
|
int bps = (int)(sofar/(time_sofar?time_sofar:1));
|
||||||
int remain=MulDiv(time_sofar,cl,sofar) - time_sofar;
|
int remain = MulDiv64(time_sofar, cl, sofar) - time_sofar;
|
||||||
char *rtext=szSecond;
|
|
||||||
if (remain >= 60)
|
if (translation_version == 2) {
|
||||||
{
|
char *rtext=remain==1?szSecond:szSeconds;;
|
||||||
remain/=60;
|
|
||||||
rtext=szMinute;
|
|
||||||
if (remain >= 60)
|
if (remain >= 60)
|
||||||
{
|
{
|
||||||
remain/=60;
|
remain/=60;
|
||||||
rtext=szHour;
|
rtext=remain==1?szMinute:szMinutes;
|
||||||
|
if (remain >= 60)
|
||||||
|
{
|
||||||
|
remain/=60;
|
||||||
|
rtext=remain==1?szHour:szHours;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char sofar_str[128];
|
||||||
|
char cl_str[128];
|
||||||
|
myitoa64(sofar/1024, sofar_str);
|
||||||
|
myitoa64(cl/1024, cl_str);
|
||||||
|
|
||||||
|
wsprintf (buf,
|
||||||
|
szProgress, //%skB (%d%%) of %skB @ %u.%01ukB/s
|
||||||
|
sofar_str,
|
||||||
|
MulDiv64(100, sofar, cl),
|
||||||
|
cl_str,
|
||||||
|
bps/1024,((bps*10)/1024)%10
|
||||||
|
);
|
||||||
|
if (remain) wsprintf(buf+lstrlen(buf),rtext,
|
||||||
|
remain
|
||||||
|
);
|
||||||
|
} else if (translation_version == 1) {
|
||||||
|
char *rtext=szSecond;
|
||||||
|
if (remain >= 60)
|
||||||
|
{
|
||||||
|
remain/=60;
|
||||||
|
rtext=szMinute;
|
||||||
|
if (remain >= 60)
|
||||||
|
{
|
||||||
|
remain/=60;
|
||||||
|
rtext=szHour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wsprintf (buf,
|
||||||
|
szProgress, //%dkB (%d%%) of %dkB @ %d.%01dkB/s
|
||||||
|
int(sofar),
|
||||||
|
MulDiv64(100, sofar, cl),
|
||||||
|
int(cl),
|
||||||
|
bps/1024,((bps*10)/1024)%10
|
||||||
|
);
|
||||||
|
if (remain) wsprintf(buf+lstrlen(buf),szRemaining,
|
||||||
|
remain,
|
||||||
|
rtext,
|
||||||
|
remain==1?"":szPlural
|
||||||
|
);
|
||||||
}
|
}
|
||||||
wsprintf (buf,
|
|
||||||
szProgress,
|
|
||||||
sofar/1024,
|
|
||||||
MulDiv(100,sofar,cl),
|
|
||||||
cl/1024,
|
|
||||||
bps/1024,((bps*10)/1024)%10
|
|
||||||
);
|
|
||||||
if (remain) wsprintf(buf+lstrlen(buf),szRemaining,
|
|
||||||
remain,
|
|
||||||
rtext,
|
|
||||||
remain==1?"":szPlural
|
|
||||||
);
|
|
||||||
progress_callback(buf, sofar);
|
progress_callback(buf, sofar);
|
||||||
} else {
|
} else {
|
||||||
if (sofar < cl)
|
if (sofar < cl)
|
||||||
|
|
|
@ -26,6 +26,82 @@ int my_atoi(char *s)
|
||||||
return (int)v;
|
return (int)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Updated for int64 and simple bitwise operations
|
||||||
|
__int64 myatoi64(char *s)
|
||||||
|
{
|
||||||
|
__int64 v=0;
|
||||||
|
// Check for right input
|
||||||
|
if (!s) return 0;
|
||||||
|
if (*s == '0' && (s[1] == 'x' || s[1] == 'X'))
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int c=*(++s);
|
||||||
|
if (c >= '0' && c <= '9') c-='0';
|
||||||
|
else if (c >= 'a' && c <= 'f') c-='a'-10;
|
||||||
|
else if (c >= 'A' && c <= 'F') c-='A'-10;
|
||||||
|
else break;
|
||||||
|
v<<=4;
|
||||||
|
v+=c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*s == '0' && s[1] <= '7' && s[1] >= '0')
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int c=*(++s);
|
||||||
|
if (c >= '0' && c <= '7') c-='0';
|
||||||
|
else break;
|
||||||
|
v<<=3;
|
||||||
|
v+=c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int sign=0;
|
||||||
|
if (*s == '-') sign++; else s--;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int c=*(++s) - '0';
|
||||||
|
if (c < 0 || c > 9) break;
|
||||||
|
v*=10;
|
||||||
|
v+=c;
|
||||||
|
}
|
||||||
|
if (sign) v = -v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support for simple ORed expressions
|
||||||
|
if (*s == '|')
|
||||||
|
{
|
||||||
|
v |= myatoi64(s+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void myitoa64(__int64 i, char *buffer)
|
||||||
|
{
|
||||||
|
char buf[128], *b = buf;
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
*(buffer++) = '-';
|
||||||
|
i = -i;
|
||||||
|
}
|
||||||
|
if (i == 0) *(buffer++) = '0';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (i > 0)
|
||||||
|
{
|
||||||
|
*(b++) = '0' + ((char) (i%10));
|
||||||
|
i /= 10;
|
||||||
|
}
|
||||||
|
while (b > buf) *(buffer++) = *(--b);
|
||||||
|
}
|
||||||
|
*buffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void mini_memset(void *o,char i,int l)
|
void mini_memset(void *o,char i,int l)
|
||||||
{
|
{
|
||||||
char *oo=(char*)o;
|
char *oo=(char*)o;
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#define _UTIL_H_
|
#define _UTIL_H_
|
||||||
|
|
||||||
int my_atoi(char *p);
|
int my_atoi(char *p);
|
||||||
|
__int64 myatoi64(char *s);
|
||||||
|
void myitoa64(__int64 i, char *buffer);
|
||||||
void mini_memset(void *,char,int);
|
void mini_memset(void *,char,int);
|
||||||
void mini_memcpy(void *,void*,int);
|
void mini_memcpy(void *,void*,int);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue