(args: MkdirArgs<'_>, vm: &VirtualMachine)
| 1948 | |
| 1949 | #[pyfunction] |
| 1950 | fn mkdir(args: MkdirArgs<'_>, vm: &VirtualMachine) -> PyResult<()> { |
| 1951 | use windows_sys::Win32::Foundation::LocalFree; |
| 1952 | use windows_sys::Win32::Security::Authorization::{ |
| 1953 | ConvertStringSecurityDescriptorToSecurityDescriptorW, SDDL_REVISION_1, |
| 1954 | }; |
| 1955 | use windows_sys::Win32::Security::SECURITY_ATTRIBUTES; |
| 1956 | |
| 1957 | let [] = args.dir_fd.0; |
| 1958 | let wide = args.path.to_wide_cstring(vm)?; |
| 1959 | |
| 1960 | // special case: mode 0o700 sets a protected ACL |
| 1961 | let res = if args.mode == 0o700 { |
| 1962 | let mut sec_attr = SECURITY_ATTRIBUTES { |
| 1963 | nLength: core::mem::size_of::<SECURITY_ATTRIBUTES>() as u32, |
| 1964 | lpSecurityDescriptor: core::ptr::null_mut(), |
| 1965 | bInheritHandle: 0, |
| 1966 | }; |
| 1967 | // Set a discretionary ACL (D) that is protected (P) and includes |
| 1968 | // inheritable (OICI) entries that allow (A) full control (FA) to |
| 1969 | // SYSTEM (SY), Administrators (BA), and the owner (OW). |
| 1970 | let sddl: Vec<u16> = "D:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;OW)\0" |
| 1971 | .encode_utf16() |
| 1972 | .collect(); |
| 1973 | let convert_result = unsafe { |
| 1974 | ConvertStringSecurityDescriptorToSecurityDescriptorW( |
| 1975 | sddl.as_ptr(), |
| 1976 | SDDL_REVISION_1, |
| 1977 | &mut sec_attr.lpSecurityDescriptor, |
| 1978 | core::ptr::null_mut(), |
| 1979 | ) |
| 1980 | }; |
| 1981 | if convert_result == 0 { |
| 1982 | return Err(vm.new_last_os_error()); |
| 1983 | } |
| 1984 | let res = |
| 1985 | unsafe { FileSystem::CreateDirectoryW(wide.as_ptr(), &sec_attr as *const _ as _) }; |
| 1986 | unsafe { LocalFree(sec_attr.lpSecurityDescriptor) }; |
| 1987 | res |
| 1988 | } else { |
| 1989 | unsafe { FileSystem::CreateDirectoryW(wide.as_ptr(), core::ptr::null_mut()) } |
| 1990 | }; |
| 1991 | |
| 1992 | if res == 0 { |
| 1993 | return Err(vm.new_last_os_error()); |
| 1994 | } |
| 1995 | Ok(()) |
| 1996 | } |
| 1997 | |
| 1998 | unsafe extern "C" { |
| 1999 | fn _umask(mask: i32) -> i32; |
no test coverage detected