Skip to content

Commit 2c8b124

Browse files
committed
mkdir
1 parent c3ab168 commit 2c8b124

File tree

1 file changed

+52
-11
lines changed
  • crates/vm/src/stdlib

1 file changed

+52
-11
lines changed

crates/vm/src/stdlib/nt.rs

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -790,18 +790,59 @@ pub(crate) mod module {
790790
raw_set_handle_inheritable(handle, inheritable).map_err(|e| e.to_pyexception(vm))
791791
}
792792

793-
#[pyfunction]
794-
fn mkdir(
793+
#[derive(FromArgs)]
794+
struct MkdirArgs<'a> {
795+
#[pyarg(any)]
795796
path: OsPath,
796-
mode: OptionalArg<i32>,
797-
dir_fd: DirFd<'_, { _os::MKDIR_DIR_FD as usize }>,
798-
vm: &VirtualMachine,
799-
) -> PyResult<()> {
800-
let mode = mode.unwrap_or(0o777);
801-
let [] = dir_fd.0;
802-
let _ = mode;
803-
let wide = path.to_wide_cstring(vm)?;
804-
let res = unsafe { FileSystem::CreateDirectoryW(wide.as_ptr(), std::ptr::null_mut()) };
797+
#[pyarg(any, default = 0o777)]
798+
mode: i32,
799+
#[pyarg(flatten)]
800+
dir_fd: DirFd<'a, { _os::MKDIR_DIR_FD as usize }>,
801+
}
802+
803+
#[pyfunction]
804+
fn mkdir(args: MkdirArgs<'_>, vm: &VirtualMachine) -> PyResult<()> {
805+
use windows_sys::Win32::Foundation::LocalFree;
806+
use windows_sys::Win32::Security::Authorization::{
807+
ConvertStringSecurityDescriptorToSecurityDescriptorW, SDDL_REVISION_1,
808+
};
809+
use windows_sys::Win32::Security::SECURITY_ATTRIBUTES;
810+
811+
let [] = args.dir_fd.0;
812+
let wide = args.path.to_wide_cstring(vm)?;
813+
814+
// CPython special case: mode 0o700 sets a protected ACL
815+
let res = if args.mode == 0o700 {
816+
let mut sec_attr = SECURITY_ATTRIBUTES {
817+
nLength: std::mem::size_of::<SECURITY_ATTRIBUTES>() as u32,
818+
lpSecurityDescriptor: std::ptr::null_mut(),
819+
bInheritHandle: 0,
820+
};
821+
// Set a discretionary ACL (D) that is protected (P) and includes
822+
// inheritable (OICI) entries that allow (A) full control (FA) to
823+
// SYSTEM (SY), Administrators (BA), and the owner (OW).
824+
let sddl: Vec<u16> = "D:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;OW)\0"
825+
.encode_utf16()
826+
.collect();
827+
let convert_result = unsafe {
828+
ConvertStringSecurityDescriptorToSecurityDescriptorW(
829+
sddl.as_ptr(),
830+
SDDL_REVISION_1,
831+
&mut sec_attr.lpSecurityDescriptor,
832+
std::ptr::null_mut(),
833+
)
834+
};
835+
if convert_result == 0 {
836+
return Err(errno_err(vm));
837+
}
838+
let res =
839+
unsafe { FileSystem::CreateDirectoryW(wide.as_ptr(), &sec_attr as *const _ as _) };
840+
unsafe { LocalFree(sec_attr.lpSecurityDescriptor) };
841+
res
842+
} else {
843+
unsafe { FileSystem::CreateDirectoryW(wide.as_ptr(), std::ptr::null_mut()) }
844+
};
845+
805846
if res == 0 {
806847
return Err(errno_err(vm));
807848
}

0 commit comments

Comments
 (0)