Annotation of ntddk/src/network/tdi/stcnfg.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1989-1993  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     stcnfg.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This contains all routines necessary for the support of the dynamic
                     12:     configuration of ST.
                     13: 
                     14: Revision History:
                     15: 
                     16: --*/
                     17: 
                     18: #include "st.h"
                     19: 
                     20: 
                     21: //
                     22: // Local functions used to access the registry.
                     23: //
                     24: 
                     25: NTSTATUS
                     26: StConfigureTransport (
                     27:     IN PUNICODE_STRING RegistryPath,
                     28:     IN PCONFIG_DATA * ConfigurationInfoPtr
                     29:     );
                     30: 
                     31: VOID
                     32: StFreeConfigurationInfo (
                     33:     IN PCONFIG_DATA ConfigurationInfo
                     34:     );
                     35: 
                     36: NTSTATUS
                     37: StOpenParametersKey(
                     38:     IN HANDLE StConfigHandle,
                     39:     OUT PHANDLE ParametersHandle
                     40:     );
                     41: 
                     42: VOID
                     43: StCloseParametersKey(
                     44:     IN HANDLE ParametersHandle
                     45:     );
                     46: 
                     47: NTSTATUS
                     48: StCountEntries(
                     49:     IN PWSTR ValueName,
                     50:     IN ULONG ValueType,
                     51:     IN PVOID ValueData,
                     52:     IN ULONG ValueLength,
                     53:     IN PVOID Context,
                     54:     IN PVOID EntryContext
                     55:     );
                     56: 
                     57: NTSTATUS
                     58: StAddBind(
                     59:     IN PWSTR ValueName,
                     60:     IN ULONG ValueType,
                     61:     IN PVOID ValueData,
                     62:     IN ULONG ValueLength,
                     63:     IN PVOID Context,
                     64:     IN PVOID EntryContext
                     65:     );
                     66: 
                     67: NTSTATUS
                     68: StAddExport(
                     69:     IN PWSTR ValueName,
                     70:     IN ULONG ValueType,
                     71:     IN PVOID ValueData,
                     72:     IN ULONG ValueLength,
                     73:     IN PVOID Context,
                     74:     IN PVOID EntryContext
                     75:     );
                     76: 
                     77: VOID
                     78: StReadLinkageInformation(
                     79:     IN PWSTR RegistryPathBuffer,
                     80:     IN PCONFIG_DATA * ConfigurationInfo
                     81:     );
                     82: 
                     83: UINT
                     84: StReadSizeInformation(
                     85:     IN HANDLE ParametersHandle
                     86:     );
                     87: 
                     88: ULONG
                     89: StReadSingleParameter(
                     90:     IN HANDLE ParametersHandle,
                     91:     IN PWCHAR ValueName,
                     92:     IN ULONG DefaultValue
                     93:     );
                     94: 
                     95: VOID
                     96: StWriteSingleParameter(
                     97:     IN HANDLE ParametersHandle,
                     98:     IN PWCHAR ValueName,
                     99:     IN ULONG ValueData
                    100:     );
                    101: 
                    102: VOID
                    103: StSaveConfigInRegistry(
                    104:     IN HANDLE ParametersHandle,
                    105:     IN PCONFIG_DATA ConfigurationInfo
                    106:     );
                    107: 
                    108: UINT
                    109: StWstrLength(
                    110:     IN PWSTR Wstr
                    111:     );
                    112: 
                    113: #ifdef ALLOC_PRAGMA
                    114: #pragma alloc_text(init,StWstrLength)
                    115: #pragma alloc_text(init,StConfigureTransport)
                    116: #pragma alloc_text(init,StFreeConfigurationInfo)
                    117: #pragma alloc_text(init,StOpenParametersKey)
                    118: #pragma alloc_text(init,StCloseParametersKey)
                    119: #pragma alloc_text(init,StCountEntries)
                    120: #pragma alloc_text(init,StAddBind)
                    121: #pragma alloc_text(init,StAddExport)
                    122: #pragma alloc_text(init,StReadLinkageInformation)
                    123: #pragma alloc_text(init,StReadSingleParameter)
                    124: #pragma alloc_text(init,StWriteSingleParameter)
                    125: #pragma alloc_text(init,StSaveConfigInRegistry)
                    126: #endif
                    127: 
                    128: 
                    129: UINT
                    130: StWstrLength(
                    131:     IN PWSTR Wstr
                    132:     )
                    133: {
                    134:     UINT Length = 0;
                    135:     while (*Wstr++) {
                    136:         Length += sizeof(WCHAR);
                    137:     }
                    138:     return Length;
                    139: }
                    140: 
                    141: #define InsertAdapter(ConfigurationInfo, Subscript, Name)                \
                    142: { \
                    143:     PWSTR _S; \
                    144:     PWSTR _N = (Name); \
                    145:     UINT _L = StWstrLength(_N)+sizeof(WCHAR); \
                    146:     _S = (PWSTR)ExAllocatePool(NonPagedPool, _L); \
                    147:     if (_S != NULL) { \
                    148:         RtlCopyMemory(_S, _N, _L); \
                    149:         RtlInitUnicodeString (&(ConfigurationInfo)->Names[Subscript], _S); \
                    150:     } \
                    151: }
                    152: 
                    153: #define InsertDevice(ConfigurationInfo, Subscript, Name)                \
                    154: { \
                    155:     PWSTR _S; \
                    156:     PWSTR _N = (Name); \
                    157:     UINT _L = StWstrLength(_N)+sizeof(WCHAR); \
                    158:     _S = (PWSTR)ExAllocatePool(NonPagedPool, _L); \
                    159:     if (_S != NULL) { \
                    160:         RtlCopyMemory(_S, _N, _L); \
                    161:         RtlInitUnicodeString (&(ConfigurationInfo)->Names[(ConfigurationInfo)->DevicesOffset+Subscript], _S); \
                    162:     } \
                    163: }
                    164: 
                    165: 
                    166: #define RemoveAdapter(ConfigurationInfo, Subscript)                \
                    167:     ExFreePool ((ConfigurationInfo)->Names[Subscript].Buffer)
                    168: 
                    169: #define RemoveDevice(ConfigurationInfo, Subscript)                \
                    170:     ExFreePool ((ConfigurationInfo)->Names[(ConfigurationInfo)->DevicesOffset+Subscript].Buffer)
                    171: 
                    172: 
                    173: 
                    174: //
                    175: // These strings are used in various places by the registry.
                    176: //
                    177: 
                    178: #define DECLARE_STRING(_str_) STATIC WCHAR Str ## _str_[] = L#_str_
                    179: 
                    180: DECLARE_STRING(Large);
                    181: DECLARE_STRING(Medium);
                    182: DECLARE_STRING(Small);
                    183: 
                    184: DECLARE_STRING(InitRequests);
                    185: DECLARE_STRING(InitConnections);
                    186: DECLARE_STRING(InitAddressFiles);
                    187: DECLARE_STRING(InitAddresses);
                    188: 
                    189: DECLARE_STRING(MaxRequests);
                    190: DECLARE_STRING(MaxConnections);
                    191: DECLARE_STRING(MaxAddressFiles);
                    192: DECLARE_STRING(MaxAddresses);
                    193: 
                    194: DECLARE_STRING(InitPackets);
                    195: DECLARE_STRING(InitReceivePackets);
                    196: DECLARE_STRING(InitReceiveBuffers);
                    197: 
                    198: DECLARE_STRING(SendPacketPoolSize);
                    199: DECLARE_STRING(ReceivePacketPoolSize);
                    200: DECLARE_STRING(MaxMemoryUsage);
                    201: 
                    202: 
                    203: #define READ_HIDDEN_CONFIG(_Field) \
                    204: { \
                    205:     ConfigurationInfo->_Field = \
                    206:         StReadSingleParameter( \
                    207:              ParametersHandle, \
                    208:              Str ## _Field, \
                    209:              ConfigurationInfo->_Field); \
                    210: }
                    211: 
                    212: #define WRITE_HIDDEN_CONFIG(_Field) \
                    213: { \
                    214:     StWriteSingleParameter( \
                    215:         ParametersHandle, \
                    216:         Str ## _Field, \
                    217:         ConfigurationInfo->_Field); \
                    218: }
                    219: 
                    220: 
                    221: 
                    222: NTSTATUS
                    223: StConfigureTransport (
                    224:     IN PUNICODE_STRING RegistryPath,
                    225:     IN PCONFIG_DATA * ConfigurationInfoPtr
                    226:     )
                    227: /*++
                    228: 
                    229: Routine Description:
                    230: 
                    231:     This routine is called by ST to get information from the configuration
                    232:     management routines. We read the registry, starting at RegistryPath,
                    233:     to get the parameters. If they don't exist, we use the defaults
                    234:     set in nbfcnfg.h file.
                    235: 
                    236: Arguments:
                    237: 
                    238:     RegistryPath - The name of ST's node in the registry.
                    239: 
                    240:     ConfigurationInfoPtr - A pointer to the configuration information structure.
                    241: 
                    242: Return Value:
                    243: 
                    244:     Status - STATUS_SUCCESS if everything OK, STATUS_INSUFFICIENT_RESOURCES
                    245:             otherwise.
                    246: 
                    247: --*/
                    248: {
                    249: 
                    250:     NTSTATUS OpenStatus;
                    251:     HANDLE ParametersHandle;
                    252:     UINT StSize;
                    253:     HANDLE StConfigHandle;
                    254:     NTSTATUS Status;
                    255:     ULONG Disposition;
                    256:     PWSTR RegistryPathBuffer;
                    257:     OBJECT_ATTRIBUTES TmpObjectAttributes;
                    258:     PCONFIG_DATA ConfigurationInfo;
                    259: 
                    260: 
                    261:     //
                    262:     // Open the registry.
                    263:     //
                    264: 
                    265:     InitializeObjectAttributes(
                    266:         &TmpObjectAttributes,
                    267:         RegistryPath,               // name
                    268:         OBJ_CASE_INSENSITIVE,       // attributes
                    269:         NULL,                       // root
                    270:         NULL                        // security descriptor
                    271:         );
                    272: 
                    273:     Status = ZwCreateKey(
                    274:                  &StConfigHandle,
                    275:                  KEY_WRITE,
                    276:                  &TmpObjectAttributes,
                    277:                  0,                 // title index
                    278:                  NULL,              // class
                    279:                  0,                 // create options
                    280:                  &Disposition);     // disposition
                    281: 
                    282:     if (!NT_SUCCESS(Status)) {
                    283:         StPrint1("ST: Could not open/create ST key: %lx\n", Status);
                    284:         return Status;
                    285:     }
                    286: 
                    287: 
                    288:     OpenStatus = StOpenParametersKey (StConfigHandle, &ParametersHandle);
                    289: 
                    290:     if (OpenStatus != STATUS_SUCCESS) {
                    291:         return OpenStatus;
                    292:     }
                    293: 
                    294:     //
                    295:     // Read in the NDIS binding information (if none is present
                    296:     // the array will be filled with all known drivers).
                    297:     //
                    298:     // StReadLinkageInformation expects a null-terminated path,
                    299:     // so we have to create one from the UNICODE_STRING.
                    300:     //
                    301: 
                    302:     RegistryPathBuffer = (PWSTR)ExAllocatePool(
                    303:                                     NonPagedPool,
                    304:                                     RegistryPath->Length + sizeof(WCHAR));
                    305:     if (RegistryPathBuffer == NULL) {
                    306:         StCloseParametersKey (ParametersHandle);
                    307:         return STATUS_INSUFFICIENT_RESOURCES;
                    308:     }
                    309:     RtlCopyMemory (RegistryPathBuffer, RegistryPath->Buffer, RegistryPath->Length);
                    310:     *(PWCHAR)(((PUCHAR)RegistryPathBuffer)+RegistryPath->Length) = (WCHAR)'\0';
                    311: 
                    312:     StReadLinkageInformation (RegistryPathBuffer, ConfigurationInfoPtr);
                    313: 
                    314:     if (*ConfigurationInfoPtr == NULL) {
                    315:         ExFreePool (RegistryPathBuffer);
                    316:         StCloseParametersKey (ParametersHandle);
                    317:         return STATUS_INSUFFICIENT_RESOURCES;
                    318:     }
                    319:     ConfigurationInfo = *ConfigurationInfoPtr;
                    320: 
                    321: 
                    322:     //
                    323:     // Read the size parameter; this returns 0 if none is
                    324:     // present, or 1 (Small), 2 (Medium) and 3 (Large).
                    325:     //
                    326: 
                    327:     StSize = StReadSizeInformation (ParametersHandle);
                    328: 
                    329:     switch (StSize) {
                    330: 
                    331:         case 0:
                    332:         case 1:
                    333: 
                    334:             //
                    335:             // Default is Small.
                    336:             //
                    337: 
                    338:             //
                    339:             // These are the initial value used; the comment after
                    340:             // each one shows the expected maximum (if every resource
                    341:             // is at the expected maximum, ST should be very close
                    342:             // to being out of memory).
                    343:             //
                    344:             // For now the "Max" values default to 0 (no limit).
                    345:             //
                    346: 
                    347:             ConfigurationInfo->InitRequests = 5;         // 30
                    348:             ConfigurationInfo->InitConnections = 1;      // 10
                    349:             ConfigurationInfo->InitAddressFiles = 0;     // 10
                    350:             ConfigurationInfo->InitAddresses = 0;        // 10
                    351: 
                    352:             //
                    353:             // These are the initial values; remember that the
                    354:             // resources above also allocate some of these each
                    355:             // time they are allocated (shown in the comment).
                    356:             //
                    357: 
                    358:             ConfigurationInfo->InitPackets = 30;         // + link + conn (40)
                    359:             ConfigurationInfo->InitReceivePackets = 10;  // + link + addr (30)
                    360:             ConfigurationInfo->InitReceiveBuffers = 5;   // + addr (15)
                    361: 
                    362:             //
                    363:             // Set the size of the packet pools and the total
                    364:             // allocateable by ST.
                    365:             //
                    366: 
                    367:             ConfigurationInfo->SendPacketPoolSize = 100;
                    368:             ConfigurationInfo->ReceivePacketPoolSize = 30;
                    369:             ConfigurationInfo->MaxMemoryUsage = 100000;
                    370: 
                    371:             break;
                    372: 
                    373:         case 2:
                    374: 
                    375:             //
                    376:             // Medium ST.
                    377:             //
                    378: 
                    379:             //
                    380:             // These are the initial value used; the comment after
                    381:             // each one shows the expected maximum (if every resource
                    382:             // is at the expected maximum, ST should be very close
                    383:             // to being out of memory).
                    384:             //
                    385:             // For now the "Max" values default to 0 (no limit).
                    386:             //
                    387: 
                    388:             ConfigurationInfo->InitRequests = 10;        // 100
                    389:             ConfigurationInfo->InitConnections = 2;      // 64
                    390:             ConfigurationInfo->InitAddressFiles = 1;     // 20
                    391:             ConfigurationInfo->InitAddresses = 1;        // 20
                    392: 
                    393:             //
                    394:             // These are the initial values; remember that the
                    395:             // resources above also allocate some of these each
                    396:             // time they are allocated (shown in the comment).
                    397:             //
                    398: 
                    399:             ConfigurationInfo->InitPackets = 50;         // + link + conn (150)
                    400:             ConfigurationInfo->InitReceivePackets = 15;  // + link + addr (100)
                    401:             ConfigurationInfo->InitReceiveBuffers = 10;  // + addr (30)
                    402: 
                    403:             //
                    404:             // Set the size of the packet pools and the total
                    405:             // allocateable by ST.
                    406:             //
                    407: 
                    408:             ConfigurationInfo->SendPacketPoolSize = 250;
                    409:             ConfigurationInfo->ReceivePacketPoolSize = 100;
                    410:             ConfigurationInfo->MaxMemoryUsage = 250000;
                    411: 
                    412:             break;
                    413: 
                    414:         case 3:
                    415: 
                    416:             //
                    417:             // Big ST.
                    418:             //
                    419: 
                    420:             //
                    421:             // These are the initial value used.
                    422:             //
                    423:             // For now the "Max" values default to 0 (no limit).
                    424:             //
                    425: 
                    426:             ConfigurationInfo->InitRequests = 15;
                    427:             ConfigurationInfo->InitConnections = 3;
                    428:             ConfigurationInfo->InitAddressFiles = 2;
                    429:             ConfigurationInfo->InitAddresses = 2;
                    430: 
                    431:             //
                    432:             // These are the initial values; remember that the
                    433:             // resources above also allocate some of these each
                    434:             // time they are allocated (shown in the comment).
                    435:             //
                    436: 
                    437:             ConfigurationInfo->InitPackets = 75;         // + link + conn
                    438:             ConfigurationInfo->InitReceivePackets = 25;  // + link + addr
                    439:             ConfigurationInfo->InitReceiveBuffers = 20;  // + addr
                    440: 
                    441:             //
                    442:             // Set the size of the packet pools and the total
                    443:             // allocateable by ST.
                    444:             //
                    445: 
                    446:             ConfigurationInfo->SendPacketPoolSize = 500;
                    447:             ConfigurationInfo->ReceivePacketPoolSize = 200;
                    448:             ConfigurationInfo->MaxMemoryUsage = 0;       // no limit
                    449: 
                    450:             break;
                    451: 
                    452:         default:
                    453: 
                    454:             ASSERT(FALSE);
                    455:             break;
                    456: 
                    457:     }
                    458: 
                    459: 
                    460:     //
                    461:     // Now read the optional "hidden" parameters; if these do
                    462:     // not exist then the current values are used. Note that
                    463:     // the current values will be 0 unless they have been
                    464:     // explicitly initialized above.
                    465:     //
                    466:     // NOTE: These macros expect "ConfigurationInfo" and
                    467:     // "ParametersHandle" to exist when they are expanded.
                    468:     //
                    469: 
                    470:     READ_HIDDEN_CONFIG (InitRequests);
                    471:     READ_HIDDEN_CONFIG (InitConnections);
                    472:     READ_HIDDEN_CONFIG (InitAddressFiles);
                    473:     READ_HIDDEN_CONFIG (InitAddresses);
                    474: 
                    475:     READ_HIDDEN_CONFIG (MaxRequests);
                    476:     READ_HIDDEN_CONFIG (MaxConnections);
                    477:     READ_HIDDEN_CONFIG (MaxAddressFiles);
                    478:     READ_HIDDEN_CONFIG (MaxAddresses);
                    479: 
                    480:     READ_HIDDEN_CONFIG (InitPackets);
                    481:     READ_HIDDEN_CONFIG (InitReceivePackets);
                    482:     READ_HIDDEN_CONFIG (InitReceiveBuffers);
                    483: 
                    484:     READ_HIDDEN_CONFIG (SendPacketPoolSize);
                    485:     READ_HIDDEN_CONFIG (ReceivePacketPoolSize);
                    486:     READ_HIDDEN_CONFIG (MaxMemoryUsage);
                    487: 
                    488: 
                    489:     //
                    490:     // Now that we are completely configured, save the information
                    491:     // in the registry.
                    492:     //
                    493: 
                    494:     StSaveConfigInRegistry (ParametersHandle, ConfigurationInfo);
                    495: 
                    496:     ExFreePool (RegistryPathBuffer);
                    497:     StCloseParametersKey (ParametersHandle);
                    498:     ZwClose (StConfigHandle);
                    499: 
                    500:     return STATUS_SUCCESS;
                    501: 
                    502: }   /* StConfigureTransport */
                    503: 
                    504: 
                    505: VOID
                    506: StFreeConfigurationInfo (
                    507:     IN PCONFIG_DATA ConfigurationInfo
                    508:     )
                    509: 
                    510: /*++
                    511: 
                    512: Routine Description:
                    513: 
                    514:     This routine is called by ST to get free any storage that was allocated
                    515:     by StConfigureTransport in producing the specified CONFIG_DATA structure.
                    516: 
                    517: Arguments:
                    518: 
                    519:     ConfigurationInfo - A pointer to the configuration information structure.
                    520: 
                    521: Return Value:
                    522: 
                    523:     None.
                    524: 
                    525: --*/
                    526: {
                    527:     UINT i;
                    528: 
                    529:     for (i=0; i<ConfigurationInfo->NumAdapters; i++) {
                    530:         RemoveAdapter (ConfigurationInfo, i);
                    531:         RemoveDevice (ConfigurationInfo, i);
                    532:     }
                    533:     ExFreePool (ConfigurationInfo);
                    534: 
                    535: }   /* StFreeConfigurationInfo */
                    536: 
                    537: 
                    538: NTSTATUS
                    539: StOpenParametersKey(
                    540:     IN HANDLE StConfigHandle,
                    541:     OUT PHANDLE ParametersHandle
                    542:     )
                    543: 
                    544: /*++
                    545: 
                    546: Routine Description:
                    547: 
                    548:     This routine is called by ST to open the ST "Parameters" key.
                    549: 
                    550: Arguments:
                    551: 
                    552:     ParametersHandle - Returns the handle used to read parameters.
                    553: 
                    554: Return Value:
                    555: 
                    556:     The status of the request.
                    557: 
                    558: --*/
                    559: {
                    560: 
                    561:     NTSTATUS Status;
                    562:     HANDLE ParamHandle;
                    563:     PWSTR ParametersString = L"Parameters";
                    564:     UNICODE_STRING ParametersKeyName;
                    565:     OBJECT_ATTRIBUTES TmpObjectAttributes;
                    566: 
                    567:     //
                    568:     // Open the ST parameters key.
                    569:     //
                    570: 
                    571:     RtlInitUnicodeString (&ParametersKeyName, ParametersString);
                    572: 
                    573:     InitializeObjectAttributes(
                    574:         &TmpObjectAttributes,
                    575:         &ParametersKeyName,         // name
                    576:         OBJ_CASE_INSENSITIVE,       // attributes
                    577:         StConfigHandle,            // root
                    578:         NULL                        // security descriptor
                    579:         );
                    580: 
                    581: 
                    582:     Status = ZwOpenKey(
                    583:                  &ParamHandle,
                    584:                  KEY_READ,
                    585:                  &TmpObjectAttributes);
                    586: 
                    587:     if (!NT_SUCCESS(Status)) {
                    588: 
                    589:         StPrint1("Could not open parameters key: %lx\n", Status);
                    590:         return Status;
                    591: 
                    592:     }
                    593: 
                    594:     *ParametersHandle = ParamHandle;
                    595: 
                    596: 
                    597:     //
                    598:     // All keys successfully opened or created.
                    599:     //
                    600: 
                    601:     return STATUS_SUCCESS;
                    602: 
                    603: }   /* StOpenParametersKey */
                    604: 
                    605: VOID
                    606: StCloseParametersKey(
                    607:     IN HANDLE ParametersHandle
                    608:     )
                    609: 
                    610: /*++
                    611: 
                    612: Routine Description:
                    613: 
                    614:     This routine is called by ST to close the "Parameters" key.
                    615:     It closes the handles passed in and does any other work needed.
                    616: 
                    617: Arguments:
                    618: 
                    619:     ParametersHandle - The handle used to read other parameters.
                    620: 
                    621: Return Value:
                    622: 
                    623:     None.
                    624: 
                    625: --*/
                    626: 
                    627: {
                    628: 
                    629:     ZwClose (ParametersHandle);
                    630: 
                    631: }   /* StCloseParametersKey */
                    632: 
                    633: 
                    634: NTSTATUS
                    635: StCountEntries(
                    636:     IN PWSTR ValueName,
                    637:     IN ULONG ValueType,
                    638:     IN PVOID ValueData,
                    639:     IN ULONG ValueLength,
                    640:     IN PVOID Context,
                    641:     IN PVOID EntryContext
                    642:     )
                    643: 
                    644: /*++
                    645: 
                    646: Routine Description:
                    647: 
                    648:     This routine is a callback routine for RtlQueryRegistryValues
                    649:     It is called with the "Bind" and "Export" multi-strings.
                    650:     It counts the number of name entries required in the
                    651:     CONFIGURATION_DATA structure and then allocates it.
                    652: 
                    653: Arguments:
                    654: 
                    655:     ValueName - The name of the value ("Bind" or "Export" -- ignored).
                    656: 
                    657:     ValueType - The type of the value (REG_MULTI_SZ -- ignored).
                    658: 
                    659:     ValueData - The null-terminated data for the value.
                    660: 
                    661:     ValueLength - The length of ValueData (ignored).
                    662: 
                    663:     Context - A pointer to a pointer to the ConfigurationInfo structure.
                    664:         When the "Export" callback is made this is filled in
                    665:         with the allocate structure.
                    666: 
                    667:     EntryContext - A pointer to a counter holding the total number
                    668:         of name entries required.
                    669: 
                    670: Return Value:
                    671: 
                    672:     STATUS_SUCCESS
                    673: 
                    674: --*/
                    675: 
                    676: {
                    677:     ULONG StringCount;
                    678:     PWCHAR ValuePointer = (PWCHAR)ValueData;
                    679:     PCONFIG_DATA * ConfigurationInfo = (PCONFIG_DATA *)Context;
                    680:     PULONG TotalCount = ((PULONG)EntryContext);
                    681:     ULONG OldTotalCount = *TotalCount;
                    682: 
                    683:     ASSERT (ValueType == REG_MULTI_SZ);
                    684: 
                    685:     //
                    686:     // Count the number of strings in the multi-string; first
                    687:     // check that it is NULL-terminated to make the rest
                    688:     // easier.
                    689:     //
                    690: 
                    691:     if ((ValueLength < 2) ||
                    692:         (ValuePointer[(ValueLength/2)-1] != (WCHAR)'\0')) {
                    693:         return STATUS_INVALID_PARAMETER;
                    694:     }
                    695: 
                    696:     StringCount = 0;
                    697:     while (*ValuePointer != (WCHAR)'\0') {
                    698:         while (*ValuePointer != (WCHAR)'\0') {
                    699:             ++ValuePointer;
                    700:         }
                    701:         ++StringCount;
                    702:         ++ValuePointer;
                    703:         if ((ULONG)((PUCHAR)ValuePointer - (PUCHAR)ValueData) >= ValueLength) {
                    704:             break;
                    705:         }
                    706:     }
                    707: 
                    708:     (*TotalCount) += StringCount;
                    709: 
                    710:     if (*ValueName == (WCHAR)'E') {
                    711: 
                    712:         //
                    713:         // This is "Export", allocate the config data structure.
                    714:         //
                    715: 
                    716:         *ConfigurationInfo = ExAllocatePool(
                    717:                                  NonPagedPool,
                    718:                                  sizeof (CONFIG_DATA) +
                    719:                                      ((*TotalCount-1) * sizeof(NDIS_STRING)));
                    720: 
                    721:         if (*ConfigurationInfo == NULL) {
                    722:             return STATUS_INSUFFICIENT_RESOURCES;
                    723:         }
                    724: 
                    725:         RtlZeroMemory(
                    726:             *ConfigurationInfo,
                    727:             sizeof(CONFIG_DATA) + ((*TotalCount-1) * sizeof(NDIS_STRING)));
                    728: 
                    729:         (*ConfigurationInfo)->DevicesOffset = OldTotalCount;
                    730: 
                    731:     }
                    732: 
                    733:     return STATUS_SUCCESS;
                    734: 
                    735: }   /* StCountEntries */
                    736: 
                    737: 
                    738: NTSTATUS
                    739: StAddBind(
                    740:     IN PWSTR ValueName,
                    741:     IN ULONG ValueType,
                    742:     IN PVOID ValueData,
                    743:     IN ULONG ValueLength,
                    744:     IN PVOID Context,
                    745:     IN PVOID EntryContext
                    746:     )
                    747: 
                    748: /*++
                    749: 
                    750: Routine Description:
                    751: 
                    752:     This routine is a callback routine for RtlQueryRegistryValues
                    753:     It is called for each piece of the "Bind" multi-string and
                    754:     saves the information in a ConfigurationInfo structure.
                    755: 
                    756: Arguments:
                    757: 
                    758:     ValueName - The name of the value ("Bind" -- ignored).
                    759: 
                    760:     ValueType - The type of the value (REG_SZ -- ignored).
                    761: 
                    762:     ValueData - The null-terminated data for the value.
                    763: 
                    764:     ValueLength - The length of ValueData (ignored).
                    765: 
                    766:     Context - A pointer to the ConfigurationInfo structure.
                    767: 
                    768:     EntryContext - A pointer to a count of binds that is incremented.
                    769: 
                    770: Return Value:
                    771: 
                    772:     STATUS_SUCCESS
                    773: 
                    774: --*/
                    775: 
                    776: {
                    777:     PCONFIG_DATA ConfigurationInfo = *(PCONFIG_DATA *)Context;
                    778:     PULONG CurBindNum = ((PULONG)EntryContext);
                    779: 
                    780:     UNREFERENCED_PARAMETER(ValueName);
                    781:     UNREFERENCED_PARAMETER(ValueType);
                    782:     UNREFERENCED_PARAMETER(ValueLength);
                    783: 
                    784:     InsertAdapter(
                    785:         ConfigurationInfo,
                    786:         *CurBindNum,
                    787:         (PWSTR)(ValueData));
                    788: 
                    789:     ++(*CurBindNum);
                    790: 
                    791:     return STATUS_SUCCESS;
                    792: 
                    793: }   /* StAddBind */
                    794: 
                    795: 
                    796: NTSTATUS
                    797: StAddExport(
                    798:     IN PWSTR ValueName,
                    799:     IN ULONG ValueType,
                    800:     IN PVOID ValueData,
                    801:     IN ULONG ValueLength,
                    802:     IN PVOID Context,
                    803:     IN PVOID EntryContext
                    804:     )
                    805: 
                    806: /*++
                    807: 
                    808: Routine Description:
                    809: 
                    810:     This routine is a callback routine for RtlQueryRegistryValues
                    811:     It is called for each piece of the "Export" multi-string and
                    812:     saves the information in a ConfigurationInfo structure.
                    813: 
                    814: Arguments:
                    815: 
                    816:     ValueName - The name of the value ("Export" -- ignored).
                    817: 
                    818:     ValueType - The type of the value (REG_SZ -- ignored).
                    819: 
                    820:     ValueData - The null-terminated data for the value.
                    821: 
                    822:     ValueLength - The length of ValueData (ignored).
                    823: 
                    824:     Context - A pointer to the ConfigurationInfo structure.
                    825: 
                    826:     EntryContext - A pointer to a count of exports that is incremented.
                    827: 
                    828: Return Value:
                    829: 
                    830:     STATUS_SUCCESS
                    831: 
                    832: --*/
                    833: 
                    834: {
                    835:     PCONFIG_DATA ConfigurationInfo = *(PCONFIG_DATA *)Context;
                    836:     PULONG CurExportNum = ((PULONG)EntryContext);
                    837: 
                    838:     UNREFERENCED_PARAMETER(ValueName);
                    839:     UNREFERENCED_PARAMETER(ValueType);
                    840:     UNREFERENCED_PARAMETER(ValueLength);
                    841: 
                    842:     InsertDevice(
                    843:         ConfigurationInfo,
                    844:         *CurExportNum,
                    845:         (PWSTR)(ValueData));
                    846: 
                    847:     ++(*CurExportNum);
                    848: 
                    849:     return STATUS_SUCCESS;
                    850: 
                    851: }   /* StAddExport */
                    852: 
                    853: 
                    854: VOID
                    855: StReadLinkageInformation(
                    856:     IN PWSTR RegistryPathBuffer,
                    857:     IN PCONFIG_DATA * ConfigurationInfo
                    858:     )
                    859: 
                    860: /*++
                    861: 
                    862: Routine Description:
                    863: 
                    864:     This routine is called by ST to read its linkage information
                    865:     from the registry. If there is none present, then ConfigData
                    866:     is filled with a list of all the adapters that are known
                    867:     to ST.
                    868: 
                    869: Arguments:
                    870: 
                    871:     RegistryPathBuffer - The null-terminated root of the ST registry tree.
                    872: 
                    873:     ConfigurationInfo - Returns ST's current configuration.
                    874: 
                    875: Return Value:
                    876: 
                    877:     None.
                    878: 
                    879: --*/
                    880: 
                    881: {
                    882: 
                    883:     UINT ConfigBindings;
                    884:     UINT NameCount = 0;
                    885:     NTSTATUS Status;
                    886:     RTL_QUERY_REGISTRY_TABLE QueryTable[6];
                    887:     PWSTR Subkey = L"Linkage";
                    888:     PWSTR Bind = L"Bind";
                    889:     PWSTR Export = L"Export";
                    890:     ULONG BindCount, ExportCount;
                    891:     UINT i;
                    892: 
                    893: 
                    894:     //
                    895:     // Set up QueryTable to do the following:
                    896:     //
                    897: 
                    898:     //
                    899:     // 1) Switch to the Linkage key below ST
                    900:     //
                    901: 
                    902:     QueryTable[0].QueryRoutine = NULL;
                    903:     QueryTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
                    904:     QueryTable[0].Name = Subkey;
                    905: 
                    906:     //
                    907:     // 2) Call StCountEntries for the "Bind" multi-string
                    908:     //
                    909: 
                    910:     QueryTable[1].QueryRoutine = StCountEntries;
                    911:     QueryTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND;
                    912:     QueryTable[1].Name = Bind;
                    913:     QueryTable[1].EntryContext = (PVOID)&NameCount;
                    914:     QueryTable[1].DefaultType = REG_NONE;
                    915: 
                    916:     //
                    917:     // 3) Call StCountEntries for the "Export" multi-string
                    918:     //
                    919: 
                    920:     QueryTable[2].QueryRoutine = StCountEntries;
                    921:     QueryTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND;
                    922:     QueryTable[2].Name = Export;
                    923:     QueryTable[2].EntryContext = (PVOID)&NameCount;
                    924:     QueryTable[2].DefaultType = REG_NONE;
                    925: 
                    926:     //
                    927:     // 4) Call StAddBind for each string in "Bind"
                    928:     //
                    929: 
                    930:     QueryTable[3].QueryRoutine = StAddBind;
                    931:     QueryTable[3].Flags = 0;
                    932:     QueryTable[3].Name = Bind;
                    933:     QueryTable[3].EntryContext = (PVOID)&BindCount;
                    934:     QueryTable[3].DefaultType = REG_NONE;
                    935: 
                    936:     //
                    937:     // 5) Call StAddExport for each string in "Export"
                    938:     //
                    939: 
                    940:     QueryTable[4].QueryRoutine = StAddExport;
                    941:     QueryTable[4].Flags = 0;
                    942:     QueryTable[4].Name = Export;
                    943:     QueryTable[4].EntryContext = (PVOID)&ExportCount;
                    944:     QueryTable[4].DefaultType = REG_NONE;
                    945: 
                    946:     //
                    947:     // 6) Stop
                    948:     //
                    949: 
                    950:     QueryTable[5].QueryRoutine = NULL;
                    951:     QueryTable[5].Flags = 0;
                    952:     QueryTable[5].Name = NULL;
                    953: 
                    954: 
                    955:     BindCount = 0;
                    956:     ExportCount = 0;
                    957: 
                    958:     Status = RtlQueryRegistryValues(
                    959:                  RTL_REGISTRY_ABSOLUTE,
                    960:                  RegistryPathBuffer,
                    961:                  QueryTable,
                    962:                  (PVOID)ConfigurationInfo,
                    963:                  NULL);
                    964: 
                    965:     if (Status != STATUS_SUCCESS) {
                    966:         return;
                    967:     }
                    968: 
                    969:     //
                    970:     // Make sure that BindCount and ExportCount match, if not
                    971:     // remove the extras.
                    972:     //
                    973: 
                    974:     if (BindCount < ExportCount) {
                    975: 
                    976:         for (i=BindCount; i<ExportCount; i++) {
                    977:             RemoveDevice (*ConfigurationInfo, i);
                    978:         }
                    979:         ConfigBindings = BindCount;
                    980: 
                    981:     } else if (ExportCount < BindCount) {
                    982: 
                    983:         for (i=ExportCount; i<BindCount; i++) {
                    984:             RemoveAdapter (*ConfigurationInfo, i);
                    985:         }
                    986:         ConfigBindings = ExportCount;
                    987: 
                    988:     } else {
                    989: 
                    990:         ConfigBindings = BindCount;      // which is equal to ExportCount
                    991: 
                    992:     }
                    993: 
                    994:     (*ConfigurationInfo)->NumAdapters = ConfigBindings;
                    995: 
                    996: }   /* StReadLinkageInformation */
                    997: 
                    998: 
                    999: UINT
                   1000: StReadSizeInformation(
                   1001:     IN HANDLE ParametersHandle
                   1002:     )
                   1003: 
                   1004: /*++
                   1005: 
                   1006: Routine Description:
                   1007: 
                   1008:     This routine is called by ST to read the Size information
                   1009:     from the registry.
                   1010: 
                   1011: Arguments:
                   1012: 
                   1013:     RegistryHandle - A pointer to the open registry.
                   1014: 
                   1015: Return Value:
                   1016: 
                   1017:     0 - no Size specified
                   1018:     1 - Small
                   1019:     2 - Medium
                   1020:     3 - Big / Large
                   1021: 
                   1022: --*/
                   1023: 
                   1024: {
                   1025: 
                   1026:     UINT SizeToReturn;
                   1027: //  STRING KeywordName;
                   1028: //  PCONFIG_KEYWORD Keyword;
                   1029: 
                   1030:     ULONG InformationBuffer[16];   // declare ULONG to get it aligned
                   1031:     PKEY_VALUE_FULL_INFORMATION Information =
                   1032:         (PKEY_VALUE_FULL_INFORMATION)InformationBuffer;
                   1033:     ULONG InformationLength;
                   1034:     WCHAR SizeString[] = L"Size";
                   1035:     UNICODE_STRING SizeValueName;
                   1036:     NTSTATUS Status;
                   1037:     PUCHAR InformationData;
                   1038:     ULONG InformationLong;
                   1039: 
                   1040: 
                   1041:     //
                   1042:     // Read the size parameter out of the registry.
                   1043:     //
                   1044: 
                   1045:     RtlInitUnicodeString (&SizeValueName, SizeString);
                   1046: 
                   1047:     Status = ZwQueryValueKey(
                   1048:                  ParametersHandle,
                   1049:                  &SizeValueName,
                   1050:                  KeyValueFullInformation,
                   1051:                  (PVOID)Information,
                   1052:                  sizeof (InformationBuffer),
                   1053:                  &InformationLength);
                   1054: 
                   1055:     //
                   1056:     // Compare to the expected values.
                   1057:     //
                   1058: 
                   1059:     if (Status == STATUS_SUCCESS) {
                   1060: 
                   1061:         InformationData = ((PUCHAR)Information) + Information->DataOffset;
                   1062:         InformationLong = *((PULONG)InformationData);
                   1063: 
                   1064:         if ((Information->DataLength == sizeof(ULONG)) &&
                   1065:             (InformationLong >= 1 && InformationLong <= 3)) {
                   1066: 
                   1067:             SizeToReturn = InformationLong;
                   1068: 
                   1069:         } else {
                   1070: 
                   1071:             if ((Information->DataLength >= 10) &&
                   1072:                     (RtlCompareMemory (StrLarge, InformationData, 10) == 10)) {
                   1073: 
                   1074:                 SizeToReturn = 3;
                   1075: 
                   1076:             } else if ((Information->DataLength >= 12) &&
                   1077:                     (RtlCompareMemory (StrMedium, InformationData, 12) == 12)) {
                   1078: 
                   1079:                 SizeToReturn = 2;
                   1080: 
                   1081:             } else if ((Information->DataLength >= 10) &&
                   1082:                     (RtlCompareMemory (StrSmall, InformationData, 10) == 10)) {
                   1083: 
                   1084:                 SizeToReturn = 1;
                   1085: 
                   1086:             } else {
                   1087: 
                   1088:                 SizeToReturn = 0;
                   1089: 
                   1090:             }
                   1091: 
                   1092:         }
                   1093: 
                   1094:     } else {
                   1095: 
                   1096:         SizeToReturn = 0;
                   1097: 
                   1098:     }
                   1099: 
                   1100:     return SizeToReturn;
                   1101: 
                   1102: }   /* StReadSizeInformation */
                   1103: 
                   1104: 
                   1105: ULONG
                   1106: StReadSingleParameter(
                   1107:     IN HANDLE ParametersHandle,
                   1108:     IN PWCHAR ValueName,
                   1109:     IN ULONG DefaultValue
                   1110:     )
                   1111: 
                   1112: /*++
                   1113: 
                   1114: Routine Description:
                   1115: 
                   1116:     This routine is called by ST to read a single parameter
                   1117:     from the registry. If the parameter is found it is stored
                   1118:     in Data.
                   1119: 
                   1120: Arguments:
                   1121: 
                   1122:     ParametersHandle - A pointer to the open registry.
                   1123: 
                   1124:     ValueName - The name of the value to search for.
                   1125: 
                   1126:     DefaultValue - The default value.
                   1127: 
                   1128: Return Value:
                   1129: 
                   1130:     The value to use; will be the default if the value is not
                   1131:     found or is not in the correct range.
                   1132: 
                   1133: --*/
                   1134: 
                   1135: {
                   1136:     ULONG InformationBuffer[16];   // declare ULONG to get it aligned
                   1137:     PKEY_VALUE_FULL_INFORMATION Information =
                   1138:         (PKEY_VALUE_FULL_INFORMATION)InformationBuffer;
                   1139:     UNICODE_STRING ValueKeyName;
                   1140:     ULONG InformationLength;
                   1141:     ULONG ReturnValue;
                   1142:     NTSTATUS Status;
                   1143: 
                   1144:     RtlInitUnicodeString (&ValueKeyName, ValueName);
                   1145: 
                   1146:     Status = ZwQueryValueKey(
                   1147:                  ParametersHandle,
                   1148:                  &ValueKeyName,
                   1149:                  KeyValueFullInformation,
                   1150:                  (PVOID)Information,
                   1151:                  sizeof (InformationBuffer),
                   1152:                  &InformationLength);
                   1153: 
                   1154:     if ((Status == STATUS_SUCCESS) && (Information->DataLength == sizeof(ULONG))) {
                   1155: 
                   1156:         RtlCopyMemory(
                   1157:             (PVOID)&ReturnValue,
                   1158:             ((PUCHAR)Information) + Information->DataOffset,
                   1159:             sizeof(ULONG));
                   1160: 
                   1161:         if (ReturnValue < 0) {
                   1162: 
                   1163:             ReturnValue = DefaultValue;
                   1164: 
                   1165:         }
                   1166: 
                   1167:     } else {
                   1168: 
                   1169:         ReturnValue = DefaultValue;
                   1170: 
                   1171:     }
                   1172: 
                   1173:     return ReturnValue;
                   1174: 
                   1175: }   /* StReadSingleParameter */
                   1176: 
                   1177: 
                   1178: VOID
                   1179: StWriteSingleParameter(
                   1180:     IN HANDLE ParametersHandle,
                   1181:     IN PWCHAR ValueName,
                   1182:     IN ULONG ValueData
                   1183:     )
                   1184: 
                   1185: /*++
                   1186: 
                   1187: Routine Description:
                   1188: 
                   1189:     This routine is called by ST to write a single parameter
                   1190:     from the registry.
                   1191: 
                   1192: Arguments:
                   1193: 
                   1194:     ParametersHandle - A pointer to the open registry.
                   1195: 
                   1196:     ValueName - The name of the value to store.
                   1197: 
                   1198:     ValueData - The data to store at the value.
                   1199: 
                   1200: Return Value:
                   1201: 
                   1202:     None.
                   1203: 
                   1204: --*/
                   1205: 
                   1206: {
                   1207:     UNICODE_STRING ValueKeyName;
                   1208:     NTSTATUS Status;
                   1209:     ULONG TmpValueData = ValueData;
                   1210: 
                   1211:     RtlInitUnicodeString (&ValueKeyName, ValueName);
                   1212: 
                   1213:     Status = ZwSetValueKey(
                   1214:                  ParametersHandle,
                   1215:                  &ValueKeyName,
                   1216:                  0,
                   1217:                  REG_DWORD,
                   1218:                  (PVOID)&TmpValueData,
                   1219:                  sizeof(ULONG));
                   1220: 
                   1221:     if (!NT_SUCCESS(Status)) {
                   1222:         StPrint1("ST: Could not write dword key: %lx\n", Status);
                   1223:     }
                   1224: 
                   1225: }   /* StWriteSingleParameter */
                   1226: 
                   1227: 
                   1228: VOID
                   1229: StSaveConfigInRegistry(
                   1230:     IN HANDLE ParametersHandle,
                   1231:     IN PCONFIG_DATA ConfigurationInfo
                   1232:     )
                   1233: 
                   1234: /*++
                   1235: 
                   1236: Routine Description:
                   1237: 
                   1238:     This routine is called by ST to save its configuraition
                   1239:     information in the registry. It saves the information if
                   1240:     the registry structure did not exist before this boot.
                   1241: 
                   1242: Arguments:
                   1243: 
                   1244:     ParametersHandle - The handle used to read other parameters.
                   1245: 
                   1246:     ConfigurationInfo - Describes ST's current configuration.
                   1247: 
                   1248: Return Value:
                   1249: 
                   1250:     None.
                   1251: 
                   1252: --*/
                   1253: 
                   1254: {
                   1255: 
                   1256:     //
                   1257:     // Save the "hidden" parameters, these may not exist in
                   1258:     // the registry.
                   1259:     //
                   1260:     // NOTE: These macros expect "ConfigurationInfo" and
                   1261:     // "ParametersHandle" to exist when they are expanded.
                   1262:     //
                   1263: 
                   1264:     //
                   1265:     // Don't write the parameters that are set
                   1266:     // based on Size, since otherwise these will overwrite
                   1267:     // those values since hidden parameters are set up
                   1268:     // after the Size-based configuration is done.
                   1269:     //
                   1270: 
                   1271:     WRITE_HIDDEN_CONFIG (MaxRequests);
                   1272:     WRITE_HIDDEN_CONFIG (MaxConnections);
                   1273:     WRITE_HIDDEN_CONFIG (MaxAddressFiles);
                   1274:     WRITE_HIDDEN_CONFIG (MaxAddresses);
                   1275: 
                   1276: }   /* StSaveConfigInRegistry */
                   1277: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.