|
4 | 4 | #![cfg_attr(test, allow(dead_code))]
|
5 | 5 | #![unstable(issue = "none", feature = "windows_c")]
|
6 | 6 |
|
| 7 | +use crate::mem; |
7 | 8 | use crate::os::raw::NonZero_c_ulong;
|
8 | 9 | use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort};
|
9 | 10 | use crate::ptr;
|
@@ -36,6 +37,7 @@ pub type USHORT = c_ushort;
|
36 | 37 | pub type SIZE_T = usize;
|
37 | 38 | pub type WORD = u16;
|
38 | 39 | pub type CHAR = c_char;
|
| 40 | +pub type CCHAR = c_char; |
39 | 41 | pub type ULONG_PTR = usize;
|
40 | 42 | pub type ULONG = c_ulong;
|
41 | 43 | pub type NTSTATUS = LONG;
|
@@ -86,16 +88,21 @@ pub const FILE_SHARE_DELETE: DWORD = 0x4;
|
86 | 88 | pub const FILE_SHARE_READ: DWORD = 0x1;
|
87 | 89 | pub const FILE_SHARE_WRITE: DWORD = 0x2;
|
88 | 90 |
|
| 91 | +pub const FILE_OPEN_REPARSE_POINT: ULONG = 0x200000; |
| 92 | +pub const OBJ_DONT_REPARSE: ULONG = 0x1000; |
| 93 | + |
89 | 94 | pub const CREATE_ALWAYS: DWORD = 2;
|
90 | 95 | pub const CREATE_NEW: DWORD = 1;
|
91 | 96 | pub const OPEN_ALWAYS: DWORD = 4;
|
92 | 97 | pub const OPEN_EXISTING: DWORD = 3;
|
93 | 98 | pub const TRUNCATE_EXISTING: DWORD = 5;
|
94 | 99 |
|
| 100 | +pub const FILE_LIST_DIRECTORY: DWORD = 0x1; |
95 | 101 | pub const FILE_WRITE_DATA: DWORD = 0x00000002;
|
96 | 102 | pub const FILE_APPEND_DATA: DWORD = 0x00000004;
|
97 | 103 | pub const FILE_WRITE_EA: DWORD = 0x00000010;
|
98 | 104 | pub const FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100;
|
| 105 | +pub const DELETE: DWORD = 0x10000; |
99 | 106 | pub const READ_CONTROL: DWORD = 0x00020000;
|
100 | 107 | pub const SYNCHRONIZE: DWORD = 0x00100000;
|
101 | 108 | pub const GENERIC_READ: DWORD = 0x80000000;
|
@@ -261,9 +268,61 @@ pub const FD_SETSIZE: usize = 64;
|
261 | 268 | pub const STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD = 0x00010000;
|
262 | 269 |
|
263 | 270 | pub const STATUS_SUCCESS: NTSTATUS = 0x00000000;
|
| 271 | +pub const STATUS_DELETE_PENDING: NTSTATUS = 0xc0000056_u32 as _; |
| 272 | +pub const STATUS_INVALID_PARAMETER: NTSTATUS = 0xc000000d_u32 as _; |
| 273 | + |
| 274 | +// Equivalent to the `NT_SUCCESS` C preprocessor macro. |
| 275 | +// See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values |
| 276 | +pub fn nt_success(status: NTSTATUS) -> bool { |
| 277 | + status >= 0 |
| 278 | +} |
264 | 279 |
|
265 | 280 | pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
|
266 | 281 |
|
| 282 | +#[repr(C)] |
| 283 | +pub struct UNICODE_STRING { |
| 284 | + pub Length: u16, |
| 285 | + pub MaximumLength: u16, |
| 286 | + pub Buffer: *mut u16, |
| 287 | +} |
| 288 | +impl UNICODE_STRING { |
| 289 | + pub fn from_ref(slice: &[u16]) -> Self { |
| 290 | + let len = slice.len() * mem::size_of::<u16>(); |
| 291 | + Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ } |
| 292 | + } |
| 293 | +} |
| 294 | +#[repr(C)] |
| 295 | +pub struct OBJECT_ATTRIBUTES { |
| 296 | + pub Length: ULONG, |
| 297 | + pub RootDirectory: HANDLE, |
| 298 | + pub ObjectName: *const UNICODE_STRING, |
| 299 | + pub Attributes: ULONG, |
| 300 | + pub SecurityDescriptor: *mut c_void, |
| 301 | + pub SecurityQualityOfService: *mut c_void, |
| 302 | +} |
| 303 | +impl Default for OBJECT_ATTRIBUTES { |
| 304 | + fn default() -> Self { |
| 305 | + Self { |
| 306 | + Length: mem::size_of::<Self>() as _, |
| 307 | + RootDirectory: ptr::null_mut(), |
| 308 | + ObjectName: ptr::null_mut(), |
| 309 | + Attributes: 0, |
| 310 | + SecurityDescriptor: ptr::null_mut(), |
| 311 | + SecurityQualityOfService: ptr::null_mut(), |
| 312 | + } |
| 313 | + } |
| 314 | +} |
| 315 | +#[repr(C)] |
| 316 | +pub struct IO_STATUS_BLOCK { |
| 317 | + pub Pointer: *mut c_void, |
| 318 | + pub Information: usize, |
| 319 | +} |
| 320 | +impl Default for IO_STATUS_BLOCK { |
| 321 | + fn default() -> Self { |
| 322 | + Self { Pointer: ptr::null_mut(), Information: 0 } |
| 323 | + } |
| 324 | +} |
| 325 | + |
267 | 326 | #[repr(C)]
|
268 | 327 | #[cfg(not(target_pointer_width = "64"))]
|
269 | 328 | pub struct WSADATA {
|
@@ -353,9 +412,43 @@ pub enum FILE_INFO_BY_HANDLE_CLASS {
|
353 | 412 | FileIdInfo = 18, // 0x12
|
354 | 413 | FileIdExtdDirectoryInfo = 19, // 0x13
|
355 | 414 | FileIdExtdDirectoryRestartInfo = 20, // 0x14
|
| 415 | + FileDispositionInfoEx = 21, // 0x15, Windows 10 version 1607 |
356 | 416 | MaximumFileInfoByHandlesClass,
|
357 | 417 | }
|
358 | 418 |
|
| 419 | +#[repr(C)] |
| 420 | +pub struct FILE_DISPOSITION_INFO { |
| 421 | + pub DeleteFile: BOOLEAN, |
| 422 | +} |
| 423 | + |
| 424 | +pub const FILE_DISPOSITION_DELETE: DWORD = 0x1; |
| 425 | +pub const FILE_DISPOSITION_POSIX_SEMANTICS: DWORD = 0x2; |
| 426 | +pub const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: DWORD = 0x10; |
| 427 | + |
| 428 | +#[repr(C)] |
| 429 | +pub struct FILE_DISPOSITION_INFO_EX { |
| 430 | + pub Flags: DWORD, |
| 431 | +} |
| 432 | + |
| 433 | +#[repr(C)] |
| 434 | +#[derive(Default)] |
| 435 | +pub struct FILE_ID_BOTH_DIR_INFO { |
| 436 | + pub NextEntryOffset: DWORD, |
| 437 | + pub FileIndex: DWORD, |
| 438 | + pub CreationTime: LARGE_INTEGER, |
| 439 | + pub LastAccessTime: LARGE_INTEGER, |
| 440 | + pub LastWriteTime: LARGE_INTEGER, |
| 441 | + pub ChangeTime: LARGE_INTEGER, |
| 442 | + pub EndOfFile: LARGE_INTEGER, |
| 443 | + pub AllocationSize: LARGE_INTEGER, |
| 444 | + pub FileAttributes: DWORD, |
| 445 | + pub FileNameLength: DWORD, |
| 446 | + pub EaSize: DWORD, |
| 447 | + pub ShortNameLength: CCHAR, |
| 448 | + pub ShortName: [WCHAR; 12], |
| 449 | + pub FileId: LARGE_INTEGER, |
| 450 | + pub FileName: [WCHAR; 1], |
| 451 | +} |
359 | 452 | #[repr(C)]
|
360 | 453 | pub struct FILE_BASIC_INFO {
|
361 | 454 | pub CreationTime: LARGE_INTEGER,
|
@@ -750,16 +843,6 @@ if #[cfg(target_vendor = "uwp")] {
|
750 | 843 | pub DeletePending: BOOLEAN,
|
751 | 844 | pub Directory: BOOLEAN,
|
752 | 845 | }
|
753 |
| - |
754 |
| - #[link(name = "kernel32")] |
755 |
| - extern "system" { |
756 |
| - pub fn GetFileInformationByHandleEx( |
757 |
| - hFile: HANDLE, |
758 |
| - fileInfoClass: FILE_INFO_BY_HANDLE_CLASS, |
759 |
| - lpFileInformation: LPVOID, |
760 |
| - dwBufferSize: DWORD, |
761 |
| - ) -> BOOL; |
762 |
| - } |
763 | 846 | }
|
764 | 847 | }
|
765 | 848 |
|
@@ -949,6 +1032,12 @@ extern "system" {
|
949 | 1032 | cchFilePath: DWORD,
|
950 | 1033 | dwFlags: DWORD,
|
951 | 1034 | ) -> DWORD;
|
| 1035 | + pub fn GetFileInformationByHandleEx( |
| 1036 | + hFile: HANDLE, |
| 1037 | + fileInfoClass: FILE_INFO_BY_HANDLE_CLASS, |
| 1038 | + lpFileInformation: LPVOID, |
| 1039 | + dwBufferSize: DWORD, |
| 1040 | + ) -> BOOL; |
952 | 1041 | pub fn SetFileInformationByHandle(
|
953 | 1042 | hFile: HANDLE,
|
954 | 1043 | FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
|
@@ -1139,6 +1228,21 @@ compat_fn! {
|
1139 | 1228 |
|
1140 | 1229 | compat_fn! {
|
1141 | 1230 | "ntdll":
|
| 1231 | + pub fn NtOpenFile( |
| 1232 | + FileHandle: *mut HANDLE, |
| 1233 | + DesiredAccess: ACCESS_MASK, |
| 1234 | + ObjectAttributes: *const OBJECT_ATTRIBUTES, |
| 1235 | + IoStatusBlock: *mut IO_STATUS_BLOCK, |
| 1236 | + ShareAccess: ULONG, |
| 1237 | + OpenOptions: ULONG |
| 1238 | + ) -> NTSTATUS { |
| 1239 | + panic!("`NtOpenFile` not available"); |
| 1240 | + } |
| 1241 | + pub fn RtlNtStatusToDosError( |
| 1242 | + Status: NTSTATUS |
| 1243 | + ) -> ULONG { |
| 1244 | + panic!("`RtlNtStatusToDosError` not available"); |
| 1245 | + } |
1142 | 1246 | pub fn NtCreateKeyedEvent(
|
1143 | 1247 | KeyedEventHandle: LPHANDLE,
|
1144 | 1248 | DesiredAccess: ACCESS_MASK,
|
|
0 commit comments