Bug 502933: 7z archive implementation to replace the CAB installer for Windows Mobile, r=crowder
authorAlex Pahotkin <alexp@mozilla.com>
Fri, 13 Nov 2009 15:03:31 -0800
changeset 34846 57e57190f52087de4f45cca1784d137b8a5e9f17
parent 34845 20d4d539beb1a49e7ec2c0451e8cbe3d790924a1
child 34847 0b3c29bf0fb89bec1c86f5ed97ec238a5327f9fd
push idunknown
push userunknown
push dateunknown
reviewerscrowder
bugs502933
milestone1.9.3a1pre
Bug 502933: 7z archive implementation to replace the CAB installer for Windows Mobile, r=crowder
toolkit/mozapps/Makefile.in
toolkit/mozapps/installer/wince/Makefile.in
toolkit/mozapps/installer/wince/ns7zipExtractor.cpp
toolkit/mozapps/installer/wince/ns7zipExtractor.h
toolkit/mozapps/installer/wince/nsArchiveExtractor.cpp
toolkit/mozapps/installer/wince/nsArchiveExtractor.h
toolkit/mozapps/installer/wince/nsInstaller.cpp
toolkit/mozapps/installer/wince/nsInstaller.h
toolkit/mozapps/installer/wince/nsInstallerDlg.cpp
toolkit/mozapps/installer/wince/nsInstallerDlg.h
toolkit/mozapps/installer/wince/nsInstallerppc.rc
toolkit/mozapps/installer/wince/nsInstallerppc.rc2
toolkit/mozapps/installer/wince/nsSetupStrings.cpp
toolkit/mozapps/installer/wince/nsSetupStrings.h
toolkit/mozapps/installer/wince/nsSetupStrings.inc
toolkit/mozapps/installer/wince/readme.txt
toolkit/mozapps/installer/wince/resourceppc.h
toolkit/mozapps/installer/wince/uninstall/Makefile.in
toolkit/mozapps/installer/wince/uninstall/Uninstall.cpp
toolkit/mozapps/installer/wince/xulrunnerinstaller.ico
toolkit/mozapps/update/src/updater/readstrings.cpp
toolkit/mozapps/update/src/updater/readstrings.h
--- a/toolkit/mozapps/Makefile.in
+++ b/toolkit/mozapps/Makefile.in
@@ -39,10 +39,16 @@
 DEPTH   = ../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 DIRS = downloads extensions update xpinstall plugins handling shared
+ 
+ifeq ($(OS_ARCH),WINCE)
+ifdef WINCE_WINDOWS_MOBILE
+DIRS += installer/wince
+endif
+endif
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/Makefile.in
@@ -0,0 +1,76 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Fennec Installer for WinCE.
+#
+# The Initial Developer of the Original Code is The Mozilla Foundation.
+#
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Mozilla Foundation <http://www.mozilla.org/>. All Rights Reserved.
+#
+# Contributor(s): 
+#   Alex Pakhotin <alexp@mozilla.com> (original author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH     = ../../../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+export NO_SHUNT = 1
+USE_STATIC_LIBS = 1
+
+PROGRAM   = xulrunner-stub-installer.sfx
+
+REQUIRES  = lib7z
+
+CPPSRCS = \
+	nsInstaller.cpp \
+	nsInstallerDlg.cpp \
+	nsArchiveExtractor.cpp \
+	ns7zipExtractor.cpp \
+	nsSetupStrings.cpp \
+	$(srcdir)/../../update/src/updater/readstrings.cpp \
+	$(NULL)
+
+LOCAL_INCLUDES += -I$(srcdir)/../../update/src/updater
+
+RCINCLUDE = nsInstallerppc.rc
+
+DEFINES += -D_UNICODE
+
+LIBS += $(DIST)/lib/7z.lib
+
+OS_LIBS += aygshell.lib commctrl.lib note_prj.lib oleaut32.lib ole32.lib libcmt.lib coredll.lib corelibc.lib
+
+WIN32_EXE_LDFLAGS += -ENTRY:WinMain
+
+DIRS += uninstall
+
+include $(topsrcdir)/config/rules.mk
+
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/ns7zipExtractor.cpp
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "wtypes.h"
+#include "nsArchiveExtractor.h"
+#include "ns7zipExtractor.h"
+#include "7zLib.h"
+
+static nsExtractorProgress *g_pProgress = NULL;
+
+static void ExtractProgressCallback(int nPercentComplete)
+{
+  if (g_pProgress)
+  {
+    g_pProgress->Progress(nPercentComplete);
+  }
+}
+
+static void ShowError()
+{
+  MessageBoxW(GetForegroundWindow(), GetExtractorError(), L"Extractor", MB_OK|MB_ICONERROR);
+}
+
+ns7zipExtractor::ns7zipExtractor(const WCHAR *sArchiveName, DWORD dwSfxStubSize, nsExtractorProgress *pProgress) :
+  nsArchiveExtractor(sArchiveName, dwSfxStubSize, pProgress)
+{
+  g_pProgress = pProgress;
+}
+
+ns7zipExtractor::~ns7zipExtractor()
+{
+  g_pProgress = NULL;
+}
+
+int ns7zipExtractor::Extract(const WCHAR *sDestinationDir)
+{
+  int res = SzExtractSfx(m_sArchiveName, m_dwSfxStubSize, NULL, sDestinationDir, ExtractProgressCallback);
+  if (res != 0)
+    ShowError();
+  return res;
+}
+
+int ns7zipExtractor::ExtractFile(const WCHAR *sFileName, const WCHAR *sDestinationDir)
+{
+  int res = SzExtractSfx(m_sArchiveName, m_dwSfxStubSize, sFileName, sDestinationDir, NULL);
+  if (res != 0)
+    ShowError();
+  return res;
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/ns7zipExtractor.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#pragma once
+
+#include "nsArchiveExtractor.h"
+
+class ns7zipExtractor : public nsArchiveExtractor
+{
+public:
+  ns7zipExtractor(const WCHAR *sArchiveName, DWORD dwSfxStubSize, nsExtractorProgress *pProgress);
+  virtual ~ns7zipExtractor();
+
+  virtual int Extract(const WCHAR *sDestinationDir);
+  virtual int ExtractFile(const WCHAR *sFileName, const WCHAR *sDestinationDir);
+};
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsArchiveExtractor.cpp
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "wtypes.h"
+#include "nsArchiveExtractor.h"
+
+nsArchiveExtractor::nsArchiveExtractor(const WCHAR *sArchiveName, DWORD dwSfxStubSize, nsExtractorProgress *pProgress) :
+  m_sArchiveName(NULL), m_pProgress(pProgress), m_dwSfxStubSize(dwSfxStubSize)
+{
+  if (sArchiveName)
+    m_sArchiveName = wcsdup(sArchiveName);
+}
+
+nsArchiveExtractor::~nsArchiveExtractor()
+{
+  free(m_sArchiveName);
+}
+
+int nsArchiveExtractor::Extract(const WCHAR *sDestinationDir)
+{
+  return OK;
+}
+
+int nsArchiveExtractor::ExtractFile(const WCHAR *sFileName, const WCHAR *sDestinationDir)
+{
+  return OK;
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsArchiveExtractor.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#pragma once
+
+/**
+ *  Class to show the progress
+ */
+class nsExtractorProgress
+{
+public:
+  nsExtractorProgress() {}
+  virtual void Progress(int nPercentComplete) = 0; /* to be overriden to get progress notifications */
+};
+
+/**
+ *  Base archive-extractor class.
+ *  Used to derive a specific archive format implementation.
+ */
+class nsArchiveExtractor
+{
+public:
+  enum
+  {
+    OK = 0,
+    ERR_FAIL = -1,
+    ERR_PARAM = -2,
+    ERR_READ = -3,
+    ERR_WRITE = -4,
+    ERR_MEM = -5,
+    ERR_NO_ARCHIVE = -6,
+    ERR_EXTRACTION = -7,
+  };
+
+  nsArchiveExtractor(const WCHAR *sArchiveName, DWORD dwSfxStubSize, nsExtractorProgress *pProgress);
+  virtual ~nsArchiveExtractor();
+
+  virtual int Extract(const WCHAR *sDestinationDir);
+  virtual int ExtractFile(const WCHAR *sFileName, const WCHAR *sDestinationDir);
+
+protected:
+  WCHAR *m_sArchiveName;
+  nsExtractorProgress *m_pProgress;
+  DWORD m_dwSfxStubSize;
+};
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsInstaller.cpp
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *
+ * nsInstaller.cpp : Mozilla Fennec Installer
+ *
+ */
+
+#include <windows.h>
+#include <DeviceResolutionAware.h>
+#include "nsSetupStrings.h"
+#include "nsInstaller.h"
+#include "ns7zipExtractor.h"
+#include "nsInstallerDlg.h"
+
+const WCHAR c_sStringsFile[] = L"setup.ini";
+
+// Global Variables:
+nsSetupStrings Strings;
+
+HINSTANCE g_hInst;
+WCHAR     g_sSourcePath[MAX_PATH];
+WCHAR     g_sExeFullFileName[MAX_PATH];
+WCHAR     g_sExeFileName[MAX_PATH];
+WCHAR     g_sInstallDir[MAX_PATH];
+DWORD     g_dwExeSize;
+
+// Forward declarations of functions included in this code module:
+BOOL InitInstance(HINSTANCE, int);
+DWORD GetExeSize();
+BOOL PostExtract();
+BOOL LoadStrings();
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// WinMain
+//
+///////////////////////////////////////////////////////////////////////////////
+int WINAPI WinMain(HINSTANCE hInstance,
+                   HINSTANCE hPrevInstance,
+                   LPTSTR    lpCmdLine,
+                   int       nCmdShow)
+{
+  int nResult = -1;
+
+  if (!InitInstance(hInstance, nCmdShow)) 
+    return nResult;
+
+  nsInstallerDlg::GetInstance()->Init(g_hInst);
+  nResult = nsInstallerDlg::GetInstance()->DoModal();
+  if (nResult == IDOK)
+    wcscpy(g_sInstallDir, nsInstallerDlg::GetInstance()->GetExtractPath());
+
+  return nResult;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// InitInstance
+//
+///////////////////////////////////////////////////////////////////////////////
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
+{
+  g_hInst = hInstance;
+
+  InitCommonControls();
+
+  g_sInstallDir[0] = L'\0';
+  g_sExeFileName[0] = L'\0';
+  if (GetModuleFileName(NULL, g_sExeFullFileName, MAX_PATH) == 0)
+    return FALSE;
+
+  wcscpy(g_sSourcePath, g_sExeFullFileName);
+  WCHAR *sSlash = wcsrchr(g_sSourcePath, L'\\');
+  wcscpy(g_sExeFileName, sSlash + 1);
+  *sSlash = L'\0'; // cut the file name
+
+  g_dwExeSize = GetExeSize();
+
+  return LoadStrings();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// GetExeSize
+//
+///////////////////////////////////////////////////////////////////////////////
+
+DWORD AbsoluteSeek(HANDLE, DWORD);
+void  ReadBytes(HANDLE, LPVOID, DWORD);
+
+DWORD GetExeSize()
+{
+  DWORD dwSize = 0;
+  HANDLE hImage;
+
+  DWORD  dwSectionOffset;
+  DWORD  dwCoffHeaderOffset;
+  DWORD  moreDosHeader[16];
+
+  ULONG  NTSignature;
+
+  IMAGE_DOS_HEADER      image_dos_header;
+  IMAGE_FILE_HEADER     image_file_header;
+  IMAGE_OPTIONAL_HEADER image_optional_header;
+  IMAGE_SECTION_HEADER  image_section_header;
+
+  // Open the EXE file.
+  hImage = CreateFile(g_sExeFullFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
+                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+  if (INVALID_HANDLE_VALUE == hImage)
+  {
+    ErrorMsg(L"Could not open the EXE");
+    return 0;
+  }
+
+  // Read the MS-DOS image header.
+  ReadBytes(hImage, &image_dos_header, sizeof(image_dos_header));
+
+  if (IMAGE_DOS_SIGNATURE != image_dos_header.e_magic)
+  {
+    ErrorMsg(L"Unknown file format.");
+    return 0;
+  }
+
+  // Read more MS-DOS header.
+  ReadBytes(hImage, moreDosHeader, sizeof(moreDosHeader));
+
+  // Get actual COFF header.
+  dwCoffHeaderOffset = AbsoluteSeek(hImage, image_dos_header.e_lfanew) + sizeof(ULONG);
+
+  ReadBytes (hImage, &NTSignature, sizeof(NTSignature));
+
+  if (IMAGE_NT_SIGNATURE != NTSignature)
+  {
+    ErrorMsg(L"Missing NT signature. Unknown file type.");
+    return 0;
+  }
+
+  dwSectionOffset = dwCoffHeaderOffset + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_NT_OPTIONAL_HEADER;
+
+  ReadBytes(hImage, &image_file_header, IMAGE_SIZEOF_FILE_HEADER);
+
+  // Read optional header.
+  ReadBytes(hImage, &image_optional_header, IMAGE_SIZEOF_NT_OPTIONAL_HEADER);
+
+  WORD nNumSections = image_file_header.NumberOfSections;
+
+  for (WORD i = 0; i < nNumSections; i++)
+  {
+    ReadBytes(hImage, &image_section_header, sizeof(IMAGE_SECTION_HEADER));
+
+    DWORD dwRawData = image_section_header.PointerToRawData + image_section_header.SizeOfRawData;
+    if (dwRawData > dwSize)
+      dwSize = dwRawData;
+  }
+
+  CloseHandle(hImage);
+
+  return dwSize;
+}
+
+DWORD AbsoluteSeek(HANDLE hFile, DWORD offset)
+{
+  DWORD newOffset;
+
+  if ((newOffset = SetFilePointer(hFile, offset, NULL, FILE_BEGIN)) == 0xFFFFFFFF)
+    ErrorMsg(L"SetFilePointer failed");
+
+  return newOffset;
+}
+
+void ReadBytes(HANDLE hFile, LPVOID buffer, DWORD size)
+{
+  DWORD bytes;
+
+  if (!ReadFile(hFile, buffer, size, &bytes, NULL))
+    ErrorMsg(L"ReadFile failed");
+  else if (size != bytes)
+    ErrorMsg(L"Read the wrong number of bytes");
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+// Read strings resource from the attached archive
+//
+//////////////////////////////////////////////////////////////////////////
+BOOL LoadStrings()
+{
+  WCHAR *sExtractPath = L"\\Temp\\";
+  WCHAR sExtractedStringsFile[MAX_PATH];
+  _snwprintf(sExtractedStringsFile, MAX_PATH, L"%s%s", sExtractPath, c_sStringsFile);
+
+  ns7zipExtractor archiveExtractor(g_sExeFullFileName, g_dwExeSize, NULL);
+
+  int nResult = archiveExtractor.ExtractFile(c_sStringsFile, sExtractPath);
+
+  if (nResult != 0)
+    return FALSE;
+
+  BOOL bResult = Strings.LoadStrings(sExtractedStringsFile);
+  DeleteFile(sExtractedStringsFile);
+
+  return bResult;
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsInstaller.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#pragma once
+#include "resourceppc.h"
+
+extern nsSetupStrings Strings;
+extern const WCHAR c_sStringsFile[];
+
+extern WCHAR g_sSourcePath[MAX_PATH];
+extern WCHAR g_sExeFileName[MAX_PATH];
+extern WCHAR g_sExeFullFileName[MAX_PATH];
+extern DWORD g_dwExeSize;
+
+#define ErrorMsg(msg) MessageBoxW(GetForegroundWindow(), msg, L"Setup", MB_OK|MB_ICONERROR)
+bool ConvertToChar(const WCHAR *wstr, char *str);
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsInstallerDlg.cpp
@@ -0,0 +1,360 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *
+ * nsInstallerDlg.cpp : Mozilla Fennec Installer UI.
+ *
+ */
+
+#include <windows.h>
+#include <projects.h>
+#include <aygshell.h>
+#include <DeviceResolutionAware.h>
+#define SHELL_AYGSHELL
+
+#include "nsSetupStrings.h"
+#include "nsInstaller.h"
+#include "ns7zipExtractor.h"
+#include "nsInstallerDlg.h"
+
+const WCHAR c_sInstallPathTemplate[] = L"%s\\%s";
+const WCHAR c_sExtractCardPathTemplate[] = L"\\%s%s\\%s";
+
+// Message handler for the dialog
+INT_PTR CALLBACK DlgMain(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  return nsInstallerDlg::GetInstance()->DlgMain(hDlg, message, wParam, lParam);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// nsInstallerDlg dialog
+//
+///////////////////////////////////////////////////////////////////////////////
+
+nsInstallerDlg::nsInstallerDlg()
+{
+  m_hInst = NULL;
+  m_sExtractPath[0] = 0;
+  m_sInstallPath[0] = 0;
+  m_sProgramFiles[0] = 0;
+  m_sErrorMsg[0] = 0;
+}
+
+nsInstallerDlg* nsInstallerDlg::GetInstance()
+{
+  static nsInstallerDlg dlg;
+  return &dlg;
+}
+
+void nsInstallerDlg::Init(HINSTANCE hInst)
+{
+  m_hInst = hInst;
+}
+
+int nsInstallerDlg::DoModal()
+{
+  return (int)DialogBox(m_hInst, (LPCTSTR)IDD_MAIN, 0, ::DlgMain);
+}
+
+INT_PTR CALLBACK nsInstallerDlg::DlgMain(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  switch (message)
+  {
+    case WM_INITDIALOG:
+      return OnInitDialog(hDlg, wParam, lParam);
+
+    case WM_COMMAND:
+      switch (LOWORD(wParam))
+      {
+        case IDOK:
+          {
+            EndDialog(hDlg, LOWORD(wParam));
+            return (INT_PTR)TRUE;
+          }
+
+        case IDCANCEL:
+          {
+            EndDialog(hDlg, LOWORD(wParam));
+            return (INT_PTR)FALSE;
+          }
+
+        case IDC_BTN_INSTALL:
+          {
+            if (OnBtnExtract())
+            {
+              EndDialog(hDlg, IDOK);
+              return (INT_PTR)TRUE;
+            }
+            else
+              return (INT_PTR)FALSE;
+          }
+        }
+        break;
+
+    case WM_CLOSE:
+      EndDialog(hDlg, message);
+      return (INT_PTR)TRUE;
+
+  }
+  return (INT_PTR)FALSE;
+}
+
+BOOL nsInstallerDlg::OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
+{
+#ifdef SHELL_AYGSHELL
+  {
+    // Create a Done button and size it.  
+    SHINITDLGINFO shidi;
+    shidi.dwMask = SHIDIM_FLAGS;
+    shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;
+    shidi.hDlg = hDlg;
+    SHInitDialog(&shidi);
+  }
+#endif // SHELL_AYGSHELL
+
+  m_hDlg = hDlg;
+
+  SetWindowText(m_hDlg, Strings.GetString(StrID_WindowCaption));
+  SetControlWindowText(IDC_STATIC_TITLE, Strings.GetString(StrID_WindowCaption));
+  SetControlWindowText(IDC_STATIC_INSTALL, Strings.GetString(StrID_InstallTo));
+  SetControlWindowText(IDC_BTN_INSTALL, Strings.GetString(StrID_Install));
+  SetControlWindowText(IDCANCEL, Strings.GetString(StrID_Cancel));
+
+  if (!SHGetSpecialFolderPath(m_hDlg, m_sProgramFiles, CSIDL_PROGRAM_FILES, FALSE))
+    wcscpy(m_sProgramFiles, L"\\Program Files");
+
+  _snwprintf(m_sInstallPath, MAX_PATH, c_sInstallPathTemplate,
+             m_sProgramFiles, Strings.GetString(StrID_AppShortName));
+
+  SendMessageToControl(IDC_CMB_PATH, CB_ADDSTRING, 0, (LPARAM)(m_sInstallPath));
+
+  FindMemCards();
+
+  SendMessageToControl(IDC_CMB_PATH, CB_SETCURSEL, 0, 0 );
+
+  return (INT_PTR)TRUE;
+}
+
+void nsInstallerDlg::FindMemCards()
+{
+  WIN32_FIND_DATA fd;
+  HANDLE hFlashCard = FindFirstFlashCard(&fd);
+  if (hFlashCard != INVALID_HANDLE_VALUE)
+  {
+    WCHAR sPath[MAX_PATH];
+    do 
+    {
+      if (wcslen(fd.cFileName) > 0)
+      {
+        _snwprintf(sPath, MAX_PATH, c_sExtractCardPathTemplate,
+          fd.cFileName, m_sProgramFiles, Strings.GetString(StrID_AppShortName));
+        SendMessageToControl(IDC_CMB_PATH, CB_ADDSTRING, 0, (LPARAM)(sPath));
+      }
+    } while(FindNextFlashCard(hFlashCard, &fd) && *fd.cFileName);
+  }
+}
+
+BOOL nsInstallerDlg::OnBtnExtract()
+{
+  BOOL bResult = FALSE;
+
+  int nPathIndex = SendMessageToControl(IDC_CMB_PATH, CB_GETCURSEL, 0, 0);
+  if (nPathIndex >=0 )
+    SendMessageToControl(IDC_CMB_PATH, CB_GETLBTEXT, nPathIndex, (LPARAM)(m_sInstallPath));
+
+  wcscpy(m_sExtractPath, m_sInstallPath);
+
+  // Remove the last directory ("Fennec") from the path as it is already in the archive
+  WCHAR *sSlash = wcsrchr(m_sExtractPath, L'\\');
+  if (sSlash)
+    *sSlash = 0;
+
+  ns7zipExtractor archiveExtractor(g_sExeFullFileName, g_dwExeSize, this);
+
+  SendMessageToControl(IDC_PROGRESS, PBM_SETRANGE, 0, (LPARAM) MAKELPARAM (0, 100)); // progress in percents
+  SendMessageToControl(IDC_PROGRESS, PBM_SETPOS, 0, 0);
+
+  int nResult = archiveExtractor.Extract(m_sExtractPath);
+  if (nResult == 0)
+  {
+    Progress(100); // 100%
+    bResult = PostExtract();
+  }
+
+  if (bResult)
+  {
+    MessageBoxW(m_hDlg, Strings.GetString(StrID_InstalledSuccessfully),
+                Strings.GetString(StrID_WindowCaption), MB_OK|MB_ICONINFORMATION);
+  }
+  else
+  {
+    WCHAR sMsg[c_nMaxErrorLen];
+    if (nResult != 0)
+      _snwprintf(sMsg, c_nMaxErrorLen, L"%s %d", Strings.GetString(StrID_ExtractionError), nResult);
+    else
+      _snwprintf(sMsg, c_nMaxErrorLen, L"%s\n%s", Strings.GetString(StrID_ThereWereErrors), m_sErrorMsg);
+
+    MessageBoxW(m_hDlg, sMsg, Strings.GetString(StrID_WindowCaption), MB_OK|MB_ICONERROR);
+  }
+
+  return bResult;
+}
+
+LRESULT nsInstallerDlg::SendMessageToControl(int nCtlID, UINT Msg, WPARAM wParam /*= 0*/, LPARAM lParam /*= 0*/)
+{
+  return SendMessage( GetDlgItem(m_hDlg, nCtlID), Msg, wParam, lParam);
+}
+
+void nsInstallerDlg::SetControlWindowText(int nCtlID, const WCHAR *sText)
+{
+  SetWindowText(GetDlgItem(m_hDlg, nCtlID), sText);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// ZipProgress member override
+//
+///////////////////////////////////////////////////////////////////////////////
+void nsInstallerDlg::Progress(int n)
+{
+  SendMessageToControl( IDC_PROGRESS, PBM_SETPOS, (WPARAM)n, 0);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+// PostExtract - additional step after extraction
+//
+//////////////////////////////////////////////////////////////////////////
+BOOL nsInstallerDlg::PostExtract()
+{
+  BOOL bResult = TRUE;
+
+  if (!CreateShortcut())
+  {
+    bResult = FALSE;
+    AddErrorMsg(L"CreateShortcut failed");
+  }
+
+  if (!StoreInstallPath())
+  {
+    bResult = FALSE;
+    AddErrorMsg(L"StoreInstallPath failed");
+  }
+
+  MoveSetupStrings();
+
+  if (!SilentFirstRun())
+  {
+    bResult = FALSE;
+    AddErrorMsg(L"SilentFirstRun failed");
+  }
+
+  return bResult;
+}
+
+BOOL nsInstallerDlg::StoreInstallPath()
+{
+  HKEY hKey;
+  WCHAR sRegFennecKey[MAX_PATH];
+  _snwprintf(sRegFennecKey, MAX_PATH, L"Software\\%s", Strings.GetString(StrID_AppShortName));
+
+  // Store the installation path - to be used by the uninstaller
+  LONG result = RegCreateKeyEx(HKEY_LOCAL_MACHINE, sRegFennecKey, 0, REG_NONE,
+                               REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
+  if (result == ERROR_SUCCESS)
+  {
+    result = RegSetValueEx(hKey, L"Path", 0, REG_SZ, (BYTE* const)m_sInstallPath, (wcslen(m_sInstallPath)+1)*sizeof(WCHAR));
+    RegCloseKey(hKey);
+  }
+
+  return (result == ERROR_SUCCESS);
+}
+
+BOOL nsInstallerDlg::CreateShortcut()
+{
+  WCHAR sFennecPath[MAX_PATH];
+  _snwprintf(sFennecPath, MAX_PATH, L"\"%s\\%s.exe\"", m_sInstallPath, Strings.GetString(StrID_AppShortName));
+
+  WCHAR sProgramsPath[MAX_PATH];
+  if (!SHGetSpecialFolderPath(m_hDlg, sProgramsPath, CSIDL_PROGRAMS, FALSE))
+    wcscpy(sProgramsPath, L"\\Windows\\Start Menu\\Programs");
+
+  WCHAR sShortcutPath[MAX_PATH];
+  _snwprintf(sShortcutPath, MAX_PATH, L"%s\\%s.lnk", sProgramsPath, Strings.GetString(StrID_AppShortName));
+
+  return SHCreateShortcut(sShortcutPath, sFennecPath);
+}
+
+BOOL nsInstallerDlg::MoveSetupStrings()
+{
+  WCHAR sExtractedStringsFile[MAX_PATH];
+  _snwprintf(sExtractedStringsFile, MAX_PATH, L"%s\\%s", m_sExtractPath, c_sStringsFile);
+
+  WCHAR sNewStringsFile[MAX_PATH];
+  _snwprintf(sNewStringsFile, MAX_PATH, L"%s\\%s", m_sInstallPath, c_sStringsFile);
+
+  return MoveFile(sExtractedStringsFile, sNewStringsFile);
+}
+
+BOOL nsInstallerDlg::SilentFirstRun()
+{
+  SetControlWindowText(IDC_STATUS_TEXT, Strings.GetString(StrID_CreatingUserProfile));
+  UpdateWindow(m_hDlg); // make sure the text is drawn
+
+  WCHAR sCmdLine[MAX_PATH];
+  _snwprintf(sCmdLine, MAX_PATH, L"%s\\%s.exe", m_sInstallPath, Strings.GetString(StrID_AppShortName));
+  PROCESS_INFORMATION pi;
+  BOOL bResult = CreateProcess(sCmdLine, L"-silent -nosplash",
+                               NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
+  if (bResult)
+  {
+    // Wait for it to finish
+    WaitForSingleObject(pi.hProcess, INFINITE);
+  }
+  SetWindowText(GetDlgItem(m_hDlg, IDC_STATUS_TEXT), L"");
+  return bResult;
+}
+
+void nsInstallerDlg::AddErrorMsg(WCHAR* sErr)
+{
+  WCHAR sMsg[c_nMaxErrorLen];
+  _snwprintf(sMsg, c_nMaxErrorLen, L"%s. LastError = %d\n", sErr, GetLastError());
+  wcsncat(m_sErrorMsg, sMsg, c_nMaxErrorLen - wcslen(m_sErrorMsg));
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsInstallerDlg.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#pragma once
+
+/**
+ * nsInstallerDlg dialog
+ */
+class nsInstallerDlg : public nsExtractorProgress
+{
+public:
+  static nsInstallerDlg* GetInstance();
+  void Init(HINSTANCE hInst);
+  int DoModal();
+  virtual void Progress(int n); // gets progress notifications
+  INT_PTR DlgMain(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+  const WCHAR* GetExtractPath() { return m_sInstallPath; }
+
+private:
+  nsInstallerDlg();
+  BOOL OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam);
+  void FindMemCards();
+  BOOL OnBtnExtract();
+  LRESULT SendMessageToControl(int nCtlID, UINT Msg, WPARAM wParam = 0, LPARAM lParam = 0);
+  void SetControlWindowText(int nCtlID, const WCHAR *sText);
+
+  BOOL PostExtract();
+  BOOL StoreInstallPath();
+  BOOL CreateShortcut();
+  BOOL MoveSetupStrings();
+  BOOL SilentFirstRun();
+
+  void AddErrorMsg(WCHAR* sErr);
+
+  static const int c_nMaxErrorLen = 2048;
+
+  HINSTANCE m_hInst;
+  HWND m_hDlg;
+
+  WCHAR m_sProgramFiles[MAX_PATH];
+  WCHAR m_sExtractPath[MAX_PATH];
+  WCHAR m_sInstallPath[MAX_PATH];
+  WCHAR m_sErrorMsg[c_nMaxErrorLen];
+};
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsInstallerppc.rc
@@ -0,0 +1,162 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Microsoft Visual C++ generated resource script.
+//
+#include "resourceppc.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "resdefce.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_NSINSTALLER        ICON                    "xulrunnerinstaller.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_MAIN DIALOG  0, 0, 156, 129
+STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION
+EXSTYLE 0x80000000L
+CAPTION "Mozilla Setup"
+FONT 8, "MS Shell Dlg"
+BEGIN
+    ICON            IDI_NSINSTALLER,IDC_STATIC,7,3,20,20,SS_REALSIZEIMAGE
+    LTEXT           "XULRunner Setup",IDC_STATIC_TITLE,39,8,106,8,SS_NOPREFIX
+    LTEXT           "Install XULRunner to",IDC_STATIC_INSTALL,2,26,142,11
+    PUSHBUTTON      "Install",IDC_BTN_INSTALL,2,57,70,20
+    PUSHBUTTON      "Cancel",IDCANCEL,84,57,70,20
+    CONTROL         "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,2,84,152,9
+    COMBOBOX        IDC_CMB_PATH,2,37,152,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "",IDC_STATUS_TEXT,2,98,152,19
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resourceppc.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""resdefce.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+    "LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r\n"
+    "#pragma code_page(1252)\r\n"
+    "#include ""nsInstallerppc.rc2""  // non-Microsoft Visual C++ edited resources\r\n"
+    "#endif\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_MAIN, DIALOG
+    BEGIN
+        LEFTMARGIN, 2
+        RIGHTMARGIN, 154
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#include "nsInstallerppc.rc2"  // non-Microsoft Visual C++ edited resources
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsInstallerppc.rc2
@@ -0,0 +1,17 @@
+//
+// nsInstallerPPC.rc2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
+HI_RES_AWARE CEUX {1}	// turn off the emulation layer
+			// Remove this resource to enable pixel-
+			// doubling on platforms that support it
+/////////////////////////////////////////////////////////////////////////////
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsSetupStrings.cpp
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *
+ * Class to work with localizable string resources
+ *
+ */
+
+#include <windows.h>
+#include "nsSetupStrings.h"
+#include "readstrings.h"
+#include "errors.h"
+
+#define STR_KEY(x) #x "\0"
+const char *kSetupStrKeys =
+#include "nsSetupStrings.inc"
+;
+#undef STR_KEY
+
+nsSetupStrings::nsSetupStrings()
+{
+  m_sBuf = NULL;
+  memset(m_arrStrings, 0, sizeof(m_arrStrings));
+}
+
+nsSetupStrings::~nsSetupStrings()
+{
+  delete[] m_sBuf;
+}
+
+BOOL nsSetupStrings::LoadStrings(WCHAR *sFileName)
+{
+  if (!sFileName)
+    return FALSE;
+
+  BOOL bResult = FALSE;
+  char strings[kNumberOfStrings][MAX_TEXT_LEN];
+  if (ReadStrings(sFileName, kSetupStrKeys, kNumberOfStrings, strings) == OK)
+  {
+    int nSize = 0;
+    for (int i = 0; i < kNumberOfStrings; i++)
+    {
+      nSize += strlen(strings[i]) + 1;
+    }
+
+    m_sBuf = new WCHAR[nSize];
+    if (!m_sBuf)
+      return FALSE;
+
+    WCHAR *p = m_sBuf;
+    for (int i = 0; i < kNumberOfStrings; i++)
+    {
+      int len = strlen(strings[i]) + 1;
+      MultiByteToWideChar(CP_UTF8, 0, strings[i], len, p, len);
+      m_arrStrings[i] = p;
+      p += len;
+    }
+
+    bResult = TRUE;
+  }
+
+  return bResult;
+}
+
+const WCHAR* nsSetupStrings::GetString(int nID)
+{
+  if (nID >= kNumberOfStrings)
+    return L"";
+  else
+    return m_arrStrings[nID];
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsSetupStrings.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *
+ * Class to work with localizable string resources
+ *
+ */
+
+#pragma once
+
+#define STR_KEY(x) StrID_##x,
+enum
+{
+  #include "nsSetupStrings.inc"
+  StrID_NumberOfStrings
+};
+#undef STR_KEY
+
+class nsSetupStrings
+{
+public:
+  nsSetupStrings();
+  ~nsSetupStrings();
+
+  BOOL LoadStrings(TCHAR *sFileName);
+  const TCHAR* GetString(int nID);
+
+private:
+
+  static const int kNumberOfStrings = StrID_NumberOfStrings;
+  TCHAR* m_sBuf;
+  TCHAR* m_arrStrings[kNumberOfStrings];
+};
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/nsSetupStrings.inc
@@ -0,0 +1,15 @@
+  STR_KEY(AppShortName)
+  STR_KEY(AppLongName)
+  STR_KEY(WindowCaption)
+  STR_KEY(InstallTo)
+  STR_KEY(Install)
+  STR_KEY(Cancel)
+  STR_KEY(InstalledSuccessfully)
+  STR_KEY(ExtractionError)
+  STR_KEY(ThereWereErrors)
+  STR_KEY(CreatingUserProfile)
+  STR_KEY(UninstallCaption)
+  STR_KEY(FilesWillBeRemoved)
+  STR_KEY(AreYouSure)
+  STR_KEY(InstallationNotFound)
+  STR_KEY(UninstalledSuccessfully)
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/readme.txt
@@ -0,0 +1,13 @@
+FennecInstaller implementation to replace CAB installer.
+
+This version extracts a 7z file appended to the EXE, i.e. works like a
+self-extracted archive.
+
+For example if you want to install fennec-1.0a3pre.en-US.wince-arm.7z, build
+the program, run the following command:
+
+  cat fennec_installer.exe fennec-1.0a3pre.en-US.wince-arm.7z >fennec-1.0a3pre.en-US.wince-arm.exe
+
+Then copy fennec-1.0a3pre.en-US.wince-arm.exe to a device and run it.
+
+Note: Requires lib7z.
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/resourceppc.h
@@ -0,0 +1,27 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by nsInstallerppc.rc
+//
+#define IDS_APP_TITLE                   1
+#define IDI_NSINSTALLER                 101
+#define IDR_MENU                        102
+#define IDD_MAIN                        103
+#define IDC_BTN_INSTALL                 1000
+#define IDC_PROGRESS                    1001
+#define IDC_CMB_PATH                    1002
+#define IDC_STATUS_TEXT                 1003
+#define IDC_STATIC_TITLE                1004
+#define IDC_STATIC_INSTALL              1005
+#define IDC_STATIC                      -1
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_NEXT_RESOURCE_VALUE        129
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         1006
+#define _APS_NEXT_SYMED_VALUE           110
+#endif
+#endif
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/uninstall/Makefile.in
@@ -0,0 +1,61 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Fennec Installer for WinCE.
+#
+# The Initial Developer of the Original Code is The Mozilla Foundation.
+#
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Mozilla Foundation <http://www.mozilla.org/>. All Rights Reserved.
+#
+# Contributor(s): 
+#   Alex Pakhotin <alexp@mozilla.com> (original author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH     = ../../../../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+PROGRAM   = uninstall$(BIN_SUFFIX)
+
+CPPSRCS = \
+	Uninstall.cpp \
+	../nsSetupStrings.cpp \
+	$(srcdir)/../../../update/src/updater/readstrings.cpp \
+	$(NULL)
+
+LOCAL_INCLUDES += -I$(srcdir)/.. -I$(srcdir)/../../../update/src/updater
+
+# Statically link the CRT when possible
+USE_STATIC_LIBS = 1
+
+WIN32_EXE_LDFLAGS += -ENTRY:WinMain
+
+include $(topsrcdir)/config/rules.mk
+
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/installer/wince/uninstall/Uninstall.cpp
@@ -0,0 +1,277 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Fennec Installer for WinCE.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *
+ * Uninstall.cpp : Mozilla Fennec Uninstaller
+ *
+ */
+
+#include <windows.h>
+#include "nsSetupStrings.h"
+
+const WCHAR c_sStringsFile[] = L"setup.ini";
+nsSetupStrings Strings;
+
+WCHAR g_sUninstallPath[MAX_PATH];
+
+const WCHAR c_sRemoveParam[] = L"remove";
+
+// Forward declarations
+BOOL GetModulePath(WCHAR *sPath);
+BOOL LoadStrings();
+BOOL GetInstallPath(WCHAR *sPath);
+BOOL DeleteShortcut(HWND hwndParent);
+BOOL DeleteDirectory(const WCHAR* sPathToDelete);
+BOOL DeleteRegistryKey();
+BOOL CopyAndLaunch();
+
+// Main
+int WINAPI WinMain(HINSTANCE hInstance,
+                   HINSTANCE hPrevInstance,
+                   LPTSTR    lpCmdLine,
+                   int       nCmdShow)
+{
+  HWND hWnd = GetForegroundWindow();
+  *g_sUninstallPath = 0;
+
+  WCHAR *sCommandLine = GetCommandLine();
+  WCHAR *sRemoveParam = wcsstr(sCommandLine, c_sRemoveParam);
+  if (sRemoveParam != NULL)
+  {
+    // Launched from a temp directory with parameters "remove \Program Files\Fennec\"
+    wcscpy(g_sUninstallPath, sRemoveParam + wcslen(c_sRemoveParam) + 1);
+  }
+  else
+  {
+    // Just copy this EXE and launch it from a temp location with a special parameter
+    // to delete itself in the installation directory
+    if (CopyAndLaunch())
+      return 0;
+  }
+  // Perform uninstallation when executed with a special parameter
+  // (or in case when CopyAndLaunch failed - just execute in place)
+
+  if (!LoadStrings())
+  {
+    MessageBoxW(hWnd, L"Cannot find the strings file.", L"Uninstall", MB_OK|MB_ICONWARNING);
+    return -1;
+  }
+
+  WCHAR sInstallPath[MAX_PATH];
+  if (GetInstallPath(sInstallPath))
+  {
+    WCHAR sMsg[MAX_PATH+256];
+    _snwprintf(sMsg, MAX_PATH+256, L"%s %s\n%s", Strings.GetString(StrID_FilesWillBeRemoved),
+      sInstallPath, Strings.GetString(StrID_AreYouSure));
+    if (MessageBoxW(hWnd, sMsg, Strings.GetString(StrID_UninstallCaption),
+                    MB_YESNO|MB_ICONWARNING) == IDNO)
+    {
+      return -2;
+    }
+
+    // Remove all installed files
+    DeleteDirectory(sInstallPath);
+    DeleteShortcut(hWnd);
+    DeleteRegistryKey();
+
+    // TODO: May probably handle errors during deletion (such as locked directories)
+    // and notify user. Right now just show successful message.
+    MessageBoxW(hWnd, Strings.GetString(StrID_UninstalledSuccessfully),
+                Strings.GetString(StrID_UninstallCaption), MB_OK|MB_ICONINFORMATION);
+  }
+  else
+  {
+    MessageBoxW(hWnd, Strings.GetString(StrID_InstallationNotFound),
+                Strings.GetString(StrID_UninstallCaption), MB_OK|MB_ICONINFORMATION);
+    return -1;
+  }
+
+  return 0;
+}
+
+BOOL LoadStrings()
+{
+  // Locate and load the strings file used by installer
+  if (*g_sUninstallPath == 0)
+    GetModulePath(g_sUninstallPath);
+
+  WCHAR sStringsFile[MAX_PATH];
+  _snwprintf(sStringsFile, MAX_PATH, L"%s\\%s", g_sUninstallPath, c_sStringsFile);
+
+  return Strings.LoadStrings(sStringsFile);
+}
+
+BOOL GetModulePath(WCHAR *sPath)
+{
+  if (GetModuleFileName(NULL, sPath, MAX_PATH) == 0)
+    return FALSE;
+
+  WCHAR *sSlash = wcsrchr(sPath, L'\\') + 1;
+  *sSlash = L'\0'; // cut the file name
+
+  return TRUE;
+}
+
+BOOL GetInstallPath(WCHAR *sPath)
+{
+  HKEY hKey;
+  WCHAR sRegFennecKey[MAX_PATH];
+  _snwprintf(sRegFennecKey, MAX_PATH, L"Software\\%s", Strings.GetString(StrID_AppShortName));
+
+  LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sRegFennecKey, 0, KEY_ALL_ACCESS, &hKey);
+  if (result == ERROR_SUCCESS)
+  {
+    DWORD dwType = NULL;
+    DWORD dwCount = MAX_PATH * sizeof(WCHAR);
+    result = RegQueryValueEx(hKey, L"Path", NULL, &dwType, (LPBYTE)sPath, &dwCount);
+
+    RegCloseKey(hKey);
+  }
+
+  return (result == ERROR_SUCCESS);
+}
+
+BOOL DeleteDirectory(const WCHAR* sPathToDelete)
+{
+  HANDLE          hFile;
+  WCHAR           sFilePath[MAX_PATH];
+  WCHAR           sPattern[MAX_PATH];
+  WIN32_FIND_DATA findData;
+
+  wcscpy(sPattern, sPathToDelete);
+  wcscat(sPattern, L"\\*.*");
+  hFile = FindFirstFile(sPattern, &findData);
+  if (hFile != INVALID_HANDLE_VALUE)
+  {
+    do
+    {
+      if (findData.cFileName[0] != L'.')
+      {
+        _snwprintf(sFilePath, MAX_PATH, L"%s\\%s", sPathToDelete, findData.cFileName);
+
+        if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        {
+          // Delete subdirectory
+          BOOL bRet = DeleteDirectory(sFilePath);
+          if (!bRet)
+          {
+            // Just continue
+            //return bRet;
+          }
+        }
+        else
+        {
+          // Set file attributes
+          if (SetFileAttributes(sFilePath, FILE_ATTRIBUTE_NORMAL))
+          {
+            // Delete file
+            if (!DeleteFile(sFilePath))
+            {
+              // Just continue
+              //return FALSE;
+            }
+          }
+        }
+      }
+    } while (FindNextFile(hFile, &findData));
+
+    // Close handle
+    FindClose(hFile);
+
+    DWORD dwError = GetLastError();
+    if (dwError != ERROR_NO_MORE_FILES)
+      return FALSE;
+    else
+    {
+      // Set directory attributes
+      if (SetFileAttributes(sPathToDelete, FILE_ATTRIBUTE_NORMAL))
+      {
+        // Delete directory
+        if (!RemoveDirectory(sPathToDelete))
+          return FALSE;
+      }
+    }
+  }
+
+  return TRUE;
+}
+
+BOOL DeleteShortcut(HWND hwndParent)
+{
+  WCHAR sProgramsPath[MAX_PATH];
+  if (!SHGetSpecialFolderPath(hwndParent, sProgramsPath, CSIDL_PROGRAMS, FALSE))
+    wcscpy(sProgramsPath, L"\\Windows\\Start Menu\\Programs");
+
+  WCHAR sShortcutPath[MAX_PATH];
+  _snwprintf(sShortcutPath, MAX_PATH, L"%s\\%s.lnk", sProgramsPath, Strings.GetString(StrID_AppShortName));
+
+
+  if(SetFileAttributes(sShortcutPath, FILE_ATTRIBUTE_NORMAL))
+    return DeleteFile(sShortcutPath);
+
+  return FALSE;
+}
+
+BOOL DeleteRegistryKey()
+{
+  WCHAR sRegFennecKey[MAX_PATH];
+  _snwprintf(sRegFennecKey, MAX_PATH, L"Software\\%s", Strings.GetString(StrID_AppShortName));
+  LONG result = RegDeleteKey(HKEY_LOCAL_MACHINE, sRegFennecKey);
+  return (result == ERROR_SUCCESS);
+}
+
+// Copy to a temp directory and launch from there
+BOOL CopyAndLaunch()
+{
+  WCHAR sNewName[] = L"\\Temp\\uninstall.exe";
+  WCHAR sModule[MAX_PATH];
+  if (GetModuleFileName(NULL, sModule, MAX_PATH) == 0 || !GetModulePath(g_sUninstallPath))
+    return FALSE;
+  if (CopyFile(sModule, sNewName, FALSE))
+  {
+    PROCESS_INFORMATION pi;
+    WCHAR sParam[MAX_PATH+20];
+    _snwprintf(sParam, MAX_PATH+20, L"%s %s", c_sRemoveParam, g_sUninstallPath);
+
+    // Launch "\Temp\uninstall.exe remove \Program Files\Fennec\"
+    return CreateProcess(sNewName, sParam, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
+  }
+  else
+    return FALSE;
+}
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0b65049e89134ed3688218f2cf493d06e3a5f397
GIT binary patch
literal 7406
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
--- a/toolkit/mozapps/update/src/updater/readstrings.cpp
+++ b/toolkit/mozapps/update/src/updater/readstrings.cpp
@@ -16,16 +16,17 @@
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is Google Inc.
  * Portions created by the Initial Developer are Copyright (C) 2005
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Darin Fisher <darin@meer.net>
+ *  Alex Pakhotin <alexp@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -36,17 +37,21 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <limits.h>
 #include <string.h>
 #include <stdio.h>
 #include "readstrings.h"
 #include "errors.h"
-#include "prtypes.h"
+
+// Defined bool stuff here to reduce external dependencies
+typedef int        PRBool;
+#define PR_TRUE    1
+#define PR_FALSE   0
 
 #ifdef XP_WIN
 # define NS_tfopen _wfopen
 # define OPEN_MODE L"rb"
 #else
 # define NS_tfopen fopen
 # define OPEN_MODE "r"
 #endif
@@ -106,19 +111,52 @@ NS_strtok(const char *delims, char **str
     }
     ++i;
   } while (*i);
 
   *str = NULL;
   return ret;
 }
 
-// very basic parser for updater.ini taken mostly from nsINIParser.cpp
+/**
+ * Find a key in a keyList containing zero-delimited keys ending with "\0\0".
+ * Returns a zero-based index of the key in the list, or -1 if the key is not found.
+ */
+static int
+find_key(const char *keyList, char* key)
+{
+  if (!keyList)
+    return -1;
+
+  int index = 0;
+  const char *p = keyList;
+  while (*p)
+  {
+    if (strcmp(key, p) == 0)
+      return index;
+
+    p += strlen(p) + 1;
+    index++;
+  }
+
+  // The key was not found if we came here
+  return -1;
+}
+
+/**
+ * A very basic parser for updater.ini taken mostly from nsINIParser.cpp
+ * that can be used by standalone apps.
+ *
+ * @param path       Path to the .ini file to read
+ * @param keyList    List of zero-delimited keys ending with two zero characters
+ * @param numStrings Number of strings to read into results buffer - must be equal to the number of keys
+ * @param results    Two-dimensional array of strings to be filled in the same order as the keys provided
+ */
 int
-ReadStrings(const NS_tchar *path, StringTable *results)
+ReadStrings(const NS_tchar *path, const char *keyList, int numStrings, char results[][MAX_TEXT_LEN])
 {
   AutoFILE fp = NS_tfopen(path, OPEN_MODE);
 
   if (!fp)
     return READ_ERROR;
 
   /* get file size */
   if (fseek(fp, 0, SEEK_END) != 0)
@@ -139,18 +177,18 @@ ReadStrings(const NS_tchar *path, String
   int rd = fread(fileContents, sizeof(char), flen, fp);
   if (rd != flen)
     return READ_ERROR;
 
   fileContents[flen] = '\0';
 
   char *buffer = fileContents;
   PRBool inStringsSection = PR_FALSE;
-  const unsigned None = 0, Title = 1, Info = 2, All = 3;
-  unsigned read = None;
+
+  unsigned read = 0;
 
   while (char *token = NS_strtok(kNL, &buffer)) {
     if (token[0] == '#' || token[0] == ';') // it's a comment
       continue;
 
     token = (char*) NS_strspnp(kWhitespace, token);
     if (!*token) // empty line
       continue;
@@ -180,22 +218,38 @@ ReadStrings(const NS_tchar *path, String
       continue;
     }
 
     char *key = token;
     char *e = NS_strtok(kEquals, &token);
     if (!e)
       continue;
 
-    if (strcmp(key, "Title") == 0) {
-      strncpy(results->title, token, MAX_TEXT_LEN - 1);
-      results->title[MAX_TEXT_LEN - 1] = 0;
-      read |= Title;
-    }
-    else if (strcmp(key, "Info") == 0) {
-      strncpy(results->info, token, MAX_TEXT_LEN - 1);
-      results->info[MAX_TEXT_LEN - 1] = 0;
-      read |= Info;
+    int keyIndex = find_key(keyList, key);
+    if (keyIndex >= 0 && keyIndex < numStrings)
+    {
+      strncpy(results[keyIndex], token, MAX_TEXT_LEN - 1);
+      results[keyIndex][MAX_TEXT_LEN - 1] = 0;
+      read++;
     }
   }
 
-  return (read == All) ? OK : PARSE_ERROR;
+  return (read == numStrings) ? OK : PARSE_ERROR;
 }
+
+// A wrapper function to read strings for the updater.
+// Added for compatibility with the original code.
+int
+ReadStrings(const NS_tchar *path, StringTable *results)
+{
+  const int kNumStrings = 2;
+  const char *kUpdaterKeys = "Title\0Info\0";
+  char updater_strings[kNumStrings][MAX_TEXT_LEN];
+
+  int result = ReadStrings(path, kUpdaterKeys, kNumStrings, updater_strings);
+
+  strncpy(results->title, updater_strings[0], MAX_TEXT_LEN - 1);
+  results->title[MAX_TEXT_LEN - 1] = 0;
+  strncpy(results->info, updater_strings[1], MAX_TEXT_LEN - 1);
+  results->info[MAX_TEXT_LEN - 1] = 0;
+
+  return result;
+}
--- a/toolkit/mozapps/update/src/updater/readstrings.h
+++ b/toolkit/mozapps/update/src/updater/readstrings.h
@@ -16,16 +16,17 @@
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is Google Inc.
  * Portions created by the Initial Developer are Copyright (C) 2005
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Darin Fisher <darin@meer.net>
+ *  Alex Pakhotin <alexp@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -53,9 +54,14 @@ struct StringTable {
   char info[MAX_TEXT_LEN];
 };
 
 /**
  * This function reads in localized strings from updater.ini
  */
 int ReadStrings(const NS_tchar *path, StringTable *results);
 
+/**
+ * This function reads in localized strings corresponding to the keys from a given .ini
+ */
+int ReadStrings(const NS_tchar *path, const char *keyList, int numStrings, char results[][MAX_TEXT_LEN]);
+
 #endif  // READSTRINGS_H__