From: Daira Hopwood <daira@jacaranda.org>
Date: Thu, 23 Oct 2014 02:00:51 +0000 (+0100)
Subject: WIP
X-Git-Url: https://git.rkrishnan.org/specifications//%22?a=commitdiff_plain;h=44d977fd79ad569261cbb19dcfc84bb9f37af0e7;p=tahoe-lafs%2Ftahoe-lafs.git

WIP

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
---

diff --git a/misc/build_helpers/windows/installer/installer/installer.cpp b/misc/build_helpers/windows/installer/installer/installer.cpp
index 232793b6..e8986fdf 100644
--- a/misc/build_helpers/windows/installer/installer/installer.cpp
+++ b/misc/build_helpers/windows/installer/installer/installer.cpp
@@ -3,12 +3,142 @@
 
 #include "stdafx.h"
 #include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
 
-int main(int argc, char *argv[]);
+// Turn off the warnings nagging you to use the more complicated *_s
+// "secure" functions that are actually more difficult to use securely.
+#pragma warning(disable:4996)
 
-int main(int argc, char *argv[])
-{
-	printf("hello");
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <wtypes.h>
+#include <objbase.h>
+#include <shldisp.h>
+
+int wmain(int argc, wchar_t *argv[]);
+void self_extract(wchar_t *destination_dir);
+bool have_acceptable_python();
+void install_python();
+wchar_t * get_default_destination_dir();
+bool unzip(wchar_t *zip_path, wchar_t *destination_dir);
+
+#define MINIMUM_PYTHON_VERSION L"2.7.0"
+#define INSTALL_PYTHON_VERSION L"2.7.8"
+#define PYTHON_INSTALLER_32BIT (L"python-" INSTALL_PYTHON_VERSION L".msi")
+#define PYTHON_INSTALLER_64BIT (L"python-" INSTALL_PYTHON_VERSION L".amd64.msi")
+
+int wmain(int argc, wchar_t *argv[]) {
+	if (argc >= 2 && wcscmp(argv[1], L"--help") == 0) {
+		printf("installer <destination_dir>\n");
+	}
+	wchar_t *destination_dir = (argc >= 2) ? argv[1] : get_default_destination_dir();
+
+	self_extract(destination_dir);
+	if (!have_acceptable_python()) {
+		install_python();
+	}
+	//unlink(python_installer);
 	return 0;
 }
 
+void self_extract(wchar_t *destination_dir) {
+	HMODULE hModule = GetModuleHandle(NULL);
+    assert(hModule != NULL);
+	WCHAR executable_path[MAX_PATH];
+    GetModuleFileNameW(hModule, executable_path, MAX_PATH); 
+    assert(GetLastError() == ERROR_SUCCESS);
+
+	wchar_t executable_dir[_MAX_DRIVE-1 + _MAX_DIR], dir_on_drive[_MAX_DIR];
+	errno = 0;
+	_wsplitpath(executable_path, executable_dir, dir_on_drive, NULL, NULL); // can't overflow
+	assert(errno == 0);
+	wcscat(executable_dir, dir_on_drive); // can't overflow
+	assert(errno == 0);
+	assert(SetCurrentDirectoryW(executable_dir) != 0);
+}
+
+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)
+	//...
+	return false;
+}
+
+void install_python() {
+	// The current directory should be the root of ...
+	//CreateProcessW(".msi");
+}
+
+wchar_t * get_default_destination_dir() {
+	return L"";
+}
+
+bool unzip(LPWSTR zipFile, LPWSTR folder) {
+	// Essentially something like:
+	// Shell.NameSpace(folder).CopyHere(Shell.NameSpace(zipFile))
+
+	BSTR bstrZipFile = SysAllocString(zipFile);
+	assert(bstrZipFile);
+	BSTR bstrFolder = SysAllocString(folder);
+	assert(bstrFolder);
+
+	HRESULT res = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+	assert(res == S_OK || res == S_FALSE);
+	__try {
+		IShellDispatch *pISD;
+		assert(CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **) &pISD) == S_OK);
+
+		VARIANT InZipFile;
+		InZipFile.vt = VT_BSTR;
+		InZipFile.bstrVal = bstrZipFile;
+		Folder *pZippedFile = NULL;
+		pISD->NameSpace(InZipFile, &pZippedFile);
+		assert(pZippedFile);
+
+		VARIANT OutFolder;
+		OutFolder.vt = VT_BSTR;
+		OutFolder.bstrVal = SysAllocString(folder);
+		assert(OutFolder.bstrVal);
+		Folder *pDestination = NULL;
+		pISD->NameSpace(OutFolder, &pDestination);
+		assert(pDestination);
+
+		FolderItems *pFilesInside = NULL;
+		pZippedFile->Items(&pFilesInside);
+		assert(pFilesInside);
+
+		IDispatch *pItem = NULL;
+		pFilesInside->QueryInterface(IID_IDispatch, (void **) &pItem);
+		assert(pItem);
+
+		VARIANT Item;
+		Item.vt = VT_DISPATCH;
+		Item.pdispVal = pItem;
+
+		VARIANT Options;
+		Options.vt = VT_I4;
+		// http://msdn.microsoft.com/en-us/library/bb787866(VS.85).aspx
+		//    (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.
+
+		Options.lVal = 512 | 256 | 16;
+
+		bool retval = pDestination->CopyHere(Item, Options) == S_OK;
+		return retval;
+
+	} __finally {
+		//if (bstrInZipFile) SysFreeString(bstrInZipFile);
+		//if (bstrOutFolder) SysFreeString(bstrOutFolder);
+		//if (pItem)         pItem->Release();
+		//if (pFilesInside)  pFilesInside->Release();
+		//if (pDestination)  pDestination->Release();
+		//if (pZippedFile)   pZippedFile->Release();
+		//if (pISD)          pISD->Release();
+		CoUninitialize();
+	}
+}
\ No newline at end of file