Bug 761138 - Create/remove directories (Windows version). r=froydnj
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Fri, 24 Aug 2012 16:18:15 -0400
changeset 105373 d94e6c20c4dc9e1b6df52c73e723fda55948be70
parent 105372 f9b8fb3c9395aaadd36be46e36d8036d2bd0a216
child 105374 3eb65ac5a609267437717ea444a6c9438aa60d69
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersfroydnj
bugs761138
milestone17.0a1
Bug 761138 - Create/remove directories (Windows version). r=froydnj
toolkit/components/osfile/osfile_win_allthreads.jsm
toolkit/components/osfile/osfile_win_back.jsm
toolkit/components/osfile/osfile_win_front.jsm
--- a/toolkit/components/osfile/osfile_win_allthreads.jsm
+++ b/toolkit/components/osfile/osfile_win_allthreads.jsm
@@ -114,28 +114,38 @@ if (typeof Components != "undefined") {
   };
 
   /**
    * |true| if the error was raised because a file or directory
    * already exists, |false| otherwise.
    */
   Object.defineProperty(OSError.prototype, "becauseExists", {
     get: function becauseExists() {
-      return this.winLastError == exports.OS.Constants.Win.ERROR_FILE_EXISTS;
+      return this.winLastError == exports.OS.Constants.Win.ERROR_FILE_EXISTS ||
+        this.winLastError == exports.OS.Constants.Win.ERROR_ALREADY_EXISTS;
     }
   });
   /**
    * |true| if the error was raised because a file or directory
    * does not exist, |false| otherwise.
    */
   Object.defineProperty(OSError.prototype, "becauseNoSuchFile", {
     get: function becauseNoSuchFile() {
       return this.winLastError == exports.OS.Constants.Win.ERROR_FILE_NOT_FOUND;
     }
   });
+  /**
+   * |true| if the error was raised because a directory is not empty
+   * does not exist, |false| otherwise.
+   */
+  Object.defineProperty(OSError.prototype, "becauseNotEmpty", {
+    get: function becauseNotEmpty() {
+      return this.winLastError == OS.Constants.Win.ERROR_DIR_NOT_EMPTY;
+    }
+  });
 
   /**
    * Serialize an instance of OSError to something that can be
    * transmitted across threads (not necessarily a string).
    */
   OSError.toMsg = function toMsg(error) {
     return {
       operation: error.operation,
--- a/toolkit/components/osfile/osfile_win_back.jsm
+++ b/toolkit/components/osfile/osfile_win_back.jsm
@@ -119,16 +119,19 @@
 
        /**
         * A C integer holding 0 in case of error, any other value in
         * case of success.
         */
        Types.zero_or_nothing =
          Types.int.withName("zero_or_nothing");
 
+       Types.SECURITY_ATTRIBUTES =
+         Types.void_t.withName("SECURITY_ATTRIBUTES");
+
        Types.FILETIME =
          new Type("FILETIME",
                   ctypes.StructType("FILETIME", [
                   { lo: Types.DWORD.implementation },
                   { hi: Types.DWORD.implementation }]));
 
        Types.FindData =
          new Type("FIND_DATA",
@@ -196,23 +199,29 @@
 
        WinFile.CopyFile =
          declareFFI("CopyFileW", ctypes.winapi_abi,
                     /*return*/ Types.zero_or_nothing,
                     /*sourcePath*/ Types.path,
                     /*destPath*/   Types.path,
                     /*bailIfExist*/Types.bool);
 
+       WinFile.CreateDirectory =
+         declareFFI("CreateDirectoryW", ctypes.winapi_abi,
+                    /*return*/ Types.zero_or_nothing,
+                    /*name*/   Types.jschar.in_ptr,
+                    /*security*/Types.SECURITY_ATTRIBUTES.in_ptr);
+
        WinFile.CreateFile =
          declareFFI("CreateFileW", ctypes.winapi_abi,
                     /*return*/  Types.maybe_HANDLE,
                     /*name*/    Types.path,
                     /*access*/  Types.DWORD,
                     /*share*/   Types.DWORD,
-                    /*security*/Types.void_t.in_ptr,// FIXME: Implement?
+                    /*security*/Types.SECURITY_ATTRIBUTES.in_ptr,
                     /*creation*/Types.DWORD,
                     /*flags*/   Types.DWORD,
                     /*template*/Types.HANDLE);
 
        WinFile.DeleteFile =
          declareFFI("DeleteFileW", ctypes.winapi_abi,
                     /*return*/ Types.zero_or_nothing,
                     /*path*/   Types.path);
--- a/toolkit/components/osfile/osfile_win_front.jsm
+++ b/toolkit/components/osfile/osfile_win_front.jsm
@@ -327,16 +327,55 @@
       * @throws {OS.File.Error} In case of I/O error.
       */
      File.remove = function remove(path) {
        throw_on_zero("remove",
          WinFile.DeleteFile(path));
      };
 
      /**
+      * Remove an empty directory.
+      *
+      * @param {string} path The name of the directory to remove.
+      * @param {*=} options Additional options.
+      *   - {bool} ignoreAbsent If |true|, do not fail if the
+      *     directory does not exist yet.
+      */
+     File.removeEmptyDir = function removeEmptyDir(path, options) {
+       options = options || noOptions;
+       let result = WinFile.RemoveDirectory(path);
+       if (!result) {
+         if (options.ignoreAbsent &&
+             ctypes.winLastError == Const.ERROR_FILE_NOT_FOUND) {
+           return;
+         }
+         throw new File.Error("removeEmptyDir");
+       }
+     };
+
+     /**
+      * Create a directory.
+      *
+      * @param {string} path The name of the directory.
+      * @param {*=} options Additional options. This
+      * implementation interprets the following fields:
+      *
+      * - {C pointer} winSecurity If specified, security attributes
+      * as per winapi function |CreateDirectory|. If unspecified,
+      * use the default security descriptor, inherited from the
+      * parent directory.
+      */
+     File.makeDir = function makeDir(path, options) {
+       options = options || noOptions;
+       let security = options.winSecurity || null;
+       throw_on_zero("makeDir",
+         WinFile.CreateDirectory(path, security));
+     };
+
+     /**
       * Copy a file to a destination.
       *
       * @param {string} sourcePath The platform-specific path at which
       * the file may currently be found.
       * @param {string} destPath The platform-specific path at which the
       * file should be copied.
       * @param {*=} options An object which may contain the following fields:
       *