MakeNSISW now uses WinInet when checking for updates
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6604 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
e58680c996
commit
873e860f57
20 changed files with 144 additions and 1650 deletions
|
@ -2,136 +2,146 @@
|
|||
|
||||
#include "makensisw.h"
|
||||
#include "update.h"
|
||||
#include "utils.h" // OpenUrlInDefaultBrowser
|
||||
|
||||
#include "jnetlib/httpget.h"
|
||||
#define mbtitle "NSIS Update"
|
||||
|
||||
static BOOL update_initialized = FALSE;
|
||||
|
||||
static JNL_AsyncDNS *g_dns = NULL;
|
||||
|
||||
void InitializeUpdate() {
|
||||
if (update_initialized)
|
||||
return;
|
||||
|
||||
update_initialized = TRUE;
|
||||
JNL::open_socketlib();
|
||||
g_dns = new JNL_AsyncDNS();
|
||||
static LPSTR InetGetErrorStringAllocA(DWORD ec)
|
||||
{
|
||||
LPSTR buf;
|
||||
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_IGNORE_INSERTS;
|
||||
if (FormatMessageA(flags|FORMAT_MESSAGE_FROM_SYSTEM, 0, ec, 0, (LPSTR) &buf, 0, 0))
|
||||
return buf;
|
||||
HMODULE hMod = GetModuleHandle(TEXT("WinInet"));
|
||||
if (hMod && FormatMessageA(flags|FORMAT_MESSAGE_FROM_HMODULE, hMod, ec, 0, (LPSTR) &buf, 0, 0))
|
||||
return buf;
|
||||
#if 0 // We are not using WinHttp* functions
|
||||
hMod = GetModuleHandle(TEXT("WinHTTP"));
|
||||
if (hMod && FormatMessageA(flags|FORMAT_MESSAGE_FROM_HMODULE, hMod, ec, 0, (LPSTR) &buf, 0, 0))
|
||||
return buf;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FinalizeUpdate() {
|
||||
if (!update_initialized)
|
||||
return;
|
||||
|
||||
delete g_dns;
|
||||
JNL::close_socketlib();
|
||||
}
|
||||
|
||||
int getProxyInfo(char *out) {
|
||||
DWORD v=0;
|
||||
HKEY hKey;
|
||||
if (RegOpenKeyExA(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",0,KEY_READ,&hKey) == ERROR_SUCCESS) {
|
||||
DWORD l = 4;
|
||||
DWORD t;
|
||||
if (RegQueryValueExA(hKey,"ProxyEnable",NULL,&t,(unsigned char *)&v,&l) == ERROR_SUCCESS && t == REG_DWORD) {
|
||||
l=8192;
|
||||
if (RegQueryValueExA(hKey,"ProxyServer",NULL,&t,(unsigned char *)out,&l ) != ERROR_SUCCESS || t != REG_SZ) {
|
||||
v=0;
|
||||
*out=0;
|
||||
}
|
||||
}
|
||||
else v=0;
|
||||
out[8192-1]=0;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
DWORD CALLBACK UpdateThread(LPVOID v) {
|
||||
#define RSZ 30
|
||||
int len;
|
||||
char response[RSZ], *r;
|
||||
char url[300];
|
||||
BOOL error = FALSE;
|
||||
static char pbuf[8192];
|
||||
char *p=NULL;
|
||||
*response = 0;
|
||||
|
||||
if (getProxyInfo(pbuf))
|
||||
static void InetWorkOnline(HINTERNET hInet)
|
||||
{
|
||||
//msdn.microsoft.com/library/default.asp?url=/workshop/components/offline/offline.asp#Supporting Offline Browsing in Applications and Components
|
||||
DWORD cbio = sizeof(DWORD), op32;
|
||||
if (InternetQueryOption(hInet, INTERNET_OPTION_CONNECTED_STATE, &op32, &cbio))
|
||||
{
|
||||
p=strstr(pbuf,"http=");
|
||||
if (!p) p=pbuf;
|
||||
else {
|
||||
p+=5;
|
||||
if (INTERNET_STATE_DISCONNECTED_BY_USER & op32)
|
||||
{
|
||||
INTERNET_CONNECTED_INFO ci = { INTERNET_STATE_CONNECTED, 0 };
|
||||
InternetSetOption(hInet, INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci));
|
||||
}
|
||||
char *tp=strstr(p,";");
|
||||
if (tp) *tp=0;
|
||||
char *p2=strstr(p,"=");
|
||||
if (p2) p=0; // we found the wrong proxy
|
||||
}
|
||||
}
|
||||
|
||||
InitializeUpdate();
|
||||
static DWORD InetSynchronousReadFile(HINTERNET hConn, void*Buffer, DWORD cbBuffer, DWORD*pcbReceived)
|
||||
{
|
||||
*pcbReceived = 0;
|
||||
for (DWORD cbio;;)
|
||||
{
|
||||
if (!cbBuffer)
|
||||
break;
|
||||
if (!InternetReadFile(hConn, Buffer, cbBuffer, &cbio))
|
||||
return GetLastError();
|
||||
if (!cbio)
|
||||
break; // EOF, we are done.
|
||||
Buffer = ((char*)Buffer) + cbio, cbBuffer -= cbio;
|
||||
(*pcbReceived) += cbio;
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
JNL_HTTPGet *get = new JNL_HTTPGet(g_dns,8192,(p&&p[0])?p:NULL);
|
||||
lstrcpyA(url,NSIS_UPDATE);
|
||||
lstrcatA(url,g_sdata.brandingv);
|
||||
static DWORD CALLBACK UpdateCheckWebrequestThread(LPVOID ThreadParam)
|
||||
{
|
||||
char buf[300];
|
||||
wsprintfA(buf, "%s%s", NSIS_UC_URL, g_sdata.brandingv);
|
||||
|
||||
lstrcpyA(response,"");
|
||||
get->addheader("User-Agent: MakeNSISw (jnetlib)");
|
||||
get->addheader("Accept:*/*");
|
||||
get->connect(url);
|
||||
while (1) {
|
||||
int st=get->run();
|
||||
if (st<0) { error = TRUE; break; }//error
|
||||
if (get->get_status()==2) {
|
||||
while( (len=get->bytes_available()) ) {
|
||||
char b[RSZ];
|
||||
if (len>RSZ) len=RSZ;
|
||||
if (lstrlenA(response)+len>RSZ) break;
|
||||
len=get->get_bytes(b,len);
|
||||
b[len]=0;
|
||||
lstrcatA(response,b);
|
||||
InternetAttemptConnect(0);
|
||||
UINT mbicon = MB_ICONINFORMATION;
|
||||
LPCSTR msg = NULL;
|
||||
HINTERNET hInet = InternetOpenA("MakeNSISw (WinInet)", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
DWORD gle = GetLastError();
|
||||
if (hInet)
|
||||
{
|
||||
InetWorkOnline(hInet);
|
||||
|
||||
// Note: InternetOpenUrlW does not handle the http headers in the same way, be careful if you stop forcing the A version
|
||||
static const CHAR httpheaders[] = "Accept:*/*\r\n";
|
||||
DWORD connflags = INTERNET_FLAG_NO_UI|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS;
|
||||
connflags |= INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_NO_COOKIES;
|
||||
connflags |= INTERNET_FLAG_PRAGMA_NOCACHE|INTERNET_FLAG_RELOAD;
|
||||
//if ((32|buf[4]) == 's') connflags |= INTERNET_FLAG_SECURE;
|
||||
HINTERNET hConn = InternetOpenUrlA(hInet, buf, httpheaders, -1, connflags, 0);
|
||||
gle = GetLastError();
|
||||
if (hConn)
|
||||
{
|
||||
char response[30];
|
||||
DWORD cbRecv;
|
||||
gle = InetSynchronousReadFile(hConn, response, sizeof(response), &cbRecv);
|
||||
if (!gle)
|
||||
{
|
||||
response[cbRecv] = '\0';
|
||||
switch(response[0])
|
||||
{
|
||||
case '0':
|
||||
msg = "There is no update available for NSIS at this time.";
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
if (cbRecv > 2 && '|' == response[1])
|
||||
{
|
||||
const char *reltypestr = '1' == response[0] ? "it" : "this preview release";
|
||||
wsprintfA(buf, "NSIS %.50s is now available. Would you like to download %s now?", response+2, reltypestr);
|
||||
mbicon = MB_ICONQUESTION, msg = buf;
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
default:
|
||||
gle = ERROR_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
InternetCloseHandle(hConn);
|
||||
}
|
||||
if (st==1) break; //closed
|
||||
InternetCloseHandle(hInet);
|
||||
}
|
||||
r = response;
|
||||
while (r&&*r) {
|
||||
if (*r=='\n') { *r = 0; break; }
|
||||
r++;
|
||||
}
|
||||
if (error) {
|
||||
char buf[1000];
|
||||
wsprintfA(buf, "There was a problem checking for an update. Please try again later.\n\nError: %s",get->geterrorstr());
|
||||
MessageBoxA(g_sdata.hwnd,buf,"NSIS Update",MB_OK|MB_ICONINFORMATION);
|
||||
}
|
||||
else if (*response=='1'&&lstrlenA(response)>2) {
|
||||
char buf[200];
|
||||
wsprintfA(buf, "NSIS %s is now available. Would you like to download it now?",response+2);
|
||||
if (MessageBoxA(g_sdata.hwnd,buf,"NSIS Update",MB_YESNO|MB_ICONINFORMATION)==IDYES) {
|
||||
ShellExecuteA(g_sdata.hwnd,"open",NSIS_DL_URL,NULL,NULL,SW_SHOWNORMAL);
|
||||
|
||||
HWND hwndOwner = (HWND) ThreadParam;
|
||||
// Hopefully we don't end up with a race where our main window has been closed
|
||||
// and the HWND has been reused just as this thread completes its work
|
||||
if (IsWindow(hwndOwner))
|
||||
{
|
||||
if (!msg)
|
||||
{
|
||||
LPSTR dynbuf = InetGetErrorStringAllocA(gle);
|
||||
wsprintfA(buf, "There was a problem checking for updates, please try again later.\n\nError: %u %.200s", gle, dynbuf ? dynbuf : "");
|
||||
mbicon = MB_ICONSTOP, msg = buf;
|
||||
LocalFree(dynbuf);
|
||||
}
|
||||
}
|
||||
else if (*response=='2'&&lstrlenA(response)>2) {
|
||||
char buf[200];
|
||||
wsprintfA(buf,"NSIS %s is now available. Would you like to download this preview release now?",response+2);
|
||||
if (MessageBoxA(g_sdata.hwnd,buf,"NSIS Update",MB_YESNO|MB_ICONINFORMATION)==IDYES) {
|
||||
ShellExecuteA(g_sdata.hwnd,"open",NSIS_DL_URL,NULL,NULL,SW_SHOWNORMAL);
|
||||
|
||||
UINT mbtype = MB_ICONQUESTION == mbicon ? MB_YESNO : MB_OK;
|
||||
int mbret = MessageBoxA(hwndOwner, msg, mbtitle, mbtype|mbicon);
|
||||
if (mbret == IDYES && mbtype == MB_YESNO)
|
||||
{
|
||||
OpenUrlInDefaultBrowser(hwndOwner, NSIS_DL_URL);
|
||||
}
|
||||
|
||||
EnableMenuItem(g_sdata.menu, IDM_NSISUPDATE, MF_ENABLED);
|
||||
}
|
||||
else MessageBoxA(g_sdata.hwnd,"There is no update available for NSIS at this time.","NSIS Update",MB_OK|MB_ICONINFORMATION);
|
||||
delete get;
|
||||
EnableMenuItem(g_sdata.menu,IDM_NSISUPDATE,MF_ENABLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (strstr(g_sdata.brandingv,"cvs"))
|
||||
void CheckForUpdate()
|
||||
{
|
||||
if (strstr(g_sdata.brandingv, "cvs"))
|
||||
{
|
||||
MessageBoxA(g_sdata.hwnd,"Cannot check for new version of nightly builds. To update, download a new nightly build.","NSIS Update",MB_OK|MB_ICONSTOP);
|
||||
MessageBoxA(g_sdata.hwnd, "Cannot check for new version of nightly builds. To update, download a new nightly build.", mbtitle, MB_OK|MB_ICONSTOP);
|
||||
return;
|
||||
}
|
||||
|
||||
EnableMenuItem(g_sdata.menu,IDM_NSISUPDATE,MF_GRAYED);
|
||||
EnableMenuItem(g_sdata.menu, IDM_NSISUPDATE, MF_GRAYED);
|
||||
DWORD tid;
|
||||
CloseHandle(CreateThread(NULL,0,UpdateThread,NULL,0,&tid));
|
||||
CloseHandle(CreateThread(NULL, 0, UpdateCheckWebrequestThread, (LPVOID) g_sdata.hwnd, 0, &tid));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue