1- mod c;
2- mod cast;
3- mod helpers;
1+ pub ( crate ) mod c;
2+ pub ( crate ) mod cast;
3+ pub ( crate ) mod helpers;
44
55use std:: ffi:: OsString ;
66use std:: mem:: size_of;
@@ -20,7 +20,7 @@ const NT_PREFIX: [u16; 4] = helpers::utf16s(br"\??\");
2020/// Ref: <https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry>
2121const VERBATIM_PREFIX : [ u16 ; 4 ] = helpers:: utf16s ( br"\\?\" ) ;
2222
23- const WCHAR_SIZE : u16 = size_of :: < u16 > ( ) as _ ;
23+ pub ( crate ) const WCHAR_SIZE : u16 = size_of :: < u16 > ( ) as _ ;
2424
2525pub fn create ( target : & Path , junction : & Path ) -> io:: Result < ( ) > {
2626 const UNICODE_NULL_SIZE : u16 = WCHAR_SIZE ;
@@ -152,51 +152,3 @@ pub fn get_target(junction: &Path) -> io::Result<PathBuf> {
152152 Err ( io:: Error :: new ( io:: ErrorKind :: Other , "not a reparse tag mount point" ) )
153153 }
154154}
155-
156- #[ cfg( test) ]
157- mod tests {
158- use std:: ffi:: OsString ;
159- use std:: os:: windows:: ffi:: OsStringExt ;
160- use std:: os:: windows:: io:: AsRawHandle ;
161- use std:: { fs, slice} ;
162-
163- use super :: * ;
164-
165- #[ test]
166- fn create_populates_print_name ( ) {
167- // Regression test: the junction reparse point must have a non-empty PrintName
168- // so that Windows Container layer snapshots correctly preserve the junction target.
169- let tmpdir = tempfile:: tempdir ( ) . unwrap ( ) ;
170- let target = tmpdir. path ( ) . join ( "target" ) ;
171- let junction = tmpdir. path ( ) . join ( "junction" ) ;
172- fs:: create_dir_all ( & target) . unwrap ( ) ;
173-
174- create ( & target, & junction) . unwrap ( ) ;
175-
176- // Read back the raw reparse data
177- let mut data = cast:: BytesAsReparseDataBuffer :: new ( ) ;
178- {
179- let file = helpers:: open_reparse_point ( & junction, false ) . unwrap ( ) ;
180- helpers:: get_reparse_data_point ( file. as_raw_handle ( ) , data. as_mut_ptr ( ) ) . unwrap ( ) ;
181- }
182- let rdb = unsafe { data. assume_init ( ) } ;
183-
184- assert_eq ! ( rdb. ReparseTag , c:: IO_REPARSE_TAG_MOUNT_POINT ) ;
185-
186- // Read PrintName
187- let print_offset = ( rdb. ReparseBuffer . PrintNameOffset / WCHAR_SIZE ) as usize ;
188- let print_len = ( rdb. ReparseBuffer . PrintNameLength / WCHAR_SIZE ) as usize ;
189- let print_name = unsafe {
190- let buf = rdb. ReparseBuffer . PathBuffer . as_ptr ( ) . add ( print_offset) ;
191- slice:: from_raw_parts ( buf, print_len)
192- } ;
193-
194- // PrintName must not be empty
195- assert ! ( print_len > 0 , "PrintName must not be empty" ) ;
196-
197- // PrintName should match what get_target returns (the Win32 path without \??\ prefix)
198- let print_path = PathBuf :: from ( OsString :: from_wide ( print_name) ) ;
199- let target_path = get_target ( & junction) . unwrap ( ) ;
200- assert_eq ! ( print_path, target_path, "PrintName should match the target path" ) ;
201- }
202- }
0 commit comments