about summary refs log tree commit diff
path: root/src/libstd/sys/windows/c.rs
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-04-08 09:50:50 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-04-08 10:33:39 -0700
commitf3f99fb44eea1d7037f94259aef6cbc39837ebee (patch)
tree06627f8312fb03953ec47906df9a6d356ad00334 /src/libstd/sys/windows/c.rs
parent926f38e588bb99aff1902fa94ab82b1db89cbbce (diff)
downloadrust-f3f99fb44eea1d7037f94259aef6cbc39837ebee.tar.gz
rust-f3f99fb44eea1d7037f94259aef6cbc39837ebee.zip
std: Fix fs::read_link behavior on Windows
The current implementation of using GetFinalPathNameByHandle actually reads all
intermediate links instead of just looking at the current link. This commit
alters the behavior of the function to use a different API which correctly reads
only one level of the soft link.

[breaking-change]
Diffstat (limited to 'src/libstd/sys/windows/c.rs')
-rw-r--r--src/libstd/sys/windows/c.rs30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 4804f650441..c8f6aca7bd3 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -47,6 +47,10 @@ pub const WSAESHUTDOWN: libc::c_int = 10058;
 
 pub const ERROR_NO_MORE_FILES: libc::DWORD = 18;
 pub const TOKEN_READ: libc::DWORD = 0x20008;
+pub const FILE_FLAG_OPEN_REPARSE_POINT: libc::DWORD = 0x00200000;
+pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
+pub const FSCTL_GET_REPARSE_POINT: libc::DWORD = 0x900a8;
+pub const IO_REPARSE_TAG_SYMLINK: libc::DWORD = 0xa000000c;
 
 // Note that these are not actually HANDLEs, just values to pass to GetStdHandle
 pub const STD_INPUT_HANDLE: libc::DWORD = -10i32 as libc::DWORD;
@@ -214,6 +218,24 @@ pub struct FILE_END_OF_FILE_INFO {
     pub EndOfFile: libc::LARGE_INTEGER,
 }
 
+#[repr(C)]
+pub struct REPARSE_DATA_BUFFER {
+    pub ReparseTag: libc::c_uint,
+    pub ReparseDataLength: libc::c_ushort,
+    pub Reserved: libc::c_ushort,
+    pub rest: (),
+}
+
+#[repr(C)]
+pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
+    pub SubstituteNameOffset: libc::c_ushort,
+    pub SubstituteNameLength: libc::c_ushort,
+    pub PrintNameOffset: libc::c_ushort,
+    pub PrintNameLength: libc::c_ushort,
+    pub Flags: libc::c_ulong,
+    pub PathBuffer: libc::WCHAR,
+}
+
 #[link(name = "ws2_32")]
 extern "system" {
     pub fn WSAStartup(wVersionRequested: libc::WORD,
@@ -433,6 +455,14 @@ extern "system" {
     pub fn GetCurrentProcess() -> libc::HANDLE;
     pub fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
     pub fn ExitProcess(uExitCode: libc::c_uint) -> !;
+    pub fn DeviceIoControl(hDevice: libc::HANDLE,
+                           dwIoControlCode: libc::DWORD,
+                           lpInBuffer: libc::LPVOID,
+                           nInBufferSize: libc::DWORD,
+                           lpOutBuffer: libc::LPVOID,
+                           nOutBufferSize: libc::DWORD,
+                           lpBytesReturned: libc::LPDWORD,
+                           lpOverlapped: libc::LPOVERLAPPED) -> libc::BOOL;
 }
 
 #[link(name = "userenv")]