NSIS/Contrib/Makensisw/update.cpp
anders_k 1768555f2b Just load the library
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7293 212acab6-be3b-0410-9dea-997c60f758d6
2021-08-17 18:30:33 +00:00

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));
}