1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef nsUpdateDriver_h__
8 #define nsUpdateDriver_h__
9 
10 #include "nscore.h"
11 #include "nsIUpdateService.h"
12 #include "nsIThread.h"
13 #include "nsCOMPtr.h"
14 #include "nsString.h"
15 #include "mozilla/Attributes.h"
16 
17 class nsIFile;
18 
19 #if defined(XP_WIN)
20 #  include <windows.h>
21 typedef HANDLE ProcessType;
22 #elif defined(XP_UNIX)
23 typedef pid_t ProcessType;
24 #else
25 #  include "prproces.h"
26 typedef PRProcess* ProcessType;
27 #endif
28 
29 /**
30  * This function processes any available updates.  As part of that process, it
31  * may exit the current process and relaunch it at a later time.
32  *
33  * Two directories are passed to this function: greDir (where the actual
34  * binary resides) and appDir (which contains application.ini for XULRunner
35  * apps). If this is not a XULRunner app then appDir is identical to greDir.
36  *
37  * The argc and argv passed to this function should be what is needed to
38  * relaunch the current process.
39  *
40  * The appVersion param passed to this function is the current application's
41  * version and is used to determine if an update's version is older than the
42  * current application version.
43  *
44  * If you want the update to be processed without restarting, set the restart
45  * parameter to false.
46  *
47  * This function does not modify appDir.
48  */
49 nsresult ProcessUpdates(nsIFile* greDir, nsIFile* appDir, nsIFile* updRootDir,
50                         int argc, char** argv, const char* appVersion,
51                         bool restart = true, ProcessType* pid = nullptr);
52 
53 // The implementation of the update processor handles the task of loading the
54 // updater application for staging an update.
55 // XXX ehsan this is living in this file in order to make use of the existing
56 // stuff here, we might want to move it elsewhere in the future.
57 class nsUpdateProcessor final : public nsIUpdateProcessor {
58  public:
59   nsUpdateProcessor();
60 
61   NS_DECL_THREADSAFE_ISUPPORTS
62   NS_DECL_NSIUPDATEPROCESSOR
63 
64  private:
65   ~nsUpdateProcessor();
66 
67   struct StagedUpdateInfo {
StagedUpdateInfoStagedUpdateInfo68     StagedUpdateInfo() : mArgc(0), mArgv(nullptr) {}
~StagedUpdateInfoStagedUpdateInfo69     ~StagedUpdateInfo() {
70       for (int i = 0; i < mArgc; ++i) {
71         delete[] mArgv[i];
72       }
73       delete[] mArgv;
74     }
75 
76     nsCOMPtr<nsIFile> mGREDir;
77     nsCOMPtr<nsIFile> mAppDir;
78     nsCOMPtr<nsIFile> mUpdateRoot;
79     int mArgc;
80     char** mArgv;
81     nsCString mAppVersion;
82   };
83 
84  private:
85   void StartStagedUpdate();
86   void WaitForProcess();
87   void UpdateDone();
88   void ShutdownWatcherThread();
89 
90  private:
91   ProcessType mUpdaterPID;
92   nsCOMPtr<nsIThread> mProcessWatcher;
93   StagedUpdateInfo mInfo;
94 };
95 #endif  // nsUpdateDriver_h__
96