|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.