bug 776783 - build win32 wrapper program r=cjones
authorJohn Ford <jhford@mozilla.com>
Fri, 28 Sep 2012 16:25:20 -0700
changeset 108580 c1eccb33893206027726f19883845d54431bbe20
parent 108579 189a1aaac3451b00d45445accd808b33add4d22f
child 108581 b6a9cb1be492dc87926b1001fa6a1fdf795fea7c
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerscjones
bugs776783
milestone18.0a1
bug 776783 - build win32 wrapper program r=cjones
b2g/gaia/Makefile.in
b2g/gaia/run-b2g.cpp
--- a/b2g/gaia/Makefile.in
+++ b/b2g/gaia/Makefile.in
@@ -6,37 +6,38 @@ DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 GAIA_PATH := gaia/profile
 
+PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
 
-# We don't have a wrapper script on Windows yet
-ifneq ($(OS_ARCH),WINNT)
-PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
+ifeq ($(OS_ARCH),WINNT)
+CPPSRCS = run-b2g.cpp
+DEFINES += \
+  -DB2G_NAME=L\"$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)\" \
+  -DGAIA_PATH=L\"$(subst /,\\\\,$(GAIA_PATH))\" \
+  $(NULL)
+GAIA_MAKE=make
+else # Non-windows machines use the same wrapper program
 CSRCS = run-b2g.c
-
 DEFINES += \
   -DB2G_NAME=\"$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)\" \
   -DGAIA_PATH=\"$(GAIA_PATH)\" \
   $(NULL)
+GAIA_MAKE=$(MAKE)
+endif
 
 # This is needed to avoid making run-b2g depend on mozglue
 WRAP_LDFLAGS :=
-endif
 
 GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)
 
 include $(topsrcdir)/config/rules.mk
 
-
 libs::
-	# Below here is how Gaia gets built
-	# The Gaia build system freaks out when N > 1 for -jN
-	$(MAKE) -j1 -C $(GAIADIR) clean
-	$(MAKE) -j1 -C $(GAIADIR) profile GAIA_DOMAIN=desktop-builds.$(MOZ_APP_NAME).mozilla.org
+	$(GAIA_MAKE) -j1 -C $(GAIADIR) clean
+	$(GAIA_MAKE) -j1 -C $(GAIADIR) profile GAIA_DOMAIN=desktop-builds.$(MOZ_APP_NAME).mozilla.org
 	(cd $(GAIADIR)/profile && tar $(TAR_CREATE_FLAGS) - .) | (cd $(abspath $(DIST))/bin/$(GAIA_PATH) && tar -xf -)
 
-
-
new file mode 100644
--- /dev/null
+++ b/b2g/gaia/run-b2g.cpp
@@ -0,0 +1,102 @@
+#include <Windows.h>
+#include <Shlwapi.h>
+#include <strsafe.h>
+
+// Linker options
+#pragma comment(lib, "User32.lib")
+#pragma comment(lib, "shlwapi.lib")
+#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:wmainCRTStartup")
+
+#define NUM_MAX_PATH_BYTES sizeof(wchar_t) * MAX_PATH + 1
+#define PROFILE_ARG L" -profile "
+
+// Options that can be overridden at build time with -D
+#ifndef B2G_NAME
+#define B2G_NAME L"b2g.exe"
+#endif
+#ifndef GAIA_PATH
+#define GAIA_PATH L"gaia\\profile"
+#endif
+
+void error(wchar_t* msg){
+    MessageBoxW(NULL, msg, L"Error starting program", MB_OK | MB_ICONERROR);
+}
+
+/* This function takes a string which represents a windows path, orig.
+ * The file portion of the path is stripped off and replaced with the
+ * path component, file.  This function returns a string which represents
+ * a windows path with the modifications requested and needs to be freed
+ * explicitly by the calling function.
+ */
+wchar_t* make_path_with_leaf_file_name(wchar_t* orig, wchar_t* file){
+    wchar_t* buffer = (wchar_t*) malloc(NUM_MAX_PATH_BYTES);
+    if (!buffer) {
+        return NULL;
+    }
+    if (FAILED(StringCchCopyW(buffer, NUM_MAX_PATH_BYTES, orig))) {
+        error(L"Error copying string");
+        free(buffer);
+        buffer = NULL;
+    }
+    PathRemoveFileSpecW(buffer);
+    if (!PathAppendW(buffer, file)) {
+        error(L"Unable to append file to directory");
+        free(buffer);
+        buffer = NULL;
+    }
+    return buffer;
+}
+
+BOOL execute(wchar_t* binary_path, wchar_t* args, int cp_flags) {
+    STARTUPINFOW si;
+    PROCESS_INFORMATION pi;
+
+    ZeroMemory(&si, sizeof(si));
+    si.cb = sizeof(si);
+    ZeroMemory(&pi, sizeof(pi));
+    
+    if (!CreateProcessW(
+        binary_path,
+        args,
+        NULL,
+        NULL,
+        FALSE,
+        cp_flags,
+        NULL,
+        NULL,
+        &si,
+        &pi)){
+            error(L"Could not execute program");
+            return FALSE;
+    }
+
+    WaitForInputIdle(pi.hProcess, 0);
+    CloseHandle(pi.hProcess);
+    CloseHandle(pi.hThread);
+    return true;
+}
+
+int wmain(int argc, wchar_t *argv[], wchar_t *envp[]){
+    int cp_flags;
+    wchar_t* b2g_path = make_path_with_leaf_file_name(argv[0], B2G_NAME);
+    wchar_t* profile_path = make_path_with_leaf_file_name(argv[0], GAIA_PATH);
+	// 10 chars for the ' -profile ' portion of the argument
+    wchar_t* args = (wchar_t*) malloc(2 * NUM_MAX_PATH_BYTES + wcslen(PROFILE_ARG));
+    if (FAILED(StringCchPrintfW(args, NUM_MAX_PATH_BYTES, L"\"%ws\"%ws\"%ws\"", b2g_path, PROFILE_ARG, profile_path))) {
+        error(L"Could not create argument string");
+        ExitProcess(1);
+    }
+#ifdef SHOW_CONSOLE
+    cp_flags = 0;
+#else
+    cp_flags = DETACHED_PROCESS;
+#endif
+    if (!execute(b2g_path, args, cp_flags)) {
+        error(L"Failed to launch program");
+    }
+    free(profile_path);
+    free(b2g_path);
+    free(args);
+    profile_path = b2g_path = args = NULL;
+    
+}