toolkit/components/osfile/modules/osfile_win_allthreads.jsm

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /**
     6  * This module defines the thread-agnostic components of the Win version
     7  * of OS.File. It depends on the thread-agnostic cross-platform components
     8  * of OS.File.
     9  *
    10  * It serves the following purposes:
    11  * - open kernel32;
    12  * - define OS.Shared.Win.Error;
    13  * - define a few constants and types that need to be defined on all platforms.
    14  *
    15  * This module can be:
    16  * - opened from the main thread as a jsm module;
    17  * - opened from a chrome worker through require().
    18  */
    20 "use strict";
    22 let SharedAll;
    23 if (typeof Components != "undefined") {
    24   let Cu = Components.utils;
    25   // Module is opened as a jsm module
    26   Cu.import("resource://gre/modules/ctypes.jsm", this);
    28   SharedAll = {};
    29   Cu.import("resource://gre/modules/osfile/osfile_shared_allthreads.jsm", SharedAll);
    30   this.exports = {};
    31 } else if (typeof "module" != "undefined" && typeof "require" != "undefined") {
    32   // Module is loaded with require()
    33   SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
    34 } else {
    35   throw new Error("Please open this module with Component.utils.import or with require()");
    36 }
    38 let LOG = SharedAll.LOG.bind(SharedAll, "Win", "allthreads");
    39 let Const = SharedAll.Constants.Win;
    41 // Open libc
    42 let libc = new SharedAll.Library("libc", "kernel32.dll");
    43 exports.libc = libc;
    45 // Define declareFFI
    46 let declareFFI = SharedAll.declareFFI.bind(null, libc);
    47 exports.declareFFI = declareFFI;
    49 let Scope = {};
    51 // Define Error
    52 libc.declareLazy(Scope, "FormatMessage",
    53                  "FormatMessageW", ctypes.winapi_abi,
    54                  /*return*/ ctypes.uint32_t,
    55                  /*flags*/  ctypes.uint32_t,
    56                  /*source*/ ctypes.voidptr_t,
    57                  /*msgid*/  ctypes.uint32_t,
    58                  /*langid*/ ctypes.uint32_t,
    59                  /*buf*/    ctypes.jschar.ptr,
    60                  /*size*/   ctypes.uint32_t,
    61                  /*Arguments*/ctypes.voidptr_t);
    63 /**
    64  * A File-related error.
    65  *
    66  * To obtain a human-readable error message, use method |toString|.
    67  * To determine the cause of the error, use the various |becauseX|
    68  * getters. To determine the operation that failed, use field
    69  * |operation|.
    70  *
    71  * Additionally, this implementation offers a field
    72  * |winLastError|, which holds the OS-specific error
    73  * constant. If you need this level of detail, you may match the value
    74  * of this field against the error constants of |OS.Constants.Win|.
    75  *
    76  * @param {string=} operation The operation that failed. If unspecified,
    77  * the name of the calling function is taken to be the operation that
    78  * failed.
    79  * @param {number=} lastError The OS-specific constant detailing the
    80  * reason of the error. If unspecified, this is fetched from the system
    81  * status.
    82  * @param {string=} path The file path that manipulated. If unspecified,
    83  * assign the empty string.
    84  *
    85  * @constructor
    86  * @extends {OS.Shared.Error}
    87  */
    88 let OSError = function OSError(operation = "unknown operation",
    89                                lastError = ctypes.winLastError, path = "") {
    90   operation = operation;
    91   SharedAll.OSError.call(this, operation, path);
    92   this.winLastError = lastError;
    93 };
    94 OSError.prototype = Object.create(SharedAll.OSError.prototype);
    95 OSError.prototype.toString = function toString() {
    96   let buf = new (ctypes.ArrayType(ctypes.jschar, 1024))();
    97   let result = Scope.FormatMessage(
    98     Const.FORMAT_MESSAGE_FROM_SYSTEM |
    99     Const.FORMAT_MESSAGE_IGNORE_INSERTS,
   100     null,
   101     /* The error number */ this.winLastError,
   102     /* Default language */ 0,
   103     /* Output buffer*/     buf,
   104     /* Minimum size of buffer */ 1024,
   105     /* Format args*/       null
   106   );
   107   if (!result) {
   108     buf = "additional error " +
   109       ctypes.winLastError +
   110       " while fetching system error message";
   111   }
   112   return "Win error " + this.winLastError + " during operation "
   113     + this.operation + (this.path? " on file " + this.path : "") +
   114     " (" + buf.readString() + ")";
   115 };
   117 /**
   118  * |true| if the error was raised because a file or directory
   119  * already exists, |false| otherwise.
   120  */
   121 Object.defineProperty(OSError.prototype, "becauseExists", {
   122   get: function becauseExists() {
   123     return this.winLastError == Const.ERROR_FILE_EXISTS ||
   124       this.winLastError == Const.ERROR_ALREADY_EXISTS;
   125   }
   126 });
   127 /**
   128  * |true| if the error was raised because a file or directory
   129  * does not exist, |false| otherwise.
   130  */
   131 Object.defineProperty(OSError.prototype, "becauseNoSuchFile", {
   132   get: function becauseNoSuchFile() {
   133     return this.winLastError == Const.ERROR_FILE_NOT_FOUND ||
   134       this.winLastError == Const.ERROR_PATH_NOT_FOUND;
   135   }
   136 });
   137 /**
   138  * |true| if the error was raised because a directory is not empty
   139  * does not exist, |false| otherwise.
   140  */
   141 Object.defineProperty(OSError.prototype, "becauseNotEmpty", {
   142   get: function becauseNotEmpty() {
   143     return this.winLastError == Const.ERROR_DIR_NOT_EMPTY;
   144   }
   145 });
   146 /**
   147  * |true| if the error was raised because a file or directory
   148  * is closed, |false| otherwise.
   149  */
   150 Object.defineProperty(OSError.prototype, "becauseClosed", {
   151   get: function becauseClosed() {
   152     return this.winLastError == Const.ERROR_INVALID_HANDLE;
   153   }
   154 });
   155 /**
   156  * |true| if the error was raised because permission is denied to
   157  * access a file or directory, |false| otherwise.
   158  */
   159 Object.defineProperty(OSError.prototype, "becauseAccessDenied", {
   160   get: function becauseAccessDenied() {
   161     return this.winLastError == Const.ERROR_ACCESS_DENIED;
   162   }
   163 });
   164 /**
   165  * |true| if the error was raised because some invalid argument was passed,
   166  * |false| otherwise.
   167  */
   168 Object.defineProperty(OSError.prototype, "becauseInvalidArgument", {
   169   get: function becauseInvalidArgument() {
   170     return this.winLastError == Const.ERROR_NOT_SUPPORTED ||
   171            this.winLastError == Const.ERROR_BAD_ARGUMENTS;
   172   }
   173 });
   175 /**
   176  * Serialize an instance of OSError to something that can be
   177  * transmitted across threads (not necessarily a string).
   178  */
   179 OSError.toMsg = function toMsg(error) {
   180   return {
   181     operation: error.operation,
   182     winLastError: error.winLastError,
   183     path: error.path
   184   };
   185 };
   187 /**
   188  * Deserialize a message back to an instance of OSError
   189  */
   190 OSError.fromMsg = function fromMsg(msg) {
   191   return new OSError(msg.operation, msg.winLastError, msg.path);
   192 };
   193 exports.Error = OSError;
   195 /**
   196  * Code shared by implementation of File.Info on Windows
   197  *
   198  * @constructor
   199  */
   200 let AbstractInfo = function AbstractInfo(path, isDir, isSymLink, size,
   201                                          winBirthDate,
   202                                          lastAccessDate, lastWriteDate) {
   203   this._path = path;
   204   this._isDir = isDir;
   205   this._isSymLink = isSymLink;
   206   this._size = size;
   207   this._winBirthDate = winBirthDate;
   208   this._lastAccessDate = lastAccessDate;
   209   this._lastModificationDate = lastWriteDate;
   210 };
   212 AbstractInfo.prototype = {
   213   /**
   214    * The path of the file, used for error-reporting.
   215    *
   216    * @type {string}
   217    */
   218   get path() {
   219     return this._path;
   220   },
   221   /**
   222    * |true| if this file is a directory, |false| otherwise
   223    */
   224   get isDir() {
   225     return this._isDir;
   226   },
   227   /**
   228    * |true| if this file is a symbolic link, |false| otherwise
   229    */
   230   get isSymLink() {
   231     return this._isSymLink;
   232   },
   233   /**
   234    * The size of the file, in bytes.
   235    *
   236    * Note that the result may be |NaN| if the size of the file cannot be
   237    * represented in JavaScript.
   238    *
   239    * @type {number}
   240    */
   241   get size() {
   242     return this._size;
   243   },
   244   // Deprecated
   245   get creationDate() {
   246     return this._winBirthDate;
   247   },
   248   /**
   249    * The date of creation of this file.
   250    *
   251    * @type {Date}
   252    */
   253   get winBirthDate() {
   254     return this._winBirthDate;
   255   },
   256   /**
   257    * The date of last access to this file.
   258    *
   259    * Note that the definition of last access may depend on the underlying
   260    * operating system and file system.
   261    *
   262    * @type {Date}
   263    */
   264   get lastAccessDate() {
   265     return this._lastAccessDate;
   266   },
   267   /**
   268    * The date of last modification of this file.
   269    *
   270    * Note that the definition of last access may depend on the underlying
   271    * operating system and file system.
   272    *
   273    * @type {Date}
   274    */
   275   get lastModificationDate() {
   276     return this._lastModificationDate;
   277   }
   278 };
   279 exports.AbstractInfo = AbstractInfo;
   281 /**
   282  * Code shared by implementation of File.DirectoryIterator.Entry on Windows
   283  *
   284  * @constructor
   285  */
   286 let AbstractEntry = function AbstractEntry(isDir, isSymLink, name,
   287                                            winCreationDate, winLastWriteDate,
   288                                            winLastAccessDate, path) {
   289   this._isDir = isDir;
   290   this._isSymLink = isSymLink;
   291   this._name = name;
   292   this._winCreationDate = winCreationDate;
   293   this._winLastWriteDate = winLastWriteDate;
   294   this._winLastAccessDate = winLastAccessDate;
   295   this._path = path;
   296 };
   298 AbstractEntry.prototype = {
   299   /**
   300    * |true| if the entry is a directory, |false| otherwise
   301    */
   302   get isDir() {
   303     return this._isDir;
   304   },
   305   /**
   306    * |true| if the entry is a symbolic link, |false| otherwise
   307    */
   308   get isSymLink() {
   309     return this._isSymLink;
   310   },
   311   /**
   312    * The name of the entry.
   313    * @type {string}
   314    */
   315   get name() {
   316     return this._name;
   317   },
   318   /**
   319    * The creation time of this file.
   320    * @type {Date}
   321    */
   322   get winCreationDate() {
   323     return this._winCreationDate;
   324   },
   325   /**
   326    * The last modification time of this file.
   327    * @type {Date}
   328    */
   329   get winLastWriteDate() {
   330     return this._winLastWriteDate;
   331   },
   332   /**
   333    * The last access time of this file.
   334    * @type {Date}
   335    */
   336   get winLastAccessDate() {
   337     return this._winLastAccessDate;
   338   },
   339   /**
   340    * The full path of the entry
   341    * @type {string}
   342    */
   343   get path() {
   344     return this._path;
   345   }
   346 };
   347 exports.AbstractEntry = AbstractEntry;
   349 // Special constants that need to be defined on all platforms
   351 exports.POS_START = Const.FILE_BEGIN;
   352 exports.POS_CURRENT = Const.FILE_CURRENT;
   353 exports.POS_END = Const.FILE_END;
   355 // Special types that need to be defined for communication
   356 // between threads
   357 let Type = Object.create(SharedAll.Type);
   358 exports.Type = Type;
   360 /**
   361  * Native paths
   362  *
   363  * Under Windows, expressed as wide strings
   364  */
   365 Type.path = Type.wstring.withName("[in] path");
   366 Type.out_path = Type.out_wstring.withName("[out] path");
   368 // Special constructors that need to be defined on all threads
   369 OSError.closed = function closed(operation, path) {
   370   return new OSError(operation, Const.ERROR_INVALID_HANDLE, path);
   371 };
   373 OSError.exists = function exists(operation, path) {
   374   return new OSError(operation, Const.ERROR_FILE_EXISTS, path);
   375 };
   377 OSError.noSuchFile = function noSuchFile(operation, path) {
   378   return new OSError(operation, Const.ERROR_FILE_NOT_FOUND, path);
   379 };
   381 OSError.invalidArgument = function invalidArgument(operation) {
   382   return new OSError(operation, Const.ERROR_NOT_SUPPORTED);
   383 };
   385 let EXPORTED_SYMBOLS = [
   386   "declareFFI",
   387   "libc",
   388   "Error",
   389   "AbstractInfo",
   390   "AbstractEntry",
   391   "Type",
   392   "POS_START",
   393   "POS_CURRENT",
   394   "POS_END"
   395 ];
   397 //////////// Boilerplate
   398 if (typeof Components != "undefined") {
   399   this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
   400   for (let symbol of EXPORTED_SYMBOLS) {
   401     this[symbol] = exports[symbol];
   402   }
   403 }

mercurial