Example #1
0
int TestFuncDebug()
{
	/* log the function entry log. */
	LogFuncEntry();

	LogTrace("Trace log %s %f", "Test", 1.066f);
	LogDebug("Debug level log" );
	LogInfo("Info level log %d" , 0);
	LogWarn("Warn level log" );
	LogError("Error level log" );
	LogFatal("Fatal level log" );

	if(1)
	{
		/* log the function exit. */
		LogFuncExit();
		return 0;
	}
	else
	{
		/* log the function exit. */
		LogFuncExit();
		return -1;
	}
	
}
Example #2
0
VOID
otLwfEventProcessingIndicateAddressChange(
    _In_ PMS_FILTER             pFilter,
    _In_ MIB_NOTIFICATION_TYPE  NotificationType,
    _In_ PIN6_ADDR              pAddr
    )
{
    LogFuncEntryMsg(DRIVER_DEFAULT, "Filter: %p", pFilter);

    NT_ASSERT(pFilter->DeviceStatus == OTLWF_DEVICE_STATUS_RADIO_MODE);

    POTLWF_ADDR_EVENT Event = FILTER_ALLOC_MEM(pFilter->FilterHandle, sizeof(OTLWF_ADDR_EVENT));
    if (Event == NULL)
    {
        LogWarning(DRIVER_DEFAULT, "Failed to alloc new OTLWF_ADDR_EVENT");
    }
    else
    {
        Event->NotificationType = NotificationType;
        Event->Address = *pAddr;

        // Add the event to the queue
        NdisAcquireSpinLock(&pFilter->EventsLock);
        InsertTailList(&pFilter->AddressChangesHead, &Event->Link);
        NdisReleaseSpinLock(&pFilter->EventsLock);

        // Set the event to indicate we have a new address to process
        KeSetEvent(&pFilter->EventWorkerThreadProcessAddressChanges, 0, FALSE);
    }

    LogFuncExit(DRIVER_DEFAULT);
}
Example #3
0
void 
otLwfTunUninitialize(
    _In_ PMS_FILTER pFilter
    )
{
    LogFuncEntry(DRIVER_DEFAULT);

    // Clean up worker thread
    if (pFilter->TunWorkerThread)
    {
        LogInfo(DRIVER_DEFAULT, "Stopping tunnel worker thread and waiting for it to complete.");

        // Send event to shutdown worker thread
        KeSetEvent(&pFilter->TunWorkerThreadStopEvent, 0, FALSE);

        // Wait for worker thread to finish
        KeWaitForSingleObject(
            pFilter->TunWorkerThread,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

        // Free worker thread
        ObDereferenceObject(pFilter->TunWorkerThread);
        pFilter->TunWorkerThread = NULL;

        LogInfo(DRIVER_DEFAULT, "Tunnel worker thread cleaned up.");
    }

    LogFuncExit(DRIVER_DEFAULT);
}
Example #4
0
_Use_decl_annotations_
VOID
FilterCancelOidRequest(
    NDIS_HANDLE             FilterModuleContext,
    PVOID                   RequestId
    )
/*++

Routine Description:

    Cancels an OID request

    If your filter driver does not intercept and hold onto any OID requests,
    then you do not need to implement this routine.  You may simply omit it.
    Furthermore, if the filter only holds onto OID requests so it can pass
    down a clone (the most common case) the filter does not need to implement
    this routine; NDIS will then automatically request that the lower-level
    filter/miniport cancel your cloned OID.

    Most filters do not need to implement this routine.

Arguments:

    FilterModuleContext   - our filter
    RequestId             - identifies the request(s) to cancel

--*/
{
    PMS_FILTER                          pFilter = (PMS_FILTER)FilterModuleContext;
    PNDIS_OID_REQUEST                   Request = NULL;
    POTLWF_REQUEST_CONTEXT              Context;
    PNDIS_OID_REQUEST                   OriginalRequest = NULL;
    BOOLEAN                             bFalse = FALSE;
    
    LogFuncEntryMsg(DRIVER_OID, "Filter: %p, RequestId: %p", FilterModuleContext, RequestId);

    FILTER_ACQUIRE_LOCK(&pFilter->PendingOidRequestLock, bFalse);

    Request = pFilter->PendingOidRequest;

    if (Request != NULL)
    {
        Context = (POTLWF_REQUEST_CONTEXT)(&Request->SourceReserved[0]);

        OriginalRequest = (*Context);
    }

    if ((OriginalRequest != NULL) && (OriginalRequest->RequestId == RequestId))
    {
        FILTER_RELEASE_LOCK(&pFilter->PendingOidRequestLock, bFalse);

        NdisFCancelOidRequest(pFilter->FilterHandle, RequestId);
    }
    else
    {
        FILTER_RELEASE_LOCK(&pFilter->PendingOidRequestLock, bFalse);
    }
    
    LogFuncExit(DRIVER_OID);
}
Example #5
0
_Use_decl_annotations_
VOID
FilterDetach(
    NDIS_HANDLE     FilterModuleContext
    )
/*++

Routine Description:

    Filter detach routine.
    This is a required function that will deallocate all the resources allocated during
    FilterAttach. NDIS calls FilterAttach to remove a filter instance from a filter stack.

Arguments:

    FilterModuleContext - pointer to the filter context area.

Return Value:
    None.

NOTE: Called at PASSIVE_LEVEL and the filter is in paused state

--*/
{
    PMS_FILTER  pFilter = (PMS_FILTER)FilterModuleContext;

    LogFuncEntryMsg(DRIVER_DEFAULT, "Filter: %p", FilterModuleContext);

    // Filter must be in paused state and pretty much inactive
    NT_ASSERT(pFilter->State == FilterPaused);
    NT_ASSERT(pFilter->DeviceStatus == OTLWF_DEVICE_STATUS_UNINTIALIZED);

    //
    // Detach must not fail, so do not put any code here that can possibly fail.
    //

    // Remove this Filter from the global list
    NdisAcquireSpinLock(&FilterListLock);
    RemoveEntryList(&pFilter->FilterModuleLink);
    NdisReleaseSpinLock(&FilterListLock);

    // Unregister from address change notifications
    CancelMibChangeNotify2(pFilter->AddressChangeHandle);
    pFilter->AddressChangeHandle = NULL;

    // Close the registry key
    if (pFilter->InterfaceRegKey)
    {
        ZwClose(pFilter->InterfaceRegKey);
        pFilter->InterfaceRegKey = NULL;
    }

    // Free the memory allocated
    NdisFreeMemory(pFilter, 0, 0);

    LogFuncExit(DRIVER_DEFAULT);
}
Example #6
0
_Use_decl_annotations_
VOID
FilterStatus(
    NDIS_HANDLE             FilterModuleContext,
    PNDIS_STATUS_INDICATION StatusIndication
    )
/*++

Routine Description:

    Status indication handler

Arguments:

    FilterModuleContext     - our filter context
    StatusIndication        - the status being indicated

NOTE: called at <= DISPATCH_LEVEL

  FILTER driver may call NdisFIndicateStatus to generate a status indication to
  all higher layer modules.

--*/
{
    PMS_FILTER      pFilter = (PMS_FILTER)FilterModuleContext;

    LogFuncEntryMsg(DRIVER_DEFAULT, "Filter: %p, IndicateStatus: %8x", FilterModuleContext, StatusIndication->StatusCode);

    if (StatusIndication->StatusCode == NDIS_STATUS_LINK_STATE)
    {
        PNDIS_LINK_STATE LinkState = (PNDIS_LINK_STATE)StatusIndication->StatusBuffer;

        LogInfo(DRIVER_DEFAULT, "Filter: %p, MediaConnectState: %u", FilterModuleContext, LinkState->MediaConnectState);

        // Cache the link state from the miniport
        memcpy(&pFilter->MiniportLinkState, LinkState, sizeof(NDIS_LINK_STATE));
    }

    NdisFIndicateStatus(pFilter->FilterHandle, StatusIndication);
    
    LogFuncExit(DRIVER_DEFAULT);
}
Example #7
0
void otPlatSettingsInit(otInstance *otCtx)
{
    NT_ASSERT(otCtx);
    PMS_FILTER pFilter = otCtxToFilter(otCtx);

    DECLARE_CONST_UNICODE_STRING(SubKeyName, L"OpenThread");

    OBJECT_ATTRIBUTES attributes;
    ULONG disposition;

    LogFuncEntry(DRIVER_DEFAULT);

    InitializeObjectAttributes(
        &attributes,
        (PUNICODE_STRING)&SubKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
        pFilter->InterfaceRegKey,
        NULL);

    // Create/Open the 'OpenThread' sub key
    NTSTATUS status =
        ZwCreateKey(
            &pFilter->otSettingsRegKey,
            KEY_ALL_ACCESS,
            &attributes,
            0,
            NULL,
            REG_OPTION_NON_VOLATILE,
            &disposition);

    NT_ASSERT(NT_SUCCESS(status));
    if (!NT_SUCCESS(status))
    {
        LogError(DRIVER_DEFAULT, "ZwCreateKey for 'OpenThread' key failed, %!STATUS!", status);
    }

    LogFuncExit(DRIVER_DEFAULT);
}
Example #8
0
// Worker thread for processing all tunnel events
_Use_decl_annotations_
VOID
otLwfTunWorkerThread(
    PVOID   Context
    )
{
    PMS_FILTER pFilter = (PMS_FILTER)Context;
    NT_ASSERT(pFilter);

    LogFuncEntry(DRIVER_DEFAULT);

    PKEVENT WaitEvents[] = 
    { 
        &pFilter->TunWorkerThreadStopEvent,
        &pFilter->TunWorkerThreadAddressChangedEvent
    };

    LogFuncExit(DRIVER_DEFAULT);
    
    while (true)
    {
        // Wait for event to stop or process event to fire
        NTSTATUS status = 
            KeWaitForMultipleObjects(
                ARRAYSIZE(WaitEvents), 
                (PVOID*)WaitEvents, 
                WaitAny, 
                Executive, 
                KernelMode, 
                FALSE, 
                NULL, 
                NULL);

        // If it is the first event, then we are shutting down. Exit loop and terminate thread
        if (status == STATUS_WAIT_0)
        {
            LogInfo(DRIVER_DEFAULT, "Received tunnel worker thread shutdown event.");
            break;
        }
        else if (status == STATUS_WAIT_0 + 1) // TunWorkerThreadAddressChangedEvent fired
        {
            PVOID DataBuffer = NULL;
            const uint8_t* value_data_ptr = NULL;
            spinel_size_t value_data_len = 0;
            
            // Query the current addresses
            status = 
                otLwfCmdGetProp(
                    pFilter,
                    &DataBuffer,
                    SPINEL_PROP_IPV6_ADDRESS_TABLE,
                    SPINEL_DATATYPE_DATA_S,
                    &value_data_ptr,
                    &value_data_len);
            if (NT_SUCCESS(status))
            {
                uint32_t aNotifFlags = 0;
                otLwfTunAddressesUpdated(pFilter, value_data_ptr, value_data_len, &aNotifFlags);

                // Send notification
                if (aNotifFlags != 0)
                {
                    PFILTER_NOTIFICATION_ENTRY NotifEntry = FILTER_ALLOC_NOTIF(pFilter);
                    if (NotifEntry)
                    {
                        RtlZeroMemory(NotifEntry, sizeof(FILTER_NOTIFICATION_ENTRY));
                        NotifEntry->Notif.InterfaceGuid = pFilter->InterfaceGuid;
                        NotifEntry->Notif.NotifType = OTLWF_NOTIF_STATE_CHANGE;
                        NotifEntry->Notif.StateChangePayload.Flags = aNotifFlags;

                        otLwfIndicateNotification(NotifEntry);
                    }
                }
            }
            else
            {
                LogWarning(DRIVER_DEFAULT, "Failed to query addresses, %!STATUS!", status);
            }

            if (DataBuffer) FILTER_FREE_MEM(DataBuffer);
        }
        else
        {
            LogWarning(DRIVER_DEFAULT, "Unexpected wait result, %!STATUS!", status);
        }
    }

    PsTerminateSystemThread(STATUS_SUCCESS);
}
Example #9
0
_Use_decl_annotations_
VOID
FilterOidRequestComplete(
    NDIS_HANDLE         FilterModuleContext,
    PNDIS_OID_REQUEST   Request,
    NDIS_STATUS         Status
    )
/*++

Routine Description:

    Notification that an OID request has been completed

    If this filter sends a request down to a lower layer, and the request is
    pended, the FilterOidRequestComplete routine is invoked when the request
    is complete.  Most requests we've sent are simply clones of requests
    received from a higher layer; all we need to do is complete the original
    higher request.

    However, if this filter driver sends original requests down, it must not
    attempt to complete a pending request to the higher layer.

Arguments:

    FilterModuleContext   - our filter context area
    NdisRequest           - the completed request
    Status                - completion status

--*/
{
    PMS_FILTER                          pFilter = (PMS_FILTER)FilterModuleContext;
    PNDIS_OID_REQUEST                   OriginalRequest;
    POTLWF_REQUEST_CONTEXT              Context;
    BOOLEAN                             bFalse = FALSE;

    LogFuncEntryMsg(DRIVER_OID, "Filter: %p, Request %p", FilterModuleContext, Request);

    Context = (POTLWF_REQUEST_CONTEXT)(&Request->SourceReserved[0]);
    OriginalRequest = (*Context);

    //
    // This is an internal request
    //
    if (OriginalRequest == NULL)
    {
        otLwfInternalRequestComplete(pFilter, Request, Status);
        LogFuncExit(DRIVER_OID);
        return;
    }

    FILTER_ACQUIRE_LOCK(&pFilter->PendingOidRequestLock, bFalse);

    ASSERT(pFilter->PendingOidRequest == Request);
    pFilter->PendingOidRequest = NULL;

    FILTER_RELEASE_LOCK(&pFilter->PendingOidRequestLock, bFalse);

    //
    // Copy the information from the returned request to the original request
    //
    switch(Request->RequestType)
    {
        case NdisRequestMethod:
            OriginalRequest->DATA.METHOD_INFORMATION.OutputBufferLength =  Request->DATA.METHOD_INFORMATION.OutputBufferLength;
            OriginalRequest->DATA.METHOD_INFORMATION.BytesRead = Request->DATA.METHOD_INFORMATION.BytesRead;
            OriginalRequest->DATA.METHOD_INFORMATION.BytesNeeded = Request->DATA.METHOD_INFORMATION.BytesNeeded;
            OriginalRequest->DATA.METHOD_INFORMATION.BytesWritten = Request->DATA.METHOD_INFORMATION.BytesWritten;
            break;

        case NdisRequestSetInformation:
            OriginalRequest->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.BytesRead;
            OriginalRequest->DATA.SET_INFORMATION.BytesNeeded = Request->DATA.SET_INFORMATION.BytesNeeded;
            break;

        case NdisRequestQueryInformation:
        case NdisRequestQueryStatistics:
        default:
            OriginalRequest->DATA.QUERY_INFORMATION.BytesWritten = Request->DATA.QUERY_INFORMATION.BytesWritten;
            OriginalRequest->DATA.QUERY_INFORMATION.BytesNeeded = Request->DATA.QUERY_INFORMATION.BytesNeeded;
            break;
    }


    (*Context) = NULL;

    LogVerbose(DRIVER_OID, "Freeing (cloned) Oid Request %p", Request);

    NdisFreeCloneOidRequest(pFilter->FilterHandle, Request);

    LogVerbose(DRIVER_OID, "Completing (external) Oid Request %p", OriginalRequest);

    NdisFOidRequestComplete(pFilter->FilterHandle, OriginalRequest, Status);

    LogFuncExit(DRIVER_OID);
}
Example #10
0
void otPlatSettingsWipe(otInstance *otCtx)
{
    NT_ASSERT(otCtx);
    PMS_FILTER pFilter = otCtxToFilter(otCtx);

    LogFuncEntry(DRIVER_DEFAULT);

    // Delete all subkeys of 'OpenThread'
    if (pFilter->otSettingsRegKey)
    {
        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++;
            }
        }
    }

    LogFuncExit(DRIVER_DEFAULT);
}
Example #11
0
VOID
otLwfEventProcessingStop(
    _In_ PMS_FILTER             pFilter
    )
{
    PLIST_ENTRY Link = NULL;

    LogFuncEntryMsg(DRIVER_DEFAULT, "Filter: %p", pFilter);

    // By this point, we have disabled the Data Path, so no more 
    // NBLs should be queued up.

    // Clean up worker thread
    if (pFilter->EventWorkerThread)
    {
        LogInfo(DRIVER_DEFAULT, "Stopping event processing worker thread and waiting for it to complete.");

        // Send event to shutdown worker thread
        KeSetEvent(&pFilter->EventWorkerThreadStopEvent, 0, FALSE);

        // Wait for worker thread to finish
        KeWaitForSingleObject(
            pFilter->EventWorkerThread,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

        // Free worker thread
        ObDereferenceObject(pFilter->EventWorkerThread);
        pFilter->EventWorkerThread = NULL;

        LogInfo(DRIVER_DEFAULT, "Event processing worker thread cleaned up.");
    }

    // Clean up any left over events
    if (pFilter->AddressChangesHead.Flink)
    {
        Link = pFilter->AddressChangesHead.Flink;
        while (Link != &pFilter->AddressChangesHead)
        {
            POTLWF_ADDR_EVENT Event = CONTAINING_RECORD(Link, OTLWF_ADDR_EVENT, Link);
            Link = Link->Flink;

            // Delete the event
            NdisFreeMemory(Event, 0, 0);
        }
    }

    // Clean up any left over events
    if (pFilter->NBLsHead.Flink)
    {
        Link = pFilter->NBLsHead.Flink;
        while (Link != &pFilter->NBLsHead)
        {
            POTLWF_NBL_EVENT Event = CONTAINING_RECORD(Link, OTLWF_NBL_EVENT, Link);
            Link = Link->Flink;

            otLwfCompleteNBLs(pFilter, FALSE, Event->NetBufferLists, STATUS_CANCELLED);

            // Delete the event
            NdisFreeMemory(Event, 0, 0);
        }
    }

    // Clean up any left over events
    if (pFilter->MacFramesHead.Flink)
    {
        Link = pFilter->MacFramesHead.Flink;
        while (Link != &pFilter->MacFramesHead)
        {
            POTLWF_MAC_FRAME_EVENT Event = CONTAINING_RECORD(Link, OTLWF_MAC_FRAME_EVENT, Link);
            Link = Link->Flink;

            // Delete the event
            NdisFreeMemory(Event, 0, 0);
        }
    }

    // Reinitialize the list head
    InitializeListHead(&pFilter->AddressChangesHead);
    InitializeListHead(&pFilter->NBLsHead);
    InitializeListHead(&pFilter->MacFramesHead);
    
    if (pFilter->EventIrpListHead.Flink)
    {
        FILTER_ACQUIRE_LOCK(&pFilter->EventsLock, FALSE);

        // Clean up any left over IRPs
        Link = pFilter->EventIrpListHead.Flink;
        while (Link != &pFilter->EventIrpListHead)
        {
            PIRP Irp = CONTAINING_RECORD(Link, IRP, Tail.Overlay.ListEntry);
            Link = Link->Flink;
        
            // Before we are allowed to complete the pending IRP, we must remove the cancel routine
            KIRQL irql;
            IoAcquireCancelSpinLock(&irql);
            IoSetCancelRoutine(Irp, NULL);
            IoReleaseCancelSpinLock(irql);

            Irp->IoStatus.Status = STATUS_CANCELLED;
            Irp->IoStatus.Information = 0;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
        }
    
        // Reinitialize the list head
        InitializeListHead(&pFilter->EventIrpListHead);
    
        FILTER_RELEASE_LOCK(&pFilter->EventsLock, FALSE);
    }

    LogFuncExit(DRIVER_DEFAULT);
}