⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 config.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * COPYRIGHT:   See COPYING in the top level directory
 * PROJECT:     ReactOS NDIS library
 * FILE:        ndis/config.c
 * PURPOSE:     NDIS Configuration Services
 * PROGRAMMERS: Vizzini (vizzini@plasmic.com)
 * REVISIONS:
 *     Vizzini 07-28-2003 Created
 * NOTES:
 *     - Resource tracking has to be implemented here because of the design of the NDIS API.
 *       Whenever a read operation is performed, the NDIS library allocates space and returns
 *       it.  A linked list is kept associated with every handle of the memory allocated to
 *       it.  When the handle is closed, the resources are systematically released.
 *     - The NDIS_HANDLE Configuraiton context is no longer a registry handle.  An opaque struct
 *       had to be created to allow for resource tracking.  This means that Miniports cannot just
 *       pass this NDIS_HANDLE to things like ZwQueryValueKey().  I don't thknk they do (they
 *       certainly should not), but it should be kept in mind.
 *         UPDATE:  I just found this in the NTDDK:
 *         NdisOpenProtocolConfiguration returns a handle for the
 *         HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NICDriverInstance\Parameters\ProtocolName
 *         registry key.  XXX This is a problem.  Following that, the DDK instructs programmers
 *         to use NdisReadConfiguration and NdisWriteConfiguration.  No telling what the world's idiots
 *         have done with this.
 *     - I have tried to stick to the DDK's definition of what return values are possible, which
 *       has resulted in stupid return values in some cases.  I do use STATUS_RESOURCES in a few
 *       places that the DDK doesn't explicitly mention it, though.
 *     - There's a general reliance on the fact that UNICODE_STRING.Length doesn't include a trailing
 *       0, which it shouldn't
 *     - I added support for NdisParameterBinary.  It's at the end of the struct.  I wonder if
 *       it'll break things.
 *     - All the routines in this file are PASSIVE_LEVEL only, and all memory is PagedPool
 */

#include "ndissys.h"

#define NDIS_VERSION 0x00040000          /* the version of NDIS we claim to be to miniport drivers */
#define PARAMETERS_KEY L"Parameters"     /* The parameters subkey under the device-specific key */

/*
 * @implemented
 */
VOID
EXPORT
NdisWriteConfiguration(
    OUT PNDIS_STATUS                    Status,
    IN  NDIS_HANDLE                     ConfigurationHandle,
    IN  PNDIS_STRING                    Keyword,
    IN  PNDIS_CONFIGURATION_PARAMETER   ParameterValue)
/*
 * FUNCTION: Writes a configuration value to the registry
 * ARGUMENTS:
 *     Status: Pointer to a caller-supplied NDIS_STATUS where we return status
 *     ConfigurationHandle: The Configuration Handle passed back from the call to one of the Open functions
 *     Keyword: The registry value name to write
 *     ParameterValue: The value data to write
 * RETURNS:
 *     NDIS_STATUS_SUCCESS - the operation completed successfully
 *     NDIS_STATUS_NOT_SUPPORTED - The parameter type is not supported
 *     NDIS_STATUS_RESOURCES - out of memory, etc.
 *     NDIS_STATUS_FAILURE - any other failure
 * NOTES:
 *    There's a cryptic comment in the ddk implying that this function allocates and keeps memory.
 *    I don't know why tho so i free everything before return.  comments welcome.
 */
{
    ULONG ParameterType = ParameterValue->ParameterType;
    ULONG DataSize;
    PVOID Data;
    WCHAR Buff[25]; 

    if(ParameterType != NdisParameterInteger &&
        ParameterType != NdisParameterHexInteger &&
        ParameterType != NdisParameterString &&
        ParameterType != NdisParameterMultiString &&
        ParameterType != NdisParameterBinary
      )
    {
        *Status = NDIS_STATUS_NOT_SUPPORTED;
        return;
    }

    /* reset parameter type to standard reg types */
    switch(ParameterType)
    {        
        case NdisParameterHexInteger:
        case NdisParameterInteger:     
             {                     
                 UNICODE_STRING Str;
                 
                 Str.Buffer = (PWSTR) &Buff;
                 Str.MaximumLength = (USHORT)sizeof(Buff);
                 Str.Length = 0;
                 
                 ParameterType = REG_SZ;
                 if (!NT_SUCCESS(RtlIntegerToUnicodeString(
                      ParameterValue->ParameterData.IntegerData,
                      (ParameterType == NdisParameterInteger) ? 10 : 16, &Str))) 
                 {
                      *Status = NDIS_STATUS_FAILURE;
                      return;
                 }                              
                 Data = Str.Buffer;
                 DataSize = Str.Length;                    
             }
             break;                       
        case NdisParameterString:
        case NdisParameterMultiString:
            ParameterType = REG_SZ;
            Data = ParameterValue->ParameterData.StringData.Buffer;
            DataSize = ParameterValue->ParameterData.StringData.Length;
            break;

        /* New (undocumented) addition to 2k ddk */
        case NdisParameterBinary:
            ParameterType = REG_BINARY;
            Data = ParameterValue->ParameterData.BinaryData.Buffer;
            DataSize = ParameterValue->ParameterData.BinaryData.Length;
            break;

        default:
            *Status = NDIS_STATUS_FAILURE;
            return;
    }

    *Status = ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle)->Handle,
            Keyword, 0, ParameterType, Data, DataSize);

    if(*Status != STATUS_SUCCESS)
        *Status = NDIS_STATUS_FAILURE;
    else
        *Status = NDIS_STATUS_SUCCESS;
}


/*
 * @implemented
 */
VOID
EXPORT
NdisCloseConfiguration(
    IN  NDIS_HANDLE ConfigurationHandle)
/*
 * FUNCTION: Closes handles and releases per-handle resources
 * ARGUMENTS:
 *     ConfigurationHandle - pointer to the context with the resources to free
 */
{
    PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle;
    PMINIPORT_RESOURCE Resource;

    while(!IsListEmpty(&ConfigurationContext->ResourceListHead))
    {
        Resource = (PMINIPORT_RESOURCE)RemoveTailList(&ConfigurationContext->ResourceListHead);
        if(Resource->ResourceType == MINIPORT_RESOURCE_TYPE_MEMORY)
        {
            NDIS_DbgPrint(MAX_TRACE,("freeing 0x%x\n", Resource->Resource));
            ExFreePool(Resource->Resource);
        }

        ExFreePool(Resource);
    }

    ZwClose(ConfigurationContext->Handle);
}


/*
 * @implemented
 */
VOID
EXPORT
NdisOpenConfiguration(
    OUT PNDIS_STATUS    Status,
    OUT PNDIS_HANDLE    ConfigurationHandle,
    IN  NDIS_HANDLE     WrapperConfigurationContext)
/*
 * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
 * ARGUMENTS:
 *     Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
 *     ConfigurationHandle: Pointer to an opaque configuration handle returned on success
 *     WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
 * RETURNS:
 *     NDIS_STATUS_SUCCESS: the operation completed successfully
 *     NDIS_STATUS_FAILURE: the operation failed
 * NOTES:
 *     I think this is the parameters key; please verify.
 */
{
    HANDLE KeyHandle;
    PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext;
    PNDIS_WRAPPER_CONTEXT WrapperContext = (PNDIS_WRAPPER_CONTEXT)WrapperConfigurationContext;
    HANDLE RootKeyHandle = WrapperContext->RegistryHandle;

    NDIS_DbgPrint(MAX_TRACE, ("Called\n"));

    *Status = ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle,
                                NtCurrentProcess(), &KeyHandle, 0, 0,
                                DUPLICATE_SAME_ACCESS);
    if(!NT_SUCCESS(*Status))
    {
        NDIS_DbgPrint(MID_TRACE, ("Failed to open registry configuration for this miniport\n"));
        *ConfigurationHandle = NULL;
        *Status = NDIS_STATUS_FAILURE;
        return;
    }

    ConfigurationContext = ExAllocatePool(PagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT));
    if(!ConfigurationContext)
    {
        NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
        ZwClose(KeyHandle);
        *Status = NDIS_STATUS_RESOURCES;
        return;
    }

    KeInitializeSpinLock(&ConfigurationContext->ResourceLock);
    InitializeListHead(&ConfigurationContext->ResourceListHead);

    ConfigurationContext->Handle = KeyHandle;

    *ConfigurationHandle = (NDIS_HANDLE)ConfigurationContext;
    *Status = NDIS_STATUS_SUCCESS;

    NDIS_DbgPrint(MAX_TRACE,("returning success\n"));
}


/*
 * @implemented
 */
VOID
EXPORT
NdisOpenProtocolConfiguration(
    OUT PNDIS_STATUS    Status,
    OUT PNDIS_HANDLE    ConfigurationHandle,
    IN  PNDIS_STRING    ProtocolSection)
/*
 * FUNCTION: Open the configuration key and set up resource tracking for the protocol
 * ARGUMENTS:
 *     Status: caller-allocated buffer where status is returned
 *     ConfigurationHandle: spot to return the opaque configuration context
 *     ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
 * RETURNS:
 *     NDIS_STATUS_SUCCESS: the operation was a success
 *     NDIS_STATUS_FAILURE: the operation was not a success
 * NOTES:
 *     I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
 */
{
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING KeyNameU;
    HANDLE KeyHandle;
    PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext;

    KeyNameU.Length = 0;
    KeyNameU.MaximumLength = ProtocolSection->Length + sizeof(PARAMETERS_KEY) + sizeof(UNICODE_NULL);
    KeyNameU.Buffer = ExAllocatePool(PagedPool, KeyNameU.MaximumLength);
    if(!KeyNameU.Buffer)
    {
        NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
        *ConfigurationHandle = NULL;
        *Status = NDIS_STATUS_FAILURE;
        return;
    }

    RtlCopyUnicodeString(&KeyNameU, ProtocolSection);
    RtlAppendUnicodeToString(&KeyNameU, PARAMETERS_KEY);
    InitializeObjectAttributes(&KeyAttributes, &KeyNameU, OBJ_CASE_INSENSITIVE, NULL, NULL);

    *Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &KeyAttributes);

    ExFreePool(KeyNameU.Buffer);

    if(*Status != NDIS_STATUS_SUCCESS)
    {
        *ConfigurationHandle = NULL;
        *Status = NDIS_STATUS_FAILURE;
        return;
    }

    ConfigurationContext = ExAllocatePool(PagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT));
    if(!ConfigurationContext)
    {
        NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
        *ConfigurationHandle = NULL;
        *Status = NDIS_STATUS_FAILURE;
        return;
    }

    KeInitializeSpinLock(&ConfigurationContext->ResourceLock);
    InitializeListHead(&ConfigurationContext->ResourceListHead);

    ConfigurationContext->Handle = KeyHandle;

    *ConfigurationHandle = (NDIS_HANDLE)ConfigurationContext;
    *Status = NDIS_STATUS_SUCCESS;
}


/*
 * @implemented
 */
VOID
EXPORT
NdisReadConfiguration(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -