diff --git a/toolkit/components/osfile/osfile_win_allthreads.jsm b/toolkit/components/osfile/osfile_win_allthreads.jsm index 959252211233..b1a83284f0c7 100644 --- a/toolkit/components/osfile/osfile_win_allthreads.jsm +++ b/toolkit/components/osfile/osfile_win_allthreads.jsm @@ -119,7 +119,8 @@ if (typeof Components != "undefined") { */ 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; } }); /** @@ -131,6 +132,15 @@ if (typeof Components != "undefined") { 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 diff --git a/toolkit/components/osfile/osfile_win_back.jsm b/toolkit/components/osfile/osfile_win_back.jsm index 655e42f566f5..aee7c8e42c74 100644 --- a/toolkit/components/osfile/osfile_win_back.jsm +++ b/toolkit/components/osfile/osfile_win_back.jsm @@ -124,6 +124,9 @@ 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", [ @@ -201,13 +204,19 @@ /*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); diff --git a/toolkit/components/osfile/osfile_win_front.jsm b/toolkit/components/osfile/osfile_win_front.jsm index a0d82c825a19..d639b46c2317 100644 --- a/toolkit/components/osfile/osfile_win_front.jsm +++ b/toolkit/components/osfile/osfile_win_front.jsm @@ -331,6 +331,45 @@ 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. *