1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/osfile/modules/osfile_win_back.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,428 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/** 1.9 + * This file can be used in the following contexts: 1.10 + * 1.11 + * 1. included from a non-osfile worker thread using importScript 1.12 + * (it serves to define a synchronous API for that worker thread) 1.13 + * (bug 707681) 1.14 + * 1.15 + * 2. included from the main thread using Components.utils.import 1.16 + * (it serves to define the asynchronous API, whose implementation 1.17 + * resides in the worker thread) 1.18 + * (bug 729057) 1.19 + * 1.20 + * 3. included from the osfile worker thread using importScript 1.21 + * (it serves to define the implementation of the asynchronous API) 1.22 + * (bug 729057) 1.23 + */ 1.24 + 1.25 +{ 1.26 + if (typeof Components != "undefined") { 1.27 + // We do not wish osfile_win.jsm to be used directly as a main thread 1.28 + // module yet. When time comes, it will be loaded by a combination of 1.29 + // a main thread front-end/worker thread implementation that makes sure 1.30 + // that we are not executing synchronous IO code in the main thread. 1.31 + 1.32 + throw new Error("osfile_win.jsm cannot be used from the main thread yet"); 1.33 + } 1.34 + 1.35 + (function(exports) { 1.36 + "use strict"; 1.37 + if (exports.OS && exports.OS.Win && exports.OS.Win.File) { 1.38 + return; // Avoid double initialization 1.39 + } 1.40 + 1.41 + let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm"); 1.42 + let SysAll = require("resource://gre/modules/osfile/osfile_win_allthreads.jsm"); 1.43 + let LOG = SharedAll.LOG.bind(SharedAll, "Unix", "back"); 1.44 + let libc = SysAll.libc; 1.45 + let advapi32 = new SharedAll.Library("advapi32", "advapi32.dll"); 1.46 + let Const = SharedAll.Constants.Win; 1.47 + 1.48 + /** 1.49 + * Initialize the Windows module. 1.50 + * 1.51 + * @param {function=} declareFFI 1.52 + */ 1.53 + // FIXME: Both |init| and |aDeclareFFI| are deprecated, we should remove them 1.54 + let init = function init(aDeclareFFI) { 1.55 + let declareFFI; 1.56 + if (aDeclareFFI) { 1.57 + declareFFI = aDeclareFFI.bind(null, libc); 1.58 + } else { 1.59 + declareFFI = SysAll.declareFFI; 1.60 + } 1.61 + let declareLazyFFI = SharedAll.declareLazyFFI; 1.62 + 1.63 + // Initialize types that require additional OS-specific 1.64 + // support - either finalization or matching against 1.65 + // OS-specific constants. 1.66 + let Type = Object.create(SysAll.Type); 1.67 + let SysFile = exports.OS.Win.File = { Type: Type }; 1.68 + 1.69 + // Initialize types 1.70 + 1.71 + /** 1.72 + * A C integer holding INVALID_HANDLE_VALUE in case of error or 1.73 + * a file descriptor in case of success. 1.74 + */ 1.75 + Type.HANDLE = 1.76 + Type.voidptr_t.withName("HANDLE"); 1.77 + Type.HANDLE.importFromC = function importFromC(maybe) { 1.78 + if (Type.int.cast(maybe).value == INVALID_HANDLE) { 1.79 + // Ensure that API clients can effectively compare against 1.80 + // Const.INVALID_HANDLE_VALUE. Without this cast, 1.81 + // == would always return |false|. 1.82 + return INVALID_HANDLE; 1.83 + } 1.84 + return ctypes.CDataFinalizer(maybe, this.finalizeHANDLE); 1.85 + }; 1.86 + Type.HANDLE.finalizeHANDLE = function placeholder() { 1.87 + throw new Error("finalizeHANDLE should be implemented"); 1.88 + }; 1.89 + let INVALID_HANDLE = Const.INVALID_HANDLE_VALUE; 1.90 + 1.91 + Type.file_HANDLE = Type.HANDLE.withName("file HANDLE"); 1.92 + SharedAll.defineLazyGetter(Type.file_HANDLE, 1.93 + "finalizeHANDLE", 1.94 + function() { 1.95 + return SysFile._CloseHandle; 1.96 + }); 1.97 + 1.98 + Type.find_HANDLE = Type.HANDLE.withName("find HANDLE"); 1.99 + SharedAll.defineLazyGetter(Type.find_HANDLE, 1.100 + "finalizeHANDLE", 1.101 + function() { 1.102 + return SysFile._FindClose; 1.103 + }); 1.104 + 1.105 + Type.DWORD = Type.uint32_t.withName("DWORD"); 1.106 + 1.107 + /* A special type used to represent flags passed as DWORDs to a function. 1.108 + * In JavaScript, bitwise manipulation of numbers, such as or-ing flags, 1.109 + * can produce negative numbers. Since DWORD is unsigned, these negative 1.110 + * numbers simply cannot be converted to DWORD. For this reason, whenever 1.111 + * bit manipulation is called for, you should rather use DWORD_FLAGS, 1.112 + * which is represented as a signed integer, hence has the correct 1.113 + * semantics. 1.114 + */ 1.115 + Type.DWORD_FLAGS = Type.int32_t.withName("DWORD_FLAGS"); 1.116 + 1.117 + /** 1.118 + * A C integer holding 0 in case of error or a positive integer 1.119 + * in case of success. 1.120 + */ 1.121 + Type.zero_or_DWORD = 1.122 + Type.DWORD.withName("zero_or_DWORD"); 1.123 + 1.124 + /** 1.125 + * A C integer holding 0 in case of error, any other value in 1.126 + * case of success. 1.127 + */ 1.128 + Type.zero_or_nothing = 1.129 + Type.int.withName("zero_or_nothing"); 1.130 + 1.131 + /** 1.132 + * A C integer holding flags related to NTFS security. 1.133 + */ 1.134 + Type.SECURITY_ATTRIBUTES = 1.135 + Type.void_t.withName("SECURITY_ATTRIBUTES"); 1.136 + 1.137 + /** 1.138 + * A C integer holding pointers related to NTFS security. 1.139 + */ 1.140 + Type.PSID = 1.141 + Type.voidptr_t.withName("PSID"); 1.142 + 1.143 + Type.PACL = 1.144 + Type.voidptr_t.withName("PACL"); 1.145 + 1.146 + Type.PSECURITY_DESCRIPTOR = 1.147 + Type.voidptr_t.withName("PSECURITY_DESCRIPTOR"); 1.148 + 1.149 + /** 1.150 + * A C integer holding Win32 local memory handle. 1.151 + */ 1.152 + Type.HLOCAL = 1.153 + Type.voidptr_t.withName("HLOCAL"); 1.154 + 1.155 + Type.FILETIME = 1.156 + new SharedAll.Type("FILETIME", 1.157 + ctypes.StructType("FILETIME", [ 1.158 + { lo: Type.DWORD.implementation }, 1.159 + { hi: Type.DWORD.implementation }])); 1.160 + 1.161 + Type.FindData = 1.162 + new SharedAll.Type("FIND_DATA", 1.163 + ctypes.StructType("FIND_DATA", [ 1.164 + { dwFileAttributes: ctypes.uint32_t }, 1.165 + { ftCreationTime: Type.FILETIME.implementation }, 1.166 + { ftLastAccessTime: Type.FILETIME.implementation }, 1.167 + { ftLastWriteTime: Type.FILETIME.implementation }, 1.168 + { nFileSizeHigh: Type.DWORD.implementation }, 1.169 + { nFileSizeLow: Type.DWORD.implementation }, 1.170 + { dwReserved0: Type.DWORD.implementation }, 1.171 + { dwReserved1: Type.DWORD.implementation }, 1.172 + { cFileName: ctypes.ArrayType(ctypes.jschar, Const.MAX_PATH) }, 1.173 + { cAlternateFileName: ctypes.ArrayType(ctypes.jschar, 14) } 1.174 + ])); 1.175 + 1.176 + Type.FILE_INFORMATION = 1.177 + new SharedAll.Type("FILE_INFORMATION", 1.178 + ctypes.StructType("FILE_INFORMATION", [ 1.179 + { dwFileAttributes: ctypes.uint32_t }, 1.180 + { ftCreationTime: Type.FILETIME.implementation }, 1.181 + { ftLastAccessTime: Type.FILETIME.implementation }, 1.182 + { ftLastWriteTime: Type.FILETIME.implementation }, 1.183 + { dwVolumeSerialNumber: ctypes.uint32_t }, 1.184 + { nFileSizeHigh: Type.DWORD.implementation }, 1.185 + { nFileSizeLow: Type.DWORD.implementation }, 1.186 + { nNumberOfLinks: ctypes.uint32_t }, 1.187 + { nFileIndex: ctypes.uint64_t } 1.188 + ])); 1.189 + 1.190 + Type.SystemTime = 1.191 + new SharedAll.Type("SystemTime", 1.192 + ctypes.StructType("SystemTime", [ 1.193 + { wYear: ctypes.int16_t }, 1.194 + { wMonth: ctypes.int16_t }, 1.195 + { wDayOfWeek: ctypes.int16_t }, 1.196 + { wDay: ctypes.int16_t }, 1.197 + { wHour: ctypes.int16_t }, 1.198 + { wMinute: ctypes.int16_t }, 1.199 + { wSecond: ctypes.int16_t }, 1.200 + { wMilliSeconds: ctypes.int16_t } 1.201 + ])); 1.202 + 1.203 + // Special case: these functions are used by the 1.204 + // finalizer 1.205 + libc.declareLazy(SysFile, "_CloseHandle", 1.206 + "CloseHandle", ctypes.winapi_abi, 1.207 + /*return */ctypes.bool, 1.208 + /*handle*/ ctypes.voidptr_t); 1.209 + 1.210 + SysFile.CloseHandle = function(fd) { 1.211 + if (fd == INVALID_HANDLE) { 1.212 + return true; 1.213 + } else { 1.214 + return fd.dispose(); // Returns the value of |CloseHandle|. 1.215 + } 1.216 + }; 1.217 + 1.218 + libc.declareLazy(SysFile, "_FindClose", 1.219 + "FindClose", ctypes.winapi_abi, 1.220 + /*return */ctypes.bool, 1.221 + /*handle*/ ctypes.voidptr_t); 1.222 + 1.223 + SysFile.FindClose = function(handle) { 1.224 + if (handle == INVALID_HANDLE) { 1.225 + return true; 1.226 + } else { 1.227 + return handle.dispose(); // Returns the value of |FindClose|. 1.228 + } 1.229 + }; 1.230 + 1.231 + // Declare libc functions as functions of |OS.Win.File| 1.232 + 1.233 + libc.declareLazyFFI(SysFile, "CopyFile", 1.234 + "CopyFileW", ctypes.winapi_abi, 1.235 + /*return*/ Type.zero_or_nothing, 1.236 + /*sourcePath*/ Type.path, 1.237 + /*destPath*/ Type.path, 1.238 + /*bailIfExist*/Type.bool); 1.239 + 1.240 + libc.declareLazyFFI(SysFile, "CreateDirectory", 1.241 + "CreateDirectoryW", ctypes.winapi_abi, 1.242 + /*return*/ Type.zero_or_nothing, 1.243 + /*name*/ Type.jschar.in_ptr, 1.244 + /*security*/Type.SECURITY_ATTRIBUTES.in_ptr); 1.245 + 1.246 + libc.declareLazyFFI(SysFile, "CreateFile", 1.247 + "CreateFileW", ctypes.winapi_abi, 1.248 + /*return*/ Type.file_HANDLE, 1.249 + /*name*/ Type.path, 1.250 + /*access*/ Type.DWORD_FLAGS, 1.251 + /*share*/ Type.DWORD_FLAGS, 1.252 + /*security*/Type.SECURITY_ATTRIBUTES.in_ptr, 1.253 + /*creation*/Type.DWORD_FLAGS, 1.254 + /*flags*/ Type.DWORD_FLAGS, 1.255 + /*template*/Type.HANDLE); 1.256 + 1.257 + libc.declareLazyFFI(SysFile, "DeleteFile", 1.258 + "DeleteFileW", ctypes.winapi_abi, 1.259 + /*return*/ Type.zero_or_nothing, 1.260 + /*path*/ Type.path); 1.261 + 1.262 + libc.declareLazyFFI(SysFile, "FileTimeToSystemTime", 1.263 + "FileTimeToSystemTime", ctypes.winapi_abi, 1.264 + /*return*/ Type.zero_or_nothing, 1.265 + /*filetime*/Type.FILETIME.in_ptr, 1.266 + /*systime*/ Type.SystemTime.out_ptr); 1.267 + 1.268 + libc.declareLazyFFI(SysFile, "SystemTimeToFileTime", 1.269 + "SystemTimeToFileTime", ctypes.winapi_abi, 1.270 + /*return*/ Type.zero_or_nothing, 1.271 + /*systime*/ Type.SystemTime.in_ptr, 1.272 + /*filetime*/ Type.FILETIME.out_ptr); 1.273 + 1.274 + libc.declareLazyFFI(SysFile, "FindFirstFile", 1.275 + "FindFirstFileW", ctypes.winapi_abi, 1.276 + /*return*/ Type.find_HANDLE, 1.277 + /*pattern*/Type.path, 1.278 + /*data*/ Type.FindData.out_ptr); 1.279 + 1.280 + libc.declareLazyFFI(SysFile, "FindNextFile", 1.281 + "FindNextFileW", ctypes.winapi_abi, 1.282 + /*return*/ Type.zero_or_nothing, 1.283 + /*prev*/ Type.find_HANDLE, 1.284 + /*data*/ Type.FindData.out_ptr); 1.285 + 1.286 + libc.declareLazyFFI(SysFile, "FormatMessage", 1.287 + "FormatMessageW", ctypes.winapi_abi, 1.288 + /*return*/ Type.DWORD, 1.289 + /*flags*/ Type.DWORD_FLAGS, 1.290 + /*source*/ Type.void_t.in_ptr, 1.291 + /*msgid*/ Type.DWORD_FLAGS, 1.292 + /*langid*/ Type.DWORD_FLAGS, 1.293 + /*buf*/ Type.out_wstring, 1.294 + /*size*/ Type.DWORD, 1.295 + /*Arguments*/Type.void_t.in_ptr 1.296 + ); 1.297 + 1.298 + libc.declareLazyFFI(SysFile, "GetCurrentDirectory", 1.299 + "GetCurrentDirectoryW", ctypes.winapi_abi, 1.300 + /*return*/ Type.zero_or_DWORD, 1.301 + /*length*/ Type.DWORD, 1.302 + /*buf*/ Type.out_path 1.303 + ); 1.304 + 1.305 + libc.declareLazyFFI(SysFile, "GetDiskFreeSpaceEx", 1.306 + "GetDiskFreeSpaceExW", ctypes.winapi_abi, 1.307 + /*return*/ Type.zero_or_nothing, 1.308 + /*directoryName*/ Type.path, 1.309 + /*freeBytesForUser*/ Type.uint64_t.out_ptr, 1.310 + /*totalBytesForUser*/ Type.uint64_t.out_ptr, 1.311 + /*freeTotalBytesOnDrive*/ Type.uint64_t.out_ptr); 1.312 + 1.313 + libc.declareLazyFFI(SysFile, "GetFileInformationByHandle", 1.314 + "GetFileInformationByHandle", ctypes.winapi_abi, 1.315 + /*return*/ Type.zero_or_nothing, 1.316 + /*handle*/ Type.HANDLE, 1.317 + /*info*/ Type.FILE_INFORMATION.out_ptr); 1.318 + 1.319 + libc.declareLazyFFI(SysFile, "MoveFileEx", 1.320 + "MoveFileExW", ctypes.winapi_abi, 1.321 + /*return*/ Type.zero_or_nothing, 1.322 + /*sourcePath*/ Type.path, 1.323 + /*destPath*/ Type.path, 1.324 + /*flags*/ Type.DWORD 1.325 + ); 1.326 + 1.327 + libc.declareLazyFFI(SysFile, "ReadFile", 1.328 + "ReadFile", ctypes.winapi_abi, 1.329 + /*return*/ Type.zero_or_nothing, 1.330 + /*file*/ Type.HANDLE, 1.331 + /*buffer*/ Type.voidptr_t, 1.332 + /*nbytes*/ Type.DWORD, 1.333 + /*nbytes_read*/Type.DWORD.out_ptr, 1.334 + /*overlapped*/Type.void_t.inout_ptr // FIXME: Implement? 1.335 + ); 1.336 + 1.337 + libc.declareLazyFFI(SysFile, "RemoveDirectory", 1.338 + "RemoveDirectoryW", ctypes.winapi_abi, 1.339 + /*return*/ Type.zero_or_nothing, 1.340 + /*path*/ Type.path); 1.341 + 1.342 + libc.declareLazyFFI(SysFile, "SetCurrentDirectory", 1.343 + "SetCurrentDirectoryW", ctypes.winapi_abi, 1.344 + /*return*/ Type.zero_or_nothing, 1.345 + /*path*/ Type.path 1.346 + ); 1.347 + 1.348 + libc.declareLazyFFI(SysFile, "SetEndOfFile", 1.349 + "SetEndOfFile", ctypes.winapi_abi, 1.350 + /*return*/ Type.zero_or_nothing, 1.351 + /*file*/ Type.HANDLE); 1.352 + 1.353 + libc.declareLazyFFI(SysFile, "SetFilePointer", 1.354 + "SetFilePointer", ctypes.winapi_abi, 1.355 + /*return*/ Type.DWORD, 1.356 + /*file*/ Type.HANDLE, 1.357 + /*distlow*/Type.long, 1.358 + /*disthi*/ Type.long.in_ptr, 1.359 + /*method*/ Type.DWORD); 1.360 + 1.361 + libc.declareLazyFFI(SysFile, "SetFileTime", 1.362 + "SetFileTime", ctypes.winapi_abi, 1.363 + /*return*/ Type.zero_or_nothing, 1.364 + /*file*/ Type.HANDLE, 1.365 + /*creation*/ Type.FILETIME.in_ptr, 1.366 + /*access*/ Type.FILETIME.in_ptr, 1.367 + /*write*/ Type.FILETIME.in_ptr); 1.368 + 1.369 + 1.370 + libc.declareLazyFFI(SysFile, "WriteFile", 1.371 + "WriteFile", ctypes.winapi_abi, 1.372 + /*return*/ Type.zero_or_nothing, 1.373 + /*file*/ Type.HANDLE, 1.374 + /*buffer*/ Type.voidptr_t, 1.375 + /*nbytes*/ Type.DWORD, 1.376 + /*nbytes_wr*/Type.DWORD.out_ptr, 1.377 + /*overlapped*/Type.void_t.inout_ptr // FIXME: Implement? 1.378 + ); 1.379 + 1.380 + libc.declareLazyFFI(SysFile, "FlushFileBuffers", 1.381 + "FlushFileBuffers", ctypes.winapi_abi, 1.382 + /*return*/ Type.zero_or_nothing, 1.383 + /*file*/ Type.HANDLE); 1.384 + 1.385 + libc.declareLazyFFI(SysFile, "GetFileAttributes", 1.386 + "GetFileAttributesW", ctypes.winapi_abi, 1.387 + /*return*/ Type.DWORD_FLAGS, 1.388 + /*fileName*/ Type.path); 1.389 + 1.390 + libc.declareLazyFFI(SysFile, "SetFileAttributes", 1.391 + "SetFileAttributesW", ctypes.winapi_abi, 1.392 + /*return*/ Type.zero_or_nothing, 1.393 + /*fileName*/ Type.path, 1.394 + /*fileAttributes*/ Type.DWORD_FLAGS); 1.395 + 1.396 + advapi32.declareLazyFFI(SysFile, "GetNamedSecurityInfo", 1.397 + "GetNamedSecurityInfoW", ctypes.winapi_abi, 1.398 + /*return*/ Type.DWORD, 1.399 + /*objectName*/ Type.path, 1.400 + /*objectType*/ Type.DWORD, 1.401 + /*securityInfo*/ Type.DWORD, 1.402 + /*sidOwner*/ Type.PSID.out_ptr, 1.403 + /*sidGroup*/ Type.PSID.out_ptr, 1.404 + /*dacl*/ Type.PACL.out_ptr, 1.405 + /*sacl*/ Type.PACL.out_ptr, 1.406 + /*securityDesc*/ Type.PSECURITY_DESCRIPTOR.out_ptr); 1.407 + 1.408 + advapi32.declareLazyFFI(SysFile, "SetNamedSecurityInfo", 1.409 + "SetNamedSecurityInfoW", ctypes.winapi_abi, 1.410 + /*return*/ Type.DWORD, 1.411 + /*objectName*/ Type.path, 1.412 + /*objectType*/ Type.DWORD, 1.413 + /*securityInfo*/ Type.DWORD, 1.414 + /*sidOwner*/ Type.PSID, 1.415 + /*sidGroup*/ Type.PSID, 1.416 + /*dacl*/ Type.PACL, 1.417 + /*sacl*/ Type.PACL); 1.418 + 1.419 + libc.declareLazyFFI(SysFile, "LocalFree", 1.420 + "LocalFree", ctypes.winapi_abi, 1.421 + /*return*/ Type.HLOCAL, 1.422 + /*mem*/ Type.HLOCAL); 1.423 + }; 1.424 + 1.425 + exports.OS.Win = { 1.426 + File: { 1.427 + _init: init 1.428 + } 1.429 + }; 1.430 + })(this); 1.431 +}