|
24 | 24 | with GNATCOLL.OS.Win32.Files; use GNATCOLL.OS.Win32.Files; |
25 | 25 | with GNATCOLL.OS.Win32; use GNATCOLL.OS.Win32; |
26 | 26 | with GNAT.OS_Lib; |
| 27 | +with Ada.Calendar.Conversions; |
| 28 | +with Interfaces.C; |
27 | 29 |
|
28 | 30 | separate (GNATCOLL.OS.Stat) |
29 | 31 | function Stat |
30 | | - (Path : UTF8.UTF_8_String; |
| 32 | + (Path : UTF8.UTF_8_String; |
31 | 33 | Follow_Symlinks : Boolean := True) |
32 | | - return File_Attributes is |
33 | | - Attr : FILE_OBJECT_ATTRIBUTES; |
34 | | - Status : NTSTATUS; |
35 | | - Information : FILE_BASIC_INFORMATION; |
36 | | - Result : File_Attributes; |
37 | | - |
| 34 | + return File_Attributes |
| 35 | +is |
| 36 | + Attr : UNICODE_PATH; |
| 37 | + Status : NTSTATUS; |
| 38 | + Info : FILE_ALL_INFORMATION; |
| 39 | + Result : File_Attributes; |
| 40 | + WinHandle : HANDLE := NULL_HANDLE; |
| 41 | + IO : IO_STATUS_BLOCK; |
38 | 42 | pragma Unreferenced (Follow_Symlinks); |
39 | 43 |
|
40 | 44 | begin |
41 | 45 | -- NtQueryAttributesFile requires an absolute path |
42 | | - if GNAT.OS_Lib.Is_Absolute_Path (Path) then |
43 | | - Initialize (Attr, Path); |
44 | | - else |
45 | | - Initialize (Attr, GNAT.OS_Lib.Normalize_Pathname (Path)); |
46 | | - end if; |
| 46 | + Initialize (Attr, GNAT.OS_Lib.Normalize_Pathname (Path)); |
47 | 47 |
|
48 | | - Status := NtQueryAttributesFile (Attr.OA, Information); |
| 48 | + Status := NtOpenFile |
| 49 | + (WinHandle, |
| 50 | + Attr.Str, |
| 51 | + FILE_READ_ATTRIBUTES, |
| 52 | + IO, |
| 53 | + SHARE_ALL, |
| 54 | + FILE_OPEN_FOR_BACKUP_INTENT); |
| 55 | + if not Is_Success (Status) then |
| 56 | + Result.Exists := False; |
| 57 | + return Result; |
| 58 | + end if; |
| 59 | + WinHandle := WinHandle and 16#FFFFFFFF#; |
49 | 60 |
|
| 61 | + Status := NtQueryInformationFile (WinHandle, IO, LPVOID (Info'Address), |
| 62 | + FILE_ALL_INFORMATION'Size / 8, |
| 63 | + FileAllInformation); |
50 | 64 | if Is_Success (Status) then |
51 | 65 | Result.Exists := True; |
52 | | - Result.Directory := (DIRECTORY and Information.FileAttributes) > 0; |
| 66 | + Result.Directory := |
| 67 | + (DIRECTORY and Info.BasicInformation.FileAttributes) > 0; |
53 | 68 | Result.Symbolic_Link := |
54 | | - (REPARSE_POINT and Information.FileAttributes) > 0; |
| 69 | + (REPARSE_POINT and Info.BasicInformation.FileAttributes) > 0; |
55 | 70 | Result.Regular := |
56 | 71 | not (Result.Directory or Result.Symbolic_Link); |
| 72 | + Result.Stamp := Ada.Calendar.Conversions.To_Ada_Time |
| 73 | + (Interfaces.C.long |
| 74 | + ((Info.BasicInformation.LastWriteTime / 10000000) |
| 75 | + - Win32_Epoch_Offset)); |
| 76 | + Result.Length := Info.StandardInformation.EndOfFile; |
| 77 | + Result.Executable := True; |
| 78 | + Result.Readable := True; |
| 79 | + Result.Writable := True; |
| 80 | + else |
| 81 | + Result.Exists := False; |
57 | 82 | end if; |
58 | 83 |
|
| 84 | + Status := NtClose (WinHandle); |
59 | 85 | return Result; |
60 | 86 | end Stat; |
0 commit comments