gecko-dev/toolkit/components/osfile/modules/osfile_win_back.jsm

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