diff options
Diffstat (limited to 'application/palemoon/components/migration/IEProfileMigrator.js')
-rw-r--r-- | application/palemoon/components/migration/IEProfileMigrator.js | 521 |
1 files changed, 0 insertions, 521 deletions
diff --git a/application/palemoon/components/migration/IEProfileMigrator.js b/application/palemoon/components/migration/IEProfileMigrator.js deleted file mode 100644 index a46deae68..000000000 --- a/application/palemoon/components/migration/IEProfileMigrator.js +++ /dev/null @@ -1,521 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -const kMainKey = "Software\\Microsoft\\Internet Explorer\\Main"; -const kRegMultiSz = 7; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/NetUtil.jsm"); -Cu.import("resource:///modules/MigrationUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "ctypes", - "resource://gre/modules/ctypes.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry", - "resource://gre/modules/WindowsRegistry.jsm"); - -Cu.importGlobalProperties(["File"]); - -//////////////////////////////////////////////////////////////////////////////// -//// Helpers. - -let CtypesHelpers = { - _structs: {}, - _functions: {}, - _libs: {}, - - /** - * Must be invoked once before first use of any of the provided helpers. - */ - initialize: function CH_initialize() { - const WORD = ctypes.uint16_t; - const DWORD = ctypes.uint32_t; - const BOOL = ctypes.int; - - this._structs.SYSTEMTIME = new ctypes.StructType('SYSTEMTIME', [ - {wYear: WORD}, - {wMonth: WORD}, - {wDayOfWeek: WORD}, - {wDay: WORD}, - {wHour: WORD}, - {wMinute: WORD}, - {wSecond: WORD}, - {wMilliseconds: WORD} - ]); - - this._structs.FILETIME = new ctypes.StructType('FILETIME', [ - {dwLowDateTime: DWORD}, - {dwHighDateTime: DWORD} - ]); - - try { - this._libs.kernel32 = ctypes.open("Kernel32"); - this._functions.FileTimeToSystemTime = - this._libs.kernel32.declare("FileTimeToSystemTime", - ctypes.default_abi, - BOOL, - this._structs.FILETIME.ptr, - this._structs.SYSTEMTIME.ptr); - } catch (ex) { - this.finalize(); - } - }, - - /** - * Must be invoked once after last use of any of the provided helpers. - */ - finalize: function CH_finalize() { - this._structs = {}; - this._functions = {}; - for each (let lib in this._libs) { - try { - lib.close(); - } catch (ex) {} - } - this._libs = {}; - }, - - /** - * Converts a FILETIME struct (2 DWORDS), to a SYSTEMTIME struct. - * - * @param aTimeHi - * Least significant DWORD. - * @param aTimeLo - * Most significant DWORD. - * @return a Date object representing the converted datetime. - */ - fileTimeToDate: function CH_fileTimeToDate(aTimeHi, aTimeLo) { - let fileTime = this._structs.FILETIME(); - fileTime.dwLowDateTime = aTimeLo; - fileTime.dwHighDateTime = aTimeHi; - let systemTime = this._structs.SYSTEMTIME(); - let result = this._functions.FileTimeToSystemTime(fileTime.address(), - systemTime.address()); - if (result == 0) - throw new Error(ctypes.winLastError); - - return new Date(systemTime.wYear, - systemTime.wMonth - 1, - systemTime.wDay, - systemTime.wHour, - systemTime.wMinute, - systemTime.wSecond, - systemTime.wMilliseconds); - } -}; - -/** - * Checks whether an host is an IP (v4 or v6) address. - * - * @param aHost - * The host to check. - * @return whether aHost is an IP address. - */ -function hostIsIPAddress(aHost) { - try { - Services.eTLD.getBaseDomainFromHost(aHost); - } catch (e if e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS) { - return true; - } catch (e) {} - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -//// Resources - -function Bookmarks() { -} - -Bookmarks.prototype = { - type: MigrationUtils.resourceTypes.BOOKMARKS, - - get exists() !!this._favoritesFolder, - - __favoritesFolder: null, - get _favoritesFolder() { - if (!this.__favoritesFolder) { - let favoritesFolder = Services.dirsvc.get("Favs", Ci.nsIFile); - if (favoritesFolder.exists() && favoritesFolder.isReadable()) - this.__favoritesFolder = favoritesFolder; - } - return this.__favoritesFolder; - }, - - __toolbarFolderName: null, - get _toolbarFolderName() { - if (!this.__toolbarFolderName) { - // Retrieve the name of IE's favorites subfolder that holds the bookmarks - // in the toolbar. This was previously stored in the registry and changed - // in IE7 to always be called "Links". - let folderName = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - "Software\\Microsoft\\Internet Explorer\\Toolbar", - "LinksFolderName"); - this.__toolbarFolderName = folderName || "Links"; - } - return this.__toolbarFolderName; - }, - - migrate: function B_migrate(aCallback) { - PlacesUtils.bookmarks.runInBatchMode({ - runBatched: (function migrateBatched() { - // Import to the bookmarks menu. - let destFolderId = PlacesUtils.bookmarksMenuFolderId; - if (!MigrationUtils.isStartupMigration) { - destFolderId = - MigrationUtils.createImportedBookmarksFolder("IE", destFolderId); - } - - this._migrateFolder(this._favoritesFolder, destFolderId); - - aCallback(true); - }).bind(this) - }, null); - }, - - _migrateFolder: function B__migrateFolder(aSourceFolder, aDestFolderId) { - // TODO (bug 741993): the favorites order is stored in the Registry, at - // HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Favorites - // Until we support it, bookmarks are imported in alphabetical order. - let entries = aSourceFolder.directoryEntries; - while (entries.hasMoreElements()) { - let entry = entries.getNext().QueryInterface(Ci.nsIFile); - - // Make sure that entry.path == entry.target to not follow .lnk folder - // shortcuts which could lead to infinite cycles. - if (entry.isDirectory() && entry.path == entry.target) { - let destFolderId; - if (entry.leafName == this._toolbarFolderName && - entry.parent.equals(this._favoritesFolder)) { - // Import to the bookmarks toolbar. - destFolderId = PlacesUtils.toolbarFolderId; - if (!MigrationUtils.isStartupMigration) { - destFolderId = - MigrationUtils.createImportedBookmarksFolder("IE", destFolderId); - } - } - else { - // Import to a new folder. - destFolderId = - PlacesUtils.bookmarks.createFolder(aDestFolderId, entry.leafName, - PlacesUtils.bookmarks.DEFAULT_INDEX); - } - - if (entry.isReadable()) { - // Recursively import the folder. - this._migrateFolder(entry, destFolderId); - } - } - else { - // Strip the .url extension, to both check this is a valid link file, - // and get the associated title. - let matches = entry.leafName.match(/(.+)\.url$/i); - if (matches) { - let fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"]. - getService(Ci.nsIFileProtocolHandler); - let uri = fileHandler.readURLFile(entry); - let title = matches[1]; - - PlacesUtils.bookmarks.insertBookmark(aDestFolderId, - uri, - PlacesUtils.bookmarks.DEFAULT_INDEX, - title); - } - } - } - } -}; - -function History() { -} - -History.prototype = { - type: MigrationUtils.resourceTypes.HISTORY, - - get exists() true, - - __typedURLs: null, - get _typedURLs() { - if (!this.__typedURLs) { - // The list of typed URLs is a sort of annotation stored in the registry. - // Currently, IE stores 25 entries and this value is not configurable, - // but we just keep reading up to the first non-existing entry to support - // possible future bumps of this limit. - this.__typedURLs = {}; - let registry = Cc["@mozilla.org/windows-registry-key;1"]. - createInstance(Ci.nsIWindowsRegKey); - try { - registry.open(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - "Software\\Microsoft\\Internet Explorer\\TypedURLs", - Ci.nsIWindowsRegKey.ACCESS_READ); - for (let entry = 1; registry.hasValue("url" + entry); entry++) { - let url = registry.readStringValue("url" + entry); - this.__typedURLs[url] = true; - } - } catch (ex) { - } finally { - registry.close(); - } - } - return this.__typedURLs; - }, - - migrate: function H_migrate(aCallback) { - let places = []; - let historyEnumerator = Cc["@mozilla.org/profile/migrator/iehistoryenumerator;1"]. - createInstance(Ci.nsISimpleEnumerator); - while (historyEnumerator.hasMoreElements()) { - let entry = historyEnumerator.getNext().QueryInterface(Ci.nsIPropertyBag2); - let uri = entry.get("uri").QueryInterface(Ci.nsIURI); - // MSIE stores some types of URLs in its history that we don't handle, - // like HTMLHelp and others. Since we don't properly map handling for - // all of them we just avoid importing them. - if (["http", "https", "ftp", "file"].indexOf(uri.scheme) == -1) { - continue; - } - - let title = entry.get("title"); - // Embed visits have no title and don't need to be imported. - if (title.length == 0) { - continue; - } - - // The typed urls are already fixed-up, so we can use them for comparison. - let transitionType = this._typedURLs[uri.spec] ? - Ci.nsINavHistoryService.TRANSITION_TYPED : - Ci.nsINavHistoryService.TRANSITION_LINK; - let lastVisitTime = entry.get("time"); - - places.push( - { uri: uri, - title: title, - visits: [{ transitionType: transitionType, - visitDate: lastVisitTime }] - } - ); - } - - // Check whether there is any history to import. - if (places.length == 0) { - aCallback(true); - return; - } - - PlacesUtils.asyncHistory.updatePlaces(places, { - _success: false, - handleResult: function() { - // Importing any entry is considered a successful import. - this._success = true; - }, - handleError: function() {}, - handleCompletion: function() { - aCallback(this._success); - } - }); - } -}; - -function Cookies() { -} - -Cookies.prototype = { - type: MigrationUtils.resourceTypes.COOKIES, - - get exists() !!this._cookiesFolder, - - __cookiesFolder: null, - get _cookiesFolder() { - // Cookies are stored in txt files, in a Cookies folder whose path varies - // across the different OS versions. CookD takes care of most of these - // cases, though, in Windows Vista/7, UAC makes a difference. - // If UAC is enabled, the most common destination is CookD/Low. Though, - // if the user runs the application in administrator mode or disables UAC, - // cookies are stored in the original CookD destination. Cause running the - // browser in administrator mode is unsafe and discouraged, we just care - // about the UAC state. - if (!this.__cookiesFolder) { - let cookiesFolder = Services.dirsvc.get("CookD", Ci.nsIFile); - if (cookiesFolder.exists() && cookiesFolder.isReadable()) { - // Check if UAC is enabled. - if (Services.appinfo.QueryInterface(Ci.nsIWinAppHelper).userCanElevate) { - cookiesFolder.append("Low"); - } - this.__cookiesFolder = cookiesFolder; - } - } - return this.__cookiesFolder; - }, - - migrate: function C_migrate(aCallback) { - CtypesHelpers.initialize(); - - let cookiesGenerator = (function genCookie() { - let success = false; - let entries = this._cookiesFolder.directoryEntries; - while (entries.hasMoreElements()) { - let entry = entries.getNext().QueryInterface(Ci.nsIFile); - // Skip eventual bogus entries. - if (!entry.isFile() || !/\.txt$/.test(entry.leafName)) - continue; - - this._readCookieFile(entry, function(aSuccess) { - // Importing even a single cookie file is considered a success. - if (aSuccess) - success = true; - try { - cookiesGenerator.next(); - } catch (ex) {} - }); - - yield; - } - - CtypesHelpers.finalize(); - - aCallback(success); - }).apply(this); - cookiesGenerator.next(); - }, - - _readCookieFile: function C__readCookieFile(aFile, aCallback) { - let fileReader = Cc["@mozilla.org/files/filereader;1"]. - createInstance(Ci.nsIDOMFileReader); - fileReader.addEventListener("loadend", (function onLoadEnd() { - fileReader.removeEventListener("loadend", onLoadEnd, false); - - if (fileReader.readyState != fileReader.DONE) { - Cu.reportError("Could not read cookie contents: " + fileReader.error); - aCallback(false); - return; - } - - let success = true; - try { - this._parseCookieBuffer(fileReader.result); - } catch (ex) { - Components.utils.reportError("Unable to migrate cookie: " + ex); - success = false; - } finally { - aCallback(success); - } - }).bind(this), false); - fileReader.readAsText(new File(aFile)); - }, - - /** - * Parses a cookie file buffer and returns an array of the contained cookies. - * - * The cookie file format is a newline-separated-values with a "*" used as - * delimeter between multiple records. - * Each cookie has the following fields: - * - name - * - value - * - host/path - * - flags - * - Expiration time most significant integer - * - Expiration time least significant integer - * - Creation time most significant integer - * - Creation time least significant integer - * - Record delimiter "*" - * - * @note All the times are in FILETIME format. - */ - _parseCookieBuffer: function C__parseCookieBuffer(aTextBuffer) { - // Note the last record is an empty string. - let records = [r for each (r in aTextBuffer.split("*\n")) if (r)]; - for (let record of records) { - let [name, value, hostpath, flags, - expireTimeLo, expireTimeHi] = record.split("\n"); - - // IE stores deleted cookies with a zero-length value, skip them. - if (value.length == 0) - continue; - - let hostLen = hostpath.indexOf("/"); - let host = hostpath.substr(0, hostLen); - let path = hostpath.substr(hostLen); - - // For a non-null domain, assume it's what Mozilla considers - // a domain cookie. See bug 222343. - if (host.length > 0) { - // Fist delete any possible extant matching host cookie. - Services.cookies.remove(host, name, path, false); - // Now make it a domain cookie. - if (host[0] != "." && !hostIsIPAddress(host)) - host = "." + host; - } - - let expireTime = CtypesHelpers.fileTimeToDate(Number(expireTimeHi), - Number(expireTimeLo)); - Services.cookies.add(host, - path, - name, - value, - Number(flags) & 0x1, // secure - false, // httpOnly - false, // session - expireTime); - } - } -}; - - -//////////////////////////////////////////////////////////////////////////////// -//// Migrator - -function IEProfileMigrator() -{ -} - -IEProfileMigrator.prototype = Object.create(MigratorPrototype); - -IEProfileMigrator.prototype.getResources = function IE_getResources() { - let resources = [ - new Bookmarks() - , new History() - , new Cookies() - ]; - return [r for each (r in resources) if (r.exists)]; -}; - -Object.defineProperty(IEProfileMigrator.prototype, "sourceHomePageURL", { - get: function IE_get_sourceHomePageURL() { - let defaultStartPage = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE, - kMainKey, "Default_Page_URL"); - let startPage = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - kMainKey, "Start Page"); - // If the user didn't customize the Start Page, he is still on the default - // page, that may be considered the equivalent of our about:home. There's - // no reason to retain it, since it is heavily targeted to IE. - let homepage = startPage != defaultStartPage ? startPage : ""; - - // IE7+ supports secondary home pages located in a REG_MULTI_SZ key. These - // are in addition to the Start Page, and no empty entries are possible, - // thus a Start Page is always defined if any of these exists, though it - // may be the default one. - let secondaryPages = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, - kMainKey, "Secondary Start Pages"); - if (secondaryPages) { - if (homepage) - secondaryPages.unshift(homepage); - homepage = secondaryPages.join("|"); - } - - return homepage; - } -}); - -IEProfileMigrator.prototype.classDescription = "IE Profile Migrator"; -IEProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=ie"; -IEProfileMigrator.prototype.classID = Components.ID("{3d2532e3-4932-4774-b7ba-968f5899d3a4}"); - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([IEProfileMigrator]); |