From 448d0df6719797426d796ce639055214a716de37 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Mon, 27 Oct 2014 02:36:55 +0000 Subject: [PATCH] WIP. Signed-off-by: Daira Hopwood --- .../windows/installer/installer/installer.cpp | 81 +++++++++++++------ 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/misc/build_helpers/windows/installer/installer/installer.cpp b/misc/build_helpers/windows/installer/installer/installer.cpp index e17bb26a..2baa942d 100644 --- a/misc/build_helpers/windows/installer/installer/installer.cpp +++ b/misc/build_helpers/windows/installer/installer/installer.cpp @@ -17,12 +17,14 @@ int wmain(int argc, wchar_t *argv[]); wchar_t * get_default_destination_dir(); +void initialize_com(); void self_extract(wchar_t *destination_dir); void unzip_from_executable(wchar_t *executable_path, wchar_t *destination_dir); size_t read_uint32_le(unsigned char *b); void unzip(wchar_t *zip_path, wchar_t *destination_dir); bool have_acceptable_python(); void install_python(wchar_t *python_installer_dir); +void execute(wchar_t *command, wchar_t *arguments, wchar_t *stdout_buf, size_t stdout_size); #define fail_unless(x, s) if (!(x)) { fail(s); } void fail(char *s); @@ -47,6 +49,8 @@ int wmain(int argc, wchar_t *argv[]) { } wchar_t *destination_dir = (argc >= 2) ? argv[1] : get_default_destination_dir(); + initialize_com(); + self_extract(destination_dir); //unzip(L"C:\\tahoe\\allmydata-tahoe-1.10.0c1.zip", destination_dir); @@ -62,6 +66,16 @@ wchar_t * get_default_destination_dir() { return L"C:\\tahoe\\windowstest"; } +void initialize_com() { + // CoInitializeEx: + HRESULT res = CoInitializeEx(NULL, 0); + fail_unless(res == S_OK || res == S_FALSE, "Could not initialize COM."); + + // Despite what the documentation says, we don't need to call CoUninitialize because + // any resources will be cleaned up on process exit, and there will be no pending COM + // messages at that point. +} + void self_extract(wchar_t *destination_dir) { wchar_t executable_path[MAX_PATH]; @@ -123,7 +137,7 @@ void unzip_from_executable(wchar_t *executable_path, wchar_t *destination_dir) { size_t cd_length = read_uint32_le(end_data + 12); size_t cd_offset = read_uint32_le(end_data + 16); - __int64 zip_length = cd_offset + cd_length + sizeof_eocd; + __int64 zip_length = (__int64) cd_offset + cd_length + sizeof_eocd; fail_unless(zip_length <= 0x7FFFFFFFi64, "Cannot copy a zip file >= 2 GiB."); fseek(f, -(off_t) zip_length, SEEK_END); @@ -133,11 +147,11 @@ void unzip_from_executable(wchar_t *executable_path, wchar_t *destination_dir) { const wchar_t tmp_filename[] = L"tahoe-lafs.zip"; // FIXME make this more unique. wchar_t tmp_path[MAX_PATH]; DWORD len = GetTempPathW(MAX_PATH, tmp_path); - fail_unless(len > 0 && len < MAX_PATH - wcslen(tmp_filename), - "Could not obtain temporary directory path."); + fail_unless(len > 0, "Could not obtain temporary directory path."); + fail_unless(len < MAX_PATH - wcslen(tmp_filename), "Temporary directory path is too long."); wcscpy(tmp_path + len, tmp_filename); - FILE *tmp_file = _wfopen(tmp_path, L"wb"); + FILE *tmp_file = _wfopen(tmp_path, L"wbTD"); // TD => short-lived temporary file unsigned char buf[16384]; size_t remaining_length = (size_t) zip_length; while (remaining_length > 0) { @@ -151,6 +165,7 @@ void unzip_from_executable(wchar_t *executable_path, wchar_t *destination_dir) { remaining_length -= chunk_length; } fclose(tmp_file); + fclose(f); unzip(tmp_path, destination_dir); } @@ -164,9 +179,8 @@ size_t read_uint32_le(unsigned char *b) { } void unzip(wchar_t *zip_path, wchar_t *destination_dir) { - // Based on - - wprintf(L"Extracting %ls\nto %ls\n", zip_path, destination_dir); + // Based loosely on + // . // SysAllocString: // BSTR: @@ -181,13 +195,9 @@ void unzip(wchar_t *zip_path, wchar_t *destination_dir) { destination_dir_var.bstrVal = SysAllocString(destination_dir); fail_unless(destination_dir_var.bstrVal != NULL, "Could not allocate string for destination directory path."); - // CoInitializeEx: - HRESULT res = CoInitializeEx(NULL, 0); - fail_unless(res == S_OK || res == S_FALSE, "Could not initialize COM."); - // CoCreateInstance: IShellDispatch *shell; - res = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **) &shell); + HRESULT res = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **) &shell); fail_unless(res == S_OK, "Could not create Shell instance."); // Folder.NameSpace: @@ -203,10 +213,6 @@ void unzip(wchar_t *zip_path, wchar_t *destination_dir) { zip_folder->Items(&zip_folderitems); fail_unless(zip_folderitems != NULL, "Could not create zip FolderItems object."); - long files_count = 0; - zip_folderitems->get_Count(&files_count); - printf("count %d\n", files_count); - VARIANT zip_idispatch_var; zip_idispatch_var.vt = VT_DISPATCH; zip_idispatch_var.pdispVal = NULL; @@ -214,11 +220,11 @@ void unzip(wchar_t *zip_path, wchar_t *destination_dir) { fail_unless(zip_idispatch_var.pdispVal != NULL, "Could not create IDispatch for zip FolderItems object."); // Folder.CopyHere: - // (4) Do not display a progress dialog box. // (16) Respond with "Yes to All" for any dialog box that is displayed. // (256) Display a progress dialog box but do not show the file names. // (512) Do not confirm the creation of a new directory if the operation requires one to be created. // (1024) Do not display a user interface if an error occurs. + // These options are ignored on Windows XP. VARIANT options_var; options_var.vt = VT_I4; options_var.lVal = 16 | 256 | 512 | 1024; @@ -236,21 +242,42 @@ void unzip(wchar_t *zip_path, wchar_t *destination_dir) { destination_folder->Release(); zip_folder->Release(); shell->Release(); - - // CoUninitialize: - CoUninitialize(); } bool have_acceptable_python() { printf("Checking for Python 2.7..."); - //key = OpenKey(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE) - //key = OpenKey(HKEY_CURRENT_USER, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE) - //... + // SearchPathW: + + wchar_t python_exe_path[MAX_PATH]; + DWORD res = SearchPathW(NULL, L"python.exe", NULL, MAX_PATH, python_exe_path, NULL); + if (res == 0 || res >= MAX_PATH) { + return false; + } + //execute(python_exe_path, L"--version"); + //execute(python_exe_path, L"setup.py scriptsetup --allusers"); + HKEY environment_key; + + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", + 0, KEY_QUERY_VALUE, &environment_key) != ERROR_SUCCESS) { + return false; + } + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", + 0, KEY_QUERY_VALUE, &environment_key) != ERROR_SUCCESS) { + return false; + } + return false; } +void execute(wchar_t *command, wchar_t *arguments, wchar_t *stdout_buf, size_t stdout_size) { + CreateProcessW(command, arguments, NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL); +} + void install_python(wchar_t *python_installer_dir) { wchar_t installer_wildcard[] = L"\\*.msi"; + if (python_installer_dir[wcslen(python_installer_dir)-1] == '\\') { + wcscpy(installer_wildcard, L"*.msi"); + } wchar_t installer_pattern[MAX_PATH]; fail_unless(wcslen(python_installer_dir) < MAX_PATH - wcslen(installer_wildcard), "Could not construct pattern for Python installer.") @@ -264,9 +291,11 @@ void install_python(wchar_t *python_installer_dir) { fail_unless(wcslen(python_installer_dir) < MAX_PATH - wcslen(find_data.cFileName), "Could not construct path to Python installer.") - wcscpy(installer_pattern, python_installer_dir); - wcscat(installer_pattern, find_data.cFileName); - //CreateProcessW(".msi"); + + wchar_t installer_path[MAX_PATH]; + wcscpy(installer_path, python_installer_dir); + wcscat(installer_path, find_data.cFileName); + //execute(installer_path, L""); } void fail(char *s) { -- 2.45.2