diff options
Diffstat (limited to 'toolkit/components/osfile/modules/osfile_win_back.js')
-rw-r--r-- | toolkit/components/osfile/modules/osfile_win_back.js | 542 |
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); +} |