
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7293 212acab6-be3b-0410-9dea-997c60f758d6
148 lines
4.8 KiB
C++
148 lines
4.8 KiB
C++
// Unicode support by Jim Park -- 08/20/2007
|
|
|
|
#include "makensisw.h"
|
|
#include "update.h"
|
|
#include <wininet.h>
|
|
#include "utils.h" // OpenUrlInDefaultBrowser
|
|
|
|
#define mbtitle "NSIS Update"
|
|
|
|
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 = LoadSysLibrary("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 = LoadSysLibrary("WinHTTP");
|
|
if (hMod && FormatMessageA(flags|FORMAT_MESSAGE_FROM_HMODULE, hMod, ec, 0, (LPSTR) &buf, 0, 0))
|
|
return buf;
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
static void InetWorkOnline(HINTERNET hInet)
|
|
{
|
|
//msdn.microsoft.com/en-us/library/Aa768170#Supporting Offline Browsing in Applications and Components
|
|
DWORD cbio = sizeof(DWORD), op32;
|
|
if (InternetQueryOption(hInet, INTERNET_OPTION_CONNECTED_STATE, &op32, &cbio))
|
|
{
|
|
if (INTERNET_STATE_DISCONNECTED_BY_USER & op32)
|
|
{
|
|
INTERNET_CONNECTED_INFO ci = { INTERNET_STATE_CONNECTED, 0 };
|
|
InternetSetOption(hInet, INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci));
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static DWORD CALLBACK UpdateCheckWebrequestThread(LPVOID ThreadParam)
|
|
{
|
|
char buf[300];
|
|
wsprintfA(buf, "%s%s", NSIS_UC_URL, g_sdata.brandingv);
|
|
|
|
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+1];
|
|
DWORD cbRecv;
|
|
gle = InetSynchronousReadFile(hConn, response, sizeof(response)-1, &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);
|
|
}
|
|
InternetCloseHandle(hInet);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
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.", mbtitle, MB_OK|MB_ICONSTOP);
|
|
return;
|
|
}
|
|
|
|
EnableMenuItem(g_sdata.menu, IDM_NSISUPDATE, MF_GRAYED);
|
|
DWORD tid;
|
|
CloseHandle(CreateThread(NULL, 0, UpdateCheckWebrequestThread, (LPVOID) g_sdata.hwnd, 0, &tid));
|
|
}
|