diff --git a/ForTun/ForTun.inf b/ForTun/ForTun.inf
index 9aa103c..ecfc32a 100644
--- a/ForTun/ForTun.inf
+++ b/ForTun/ForTun.inf
@@ -8,7 +8,6 @@ Class=Net
ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318}
Provider=%ManufacturerName%
CatalogFile=ForTun.cat
-;DriverVer=0.0.1
PnpLockdown=1
[DestinationDirs]
diff --git a/ForTun/ForTun.vcxproj b/ForTun/ForTun.vcxproj
index a458c00..40697e7 100644
--- a/ForTun/ForTun.vcxproj
+++ b/ForTun/ForTun.vcxproj
@@ -19,6 +19,7 @@
+
@@ -44,7 +45,9 @@
-
+
+ *
+
{4EF57910-A75E-48FB-89A0-B4005D9F609B}
@@ -113,6 +116,7 @@
DbgengKernelDebugger
+ true
DbgengKernelDebugger
@@ -131,6 +135,12 @@
sha256
+
+ true
+
+
+ *
+
@@ -142,6 +152,9 @@
sha256
+
+ $(FOR_TUN_VERSION_MAJOR).$(FOR_TUN_VERSION_MINOR).$(FOR_TUN_VERSION_PATCH)
+
diff --git a/ForTun/ForTun.vcxproj.filters b/ForTun/ForTun.vcxproj.filters
index f66c6c3..ba077f4 100644
--- a/ForTun/ForTun.vcxproj.filters
+++ b/ForTun/ForTun.vcxproj.filters
@@ -20,6 +20,7 @@
+
diff --git a/ForTun/Queue.c b/ForTun/Queue.c
index 238962a..52a1e76 100644
--- a/ForTun/Queue.c
+++ b/ForTun/Queue.c
@@ -66,6 +66,7 @@ Return Value:
//
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
&queueConfig,
+ //WdfIoQueueDispatchParallel
WdfIoQueueDispatchSequential
);
@@ -94,10 +95,7 @@ Return Value:
TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "create read queue failed %!STATUS!", status);
return status;
}
- //status = WdfDeviceConfigureRequestDispatching(Device, readQueue, WdfRequestTypeRead);
- //if (!NT_SUCCESS(status)) {
- // goto done;
- //}
+
WDFQUEUE writeQueue;
WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);
status = WdfIoQueueCreate(Device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &writeQueue);
@@ -106,22 +104,10 @@ Return Value:
TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "create write queue failed %!STATUS!", status);
return status;
}
- //status = WdfDeviceConfigureRequestDispatching(Device, writeQueue, WdfRequestTypeWrite);
+
PDEVICE_CONTEXT device_context = DeviceGetContext(Device);
- /*
- WDF_OBJECT_ATTRIBUTES attr;
- WDF_OBJECT_ATTRIBUTES_INIT(&attr);
- attr.ParentObject = Device;
- WDFMEMORY BufferHandler;
- status = WdfMemoryCreate(&attr, NonPagedPool, 'FTun', READ_POOL_SIZE, &BufferHandler, &device_context->PReadBuffer);
- if (!NT_SUCCESS(status)) {
- TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "create ReadBuffer failed %!STATUS!", status);
- goto done;
- }
- RtlZeroMemory(device_context->PReadBuffer, READ_POOL_SIZE);
- RingBufferInitialize(&device_context->ReadRingBuffer, device_context->PReadBuffer, READ_POOL_SIZE);
- */
+
PPOOL_QUEUE poolQueue;
status = PoolQueueCreate(&poolQueue);
if (!NT_SUCCESS(status)) {
@@ -277,6 +263,7 @@ ForTunEvtIoRead(
IN size_t Length
)
{
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "Io Read has trigger");
UNREFERENCED_PARAMETER(Length);
NTSTATUS status;
@@ -294,6 +281,7 @@ ForTunEvtIoRead(
PPOOL_QUEUE_ITEM poolQueueItem = PoolQueueGetFromQueue(deviceContext->PoolQueue);
if (poolQueueItem) {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "Pool Has Item");
RtlCopyMemory(readBuffer, &poolQueueItem->Data, poolQueueItem->DataSize);
size_t dataSize = poolQueueItem->DataSize;
PoolQueuePutToPool(deviceContext->PoolQueue, poolQueueItem);
@@ -312,6 +300,7 @@ ForTunEvtIoRead(
}*/
else {
status = WdfRequestForwardToIoQueue(Request, deviceContext->PendingReadQueue);
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "Append Request To Queue");
WdfSpinLockRelease(deviceContext->readLock);
if (!NT_SUCCESS(status)) {
goto logErr;
@@ -332,6 +321,7 @@ ForTunEvtIoWrite(
)
{
UNREFERENCED_PARAMETER(Length);
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "Write item");
PDEVICE_CONTEXT context = DeviceGetContext(WdfIoQueueGetDevice(Queue));
@@ -345,6 +335,7 @@ ForTunEvtIoWrite(
//this should always be success
ForTunAdapterNotifyRx(context->Adapter);
+
return;
logErr:
diff --git a/ForTun/TXQueue.c b/ForTun/TXQueue.c
index a53e45e..3c74644 100644
--- a/ForTun/TXQueue.c
+++ b/ForTun/TXQueue.c
@@ -47,13 +47,14 @@ ForTunTxQueueSetNotificationEnabled(_In_ NETPACKETQUEUE PacketQueue, _In_ BOOLEA
VOID
ForTunTxQueueAdvance(_In_ NETPACKETQUEUE PacketQueue)
{
- TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_ADAPTER, "%!FUNC! Entry");
+ TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_ADAPTER, "%!FUNC! Entry");
PTXQUEUE_CONTEXT context = TxQueueGetContext(PacketQueue);
PDEVICE_CONTEXT deviceContext = context->AdapterContext->DeviceContext;
NET_RING_COLLECTION const* ringCollection = context->RingCollection;
NET_RING_PACKET_ITERATOR pi = NetRingGetAllPackets(ringCollection);
+ SIZE_T length = 0;
NTSTATUS status = STATUS_SUCCESS;
// in
@@ -63,6 +64,7 @@ ForTunTxQueueAdvance(_In_ NETPACKETQUEUE PacketQueue)
// Process
NET_RING_FRAGMENT_ITERATOR fi = NetPacketIteratorGetFragments(&pi);
WDFREQUEST request;
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_ADAPTER, "TXQueue begin to acquire readLock");
WdfSpinLockAcquire(deviceContext->readLock);
status = WdfIoQueueRetrieveNextRequest(deviceContext->PendingReadQueue, &request);
UCHAR* buffer = NULL;
@@ -89,11 +91,11 @@ ForTunTxQueueAdvance(_In_ NETPACKETQUEUE PacketQueue)
}
if (!NT_SUCCESS(status)) {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_ADAPTER, "TXQueue begin to release readLock for %!STATUS!", status);
WdfSpinLockRelease(deviceContext->readLock);
NetFragmentIteratorSet(&fi);
}
else {
- SIZE_T length = 0;
while (NetFragmentIteratorHasAny(&fi)) {
NET_FRAGMENT* fragment = NetFragmentIteratorGetFragment(&fi);
BYTE* netBuf = (BYTE *)NetExtensionGetFragmentVirtualAddressOffset(fragment, &context->VirtualAddressExtension, NetFragmentIteratorGetIndex(&fi));
@@ -108,12 +110,15 @@ ForTunTxQueueAdvance(_In_ NETPACKETQUEUE PacketQueue)
NetFragmentIteratorAdvance(&fi);
}
if (buffer) {
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_ADAPTER, "wdf request complete length: %I64d", length);
WdfRequestCompleteWithInformation(request, status, length);
}
else if(poolQueueItem){
poolQueueItem->DataSize = length;
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_ADAPTER, "push pool queue length: %I64d", length);
PoolQueuePutToQueue(deviceContext->PoolQueue, poolQueueItem);
}
+ TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_ADAPTER, "TXQueue begin to release readLock");
WdfSpinLockRelease(deviceContext->readLock);
}
diff --git a/ForTunCli/.gitignore b/ForTunCli/.gitignore
index 9b567b4..0c2a611 100644
--- a/ForTunCli/.gitignore
+++ b/ForTunCli/.gitignore
@@ -1,5 +1,4 @@
/target
.idea
/win11
-/examples
driver
\ No newline at end of file
diff --git a/ForTunCli/Cargo.lock b/ForTunCli/Cargo.lock
index c5bd110..b715fee 100644
--- a/ForTunCli/Cargo.lock
+++ b/ForTunCli/Cargo.lock
@@ -35,6 +35,12 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+[[package]]
+name = "bytes"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+
[[package]]
name = "cfg-if"
version = "1.0.0"
@@ -71,6 +77,8 @@ dependencies = [
"scopeguard",
"tokio",
"tracing",
+ "tracing-subscriber",
+ "tracing-test",
"version-compare",
"windows",
]
@@ -90,6 +98,12 @@ dependencies = [
"unicode-width",
]
+[[package]]
+name = "hermit-abi"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
+
[[package]]
name = "hwaddr"
version = "0.1.7"
@@ -109,6 +123,12 @@ dependencies = [
"winapi-build",
]
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
[[package]]
name = "libc"
version = "0.2.139"
@@ -126,12 +146,59 @@ dependencies = [
"winapi 0.2.8",
]
+[[package]]
+name = "lock_api"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+
+[[package]]
+name = "matchers"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
+dependencies = [
+ "regex-automata",
+]
+
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+[[package]]
+name = "mio"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "nu-ansi-term"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
+dependencies = [
+ "overload",
+ "winapi 0.3.9",
+]
+
[[package]]
name = "num-bigint"
version = "0.4.3"
@@ -162,12 +229,28 @@ dependencies = [
"autocfg",
]
+[[package]]
+name = "num_cpus"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
[[package]]
name = "once_cell"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
+[[package]]
+name = "overload"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
+
[[package]]
name = "packet"
version = "0.1.4"
@@ -180,6 +263,29 @@ dependencies = [
"thiserror",
]
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-targets",
+]
+
[[package]]
name = "phf"
version = "0.8.0"
@@ -268,6 +374,15 @@ dependencies = [
"rand_core 0.3.1",
]
+[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags",
+]
+
[[package]]
name = "regex"
version = "1.7.1"
@@ -279,6 +394,15 @@ dependencies = [
"regex-syntax",
]
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+dependencies = [
+ "regex-syntax",
+]
+
[[package]]
name = "regex-syntax"
version = "0.6.28"
@@ -300,6 +424,24 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+[[package]]
+name = "sharded-slab"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "siphasher"
version = "0.3.10"
@@ -316,6 +458,22 @@ dependencies = [
"tempdir",
]
+[[package]]
+name = "smallvec"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
+
+[[package]]
+name = "socket2"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
+dependencies = [
+ "libc",
+ "winapi 0.3.9",
+]
+
[[package]]
name = "syn"
version = "1.0.107"
@@ -357,6 +515,16 @@ dependencies = [
"syn",
]
+[[package]]
+name = "thread_local"
+version = "1.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
[[package]]
name = "tokio"
version = "1.25.0"
@@ -364,8 +532,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
dependencies = [
"autocfg",
+ "bytes",
+ "libc",
+ "memchr",
+ "mio",
+ "num_cpus",
+ "parking_lot",
"pin-project-lite",
- "windows-sys",
+ "signal-hook-registry",
+ "socket2",
+ "tokio-macros",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
]
[[package]]
@@ -398,6 +586,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
dependencies = [
"once_cell",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
+dependencies = [
+ "lazy_static",
+ "log",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
+dependencies = [
+ "matchers",
+ "nu-ansi-term",
+ "once_cell",
+ "regex",
+ "sharded-slab",
+ "smallvec",
+ "thread_local",
+ "tracing",
+ "tracing-core",
+ "tracing-log",
+]
+
+[[package]]
+name = "tracing-test"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a2c0ff408fe918a94c428a3f2ad04e4afd5c95bbc08fcf868eff750c15728a4"
+dependencies = [
+ "lazy_static",
+ "tracing-core",
+ "tracing-subscriber",
+ "tracing-test-macro",
+]
+
+[[package]]
+name = "tracing-test-macro"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "258bc1c4f8e2e73a977812ab339d503e6feeb92700f6d07a6de4d321522d5c08"
+dependencies = [
+ "lazy_static",
+ "quote",
+ "syn",
]
[[package]]
@@ -412,12 +653,24 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+[[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
[[package]]
name = "version-compare"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
[[package]]
name = "winapi"
version = "0.2.8"
@@ -454,9 +707,19 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
-version = "0.48.0"
+version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
+checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9"
+dependencies = [
+ "windows-core",
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.51.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets",
]
@@ -476,19 +739,28 @@ dependencies = [
"windows_x86_64_msvc 0.42.1",
]
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets",
+]
+
[[package]]
name = "windows-targets"
-version = "0.48.1"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
- "windows_aarch64_gnullvm 0.48.0",
- "windows_aarch64_msvc 0.48.0",
- "windows_i686_gnu 0.48.0",
- "windows_i686_msvc 0.48.0",
- "windows_x86_64_gnu 0.48.0",
- "windows_x86_64_gnullvm 0.48.0",
- "windows_x86_64_msvc 0.48.0",
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
]
[[package]]
@@ -499,9 +771,9 @@ checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.48.0"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
@@ -511,9 +783,9 @@ checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.48.0"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
@@ -523,9 +795,9 @@ checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]]
name = "windows_i686_gnu"
-version = "0.48.0"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
@@ -535,9 +807,9 @@ checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]]
name = "windows_i686_msvc"
-version = "0.48.0"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
@@ -547,9 +819,9 @@ checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.48.0"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -559,9 +831,9 @@ checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.48.0"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
@@ -571,6 +843,6 @@ checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.48.0"
+version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
diff --git a/ForTunCli/Cargo.toml b/ForTunCli/Cargo.toml
index 3c07fda..c7af015 100644
--- a/ForTunCli/Cargo.toml
+++ b/ForTunCli/Cargo.toml
@@ -11,7 +11,7 @@ edition = "2021"
[dependencies]
-windows = { version = "0.48.0", features = ["Win32_System_IO", "Win32_Storage_FileSystem", "Win32_Devices_Enumeration_Pnp", "Win32_System_Threading" ,"Win32_Devices_Properties", "Win32_Foundation", "Win32_Security", "Win32_Devices_DeviceAndDriverInstallation", "Win32_System_Registry", "Win32_NetworkManagement_IpHelper"] }
+windows = { version = "0.51.1", features = ["Win32_System_IO", "Win32_Storage_FileSystem", "Win32_Devices_Enumeration_Pnp", "Win32_System_Threading" ,"Win32_Devices_Properties", "Win32_Foundation", "Win32_Security", "Win32_Devices_DeviceAndDriverInstallation", "Win32_System_Registry", "Win32_NetworkManagement_IpHelper"] }
anyhow = "1"
scopeguard = "1"
local-encoding = "*"
@@ -20,5 +20,7 @@ packet = "0.1"
cidr-utils = "0.5"
tracing = "0.1"
version-compare = "0.1.1"
-
-#tracing-subscriber = "0.3"
\ No newline at end of file
+[dev-dependencies]
+tracing-subscriber = "0.3"
+tracing-test = "0.2"
+tokio = {version = "1", features = ["full"]}
\ No newline at end of file
diff --git a/ForTunCli/examples/simple.rs b/ForTunCli/examples/simple.rs
new file mode 100644
index 0000000..01d3f7f
--- /dev/null
+++ b/ForTunCli/examples/simple.rs
@@ -0,0 +1,68 @@
+use std::time::Duration;
+use tokio::net::UdpSocket;
+use windows::core::GUID;
+use fortun_cli::{create_async_tun, net_config};
+
+
+// Run with Administrator Permission
+#[tokio::main]
+async fn main() -> anyhow::Result<()> {
+ tracing_subscriber::fmt().init();
+
+ let guid = GUID::from("15D95261-C48F-428E-853F-FF080ACA23FA");
+ //let inf_path = std::env::current_dir().unwrap().join("driver\\fortun\\fortun.inf");
+ let inf_path = "C:/DriverTest/Drivers/ForTun.inf";
+
+ let (mut read,mut write, device) = create_async_tun(&guid, "ForTunTest", inf_path).unwrap();
+ net_config(device.instance_id.clone(), "10.0.0.2", "255.255.0.0",1428).unwrap();
+
+ let mut read_buf:Vec = vec![0;2048];
+
+ let task = tokio::spawn(async move {
+ while let Ok(size) = read.read(read_buf.as_mut_slice()) {
+ println!("receive: {size}");
+ tokio::time::sleep(Duration::from_secs(1)).await;
+ }
+ });
+
+
+ /*
+ let addr = "10.0.0.2:8080";
+
+ let socket = UdpSocket::bind(&addr).await?;
+ println!("Listening on: {}", socket.local_addr()?);
+
+ let mut to_send = None;
+ let mut buf = vec![0;1024];
+ tokio::spawn(async move {
+ loop {
+ if let Some((size, peer)) = to_send {
+ let amt = socket.send_to(b"pong", &peer).await.unwrap();
+ println!("Echoed {}/{} bytes to {}", amt, size, peer);
+ }
+ to_send = Some(socket.recv_from(&mut buf).await.unwrap());
+ }
+ });
+ tokio::time::sleep(Duration::from_secs(1)).await;
+
+
+ let socket = UdpSocket::bind("10.0.0.2:8089").await?;
+ const MAX_DATAGRAM_SIZE: usize = 1204;
+ socket.connect(addr).await?;
+ let data = b"ping";
+ socket.send(data).await?;
+ let mut data = vec![0u8; MAX_DATAGRAM_SIZE];
+
+ let len = socket.recv(&mut data).await?;
+ println!(
+ "Received {} bytes:\n{}",
+ len,
+ String::from_utf8_lossy(&data[..len])
+ );
+ tokio::time::sleep(Duration::from_secs(2)).await;
+*/
+ let _ = task.await;
+
+
+ Ok(())
+}
diff --git a/ForTunCli/src/device_ops.rs b/ForTunCli/src/device_ops.rs
index f84eb52..d57c1ef 100644
--- a/ForTunCli/src/device_ops.rs
+++ b/ForTunCli/src/device_ops.rs
@@ -9,17 +9,14 @@ use cidr_utils::cidr::IpCidr;
use std::thread::sleep;
use std::time::Duration;
use version_compare::Version;
-use windows::core::{wcslen, GUID, HRESULT, HSTRING, PCWSTR, PWSTR};
-use windows::w;
+use windows::core::{wcslen, GUID, HRESULT, HSTRING, PCWSTR, PWSTR, w};
use windows::Win32::Devices::DeviceAndDriverInstallation::{CM_Get_DevNode_PropertyW, CM_Get_Device_ID_ListW, CM_Get_Device_ID_List_SizeW, CM_Get_Device_Interface_ListW, CM_Get_Device_Interface_List_SizeW, CM_Locate_DevNodeW, SetupCopyOEMInfW, SetupDiSetClassInstallParamsW, CM_GETIDLIST_FILTER_CLASS, CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES, CM_LOCATE_DEVINST_NORMAL, CM_LOCATE_DEVNODE_PHANTOM, CR_NO_SUCH_DEVNODE, CR_SUCCESS, DIF_REMOVE, DI_REMOVEDEVICE_GLOBAL, GUID_DEVCLASS_NET, HDEVINFO, SPOST_PATH, SP_CLASSINSTALL_HEADER, SP_COPY_NEWER, SP_DEVINFO_DATA, SP_REMOVEDEVICE_PARAMS};
use windows::Win32::Devices::Enumeration::Pnp::{
SWDeviceCapabilitiesDriverRequired, SWDeviceCapabilitiesSilentInstall, SwDeviceClose,
SwDeviceCreate, HSWDEVICE, SW_DEVICE_CREATE_INFO,
};
-use windows::Win32::Devices::Properties::{DEVPKEY_Device_ClassGuid, DEVPKEY_Device_FriendlyName, DEVPKEY_Device_HardwareIds, DEVPROPCOMPKEY, DEVPROPERTY, DEVPROP_STORE_SYSTEM, DEVPROP_TYPE_GUID, DEVPROP_TYPE_STRING, DEVPROPTYPE, DEVPROPKEY, DEVPKEY_Device_DriverVersion};
-use windows::Win32::Foundation::{
- CloseHandle, GetLastError, ERROR_NO_MORE_ITEMS, HANDLE, NO_ERROR, WAIT_OBJECT_0,
-};
+use windows::Win32::Devices::Properties::{DEVPKEY_Device_ClassGuid, DEVPKEY_Device_FriendlyName, DEVPKEY_Device_HardwareIds, DEVPROPCOMPKEY, DEVPROPERTY, DEVPROP_STORE_SYSTEM, DEVPROP_TYPE_GUID, DEVPROP_TYPE_STRING, DEVPROPTYPE, DEVPROPKEY, DEVPKEY_Device_DriverVersion, DEVPROP_TYPE_STRING_LIST};
+use windows::Win32::Foundation::{CloseHandle, GetLastError, HANDLE, WAIT_OBJECT_0, ERROR_IO_PENDING};
use windows::Win32::NetworkManagement::IpHelper::GetAdapterIndex;
use windows::Win32::Storage::FileSystem::{CreateFileW, FILE_ATTRIBUTE_SYSTEM, FILE_FLAG_OVERLAPPED, FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_SHARE_NONE, OPEN_EXISTING};
use windows::Win32::System::Registry::{
@@ -38,11 +35,6 @@ pub const FOR_TUN_IOCTL_OPEN_ADAPTER: u32 = ctl_code!(0x00000022, 0x0801, 0, 0);
pub const FOR_TUN_INTERFACE_GUID: &str = "f579d929-6c40-4e5a-8532-180199a4e321";
pub const FOR_TUN_HWID: &str = "ForTun";
-// pub const FOR_TUN_IOCTL_OPEN_ADAPTER: u32 = ctl_code!(0x00000022, 6, 0, 0);
-// pub const FOR_TUN_INTERFACE_GUID: &str = "CAC88484-7515-4C03-82E6-71A87ABAC361";
-// pub const FOR_TUN_HWID: &str = "ovpn-dco";
-
-//const FOR_TUN_ENUMERATOR:PCWSTR = w!("SWD\\ForTun");
pub const FOR_TUN_DEV_CLASS: GUID = GUID_DEVCLASS_NET;
pub struct AdapterDevice {
@@ -60,47 +52,17 @@ impl AdapterDevice {
}
}
- pub fn start_adapter(&self) -> anyhow::Result {
- //println!("interface_id:{}",self.interface_id);
- /*
- let file = OpenOptions::new()
- .write(true)
- .read(true)
- .create(false)
- //.custom_flags(0x40000000)
- //.custom_flags(FILE_FLAG_OVERLAPPED.0|FILE_ATTRIBUTE_SYSTEM.0)
- //.share_mode()
- .open(self.interface_id.clone())?;
-
-
- let result = unsafe {
- DeviceIoControl(
- HANDLE(file.as_raw_handle() as _),
- FOR_TUN_IOCTL_OPEN_ADAPTER,
- None,
- 0,
- None,
- 0,
- None,
- None,
- )
- .as_bool()
- };
- if !result {
- bail!("init adapter error: {:?}", unsafe { GetLastError() })
- }
-
- */
+ pub(crate) fn start_adapter(&self) -> anyhow::Result {
let file = unsafe {
let name = HSTRING::from(self.interface_id.clone());
CreateFileW(
PCWSTR(name.as_ptr()),
- (FILE_GENERIC_READ | FILE_GENERIC_WRITE).0,
+ FILE_GENERIC_READ.0| FILE_GENERIC_WRITE.0,
FILE_SHARE_NONE,
None,
OPEN_EXISTING,
- FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
+ FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,
None,
)
}
@@ -116,12 +78,12 @@ impl AdapterDevice {
None,
None,
)
- .as_bool()
+ .is_ok()
};
if !result {
- unsafe { CloseHandle(file) };
- bail!("init adapter error: {:?}", unsafe { GetLastError() })
+ let _ = unsafe { CloseHandle(file) };
+ bail!("init adapter error: {:?}", result)
}
Ok(file)
@@ -134,6 +96,9 @@ pub fn init_device>(
inf_path: T,
) -> anyhow::Result {
let devices = enum_device(&FOR_TUN_DEV_CLASS, FOR_TUN_HWID)?;
+ for (guid, version_str) in devices.iter() {
+ tracing::debug!("device: {}, version: {}", guid, version_str);
+ }
if devices.is_empty() {
// There is no devices
install_driver(inf_path)?; // TODO: this may install multiple times. need add more exact function to check if driver installed.
@@ -191,12 +156,12 @@ fn install_driver>(inf_path: T) -> anyhow::Result<()> {
None,
)
};
- if !ret.as_bool() {
+ if !ret.is_ok() {
unsafe {
return Err(anyhow!(
- "install driver:{} fail, code:{}",
+ "install driver:{} fail, code:{:?}",
inf_path.display(),
- GetLastError().0
+ ret
));
}
}
@@ -323,22 +288,22 @@ pub fn create_device(
if wait_result != WAIT_OBJECT_0 {
unsafe {
return Err(anyhow!(
- "create sw device error: {}, last_error:{}",
+ "create sw device error: {}, last_error:{:?}",
wait_result.0,
- GetLastError().0
+ GetLastError()
));
}
}
if !context.success {
unsafe {
bail!(
- "create sw device error in callback, last error:{}",
- GetLastError().0
+ "create sw device error in callback, last error:{:?}",
+ GetLastError()
)
}
}
- Ok((HSWDEVICE(sw_device), context.instance_id))
+ Ok((sw_device, context.instance_id))
}
unsafe extern "system" fn creation_callback(
@@ -357,7 +322,7 @@ unsafe extern "system" fn creation_callback(
//println!("device creation device_id error, {}",_create_result);
}
let ret = windows::Win32::System::Threading::SetEvent(context.event);
- if !ret.as_bool() {
+ if !ret.is_ok() {
//println!("set event error, {}", GetLastError().0)
}
}
@@ -448,15 +413,13 @@ pub fn get_net_index(device_instance_id: String) -> anyhow::Result {
let mut key = HKEY::default();
- let _display_name_buf: [u16; 1024] = unsafe { zeroed() };
-
let key_path_str =
format!("SYSTEM\\CurrentControlSet\\Control\\Class\\{{{FOR_TUN_DEV_CLASS:?}}}");
let key_path = HSTRING::from(key_path_str.clone());
let key_path = PCWSTR(key_path.as_ptr());
- if unsafe {
+ if !unsafe {
RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
key_path,
@@ -464,9 +427,9 @@ pub fn get_net_index(device_instance_id: String) -> anyhow::Result {
KEY_READ | KEY_ENUMERATE_SUB_KEYS,
&mut key,
)
- } != NO_ERROR
+ }.is_ok()
{
- unsafe { RegCloseKey(key) };
+ let _ = unsafe { RegCloseKey(key) };
bail!("can not open registry key: {}", key_path_str);
} else {
let mut value_buffer = vec![0; 200];
@@ -489,14 +452,16 @@ pub fn get_net_index(device_instance_id: String) -> anyhow::Result {
)
};
- if ret == ERROR_NO_MORE_ITEMS {
- break;
- } else if ret != NO_ERROR {
- bail!(
- "can not enum registry key: {}, error:{:?}",
- key_path_str,
- ret
- )
+ if let Err(e) = ret {
+ if e.code() == ERROR_IO_PENDING.into() {
+ break;
+ }else {
+ bail!(
+ "can not enum registry key: {}, error:{:?}",
+ key_path_str,
+ e
+ )
+ }
}
let instance_name_key =
@@ -635,7 +600,6 @@ fn enum_device(device_class_id: &GUID, hwid: &str) -> anyhow::Result anyhow::Result = Vec::with_capacity(2048);
+ let mut property_value: Vec = vec![0;2048];
let mut index = 0;
let mut device_id = PCWSTR::from_raw(buffer[index..].as_mut_ptr());
@@ -671,7 +635,6 @@ fn enum_device(device_class_id: &GUID, hwid: &str) -> anyhow::Result anyhow::Result) -> anyhow::Result {
let mut property_type: DEVPROPTYPE = DEVPROPTYPE::default();
-
- let mut property_value_length = 0;
-
+ let mut property_value_length = property_value.len() as u32;
unsafe {
CM_Get_DevNode_PropertyW(
dev_inst,
@@ -708,12 +669,20 @@ fn _cm_get_string_property(dev_inst:u32, key:&DEVPROPKEY, property_value:&mut Ve
0,
);
}
+
+ //8210 property string list
if property_value_length > 0 {
unsafe {
- property_value.set_len(property_value_length as usize);
+ property_value.set_len((property_value_length as usize)*2);
};
+ if property_type == DEVPROP_TYPE_STRING_LIST {
+
+ //get_pcwstr_list()
+ }
let value = unsafe {
+ //let z= PCWSTR(property_value.as_ptr() as *mut u16);
+ //println!("zx:{:?}", z.to_string());
PCWSTR::from_raw(property_value.as_mut_ptr().cast::()).to_string()
};
return Ok(value?);
diff --git a/ForTunCli/src/lib.rs b/ForTunCli/src/lib.rs
index 902299d..b96f795 100644
--- a/ForTunCli/src/lib.rs
+++ b/ForTunCli/src/lib.rs
@@ -1,6 +1,7 @@
mod device_ops;
pub mod overlapped_file;
+//use std::os::windows::io::FromRawHandle;
use std::path::Path;
use crate::overlapped_file::WinOverlappedFile;
use anyhow::bail;
@@ -9,7 +10,6 @@ pub use device_ops::init_device;
pub use device_ops::net_config;
pub use device_ops::AdapterDevice;
use std::sync::Arc;
-use tokio::io;
use windows::core::GUID;
use windows::Win32::Foundation::CloseHandle;
use windows::Win32::System::IO::OVERLAPPED;
@@ -29,7 +29,7 @@ unsafe impl Send for ReadFile {}
impl ReadFile {
// this would block...
- pub fn read(&mut self, buf: &mut [u8]) -> io::Result {
+ pub fn read(&mut self, buf: &mut [u8]) -> anyhow::Result {
self.file.read(buf, &mut self.overlapped)
}
}
@@ -49,7 +49,7 @@ unsafe impl Send for WriteFile {}
impl WriteFile {
//this would Finish quick
- pub fn write(&mut self, buf: &[u8]) -> io::Result {
+ pub fn write(&mut self, buf: &[u8]) -> anyhow::Result {
self.file.write(buf, &mut self.overlapped)
}
}
@@ -85,54 +85,3 @@ pub fn create_async_tun>(device_id: &GUID, name: &str, inf_path: T
device,
))
}
-
-/*
-pub struct TunSocket {
- pub file: tokio::fs::File,
- pub device: AdapterDevice,
-}
-
-pub fn create_async_tun(device_id: &GUID, name: &str) -> anyhow::Result {
- let device = init_device(device_id, name, "C:/DriverTest/Drivers/ForTun.inf")?;
- let file = device.start_adapter()?;
-
- let file = tokio::fs::File::from_std(file);
- Ok(TunSocket { file, device })
-}
-
-
-impl AsyncRead for TunSocket {
- fn poll_read(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &mut ReadBuf<'_>,
- ) -> Poll> {
- Pin::new(&mut self.get_mut().file).poll_read(cx, buf)
- }
-}
-
-impl AsyncWrite for TunSocket {
- fn poll_write(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll> {
- Pin::new(&mut self.get_mut().file).poll_write(cx, buf)
- }
-
- fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> {
- Pin::new(&mut self.get_mut().file).poll_flush(cx)
- }
-
- fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> {
- Pin::new(&mut self.get_mut().file).poll_shutdown(cx)
- }
- fn poll_write_vectored(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- bufs: &[IoSlice<'_>],
- ) -> Poll> {
- Pin::new(&mut self.get_mut().file).poll_write_vectored(cx, bufs)
- }
-}
-*/
diff --git a/ForTunCli/src/overlapped_file.rs b/ForTunCli/src/overlapped_file.rs
index 54b0747..5cfaf4b 100644
--- a/ForTunCli/src/overlapped_file.rs
+++ b/ForTunCli/src/overlapped_file.rs
@@ -1,5 +1,5 @@
-use std::io;
-use windows::Win32::Foundation::{CloseHandle, GetLastError, BOOL, ERROR_IO_PENDING, HANDLE};
+use anyhow::bail;
+use windows::Win32::Foundation::{CloseHandle, HANDLE, ERROR_IO_PENDING};
use windows::Win32::Storage::FileSystem::{ReadFile, WriteFile};
use windows::Win32::System::IO::{CancelIoEx, DeviceIoControl, GetOverlappedResult, OVERLAPPED};
@@ -9,12 +9,8 @@ pub struct WinOverlappedFile {
impl WinOverlappedFile {
pub fn new(file: HANDLE) -> anyhow::Result {
- //let mut overlapped = OVERLAPPED::default();
- //overlapped.hEvent = unsafe {CreateEventW(None, false, false, None)}?;
-
Ok(Self {
file,
- //read_overlapped: overlapped,
})
}
@@ -26,7 +22,7 @@ impl WinOverlappedFile {
lpoutbuffer: Option<*mut ::core::ffi::c_void>,
noutbuffersize: u32,
lpbytesreturned: Option<*mut u32>,
- ) -> BOOL {
+ ) -> windows::core::Result<()> {
unsafe {
DeviceIoControl(
self.file,
@@ -42,33 +38,31 @@ impl WinOverlappedFile {
}
// driver would wait
- pub fn read(&self, buf: &mut [u8], overlapped: &mut OVERLAPPED) -> io::Result {
+ pub fn read(&self, buf: &mut [u8], overlapped: &mut OVERLAPPED) -> anyhow::Result {
let mut size = 0;
let ret = unsafe {
ReadFile(
self.file,
- Some(buf.as_mut_ptr() as _),
- buf.len() as u32,
+ Some(buf),
Some(&mut size),
Some(overlapped),
)
};
- return if ret.as_bool() {
- //success
- Ok(size as usize)
- } else {
- let last_error = unsafe { GetLastError() };
- if last_error == ERROR_IO_PENDING {
- let r = unsafe { GetOverlappedResult(self.file, overlapped, &mut size, true) };
- if r.as_bool() {
- Ok(size as usize)
+ match ret {
+ Ok(()) => Ok(size as usize),
+ Err(e) => {
+ if e.code() == ERROR_IO_PENDING.into() {
+ let r = unsafe { GetOverlappedResult(self.file, overlapped, &mut size, true) };
+ if r.is_ok() {
+ Ok(size as usize)
+ } else {
+ bail!("GetOverlappedResult error: {:?}",r)
+ }
} else {
- Err(io::Error::from_raw_os_error(last_error.0 as i32))
+ bail!("read file error: {:?}",e)
}
- } else {
- Err(io::Error::from_raw_os_error(last_error.0 as i32))
}
- };
+ }
}
/*
pub fn read_result(&self, overlapped: &mut OVERLAPPED) -> io::Result