diff --git a/build/package/wince/make_wince_cab.py b/build/package/wince/make_wince_cab.py index aff91b727ef..91a784985ae 100644 --- a/build/package/wince/make_wince_cab.py +++ b/build/package/wince/make_wince_cab.py @@ -21,6 +21,7 @@ # Contributor(s): # John Wolfe # Vladimir Vukicevic +# Alex Pakhotin # # 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 @@ -37,11 +38,11 @@ # ***** END LICENSE BLOCK ***** ################################################################ # -# make-wince-cab.py --- Given a directory, walk it and make an +# make_wince_cab.py --- Given a directory, walk it and make an # installer based upon the contents of that directory # # Usage: -# python make-wince-inf.py [-s] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME +# python make_wince_cab.py [-setupdll] [-s] [-faststart] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME # # Walk through the relative directory SOURCE_DIR, parsing filenames # Checks for duplicate filenames and renames where needed @@ -55,12 +56,15 @@ # Blank lines and '#' comments in the 'install-exceptions' file are # ignored. # -# EXAMPLE OF COMMAND LINE: -# python make_wince_inf.py /c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/SmartDevices/SDK/SDKTools/cabwiz.exe dist/fennec Fennec fennec-0.11.en-US.wince-arm.cab -# # ARGS: +# -setupdll - Make a small additional CAB including Setup.dll. +# This is to add Fennec to the system list of installed applications +# available in Settings - System - Remove Programs. +# # -s - Don't pass /compress to cabwiz (generate CAB compatible with Windows CE) # +# -faststart - Add FastStart shortcut +# # CABWIZ_PATH - If specified, will use this cabwiz.exe executable. Otherwise, will attempt # to find one using $VSINSTALLDIR. # @@ -72,6 +76,9 @@ # # CAB_FINAL_NAME - actual final name for the produced CAB file # +# EXAMPLE OF COMMAND LINE: +# python make_wince_cab.py /c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/SmartDevices/SDK/SDKTools/cabwiz.exe dist/fennec Fennec fennec-0.11.en-US.wince-arm.cab +# # NOTE: In our example, "fennec" is the directory [source_name] # "fennec.exe" is the application [$(source_name).exe], and # "Fennec" is the shortcut name [program_name] @@ -87,6 +94,7 @@ import shutil CompressFlag = "/compress" FaststartFlag = 0 +MakeSetupDllCab = 0 class FileEntry: def __init__(self, dirpath, dircount, filename, filecount, actual_filename): @@ -309,6 +317,47 @@ def output_inf_file(program_name, app_name): +def output_setup_dll_inf_file(source_dir, program_name, app_name): + inf_name = "%s.inf" % program_name + f = open(inf_name, 'w') + + f.write("""; Additional CAB to create Fennec entry in the installed programs list + +[Version] +Signature = "$Windows NT$" ; required as-is +Provider = "Mozilla" ; maximum of 30 characters, full app name will be \" \" +CESignature = "$Windows CE$" ; required as-is + +[CEStrings] +AppName = "%s" ; maximum of 40 characters, full app name will be \" \"\n""" % program_name) + + f.write("InstallDir = %CE1%\\%AppName% ; Program Files\Fennec\n\n") + + f.write("[SourceDisksNames] ; directory that holds the application's files\n") + f.write('1 = , "%s",,%s\n\n' % (source_dir, source_dir)) + + f.write("[SourceDisksFiles] ; list of files to be included in .cab\n") + f.write("Setup.dll = 1\n\n") + + f.write("""[DefaultInstall] ; operations to be completed during install +CopyFiles = Files.%s +AddReg = RegData +CESetupDLL = "Setup.dll" +\n""" % program_name) + + f.write("[DestinationDirs] ; default destination directories for each operation section\n") + f.write("Files.%s = 0, %%InstallDir%%\n\n" % program_name) + + f.write("""[Files.%s] +;No files to copy + +[RegData] +;No registry entries +""" % program_name) + + f.close() + + def make_cab_file(cabwiz_path, program_name, cab_final_name): make_cab_command = "\"%s\" %s %s.inf" % (cabwiz_path, CompressFlag, program_name) print "INFORMATION: Executing command to make %s CAB file (only works on BASH)" % program_name @@ -322,14 +371,14 @@ def make_cab_file(cabwiz_path, program_name, cab_final_name): print """*************************************************************************** ERROR: CAB FILE NOT CREATED. You can try running the command by hand: - %s" % make_cab_comman + %s ---- NOTE: If you see an error like this: Error: File XXXXXXXXXX.inf contains DirIDs, which are not supported -- this may mean that your PYTHON is outputting Windows files WITHOUT CR-LF line endings. Please verify that your INF file has CR-LF line endings. -***************************************************************************""" +***************************************************************************""" % make_cab_command sys.exit(2) print "INFORMATION: Executing command to move %s.CAB to %s" % (program_name, cab_final_name) @@ -347,12 +396,17 @@ def purge_copied_files(): def main(): args = sys.argv if len(args) < 4 or len(args) > 7: - print >> sys.stderr, "Usage: %s [-s] [-faststart] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME" % args[0] + print >> sys.stderr, "Usage: %s [-setupdll] [-s] [-faststart] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME" % args[0] print >> sys.stderr, "Example: %s /c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/ fennec Fennec fennec-0.11.en-US.wince-arm.cab" % args[0] sys.exit(1) args = args[1:] + if args[0] == "-setupdll": + global MakeSetupDllCab + MakeSetupDllCab = 1 + args = args[1:] + if args[0] == "-s": global CompressFlag CompressFlag = "" @@ -383,12 +437,18 @@ ERROR: CABWIZ_PATH is not a valid file, or cabwiz couldn't be found! ***************************************************************************""" sys.exit(2) - walk_tree(source_dir, ignored_patterns) - sys.stdout.flush() - output_inf_file(program_name, app_name) - sys.stdout.flush() - make_cab_file(cabwiz_path, program_name, cab_final_name) - purge_copied_files() + if MakeSetupDllCab: + output_setup_dll_inf_file(source_dir, program_name, app_name) + sys.stdout.flush() + make_cab_file(cabwiz_path, program_name, cab_final_name) + os.remove("%s/setup.dll" % source_dir) + else: + walk_tree(source_dir, ignored_patterns) + sys.stdout.flush() + output_inf_file(program_name, app_name) + sys.stdout.flush() + make_cab_file(cabwiz_path, program_name, cab_final_name) + purge_copied_files() # run main if run directly diff --git a/toolkit/mozapps/installer/wince/nsInstallerDlg.cpp b/toolkit/mozapps/installer/wince/nsInstallerDlg.cpp index 37e8d6ca4ec..2f95edf01e8 100644 --- a/toolkit/mozapps/installer/wince/nsInstallerDlg.cpp +++ b/toolkit/mozapps/installer/wince/nsInstallerDlg.cpp @@ -55,7 +55,7 @@ const WCHAR c_sInstallPathTemplate[] = L"%s\\%s"; const WCHAR c_sExtractCardPathTemplate[] = L"\\%s%s\\%s"; -const WCHAR c_sAppRegKeyTemplate[] = L"Software\\%s"; +const WCHAR c_sAppRegKeyTemplate[] = L"Software\\Mozilla\\%s"; const WCHAR c_sFastStartTemplate[] = L"%s\\%sfaststart.exe"; // Message handler for the dialog @@ -294,6 +294,8 @@ BOOL nsInstallerDlg::PostExtract() RUN_AND_CHECK(SilentFirstRun) + RUN_AND_CHECK(RunSetupCab) + return bResult; } @@ -420,6 +422,28 @@ BOOL nsInstallerDlg::SilentFirstRun() return bResult; } +BOOL nsInstallerDlg::RunSetupCab() +{ + BOOL bResult = FALSE; + + WCHAR sCabPath[MAX_PATH]; + WCHAR sParams[MAX_PATH + 20]; + _snwprintf(sCabPath, MAX_PATH, L"%s\\setup.cab", m_sInstallPath); + + // Run "wceload.exe /noui Fennec.cab" + _snwprintf(sParams, MAX_PATH, L"/noui \"%s\"", sCabPath); + PROCESS_INFORMATION pi; + bResult = CreateProcess(L"\\Windows\\wceload.exe", + sParams, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi); + if (bResult) + { + // Wait for it to finish + WaitForSingleObject(pi.hProcess, INFINITE); + } + + return bResult; +} + void nsInstallerDlg::AddErrorMsg(WCHAR* sErr) { WCHAR sMsg[c_nMaxErrorLen]; diff --git a/toolkit/mozapps/installer/wince/nsInstallerDlg.h b/toolkit/mozapps/installer/wince/nsInstallerDlg.h index 9195bf4b1d7..80e52c5bee9 100644 --- a/toolkit/mozapps/installer/wince/nsInstallerDlg.h +++ b/toolkit/mozapps/installer/wince/nsInstallerDlg.h @@ -65,6 +65,7 @@ private: BOOL CreateShortcut(); BOOL MoveSetupStrings(); BOOL SilentFirstRun(); + BOOL RunSetupCab(); BOOL GetInstallPath(WCHAR *sPath); BOOL RunUninstall(BOOL *pbCancelled); diff --git a/toolkit/mozapps/installer/wince/uninstall/Uninstall.cpp b/toolkit/mozapps/installer/wince/uninstall/Uninstall.cpp index 0ac59baf1b9..84bd5f312ed 100644 --- a/toolkit/mozapps/installer/wince/uninstall/Uninstall.cpp +++ b/toolkit/mozapps/installer/wince/uninstall/Uninstall.cpp @@ -44,6 +44,7 @@ #include #include +#include #include "nsSetupStrings.h" #include "resource.h" @@ -53,12 +54,17 @@ const WCHAR c_sStringsFile[] = L"setup.ini"; nsSetupStrings Strings; +BOOL g_bRunFromSetupDll = FALSE; + WCHAR g_sInstallPath[MAX_PATH]; WCHAR g_sUninstallPath[MAX_PATH]; HWND g_hDlg = NULL; +const WCHAR c_sAppRegKeyTemplate[] = L"Software\\Mozilla\\%s"; + const DWORD c_nTempBufSize = MAX_PATH * 2; const WCHAR c_sRemoveParam[] = L"[remove]"; +const WCHAR c_sSetupParam[] = L"[setup]"; // means executed by Setup.dll // Retry counter for the file/directory deletion int nTotalRetries = 0; @@ -88,6 +94,7 @@ BOOL DeleteDirectory(const WCHAR* sPathToDelete); BOOL DeleteRegistryKey(); BOOL CopyAndLaunch(); BOOL ShutdownFastStartService(const WCHAR *sInstallPath); +BOOL RunSystemUninstall(); BOOL CALLBACK DlgUninstall(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); BOOL OnDialogInit(HWND hDlg); @@ -108,6 +115,7 @@ int WINAPI WinMain(HINSTANCE hInstance, WCHAR *sCommandLine = GetCommandLine(); WCHAR *sRemoveParam = wcsstr(sCommandLine, c_sRemoveParam); + WCHAR g_bRunFromSetupDll = (wcsstr(sCommandLine, c_sSetupParam) != NULL); if (sRemoveParam != NULL) { // Launched from a temp directory with parameters "[remove] \Program Files\Fennec\" @@ -152,6 +160,9 @@ int Uninstall(HWND hWnd) DeleteShortcut(hWnd); DeleteRegistryKey(); + if (!g_bRunFromSetupDll) + RunSystemUninstall(); + // TODO: May probably handle errors during deletion (such as locked directories) // and notify user. Right now just return OK. return ErrOK; @@ -295,7 +306,7 @@ BOOL GetInstallPath(WCHAR *sPath) { HKEY hKey; WCHAR sRegFennecKey[MAX_PATH]; - _snwprintf(sRegFennecKey, MAX_PATH, L"Software\\%s", Strings.GetString(StrID_AppShortName)); + _snwprintf(sRegFennecKey, MAX_PATH, c_sAppRegKeyTemplate, Strings.GetString(StrID_AppShortName)); LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sRegFennecKey, 0, KEY_ALL_ACCESS, &hKey); if (result == ERROR_SUCCESS) @@ -428,7 +439,8 @@ BOOL DeleteShortcut(HWND hwndParent) BOOL DeleteRegistryKey() { WCHAR sRegFennecKey[MAX_PATH]; - _snwprintf(sRegFennecKey, MAX_PATH, L"Software\\%s", Strings.GetString(StrID_AppShortName)); + _snwprintf(sRegFennecKey, MAX_PATH, c_sAppRegKeyTemplate, Strings.GetString(StrID_AppShortName)); + LONG result = RegDeleteKey(HKEY_LOCAL_MACHINE, sRegFennecKey); return (result == ERROR_SUCCESS); } @@ -444,7 +456,10 @@ BOOL CopyAndLaunch() { PROCESS_INFORMATION pi; WCHAR sParam[c_nTempBufSize]; - _snwprintf(sParam, c_nTempBufSize, L"%s %s", c_sRemoveParam, g_sUninstallPath); + if (g_bRunFromSetupDll) + _snwprintf(sParam, c_nTempBufSize, L"%s %s %s", c_sSetupParam, c_sRemoveParam, g_sUninstallPath); + else + _snwprintf(sParam, c_nTempBufSize, 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); @@ -504,3 +519,25 @@ BOOL ShutdownFastStartService(const WCHAR *wsInstallPath) } return result; } + +// Remove the part installed from the CAB +BOOL RunSystemUninstall() +{ + WCHAR sXML[c_nTempBufSize]; + LPWSTR sXMLOut = NULL; + + _snwprintf(sXML, c_nTempBufSize, + L"" + L" " + L" " + L" " + L" " + L" " + L"", + Strings.GetString(StrID_AppLongName)); + + HRESULT hr = DMProcessConfigXML(sXML, CFGFLAG_PROCESS, &sXMLOut); + delete[] sXMLOut; + + return hr == S_OK; +}