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> { @@ -94,7 +88,7 @@ impl WinOverlappedFile { }*/ // this is quick , so block - pub fn write(&self, buf: &[u8], overlapped: &mut OVERLAPPED) -> io::Result { + pub fn write(&self, buf: &[u8], overlapped: &mut OVERLAPPED) -> anyhow::Result { let mut size = 0; let r = unsafe { WriteFile( @@ -104,32 +98,26 @@ impl WinOverlappedFile { Some(overlapped), ) }; - return if r.as_bool() { - 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 r { + 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!("write file error: {:?}",e) } - } else { - Err(io::Error::from_raw_os_error(last_error.0 as i32)) } - }; + } } - pub fn cancel_io(&self, overlapped: &mut OVERLAPPED) -> io::Result<()> { - if unsafe { CancelIoEx(self.file, Some(overlapped)) }.as_bool() { - Ok(()) - } else { - Err(io::Error::last_os_error()) - //Err(io::Error::from_raw_os_error(last_error.0 as i32)) - //Err(anyhow!("read file fail:{:?}", last_error)) - //Err(anyhow!("cancel file fail:{:?}", unsafe {GetLastError()})) - } + + pub fn cancel_io(&self, overlapped: &mut OVERLAPPED) -> windows::core::Result<()> { + unsafe { CancelIoEx(self.file, Some(overlapped)) } } } diff --git a/LICENSE b/LICENSE index 261eeb9..3655b9f 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright (c) 2023 Timzaak Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 13a1443..2cef587 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,35 @@ # simple-windows-tun -Very simple windows tun, base on NetAdapterCx. +Very simple windows tun, base on NetAdapterCx. This is used for [ForNet](https://github.com/ForNetCode/fornet). -This is used for [ForNet](https://github.com/ForNetCode/fornet), It now passed simple test case in Windows 11 X86 Virtual Machine. But It has lots of job to do. - -- [ ] Get a company to buy code sign. -- [ ] Pass Windows Test. -- [ ] Release the signed driver files at GitHub Release. -- [ ] Release ForTunCli To crate. ## How to Use it -1. Download the signed driver from the release page. -2. run command `cargo add simple-windows-tun` - -The Below is an example code: - -```rust - -``` +1. Download the driver files at [Release Page](https://github.com/ForNetCode/simple-windows-tun/releases) +2. write rust code like [example](https://github.com/ForNetCode/simple-windows-tun/blob/main/FunTunCli/src/examples/simple.rs), replace guid with your own defined and inf_path to the proper path. ## Support Platform -Windows Version: Newer than Windows 10, version 2004. +Windows Version: Newer than Windows 10, version 2004.(We have tested with Windows 11) Architecture Platform: x86_64. -We may support `aarch64` later. +We may support `aarch64` and Win 10 later. If you have any idea, feel free to open issue. -### how to build it +### How To Build It Because of the EV certifacte, It may be very hard for developer to build the certificated driver. We just write this for a guide of our own to release the driver. ```powershell -# after build the driver. +# after build the driver with Visual Studio. cp .\ForTun\fortun.ddf .\ForTun\x64\Release\ForTun\ cp .\ForTun\x64\Release\ForTun.pdb .\ForTun\x64\Release\ForTun\ForTun.pdb -cd .\ForTun\x64\Realse\ForTun +cd .\ForTun\x64\Release\ForTun MakeCab /f "fortun.ddf" # sign dist1/fortun.cab with EV certifacter -# go to https://partner.microsoft.com/zh-cn/dashboard/hardware/Search to submit +# go to https://partner.microsoft.com/zh-cn/dashboard/hardware/Search to submit and signed with Windows. + +# There's also a simple [tutorial]() to tell you how develop and debug Windows driver in Chiease. ``` +## TODO +1. release rust client code to crate.io +2. support win10 and test. +3. add Git Action to build unsigned driver. \ No newline at end of file