1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is Mozilla XULRunner.
16 * The Initial Developer of the Original Code is
17 * Benjamin Smedberg <benjamin@smedbergs.us>.
19 * Portions created by the Initial Developer are Copyright (C) 2005
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsRegisterGRE.h"
42 #include "nsILocalFile.h"
44 #include "nsAppRunner.h" // for MAXPATHLEN
45 #include "nsStringAPI.h"
46 #include "nsXPCOMGlue.h"
54 static const wchar_t kRegKeyRoot
[] = L
"Software\\mozilla.org\\GRE";
55 static const wchar_t kRegFileGlobal
[] = L
"global.reginfo";
56 static const wchar_t kRegFileUser
[] = L
"user.reginfo";
59 MakeVersionKey(HKEY root
, const wchar_t* keyname
, const nsString
&grehome
,
60 const GREProperty
*aProperties
, PRUint32 aPropertiesLen
,
61 const wchar_t *aGREMilestone
)
66 if (::RegCreateKeyExW(root
, keyname
, NULL
, NULL
, 0, KEY_WRITE
, NULL
,
67 &subkey
, &disp
) != ERROR_SUCCESS
)
68 return NS_ERROR_FAILURE
;
70 if (disp
!= REG_CREATED_NEW_KEY
) {
71 ::RegCloseKey(subkey
);
72 return NS_ERROR_FAILURE
;
75 PRBool failed
= PR_FALSE
;
76 failed
|= ::RegSetValueExW(subkey
, L
"Version", NULL
, REG_SZ
,
77 (BYTE
*) aGREMilestone
,
78 sizeof(PRUnichar
) * (wcslen(aGREMilestone
) + 1))
80 failed
|= ::RegSetValueExW(subkey
, L
"GreHome", NULL
, REG_SZ
,
81 (BYTE
*) grehome
.get(),
82 sizeof(PRUnichar
) * (grehome
.Length() + 1))
85 for (PRUint32 i
= 0; i
< aPropertiesLen
; ++i
) {
86 // Properties should be ascii only
87 NS_ConvertASCIItoUTF16
prop(aProperties
[i
].property
);
88 NS_ConvertASCIItoUTF16
val(aProperties
[i
].value
);
89 failed
|= ::RegSetValueExW(subkey
, prop
.get(), NULL
, REG_SZ
,
91 sizeof(wchar_t)*(val
.Length()+1)
95 ::RegCloseKey(subkey
);
98 // we created a key but couldn't fill it properly: delete it
99 ::RegDeleteKeyW(root
, keyname
);
100 return NS_ERROR_FAILURE
;
107 RegisterXULRunner(PRBool aRegisterGlobally
, nsIFile
* aLocation
,
108 const GREProperty
*aProperties
, PRUint32 aPropertiesLen
,
109 const char *aGREMilestoneAscii
)
111 // Register ourself in the windows registry, and record what key we created
112 // for future unregistration.
117 NS_ConvertASCIItoUTF16
aGREMilestone(aGREMilestoneAscii
);
119 rv
= aLocation
->GetPath(greHome
);
123 nsCOMPtr
<nsIFile
> savedInfoFile
;
124 aLocation
->Clone(getter_AddRefs(savedInfoFile
));
125 nsCOMPtr
<nsILocalFile
> localSaved(do_QueryInterface(savedInfoFile
));
129 const wchar_t *infoname
= aRegisterGlobally
? kRegFileGlobal
: kRegFileUser
;
130 localSaved
->Append(nsDependentString(infoname
));
132 PRFileDesc
* fd
= nsnull
;
133 rv
= localSaved
->OpenNSPRFileDesc(PR_CREATE_FILE
| PR_RDWR
, 0664, &fd
);
140 wchar_t keyName
[MAXPATHLEN
];
143 if (::RegCreateKeyExW(aRegisterGlobally
? HKEY_LOCAL_MACHINE
:
145 kRegKeyRoot
, NULL
, NULL
, 0, KEY_WRITE
,
146 NULL
, &rootKey
, NULL
) != ERROR_SUCCESS
) {
151 r
= PR_Read(fd
, keyName
, MAXPATHLEN
);
160 // There was already a .reginfo file, let's see if we are already
162 HKEY existing
= NULL
;
163 if (::RegOpenKeyExW(rootKey
, keyName
, NULL
, KEY_QUERY_VALUE
, &existing
) ==
165 fprintf(stderr
, "Warning: Registry key Software\\mozilla.org\\GRE\\%s already exists.\n"
166 "No action was performed.\n",
175 rv
= localSaved
->OpenNSPRFileDesc(PR_CREATE_FILE
| PR_WRONLY
| PR_TRUNCATE
, 0664, &fd
);
183 wcscpy(keyName
, aGREMilestone
.get());
184 rv
= MakeVersionKey(rootKey
, keyName
, greHome
, aProperties
, aPropertiesLen
,
185 aGREMilestone
.get());
186 if (NS_SUCCEEDED(rv
)) {
187 NS_ConvertUTF16toUTF8
keyNameAscii(keyName
);
188 PR_Write(fd
, keyNameAscii
.get(), sizeof(char)*keyNameAscii
.Length());
193 for (i
= 0; i
< 1000; ++i
) {
194 swprintf(keyName
, L
"%s_%i", aGREMilestone
.get(), i
);
195 rv
= MakeVersionKey(rootKey
, keyName
, greHome
,
196 aProperties
, aPropertiesLen
,
197 aGREMilestone
.get());
198 if (NS_SUCCEEDED(rv
)) {
199 NS_ConvertUTF16toUTF8
keyNameAscii(keyName
);
200 PR_Write(fd
, keyNameAscii
.get(), sizeof(char)*keyNameAscii
.Length());
213 ::RegCloseKey(rootKey
);
219 UnregisterXULRunner(PRBool aGlobal
, nsIFile
* aLocation
,
220 const char *aGREMilestone
)
222 nsCOMPtr
<nsIFile
> savedInfoFile
;
223 aLocation
->Clone(getter_AddRefs(savedInfoFile
));
224 nsCOMPtr
<nsILocalFile
> localSaved (do_QueryInterface(savedInfoFile
));
228 const wchar_t *infoname
= aGlobal
? kRegFileGlobal
: kRegFileUser
;
229 localSaved
->Append(nsDependentString(infoname
));
231 PRFileDesc
* fd
= nsnull
;
232 nsresult rv
= localSaved
->OpenNSPRFileDesc(PR_RDONLY
, 0, &fd
);
238 wchar_t keyName
[MAXPATHLEN
];
239 PRInt32 r
= PR_Read(fd
, keyName
, MAXPATHLEN
);
242 localSaved
->Remove(PR_FALSE
);
250 if (::RegOpenKeyExW(aGlobal
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
251 kRegKeyRoot
, 0, KEY_READ
, &rootKey
) != ERROR_SUCCESS
)
255 if (::RegOpenKeyExW(rootKey
, keyName
, 0, KEY_READ
, &subKey
) == ERROR_SUCCESS
) {
257 char regpath
[MAXPATHLEN
];
258 DWORD reglen
= MAXPATHLEN
;
260 if (::RegQueryValueExW(subKey
, L
"GreHome", NULL
, NULL
,
261 (BYTE
*) regpath
, ®len
) == ERROR_SUCCESS
) {
263 nsCOMPtr
<nsILocalFile
> regpathfile
;
264 rv
= NS_NewNativeLocalFile(nsDependentCString(regpath
), PR_FALSE
,
265 getter_AddRefs(regpathfile
));
268 if (NS_SUCCEEDED(rv
) &&
269 NS_SUCCEEDED(aLocation
->Equals(regpathfile
, &eq
)) && !eq
) {
270 // We think we registered for this key, but it doesn't point to
272 fprintf(stderr
, "Warning: Registry key Software\\mozilla.org\\GRE\\%s points to\n"
273 "alternate path '%s'; unregistration was not successful.\n",
276 ::RegCloseKey(subKey
);
277 ::RegCloseKey(rootKey
);
283 ::RegCloseKey(subKey
);
286 ::RegDeleteKeyW(rootKey
, keyName
);
287 ::RegCloseKey(rootKey
);