/* 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); }