Skip to content

Commit c609b17

Browse files
committed
Review Windows implementation of Stat to include missing fields.
Change-Id: I8279590f33589af3e75d25879147c71cc81424dd
1 parent d7b49cd commit c609b17

File tree

2 files changed

+47
-16
lines changed

2 files changed

+47
-16
lines changed

src/os/gnatcoll-os-stat-stat__win32.adb

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,63 @@
2424
with GNATCOLL.OS.Win32.Files; use GNATCOLL.OS.Win32.Files;
2525
with GNATCOLL.OS.Win32; use GNATCOLL.OS.Win32;
2626
with GNAT.OS_Lib;
27+
with Ada.Calendar.Conversions;
28+
with Interfaces.C;
2729

2830
separate (GNATCOLL.OS.Stat)
2931
function Stat
30-
(Path : UTF8.UTF_8_String;
32+
(Path : UTF8.UTF_8_String;
3133
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;
3842
pragma Unreferenced (Follow_Symlinks);
3943

4044
begin
4145
-- 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));
4747

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#;
4960

61+
Status := NtQueryInformationFile (WinHandle, IO, LPVOID (Info'Address),
62+
FILE_ALL_INFORMATION'Size / 8,
63+
FileAllInformation);
5064
if Is_Success (Status) then
5165
Result.Exists := True;
52-
Result.Directory := (DIRECTORY and Information.FileAttributes) > 0;
66+
Result.Directory :=
67+
(DIRECTORY and Info.BasicInformation.FileAttributes) > 0;
5368
Result.Symbolic_Link :=
54-
(REPARSE_POINT and Information.FileAttributes) > 0;
69+
(REPARSE_POINT and Info.BasicInformation.FileAttributes) > 0;
5570
Result.Regular :=
5671
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;
5782
end if;
5883

84+
Status := NtClose (WinHandle);
5985
return Result;
6086
end Stat;

testsuite/tests/os/stat/test.adb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ begin
1515
IO.Put_Line ("GNATCOLL.OS.Stat test");
1616
declare
1717
FA : File_Attributes;
18+
D : Duration;
1819
begin
1920
FA := Stat ("directory");
2021
IO.Put_Line (Image (FA));
@@ -31,7 +32,11 @@ begin
3132
Msg => "check that regular_file is not a dir");
3233
A.Assert (not Is_Symbolic_Link (FA),
3334
Msg => "check that regular_file is not a symbolic link");
34-
A.Assert (Clock - Modification_Time (FA) < 100.0);
35+
D := Clock - Modification_Time (FA);
36+
A.Assert
37+
(D < 100.0,
38+
Msg => "check that modification time is less than 100s in the past: "
39+
& D'Img);
3540

3641
IO.Put_Line ("test file with utf-8 name");
3742
FA := Stat (Character'Val (16#C3#) & Character'Val (16#A9#) & ".txt");

0 commit comments

Comments
 (0)