mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Implement winapi.GetLongPathName (#6525)
This commit is contained in:
1 parent
bcdf37bef1
commit
2063c1e0bc
2 files changed
+48
-4
No files matched your search
Vendored
-4
@@ -110,8 +110,6 @@ class WinAPIBatchedWaitForMultipleObjectsTests(unittest.TestCase):
|
||||
|
||||
|
||||
class WinAPITests(unittest.TestCase):
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_getlongpathname(self):
|
||||
testfn = pathlib.Path(os.getenv("ProgramFiles")).parents[-1] / "PROGRA~1"
|
||||
if not os.path.isdir(testfn):
|
||||
@@ -128,8 +126,6 @@ class WinAPITests(unittest.TestCase):
|
||||
candidates = set(testfn.parent.glob("Progra*"))
|
||||
self.assertIn(pathlib.Path(actual), candidates)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_getshortpathname(self):
|
||||
testfn = pathlib.Path(os.getenv("ProgramFiles"))
|
||||
if not os.path.isdir(testfn):
|
||||
|
||||
@@ -677,4 +677,52 @@ mod _winapi {
|
||||
|
||||
Ok(WinHandle(handle))
|
||||
}
|
||||
|
||||
/// Helper for GetShortPathName and GetLongPathName
|
||||
fn get_path_name_impl(
|
||||
path: &PyStrRef,
|
||||
api_fn: unsafe extern "system" fn(*const u16, *mut u16, u32) -> u32,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyStrRef> {
|
||||
use rustpython_common::wtf8::Wtf8Buf;
|
||||
|
||||
let path_wide = path.as_wtf8().to_wide_with_nul();
|
||||
|
||||
// First call to get required buffer size
|
||||
let size = unsafe { api_fn(path_wide.as_ptr(), null_mut(), 0) };
|
||||
|
||||
if size == 0 {
|
||||
return Err(vm.new_last_os_error());
|
||||
}
|
||||
|
||||
// Second call to get the actual path
|
||||
let mut buffer: Vec<u16> = vec![0; size as usize];
|
||||
let result =
|
||||
unsafe { api_fn(path_wide.as_ptr(), buffer.as_mut_ptr(), buffer.len() as u32) };
|
||||
|
||||
if result == 0 {
|
||||
return Err(vm.new_last_os_error());
|
||||
}
|
||||
|
||||
// Truncate to actual length (excluding null terminator)
|
||||
buffer.truncate(result as usize);
|
||||
|
||||
// Convert UTF-16 back to WTF-8 (handles surrogates properly)
|
||||
let result_str = Wtf8Buf::from_wide(&buffer);
|
||||
Ok(vm.ctx.new_str(result_str))
|
||||
}
|
||||
|
||||
/// GetShortPathName - Return the short version of the provided path.
|
||||
#[pyfunction]
|
||||
fn GetShortPathName(path: PyStrRef, vm: &VirtualMachine) -> PyResult<PyStrRef> {
|
||||
use windows_sys::Win32::Storage::FileSystem::GetShortPathNameW;
|
||||
get_path_name_impl(&path, GetShortPathNameW, vm)
|
||||
}
|
||||
|
||||
/// GetLongPathName - Return the long version of the provided path.
|
||||
#[pyfunction]
|
||||
fn GetLongPathName(path: PyStrRef, vm: &VirtualMachine) -> PyResult<PyStrRef> {
|
||||
use windows_sys::Win32::Storage::FileSystem::GetLongPathNameW;
|
||||
get_path_name_impl(&path, GetLongPathNameW, vm)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user