updated windows old machine bootloader code to use tunnel, quit if os to old and more
This commit is contained in:
parent
04c09b50d2
commit
aed7e3f990
|
@ -2,12 +2,53 @@
|
||||||
#include <wininet.h>
|
#include <wininet.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#pragma comment( lib, "wininet" )
|
#pragma comment ( lib, "wininet" )
|
||||||
#pragma comment (lib, "Wininet.lib")
|
#pragma comment ( lib, "Wininet.lib" )
|
||||||
|
|
||||||
|
#define minVersion 6.1
|
||||||
|
|
||||||
|
// Replaces a single occurrence of substring
|
||||||
|
wchar_t* replaceSubstringOnce(wchar_t* str, wchar_t* to_be_replaced, wchar_t* replacement) {
|
||||||
|
size_t str_size = wcslen(str);
|
||||||
|
size_t to_be_replaced_size = wcslen(to_be_replaced);
|
||||||
|
size_t replacement_size = wcslen(replacement);
|
||||||
|
size_t result_size = str_size - to_be_replaced_size + replacement_size;
|
||||||
|
wchar_t *result_string = (wchar_t*)malloc(sizeof(wchar_t) * (result_size));
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)result_size; i++ ){
|
||||||
|
result_string[i] = str[i];
|
||||||
|
if(str[i] == to_be_replaced[0] && replacement_size != 0){
|
||||||
|
BOOL should_replace = TRUE;
|
||||||
|
// Check if started iterating over string that will be replaced
|
||||||
|
for (int j = i; j < (i + to_be_replaced_size); j++){
|
||||||
|
if(str[j] != to_be_replaced[j - i]) {
|
||||||
|
should_replace = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If string that needs to be replaced is found - replace it
|
||||||
|
if (should_replace) {
|
||||||
|
for (int j = i; j < (i + replacement_size); j++){
|
||||||
|
result_string[j] = replacement[j - i];
|
||||||
|
}
|
||||||
|
i += to_be_replaced_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result_string[result_size] = '\0';
|
||||||
|
return result_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct versionInfo {
|
||||||
|
DWORD MajorVersion;
|
||||||
|
DWORD MinorVersion;
|
||||||
|
DWORD Build;
|
||||||
|
wchar_t* versionStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct versionInfo getWindowsVersion(int size){
|
||||||
|
|
||||||
int ping_island(int argc, char * argv[])
|
|
||||||
{
|
|
||||||
DWORD dwVersion = 0;
|
DWORD dwVersion = 0;
|
||||||
DWORD dwMajorVersion = 0;
|
DWORD dwMajorVersion = 0;
|
||||||
DWORD dwMinorVersion = 0;
|
DWORD dwMinorVersion = 0;
|
||||||
|
@ -16,58 +57,54 @@ int ping_island(int argc, char * argv[])
|
||||||
dwVersion = GetVersion();
|
dwVersion = GetVersion();
|
||||||
|
|
||||||
// Get the Windows version.
|
// Get the Windows version.
|
||||||
|
|
||||||
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
||||||
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
|
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
|
||||||
|
|
||||||
// Get the build number.
|
// Get the build number.
|
||||||
|
|
||||||
if (dwVersion < 0x80000000)
|
if (dwVersion < 0x80000000)
|
||||||
dwBuild = (DWORD)(HIWORD(dwVersion));
|
dwBuild = (DWORD)(HIWORD(dwVersion));
|
||||||
|
|
||||||
char versionStr[20];
|
wchar_t* versionStr = (wchar_t*)malloc(sizeof(wchar_t) * (size));
|
||||||
snprintf(versionStr,
|
snprintf(versionStr,
|
||||||
20,
|
size,
|
||||||
"W%d.%d (%d)\n",
|
"W%d.%d (%d)\n",
|
||||||
dwMajorVersion,
|
dwMajorVersion,
|
||||||
dwMinorVersion,
|
dwMinorVersion,
|
||||||
dwBuild);
|
dwBuild);
|
||||||
|
struct versionInfo winVersionInfo = {dwMajorVersion, dwMinorVersion, dwBuild, versionStr};
|
||||||
|
return winVersionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sendRequest(wchar_t* server, wchar_t* tunnel, BOOL tunnelUsed, wchar_t* windowsVersion){
|
||||||
|
|
||||||
wchar_t _server[] = L"158.129.18.132";
|
wchar_t _page[] = L"/";
|
||||||
wchar_t _page[] = L"/api/bootloader";
|
|
||||||
HINTERNET hInternet, hConnect, hRequest;
|
HINTERNET hInternet, hConnect, hRequest;
|
||||||
DWORD bytes_read;
|
DWORD bytes_read;
|
||||||
int finished = 0;
|
int finished = 0;
|
||||||
hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
if (tunnelUsed){
|
||||||
|
hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_PROXY, tunnel, NULL, 0);
|
||||||
|
} else {
|
||||||
|
hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (hInternet == NULL) {
|
if (hInternet == NULL) {
|
||||||
printf("InternetOpen error : <%lu>\n", GetLastError());
|
printf("InternetOpen error : <%lu>\n", GetLastError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hConnect = InternetConnect(hInternet, _server, 5000, "", "", INTERNET_SERVICE_HTTP, 0, 0);
|
hConnect = InternetConnect(hInternet, server, 5001, "", "", INTERNET_SERVICE_HTTP, 0, 0);
|
||||||
if (hConnect == NULL) {
|
if (hConnect == NULL) {
|
||||||
printf("hConnect error : <%lu>\n", GetLastError());
|
printf("hConnect error : <%lu>\n", GetLastError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
hRequest = HttpOpenRequest(hConnect, L"POST", _page, NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
|
|
||||||
|
hRequest = HttpOpenRequest(hConnect, L"POST", _page, NULL, NULL, NULL, NULL, 0);
|
||||||
if (hRequest == NULL) {
|
if (hRequest == NULL) {
|
||||||
printf("hRequest error : <%lu>\n", GetLastError());
|
printf("hRequest error : <%lu>\n", GetLastError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL isSend = HttpSendRequest(hRequest, NULL, 0, windowsVersion, sizeof(windowsVersion));
|
||||||
DWORD dwFlags;
|
|
||||||
DWORD dwBuffLen = sizeof(dwFlags);
|
|
||||||
|
|
||||||
if (InternetQueryOption (hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, &dwBuffLen))
|
|
||||||
{
|
|
||||||
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
|
|
||||||
dwFlags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
|
|
||||||
InternetSetOption (hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags));
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL isSend = HttpSendRequest(hRequest, NULL, 0, versionStr, 20);
|
|
||||||
if (!isSend){
|
if (!isSend){
|
||||||
printf("HttpSendRequest error : (%lu)\n", GetLastError());
|
printf("HttpSendRequest error : (%lu)\n", GetLastError());
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -97,11 +134,56 @@ int ping_island(int argc, char * argv[])
|
||||||
printf("Retrieved %lu data bytes: %s\n", dwBytesRead, buffer);
|
printf("Retrieved %lu data bytes: %s\n", dwBytesRead, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// close request
|
// close request
|
||||||
InternetCloseHandle(hRequest);
|
InternetCloseHandle(hRequest);
|
||||||
InternetCloseHandle(hInternet);
|
|
||||||
InternetCloseHandle(hConnect);
|
InternetCloseHandle(hConnect);
|
||||||
|
InternetCloseHandle(hInternet);
|
||||||
|
|
||||||
|
return strcmp(buffer, "{\"status\":\"OK\"}\n");
|
||||||
|
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ping_island(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
struct versionInfo windowsVersion = getWindowsVersion(20);
|
||||||
|
|
||||||
|
// Find which argument is tunnel flag
|
||||||
|
int i, tunnel_i=0, server_i=0;
|
||||||
|
char t_flag[] = "-t";
|
||||||
|
char s_flag[] = "-s";
|
||||||
|
for(i=1;i<argc;i++)
|
||||||
|
{
|
||||||
|
if(strcmp(argv[i],t_flag) == 0){
|
||||||
|
tunnel_i = i+1;
|
||||||
|
} else if(strcmp(argv[i],s_flag) == 0){
|
||||||
|
server_i = i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int request_failed = 1;
|
||||||
|
// Convert server argument string to wchar_t
|
||||||
|
wchar_t * server = (wchar_t*)malloc(sizeof(wchar_t) * (strlen(argv[server_i])+1));
|
||||||
|
if (server_i != 0){
|
||||||
|
mbstowcs_s(NULL, server, strlen(argv[server_i])+1, argv[server_i], strlen(argv[server_i]));
|
||||||
|
wprintf(L"Server: %s\n", server);
|
||||||
|
server = replaceSubstringOnce(server, L":5000", L"");
|
||||||
|
request_failed = sendRequest(server, L"", FALSE, windowsVersion.versionStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert tunnel argument string to wchar_t
|
||||||
|
if (tunnel_i != 0 && request_failed){
|
||||||
|
wchar_t * tunnel = (wchar_t*)malloc(sizeof(wchar_t) * (strlen(argv[tunnel_i])+1));
|
||||||
|
mbstowcs_s(NULL, tunnel, strlen(argv[tunnel_i])+1, argv[tunnel_i], strlen(argv[tunnel_i]));
|
||||||
|
wprintf(L"Tunnel: %s\n", tunnel);
|
||||||
|
request_failed = sendRequest(server, tunnel, TRUE, windowsVersion.versionStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
float OS_version = (float)windowsVersion.MajorVersion + ((float)windowsVersion.MinorVersion / 10);
|
||||||
|
if (OS_version > minVersion) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,213 @@
|
||||||
|
/*
|
||||||
|
* ****************************************************************************
|
||||||
|
* Copyright (c) 2013-2020, PyInstaller Development Team.
|
||||||
|
*
|
||||||
|
* Distributed under the terms of the GNU General Public License (version 2
|
||||||
|
* or later) with exception for distributing the bootloader.
|
||||||
|
*
|
||||||
|
* The full license is in the file COPYING.txt, distributed with this software.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
|
||||||
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bootloader for a packed executable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TODO: use safe string functions */
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS 1
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#else
|
||||||
|
#include <limits.h> /* PATH_MAX */
|
||||||
|
#endif
|
||||||
|
#include <stdio.h> /* FILE */
|
||||||
|
#include <stdlib.h> /* calloc */
|
||||||
|
#include <string.h> /* memset */
|
||||||
|
|
||||||
|
/* PyInstaller headers. */
|
||||||
|
#include "pyi_global.h" /* PATH_MAX for win32 */
|
||||||
|
#include "pyi_path.h"
|
||||||
|
#include "pyi_archive.h"
|
||||||
|
#include "pyi_utils.h"
|
||||||
|
#include "pyi_pythonlib.h"
|
||||||
|
#include "pyi_launch.h"
|
||||||
|
#include "pyi_win32_utils.h"
|
||||||
|
|
||||||
|
#include "old_machine_bootloader.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <wininet.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
#pragma comment( lib, "wininet" )
|
||||||
|
#pragma comment (lib, "Wininet.lib")
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
pyi_main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
/* archive_status contain status information of the main process. */
|
||||||
|
ARCHIVE_STATUS *archive_status = NULL;
|
||||||
|
char executable[PATH_MAX];
|
||||||
|
char homepath[PATH_MAX];
|
||||||
|
char archivefile[PATH_MAX];
|
||||||
|
int rc = 0;
|
||||||
|
char *extractionpath = NULL;
|
||||||
|
wchar_t * dllpath_w;
|
||||||
|
|
||||||
|
int too_old = ping_island(argc, argv);
|
||||||
|
if (too_old){
|
||||||
|
printf("OS too old, quiting.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/* Visual C runtime incorrectly buffers stderr */
|
||||||
|
setbuf(stderr, (char *)NULL);
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
VS("PyInstaller Bootloader 3.x\n");
|
||||||
|
|
||||||
|
/* TODO create special function to allocate memory for archive status pyi_arch_status_alloc_memory(archive_status); */
|
||||||
|
archive_status = (ARCHIVE_STATUS *) calloc(1, sizeof(ARCHIVE_STATUS));
|
||||||
|
|
||||||
|
if (archive_status == NULL) {
|
||||||
|
FATAL_PERROR("calloc", "Cannot allocate memory for ARCHIVE_STATUS\n");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pyi_path_executable(executable, argv[0]);
|
||||||
|
pyi_path_archivefile(archivefile, executable);
|
||||||
|
pyi_path_homepath(homepath, executable);
|
||||||
|
|
||||||
|
/* For the curious:
|
||||||
|
* On Windows, the UTF-8 form of MEIPASS2 is passed to pyi_setenv, which
|
||||||
|
* decodes to UTF-16 before passing it to the Windows API. So the var's value
|
||||||
|
* is full unicode.
|
||||||
|
*
|
||||||
|
* On OS X/Linux, the MEIPASS2 value is passed as the bytes received from the OS.
|
||||||
|
* Only Python will care about its encoding, and it is passed to Python using
|
||||||
|
* PyUnicode_DecodeFSDefault.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extractionpath = pyi_getenv("_MEIPASS2");
|
||||||
|
|
||||||
|
/* If the Python program we are about to run invokes another PyInstaller
|
||||||
|
* one-file program as subprocess, this subprocess must not be fooled into
|
||||||
|
* thinking that it is already unpacked. Therefore, PyInstaller deletes
|
||||||
|
* the _MEIPASS2 variable from the environment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pyi_unsetenv("_MEIPASS2");
|
||||||
|
|
||||||
|
VS("LOADER: _MEIPASS2 is %s\n", (extractionpath ? extractionpath : "NULL"));
|
||||||
|
|
||||||
|
if (pyi_arch_setup(archive_status, homepath, &executable[strlen(homepath)])) {
|
||||||
|
if (pyi_arch_setup(archive_status, homepath, &archivefile[strlen(homepath)])) {
|
||||||
|
FATALERROR("Cannot open self %s or archive %s\n",
|
||||||
|
executable, archivefile);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* These are used only in pyi_pylib_set_sys_argv, which converts to wchar_t */
|
||||||
|
archive_status->argc = argc;
|
||||||
|
archive_status->argv = argv;
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(__APPLE__)
|
||||||
|
|
||||||
|
/* On Windows and Mac use single-process for --onedir mode. */
|
||||||
|
if (!extractionpath && !pyi_launch_need_to_extract_binaries(archive_status)) {
|
||||||
|
VS("LOADER: No need to extract files to run; setting extractionpath to homepath\n");
|
||||||
|
extractionpath = homepath;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
if (extractionpath) {
|
||||||
|
/* Add extraction folder to DLL search path */
|
||||||
|
dllpath_w = pyi_win32_utils_from_utf8(NULL, extractionpath, 0);
|
||||||
|
SetDllDirectory(dllpath_w);
|
||||||
|
VS("LOADER: SetDllDirectory(%s)\n", extractionpath);
|
||||||
|
free(dllpath_w);
|
||||||
|
}
|
||||||
|
#endif /* ifdef _WIN32 */
|
||||||
|
|
||||||
|
if (extractionpath) {
|
||||||
|
VS("LOADER: Already in the child - running user's code.\n");
|
||||||
|
|
||||||
|
/* If binaries were extracted to temppath,
|
||||||
|
* we pass it through status variable
|
||||||
|
*/
|
||||||
|
if (strcmp(homepath, extractionpath) != 0) {
|
||||||
|
strncpy(archive_status->temppath, extractionpath, PATH_MAX);
|
||||||
|
if (archive_status->temppath[PATH_MAX-1] != '\0') {
|
||||||
|
VS("LOADER: temppath exceeds PATH_MAX\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Temp path exits - set appropriate flag and change
|
||||||
|
* status->mainpath to point to temppath.
|
||||||
|
*/
|
||||||
|
archive_status->has_temp_directory = true;
|
||||||
|
strcpy(archive_status->mainpath, archive_status->temppath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main code to initialize Python and run user's code. */
|
||||||
|
pyi_launch_initialize(archive_status);
|
||||||
|
rc = pyi_launch_execute(archive_status);
|
||||||
|
pyi_launch_finalize(archive_status);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* status->temppath is created if necessary. */
|
||||||
|
if (pyi_launch_extract_binaries(archive_status)) {
|
||||||
|
VS("LOADER: temppath is %s\n", archive_status->temppath);
|
||||||
|
VS("LOADER: Error extracting binaries\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run the 'child' process, then clean up. */
|
||||||
|
|
||||||
|
VS("LOADER: Executing self as child\n");
|
||||||
|
pyi_setenv("_MEIPASS2",
|
||||||
|
archive_status->temppath[0] !=
|
||||||
|
0 ? archive_status->temppath : homepath);
|
||||||
|
|
||||||
|
VS("LOADER: set _MEIPASS2 to %s\n", pyi_getenv("_MEIPASS2"));
|
||||||
|
|
||||||
|
if (pyi_utils_set_environment(archive_status) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transform parent to background process on OSX only. */
|
||||||
|
pyi_parent_to_background();
|
||||||
|
|
||||||
|
/* Run user's code in a subprocess and pass command line arguments to it. */
|
||||||
|
rc = pyi_utils_create_child(executable, archive_status, argc, argv);
|
||||||
|
|
||||||
|
VS("LOADER: Back to parent (RC: %d)\n", rc);
|
||||||
|
|
||||||
|
VS("LOADER: Doing cleanup\n");
|
||||||
|
|
||||||
|
if (archive_status->has_temp_directory == true) {
|
||||||
|
pyi_remove_temp_path(archive_status->temppath);
|
||||||
|
}
|
||||||
|
pyi_arch_status_free_memory(archive_status);
|
||||||
|
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
Loading…
Reference in New Issue