зеркало из https://github.com/mozilla/gecko-dev.git
418 строки
16 KiB
JavaScript
418 строки
16 KiB
JavaScript
/* 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.int32_t.withName("DWORD");
|
|
|
|
/**
|
|
* A C integer holding -1 in case of error or a positive integer
|
|
* in case of success.
|
|
*/
|
|
Type.negative_or_DWORD =
|
|
Type.DWORD.withName("negative_or_DWORD");
|
|
|
|
/**
|
|
* 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.jschar, Const.MAX_PATH) },
|
|
{ cAlternateFileName: ctypes.ArrayType(ctypes.jschar, 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.jschar.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,
|
|
/*share*/ Type.DWORD,
|
|
/*security*/Type.SECURITY_ATTRIBUTES.in_ptr,
|
|
/*creation*/Type.DWORD,
|
|
/*flags*/ Type.DWORD,
|
|
/*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,
|
|
/*source*/ Type.void_t.in_ptr,
|
|
/*msgid*/ Type.DWORD,
|
|
/*langid*/ Type.DWORD,
|
|
/*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, "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.negative_or_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,
|
|
/*fileName*/ Type.path);
|
|
|
|
libc.declareLazyFFI(SysFile, "SetFileAttributes",
|
|
"SetFileAttributesW", ctypes.winapi_abi,
|
|
/*return*/ Type.zero_or_nothing,
|
|
/*fileName*/ Type.path,
|
|
/*fileAttributes*/ Type.DWORD);
|
|
|
|
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);
|
|
}
|