From 8d01979dcf2f86bb618ad116d80acaede1fcc612 Mon Sep 17 00:00:00 2001 From: Nick Banks Date: Wed, 22 Feb 2017 09:58:02 -0800 Subject: [PATCH] Windows: Reset new test Nodes (#1364) * Reset new test Nodes * Finalize before reinitializing * Minor issues with reinitialization * Fix settings wipe --- examples/drivers/windows/otLwf/command.c | 1 - .../drivers/windows/otLwf/eventprocessing.c | 20 ++--- examples/drivers/windows/otLwf/filter.h | 1 + examples/drivers/windows/otLwf/radio.c | 37 ++++++++ examples/drivers/windows/otLwf/settings.c | 86 +++++++++++++++++-- .../drivers/windows/otNodeApi/otNodeApi.cpp | 3 + 6 files changed, 131 insertions(+), 17 deletions(-) diff --git a/examples/drivers/windows/otLwf/command.c b/examples/drivers/windows/otLwf/command.c index 628f36060..5b32fc535 100644 --- a/examples/drivers/windows/otLwf/command.c +++ b/examples/drivers/windows/otLwf/command.c @@ -242,7 +242,6 @@ otLwfCmdProcess( KeSetEvent(&pFilter->cmdResetCompleteEvent, IO_NO_INCREMENT, FALSE); // TODO - Should this be passed on to Thread or Tunnel logic? - NT_ASSERT(pFilter->DeviceStatus == OTLWF_DEVICE_STATUS_UNINTIALIZED); } } else if (ExAcquireRundownProtection(&pFilter->ExternalRefs)) diff --git a/examples/drivers/windows/otLwf/eventprocessing.c b/examples/drivers/windows/otLwf/eventprocessing.c index 9f097939c..b2be230ee 100644 --- a/examples/drivers/windows/otLwf/eventprocessing.c +++ b/examples/drivers/windows/otLwf/eventprocessing.c @@ -712,7 +712,6 @@ otLwfEventWorkerThread( ) { PMS_FILTER pFilter = (PMS_FILTER)Context; - size_t otInstanceSize = 0; NT_ASSERT(pFilter); LogFuncEntry(DRIVER_DEFAULT); @@ -753,32 +752,33 @@ otLwfEventWorkerThread( otLwfRadioInit(pFilter); // Calculate the size of the otInstance and allocate it - (VOID)otInstanceInit(NULL, &otInstanceSize); - NT_ASSERT(otInstanceSize != 0); + pFilter->otInstanceSize = 0; + (VOID)otInstanceInit(NULL, &pFilter->otInstanceSize); + NT_ASSERT(pFilter->otInstanceSize != 0); // Add space for a pointer back to the filter - otInstanceSize += sizeof(PMS_FILTER); + pFilter->otInstanceSize += sizeof(PMS_FILTER); // Allocate the buffer - pFilter->otInstanceBuffer = (PUCHAR)FILTER_ALLOC_MEM(pFilter->FilterHandle, (ULONG)otInstanceSize); + pFilter->otInstanceBuffer = (PUCHAR)FILTER_ALLOC_MEM(pFilter->FilterHandle, (ULONG)pFilter->otInstanceSize); if (pFilter == NULL) { - LogWarning(DRIVER_DEFAULT, "Failed to allocate otInstance buffer, 0x%x bytes", (ULONG)otInstanceSize); + LogWarning(DRIVER_DEFAULT, "Failed to allocate otInstance buffer, 0x%x bytes", (ULONG)pFilter->otInstanceSize); goto exit; } - RtlZeroMemory(pFilter->otInstanceBuffer, otInstanceSize); + RtlZeroMemory(pFilter->otInstanceBuffer, pFilter->otInstanceSize); // Store the pointer and decrement the size memcpy(pFilter->otInstanceBuffer, &pFilter, sizeof(PMS_FILTER)); - otInstanceSize -= sizeof(PMS_FILTER); + pFilter->otInstanceSize -= sizeof(PMS_FILTER); // Initialize the OpenThread library pFilter->otCachedRole = kDeviceRoleDisabled; - pFilter->otCtx = otInstanceInit(pFilter->otInstanceBuffer + sizeof(PMS_FILTER), &otInstanceSize); + pFilter->otCtx = otInstanceInit(pFilter->otInstanceBuffer + sizeof(PMS_FILTER), &pFilter->otInstanceSize); NT_ASSERT(pFilter->otCtx); if (pFilter->otCtx == NULL) { - LogError(DRIVER_DEFAULT, "otInstanceInit failed, otInstanceSize = %u bytes", (ULONG)otInstanceSize); + LogError(DRIVER_DEFAULT, "otInstanceInit failed, otInstanceSize = %u bytes", (ULONG)pFilter->otInstanceSize); goto exit; } diff --git a/examples/drivers/windows/otLwf/filter.h b/examples/drivers/windows/otLwf/filter.h index 33b876bcf..7f1fb6c5f 100644 --- a/examples/drivers/windows/otLwf/filter.h +++ b/examples/drivers/windows/otLwf/filter.h @@ -271,6 +271,7 @@ typedef struct _MS_FILTER // OpenThread context buffer // otInstance* otCtx; + size_t otInstanceSize; PUCHAR otInstanceBuffer; }; struct // Tunnel Mode Variables diff --git a/examples/drivers/windows/otLwf/radio.c b/examples/drivers/windows/otLwf/radio.c index 63e4408e6..10b089485 100644 --- a/examples/drivers/windows/otLwf/radio.c +++ b/examples/drivers/windows/otLwf/radio.c @@ -57,10 +57,47 @@ otPlatReset( NT_ASSERT(otCtx); PMS_FILTER pFilter = otCtxToFilter(otCtx); + LogFuncEntry(DRIVER_DEFAULT); + LogInfo(DRIVER_DEFAULT, "Interface %!GUID! resetting...", &pFilter->InterfaceGuid); // Indicate to the miniport (void)otLwfCmdResetDevice(pFilter, TRUE); + + // Finalize previous OpenThread instance + otInstanceFinalize(pFilter->otCtx); + pFilter->otCtx = NULL; + + // Reset radio layer + pFilter->otPhyState = kStateDisabled; + pFilter->otCurrentListenChannel = 0xFF; + pFilter->otPromiscuous = false; + pFilter->otPendingMacOffloadEnabled = FALSE; + pFilter->otPendingShortAddressCount = 0; + pFilter->otPendingExtendedAddressCount = 0; + + // Reinitialize the OpenThread library + pFilter->otCachedRole = kDeviceRoleDisabled; + pFilter->otCtx = otInstanceInit(pFilter->otInstanceBuffer + sizeof(PMS_FILTER), &pFilter->otInstanceSize); + ASSERT(pFilter->otCtx); + + // Make sure our helper function returns the right pointer for the filter, given the openthread instance + NT_ASSERT(otCtxToFilter(pFilter->otCtx) == pFilter); + + // Disable Icmp (ping) handling + otSetIcmpEchoEnabled(pFilter->otCtx, FALSE); + + // Register callbacks with OpenThread + otSetStateChangedCallback(pFilter->otCtx, otLwfStateChangedCallback, pFilter); + otSetReceiveIp6DatagramCallback(pFilter->otCtx, otLwfReceiveIp6DatagramCallback, pFilter); + + // Query the current addresses from TCPIP and cache them + (void)otLwfInitializeAddresses(pFilter); + + // Initialze media connect state to disconnected + otLwfIndicateLinkState(pFilter, MediaConnectStateDisconnected); + + LogFuncExit(DRIVER_DEFAULT); } otPlatResetReason diff --git a/examples/drivers/windows/otLwf/settings.c b/examples/drivers/windows/otLwf/settings.c index 09e8c8e8b..cfdfcee9d 100644 --- a/examples/drivers/windows/otLwf/settings.c +++ b/examples/drivers/windows/otLwf/settings.c @@ -45,6 +45,8 @@ void otPlatSettingsInit(otInstance *otCtx) OBJECT_ATTRIBUTES attributes; ULONG disposition; + LogFuncEntry(DRIVER_DEFAULT); + InitializeObjectAttributes( &attributes, (PUNICODE_STRING)&SubKeyName, @@ -68,6 +70,8 @@ void otPlatSettingsInit(otInstance *otCtx) { LogError(DRIVER_DEFAULT, "ZwCreateKey for 'OpenThread' key failed, %!STATUS!", status); } + + LogFuncExit(DRIVER_DEFAULT); } uint16_t FilterCountSettings(_In_ PMS_FILTER pFilter, uint16_t aKey) @@ -522,14 +526,84 @@ void otPlatSettingsWipe(otInstance *otCtx) NT_ASSERT(otCtx); PMS_FILTER pFilter = otCtxToFilter(otCtx); - // Delete the entire 'OpenThread' sub key + LogFuncEntry(DRIVER_DEFAULT); + + // Delete all subkeys of 'OpenThread' if (pFilter->otSettingsRegKey) { - ZwDeleteKey(pFilter->otSettingsRegKey); - ZwClose(pFilter->otSettingsRegKey); - pFilter->otSettingsRegKey = NULL; + NTSTATUS status = STATUS_SUCCESS; + ULONG index = 0; + UCHAR keyInfo[sizeof(KEY_BASIC_INFORMATION) + 64]; + + while (status == STATUS_SUCCESS) + { + ULONG size = sizeof(keyInfo); + status = + ZwEnumerateKey( + pFilter->otSettingsRegKey, + index, + KeyBasicInformation, + keyInfo, + size, + &size); + + bool deleted = false; + if (NT_SUCCESS(status)) + { + HANDLE subKey = NULL; + OBJECT_ATTRIBUTES attributes; + PKEY_BASIC_INFORMATION pKeyInfo = (PKEY_BASIC_INFORMATION)keyInfo; + + UNICODE_STRING subKeyName = + { + (USHORT)pKeyInfo->NameLength, + (USHORT)pKeyInfo->NameLength, + pKeyInfo->Name + }; + + InitializeObjectAttributes( + &attributes, + &subKeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + pFilter->otSettingsRegKey, + NULL); + + // Open the sub key + status = + ZwOpenKey( + &subKey, + KEY_ALL_ACCESS, + &attributes); + + if (NT_SUCCESS(status)) + { + // Delete the key + status = ZwDeleteKey(subKey); + if (!NT_SUCCESS(status)) + { + LogError(DRIVER_DEFAULT, "ZwDeleteKey for subkey failed, %!STATUS!", status); + } + else + { + deleted = true; + } + + // Close handle + ZwClose(subKey); + } + else + { + LogError(DRIVER_DEFAULT, "ZwOpenKey for subkey failed, %!STATUS!", status); + } + } + + // Only increment index if we didn't delete + if (!deleted) + { + index++; + } + } } - // Recreate and open the 'OpenThread' sub key - otPlatSettingsInit(otCtx); + LogFuncExit(DRIVER_DEFAULT); } diff --git a/examples/drivers/windows/otNodeApi/otNodeApi.cpp b/examples/drivers/windows/otNodeApi/otNodeApi.cpp index 4d2aaf2c3..1bade1133 100644 --- a/examples/drivers/windows/otNodeApi/otNodeApi.cpp +++ b/examples/drivers/windows/otNodeApi/otNodeApi.cpp @@ -843,6 +843,9 @@ OTNODEAPI otNode* OTCALL otNodeInit(uint32_t id) InitializeCriticalSection(&node->mCS); + // Reset any previously saved settings + otFactoryReset(instance); + otSetStateChangedCallback(instance, otNodeStateChangedCallback, node); HandleAddressChanges(node);