diff options
Diffstat (limited to 'toolkit/components/osfile/modules/osfile_win_back.jsm')
-rw-r--r-- | toolkit/components/osfile/modules/osfile_win_back.jsm | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/toolkit/components/osfile/modules/osfile_win_back.jsm b/toolkit/components/osfile/modules/osfile_win_back.jsm new file mode 100644 index 000000000..21172b6bf --- /dev/null +++ b/toolkit/components/osfile/modules/osfile_win_back.jsm @@ -0,0 +1,437 @@ +/* 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) + */ + +{ + if (typeof Components != "undefined") { + // We do not wish osfile_win.jsm 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.jsm 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"); + let LOG = 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; + } + let declareLazyFFI = SharedAll.declareLazyFFI; + + // 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: 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; + } else { + 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; + } else { + 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, + /*destPath*/ Type.path, + /*bailIfExist*/Type.bool); + + libc.declareLazyFFI(SysFile, "CreateDirectory", + "CreateDirectoryW", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*name*/ Type.char16_t.in_ptr, + /*security*/Type.SECURITY_ATTRIBUTES.in_ptr); + + libc.declareLazyFFI(SysFile, "CreateFile", + "CreateFileW", ctypes.winapi_abi, + /*return*/ Type.file_HANDLE, + /*name*/ Type.path, + /*access*/ Type.DWORD_FLAGS, + /*share*/ Type.DWORD_FLAGS, + /*security*/Type.SECURITY_ATTRIBUTES.in_ptr, + /*creation*/Type.DWORD_FLAGS, + /*flags*/ Type.DWORD_FLAGS, + /*template*/Type.HANDLE); + + libc.declareLazyFFI(SysFile, "DeleteFile", + "DeleteFileW", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*path*/ 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, + /*return*/ Type.zero_or_nothing, + /*systime*/ Type.SystemTime.in_ptr, + /*filetime*/ Type.FILETIME.out_ptr); + + libc.declareLazyFFI(SysFile, "FindFirstFile", + "FindFirstFileW", ctypes.winapi_abi, + /*return*/ Type.find_HANDLE, + /*pattern*/Type.path, + /*data*/ Type.FindData.out_ptr); + + libc.declareLazyFFI(SysFile, "FindNextFile", + "FindNextFileW", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*prev*/ Type.find_HANDLE, + /*data*/ Type.FindData.out_ptr); + + libc.declareLazyFFI(SysFile, "FormatMessage", + "FormatMessageW", ctypes.winapi_abi, + /*return*/ Type.DWORD, + /*flags*/ Type.DWORD_FLAGS, + /*source*/ Type.void_t.in_ptr, + /*msgid*/ Type.DWORD_FLAGS, + /*langid*/ Type.DWORD_FLAGS, + /*buf*/ Type.out_wstring, + /*size*/ Type.DWORD, + /*Arguments*/Type.void_t.in_ptr + ); + + libc.declareLazyFFI(SysFile, "GetCurrentDirectory", + "GetCurrentDirectoryW", ctypes.winapi_abi, + /*return*/ Type.zero_or_DWORD, + /*length*/ Type.DWORD, + /*buf*/ Type.out_path + ); + + libc.declareLazyFFI(SysFile, "GetFullPathName", + "GetFullPathNameW", ctypes.winapi_abi, + /*return*/ Type.zero_or_DWORD, + /*fileName*/ Type.path, + /*length*/ Type.DWORD, + /*buf*/ 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, + /*info*/ Type.FILE_INFORMATION.out_ptr); + + libc.declareLazyFFI(SysFile, "MoveFileEx", + "MoveFileExW", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*sourcePath*/ Type.path, + /*destPath*/ Type.path, + /*flags*/ Type.DWORD + ); + + libc.declareLazyFFI(SysFile, "ReadFile", + "ReadFile", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*file*/ 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, + /*path*/ Type.path); + + libc.declareLazyFFI(SysFile, "SetCurrentDirectory", + "SetCurrentDirectoryW", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*path*/ Type.path + ); + + libc.declareLazyFFI(SysFile, "SetEndOfFile", + "SetEndOfFile", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*file*/ Type.HANDLE); + + libc.declareLazyFFI(SysFile, "SetFilePointer", + "SetFilePointer", ctypes.winapi_abi, + /*return*/ Type.DWORD, + /*file*/ Type.HANDLE, + /*distlow*/Type.long, + /*disthi*/ Type.long.in_ptr, + /*method*/ Type.DWORD); + + libc.declareLazyFFI(SysFile, "SetFileTime", + "SetFileTime", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*file*/ Type.HANDLE, + /*creation*/ Type.FILETIME.in_ptr, + /*access*/ Type.FILETIME.in_ptr, + /*write*/ Type.FILETIME.in_ptr); + + + libc.declareLazyFFI(SysFile, "WriteFile", + "WriteFile", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*file*/ 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, + /*file*/ Type.HANDLE); + + libc.declareLazyFFI(SysFile, "GetFileAttributes", + "GetFileAttributesW", ctypes.winapi_abi, + /*return*/ Type.DWORD_FLAGS, + /*fileName*/ Type.path); + + libc.declareLazyFFI(SysFile, "SetFileAttributes", + "SetFileAttributesW", ctypes.winapi_abi, + /*return*/ Type.zero_or_nothing, + /*fileName*/ Type.path, + /*fileAttributes*/ Type.DWORD_FLAGS); + + advapi32.declareLazyFFI(SysFile, "GetNamedSecurityInfo", + "GetNamedSecurityInfoW", ctypes.winapi_abi, + /*return*/ Type.DWORD, + /*objectName*/ Type.path, + /*objectType*/ Type.DWORD, + /*securityInfo*/ Type.DWORD, + /*sidOwner*/ Type.PSID.out_ptr, + /*sidGroup*/ Type.PSID.out_ptr, + /*dacl*/ Type.PACL.out_ptr, + /*sacl*/ Type.PACL.out_ptr, + /*securityDesc*/ Type.PSECURITY_DESCRIPTOR.out_ptr); + + advapi32.declareLazyFFI(SysFile, "SetNamedSecurityInfo", + "SetNamedSecurityInfoW", ctypes.winapi_abi, + /*return*/ Type.DWORD, + /*objectName*/ Type.path, + /*objectType*/ Type.DWORD, + /*securityInfo*/ Type.DWORD, + /*sidOwner*/ Type.PSID, + /*sidGroup*/ Type.PSID, + /*dacl*/ Type.PACL, + /*sacl*/ Type.PACL); + + libc.declareLazyFFI(SysFile, "LocalFree", + "LocalFree", ctypes.winapi_abi, + /*return*/ Type.HLOCAL, + /*mem*/ Type.HLOCAL); + }; + + exports.OS.Win = { + File: { + _init: init + } + }; + })(this); +} |