summaryrefslogtreecommitdiffstats
path: root/toolkit/components/osfile/modules/osfile_win_back.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/osfile/modules/osfile_win_back.js')
-rw-r--r--toolkit/components/osfile/modules/osfile_win_back.js542
1 files changed, 542 insertions, 0 deletions
diff --git a/toolkit/components/osfile/modules/osfile_win_back.js b/toolkit/components/osfile/modules/osfile_win_back.js
new file mode 100644
index 0000000000..5460ef7830
--- /dev/null
+++ b/toolkit/components/osfile/modules/osfile_win_back.js
@@ -0,0 +1,542 @@
+/* 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/. */
+
+/**
+ * This file can be used in the following contexts:
+ *
+ * 1. included from a non-osfile worker thread using importScript
+ * (it serves to define a synchronous API for that worker thread)
+ * (bug 707681)
+ *
+ * 2. included from the main thread using Components.utils.import
+ * (it serves to define the asynchronous API, whose implementation
+ * resides in the worker thread)
+ * (bug 729057)
+ *
+ * 3. included from the osfile worker thread using importScript
+ * (it serves to define the implementation of the asynchronous API)
+ * (bug 729057)
+ */
+
+/* eslint-env mozilla/chrome-worker, node */
+
+// eslint-disable-next-line no-lone-blocks
+{
+ if (typeof Components != "undefined") {
+ // We do not wish osfile_win_back.js to be used directly as a main thread
+ // module yet. When time comes, it will be loaded by a combination of
+ // a main thread front-end/worker thread implementation that makes sure
+ // that we are not executing synchronous IO code in the main thread.
+
+ throw new Error(
+ "osfile_win_back.js cannot be used from the main thread yet"
+ );
+ }
+
+ (function(exports) {
+ "use strict";
+ if (exports.OS && exports.OS.Win && exports.OS.Win.File) {
+ return; // Avoid double initialization
+ }
+
+ let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
+ let SysAll = require("resource://gre/modules/osfile/osfile_win_allthreads.jsm");
+ SharedAll.LOG.bind(SharedAll, "Unix", "back");
+ let libc = SysAll.libc;
+ let advapi32 = new SharedAll.Library("advapi32", "advapi32.dll");
+ let Const = SharedAll.Constants.Win;
+
+ /**
+ * Initialize the Windows module.
+ *
+ * @param {function=} declareFFI
+ */
+ // FIXME: Both |init| and |aDeclareFFI| are deprecated, we should remove them
+ let init = function init(aDeclareFFI) {
+ let declareFFI;
+ if (aDeclareFFI) {
+ declareFFI = aDeclareFFI.bind(null, libc);
+ } else {
+ declareFFI = SysAll.declareFFI; // eslint-disable-line no-unused-vars
+ }
+ let declareLazyFFI = SharedAll.declareLazyFFI; // eslint-disable-line no-unused-vars
+
+ // Initialize types that require additional OS-specific
+ // support - either finalization or matching against
+ // OS-specific constants.
+ let Type = Object.create(SysAll.Type);
+ let SysFile = (exports.OS.Win.File = { Type });
+
+ // Initialize types
+
+ /**
+ * A C integer holding INVALID_HANDLE_VALUE in case of error or
+ * a file descriptor in case of success.
+ */
+ Type.HANDLE = Type.voidptr_t.withName("HANDLE");
+ Type.HANDLE.importFromC = function importFromC(maybe) {
+ if (Type.int.cast(maybe).value == INVALID_HANDLE) {
+ // Ensure that API clients can effectively compare against
+ // Const.INVALID_HANDLE_VALUE. Without this cast,
+ // == would always return |false|.
+ return INVALID_HANDLE;
+ }
+ return ctypes.CDataFinalizer(maybe, this.finalizeHANDLE);
+ };
+ Type.HANDLE.finalizeHANDLE = function placeholder() {
+ throw new Error("finalizeHANDLE should be implemented");
+ };
+ let INVALID_HANDLE = Const.INVALID_HANDLE_VALUE;
+
+ Type.file_HANDLE = Type.HANDLE.withName("file HANDLE");
+ SharedAll.defineLazyGetter(
+ Type.file_HANDLE,
+ "finalizeHANDLE",
+ function() {
+ return SysFile._CloseHandle;
+ }
+ );
+
+ Type.find_HANDLE = Type.HANDLE.withName("find HANDLE");
+ SharedAll.defineLazyGetter(
+ Type.find_HANDLE,
+ "finalizeHANDLE",
+ function() {
+ return SysFile._FindClose;
+ }
+ );
+
+ Type.DWORD = Type.uint32_t.withName("DWORD");
+
+ /* A special type used to represent flags passed as DWORDs to a function.
+ * In JavaScript, bitwise manipulation of numbers, such as or-ing flags,
+ * can produce negative numbers. Since DWORD is unsigned, these negative
+ * numbers simply cannot be converted to DWORD. For this reason, whenever
+ * bit manipulation is called for, you should rather use DWORD_FLAGS,
+ * which is represented as a signed integer, hence has the correct
+ * semantics.
+ */
+ Type.DWORD_FLAGS = Type.int32_t.withName("DWORD_FLAGS");
+
+ /**
+ * A C integer holding 0 in case of error or a positive integer
+ * in case of success.
+ */
+ Type.zero_or_DWORD = Type.DWORD.withName("zero_or_DWORD");
+
+ /**
+ * A C integer holding 0 in case of error, any other value in
+ * case of success.
+ */
+ Type.zero_or_nothing = Type.int.withName("zero_or_nothing");
+
+ /**
+ * A C integer holding flags related to NTFS security.
+ */
+ Type.SECURITY_ATTRIBUTES = Type.void_t.withName("SECURITY_ATTRIBUTES");
+
+ /**
+ * A C integer holding pointers related to NTFS security.
+ */
+ Type.PSID = Type.voidptr_t.withName("PSID");
+
+ Type.PACL = Type.voidptr_t.withName("PACL");
+
+ Type.PSECURITY_DESCRIPTOR = Type.voidptr_t.withName(
+ "PSECURITY_DESCRIPTOR"
+ );
+
+ /**
+ * A C integer holding Win32 local memory handle.
+ */
+ Type.HLOCAL = Type.voidptr_t.withName("HLOCAL");
+
+ Type.FILETIME = new SharedAll.Type(
+ "FILETIME",
+ ctypes.StructType("FILETIME", [
+ { lo: Type.DWORD.implementation },
+ { hi: Type.DWORD.implementation },
+ ])
+ );
+
+ Type.FindData = new SharedAll.Type(
+ "FIND_DATA",
+ ctypes.StructType("FIND_DATA", [
+ { dwFileAttributes: ctypes.uint32_t },
+ { ftCreationTime: Type.FILETIME.implementation },
+ { ftLastAccessTime: Type.FILETIME.implementation },
+ { ftLastWriteTime: Type.FILETIME.implementation },
+ { nFileSizeHigh: Type.DWORD.implementation },
+ { nFileSizeLow: Type.DWORD.implementation },
+ { dwReserved0: Type.DWORD.implementation },
+ { dwReserved1: Type.DWORD.implementation },
+ { cFileName: ctypes.ArrayType(ctypes.char16_t, Const.MAX_PATH) },
+ { cAlternateFileName: ctypes.ArrayType(ctypes.char16_t, 14) },
+ ])
+ );
+
+ Type.FILE_INFORMATION = new SharedAll.Type(
+ "FILE_INFORMATION",
+ ctypes.StructType("FILE_INFORMATION", [
+ { dwFileAttributes: ctypes.uint32_t },
+ { ftCreationTime: Type.FILETIME.implementation },
+ { ftLastAccessTime: Type.FILETIME.implementation },
+ { ftLastWriteTime: Type.FILETIME.implementation },
+ { dwVolumeSerialNumber: ctypes.uint32_t },
+ { nFileSizeHigh: Type.DWORD.implementation },
+ { nFileSizeLow: Type.DWORD.implementation },
+ { nNumberOfLinks: ctypes.uint32_t },
+ { nFileIndex: ctypes.uint64_t },
+ ])
+ );
+
+ Type.SystemTime = new SharedAll.Type(
+ "SystemTime",
+ ctypes.StructType("SystemTime", [
+ { wYear: ctypes.int16_t },
+ { wMonth: ctypes.int16_t },
+ { wDayOfWeek: ctypes.int16_t },
+ { wDay: ctypes.int16_t },
+ { wHour: ctypes.int16_t },
+ { wMinute: ctypes.int16_t },
+ { wSecond: ctypes.int16_t },
+ { wMilliSeconds: ctypes.int16_t },
+ ])
+ );
+
+ // Special case: these functions are used by the
+ // finalizer
+ libc.declareLazy(
+ SysFile,
+ "_CloseHandle",
+ "CloseHandle",
+ ctypes.winapi_abi,
+ /* return */ ctypes.bool,
+ /* handle*/ ctypes.voidptr_t
+ );
+
+ SysFile.CloseHandle = function(fd) {
+ if (fd == INVALID_HANDLE) {
+ return true;
+ }
+ return fd.dispose(); // Returns the value of |CloseHandle|.
+ };
+
+ libc.declareLazy(
+ SysFile,
+ "_FindClose",
+ "FindClose",
+ ctypes.winapi_abi,
+ /* return */ ctypes.bool,
+ /* handle*/ ctypes.voidptr_t
+ );
+
+ SysFile.FindClose = function(handle) {
+ if (handle == INVALID_HANDLE) {
+ return true;
+ }
+ return handle.dispose(); // Returns the value of |FindClose|.
+ };
+
+ // Declare libc functions as functions of |OS.Win.File|
+
+ libc.declareLazyFFI(
+ SysFile,
+ "CopyFile",
+ "CopyFileW",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ /* sourcePath*/ Type.path,
+ Type.path,
+ /* bailIfExist*/ Type.bool
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "CreateDirectory",
+ "CreateDirectoryW",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ Type.char16_t.in_ptr,
+ /* security*/ Type.SECURITY_ATTRIBUTES.in_ptr
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "CreateFile",
+ "CreateFileW",
+ ctypes.winapi_abi,
+ Type.file_HANDLE,
+ Type.path,
+ Type.DWORD_FLAGS,
+ Type.DWORD_FLAGS,
+ /* security*/ Type.SECURITY_ATTRIBUTES.in_ptr,
+ /* creation*/ Type.DWORD_FLAGS,
+ Type.DWORD_FLAGS,
+ /* template*/ Type.HANDLE
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "DeleteFile",
+ "DeleteFileW",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ Type.path
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "FileTimeToSystemTime",
+ "FileTimeToSystemTime",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ /* filetime*/ Type.FILETIME.in_ptr,
+ /* systime*/ Type.SystemTime.out_ptr
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "SystemTimeToFileTime",
+ "SystemTimeToFileTime",
+ ctypes.winapi_abi,
+ Type.zero_or_nothing,
+ Type.SystemTime.in_ptr,
+ /* filetime*/ Type.FILETIME.out_ptr
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "FindFirstFile",
+ "FindFirstFileW",
+ ctypes.winapi_abi,
+ /* return*/ Type.find_HANDLE,
+ /* pattern*/ Type.path,
+ Type.FindData.out_ptr
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "FindNextFile",
+ "FindNextFileW",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ Type.find_HANDLE,
+ Type.FindData.out_ptr
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "FormatMessage",
+ "FormatMessageW",
+ ctypes.winapi_abi,
+ /* return*/ Type.DWORD,
+ Type.DWORD_FLAGS,
+ /* source*/ Type.void_t.in_ptr,
+ Type.DWORD_FLAGS,
+ /* langid*/ Type.DWORD_FLAGS,
+ Type.out_wstring,
+ Type.DWORD,
+ /* Arguments*/ Type.void_t.in_ptr
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "GetCurrentDirectory",
+ "GetCurrentDirectoryW",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_DWORD,
+ /* length*/ Type.DWORD,
+ Type.out_path
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "GetFullPathName",
+ "GetFullPathNameW",
+ ctypes.winapi_abi,
+ Type.zero_or_DWORD,
+ /* fileName*/ Type.path,
+ Type.DWORD,
+ Type.out_path,
+ /* filePart*/ Type.DWORD
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "GetDiskFreeSpaceEx",
+ "GetDiskFreeSpaceExW",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ /* directoryName*/ Type.path,
+ /* freeBytesForUser*/ Type.uint64_t.out_ptr,
+ /* totalBytesForUser*/ Type.uint64_t.out_ptr,
+ /* freeTotalBytesOnDrive*/ Type.uint64_t.out_ptr
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "GetFileInformationByHandle",
+ "GetFileInformationByHandle",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ /* handle*/ Type.HANDLE,
+ Type.FILE_INFORMATION.out_ptr
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "MoveFileEx",
+ "MoveFileExW",
+ ctypes.winapi_abi,
+ Type.zero_or_nothing,
+ /* sourcePath*/ Type.path,
+ /* destPath*/ Type.path,
+ Type.DWORD
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "ReadFile",
+ "ReadFile",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ Type.HANDLE,
+ /* buffer*/ Type.voidptr_t,
+ /* nbytes*/ Type.DWORD,
+ /* nbytes_read*/ Type.DWORD.out_ptr,
+ /* overlapped*/ Type.void_t.inout_ptr // FIXME: Implement?
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "RemoveDirectory",
+ "RemoveDirectoryW",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ Type.path
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "SetEndOfFile",
+ "SetEndOfFile",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ Type.HANDLE
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "SetFilePointer",
+ "SetFilePointer",
+ ctypes.winapi_abi,
+ /* return*/ Type.DWORD,
+ Type.HANDLE,
+ /* distlow*/ Type.long,
+ /* disthi*/ Type.long.in_ptr,
+ /* method*/ Type.DWORD
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "SetFileTime",
+ "SetFileTime",
+ ctypes.winapi_abi,
+ Type.zero_or_nothing,
+ Type.HANDLE,
+ /* creation*/ Type.FILETIME.in_ptr,
+ Type.FILETIME.in_ptr,
+ Type.FILETIME.in_ptr
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "WriteFile",
+ "WriteFile",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ Type.HANDLE,
+ /* buffer*/ Type.voidptr_t,
+ /* nbytes*/ Type.DWORD,
+ /* nbytes_wr*/ Type.DWORD.out_ptr,
+ /* overlapped*/ Type.void_t.inout_ptr // FIXME: Implement?
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "FlushFileBuffers",
+ "FlushFileBuffers",
+ ctypes.winapi_abi,
+ /* return*/ Type.zero_or_nothing,
+ Type.HANDLE
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "GetFileAttributes",
+ "GetFileAttributesW",
+ ctypes.winapi_abi,
+ Type.DWORD_FLAGS,
+ /* fileName*/ Type.path
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "SetFileAttributes",
+ "SetFileAttributesW",
+ ctypes.winapi_abi,
+ Type.zero_or_nothing,
+ Type.path,
+ /* fileAttributes*/ Type.DWORD_FLAGS
+ );
+
+ advapi32.declareLazyFFI(
+ SysFile,
+ "GetNamedSecurityInfo",
+ "GetNamedSecurityInfoW",
+ ctypes.winapi_abi,
+ Type.DWORD,
+ Type.path,
+ Type.DWORD,
+ /* securityInfo*/ Type.DWORD,
+ Type.PSID.out_ptr,
+ Type.PSID.out_ptr,
+ Type.PACL.out_ptr,
+ Type.PACL.out_ptr,
+ /* securityDesc*/ Type.PSECURITY_DESCRIPTOR.out_ptr
+ );
+
+ advapi32.declareLazyFFI(
+ SysFile,
+ "SetNamedSecurityInfo",
+ "SetNamedSecurityInfoW",
+ ctypes.winapi_abi,
+ Type.DWORD,
+ Type.path,
+ Type.DWORD,
+ /* securityInfo*/ Type.DWORD,
+ Type.PSID,
+ Type.PSID,
+ Type.PACL,
+ Type.PACL
+ );
+
+ libc.declareLazyFFI(
+ SysFile,
+ "LocalFree",
+ "LocalFree",
+ ctypes.winapi_abi,
+ Type.HLOCAL,
+ Type.HLOCAL
+ );
+ };
+
+ exports.OS.Win = {
+ File: {
+ _init: init,
+ },
+ };
+ })(this);
+}