From 64c8e57e3f9eee294913df4b15bb036ff8824e17 Mon Sep 17 00:00:00 2001 From: Jon-Luke Biddle Date: Tue, 31 Mar 2026 18:24:37 -0600 Subject: [PATCH 1/8] upgrade to rust 2024 --- Cargo.lock | 237 ++++++++++++++++------------------- dokan-sys/Cargo.toml | 2 +- dokan-sys/src/lib.rs | 56 ++++----- dokan/Cargo.toml | 2 +- dokan/examples/memfs/main.rs | 6 +- dokan/src/data/find_data.rs | 6 +- dokan/src/operations.rs | 50 ++++---- dokan/src/usage_tests.rs | 17 +-- 8 files changed, 180 insertions(+), 196 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8234ae..88149e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 4 [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.6.18" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -28,65 +28,69 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", - "once_cell", + "once_cell_polyfill", "windows-sys", ] [[package]] -name = "autocfg" -version = "1.4.0" +name = "bitflags" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] -name = "bitflags" -version = "2.9.0" +name = "block2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] [[package]] name = "cc" -version = "1.2.20" +version = "1.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" +checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" dependencies = [ + "find-msvc-tools", "shlex", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -96,18 +100,18 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "clap" -version = "4.5.37" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.37" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -117,26 +121,39 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "ctrlc" -version = "3.4.6" +version = "3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c" +checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162" dependencies = [ + "dispatch2", "nix", "windows-sys", ] +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags", + "block2", + "libc", + "objc2", +] + [[package]] name = "dokan" version = "0.3.1+dokan230" @@ -161,11 +178,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "lazy_static" @@ -175,31 +198,30 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.172" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "memchr" -version = "2.7.4" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "nix" -version = "0.29.0" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3" dependencies = [ "bitflags", "cfg-if", @@ -208,16 +230,31 @@ dependencies = [ ] [[package]] -name = "once_cell" -version = "1.21.3" +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -225,31 +262,31 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-link", ] [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -259,9 +296,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -270,9 +307,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "scopeguard" @@ -288,9 +325,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "strsim" @@ -306,9 +343,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "widestring" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "winapi" @@ -333,74 +370,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.59.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] -name = "windows-targets" -version = "0.52.6" +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows-link", ] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/dokan-sys/Cargo.toml b/dokan-sys/Cargo.toml index ae10f8f..fb1dedd 100644 --- a/dokan-sys/Cargo.toml +++ b/dokan-sys/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["ffi", "dokan", "bindings", "driver", "filesystem"] categories = ["external-ffi-bindings"] readme = "README.md" license = "MIT" -edition = "2021" +edition = "2024" links = "dokan" build = "build.rs" diff --git a/dokan-sys/src/lib.rs b/dokan-sys/src/lib.rs index 13976bf..7a48f26 100644 --- a/dokan-sys/src/lib.rs +++ b/dokan-sys/src/lib.rs @@ -93,8 +93,8 @@ pub struct DOKAN_FILE_INFO { pub type PDOKAN_FILE_INFO = *mut DOKAN_FILE_INFO; -pub type PFillFindData = unsafe extern "stdcall" fn(PWIN32_FIND_DATAW, PDOKAN_FILE_INFO) -> c_int; -pub type PFillFindStreamData = unsafe extern "stdcall" fn(PWIN32_FIND_STREAM_DATA, PVOID) -> BOOL; +pub type PFillFindData = unsafe extern "system" fn(PWIN32_FIND_DATAW, PDOKAN_FILE_INFO) -> c_int; +pub type PFillFindStreamData = unsafe extern "system" fn(PWIN32_FIND_STREAM_DATA, PVOID) -> BOOL; #[repr(C)] pub struct DOKAN_ACCESS_STATE { @@ -125,7 +125,7 @@ pub type PDOKAN_IO_SECURITY_CONTEXT = *mut DOKAN_IO_SECURITY_CONTEXT; #[derive(Clone)] pub struct DOKAN_OPERATIONS { pub ZwCreateFile: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, SecurityContext: PDOKAN_IO_SECURITY_CONTEXT, DesiredAccess: ACCESS_MASK, @@ -136,10 +136,10 @@ pub struct DOKAN_OPERATIONS { DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, - pub Cleanup: Option, - pub CloseFile: Option, + pub Cleanup: Option, + pub CloseFile: Option, pub ReadFile: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, Buffer: LPVOID, BufferLength: DWORD, @@ -149,7 +149,7 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub WriteFile: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, Buffer: LPCVOID, NumberOfBytesToWrite: DWORD, @@ -159,23 +159,23 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub FlushFileBuffers: - Option NTSTATUS>, + Option NTSTATUS>, pub GetFileInformation: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, Buffer: LPBY_HANDLE_FILE_INFORMATION, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub FindFiles: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, FillFindData: PFillFindData, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub FindFilesWithPattern: Option< - extern "stdcall" fn( + extern "system" fn( PathName: LPCWSTR, SearchPattern: LPCWSTR, FillFindData: PFillFindData, @@ -183,14 +183,14 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub SetFileAttributes: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, FileAttributes: DWORD, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub SetFileTime: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, creation_time: *const FILETIME, last_access_time: *const FILETIME, @@ -199,11 +199,11 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub DeleteFile: - Option NTSTATUS>, + Option NTSTATUS>, pub DeleteDirectory: - Option NTSTATUS>, + Option NTSTATUS>, pub MoveFile: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, NewFileName: LPCWSTR, ReplaceIfExisting: BOOL, @@ -211,21 +211,21 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub SetEndOfFile: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, ByteOffset: LONGLONG, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub SetAllocationSize: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, AllocSize: LONGLONG, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub LockFile: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, ByteOffset: LONGLONG, Length: LONGLONG, @@ -233,7 +233,7 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub UnlockFile: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, ByteOffset: LONGLONG, Length: LONGLONG, @@ -241,7 +241,7 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub GetDiskFreeSpace: Option< - extern "stdcall" fn( + extern "system" fn( FreeBytesAvailable: PULONGLONG, TotalNumberOfBytes: PULONGLONG, TotalNumberOfFreeBytes: PULONGLONG, @@ -249,7 +249,7 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub GetVolumeInformation: Option< - extern "stdcall" fn( + extern "system" fn( VolumeNameBuffer: LPWSTR, VolumeNameSize: DWORD, VolumeSerialNumber: LPDWORD, @@ -261,11 +261,11 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub Mounted: Option< - extern "stdcall" fn(MountPoint: LPCWSTR, DokanFileInfo: PDOKAN_FILE_INFO) -> NTSTATUS, + extern "system" fn(MountPoint: LPCWSTR, DokanFileInfo: PDOKAN_FILE_INFO) -> NTSTATUS, >, - pub Unmounted: Option NTSTATUS>, + pub Unmounted: Option NTSTATUS>, pub GetFileSecurity: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, PSECURITY_INFORMATION: PSECURITY_INFORMATION, PSECURITY_DESCRIPTOR: PSECURITY_DESCRIPTOR, @@ -275,7 +275,7 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub SetFileSecurity: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, SecurityInformation: PSECURITY_INFORMATION, SecurityDescriptor: PSECURITY_DESCRIPTOR, @@ -284,7 +284,7 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub FindStreams: Option< - extern "stdcall" fn( + extern "system" fn( FileName: LPCWSTR, FillFindStreamData: PFillFindStreamData, FindStreamContext: PVOID, @@ -316,7 +316,7 @@ pub struct DOKAN_MOUNT_POINT_INFO { pub type PDOKAN_MOUNT_POINT_INFO = *mut DOKAN_MOUNT_POINT_INFO; -extern "stdcall" { +unsafe extern "system" { pub fn DokanInit(); pub fn DokanShutdown(); pub fn DokanMain(DokanOptions: PDOKAN_OPTIONS, DokanOperations: PDOKAN_OPERATIONS) -> c_int; diff --git a/dokan/Cargo.toml b/dokan/Cargo.toml index af3ccd1..702931b 100644 --- a/dokan/Cargo.toml +++ b/dokan/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["dokan", "bindings", "driver", "filesystem"] categories = ["external-ffi-bindings"] readme = "README.md" license = "MIT" -edition = "2021" +edition = "2024" [badges] appveyor = { repository = "Liryna/dokan-rust" } diff --git a/dokan/examples/memfs/main.rs b/dokan/examples/memfs/main.rs index 35de54d..f7e9463 100644 --- a/dokan/examples/memfs/main.rs +++ b/dokan/examples/memfs/main.rs @@ -692,12 +692,14 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { context: &'c Self::Context, ) { let mut stat = context.entry.stat().write().unwrap(); - if let Some(mtime) = context.mtime_delayed.lock().unwrap().clone() { + let mtime_delayed = context.mtime_delayed.lock().unwrap().clone(); + if let Some(mtime) = mtime_delayed { if mtime > stat.mtime { stat.mtime = mtime; } } - if let Some(atime) = context.atime_delayed.lock().unwrap().clone() { + let atime_delayed = context.atime_delayed.lock().unwrap().clone(); + if let Some(atime) = atime_delayed { if atime > stat.atime { stat.atime = atime; } diff --git a/dokan/src/data/find_data.rs b/dokan/src/data/find_data.rs index c500cf8..c9ad4a7 100644 --- a/dokan/src/data/find_data.rs +++ b/dokan/src/data/find_data.rs @@ -100,7 +100,7 @@ impl ToRawStruct for FindStreamData { } pub(crate) fn wrap_fill_data, TArg: Copy, TResult: PartialEq>( - fill_data: unsafe extern "stdcall" fn(*mut T, TArg) -> TResult, + fill_data: unsafe extern "system" fn(*mut T, TArg) -> TResult, fill_data_arg: TArg, success_value: TResult, ) -> impl FnMut(&U) -> FillDataResult { @@ -137,11 +137,11 @@ mod tests { } } - extern "stdcall" fn fill_data_stub(_data: *mut (), _info: PDOKAN_FILE_INFO) -> c_int { + extern "system" fn fill_data_stub(_data: *mut (), _info: PDOKAN_FILE_INFO) -> c_int { 0 } - extern "stdcall" fn failing_fill_data_stub(_data: *mut (), _info: PDOKAN_FILE_INFO) -> c_int { + extern "system" fn failing_fill_data_stub(_data: *mut (), _info: PDOKAN_FILE_INFO) -> c_int { 1 } diff --git a/dokan/src/operations.rs b/dokan/src/operations.rs index 2c56991..5772dd0 100644 --- a/dokan/src/operations.rs +++ b/dokan/src/operations.rs @@ -23,7 +23,7 @@ use crate::{ operations_helpers::{wrap_nt_result, wrap_unit, NtResult}, }; -pub extern "stdcall" fn create_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn create_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, security_context: PDOKAN_IO_SECURITY_CONTEXT, desired_access: ACCESS_MASK, @@ -64,7 +64,7 @@ pub extern "stdcall" fn create_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + }) } -pub extern "stdcall" fn cleanup<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn cleanup<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) { @@ -75,7 +75,7 @@ pub extern "stdcall" fn cleanup<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h> }); } -pub extern "stdcall" fn close_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn close_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) { @@ -87,7 +87,7 @@ pub extern "stdcall" fn close_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + }); } -pub extern "stdcall" fn read_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn read_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, buffer: LPVOID, buffer_length: DWORD, @@ -108,7 +108,7 @@ pub extern "stdcall" fn read_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + ' }) } -pub extern "stdcall" fn write_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn write_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, buffer: LPCVOID, number_of_bytes_to_write: DWORD, @@ -129,7 +129,7 @@ pub extern "stdcall" fn write_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + }) } -pub extern "stdcall" fn flush_file_buffers<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn flush_file_buffers<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -141,7 +141,7 @@ pub extern "stdcall" fn flush_file_buffers<'c, 'h: 'c, FSH: FileSystemHandler<'c }) } -pub extern "stdcall" fn get_file_information<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn get_file_information<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, buffer: LPBY_HANDLE_FILE_INFORMATION, dokan_file_info: PDOKAN_FILE_INFO, @@ -157,7 +157,7 @@ pub extern "stdcall" fn get_file_information<'c, 'h: 'c, FSH: FileSystemHandler< }) } -pub extern "stdcall" fn find_files<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn find_files<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, fill_find_data: PFillFindData, dokan_file_info: PDOKAN_FILE_INFO, @@ -171,7 +171,7 @@ pub extern "stdcall" fn find_files<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + }) } -pub extern "stdcall" fn find_files_with_pattern<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn find_files_with_pattern<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, search_pattern: LPCWSTR, fill_find_data: PFillFindData, @@ -192,7 +192,7 @@ pub extern "stdcall" fn find_files_with_pattern<'c, 'h: 'c, FSH: FileSystemHandl }) } -pub extern "stdcall" fn set_file_attributes<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn set_file_attributes<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, file_attributes: DWORD, dokan_file_info: PDOKAN_FILE_INFO, @@ -205,7 +205,7 @@ pub extern "stdcall" fn set_file_attributes<'c, 'h: 'c, FSH: FileSystemHandler<' }) } -pub extern "stdcall" fn set_file_time<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn set_file_time<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, creation_time: *const FILETIME, last_access_time: *const FILETIME, @@ -226,7 +226,7 @@ pub extern "stdcall" fn set_file_time<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> }) } -pub extern "stdcall" fn delete_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn delete_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -237,7 +237,7 @@ pub extern "stdcall" fn delete_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + }) } -pub extern "stdcall" fn delete_directory<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn delete_directory<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -249,7 +249,7 @@ pub extern "stdcall" fn delete_directory<'c, 'h: 'c, FSH: FileSystemHandler<'c, }) } -pub extern "stdcall" fn move_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn move_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, new_file_name: LPCWSTR, replace_if_existing: BOOL, @@ -269,7 +269,7 @@ pub extern "stdcall" fn move_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + ' }) } -pub extern "stdcall" fn set_end_of_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn set_end_of_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, byte_offset: LONGLONG, dokan_file_info: PDOKAN_FILE_INFO, @@ -282,7 +282,7 @@ pub extern "stdcall" fn set_end_of_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, ' }) } -pub extern "stdcall" fn set_allocation_size<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn set_allocation_size<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, alloc_size: LONGLONG, dokan_file_info: PDOKAN_FILE_INFO, @@ -326,7 +326,7 @@ fn lock_unlock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( }) } -pub extern "stdcall" fn lock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn lock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, byte_offset: LONGLONG, length: LONGLONG, @@ -341,7 +341,7 @@ pub extern "stdcall" fn lock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + ' ) } -pub extern "stdcall" fn unlock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn unlock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, byte_offset: LONGLONG, length: LONGLONG, @@ -356,7 +356,7 @@ pub extern "stdcall" fn unlock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + ) } -pub extern "stdcall" fn get_disk_free_space<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn get_disk_free_space<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( free_bytes_available: PULONGLONG, total_number_of_bytes: PULONGLONG, total_number_of_free_bytes: PULONGLONG, @@ -380,7 +380,7 @@ pub extern "stdcall" fn get_disk_free_space<'c, 'h: 'c, FSH: FileSystemHandler<' }) } -pub extern "stdcall" fn get_volume_information<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn get_volume_information<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( volume_name_buffer: LPWSTR, volume_name_size: DWORD, volume_serial_number: LPDWORD, @@ -416,7 +416,7 @@ pub extern "stdcall" fn get_volume_information<'c, 'h: 'c, FSH: FileSystemHandle }) } -pub extern "stdcall" fn mounted<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn mounted<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( mount_point: LPCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -427,7 +427,7 @@ pub extern "stdcall" fn mounted<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h> }) } -pub extern "stdcall" fn unmounted<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn unmounted<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { wrap_nt_result(|| { @@ -436,7 +436,7 @@ pub extern "stdcall" fn unmounted<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + ' }) } -pub extern "stdcall" fn get_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn get_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, security_information: PSECURITY_INFORMATION, security_descriptor: PSECURITY_DESCRIPTOR, @@ -467,7 +467,7 @@ pub extern "stdcall" fn get_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, }) } -pub extern "stdcall" fn set_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn set_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, security_information: PSECURITY_INFORMATION, security_descriptor: PSECURITY_DESCRIPTOR, @@ -488,7 +488,7 @@ pub extern "stdcall" fn set_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, }) } -pub extern "stdcall" fn find_streams<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( +pub extern "system" fn find_streams<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( file_name: LPCWSTR, fill_find_stream_data: PFillFindStreamData, find_stream_context: PVOID, diff --git a/dokan/src/usage_tests.rs b/dokan/src/usage_tests.rs index 1876456..4af41c5 100644 --- a/dokan/src/usage_tests.rs +++ b/dokan/src/usage_tests.rs @@ -1468,13 +1468,16 @@ fn can_open_requester_token() { let expected_info_buffer = get_current_user_info(); let hf = open_file("Z:\\test_open_requester_token"); assert_eq_win32!(CloseHandle(hf), TRUE); - if let HandlerSignal::OpenRequesterToken(info_buffer) = context.signal() { - let expected_info = &*(expected_info_buffer.as_ptr() as *const TOKEN_USER); - let info = &*(info_buffer.as_ptr() as *const TOKEN_USER); - assert_eq_win32!(EqualSid(info.User.Sid, expected_info.User.Sid), TRUE); - assert_eq!(info.User.Attributes, expected_info.User.Attributes); - } else { - panic!("unexpected signal type"); + match context.signal() { + HandlerSignal::OpenRequesterToken(info_buffer) => { + let expected_info = &*(expected_info_buffer.as_ptr() as *const TOKEN_USER); + let info = &*(info_buffer.as_ptr() as *const TOKEN_USER); + assert_eq_win32!(EqualSid(info.User.Sid, expected_info.User.Sid), TRUE); + assert_eq!(info.User.Attributes, expected_info.User.Attributes); + } + _ => { + panic!("unexpected signal type"); + } } }); } From 396fd7762bf5be5c2152ca5f523b4cc8c6cfe97f Mon Sep 17 00:00:00 2001 From: Jon-Luke Biddle Date: Tue, 31 Mar 2026 18:27:22 -0600 Subject: [PATCH 2/8] add .lock file to .gitignore --- .gitignore | 1 + Cargo.lock | 385 ----------------------------------------------------- 2 files changed, 1 insertion(+), 385 deletions(-) delete mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 332008f..7377b8f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target **/*.rs.bk .idea/ +Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 88149e6..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,385 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "anstream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" - -[[package]] -name = "anstyle-parse" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys", -] - -[[package]] -name = "bitflags" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" - -[[package]] -name = "block2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" -dependencies = [ - "objc2", -] - -[[package]] -name = "cc" -version = "1.2.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "clap" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_lex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" - -[[package]] -name = "colorchoice" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" - -[[package]] -name = "ctrlc" -version = "3.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162" -dependencies = [ - "dispatch2", - "nix", - "windows-sys", -] - -[[package]] -name = "dispatch2" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" -dependencies = [ - "bitflags", - "block2", - "libc", - "objc2", -] - -[[package]] -name = "dokan" -version = "0.3.1+dokan230" -dependencies = [ - "bitflags", - "clap", - "ctrlc", - "dokan-sys", - "lazy_static", - "parking_lot", - "regex", - "widestring", - "winapi", -] - -[[package]] -name = "dokan-sys" -version = "0.3.1+dokan230" -dependencies = [ - "cc", - "libc", - "winapi", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "nix" -version = "0.31.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3" -dependencies = [ - "bitflags", - "cfg-if", - "cfg_aliases", - "libc", -] - -[[package]] -name = "objc2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" -dependencies = [ - "objc2-encode", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "widestring" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] From 43a4a995d284b62afd2e5dc19deb673bb5418c96 Mon Sep 17 00:00:00 2001 From: Jon-Luke Biddle Date: Tue, 31 Mar 2026 19:22:06 -0600 Subject: [PATCH 3/8] upgrade dependencies --- dokan-sys/Cargo.toml | 3 +- dokan-sys/src/lib.rs | 131 +++++++++------- dokan-sys/src/win32.rs | 9 +- dokan/Cargo.toml | 17 +- dokan/examples/memfs/main.rs | 166 ++++++++++++-------- dokan/examples/memfs/path.rs | 4 +- dokan/examples/memfs/security.rs | 218 +++++++++++++------------- dokan/src/data/file_info.rs | 2 +- dokan/src/data/file_time_operation.rs | 2 +- dokan/src/data/fill_data.rs | 7 +- dokan/src/data/find_data.rs | 18 +-- dokan/src/data/mount_point.rs | 4 +- dokan/src/data/operation_info.rs | 6 +- dokan/src/file_system.rs | 23 +-- dokan/src/file_system_handler.rs | 11 +- dokan/src/lib.rs | 26 ++- dokan/src/notify.rs | 2 +- dokan/src/operations.rs | 79 +++++----- dokan/src/operations_helpers.rs | 5 +- dokan/src/to_file_time.rs | 2 +- dokan/src/usage_tests.rs | 103 ++++++------ 21 files changed, 440 insertions(+), 398 deletions(-) diff --git a/dokan-sys/Cargo.toml b/dokan-sys/Cargo.toml index fb1dedd..b30c03b 100644 --- a/dokan-sys/Cargo.toml +++ b/dokan-sys/Cargo.toml @@ -18,8 +18,7 @@ build = "build.rs" appveyor = { repository = "Liryna/dokan-rust" } [dependencies] -libc = "0.2" -winapi = { version = "0.3", features = ["std", "basetsd", "fileapi", "minwinbase", "minwindef", "ntdef", "winnt"] } +windows-sys = { version = "0.61", features = ["Win32_Foundation", "Win32_Storage_FileSystem", "Win32_Security", "Win32_System_IO", "Win32_System_Threading"] } [build-dependencies] cc = "1.2" diff --git a/dokan-sys/src/lib.rs b/dokan-sys/src/lib.rs index 7a48f26..2701246 100644 --- a/dokan-sys/src/lib.rs +++ b/dokan-sys/src/lib.rs @@ -13,26 +13,40 @@ //! [Dokan's documentation]: https://dokan-dev.github.io/dokany-doc/html/ //! [`dokan`]: https://crates.io/crates/dokan -use libc::c_int; +use core::ffi::{c_int, c_void}; use win32::PWIN32_FIND_STREAM_DATA; -use winapi::{ - shared::{ - basetsd::ULONG64, - minwindef::{BOOL, DWORD, FILETIME, LPCVOID, LPDWORD, LPVOID, MAX_PATH}, - ntdef::{ - BOOLEAN, HANDLE, LONGLONG, LPCWSTR, LPWSTR, NTSTATUS, PULONG, PULONGLONG, PVOID, SCHAR, - UCHAR, ULONG, UNICODE_STRING, USHORT, WCHAR, - }, - }, - um::{ - fileapi::LPBY_HANDLE_FILE_INFORMATION, - minwinbase::PWIN32_FIND_DATAW, - winnt::{ - ACCESS_MASK, PHANDLE, PSECURITY_DESCRIPTOR, PSECURITY_INFORMATION, - WAITORTIMERCALLBACKFUNC, - }, - }, +use windows_sys::Win32::{ + Foundation::{FILETIME, HANDLE, MAX_PATH, NTSTATUS, UNICODE_STRING}, + Security::PSECURITY_DESCRIPTOR, + Storage::FileSystem::{BY_HANDLE_FILE_INFORMATION, WIN32_FIND_DATAW}, + System::Threading::WAITORTIMERCALLBACK, }; +use windows_sys::core::{BOOL, PCWSTR, PWSTR}; + +/// Win32 `BOOLEAN` type (unsigned 8-bit). +pub type BOOLEAN = u8; + +// Type aliases matching the old winapi names for compatibility. +pub type ULONG64 = u64; +pub type DWORD = u32; +pub type ULONG = u32; +pub type USHORT = u16; +pub type UCHAR = u8; +pub type WCHAR = u16; +pub type SCHAR = i8; +pub type LONGLONG = i64; +pub type ACCESS_MASK = u32; + +pub type PVOID = *mut c_void; +pub type LPVOID = *mut c_void; +pub type LPCVOID = *const c_void; +pub type LPDWORD = *mut u32; +pub type PULONG = *mut u32; +pub type PULONGLONG = *mut u64; +pub type PHANDLE = *mut HANDLE; +pub type PSECURITY_INFORMATION = *mut u32; +pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION; +pub type PWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW; pub mod win32; @@ -52,7 +66,7 @@ pub const DOKAN_OPTION_ENABLE_UNMOUNT_NETWORK_DRIVE: ULONG = 1 << 10; pub const DOKAN_OPTION_DISPATCH_DRIVER_LOGS: ULONG = 1 << 11; pub const DOKAN_OPTION_ALLOW_IPC_BATCHING: ULONG = 1 << 12; -pub type DOKAN_HANDLE = *mut libc::c_void; +pub type DOKAN_HANDLE = *mut c_void; pub type PDOKAN_HANDLE = *mut DOKAN_HANDLE; pub const VOLUME_SECURITY_DESCRIPTOR_MAX_SIZE: usize = 1024 * 16; @@ -64,8 +78,8 @@ pub struct DOKAN_OPTIONS { pub SingleThread: BOOLEAN, pub Options: ULONG, pub GlobalContext: ULONG64, - pub MountPoint: LPCWSTR, - pub UNCName: LPCWSTR, + pub MountPoint: PCWSTR, + pub UNCName: PCWSTR, pub Timeout: ULONG, pub AllocationUnitSize: ULONG, pub SectorSize: ULONG, @@ -126,7 +140,7 @@ pub type PDOKAN_IO_SECURITY_CONTEXT = *mut DOKAN_IO_SECURITY_CONTEXT; pub struct DOKAN_OPERATIONS { pub ZwCreateFile: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, SecurityContext: PDOKAN_IO_SECURITY_CONTEXT, DesiredAccess: ACCESS_MASK, FileAttributes: ULONG, @@ -136,11 +150,11 @@ pub struct DOKAN_OPERATIONS { DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, - pub Cleanup: Option, - pub CloseFile: Option, + pub Cleanup: Option, + pub CloseFile: Option, pub ReadFile: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, Buffer: LPVOID, BufferLength: DWORD, ReadLength: LPDWORD, @@ -150,7 +164,7 @@ pub struct DOKAN_OPERATIONS { >, pub WriteFile: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, Buffer: LPCVOID, NumberOfBytesToWrite: DWORD, NumberOfBytesWritten: LPDWORD, @@ -159,39 +173,39 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub FlushFileBuffers: - Option NTSTATUS>, + Option NTSTATUS>, pub GetFileInformation: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, Buffer: LPBY_HANDLE_FILE_INFORMATION, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub FindFiles: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, FillFindData: PFillFindData, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub FindFilesWithPattern: Option< extern "system" fn( - PathName: LPCWSTR, - SearchPattern: LPCWSTR, + PathName: PCWSTR, + SearchPattern: PCWSTR, FillFindData: PFillFindData, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub SetFileAttributes: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, FileAttributes: DWORD, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub SetFileTime: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, creation_time: *const FILETIME, last_access_time: *const FILETIME, last_write_time: *const FILETIME, @@ -199,34 +213,34 @@ pub struct DOKAN_OPERATIONS { ) -> NTSTATUS, >, pub DeleteFile: - Option NTSTATUS>, + Option NTSTATUS>, pub DeleteDirectory: - Option NTSTATUS>, + Option NTSTATUS>, pub MoveFile: Option< extern "system" fn( - FileName: LPCWSTR, - NewFileName: LPCWSTR, + FileName: PCWSTR, + NewFileName: PCWSTR, ReplaceIfExisting: BOOL, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub SetEndOfFile: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, ByteOffset: LONGLONG, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub SetAllocationSize: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, AllocSize: LONGLONG, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, pub LockFile: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, ByteOffset: LONGLONG, Length: LONGLONG, DokanFileInfo: PDOKAN_FILE_INFO, @@ -234,7 +248,7 @@ pub struct DOKAN_OPERATIONS { >, pub UnlockFile: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, ByteOffset: LONGLONG, Length: LONGLONG, DokanFileInfo: PDOKAN_FILE_INFO, @@ -250,23 +264,22 @@ pub struct DOKAN_OPERATIONS { >, pub GetVolumeInformation: Option< extern "system" fn( - VolumeNameBuffer: LPWSTR, + VolumeNameBuffer: PWSTR, VolumeNameSize: DWORD, VolumeSerialNumber: LPDWORD, MaximumComponentLength: LPDWORD, FileSystemFlags: LPDWORD, - FileSystemNameBuffer: LPWSTR, + FileSystemNameBuffer: PWSTR, FileSystemNameSize: DWORD, DokanFileInfo: PDOKAN_FILE_INFO, ) -> NTSTATUS, >, - pub Mounted: Option< - extern "system" fn(MountPoint: LPCWSTR, DokanFileInfo: PDOKAN_FILE_INFO) -> NTSTATUS, - >, + pub Mounted: + Option NTSTATUS>, pub Unmounted: Option NTSTATUS>, pub GetFileSecurity: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, PSECURITY_INFORMATION: PSECURITY_INFORMATION, PSECURITY_DESCRIPTOR: PSECURITY_DESCRIPTOR, BufferLength: ULONG, @@ -276,7 +289,7 @@ pub struct DOKAN_OPERATIONS { >, pub SetFileSecurity: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, SecurityInformation: PSECURITY_INFORMATION, SecurityDescriptor: PSECURITY_DESCRIPTOR, BufferLength: ULONG, @@ -285,7 +298,7 @@ pub struct DOKAN_OPERATIONS { >, pub FindStreams: Option< extern "system" fn( - FileName: LPCWSTR, + FileName: PCWSTR, FillFindStreamData: PFillFindStreamData, FindStreamContext: PVOID, DokanFileInfo: PDOKAN_FILE_INFO, @@ -307,7 +320,7 @@ pub const DOKAN_VERSION_ERROR: c_int = -7; #[repr(C)] pub struct DOKAN_MOUNT_POINT_INFO { pub Type: ULONG, - pub MountPoint: [WCHAR; MAX_PATH], + pub MountPoint: [WCHAR; MAX_PATH as usize], pub UNCName: [WCHAR; 64], pub DeviceName: [WCHAR; 64], pub SessionId: ULONG, @@ -333,7 +346,7 @@ unsafe extern "system" { pub fn DokanRegisterWaitForFileSystemClosed( DokanInstance: DOKAN_HANDLE, WaitHandle: PHANDLE, - Callback: WAITORTIMERCALLBACKFUNC, + Callback: WAITORTIMERCALLBACK, Context: PVOID, dwMilliseconds: ULONG, ) -> BOOL; @@ -343,8 +356,8 @@ unsafe extern "system" { ) -> BOOL; pub fn DokanCloseHandle(DokanInstance: DOKAN_HANDLE); pub fn DokanUnmount(DriveLetter: WCHAR) -> BOOL; - pub fn DokanRemoveMountPoint(MountPoint: LPCWSTR) -> BOOL; - pub fn DokanIsNameInExpression(Expression: LPCWSTR, Name: LPCWSTR, IgnoreCase: BOOL) -> BOOL; + pub fn DokanRemoveMountPoint(MountPoint: PCWSTR) -> BOOL; + pub fn DokanIsNameInExpression(Expression: PCWSTR, Name: PCWSTR, IgnoreCase: BOOL) -> BOOL; pub fn DokanVersion() -> ULONG; pub fn DokanDriverVersion() -> ULONG; pub fn DokanResetTimeout(Timeout: ULONG, DokanFileInfo: PDOKAN_FILE_INFO) -> BOOL; @@ -362,20 +375,20 @@ unsafe extern "system" { ); pub fn DokanNotifyCreate( DokanInstance: DOKAN_HANDLE, - FilePath: LPCWSTR, + FilePath: PCWSTR, IsDirectory: BOOL, ) -> BOOL; pub fn DokanNotifyDelete( DokanInstance: DOKAN_HANDLE, - FilePath: LPCWSTR, + FilePath: PCWSTR, IsDirectory: BOOL, ) -> BOOL; - pub fn DokanNotifyUpdate(DokanInstance: DOKAN_HANDLE, FilePath: LPCWSTR) -> BOOL; - pub fn DokanNotifyXAttrUpdate(DokanInstance: DOKAN_HANDLE, FilePath: LPCWSTR) -> BOOL; + pub fn DokanNotifyUpdate(DokanInstance: DOKAN_HANDLE, FilePath: PCWSTR) -> BOOL; + pub fn DokanNotifyXAttrUpdate(DokanInstance: DOKAN_HANDLE, FilePath: PCWSTR) -> BOOL; pub fn DokanNotifyRename( DokanInstance: DOKAN_HANDLE, - OldPath: LPCWSTR, - NewPath: LPCWSTR, + OldPath: PCWSTR, + NewPath: PCWSTR, IsDirectory: BOOL, IsInSameDirectory: BOOL, ) -> BOOL; diff --git a/dokan-sys/src/win32.rs b/dokan-sys/src/win32.rs index 8172942..54c5e7a 100644 --- a/dokan-sys/src/win32.rs +++ b/dokan-sys/src/win32.rs @@ -1,12 +1,9 @@ -use winapi::shared::{ - minwindef::MAX_PATH, - ntdef::{LARGE_INTEGER, WCHAR}, -}; +use windows_sys::Win32::Foundation::MAX_PATH; #[repr(C)] pub struct WIN32_FIND_STREAM_DATA { - pub StreamSize: LARGE_INTEGER, - pub cStreamName: [WCHAR; MAX_PATH + 36], + pub StreamSize: i64, + pub cStreamName: [u16; MAX_PATH as usize + 36], } pub type PWIN32_FIND_STREAM_DATA = *mut WIN32_FIND_STREAM_DATA; diff --git a/dokan/Cargo.toml b/dokan/Cargo.toml index 702931b..8ce203d 100644 --- a/dokan/Cargo.toml +++ b/dokan/Cargo.toml @@ -16,16 +16,25 @@ edition = "2024" appveyor = { repository = "Liryna/dokan-rust" } [dependencies] -bitflags = "2.9" +bitflags = "2.11" dokan-sys = { path = "../dokan-sys" } widestring = "1.2" -winapi = { version = "0.3", features = ["std", "errhandlingapi", "handleapi", "heapapi", "ioapiset", "minwinbase", "minwindef", "ntdef", "ntstatus", "processenv", "processthreadsapi", "sddl", "securitybaseapi", "synchapi", "winbase", "winerror", "winnt"] } +windows-sys = { version = "0.61", features = [ + "Win32_Foundation", + "Win32_Storage_FileSystem", + "Win32_Security", + "Win32_Security_Authorization", + "Win32_System_Environment", + "Win32_System_IO", + "Win32_System_Memory", + "Win32_System_RemoteDesktop", + "Win32_System_SystemServices", + "Win32_System_Threading", +] } [dev-dependencies] clap = "4.5" ctrlc = "3.4" -lazy_static = "1.5" -parking_lot = "0.12" regex = "1.11" [package.metadata.docs.rs] diff --git a/dokan/examples/memfs/main.rs b/dokan/examples/memfs/main.rs index f7e9463..394c65c 100644 --- a/dokan/examples/memfs/main.rs +++ b/dokan/examples/memfs/main.rs @@ -7,27 +7,46 @@ use std::{ hash::{Hash, Hasher}, os::windows::io::AsRawHandle, sync::{ - atomic::{AtomicBool, AtomicU64, Ordering}, Arc, Mutex, RwLock, Weak, + atomic::{AtomicBool, AtomicU64, Ordering}, }, time::SystemTime, }; use clap::{Arg, ArgAction, Command}; use dokan::{ - init, shutdown, unmount, CreateFileInfo, DiskSpaceInfo, FileInfo, FileSystemHandler, - FileSystemMounter, FileTimeOperation, FillDataError, FillDataResult, FindData, FindStreamData, - MountFlags, MountOptions, OperationInfo, OperationResult, VolumeInfo, IO_SECURITY_CONTEXT, + CreateFileInfo, DiskSpaceInfo, FileInfo, FileSystemHandler, FileSystemMounter, + FileTimeOperation, FillDataError, FillDataResult, FindData, FindStreamData, + IO_SECURITY_CONTEXT, MountFlags, MountOptions, OperationInfo, OperationResult, VolumeInfo, + init, shutdown, unmount, }; -use dokan_sys::win32::{ - FILE_CREATE, FILE_DELETE_ON_CLOSE, FILE_DIRECTORY_FILE, FILE_MAXIMUM_DISPOSITION, - FILE_NON_DIRECTORY_FILE, FILE_OPEN, FILE_OPEN_IF, FILE_OVERWRITE, FILE_OVERWRITE_IF, - FILE_SUPERSEDE, +use dokan_sys::{ + ACCESS_MASK, + win32::{ + FILE_CREATE, FILE_DELETE_ON_CLOSE, FILE_DIRECTORY_FILE, FILE_MAXIMUM_DISPOSITION, + FILE_NON_DIRECTORY_FILE, FILE_OPEN, FILE_OPEN_IF, FILE_OVERWRITE, FILE_OVERWRITE_IF, + FILE_SUPERSEDE, + }, }; use widestring::{U16CStr, U16CString, U16Str, U16String}; -use winapi::{ - shared::{ntdef, ntstatus::*}, - um::winnt, +use windows_sys::Win32::{ + Foundation::{ + HANDLE, STATUS_ACCESS_DENIED, STATUS_BUFFER_OVERFLOW, STATUS_CANNOT_DELETE, + STATUS_DELETE_PENDING, STATUS_DIRECTORY_NOT_EMPTY, STATUS_FILE_IS_A_DIRECTORY, + STATUS_INVALID_DEVICE_REQUEST, STATUS_INVALID_PARAMETER, STATUS_NOT_A_DIRECTORY, + STATUS_OBJECT_NAME_COLLISION, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_NOT_FOUND, + STATUS_SHARING_VIOLATION, + }, + Security::PSECURITY_DESCRIPTOR, + Storage::FileSystem::{ + FILE_APPEND_DATA, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_HIDDEN, + FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, FILE_ATTRIBUTE_OFFLINE, + FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_TEMPORARY, FILE_WRITE_DATA, + }, + System::SystemServices::{ + FILE_CASE_PRESERVED_NAMES, FILE_CASE_SENSITIVE_SEARCH, FILE_NAMED_STREAMS, + FILE_PERSISTENT_ACLS, FILE_UNICODE_ON_DISK, + }, }; use crate::{path::FullName, security::SecurityDescriptor}; @@ -56,13 +75,13 @@ struct Attributes { impl Attributes { fn new(attrs: u32) -> Self { - const SUPPORTED_ATTRS: u32 = winnt::FILE_ATTRIBUTE_ARCHIVE - | winnt::FILE_ATTRIBUTE_HIDDEN - | winnt::FILE_ATTRIBUTE_NOT_CONTENT_INDEXED - | winnt::FILE_ATTRIBUTE_OFFLINE - | winnt::FILE_ATTRIBUTE_READONLY - | winnt::FILE_ATTRIBUTE_SYSTEM - | winnt::FILE_ATTRIBUTE_TEMPORARY; + const SUPPORTED_ATTRS: u32 = FILE_ATTRIBUTE_ARCHIVE + | FILE_ATTRIBUTE_HIDDEN + | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED + | FILE_ATTRIBUTE_OFFLINE + | FILE_ATTRIBUTE_READONLY + | FILE_ATTRIBUTE_SYSTEM + | FILE_ATTRIBUTE_TEMPORARY; Self { value: attrs & SUPPORTED_ATTRS, } @@ -71,10 +90,10 @@ impl Attributes { fn get_output_attrs(&self, is_dir: bool) -> u32 { let mut attrs = self.value; if is_dir { - attrs |= winnt::FILE_ATTRIBUTE_DIRECTORY; + attrs |= FILE_ATTRIBUTE_DIRECTORY; } if attrs == 0 { - attrs = winnt::FILE_ATTRIBUTE_NORMAL + attrs = FILE_ATTRIBUTE_NORMAL } attrs } @@ -410,13 +429,13 @@ impl MemFsHandler { name: &FullName, attrs: u32, delete_pending: bool, - creator_desc: winnt::PSECURITY_DESCRIPTOR, - token: ntdef::HANDLE, + creator_desc: PSECURITY_DESCRIPTOR, + token: HANDLE, parent: &Arc, children: &mut HashMap, is_dir: bool, ) -> OperationResult> { - if attrs & winnt::FILE_ATTRIBUTE_READONLY > 0 && delete_pending { + if attrs & FILE_ATTRIBUTE_READONLY > 0 && delete_pending { return Err(STATUS_CANNOT_DELETE); } let mut stat = Stat::new( @@ -435,10 +454,11 @@ impl MemFsHandler { None } else { let stream = Arc::new(RwLock::new(AltStream::new())); - assert!(stat - .alt_streams - .insert(EntryName(stream_info.name.to_owned()), Arc::clone(&stream)) - .is_none()); + assert!( + stat.alt_streams + .insert(EntryName(stream_info.name.to_owned()), Arc::clone(&stream)) + .is_none() + ); Some(stream) } } else { @@ -449,9 +469,11 @@ impl MemFsHandler { } else { Entry::File(Arc::new(FileEntry::new(stat))) }; - assert!(children - .insert(EntryName(name.file_name.to_owned()), entry.clone()) - .is_none()); + assert!( + children + .insert(EntryName(name.file_name.to_owned()), entry.clone()) + .is_none() + ); parent.stat.write().unwrap().update_mtime(SystemTime::now()); let is_dir = is_dir && stream.is_some(); Ok(CreateFileInfo { @@ -479,7 +501,7 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { &'h self, file_name: &U16CStr, security_context: &IO_SECURITY_CONTEXT, - desired_access: winnt::ACCESS_MASK, + desired_access: ACCESS_MASK, file_attributes: u32, _share_access: u32, create_disposition: u32, @@ -502,18 +524,18 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { let mut children = parent.children.write().unwrap(); if let Some(entry) = children.get(EntryNameRef::new(name.file_name)) { let stat = entry.stat().read().unwrap(); - let is_readonly = stat.attrs.value & winnt::FILE_ATTRIBUTE_READONLY > 0; + let is_readonly = stat.attrs.value & FILE_ATTRIBUTE_READONLY > 0; let is_hidden_system = create_disposition == FILE_OVERWRITE_IF - && (stat.attrs.value & winnt::FILE_ATTRIBUTE_HIDDEN > 0 - && !(file_attributes & winnt::FILE_ATTRIBUTE_HIDDEN > 0) - || stat.attrs.value & winnt::FILE_ATTRIBUTE_SYSTEM > 0 - && !(file_attributes & winnt::FILE_ATTRIBUTE_SYSTEM > 0)); + && (stat.attrs.value & FILE_ATTRIBUTE_HIDDEN > 0 + && !(file_attributes & FILE_ATTRIBUTE_HIDDEN > 0) + || stat.attrs.value & FILE_ATTRIBUTE_SYSTEM > 0 + && !(file_attributes & FILE_ATTRIBUTE_SYSTEM > 0)); if is_readonly && delete_pending { return Err(STATUS_CANNOT_DELETE); } if is_readonly - && (desired_access & winnt::FILE_WRITE_DATA > 0 - || desired_access & winnt::FILE_APPEND_DATA > 0) + && (desired_access & FILE_WRITE_DATA > 0 + || desired_access & FILE_APPEND_DATA > 0) { return Err(STATUS_ACCESS_DENIED); } @@ -538,7 +560,7 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { if create_disposition != FILE_SUPERSEDE && is_readonly { return Err(STATUS_ACCESS_DENIED); } - stat.attrs.value |= winnt::FILE_ATTRIBUTE_ARCHIVE; + stat.attrs.value |= FILE_ATTRIBUTE_ARCHIVE; stat.update_mtime(SystemTime::now()); stream.write().unwrap().data.clear(); } @@ -557,10 +579,14 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { } let stream = Arc::new(RwLock::new(AltStream::new())); stat.update_atime(SystemTime::now()); - assert!(stat - .alt_streams - .insert(EntryName(stream_info.name.to_owned()), Arc::clone(&stream)) - .is_none()); + assert!( + stat.alt_streams + .insert( + EntryName(stream_info.name.to_owned()), + Arc::clone(&stream) + ) + .is_none() + ); Some((stream, true)) } } @@ -590,9 +616,8 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { } file.data.write().unwrap().clear(); let mut stat = file.stat.write().unwrap(); - stat.attrs = Attributes::new( - file_attributes | winnt::FILE_ATTRIBUTE_ARCHIVE, - ); + stat.attrs = + Attributes::new(file_attributes | FILE_ATTRIBUTE_ARCHIVE); stat.update_mtime(SystemTime::now()); } FILE_CREATE => return Err(STATUS_OBJECT_NAME_COLLISION), @@ -653,7 +678,7 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { } else { self.create_new( &name, - file_attributes | winnt::FILE_ATTRIBUTE_ARCHIVE, + file_attributes | FILE_ATTRIBUTE_ARCHIVE, delete_pending, security_context.AccessState.SecurityDescriptor, token.as_raw_handle(), @@ -760,7 +785,7 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { Err(STATUS_ACCESS_DENIED) }; if ret.is_ok() { - context.entry.stat().write().unwrap().attrs.value |= winnt::FILE_ATTRIBUTE_ARCHIVE; + context.entry.stat().write().unwrap().attrs.value |= FILE_ATTRIBUTE_ARCHIVE; let now = SystemTime::now(); if context.mtime_enabled.load(Ordering::Relaxed) { *context.mtime_delayed.lock().unwrap() = Some(now); @@ -887,7 +912,7 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { info: &OperationInfo<'c, 'h, Self>, context: &'c Self::Context, ) -> OperationResult<()> { - if context.entry.stat().read().unwrap().attrs.value & winnt::FILE_ATTRIBUTE_READONLY > 0 { + if context.entry.stat().read().unwrap().attrs.value & FILE_ATTRIBUTE_READONLY > 0 { return Err(STATUS_CANNOT_DELETE); } let alt_stream = context.alt_stream.read().unwrap(); @@ -1003,10 +1028,11 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { stream.data = data.clone(); data.clear(); let stream = Arc::new(RwLock::new(stream)); - assert!(stat - .alt_streams - .insert(EntryName(dst_name.to_owned()), Arc::clone(&stream)) - .is_none()); + assert!( + stat.alt_streams + .insert(EntryName(dst_name.to_owned()), Arc::clone(&stream)) + .is_none() + ); *context.alt_stream.write().unwrap() = Some(stream); } else { return Err(STATUS_OBJECT_NAME_INVALID); @@ -1071,8 +1097,8 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { Err(STATUS_ACCESS_DENIED) } else { let stat = entry.stat().read().unwrap(); - let can_replace = stat.handle_count > 0 - || stat.attrs.value & winnt::FILE_ATTRIBUTE_READONLY > 0; + let can_replace = + stat.handle_count > 0 || stat.attrs.value & FILE_ATTRIBUTE_READONLY > 0; std::mem::drop(stat); if can_replace { Err(STATUS_ACCESS_DENIED) @@ -1090,9 +1116,11 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { check_can_move(&mut children)?; // Remove first in case moving to the same name. let entry = children.remove(src_name_ref).unwrap(); - assert!(children - .insert(EntryName(dst_name.file_name.to_owned()), entry) - .is_none()); + assert!( + children + .insert(EntryName(dst_name.file_name.to_owned()), entry) + .is_none() + ); src_parent.stat.write().unwrap().update_mtime(now); context.update_atime(&mut context.entry.stat().write().unwrap(), now); } else { @@ -1100,9 +1128,11 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { let mut dst_children = dst_parent.children.write().unwrap(); check_can_move(&mut dst_children)?; let entry = src_children.remove(src_name_ref).unwrap(); - assert!(dst_children - .insert(EntryName(dst_name.file_name.to_owned()), entry) - .is_none()); + assert!( + dst_children + .insert(EntryName(dst_name.file_name.to_owned()), entry) + .is_none() + ); src_parent.stat.write().unwrap().update_mtime(now); dst_parent.stat.write().unwrap().update_mtime(now); let mut stat = context.entry.stat().write().unwrap(); @@ -1197,11 +1227,11 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { name: U16CString::from_str("dokan-rust memfs").unwrap(), serial_number: 0, max_component_length: path::MAX_COMPONENT_LENGTH, - fs_flags: winnt::FILE_CASE_PRESERVED_NAMES - | winnt::FILE_CASE_SENSITIVE_SEARCH - | winnt::FILE_UNICODE_ON_DISK - | winnt::FILE_PERSISTENT_ACLS - | winnt::FILE_NAMED_STREAMS, + fs_flags: FILE_CASE_PRESERVED_NAMES + | FILE_CASE_SENSITIVE_SEARCH + | FILE_UNICODE_ON_DISK + | FILE_PERSISTENT_ACLS + | FILE_NAMED_STREAMS, // Custom names don't play well with UAC. fs_name: U16CString::from_str("NTFS").unwrap(), }) @@ -1223,7 +1253,7 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { &'h self, _file_name: &U16CStr, security_information: u32, - security_descriptor: winnt::PSECURITY_DESCRIPTOR, + security_descriptor: PSECURITY_DESCRIPTOR, buffer_length: u32, _info: &OperationInfo<'c, 'h, Self>, context: &'c Self::Context, @@ -1241,7 +1271,7 @@ impl<'c, 'h: 'c> FileSystemHandler<'c, 'h> for MemFsHandler { &'h self, _file_name: &U16CStr, security_information: u32, - security_descriptor: winnt::PSECURITY_DESCRIPTOR, + security_descriptor: PSECURITY_DESCRIPTOR, _buffer_length: u32, _info: &OperationInfo<'c, 'h, Self>, context: &'c Self::Context, diff --git a/dokan/examples/memfs/path.rs b/dokan/examples/memfs/path.rs index def1585..1a4b6c0 100644 --- a/dokan/examples/memfs/path.rs +++ b/dokan/examples/memfs/path.rs @@ -2,7 +2,9 @@ use std::{borrow::Borrow, sync::Arc}; use dokan::OperationResult; use widestring::{U16CStr, U16Str, U16String}; -use winapi::shared::ntstatus::*; +use windows_sys::Win32::Foundation::{ + STATUS_ACCESS_DENIED, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND, +}; use crate::{DirEntry, Entry, EntryName, EntryNameRef}; diff --git a/dokan/examples/memfs/security.rs b/dokan/examples/memfs/security.rs index 2b77590..52ab1e1 100644 --- a/dokan/examples/memfs/security.rs +++ b/dokan/examples/memfs/security.rs @@ -1,18 +1,39 @@ use std::{mem, pin::Pin, ptr}; -use dokan::{map_win32_error_to_ntstatus, win32_ensure, OperationResult}; -use winapi::{ - shared::{minwindef, ntdef, ntstatus::*, winerror}, - um::{errhandlingapi::GetLastError, heapapi, securitybaseapi, winnt}, +use dokan::{OperationResult, map_win32_error_to_ntstatus, win32_ensure}; +use windows_sys::Win32::{ + Foundation::{ + ERROR_INSUFFICIENT_BUFFER, FALSE, GetLastError, HANDLE, STATUS_INVALID_PARAMETER, TRUE, + }, + Security::{ + ACCESS_ALLOWED_ACE, ACL, ACL_REVISION, AddAccessAllowedAceEx, CONTAINER_INHERIT_ACE, + CreatePrivateObjectSecurity, CreateWellKnownSid, DestroyPrivateObjectSecurity, + GENERIC_MAPPING, GetPrivateObjectSecurity, GetSecurityDescriptorLength, InitializeAcl, + InitializeSecurityDescriptor, IsValidSecurityDescriptor, MakeSelfRelativeSD, + OBJECT_INHERIT_ACE, PSECURITY_DESCRIPTOR, PSID, SECURITY_DESCRIPTOR, SEF_AVOID_OWNER_CHECK, + SEF_AVOID_PRIVILEGE_CHECK, SID, SetPrivateObjectSecurityEx, SetSecurityDescriptorDacl, + SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, WELL_KNOWN_SID_TYPE, + WinAuthenticatedUserSid, WinBuiltinAdministratorsSid, WinBuiltinUsersSid, + WinLocalSystemSid, + }, + Storage::FileSystem::{ + DELETE, FILE_ALL_ACCESS, FILE_GENERIC_EXECUTE, FILE_GENERIC_READ, FILE_GENERIC_WRITE, + }, + System::{ + Memory::{GetProcessHeap, HeapAlloc, HeapFree}, + SystemServices::SECURITY_DESCRIPTOR_REVISION, + }, }; +type PACL = *mut ACL; + #[derive(Debug)] struct PrivateObjectSecurity { - value: winnt::PSECURITY_DESCRIPTOR, + value: PSECURITY_DESCRIPTOR, } impl PrivateObjectSecurity { - unsafe fn from_raw(ptr: winnt::PSECURITY_DESCRIPTOR) -> Self { + unsafe fn from_raw(ptr: PSECURITY_DESCRIPTOR) -> Self { Self { value: ptr } } } @@ -20,32 +41,32 @@ impl PrivateObjectSecurity { impl Drop for PrivateObjectSecurity { fn drop(&mut self) { unsafe { - securitybaseapi::DestroyPrivateObjectSecurity(&mut self.value); + DestroyPrivateObjectSecurity(&mut self.value); } } } #[derive(Debug)] pub struct SecurityDescriptor { - desc_ptr: winnt::PSECURITY_DESCRIPTOR, + desc_ptr: PSECURITY_DESCRIPTOR, } unsafe impl Sync for SecurityDescriptor {} unsafe impl Send for SecurityDescriptor {} -fn get_well_known_sid(sid_type: winnt::WELL_KNOWN_SID_TYPE) -> OperationResult> { +fn get_well_known_sid(sid_type: WELL_KNOWN_SID_TYPE) -> OperationResult> { unsafe { let mut sid = - vec![0u8; mem::size_of::() + mem::size_of::() * 7].into_boxed_slice(); + vec![0u8; mem::size_of::() + mem::size_of::() * 7].into_boxed_slice(); let mut len = sid.len() as u32; win32_ensure( - securitybaseapi::CreateWellKnownSid( + CreateWellKnownSid( sid_type, ptr::null_mut(), - sid.as_mut_ptr() as winnt::PSID, + sid.as_mut_ptr() as PSID, &mut len, - ) == minwindef::TRUE, + ) == TRUE, )?; Ok(sid) } @@ -53,114 +74,109 @@ fn get_well_known_sid(sid_type: winnt::WELL_KNOWN_SID_TYPE) -> OperationResult OperationResult> { unsafe { - let admins_sid = get_well_known_sid(winnt::WinBuiltinAdministratorsSid)?; - let system_sid = get_well_known_sid(winnt::WinLocalSystemSid)?; - let auth_sid = get_well_known_sid(winnt::WinAuthenticatedUserSid)?; - let users_sid = get_well_known_sid(winnt::WinBuiltinUsersSid)?; + let admins_sid = get_well_known_sid(WinBuiltinAdministratorsSid)?; + let system_sid = get_well_known_sid(WinLocalSystemSid)?; + let auth_sid = get_well_known_sid(WinAuthenticatedUserSid)?; + let users_sid = get_well_known_sid(WinBuiltinUsersSid)?; - let acl_len = mem::size_of::() - + (mem::size_of::() - mem::size_of::()) * 4 + let acl_len = mem::size_of::() + + (mem::size_of::() - mem::size_of::()) * 4 + admins_sid.len() + system_sid.len() + auth_sid.len() + users_sid.len(); let mut acl = vec![0u8; acl_len].into_boxed_slice(); win32_ensure( - securitybaseapi::InitializeAcl( - acl.as_mut_ptr() as winnt::PACL, + InitializeAcl( + acl.as_mut_ptr() as PACL, acl_len as u32, - winnt::ACL_REVISION as u32, - ) == minwindef::TRUE, + ACL_REVISION as u32, + ) == TRUE, )?; - let flags = (winnt::CONTAINER_INHERIT_ACE | winnt::OBJECT_INHERIT_ACE) as u32; + let flags = (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE) as u32; win32_ensure( - securitybaseapi::AddAccessAllowedAceEx( - acl.as_mut_ptr() as winnt::PACL, - winnt::ACL_REVISION as u32, + AddAccessAllowedAceEx( + acl.as_mut_ptr() as PACL, + ACL_REVISION as u32, flags, - winnt::FILE_ALL_ACCESS, - admins_sid.as_ptr() as winnt::PSID, - ) == minwindef::TRUE, + FILE_ALL_ACCESS, + admins_sid.as_ptr() as PSID, + ) == TRUE, )?; win32_ensure( - securitybaseapi::AddAccessAllowedAceEx( - acl.as_mut_ptr() as winnt::PACL, - winnt::ACL_REVISION as u32, + AddAccessAllowedAceEx( + acl.as_mut_ptr() as PACL, + ACL_REVISION as u32, flags, - winnt::FILE_ALL_ACCESS, - system_sid.as_ptr() as winnt::PSID, - ) == minwindef::TRUE, + FILE_ALL_ACCESS, + system_sid.as_ptr() as PSID, + ) == TRUE, )?; win32_ensure( - securitybaseapi::AddAccessAllowedAceEx( - acl.as_mut_ptr() as winnt::PACL, - winnt::ACL_REVISION as u32, + AddAccessAllowedAceEx( + acl.as_mut_ptr() as PACL, + ACL_REVISION as u32, flags, - winnt::FILE_GENERIC_READ - | winnt::FILE_GENERIC_WRITE - | winnt::FILE_GENERIC_EXECUTE - | winnt::DELETE, - auth_sid.as_ptr() as winnt::PSID, - ) == minwindef::TRUE, + FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE, + auth_sid.as_ptr() as PSID, + ) == TRUE, )?; win32_ensure( - securitybaseapi::AddAccessAllowedAceEx( - acl.as_mut_ptr() as winnt::PACL, - winnt::ACL_REVISION as u32, + AddAccessAllowedAceEx( + acl.as_mut_ptr() as PACL, + ACL_REVISION as u32, flags, - winnt::FILE_GENERIC_READ | winnt::FILE_GENERIC_EXECUTE, - users_sid.as_ptr() as winnt::PSID, - ) == minwindef::TRUE, + FILE_GENERIC_READ | FILE_GENERIC_EXECUTE, + users_sid.as_ptr() as PSID, + ) == TRUE, )?; Ok(acl) } } -const FILE_GENERIC_MAPPING: winnt::GENERIC_MAPPING = winnt::GENERIC_MAPPING { - GenericRead: winnt::FILE_GENERIC_READ, - GenericWrite: winnt::FILE_GENERIC_WRITE, - GenericExecute: winnt::FILE_GENERIC_EXECUTE, - GenericAll: winnt::FILE_ALL_ACCESS, +const FILE_GENERIC_MAPPING: GENERIC_MAPPING = GENERIC_MAPPING { + GenericRead: FILE_GENERIC_READ, + GenericWrite: FILE_GENERIC_WRITE, + GenericExecute: FILE_GENERIC_EXECUTE, + GenericAll: FILE_ALL_ACCESS, }; impl SecurityDescriptor { pub fn new_inherited( parent_desc: &SecurityDescriptor, - creator_desc: winnt::PSECURITY_DESCRIPTOR, - token: ntdef::HANDLE, + creator_desc: PSECURITY_DESCRIPTOR, + token: HANDLE, is_dir: bool, ) -> OperationResult { unsafe { - if !creator_desc.is_null() - && securitybaseapi::IsValidSecurityDescriptor(creator_desc) == minwindef::FALSE - { + if !creator_desc.is_null() && IsValidSecurityDescriptor(creator_desc) == FALSE { return Err(STATUS_INVALID_PARAMETER); } let mut priv_desc = ptr::null_mut(); win32_ensure( - securitybaseapi::CreatePrivateObjectSecurity( + CreatePrivateObjectSecurity( parent_desc.desc_ptr, creator_desc, &mut priv_desc, - is_dir as minwindef::BOOL, + is_dir as i32, token, &FILE_GENERIC_MAPPING as *const _ as *mut _, - ) == minwindef::TRUE, + ) == TRUE, )?; let priv_desc = PrivateObjectSecurity::from_raw(priv_desc); - let heap = heapapi::GetProcessHeap(); + let heap = GetProcessHeap(); win32_ensure(!heap.is_null())?; - let len = securitybaseapi::GetSecurityDescriptorLength(priv_desc.value) as usize; - let buf = heapapi::HeapAlloc(heap, 0, len); + let len = GetSecurityDescriptorLength(priv_desc.value) as usize; + let buf = HeapAlloc(heap, 0, len); win32_ensure(!buf.is_null())?; ptr::copy_nonoverlapping(priv_desc.value as *const u8, buf as *mut _, len); @@ -169,62 +185,44 @@ impl SecurityDescriptor { } pub fn new_default() -> OperationResult { - let owner_sid = Pin::new(get_well_known_sid(winnt::WinLocalSystemSid)?); - let group_sid = Pin::new(get_well_known_sid(winnt::WinLocalSystemSid)?); + let owner_sid = Pin::new(get_well_known_sid(WinLocalSystemSid)?); + let group_sid = Pin::new(get_well_known_sid(WinLocalSystemSid)?); let dacl = Pin::new(create_default_dacl()?); unsafe { - let mut abs_desc = mem::zeroed::(); - let abs_desc_ptr = &mut abs_desc as *mut _ as winnt::PSECURITY_DESCRIPTOR; + let mut abs_desc = mem::zeroed::(); + let abs_desc_ptr = &mut abs_desc as *mut _ as PSECURITY_DESCRIPTOR; win32_ensure( - securitybaseapi::InitializeSecurityDescriptor( - abs_desc_ptr, - winnt::SECURITY_DESCRIPTOR_REVISION, - ) == minwindef::TRUE, + InitializeSecurityDescriptor(abs_desc_ptr, SECURITY_DESCRIPTOR_REVISION) == TRUE, )?; win32_ensure( - securitybaseapi::SetSecurityDescriptorOwner( - abs_desc_ptr, - owner_sid.as_ptr() as winnt::PSID, - minwindef::FALSE, - ) == minwindef::TRUE, + SetSecurityDescriptorOwner(abs_desc_ptr, owner_sid.as_ptr() as PSID, FALSE) == TRUE, )?; win32_ensure( - securitybaseapi::SetSecurityDescriptorGroup( - abs_desc_ptr, - group_sid.as_ptr() as winnt::PSID, - minwindef::FALSE, - ) == minwindef::TRUE, + SetSecurityDescriptorGroup(abs_desc_ptr, group_sid.as_ptr() as PSID, FALSE) == TRUE, )?; win32_ensure( - securitybaseapi::SetSecurityDescriptorDacl( - abs_desc_ptr, - minwindef::TRUE, - dacl.as_ptr() as winnt::PACL, - minwindef::FALSE, - ) == minwindef::TRUE, + SetSecurityDescriptorDacl(abs_desc_ptr, TRUE, dacl.as_ptr() as PACL, FALSE) == TRUE, )?; let mut len = 0; - let ret = securitybaseapi::MakeSelfRelativeSD(abs_desc_ptr, ptr::null_mut(), &mut len); + let ret = MakeSelfRelativeSD(abs_desc_ptr, ptr::null_mut(), &mut len); let err = GetLastError(); - if ret != minwindef::FALSE || err != winerror::ERROR_INSUFFICIENT_BUFFER { + if ret != FALSE || err != ERROR_INSUFFICIENT_BUFFER { return Err(map_win32_error_to_ntstatus(err)); } - let heap = heapapi::GetProcessHeap(); + let heap = GetProcessHeap(); win32_ensure(!heap.is_null())?; - let buf = heapapi::HeapAlloc(heap, 0, len as usize); + let buf = HeapAlloc(heap, 0, len as usize); win32_ensure(!buf.is_null())?; - win32_ensure( - securitybaseapi::MakeSelfRelativeSD(abs_desc_ptr, buf, &mut len) == minwindef::TRUE, - )?; + win32_ensure(MakeSelfRelativeSD(abs_desc_ptr, buf, &mut len) == TRUE)?; Ok(Self { desc_ptr: buf }) } @@ -232,25 +230,25 @@ impl SecurityDescriptor { pub fn get_security_info( &self, - sec_info: winnt::SECURITY_INFORMATION, - sec_desc: winnt::PSECURITY_DESCRIPTOR, + sec_info: u32, + sec_desc: PSECURITY_DESCRIPTOR, sec_desc_len: u32, ) -> OperationResult { unsafe { - let len = securitybaseapi::GetSecurityDescriptorLength(self.desc_ptr); + let len = GetSecurityDescriptorLength(self.desc_ptr); if len > sec_desc_len { return Ok(len); } let mut ret_len = 0; win32_ensure( - securitybaseapi::GetPrivateObjectSecurity( + GetPrivateObjectSecurity( self.desc_ptr, sec_info, sec_desc, sec_desc_len, &mut ret_len, - ) == minwindef::TRUE, + ) == TRUE, )?; Ok(len) @@ -259,23 +257,23 @@ impl SecurityDescriptor { pub fn set_security_info( &mut self, - sec_info: winnt::SECURITY_INFORMATION, - sec_desc: winnt::PSECURITY_DESCRIPTOR, + sec_info: u32, + sec_desc: PSECURITY_DESCRIPTOR, ) -> OperationResult<()> { unsafe { - if securitybaseapi::IsValidSecurityDescriptor(sec_desc) == minwindef::FALSE { + if IsValidSecurityDescriptor(sec_desc) == FALSE { return Err(STATUS_INVALID_PARAMETER); } win32_ensure( - securitybaseapi::SetPrivateObjectSecurityEx( + SetPrivateObjectSecurityEx( sec_info, sec_desc, &mut self.desc_ptr, - winnt::SEF_AVOID_PRIVILEGE_CHECK | winnt::SEF_AVOID_OWNER_CHECK, + SEF_AVOID_PRIVILEGE_CHECK | SEF_AVOID_OWNER_CHECK, &FILE_GENERIC_MAPPING as *const _ as *mut _, ptr::null_mut(), - ) == minwindef::TRUE, + ) == TRUE, )?; Ok(()) @@ -286,7 +284,7 @@ impl SecurityDescriptor { impl Drop for SecurityDescriptor { fn drop(&mut self) { unsafe { - heapapi::HeapFree(heapapi::GetProcessHeap(), 0, self.desc_ptr); + HeapFree(GetProcessHeap(), 0, self.desc_ptr); } } } diff --git a/dokan/src/data/file_info.rs b/dokan/src/data/file_info.rs index 78d85b3..65e2c6a 100644 --- a/dokan/src/data/file_info.rs +++ b/dokan/src/data/file_info.rs @@ -1,6 +1,6 @@ use std::time::SystemTime; -use winapi::um::fileapi::BY_HANDLE_FILE_INFORMATION; +use windows_sys::Win32::Storage::FileSystem::BY_HANDLE_FILE_INFORMATION; use crate::to_file_time::ToFileTime; diff --git a/dokan/src/data/file_time_operation.rs b/dokan/src/data/file_time_operation.rs index b995a8b..2cf2b00 100644 --- a/dokan/src/data/file_time_operation.rs +++ b/dokan/src/data/file_time_operation.rs @@ -3,7 +3,7 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; -use winapi::shared::minwindef::FILETIME; +use windows_sys::Win32::Foundation::FILETIME; use crate::to_file_time::FILETIME_OFFSET; diff --git a/dokan/src/data/fill_data.rs b/dokan/src/data/fill_data.rs index 2e42c58..7fdd3dc 100644 --- a/dokan/src/data/fill_data.rs +++ b/dokan/src/data/fill_data.rs @@ -3,17 +3,14 @@ use std::{ fmt::{self, Display, Formatter}, }; -use winapi::shared::{ - ntdef::NTSTATUS, - ntstatus::{STATUS_BUFFER_OVERFLOW, STATUS_INTERNAL_ERROR}, -}; +use windows_sys::Win32::Foundation::{NTSTATUS, STATUS_BUFFER_OVERFLOW, STATUS_INTERNAL_ERROR}; /// Error type for the `fill_data` callbacks. #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum FillDataError { /// File name exceeds the limit of [`MAX_PATH`]. /// - /// [`MAX_PATH`]: winapi::shared::minwindef::MAX_PATH + /// [`MAX_PATH`]: windows_sys::Win32::Foundation::MAX_PATH NameTooLong, /// Buffer is full. diff --git a/dokan/src/data/find_data.rs b/dokan/src/data/find_data.rs index c9ad4a7..4ff311b 100644 --- a/dokan/src/data/find_data.rs +++ b/dokan/src/data/find_data.rs @@ -2,9 +2,9 @@ use std::{mem::transmute, time::SystemTime}; use dokan_sys::win32::WIN32_FIND_STREAM_DATA; use widestring::U16CString; -use winapi::{shared::minwindef::MAX_PATH, um::minwinbase::WIN32_FIND_DATAW}; +use windows_sys::Win32::{Foundation::MAX_PATH, Storage::FileSystem::WIN32_FIND_DATAW}; -use crate::{to_file_time::ToFileTime, FillDataError, FillDataResult}; +use crate::{FillDataError, FillDataResult, to_file_time::ToFileTime}; pub(crate) trait ToRawStruct { fn to_raw_struct(&self) -> Option; @@ -43,8 +43,8 @@ pub struct FindData { impl ToRawStruct for FindData { fn to_raw_struct(&self) -> Option { let name_slice = self.file_name.as_slice_with_nul(); - if name_slice.len() <= MAX_PATH { - let mut c_file_name = [0; MAX_PATH]; + if name_slice.len() <= MAX_PATH as usize { + let mut c_file_name = [0; MAX_PATH as usize]; c_file_name[..name_slice.len()].copy_from_slice(name_slice); Some(WIN32_FIND_DATAW { dwFileAttributes: self.attributes, @@ -81,7 +81,7 @@ pub struct FindStreamData { pub name: U16CString, } -const MAX_STREAM_NAME: usize = MAX_PATH + 36; +const MAX_STREAM_NAME: usize = MAX_PATH as usize + 36; impl ToRawStruct for FindStreamData { fn to_raw_struct(&self) -> Option { @@ -118,8 +118,8 @@ pub(crate) fn wrap_fill_data, TArg: Copy, TResult: PartialE mod tests { use std::ptr; + use core::ffi::c_int; use dokan_sys::PDOKAN_FILE_INFO; - use winapi::ctypes::c_int; use super::*; @@ -129,11 +129,7 @@ mod tests { impl ToRawStruct<()> for ToRawStructStub { fn to_raw_struct(&self) -> Option<()> { - if self.should_fail { - None - } else { - Some(()) - } + if self.should_fail { None } else { Some(()) } } } diff --git a/dokan/src/data/mount_point.rs b/dokan/src/data/mount_point.rs index cadaf1d..98a9f25 100644 --- a/dokan/src/data/mount_point.rs +++ b/dokan/src/data/mount_point.rs @@ -1,11 +1,11 @@ use std::{iter::Map, mem::transmute, slice}; +use dokan_sys::ULONG; use dokan_sys::{ win32::{FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_NETWORK_FILE_SYSTEM}, *, }; use widestring::U16CStr; -use winapi::shared::minwindef::ULONG; /// Mount point device type. #[repr(u32)] @@ -116,7 +116,7 @@ fn can_list_mount_points() { use std::process; use regex::Regex; - use winapi::{shared::minwindef::TRUE, um::processthreadsapi::ProcessIdToSessionId}; + use windows_sys::Win32::{Foundation::TRUE, System::RemoteDesktop::ProcessIdToSessionId}; use crate::usage_tests::{convert_str, with_test_drive}; diff --git a/dokan/src/data/operation_info.rs b/dokan/src/data/operation_info.rs index 02d8628..4d86b82 100644 --- a/dokan/src/data/operation_info.rs +++ b/dokan/src/data/operation_info.rs @@ -5,12 +5,12 @@ use std::{ }; use dokan_sys::{ - DokanOpenRequestorToken, DokanResetTimeout, DOKAN_FILE_INFO, DOKAN_OPTIONS, PDOKAN_FILE_INFO, + DOKAN_FILE_INFO, DOKAN_OPTIONS, DokanOpenRequestorToken, DokanResetTimeout, PDOKAN_FILE_INFO, }; use widestring::U16CStr; -use winapi::{shared::minwindef::TRUE, um::handleapi::INVALID_HANDLE_VALUE}; +use windows_sys::Win32::Foundation::{INVALID_HANDLE_VALUE, TRUE}; -use crate::{file_system_handler::FileSystemHandler, MountFlags}; +use crate::{MountFlags, file_system_handler::FileSystemHandler}; /// Information about the current operation. #[derive(Debug)] diff --git a/dokan/src/file_system.rs b/dokan/src/file_system.rs index 938f281..7f6b97b 100644 --- a/dokan/src/file_system.rs +++ b/dokan/src/file_system.rs @@ -8,21 +8,22 @@ use std::{ }; use bitflags::bitflags; +use dokan_sys::SCHAR; use dokan_sys::{ - DokanCloseHandle, DokanCreateFileSystem, DokanWaitForFileSystemClosed, - DOKAN_DRIVER_INSTALL_ERROR, DOKAN_DRIVE_LETTER_ERROR, DOKAN_ERROR, DOKAN_HANDLE, - DOKAN_MOUNT_ERROR, DOKAN_MOUNT_POINT_ERROR, DOKAN_OPERATIONS, DOKAN_OPTIONS, - DOKAN_OPTION_ALLOW_IPC_BATCHING, DOKAN_OPTION_ALT_STREAM, DOKAN_OPTION_CASE_SENSITIVE, - DOKAN_OPTION_CURRENT_SESSION, DOKAN_OPTION_DEBUG, DOKAN_OPTION_DISPATCH_DRIVER_LOGS, + DOKAN_DRIVE_LETTER_ERROR, DOKAN_DRIVER_INSTALL_ERROR, DOKAN_ERROR, DOKAN_HANDLE, + DOKAN_MOUNT_ERROR, DOKAN_MOUNT_POINT_ERROR, DOKAN_OPERATIONS, DOKAN_OPTION_ALLOW_IPC_BATCHING, + DOKAN_OPTION_ALT_STREAM, DOKAN_OPTION_CASE_SENSITIVE, DOKAN_OPTION_CURRENT_SESSION, + DOKAN_OPTION_DEBUG, DOKAN_OPTION_DISPATCH_DRIVER_LOGS, DOKAN_OPTION_ENABLE_UNMOUNT_NETWORK_DRIVE, DOKAN_OPTION_FILELOCK_USER_MODE, DOKAN_OPTION_MOUNT_MANAGER, DOKAN_OPTION_NETWORK, DOKAN_OPTION_REMOVABLE, DOKAN_OPTION_STDERR, - DOKAN_OPTION_WRITE_PROTECT, DOKAN_START_ERROR, DOKAN_SUCCESS, DOKAN_VERSION_ERROR, + DOKAN_OPTION_WRITE_PROTECT, DOKAN_OPTIONS, DOKAN_START_ERROR, DOKAN_SUCCESS, + DOKAN_VERSION_ERROR, DokanCloseHandle, DokanCreateFileSystem, DokanWaitForFileSystemClosed, VOLUME_SECURITY_DESCRIPTOR_MAX_SIZE, }; use widestring::U16CStr; -use winapi::{shared::ntdef::SCHAR, um::winbase::INFINITE}; +use windows_sys::Win32::System::Threading::INFINITE; -use crate::{file_system_handler::FileSystemHandler, operations, WRAPPER_VERSION}; +use crate::{WRAPPER_VERSION, file_system_handler::FileSystemHandler, operations}; bitflags! { /// Flags that control behavior of the mounted volume, as part of [`MountOptions`]. @@ -182,7 +183,9 @@ impl Display for FileSystemMountError { FileSystemMountError::DriveLetter => "bad drive letter", FileSystemMountError::DriverInstall => "can't install driver", FileSystemMountError::Start => "the driver responds that something is wrong", - FileSystemMountError::Mount => "can't assign a drive letter or mount point, probably already used by another volume", + FileSystemMountError::Mount => { + "can't assign a drive letter or mount point, probably already used by another volume" + } FileSystemMountError::MountPoint => "the mount point is invalid", FileSystemMountError::Version => "requested an incompatible version", }; @@ -315,7 +318,7 @@ fn can_fail_to_mount() { use crate::{ init, shutdown, - usage_tests::{convert_str, TestHandler}, + usage_tests::{TestHandler, convert_str}, }; let (tx, _rx) = mpsc::sync_channel(1024); diff --git a/dokan/src/file_system_handler.rs b/dokan/src/file_system_handler.rs index 84805b5..b68ecdf 100644 --- a/dokan/src/file_system_handler.rs +++ b/dokan/src/file_system_handler.rs @@ -1,8 +1,9 @@ +use dokan_sys::ACCESS_MASK; use dokan_sys::DOKAN_IO_SECURITY_CONTEXT; use widestring::U16CStr; -use winapi::{ - shared::{ntdef::NTSTATUS, ntstatus::STATUS_NOT_IMPLEMENTED}, - um::winnt::{ACCESS_MASK, PSECURITY_DESCRIPTOR}, +use windows_sys::Win32::{ + Foundation::{NTSTATUS, STATUS_NOT_IMPLEMENTED}, + Security::PSECURITY_DESCRIPTOR, }; use crate::data::{ @@ -32,7 +33,7 @@ pub type OperationResult = Result; /// [`close_file`]: Self::close_file /// [`create_file`]: Self::create_file /// [`map_win32_error_to_ntstatus`]: crate::map_win32_error_to_ntstatus -/// [`GetLastError`]: winapi::um::errhandlingapi::GetLastError +/// [`GetLastError`]: windows_sys::Win32::Foundation::GetLastError #[allow(unused_variables)] pub trait FileSystemHandler<'c, 'h: 'c>: Sync + Sized + 'h { /// Type of the context associated with an open file object. @@ -433,7 +434,7 @@ pub trait FileSystemHandler<'c, 'h: 'c>: Sync + Sized + 'h { /// /// See [`GetFileSecurity`] for more information. /// - /// [`STATUS_BUFFER_OVERFLOW`]: winapi::shared::ntstatus::STATUS_BUFFER_OVERFLOW + /// [`STATUS_BUFFER_OVERFLOW`]: windows_sys::Win32::Foundation::STATUS_BUFFER_OVERFLOW /// [`GetFileSecurity`]: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getfilesecuritya fn get_file_security( &'h self, diff --git a/dokan/src/lib.rs b/dokan/src/lib.rs index f2777fa..3f5662c 100644 --- a/dokan/src/lib.rs +++ b/dokan/src/lib.rs @@ -16,11 +16,11 @@ //! //! Please note that some of the constants from Win32 API that might be used when interacting with //! this crate are not provided directly here. However, you can easily find them in the -//! [`winapi`] crate. +//! [`windows-sys`] crate. //! //! [Dokan]: https://dokan-dev.github.io/ //! [`dokan-sys`]: https://crates.io/crates/dokan-sys -//! [`winapi`]: https://crates.io/crates/winapi +//! [`windows-sys`]: https://crates.io/crates/windows-sys mod data; mod file_system; @@ -35,13 +35,7 @@ mod usage_tests; use dokan_sys::*; use widestring::U16CStr; -use winapi::{ - shared::{ - minwindef::{DWORD, FALSE, TRUE}, - ntdef::NTSTATUS, - }, - um::{errhandlingapi::GetLastError, winnt::ACCESS_MASK}, -}; +use windows_sys::Win32::Foundation::{FALSE, GetLastError, NTSTATUS, TRUE}; pub use crate::{data::*, file_system::*, file_system_handler::*, notify::*}; @@ -159,7 +153,7 @@ pub fn map_win32_error_to_ntstatus(error: DWORD) -> NTSTATUS { #[test] fn can_map_win32_error_to_ntstatus() { - use winapi::shared::{ntstatus::STATUS_INTERNAL_ERROR, winerror::ERROR_INTERNAL_ERROR}; + use windows_sys::Win32::Foundation::{ERROR_INTERNAL_ERROR, STATUS_INTERNAL_ERROR}; assert_eq!( map_win32_error_to_ntstatus(ERROR_INTERNAL_ERROR), @@ -183,7 +177,7 @@ fn can_map_win32_error_to_ntstatus() { /// # /// # use dokan::win32_ensure; /// # use widestring::U16CString; -/// # use winapi::{shared::ntdef::NTSTATUS, um::processenv::GetCurrentDirectoryW}; +/// # use windows_sys::Win32::{Foundation::NTSTATUS, System::Environment::GetCurrentDirectoryW}; /// # /// fn get_current_directory() -> Result { /// unsafe { @@ -257,12 +251,10 @@ pub fn map_kernel_to_user_create_file_flags( #[test] fn test_map_kernel_to_user_create_file_flags() { use dokan_sys::win32::{FILE_OPEN, FILE_WRITE_THROUGH}; - use winapi::um::{ - fileapi::OPEN_EXISTING, - winbase::FILE_FLAG_WRITE_THROUGH, - winnt::{ - FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, GENERIC_ALL, GENERIC_EXECUTE, GENERIC_READ, - GENERIC_WRITE, + use windows_sys::Win32::{ + Foundation::{GENERIC_ALL, GENERIC_EXECUTE, GENERIC_READ, GENERIC_WRITE}, + Storage::FileSystem::{ + FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_FLAG_WRITE_THROUGH, OPEN_EXISTING, }, }; diff --git a/dokan/src/notify.rs b/dokan/src/notify.rs index 9a710af..4ede2fe 100644 --- a/dokan/src/notify.rs +++ b/dokan/src/notify.rs @@ -3,7 +3,7 @@ use dokan_sys::{ DokanNotifyXAttrUpdate, }; use widestring::U16CStr; -use winapi::shared::minwindef::TRUE; +use windows_sys::Win32::Foundation::TRUE; use crate::FileSystemHandle; diff --git a/dokan/src/operations.rs b/dokan/src/operations.rs index 5772dd0..5dd2c69 100644 --- a/dokan/src/operations.rs +++ b/dokan/src/operations.rs @@ -1,30 +1,29 @@ use std::slice; use dokan_sys::{ + ACCESS_MASK, DWORD, LONGLONG, LPBY_HANDLE_FILE_INFORMATION, LPCVOID, LPDWORD, LPVOID, + PSECURITY_INFORMATION, PULONG, PULONGLONG, PVOID, ULONG, +}; +use dokan_sys::{ + PDOKAN_FILE_INFO, PDOKAN_IO_SECURITY_CONTEXT, PFillFindData, PFillFindStreamData, win32::{FILE_OPEN_IF, FILE_OVERWRITE_IF, FILE_SUPERSEDE}, - PFillFindData, PFillFindStreamData, PDOKAN_FILE_INFO, PDOKAN_IO_SECURITY_CONTEXT, }; use widestring::U16CStr; -use winapi::{ - shared::{ - minwindef::{BOOL, DWORD, FILETIME, LPCVOID, LPDWORD, LPVOID, PULONG, TRUE, ULONG}, - ntdef::{LONGLONG, LPCWSTR, LPWSTR, NTSTATUS, PULONGLONG, PVOID}, - ntstatus::{STATUS_BUFFER_OVERFLOW, STATUS_OBJECT_NAME_COLLISION}, - }, - um::{ - fileapi::LPBY_HANDLE_FILE_INFORMATION, - winnt::{ACCESS_MASK, PSECURITY_DESCRIPTOR, PSECURITY_INFORMATION}, - }, +use windows_sys::Win32::{ + Foundation::{FILETIME, NTSTATUS, STATUS_BUFFER_OVERFLOW, STATUS_OBJECT_NAME_COLLISION, TRUE}, + Security::PSECURITY_DESCRIPTOR, }; +use windows_sys::core::BOOL; +use windows_sys::core::{PCWSTR, PWSTR}; use crate::{ - data::{wrap_fill_data, OperationInfo}, + data::{OperationInfo, wrap_fill_data}, file_system_handler::FileSystemHandler, - operations_helpers::{wrap_nt_result, wrap_unit, NtResult}, + operations_helpers::{NtResult, wrap_nt_result, wrap_unit}, }; pub extern "system" fn create_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, security_context: PDOKAN_IO_SECURITY_CONTEXT, desired_access: ACCESS_MASK, file_attributes: ULONG, @@ -65,7 +64,7 @@ pub extern "system" fn create_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + } pub extern "system" fn cleanup<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) { wrap_unit(|| unsafe { @@ -76,7 +75,7 @@ pub extern "system" fn cleanup<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( } pub extern "system" fn close_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) { wrap_unit(|| unsafe { @@ -88,7 +87,7 @@ pub extern "system" fn close_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + ' } pub extern "system" fn read_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, buffer: LPVOID, buffer_length: DWORD, read_length: LPDWORD, @@ -109,7 +108,7 @@ pub extern "system" fn read_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h } pub extern "system" fn write_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, buffer: LPCVOID, number_of_bytes_to_write: DWORD, number_of_bytes_written: LPDWORD, @@ -130,7 +129,7 @@ pub extern "system" fn write_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + ' } pub extern "system" fn flush_file_buffers<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { wrap_nt_result(|| unsafe { @@ -142,7 +141,7 @@ pub extern "system" fn flush_file_buffers<'c, 'h: 'c, FSH: FileSystemHandler<'c, } pub extern "system" fn get_file_information<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, buffer: LPBY_HANDLE_FILE_INFORMATION, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -158,7 +157,7 @@ pub extern "system" fn get_file_information<'c, 'h: 'c, FSH: FileSystemHandler<' } pub extern "system" fn find_files<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, fill_find_data: PFillFindData, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -172,8 +171,8 @@ pub extern "system" fn find_files<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + ' } pub extern "system" fn find_files_with_pattern<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, - search_pattern: LPCWSTR, + file_name: PCWSTR, + search_pattern: PCWSTR, fill_find_data: PFillFindData, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -193,7 +192,7 @@ pub extern "system" fn find_files_with_pattern<'c, 'h: 'c, FSH: FileSystemHandle } pub extern "system" fn set_file_attributes<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, file_attributes: DWORD, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -206,7 +205,7 @@ pub extern "system" fn set_file_attributes<'c, 'h: 'c, FSH: FileSystemHandler<'c } pub extern "system" fn set_file_time<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, creation_time: *const FILETIME, last_access_time: *const FILETIME, last_write_time: *const FILETIME, @@ -227,7 +226,7 @@ pub extern "system" fn set_file_time<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> } pub extern "system" fn delete_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { wrap_nt_result(|| unsafe { @@ -238,7 +237,7 @@ pub extern "system" fn delete_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + } pub extern "system" fn delete_directory<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { wrap_nt_result(|| unsafe { @@ -250,8 +249,8 @@ pub extern "system" fn delete_directory<'c, 'h: 'c, FSH: FileSystemHandler<'c, ' } pub extern "system" fn move_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, - new_file_name: LPCWSTR, + file_name: PCWSTR, + new_file_name: PCWSTR, replace_if_existing: BOOL, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -270,7 +269,7 @@ pub extern "system" fn move_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h } pub extern "system" fn set_end_of_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, byte_offset: LONGLONG, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -283,7 +282,7 @@ pub extern "system" fn set_end_of_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h } pub extern "system" fn set_allocation_size<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, alloc_size: LONGLONG, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -299,7 +298,7 @@ pub extern "system" fn set_allocation_size<'c, 'h: 'c, FSH: FileSystemHandler<'c // release mode. It seems that extracting the function bodies into a common function works around this bug. // See https://github.com/rust-lang/rust/issues/72212 fn lock_unlock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, byte_offset: LONGLONG, length: LONGLONG, dokan_file_info: PDOKAN_FILE_INFO, @@ -327,7 +326,7 @@ fn lock_unlock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( } pub extern "system" fn lock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, byte_offset: LONGLONG, length: LONGLONG, dokan_file_info: PDOKAN_FILE_INFO, @@ -342,7 +341,7 @@ pub extern "system" fn lock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h } pub extern "system" fn unlock_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, byte_offset: LONGLONG, length: LONGLONG, dokan_file_info: PDOKAN_FILE_INFO, @@ -381,12 +380,12 @@ pub extern "system" fn get_disk_free_space<'c, 'h: 'c, FSH: FileSystemHandler<'c } pub extern "system" fn get_volume_information<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - volume_name_buffer: LPWSTR, + volume_name_buffer: PWSTR, volume_name_size: DWORD, volume_serial_number: LPDWORD, maximum_component_length: LPDWORD, file_system_flags: LPDWORD, - file_system_name_buffer: LPWSTR, + file_system_name_buffer: PWSTR, file_system_name_size: DWORD, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { @@ -417,7 +416,7 @@ pub extern "system" fn get_volume_information<'c, 'h: 'c, FSH: FileSystemHandler } pub extern "system" fn mounted<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - mount_point: LPCWSTR, + mount_point: PCWSTR, dokan_file_info: PDOKAN_FILE_INFO, ) -> NTSTATUS { wrap_nt_result(|| unsafe { @@ -437,7 +436,7 @@ pub extern "system" fn unmounted<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h } pub extern "system" fn get_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, security_information: PSECURITY_INFORMATION, security_descriptor: PSECURITY_DESCRIPTOR, buffer_length: ULONG, @@ -468,7 +467,7 @@ pub extern "system" fn get_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, } pub extern "system" fn set_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, security_information: PSECURITY_INFORMATION, security_descriptor: PSECURITY_DESCRIPTOR, buffer_length: ULONG, @@ -489,7 +488,7 @@ pub extern "system" fn set_file_security<'c, 'h: 'c, FSH: FileSystemHandler<'c, } pub extern "system" fn find_streams<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( - file_name: LPCWSTR, + file_name: PCWSTR, fill_find_stream_data: PFillFindStreamData, find_stream_context: PVOID, dokan_file_info: PDOKAN_FILE_INFO, diff --git a/dokan/src/operations_helpers.rs b/dokan/src/operations_helpers.rs index 0f10980..d7ffa63 100644 --- a/dokan/src/operations_helpers.rs +++ b/dokan/src/operations_helpers.rs @@ -1,9 +1,6 @@ use std::panic::{self, UnwindSafe}; -use winapi::shared::{ - ntdef::NTSTATUS, - ntstatus::{STATUS_INTERNAL_ERROR, STATUS_SUCCESS}, -}; +use windows_sys::Win32::Foundation::{NTSTATUS, STATUS_INTERNAL_ERROR, STATUS_SUCCESS}; pub type NtResult = Result<(), NTSTATUS>; diff --git a/dokan/src/to_file_time.rs b/dokan/src/to_file_time.rs index 10bc3bb..63d9a7c 100644 --- a/dokan/src/to_file_time.rs +++ b/dokan/src/to_file_time.rs @@ -1,6 +1,6 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use winapi::shared::minwindef::FILETIME; +use windows_sys::Win32::Foundation::FILETIME; pub const FILETIME_OFFSET: Duration = Duration::from_secs(11644473600); diff --git a/dokan/src/usage_tests.rs b/dokan/src/usage_tests.rs index 4af41c5..2e3e5e2 100644 --- a/dokan/src/usage_tests.rs +++ b/dokan/src/usage_tests.rs @@ -1,5 +1,3 @@ -extern crate lazy_static; -extern crate parking_lot; extern crate regex; use std::{ @@ -9,43 +7,62 @@ use std::{ os::windows::prelude::{AsRawHandle, FromRawHandle, OwnedHandle}, pin::Pin, process, ptr, + sync::LazyLock, sync::mpsc::{self, Receiver, SyncSender}, thread, time::{Duration, UNIX_EPOCH}, }; +use dokan_sys::LPVOID; use dokan_sys::win32::{ FILE_NON_DIRECTORY_FILE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, FILE_WRITE_THROUGH, WIN32_FIND_STREAM_DATA, }; -use parking_lot::Mutex; +use std::sync::Mutex; use widestring::{U16CStr, U16CString}; -use winapi::{ - shared::{ - minwindef::{BOOL, FALSE, HLOCAL, LPCVOID, LPVOID, MAX_PATH, TRUE}, - ntdef::{HANDLE, NTSTATUS, NULL}, - ntstatus::{STATUS_ACCESS_DENIED, STATUS_NOT_IMPLEMENTED, STATUS_SUCCESS}, - sddl::ConvertSidToStringSidW, - winerror::{ - ERROR_HANDLE_EOF, ERROR_INSUFFICIENT_BUFFER, ERROR_INTERNAL_ERROR, ERROR_IO_PENDING, - ERROR_NO_MORE_FILES, - }, +use windows_sys::Win32::{ + Foundation::{ + CloseHandle, ERROR_HANDLE_EOF, ERROR_INSUFFICIENT_BUFFER, ERROR_INTERNAL_ERROR, + ERROR_IO_PENDING, ERROR_NO_MORE_FILES, FALSE, GENERIC_ALL, GENERIC_READ, GetLastError, + HANDLE, INVALID_HANDLE_VALUE, LocalFree, MAX_PATH, NTSTATUS, STATUS_ACCESS_DENIED, + STATUS_NOT_IMPLEMENTED, STATUS_SUCCESS, TRUE, + }, + Security::{ + Authorization::ConvertSidToStringSidW, EqualSid, GetFileSecurityW, + GetSecurityDescriptorOwner, GetTokenInformation, InitializeSecurityDescriptor, + MakeSelfRelativeSD, OWNER_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR, + SetFileSecurityW, SetSecurityDescriptorOwner, TOKEN_QUERY, TOKEN_USER, TokenUser, }, - um::{ - errhandlingapi::GetLastError, - fileapi::*, - handleapi::{CloseHandle, INVALID_HANDLE_VALUE}, - ioapiset::GetOverlappedResult, - minwinbase::OVERLAPPED, - processthreadsapi::{GetCurrentProcess, OpenProcessToken}, - securitybaseapi::*, - synchapi::CreateEventW, - winbase::*, - winnt::*, + Storage::FileSystem::{ + CreateFileW, DeleteFileW, FILE_ACTION_ADDED, FILE_ACTION_MODIFIED, FILE_ACTION_REMOVED, + FILE_ACTION_RENAMED_NEW_NAME, FILE_ACTION_RENAMED_OLD_NAME, FILE_ALL_ACCESS, + FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_BEGIN, + FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OVERLAPPED, FILE_FLAG_WRITE_THROUGH, + FILE_NOTIFY_CHANGE_ATTRIBUTES, FILE_NOTIFY_CHANGE_FILE_NAME, FILE_NOTIFY_INFORMATION, + FILE_SHARE_READ, FindClose, FindFirstFileW, FindFirstStreamW, FindNextFileW, + FindNextStreamW, FindStreamInfoStandard, FlushFileBuffers, GetDiskFreeSpaceExW, + GetFileInformationByHandle, GetVolumeInformationW, LockFile, MOVEFILE_REPLACE_EXISTING, + MoveFileExW, OPEN_EXISTING, ReadDirectoryChangesW, ReadFile, RemoveDirectoryW, + SetEndOfFile, SetFileAttributesW, SetFilePointer, SetFileTime, SetFileValidData, + UnlockFile, WriteFile, + }, + System::{ + IO::{GetOverlappedResult, OVERLAPPED}, + SystemServices::{ + FILE_CASE_PRESERVED_NAMES, FILE_CASE_SENSITIVE_SEARCH, FILE_NAMED_STREAMS, + FILE_UNICODE_ON_DISK, SECURITY_DESCRIPTOR_REVISION, + }, + Threading::{CreateEventW, GetCurrentProcess, OpenProcessToken}, }, }; +use windows_sys::core::BOOL; + +#[allow(non_camel_case_types)] +type SECURITY_INFORMATION = u32; use crate::{ + FileSystemHandle, FileSystemHandler, FileSystemMounter, IO_SECURITY_CONTEXT, MountFlags, + MountOptions, data::{ CreateFileInfo, DiskSpaceInfo, FileInfo, FileTimeOperation, FillDataResult, FindData, FindStreamData, OperationInfo, VolumeInfo, @@ -55,8 +72,7 @@ use crate::{ operations_helpers::NtResult, shutdown, to_file_time::ToFileTime, - unmount, FileSystemHandle, FileSystemHandler, FileSystemMounter, MountFlags, MountOptions, - IO_SECURITY_CONTEXT, + unmount, }; pub fn convert_str(s: impl AsRef) -> U16CString { @@ -183,7 +199,7 @@ fn get_descriptor_owner(desc: PSECURITY_DESCRIPTOR) -> (U16CString, BOOL) { let mut ps = ptr::null_mut(); assert_eq_win32!(ConvertSidToStringSidW(psid, &mut ps), TRUE); let sid = U16CStr::from_ptr_str(ps).to_owned(); - assert_eq_win32!(LocalFree(ps as HLOCAL), NULL); + assert_eq_win32!(LocalFree(ps as _), ptr::null_mut()); (sid, owner_defaulted) } } @@ -228,7 +244,7 @@ fn get_current_user_info() -> Pin> { fn create_test_descriptor() -> Vec { unsafe { let mut user_info_buffer = get_current_user_info(); - let user_info = &*(user_info_buffer.as_mut_ptr() as PTOKEN_USER); + let user_info = &*(user_info_buffer.as_mut_ptr() as *const TOKEN_USER); let mut abs_desc = mem::zeroed::(); let abs_desc_ptr = &mut abs_desc as *mut _ as PSECURITY_DESCRIPTOR; assert_eq_win32!( @@ -842,9 +858,7 @@ impl<'a, 'b: 'a> FileSystemHandler<'a, 'b> for TestHandler { } } -lazy_static::lazy_static! { - static ref TEST_DRIVE_LOCK: Mutex<()> = Mutex::new(()); -} +static TEST_DRIVE_LOCK: LazyLock> = LazyLock::new(|| Mutex::new(())); pub struct TestDriveContext<'a> { rx_instance: &'a Receiver, @@ -882,7 +896,7 @@ pub fn test_flags() -> MountFlags { #[allow(unused_must_use)] pub fn with_test_drive(scope: Scope) { - let _guard = TEST_DRIVE_LOCK.lock(); + let _guard = TEST_DRIVE_LOCK.lock().unwrap(); init(); @@ -951,8 +965,8 @@ fn supports_panic_in_handler() { fn can_retrieve_volume_information() { with_test_drive(|_| unsafe { let path = convert_str("Z:\\"); - let mut volume_name = [0; MAX_PATH + 1]; - let mut fs_name = [0; MAX_PATH + 1]; + let mut volume_name = [0; MAX_PATH as usize + 1]; + let mut fs_name = [0; MAX_PATH as usize + 1]; let mut serial_number = 0; let mut max_component_length = 0; let mut fs_flags = 0; @@ -999,9 +1013,9 @@ fn can_retrieve_disk_space() { assert_eq_win32!( GetDiskFreeSpaceExW( path.as_ptr(), - &mut free_bytes_available as *mut _ as PULARGE_INTEGER, - &mut total_number_of_bytes as *mut _ as PULARGE_INTEGER, - &mut total_number_of_free_bytes as *mut _ as PULARGE_INTEGER, + &mut free_bytes_available, + &mut total_number_of_bytes, + &mut total_number_of_free_bytes, ), TRUE ); @@ -1066,7 +1080,7 @@ fn can_read_from_and_write_to_file() { assert_eq_win32!( ReadFile( hf, - buf.as_mut_ptr() as LPVOID, + buf.as_mut_ptr(), buf.len() as u32, &mut len, ptr::null_mut() @@ -1080,13 +1094,7 @@ fn can_read_from_and_write_to_file() { assert_eq!(context.signal(), HandlerSignal::ReadFile(0, buf.len())); let mut bytes_written = 0; assert_eq_win32!( - WriteFile( - hf, - buf.as_ptr() as LPCVOID, - len, - &mut bytes_written, - ptr::null_mut() - ), + WriteFile(hf, buf.as_ptr(), len, &mut bytes_written, ptr::null_mut()), TRUE ); assert_eq!(bytes_written, len); @@ -1432,7 +1440,7 @@ fn can_find_streams() { 0, ); assert_ne_win32!(hf, INVALID_HANDLE_VALUE); - assert_eq!(data.StreamSize.QuadPart(), &42); + assert_eq!(data.StreamSize, 42); assert_eq!( U16CStr::from_slice_truncate(&data.cStreamName).unwrap(), convert_str("::$DATA") @@ -1566,7 +1574,8 @@ impl DirectoryChangeIterator { hd: OwnedHandle::from_raw_handle(hd), buf: Pin::new(vec![ 0; - mem::size_of::() + MAX_PATH + mem::size_of::() + + MAX_PATH as usize ]), offset: 0, he: OwnedHandle::from_raw_handle(he), From 8a309daaa1df4be9d008e7290b03b28f4f9cb0ca Mon Sep 17 00:00:00 2001 From: Jon-Luke Biddle Date: Tue, 31 Mar 2026 19:23:47 -0600 Subject: [PATCH 4/8] ci build --- .github/workflows/build.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..2507171 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,23 @@ +name: Build + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - uses: dtolnay/rust-toolchain@stable + + - name: Build + run: cargo check --examples --tests + + - name: Test + run: cargo test From 5040782da4c6e9a49586b6e343a1a4682157cdc0 Mon Sep 17 00:00:00 2001 From: Jon-Luke Biddle Date: Tue, 31 Mar 2026 19:29:17 -0600 Subject: [PATCH 5/8] fix mutex poison --- dokan/src/usage_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dokan/src/usage_tests.rs b/dokan/src/usage_tests.rs index 2e3e5e2..e8b8c68 100644 --- a/dokan/src/usage_tests.rs +++ b/dokan/src/usage_tests.rs @@ -896,7 +896,7 @@ pub fn test_flags() -> MountFlags { #[allow(unused_must_use)] pub fn with_test_drive(scope: Scope) { - let _guard = TEST_DRIVE_LOCK.lock().unwrap(); + let _guard = TEST_DRIVE_LOCK.lock().unwrap_or_else(|e| e.into_inner()); init(); From 354bf6aeea485022ef52383ce479d724c902fadd Mon Sep 17 00:00:00 2001 From: Jon-Luke Biddle Date: Tue, 31 Mar 2026 19:29:40 -0600 Subject: [PATCH 6/8] install dokan driver through winget --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2507171..21011d0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,9 @@ jobs: with: submodules: recursive + - name: Install Dokan + run: winget install -e --id dokan-dev.Dokany --accept-source-agreements --accept-package-agreements + - uses: dtolnay/rust-toolchain@stable - name: Build From a50b74ac67ec4ae87108c7986f3bdd2971163e88 Mon Sep 17 00:00:00 2001 From: Jon-Luke Biddle Date: Tue, 31 Mar 2026 19:37:37 -0600 Subject: [PATCH 7/8] fix undefined behavior leading to panic --- dokan/src/data/operation_info.rs | 13 ++++++++++++- dokan/src/operations.rs | 8 ++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/dokan/src/data/operation_info.rs b/dokan/src/data/operation_info.rs index 4d86b82..714b845 100644 --- a/dokan/src/data/operation_info.rs +++ b/dokan/src/data/operation_info.rs @@ -41,8 +41,19 @@ impl<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h> OperationInfo<'c, 'h, FSH> unsafe { &*(self.mount_options().GlobalContext as *const _) } } + pub fn try_context(&self) -> Option<&'c FSH::Context> { + let ptr = self.file_info().Context as *const FSH::Context; + if ptr.is_null() { + None + } else { + unsafe { Some(&*ptr) } + } + } + pub fn context(&self) -> &'c FSH::Context { - unsafe { &*(self.file_info().Context as *const _) } + self.try_context().expect( + "file context is null — create_file may have failed or context was already dropped", + ) } pub fn drop_context(&mut self) { diff --git a/dokan/src/operations.rs b/dokan/src/operations.rs index 5dd2c69..700f382 100644 --- a/dokan/src/operations.rs +++ b/dokan/src/operations.rs @@ -70,7 +70,9 @@ pub extern "system" fn cleanup<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + 'h>( wrap_unit(|| unsafe { let file_name = U16CStr::from_ptr_str(file_name); let info = OperationInfo::<'c, 'h, FSH>::new(dokan_file_info); - info.handler().cleanup(file_name, &info, info.context()); + if let Some(context) = info.try_context() { + info.handler().cleanup(file_name, &info, context); + } }); } @@ -81,7 +83,9 @@ pub extern "system" fn close_file<'c, 'h: 'c, FSH: FileSystemHandler<'c, 'h> + ' wrap_unit(|| unsafe { let file_name = U16CStr::from_ptr_str(file_name); let mut info = OperationInfo::<'c, 'h, FSH>::new(dokan_file_info); - info.handler().close_file(file_name, &info, info.context()); + if let Some(context) = info.try_context() { + info.handler().close_file(file_name, &info, context); + } info.drop_context(); }); } From cac725c6636cea8860ea2b05454af7421f13cff8 Mon Sep 17 00:00:00 2001 From: Jon-Luke Biddle Date: Tue, 31 Mar 2026 19:44:02 -0600 Subject: [PATCH 8/8] handle tests on windows server --- dokan/src/usage_tests.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/dokan/src/usage_tests.rs b/dokan/src/usage_tests.rs index e8b8c68..f6abc9b 100644 --- a/dokan/src/usage_tests.rs +++ b/dokan/src/usage_tests.rs @@ -872,6 +872,19 @@ impl TestDriveContext<'_> { self.rx_signal.recv().unwrap() } + /// Receives signals until one matches the predicate, discarding others. + /// This is useful when Windows may inject additional calls (e.g. extra + /// `GetFileSecurity` queries with different `security_information` values) + /// that aren't relevant to the test assertion. + pub fn signal_matching(&self, pred: impl Fn(&HandlerSignal) -> bool) -> HandlerSignal { + loop { + let sig = self.signal(); + if pred(&sig) { + return sig; + } + } + } + pub fn instance(&self) -> FileSystemHandle { *self .instance @@ -1362,7 +1375,9 @@ fn can_get_file_security() { ); assert_eq!(GetLastError(), ERROR_INSUFFICIENT_BUFFER); assert_eq!( - context.signal(), + context.signal_matching( + |s| matches!(s, HandlerSignal::GetFileSecurity(si, _) if *si == OWNER_SECURITY_INFORMATION) + ), HandlerSignal::GetFileSecurity(OWNER_SECURITY_INFORMATION, 0) ); let mut desc = vec![0u8; desc_len as usize]; @@ -1378,7 +1393,9 @@ fn can_get_file_security() { ); assert_eq!(desc.len(), desc_len as usize); assert_eq!( - context.signal(), + context.signal_matching( + |s| matches!(s, HandlerSignal::GetFileSecurity(si, _) if *si == OWNER_SECURITY_INFORMATION) + ), HandlerSignal::GetFileSecurity(OWNER_SECURITY_INFORMATION, desc_len) ); assert_eq!(desc, expected_desc);