ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

config.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:   See COPYING in the top level directory
00003  * PROJECT:     ReactOS NDIS library
00004  * FILE:        ndis/config.c
00005  * PURPOSE:     NDIS Configuration Services
00006  * PROGRAMMERS: Vizzini (vizzini@plasmic.com)
00007  * REVISIONS:
00008  *     Vizzini 07-28-2003 Created
00009  * NOTES:
00010  *     - Resource tracking has to be implemented here because of the design of the NDIS API.
00011  *       Whenever a read operation is performed, the NDIS library allocates space and returns
00012  *       it.  A linked list is kept associated with every handle of the memory allocated to
00013  *       it.  When the handle is closed, the resources are systematically released.
00014  *     - The NDIS_HANDLE Configuraiton context is no longer a registry handle.  An opaque struct
00015  *       had to be created to allow for resource tracking.  This means that Miniports cannot just
00016  *       pass this NDIS_HANDLE to things like ZwQueryValueKey().  I don't thknk they do (they
00017  *       certainly should not), but it should be kept in mind.
00018  *         UPDATE:  I just found this in the NTDDK:
00019  *         NdisOpenProtocolConfiguration returns a handle for the
00020  *         HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NICDriverInstance\Parameters\ProtocolName
00021  *         registry key.  XXX This is a problem.  Following that, the DDK instructs programmers
00022  *         to use NdisReadConfiguration and NdisWriteConfiguration.  No telling what the world's idiots
00023  *         have done with this.
00024  *     - I have tried to stick to the DDK's definition of what return values are possible, which
00025  *       has resulted in stupid return values in some cases.  I do use STATUS_RESOURCES in a few
00026  *       places that the DDK doesn't explicitly mention it, though.
00027  *     - There's a general reliance on the fact that UNICODE_STRING.Length doesn't include a trailing
00028  *       0, which it shouldn't
00029  *     - I added support for NdisParameterBinary.  It's at the end of the struct.  I wonder if
00030  *       it'll break things.
00031  *     - All the routines in this file are PASSIVE_LEVEL only, and all memory is PagedPool
00032  */
00033 
00034 #include "ndissys.h"
00035 
00036 #define PARAMETERS_KEY L"Parameters"     /* The parameters subkey under the device-specific key */
00037 
00038 /*
00039  * @implemented
00040  */
00041 VOID
00042 EXPORT
00043 NdisWriteConfiguration(
00044     OUT PNDIS_STATUS                    Status,
00045     IN  NDIS_HANDLE                     ConfigurationHandle,
00046     IN  PNDIS_STRING                    Keyword,
00047     IN  PNDIS_CONFIGURATION_PARAMETER   ParameterValue)
00048 /*
00049  * FUNCTION: Writes a configuration value to the registry
00050  * ARGUMENTS:
00051  *     Status: Pointer to a caller-supplied NDIS_STATUS where we return status
00052  *     ConfigurationHandle: The Configuration Handle passed back from the call to one of the Open functions
00053  *     Keyword: The registry value name to write
00054  *     ParameterValue: The value data to write
00055  * RETURNS:
00056  *     NDIS_STATUS_SUCCESS - the operation completed successfully
00057  *     NDIS_STATUS_NOT_SUPPORTED - The parameter type is not supported
00058  *     NDIS_STATUS_RESOURCES - out of memory, etc.
00059  *     NDIS_STATUS_FAILURE - any other failure
00060  * NOTES:
00061  *    There's a cryptic comment in the ddk implying that this function allocates and keeps memory.
00062  *    I don't know why tho so i free everything before return.  comments welcome.
00063  */
00064 {
00065     ULONG ParameterType;
00066     ULONG DataSize;
00067     PVOID Data;
00068     WCHAR Buff[11];
00069 
00070     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
00071     
00072     NDIS_DbgPrint(MID_TRACE, ("Parameter type: %d\n", ParameterValue->ParameterType));
00073 
00074     /* reset parameter type to standard reg types */
00075     switch(ParameterValue->ParameterType)
00076     {
00077         case NdisParameterHexInteger:
00078         case NdisParameterInteger:
00079              {
00080                  UNICODE_STRING Str;
00081 
00082                  Str.Buffer = (PWSTR) &Buff;
00083                  Str.MaximumLength = (USHORT)sizeof(Buff);
00084                  Str.Length = 0;
00085 
00086                  ParameterType = REG_SZ;
00087                  if (!NT_SUCCESS(RtlIntegerToUnicodeString(
00088                       ParameterValue->ParameterData.IntegerData,
00089                       (ParameterValue->ParameterType == NdisParameterInteger) ? 10 : 16, &Str)))
00090                  {
00091                       NDIS_DbgPrint(MIN_TRACE, ("RtlIntegerToUnicodeString failed (%x)\n", *Status));
00092                       *Status = NDIS_STATUS_FAILURE;
00093                       return;
00094                  }
00095                  Data = Str.Buffer;
00096                  DataSize = Str.Length;
00097              }
00098              break;
00099         case NdisParameterString:
00100         case NdisParameterMultiString:
00101             ParameterType = (ParameterValue->ParameterType == NdisParameterString) ? REG_SZ : REG_MULTI_SZ;
00102             Data = ParameterValue->ParameterData.StringData.Buffer;
00103             DataSize = ParameterValue->ParameterData.StringData.Length;
00104             break;
00105 
00106         /* New (undocumented) addition to 2k ddk */
00107         case NdisParameterBinary:
00108             ParameterType = REG_BINARY;
00109             Data = ParameterValue->ParameterData.BinaryData.Buffer;
00110             DataSize = ParameterValue->ParameterData.BinaryData.Length;
00111             break;
00112 
00113         default:
00114             *Status = NDIS_STATUS_NOT_SUPPORTED;
00115             return;
00116     }
00117 
00118     *Status = ZwSetValueKey(((PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle)->Handle,
00119             Keyword, 0, ParameterType, Data, DataSize);
00120 
00121     if(*Status != STATUS_SUCCESS) {
00122         NDIS_DbgPrint(MIN_TRACE, ("ZwSetValueKey failed (%x)\n", *Status));
00123         *Status = NDIS_STATUS_FAILURE;
00124     } else
00125         *Status = NDIS_STATUS_SUCCESS;
00126 }
00127 
00128 
00129 /*
00130  * @implemented
00131  */
00132 VOID
00133 EXPORT
00134 NdisCloseConfiguration(
00135     IN  NDIS_HANDLE ConfigurationHandle)
00136 /*
00137  * FUNCTION: Closes handles and releases per-handle resources
00138  * ARGUMENTS:
00139  *     ConfigurationHandle - pointer to the context with the resources to free
00140  */
00141 {
00142     PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle;
00143     PMINIPORT_RESOURCE Resource;
00144     PNDIS_CONFIGURATION_PARAMETER ParameterValue;
00145     PLIST_ENTRY CurrentEntry;
00146 
00147     while((CurrentEntry = ExInterlockedRemoveHeadList(&ConfigurationContext->ResourceListHead,
00148                                                       &ConfigurationContext->ResourceLock)) != NULL)
00149     {
00150         Resource = CONTAINING_RECORD(CurrentEntry, MINIPORT_RESOURCE, ListEntry);
00151         switch(Resource->ResourceType)
00152         {
00153           case MINIPORT_RESOURCE_TYPE_REGISTRY_DATA:
00154             ParameterValue = Resource->Resource;
00155 
00156             switch (ParameterValue->ParameterType)
00157             {
00158                case NdisParameterBinary:
00159                  ExFreePool(ParameterValue->ParameterData.BinaryData.Buffer);
00160                  break;
00161 
00162                case NdisParameterString:
00163                case NdisParameterMultiString:
00164                  ExFreePool(ParameterValue->ParameterData.StringData.Buffer);
00165                  break;
00166 
00167                default:
00168                  break;
00169             }
00170 
00171           /* Fall through to free NDIS_CONFIGURATION_PARAMETER struct */
00172 
00173           case MINIPORT_RESOURCE_TYPE_MEMORY:
00174             NDIS_DbgPrint(MAX_TRACE,("freeing 0x%x\n", Resource->Resource));
00175             ExFreePool(Resource->Resource);
00176             break;
00177 
00178           default:
00179             NDIS_DbgPrint(MIN_TRACE,("Unknown resource type: %d\n", Resource->ResourceType));
00180             break;
00181         }
00182 
00183         ExFreePool(Resource);
00184     }
00185 
00186     ZwClose(ConfigurationContext->Handle);
00187 }
00188 
00189 
00190 /*
00191  * @implemented
00192  */
00193 VOID
00194 EXPORT
00195 NdisOpenConfiguration(
00196     OUT PNDIS_STATUS    Status,
00197     OUT PNDIS_HANDLE    ConfigurationHandle,
00198     IN  NDIS_HANDLE     WrapperConfigurationContext)
00199 /*
00200  * FUNCTION: Opens the configuration key and sets up resource tracking for the returned handle
00201  * ARGUMENTS:
00202  *     Status: Pointer to a caller-supplied NDIS_STATUS that is filled in with a return value
00203  *     ConfigurationHandle: Pointer to an opaque configuration handle returned on success
00204  *     WrapperConfigurationContext: handle originally passed back from NdisInitializeWrapper
00205  * RETURNS:
00206  *     NDIS_STATUS_SUCCESS: the operation completed successfully
00207  *     NDIS_STATUS_FAILURE: the operation failed
00208  * NOTES:
00209  *     I think this is the parameters key; please verify.
00210  */
00211 {
00212     HANDLE KeyHandle;
00213     PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext;
00214     PNDIS_WRAPPER_CONTEXT WrapperContext = (PNDIS_WRAPPER_CONTEXT)WrapperConfigurationContext;
00215     HANDLE RootKeyHandle = WrapperContext->RegistryHandle;
00216 
00217     NDIS_DbgPrint(MAX_TRACE, ("Called\n"));
00218 
00219     *ConfigurationHandle = NULL;
00220 
00221     *Status = ZwDuplicateObject(NtCurrentProcess(), RootKeyHandle,
00222                                 NtCurrentProcess(), &KeyHandle, 0, 0,
00223                                 DUPLICATE_SAME_ACCESS);
00224     if(!NT_SUCCESS(*Status))
00225     {
00226         NDIS_DbgPrint(MIN_TRACE, ("Failed to open registry configuration for this miniport\n"));
00227         *Status = NDIS_STATUS_FAILURE;
00228         return;
00229     }
00230 
00231     ConfigurationContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT));
00232     if(!ConfigurationContext)
00233     {
00234         NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00235         ZwClose(KeyHandle);
00236         *Status = NDIS_STATUS_RESOURCES;
00237         return;
00238     }
00239 
00240     KeInitializeSpinLock(&ConfigurationContext->ResourceLock);
00241     InitializeListHead(&ConfigurationContext->ResourceListHead);
00242 
00243     ConfigurationContext->Handle = KeyHandle;
00244 
00245     *ConfigurationHandle = (NDIS_HANDLE)ConfigurationContext;
00246     *Status = NDIS_STATUS_SUCCESS;
00247 
00248     NDIS_DbgPrint(MAX_TRACE,("returning success\n"));
00249 }
00250 
00251 
00252 /*
00253  * @implemented
00254  */
00255 VOID
00256 EXPORT
00257 NdisOpenProtocolConfiguration(
00258     OUT PNDIS_STATUS    Status,
00259     OUT PNDIS_HANDLE    ConfigurationHandle,
00260     IN  PNDIS_STRING    ProtocolSection)
00261 /*
00262  * FUNCTION: Open the configuration key and set up resource tracking for the protocol
00263  * ARGUMENTS:
00264  *     Status: caller-allocated buffer where status is returned
00265  *     ConfigurationHandle: spot to return the opaque configuration context
00266  *     ProtocolSection: configuration string originally passed in to ProtocolBindAdapter
00267  * RETURNS:
00268  *     NDIS_STATUS_SUCCESS: the operation was a success
00269  *     NDIS_STATUS_FAILURE: the operation was not a success
00270  * NOTES:
00271  *     I think this is the per-device (adapter) parameters\{ProtocolName} key; please verify.
00272  */
00273 {
00274     OBJECT_ATTRIBUTES KeyAttributes;
00275     UNICODE_STRING KeyNameU;
00276     HANDLE KeyHandle;
00277     PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext;
00278 
00279     KeyNameU.Length = 0;
00280     KeyNameU.MaximumLength = ProtocolSection->Length + sizeof(PARAMETERS_KEY) + sizeof(UNICODE_NULL);
00281     KeyNameU.Buffer = ExAllocatePool(PagedPool, KeyNameU.MaximumLength);
00282     if(!KeyNameU.Buffer)
00283     {
00284         NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00285         *ConfigurationHandle = NULL;
00286         *Status = NDIS_STATUS_FAILURE;
00287         return;
00288     }
00289 
00290     RtlCopyUnicodeString(&KeyNameU, ProtocolSection);
00291     RtlAppendUnicodeToString(&KeyNameU, PARAMETERS_KEY);
00292     InitializeObjectAttributes(&KeyAttributes, &KeyNameU, OBJ_CASE_INSENSITIVE, NULL, NULL);
00293 
00294     *Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &KeyAttributes);
00295 
00296     ExFreePool(KeyNameU.Buffer);
00297 
00298     if(*Status != NDIS_STATUS_SUCCESS)
00299     {
00300         NDIS_DbgPrint(MIN_TRACE, ("ZwOpenKey failed (%x)\n", *Status));
00301         *ConfigurationHandle = NULL;
00302         *Status = NDIS_STATUS_FAILURE;
00303         return;
00304     }
00305 
00306     ConfigurationContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT));
00307     if(!ConfigurationContext)
00308     {
00309         NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00310         ZwClose(KeyHandle);
00311         *ConfigurationHandle = NULL;
00312         *Status = NDIS_STATUS_FAILURE;
00313         return;
00314     }
00315 
00316     KeInitializeSpinLock(&ConfigurationContext->ResourceLock);
00317     InitializeListHead(&ConfigurationContext->ResourceListHead);
00318 
00319     ConfigurationContext->Handle = KeyHandle;
00320 
00321     *ConfigurationHandle = (NDIS_HANDLE)ConfigurationContext;
00322     *Status = NDIS_STATUS_SUCCESS;
00323 }
00324 
00325 UCHAR UnicodeToHexByte(WCHAR chr)
00326 /*
00327  * FUNCTION: Converts a unicode hex character to its numerical value
00328  * ARGUMENTS:
00329  *     chr: Unicode character to convert
00330  * RETURNS:
00331  *     The numerical value of chr
00332  */
00333 {
00334     switch(chr)
00335     {
00336         case L'0': return 0;
00337         case L'1': return 1;
00338         case L'2': return 2;
00339         case L'3': return 3;
00340         case L'4': return 4;
00341         case L'5': return 5;
00342         case L'6': return 6;
00343         case L'7': return 7;
00344         case L'8': return 8;
00345         case L'9': return 9;
00346         case L'A':
00347         case L'a':
00348             return 10;
00349         case L'B':
00350         case L'b':
00351             return 11;
00352         case L'C':
00353         case L'c':
00354             return 12;
00355         case L'D':
00356         case L'd':
00357             return 13;
00358         case L'E':
00359         case L'e':
00360             return 14;
00361         case L'F':
00362         case L'f':
00363             return 15;
00364     }
00365     return 0xFF;
00366 }
00367 
00368 BOOLEAN
00369 IsValidNumericString(PNDIS_STRING String, ULONG Base)
00370 /*
00371  * FUNCTION: Determines if a string is a valid number
00372  * ARGUMENTS:
00373  *     String: Unicode string to evaluate
00374  * RETURNS:
00375  *     TRUE if it is valid, FALSE if not
00376  */
00377 {
00378     ULONG i;
00379 
00380     /* I don't think this will ever happen, but we warn it if it does */
00381     if (String->Length == 0)
00382     {
00383         NDIS_DbgPrint(MIN_TRACE, ("Got an empty string; not sure what to do here\n"));
00384         return FALSE;
00385     }
00386 
00387     for (i = 0; i < String->Length / sizeof(WCHAR); i++)
00388     {
00389         /* Skip any NULL characters we find */
00390         if (String->Buffer[i] == UNICODE_NULL)
00391             continue;
00392 
00393         /* Make sure the character is valid for a numeric string of this base */
00394         if (UnicodeToHexByte(String->Buffer[i]) >= Base)
00395             return FALSE;
00396     }
00397 
00398     /* It's valid */
00399     return TRUE;
00400 }
00401 
00402 /*
00403  * @implemented
00404  */
00405 VOID
00406 EXPORT
00407 NdisReadConfiguration(
00408     OUT PNDIS_STATUS                    Status,
00409     OUT PNDIS_CONFIGURATION_PARAMETER   * ParameterValue,
00410     IN  NDIS_HANDLE                     ConfigurationHandle,
00411     IN  PNDIS_STRING                    Keyword,
00412     IN  NDIS_PARAMETER_TYPE             ParameterType)
00413 /*
00414  * FUNCTION: Read a configuration value from the registry, tracking its resources
00415  * ARGUMENTS:
00416  *     Status: points to a place to write status into
00417  *     ParameterValue: Pointer to receive a newly-allocated parameter structure
00418  *     ConfigurationHandle: handle originally returned by an open function
00419  *     Keyword: Value name to read, or one of the following constants:
00420  *       Environment - returns NdisEnvironmentWindowsNt
00421  *       ProcessorType - returns NdisProcessorX86 until more architectures are added
00422  *       NdisVersion - returns NDIS_VERSION
00423  *     ParameterType: the type of the value to be queried
00424  * RETURNS:
00425  *     - A status in Status
00426  *     - A parameter value in ParameterValue
00427  */
00428 {
00429     KEY_VALUE_PARTIAL_INFORMATION *KeyInformation;
00430     ULONG KeyDataLength;
00431     PMINIPORT_RESOURCE MiniportResource;
00432     PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle;
00433     PVOID Buffer;
00434 
00435     *ParameterValue = NULL;
00436     *Status = NDIS_STATUS_FAILURE;
00437 
00438     NDIS_DbgPrint(MAX_TRACE,("requested read of %wZ\n", Keyword));
00439     NDIS_DbgPrint(MID_TRACE,("requested parameter type: %d\n", ParameterType));
00440 
00441     if (ConfigurationContext == NULL)
00442     {
00443        NDIS_DbgPrint(MIN_TRACE,("invalid parameter ConfigurationContext (0x%x)\n",ConfigurationContext));
00444        return;
00445     }
00446 
00447     if(!wcsncmp(Keyword->Buffer, L"Environment", Keyword->Length/sizeof(WCHAR)) &&
00448         wcslen(L"Environment") == Keyword->Length/sizeof(WCHAR))
00449     {
00450         *ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER));
00451         if(!*ParameterValue)
00452         {
00453             NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00454             *Status = NDIS_STATUS_RESOURCES;
00455             return;
00456         }
00457 
00458         MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE));
00459         if(!MiniportResource)
00460         {
00461             NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00462             ExFreePool(*ParameterValue);
00463             *ParameterValue = NULL;
00464             *Status = NDIS_STATUS_RESOURCES;
00465             return;
00466         }
00467 
00468         MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_REGISTRY_DATA;
00469         MiniportResource->Resource = *ParameterValue;
00470 
00471         NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n",
00472             MiniportResource->Resource));
00473 
00474         ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead,
00475             &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock);
00476 
00477         (*ParameterValue)->ParameterType = NdisParameterInteger;
00478         (*ParameterValue)->ParameterData.IntegerData = NdisEnvironmentWindowsNt;
00479         *Status = NDIS_STATUS_SUCCESS;
00480 
00481         return;
00482     }
00483 
00484     if(!wcsncmp(Keyword->Buffer, L"ProcessorType", Keyword->Length/sizeof(WCHAR)) &&
00485         wcslen(L"ProcessorType") == Keyword->Length/sizeof(WCHAR))
00486     {
00487         *ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER));
00488         if(!*ParameterValue)
00489         {
00490             NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00491             *Status = NDIS_STATUS_RESOURCES;
00492             return;
00493         }
00494 
00495         MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE));
00496         if(!MiniportResource)
00497         {
00498             NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00499             ExFreePool(*ParameterValue);
00500             *ParameterValue = NULL;
00501             *Status = NDIS_STATUS_RESOURCES;
00502             return;
00503         }
00504 
00505         MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_REGISTRY_DATA;
00506         MiniportResource->Resource = *ParameterValue;
00507         NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", MiniportResource->Resource));
00508         ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead,
00509             &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock);
00510 
00511         (*ParameterValue)->ParameterType = NdisParameterInteger;
00512         (*ParameterValue)->ParameterData.IntegerData = NdisProcessorX86;    /* XXX non-portable */
00513         *Status = NDIS_STATUS_SUCCESS;
00514 
00515         return;
00516     }
00517 
00518     if(!wcsncmp(Keyword->Buffer, L"NdisVersion", Keyword->Length/sizeof(WCHAR)) &&
00519         wcslen(L"NdisVersion") == Keyword->Length/sizeof(WCHAR))
00520     {
00521         *ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER));
00522         if(!*ParameterValue)
00523         {
00524             NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00525             *Status = NDIS_STATUS_RESOURCES;
00526             return;
00527         }
00528 
00529         MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE));
00530         if(!MiniportResource)
00531         {
00532             NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00533             ExFreePool(*ParameterValue);
00534             *ParameterValue = NULL;
00535             *Status = NDIS_STATUS_RESOURCES;
00536             return;
00537         }
00538 
00539         MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_REGISTRY_DATA;
00540         MiniportResource->Resource = *ParameterValue;
00541         NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", MiniportResource->Resource));
00542         ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead,
00543             &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock);
00544 
00545         (*ParameterValue)->ParameterType = NdisParameterInteger;
00546         (*ParameterValue)->ParameterData.IntegerData = NDIS_VERSION;
00547         *Status = NDIS_STATUS_SUCCESS;
00548 
00549         NDIS_DbgPrint(MAX_TRACE,("ParameterType = %0x%x, ParameterValue = 0x%x\n",
00550             (*ParameterValue)->ParameterType, (*ParameterValue)->ParameterData.IntegerData));
00551         return;
00552     }
00553 
00554     /* figure out how much buffer i should allocate */
00555     *Status = ZwQueryValueKey(ConfigurationContext->Handle, Keyword, KeyValuePartialInformation, NULL, 0, &KeyDataLength);
00556     if(*Status != STATUS_BUFFER_OVERFLOW && *Status != STATUS_BUFFER_TOO_SMALL && *Status != STATUS_SUCCESS)
00557     {
00558         NDIS_DbgPrint(MID_TRACE,("ZwQueryValueKey #1 failed for %wZ, status 0x%x\n", Keyword, *Status));
00559         *Status = NDIS_STATUS_FAILURE;
00560         return;
00561     }
00562 
00563     /* allocate it */
00564     KeyInformation = ExAllocatePool(PagedPool, KeyDataLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION));
00565     if(!KeyInformation)
00566     {
00567         NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00568         *Status = NDIS_STATUS_RESOURCES;
00569         return;
00570     }
00571 
00572     /* grab the value */
00573     *Status = ZwQueryValueKey(ConfigurationContext->Handle, Keyword, KeyValuePartialInformation,
00574         KeyInformation, KeyDataLength + sizeof(KEY_VALUE_PARTIAL_INFORMATION), &KeyDataLength);
00575     if(*Status != STATUS_SUCCESS)
00576     {
00577         ExFreePool(KeyInformation);
00578         NDIS_DbgPrint(MIN_TRACE,("ZwQueryValueKey #2 failed for %wZ, status 0x%x\n", Keyword, *Status));
00579         *Status = NDIS_STATUS_FAILURE;
00580         return;
00581     }
00582 
00583     MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE));
00584     if(!MiniportResource)
00585     {
00586        NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00587        ExFreePool(KeyInformation);
00588        *Status = NDIS_STATUS_RESOURCES;
00589        return;
00590     }
00591 
00592     *ParameterValue = ExAllocatePool(PagedPool, sizeof(NDIS_CONFIGURATION_PARAMETER));
00593     if (!*ParameterValue)
00594     {
00595         NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
00596         ExFreePool(MiniportResource);
00597         ExFreePool(KeyInformation);
00598         *Status = NDIS_STATUS_RESOURCES;
00599         return;
00600     }
00601 
00602     RtlZeroMemory(*ParameterValue, sizeof(NDIS_CONFIGURATION_PARAMETER));
00603 
00604     if (KeyInformation->Type == REG_BINARY)
00605     {
00606         NDIS_DbgPrint(MAX_TRACE, ("NdisParameterBinary\n"));
00607 
00608         (*ParameterValue)->ParameterType = NdisParameterBinary;
00609 
00610         Buffer = ExAllocatePool(PagedPool, KeyInformation->DataLength);
00611         if (!Buffer)
00612         {
00613             NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
00614             ExFreePool(MiniportResource);
00615             ExFreePool(KeyInformation);
00616             *Status = NDIS_STATUS_RESOURCES;
00617             return;
00618         }
00619 
00620         RtlCopyMemory(Buffer, KeyInformation->Data, KeyInformation->DataLength);
00621 
00622         (*ParameterValue)->ParameterData.BinaryData.Buffer = Buffer;
00623         (*ParameterValue)->ParameterData.BinaryData.Length = KeyInformation->DataLength;
00624     }
00625     else if (KeyInformation->Type == REG_MULTI_SZ)
00626     {
00627         NDIS_DbgPrint(MAX_TRACE, ("NdisParameterMultiString\n"));
00628 
00629         (*ParameterValue)->ParameterType = NdisParameterMultiString;
00630 
00631         Buffer = ExAllocatePool(PagedPool, KeyInformation->DataLength);
00632         if (!Buffer)
00633         {
00634             NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
00635             ExFreePool(MiniportResource);
00636             ExFreePool(KeyInformation);
00637             *Status = NDIS_STATUS_RESOURCES;
00638             return;
00639         }
00640 
00641         RtlCopyMemory(Buffer, KeyInformation->Data, KeyInformation->DataLength);
00642 
00643         (*ParameterValue)->ParameterData.StringData.Buffer = Buffer;
00644         (*ParameterValue)->ParameterData.StringData.Length = KeyInformation->DataLength;
00645     }
00646     else if (KeyInformation->Type == REG_SZ)
00647     {
00648          UNICODE_STRING str;
00649          ULONG Base;
00650         
00651          if (ParameterType == NdisParameterInteger)
00652              Base = 10;
00653          else if (ParameterType == NdisParameterHexInteger)
00654              Base = 16;
00655          else
00656              Base = 0;
00657 
00658          str.Length = str.MaximumLength = (USHORT)KeyInformation->DataLength;
00659          str.Buffer = (PWCHAR)KeyInformation->Data;
00660 
00661          if (Base != 0 && IsValidNumericString(&str, Base) &&
00662              ((*Status = RtlUnicodeStringToInteger(&str, Base,
00663                              &(*ParameterValue)->ParameterData.IntegerData)) == STATUS_SUCCESS))
00664          {
00665              NDIS_DbgPrint(MAX_TRACE, ("NdisParameter(Hex)Integer\n"));
00666 
00667              (*ParameterValue)->ParameterType = ParameterType;
00668          }
00669          else
00670          {
00671              NDIS_DbgPrint(MAX_TRACE, ("NdisParameterString\n"));
00672 
00673              (*ParameterValue)->ParameterType = NdisParameterString;
00674 
00675              Buffer = ExAllocatePool(PagedPool, KeyInformation->DataLength);
00676              if (!Buffer)
00677              {
00678                  NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
00679                  ExFreePool(MiniportResource);
00680                  ExFreePool(KeyInformation);
00681                  *Status = NDIS_STATUS_RESOURCES;
00682                  return;
00683              }
00684 
00685              RtlCopyMemory(Buffer, KeyInformation->Data, KeyInformation->DataLength);
00686 
00687              (*ParameterValue)->ParameterData.StringData.Buffer = Buffer;
00688              (*ParameterValue)->ParameterData.StringData.Length = KeyInformation->DataLength;
00689          }
00690     }
00691     else
00692     {
00693         NDIS_DbgPrint(MIN_TRACE, ("Invalid type for NdisReadConfiguration (%d)\n", KeyInformation->Type));
00694         NDIS_DbgPrint(MIN_TRACE, ("Requested type: %d\n", ParameterType));
00695         NDIS_DbgPrint(MIN_TRACE, ("Registry entry: %wZ\n", Keyword));
00696         *Status = NDIS_STATUS_FAILURE;
00697         ExFreePool(KeyInformation);
00698         return;
00699     }
00700     
00701     if ((*ParameterValue)->ParameterType != ParameterType)
00702     {
00703         NDIS_DbgPrint(MIN_TRACE, ("Parameter type mismatch! (Requested: %d | Received: %d)\n",
00704                                   ParameterType, (*ParameterValue)->ParameterType));
00705         NDIS_DbgPrint(MIN_TRACE, ("Registry entry: %wZ\n", Keyword));
00706     }
00707 
00708     MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_REGISTRY_DATA;
00709     MiniportResource->Resource = *ParameterValue;
00710 
00711     ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock);
00712 
00713     ExFreePool(KeyInformation);
00714 
00715     *Status = NDIS_STATUS_SUCCESS;
00716 }
00717 
00718 /*
00719  * @implemented
00720  */
00721 VOID
00722 EXPORT
00723 NdisReadNetworkAddress(
00724     OUT PNDIS_STATUS    Status,
00725     OUT PVOID           * NetworkAddress,
00726     OUT PUINT           NetworkAddressLength,
00727     IN  NDIS_HANDLE     ConfigurationHandle)
00728 /*
00729  * FUNCTION: Reads the network address from the registry
00730  * ARGUMENTS:
00731  *     Status - variable to receive status
00732  *     NetworkAddress - pointer to a buffered network address array
00733  *     NetworkAddressLength - length of the NetworkAddress array
00734  *     ConfigurationHandle: handle passed back from one of the open routines
00735  * RETURNS:
00736  *     NDIS_STATUS_SUCCESS on success
00737  *     NDIS_STATUS_FAILURE on failure
00738  *     The network address is placed in the NetworkAddress buffer
00739  */
00740 {
00741     PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext = (PMINIPORT_CONFIGURATION_CONTEXT)ConfigurationHandle;
00742     PMINIPORT_RESOURCE MiniportResource = NULL;
00743     PNDIS_CONFIGURATION_PARAMETER ParameterValue = NULL;
00744     NDIS_STRING Keyword;
00745     UINT *IntArray = 0;
00746     UINT i,j = 0;
00747     NDIS_STRING str;
00748 
00749     NdisInitUnicodeString(&Keyword, L"NetworkAddress");
00750     NdisReadConfiguration(Status, &ParameterValue, ConfigurationHandle, &Keyword, NdisParameterString);
00751     if(*Status != NDIS_STATUS_SUCCESS)
00752     {
00753         NDIS_DbgPrint(MID_TRACE, ("NdisReadConfiguration failed (%x)\n", *Status));
00754         *Status = NDIS_STATUS_FAILURE;
00755         return;
00756     }
00757 
00758     if (ParameterValue->ParameterType == NdisParameterInteger)
00759     {
00760         WCHAR Buff[11];
00761 
00762         NDIS_DbgPrint(MAX_TRACE, ("Read integer data %lx\n",
00763                                   ParameterValue->ParameterData.IntegerData));
00764 
00765         str.Buffer = Buff;
00766         str.MaximumLength = (USHORT)sizeof(Buff);
00767         str.Length = 0;
00768 
00769         *Status = RtlIntegerToUnicodeString(ParameterValue->ParameterData.IntegerData,
00770                                             10,
00771                                             &str);
00772 
00773         if (*Status != NDIS_STATUS_SUCCESS)
00774         {
00775             NDIS_DbgPrint(MIN_TRACE, ("RtlIntegerToUnicodeString failed (%x)\n", *Status));
00776             *Status = NDIS_STATUS_FAILURE;
00777             return;
00778         }
00779 
00780         NDIS_DbgPrint(MAX_TRACE, ("Converted integer data into %wZ\n", &str));
00781     }
00782     else
00783     {
00784         ASSERT(ParameterValue->ParameterType == NdisParameterString);
00785         str = ParameterValue->ParameterData.StringData;
00786     }
00787 
00788     while (j < str.Length && str.Buffer[j] != '\0') j++;
00789     
00790     *NetworkAddressLength = (j+1) >> 1;
00791 
00792     if ((*NetworkAddressLength) == 0)
00793     {
00794         NDIS_DbgPrint(MIN_TRACE,("Empty NetworkAddress registry entry.\n"));
00795         *Status = NDIS_STATUS_FAILURE;
00796         return;
00797     }
00798 
00799     IntArray = ExAllocatePool(PagedPool, (*NetworkAddressLength)*sizeof(UINT));
00800     if(!IntArray)
00801     {
00802         NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00803         *Status = NDIS_STATUS_RESOURCES;
00804         return;
00805     }
00806 
00807     MiniportResource = ExAllocatePool(PagedPool, sizeof(MINIPORT_RESOURCE));
00808     if(!MiniportResource)
00809     {
00810         NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00811         ExFreePool(IntArray);
00812         *Status = NDIS_STATUS_RESOURCES;
00813         return;
00814     }
00815 
00816     MiniportResource->ResourceType = MINIPORT_RESOURCE_TYPE_MEMORY;
00817     MiniportResource->Resource = IntArray;
00818     NDIS_DbgPrint(MID_TRACE,("inserting 0x%x into the resource list\n", MiniportResource->Resource));
00819     ExInterlockedInsertTailList(&ConfigurationContext->ResourceListHead, &MiniportResource->ListEntry, &ConfigurationContext->ResourceLock);
00820 
00821     /* convert from string to bytes */
00822     for(i=0; i<(*NetworkAddressLength); i++)
00823     {
00824         IntArray[i] = (UnicodeToHexByte((str.Buffer)[2*i]) << 4) +
00825                 UnicodeToHexByte((str.Buffer)[2*i+1]);
00826     }
00827 
00828     *NetworkAddress = IntArray;
00829 
00830     *Status = NDIS_STATUS_SUCCESS;
00831 }
00832 
00833 
00834 /*
00835  * @implemented
00836  */
00837 VOID
00838 EXPORT
00839 NdisOpenConfigurationKeyByIndex(
00840     OUT PNDIS_STATUS    Status,
00841     IN  NDIS_HANDLE     ConfigurationHandle,
00842     IN  ULONG           Index,
00843     OUT PNDIS_STRING    KeyName,
00844     OUT PNDIS_HANDLE    KeyHandle)
00845 /*
00846  * FUNCTION: Opens a configuration subkey by index number
00847  * ARGUMENTS:
00848  *     Status: pointer to an NDIS_STATUS to receive status info
00849  *     ConfigurationHandle: the handle passed back from a previous open function
00850  *     Index: the zero-based index of the subkey to open
00851  *     KeyName: the name of the key that was opened
00852  *     KeyHandle: a handle to the key that was opened
00853  * RETURNS:
00854  *     NDIS_STATUS_SUCCESS on success
00855  *     NDIS_STATUS_FAILURE on failure
00856  *     KeyName holds the name of the opened key
00857  *     KeyHandle holds a handle to the new key
00858  */
00859 {
00860     KEY_BASIC_INFORMATION *KeyInformation;
00861     ULONG KeyInformationLength;
00862     OBJECT_ATTRIBUTES KeyAttributes;
00863     NDIS_HANDLE RegKeyHandle;
00864     PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext;
00865 
00866     *KeyHandle = NULL;
00867 
00868     *Status = ZwEnumerateKey(ConfigurationHandle, Index, KeyBasicInformation, NULL, 0, &KeyInformationLength);
00869     if(*Status != STATUS_BUFFER_TOO_SMALL && *Status != STATUS_BUFFER_OVERFLOW && *Status != STATUS_SUCCESS)
00870     {
00871         NDIS_DbgPrint(MIN_TRACE, ("ZwEnumerateKey failed (%x)\n", *Status));
00872         *Status = NDIS_STATUS_FAILURE;
00873         return;
00874     }
00875 
00876     KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength + sizeof(KEY_BASIC_INFORMATION));
00877     if(!KeyInformation)
00878     {
00879         NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00880         *Status = NDIS_STATUS_FAILURE;
00881         return;
00882     }
00883 
00884     *Status = ZwEnumerateKey(ConfigurationHandle, Index, KeyBasicInformation, KeyInformation,
00885         KeyInformationLength + sizeof(KEY_BASIC_INFORMATION), &KeyInformationLength);
00886 
00887     if(*Status != STATUS_SUCCESS)
00888     {
00889         NDIS_DbgPrint(MIN_TRACE, ("ZwEnumerateKey failed (%x)\n", *Status));
00890         ExFreePool(KeyInformation);
00891         *Status = NDIS_STATUS_FAILURE;
00892         return;
00893     }
00894 
00895     /* should i fail instead if the passed-in string isn't long enough? */
00896     wcsncpy(KeyName->Buffer, KeyInformation->Name, KeyName->MaximumLength/sizeof(WCHAR));
00897     KeyName->Length = (USHORT)min(KeyInformation->NameLength, KeyName->MaximumLength);
00898 
00899     InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE, ConfigurationHandle, NULL);
00900 
00901     *Status = ZwOpenKey(&RegKeyHandle, KEY_ALL_ACCESS, &KeyAttributes);
00902 
00903     ExFreePool(KeyInformation);
00904 
00905     if(*Status != STATUS_SUCCESS)
00906     {
00907         NDIS_DbgPrint(MIN_TRACE, ("ZwOpenKey failed (%x)\n", *Status));
00908         *Status = NDIS_STATUS_FAILURE;
00909         return;
00910     }
00911 
00912     ConfigurationContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT));
00913     if(!ConfigurationContext)
00914     {
00915         NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00916         ZwClose(RegKeyHandle);
00917         *Status = NDIS_STATUS_FAILURE;
00918         return;
00919     }
00920 
00921     KeInitializeSpinLock(&ConfigurationContext->ResourceLock);
00922     InitializeListHead(&ConfigurationContext->ResourceListHead);
00923 
00924     ConfigurationContext->Handle = RegKeyHandle;
00925 
00926     *KeyHandle = (NDIS_HANDLE)ConfigurationContext;
00927 
00928     *Status = NDIS_STATUS_SUCCESS;
00929 }
00930 
00931 
00932 /*
00933  * @implemented
00934  */
00935 VOID
00936 EXPORT
00937 NdisOpenConfigurationKeyByName(
00938     OUT PNDIS_STATUS    Status,
00939     IN  NDIS_HANDLE     ConfigurationHandle,
00940     IN  PNDIS_STRING    KeyName,
00941     OUT PNDIS_HANDLE    KeyHandle)
00942 /*
00943  * FUNCTION: Opens a configuration subkey by name
00944  * ARGUMENTS:
00945  *     Status: points to an NDIS_STATUS where status is returned
00946  *     ConfigurationHandle: handle returned by a previous open call
00947  *     KeyName: the name of the key to open
00948  *     KeyHandle: a handle to the opened key
00949  * RETURNS:
00950  *     NDIS_STATUS_SUCCESS on success
00951  *     NDIS_STATUS_FAILURE on failure
00952  *     KeyHandle holds a handle to the newly-opened key
00953  * NOTES:
00954  */
00955 {
00956     PMINIPORT_CONFIGURATION_CONTEXT ConfigurationContext;
00957     OBJECT_ATTRIBUTES KeyAttributes;
00958     NDIS_HANDLE RegKeyHandle;
00959 
00960     *KeyHandle = NULL;
00961 
00962     InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE, ConfigurationHandle, 0);
00963     *Status = ZwOpenKey(&RegKeyHandle, KEY_ALL_ACCESS, &KeyAttributes);
00964 
00965     if(*Status != STATUS_SUCCESS)
00966     {
00967         NDIS_DbgPrint(MIN_TRACE, ("ZwOpenKey failed (%x)\n", *Status));
00968         *Status = NDIS_STATUS_FAILURE;
00969         return;
00970     }
00971 
00972     ConfigurationContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_CONFIGURATION_CONTEXT));
00973     if(!ConfigurationContext)
00974     {
00975         NDIS_DbgPrint(MIN_TRACE,("Insufficient resources.\n"));
00976         ZwClose(RegKeyHandle);
00977         *Status = NDIS_STATUS_FAILURE;
00978         return;
00979     }
00980 
00981     KeInitializeSpinLock(&ConfigurationContext->ResourceLock);
00982     InitializeListHead(&ConfigurationContext->ResourceListHead);
00983 
00984     ConfigurationContext->Handle = RegKeyHandle;
00985 
00986     *KeyHandle = (NDIS_HANDLE)ConfigurationContext;
00987 
00988     *Status = NDIS_STATUS_SUCCESS;
00989 }

Generated on Fri May 25 2012 04:16:57 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.