|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1992 Microsoft Corporation
4:
5: Module Name:
6:
7: Detect.c
8:
9: --*/
10:
11: #include <ntddk.h>
12: #include <ntddnetd.h>
13:
14: #include <windef.h>
15: #include <winerror.h>
16:
17: #include <stdio.h>
18: #include <stdlib.h>
19: #include <string.h>
20: #include "detect.h"
21:
22: #if DBG
23: #define STATIC
24: #else
25: #define STATIC static
26: #endif
27:
28: // Prototype "borrowed" from WINUSER.H
29: extern int WINAPIV wsprintfW(LPWSTR, LPCWSTR, ...);
30: // Prototype "borrowed" from WINBASE.H
31: VOID WINAPI Sleep( DWORD dwMilliseconds );
32:
33:
34: //
35: // This is the structure for all the cards which MS is shipping in this DLL.
36: // To add detection for a new adapter(s), simply add the proper routines to
37: // this structure. The rest is automatic.
38: //
39:
40: DETECT_ADAPTER DetectAdapters[] = {
41:
42: {
43: LanceIdentifyHandler,
44: LanceFirstNextHandler,
45: LanceOpenHandleHandler,
46: LanceCreateHandleHandler,
47: LanceCloseHandleHandler,
48: LanceQueryCfgHandler,
49: LanceVerifyCfgHandler,
50: LanceQueryMaskHandler,
51: LanceParamRangeHandler,
52: LanceQueryParameterNameHandler,
53: 0
54:
55: },
56:
57: {
58: EisaIdentifyHandler,
59: EisaFirstNextHandler,
60: EisaOpenHandleHandler,
61: EisaCreateHandleHandler,
62: EisaCloseHandleHandler,
63: EisaQueryCfgHandler,
64: EisaVerifyCfgHandler,
65: EisaQueryMaskHandler,
66: EisaParamRangeHandler,
67: EisaQueryParameterNameHandler,
68: 0
69:
70: }
71:
72: };
73:
74:
75: //
76: // Constant strings for parameters
77: //
78:
79:
80: WCHAR IrqString[] = L"IRQ";
81: WCHAR IrqTypeString[] = L"IRQTYPE";
82: WCHAR IoAddrString[] = L"IOADDR";
83: WCHAR IoLengthString[] = L"IOADDRLENGTH";
84: WCHAR MemAddrString[] = L"MEMADDR";
85: WCHAR MemLengthString[] = L"MEMADDRLENGTH";
86: WCHAR TransceiverString[] = L"TRANSCEIVER";
87: WCHAR ZeroWaitStateString[] = L"ZEROWAITSTATE";
88: WCHAR SlotNumberString[] = L"SLOTNUMBER";
89:
90:
91: //
92: // Variables for keeping track of the resources that the DLL currently has
93: // claimed.
94: //
95:
96: PNETDTECT_RESOURCE ResourceList;
97: ULONG NumberOfResources = 0;
98: ULONG NumberOfAllocatedResourceSlots = 0;
99:
100:
101: BOOLEAN
102: PASCAL
103: NcDetectInitialInit(
104: IN PVOID DllHandle,
105: IN ULONG Reason,
106: IN PCONTEXT Context OPTIONAL
107: )
108:
109: /*++
110:
111: Routine Description:
112:
113: This routine calls CreateFile to open the device driver.
114:
115: Arguments:
116:
117: DllHandle - Not Used
118:
119: Reason - Attach or Detach
120:
121: Context - Not Used
122:
123: Return Value:
124:
125: STATUS_SUCCESS
126:
127: --*/
128:
129: {
130: LONG SupportedDrivers;
131: LONG CurrentDriver;
132: LONG SupportedAdapters;
133: LONG TotalAdapters = 0;
134: LONG ReturnValue;
135: LONG Length = 0;
136:
137: if (Reason == 0) {
138:
139: //
140: // This is the close call
141: //
142:
143: //
144: // Free ResourceList
145: //
146:
147: if (NumberOfAllocatedResourceSlots > 0) {
148:
149: DetectFreeHeap(ResourceList);
150:
151: }
152:
153: //
154: // Free any temporary resources
155: //
156:
157: // BUGBUG: Where is this function?
158: // DetectFreeTemporaryResources();
159:
160: return(TRUE);
161:
162: }
163:
164: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER);
165:
166: CurrentDriver = 0;
167:
168: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) {
169:
170: //
171: // Count the total number of adapters supported by this DLL by
172: // iterating through each module, finding the number of adapters
173: // each module supports.
174: //
175:
176: SupportedAdapters = 0;
177:
178: for ( ; ; SupportedAdapters++) {
179:
180: ReturnValue =
181: (*(DetectAdapters[CurrentDriver].NcDetectIdentifyHandler))(
182: ((SupportedAdapters+10) * 100),
183: NULL,
184: Length
185: );
186:
187: if (ReturnValue == ERROR_NO_MORE_ITEMS) {
188:
189: break;
190:
191: }
192:
193: }
194:
195: TotalAdapters += SupportedAdapters;
196:
197: DetectAdapters[CurrentDriver].SupportedAdapters = SupportedAdapters;
198:
199: }
200:
201: if (TotalAdapters > 0xFFFF) {
202:
203: //
204: // We do not support more than this many adapters in this DLL
205: // because of the way we build the Tokens and NetcardIds.
206: //
207:
208: return(FALSE);
209:
210: }
211:
212: return TRUE;
213: }
214:
215: LONG
216: NcDetectIdentify(
217: IN LONG Index,
218: OUT WCHAR *Buffer,
219: IN LONG BuffSize
220: )
221:
222: /*++
223:
224: Routine Description:
225:
226: This routine returns information about the netcards supported by
227: this DLL.
228:
229: Arguments:
230:
231: Index - The index of the netcard being address. The first
232: cards information is at index 1000, the second at 1100, etc.
233:
234: Buffer - Buffer to store the result into.
235:
236: BuffSize - Number of bytes in pwchBuffer
237:
238: Return Value:
239:
240: 0 if nothing went wrong, else the appropriate WINERROR.H value.
241:
242: --*/
243:
244: {
245: LONG SupportedDrivers;
246: LONG CurrentDriver;
247: LONG ReturnValue;
248: LONG AdapterNumber = (Index / 100) - 10;
249: LONG CodeNumber = Index % 100;
250:
251:
252: //
253: // First we check the index for any of the 'special' values.
254: //
255:
256: if (Index == 0) {
257:
258: //
259: // Return manufacturers identfication
260: //
261:
262: if (BuffSize < 4) {
263:
264: return(ERROR_NOT_ENOUGH_MEMORY);
265: }
266:
267: //
268: // Copy in the identification number
269: //
270:
271: wsprintfW(Buffer,L"0x0");
272:
273: return(0);
274:
275: }
276:
277: if (Index == 1) {
278:
279: //
280: // Return the date and version
281: //
282:
283: if (BuffSize < 12) {
284:
285: return(ERROR_NOT_ENOUGH_MEMORY);
286: }
287:
288: //
289: // Copy it in
290: //
291:
292: wsprintfW(Buffer,L"0x10920301");
293:
294: return(0);
295:
296: }
297:
298: if (AdapterNumber < 0) {
299:
300: return(ERROR_INVALID_PARAMETER);
301:
302: }
303:
304: //
305: // Now we find the number of drivers this DLL is supporting.
306: //
307: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER);
308:
309:
310: //
311: // Iterate through index until we find the the adapter indicated above.
312: //
313:
314: CurrentDriver = 0;
315:
316: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) {
317:
318: //
319: // See if the one we want is in here
320: //
321:
322: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) {
323:
324: ReturnValue =
325: (*(DetectAdapters[CurrentDriver].NcDetectIdentifyHandler))(
326: ((AdapterNumber + 10) * 100) + CodeNumber,
327: Buffer,
328: BuffSize
329: );
330:
331: return(ReturnValue);
332:
333: } else {
334:
335: //
336: // No, move on to next driver.
337: //
338:
339: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters;
340:
341: }
342:
343: }
344:
345: return(ERROR_NO_MORE_ITEMS);
346:
347: }
348:
349: LONG
350: NcDetectFirstNext(
351: IN LONG NetcardId,
352: IN INTERFACE_TYPE InterfaceType,
353: IN ULONG BusNumber,
354: IN BOOL First,
355: OUT PVOID *Token,
356: OUT LONG *Confidence
357: )
358:
359: /*++
360:
361: Routine Description:
362:
363: This routine finds the instances of a physical adapter identified
364: by the NetcardId.
365:
366: Arguments:
367:
368: NetcardId - The index of the netcard being address. The first
369: cards information is id 1000, the second id 1100, etc.
370:
371: InterfaceType - Any bus type.
372:
373: BusNumber - The bus number of the bus to search.
374:
375: First - TRUE is we are to search for the first instance of an
376: adapter, FALSE if we are to continue search from a previous stopping
377: point.
378:
379: Token - A pointer to a handle to return to identify the found
380: instance
381:
382: Confidence - A pointer to a long for storing the confidence factor
383: that the card exists.
384:
385: Return Value:
386:
387: 0 if nothing went wrong, else the appropriate WINERROR.H value.
388:
389: --*/
390:
391: {
392: LONG SupportedDrivers;
393: LONG CurrentDriver;
394: LONG ReturnValue;
395: LONG AdapterNumber = (NetcardId / 100) - 10;
396:
397: if (AdapterNumber < 0) {
398:
399: return(ERROR_INVALID_PARAMETER);
400:
401: }
402:
403: if ((NetcardId % 100) != 0) {
404:
405: return(ERROR_INVALID_PARAMETER);
406:
407: }
408:
409: //
410: // Now we find the number of drivers this DLL is supporting.
411: //
412: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER);
413:
414: //
415: // Iterate through index until we find the the adapter indicated above.
416: //
417:
418: CurrentDriver = 0;
419:
420: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) {
421:
422: //
423: // See if the one we want is in here
424: //
425:
426: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) {
427:
428: //
429: // Yes, so call to get the right one.
430: //
431:
432: ReturnValue =
433: (*(DetectAdapters[CurrentDriver].NcDetectFirstNextHandler))(
434: (AdapterNumber + 10) * 100,
435: InterfaceType,
436: BusNumber,
437: First,
438: Token,
439: Confidence
440: );
441:
442: if (ReturnValue == 0) {
443:
444: //
445: // Store information
446: //
447:
448: *Token = (PVOID)(((ULONG)(*Token)) | (CurrentDriver << 16));
449:
450: } else {
451:
452: *Token = 0;
453:
454: }
455:
456: return(ReturnValue);
457:
458: } else {
459:
460: //
461: // No, move on to next driver.
462: //
463:
464: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters;
465:
466: }
467:
468: }
469:
470: return(ERROR_INVALID_PARAMETER);
471: }
472:
473:
474:
475:
476: LONG
477: NcDetectOpenHandle(
478: IN PVOID Token,
479: OUT PVOID *Handle
480: )
481:
482: /*++
483:
484: Routine Description:
485:
486: This routine takes a token returned by FirstNext and converts it
487: into a permanent handle.
488:
489: Arguments:
490:
491: Token - The token.
492:
493: Handle - A pointer to the handle, so we can store the resulting
494: handle.
495:
496: Return Value:
497:
498: 0 if nothing went wrong, else the appropriate WINERROR.H value.
499:
500: --*/
501:
502: {
503: LONG ReturnValue;
504: LONG DriverToken = ((ULONG)Token & 0xFFFF);
505: LONG DriverNumber = ((ULONG)Token >> 16);
506: PADAPTER_HANDLE Adapter;
507:
508: ReturnValue =
509: (*(DetectAdapters[DriverNumber].NcDetectOpenHandleHandler))(
510: (PVOID)DriverToken,
511: Handle
512: );
513:
514: if (ReturnValue == 0) {
515:
516: //
517: // Store information
518: //
519:
520: Adapter = DetectAllocateHeap(
521: sizeof(ADAPTER_HANDLE)
522: );
523:
524: if (Adapter == NULL) {
525:
526: //
527: // Error
528: //
529:
530: (*(DetectAdapters[DriverNumber].NcDetectCloseHandleHandler))(
531: *Handle
532: );
533:
534: return(ERROR_NOT_ENOUGH_MEMORY);
535:
536: }
537:
538: Adapter->Handle = *Handle;
539: Adapter->DriverNumber = DriverNumber;
540:
541: *Handle = Adapter;
542:
543: } else {
544:
545: *Handle = NULL;
546:
547: }
548:
549: return(ReturnValue);
550:
551: }
552:
553:
554:
555:
556: LONG
557: NcDetectCreateHandle(
558: IN LONG NetcardId,
559: IN INTERFACE_TYPE InterfaceType,
560: IN ULONG BusNumber,
561: OUT PVOID *Handle
562: )
563:
564: /*++
565:
566: Routine Description:
567:
568: This routine is used to force the creation of a handle for cases
569: where a card is not found via FirstNext, but the user says it does
570: exist.
571:
572: Arguments:
573:
574: NetcardId - The id of the card to create the handle for.
575:
576: InterfaceType - Any bus type.
577:
578: BusNumber - The bus number of the bus in the system.
579:
580: Handle - A pointer to the handle, for storing the resulting handle.
581:
582: Return Value:
583:
584: 0 if nothing went wrong, else the appropriate WINERROR.H value.
585:
586: --*/
587:
588: {
589: LONG SupportedDrivers;
590: LONG CurrentDriver;
591: LONG ReturnValue;
592: LONG AdapterNumber = (NetcardId / 100) - 10;
593: PADAPTER_HANDLE Adapter;
594:
595: if (AdapterNumber < 0) {
596:
597: return(ERROR_INVALID_PARAMETER);
598:
599: }
600:
601: if ((NetcardId % 100) != 0) {
602:
603: return(ERROR_INVALID_PARAMETER);
604:
605: }
606:
607: //
608: // Now we find the number of drivers this DLL is supporting.
609: //
610: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER);
611:
612: //
613: // Iterate through index until we find the the adapter indicated above.
614: //
615:
616: CurrentDriver = 0;
617:
618: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) {
619:
620: //
621: // See if the one we want is in here
622: //
623:
624: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) {
625:
626: //
627: // Yes, so call to get the right one.
628: //
629:
630: ReturnValue =
631: (*(DetectAdapters[CurrentDriver].NcDetectCreateHandleHandler))(
632: (AdapterNumber + 10) * 100,
633: InterfaceType,
634: BusNumber,
635: Handle
636: );
637:
638: if (ReturnValue == 0) {
639:
640: //
641: // Store information
642: //
643:
644: Adapter = DetectAllocateHeap(
645: sizeof(ADAPTER_HANDLE)
646: );
647:
648: if (Adapter == NULL) {
649:
650: //
651: // Error
652: //
653:
654: (*(DetectAdapters[CurrentDriver].NcDetectCloseHandleHandler))(
655: *Handle
656: );
657:
658: return(ERROR_NOT_ENOUGH_MEMORY);
659:
660: }
661:
662: Adapter->Handle = *Handle;
663: Adapter->DriverNumber = CurrentDriver;
664:
665: *Handle = Adapter;
666:
667: } else {
668:
669: *Handle = NULL;
670:
671: }
672:
673: return(ReturnValue);
674:
675: } else {
676:
677: //
678: // No, move on to next driver.
679: //
680:
681: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters;
682:
683: }
684:
685: }
686:
687: return(ERROR_INVALID_PARAMETER);
688: }
689:
690:
691:
692: LONG
693: NcDetectCloseHandle(
694: IN PVOID Handle
695: )
696:
697: /*++
698:
699: Routine Description:
700:
701: This frees any resources associated with a handle.
702:
703: Arguments:
704:
705: pvHandle - The handle.
706:
707: Return Value:
708:
709: 0 if nothing went wrong, else the appropriate WINERROR.H value.
710:
711: --*/
712:
713: {
714: PADAPTER_HANDLE Adapter = (PADAPTER_HANDLE)(Handle);
715:
716: (*(DetectAdapters[Adapter->DriverNumber].NcDetectCloseHandleHandler))(
717: Adapter->Handle
718: );
719:
720: DetectFreeHeap( Adapter );
721:
722: return(0);
723: }
724:
725:
726:
727: LONG
728: NcDetectQueryCfg(
729: IN PVOID Handle,
730: OUT WCHAR *Buffer,
731: IN LONG BuffSize
732: )
733:
734: /*++
735:
736: Routine Description:
737:
738: This routine calls the appropriate driver's query config handler to
739: get the parameters for the adapter associated with the handle.
740:
741: Arguments:
742:
743: Handle - The handle.
744:
745: Buffer - The resulting parameter list.
746:
747: BuffSize - Length of the given buffer in WCHARs.
748:
749: Return Value:
750:
751: 0 if nothing went wrong, else the appropriate WINERROR.H value.
752:
753: --*/
754:
755: {
756: PADAPTER_HANDLE Adapter = (PADAPTER_HANDLE)(Handle);
757: LONG ReturnValue;
758:
759: ReturnValue = (*(DetectAdapters[Adapter->DriverNumber].NcDetectQueryCfgHandler))(
760: Adapter->Handle,
761: Buffer,
762: BuffSize
763: );
764:
765: return(ReturnValue);
766: }
767:
768:
769:
770: LONG
771: NcDetectVerifyCfg(
772: IN PVOID Handle,
773: IN WCHAR *Buffer
774: )
775:
776: /*++
777:
778: Routine Description:
779:
780: This routine verifys that a given parameter list is complete and
781: correct for the adapter associated with the handle.
782:
783: Arguments:
784:
785: Handle - The handle.
786:
787: Buffer - The parameter list.
788:
789: Return Value:
790:
791: 0 if nothing went wrong, else the appropriate WINERROR.H value.
792:
793: --*/
794:
795: {
796: PADAPTER_HANDLE Adapter = (PADAPTER_HANDLE)(Handle);
797: LONG ReturnValue;
798:
799: ReturnValue = (*(DetectAdapters[Adapter->DriverNumber].NcDetectVerifyCfgHandler))(
800: Adapter->Handle,
801: Buffer
802: );
803:
804: return(ReturnValue);
805: }
806:
807:
808:
809: LONG
810: NcDetectQueryMask(
811: IN LONG NetcardId,
812: OUT WCHAR *Buffer,
813: IN LONG BuffSize
814: )
815:
816: /*++
817:
818: Routine Description:
819:
820: This routine returns the parameter list information for a specific
821: network card.
822:
823: Arguments:
824:
825: NetcardId - The id of the desired netcard.
826:
827: Buffer - The buffer for storing the parameter information.
828:
829: BuffSize - Length of Buffer in WCHARs.
830:
831: Return Value:
832:
833: 0 if nothing went wrong, else the appropriate WINERROR.H value.
834:
835: --*/
836:
837: {
838: LONG SupportedDrivers;
839: LONG CurrentDriver;
840: LONG ReturnValue;
841: LONG AdapterNumber = (NetcardId / 100) - 10;
842:
843: if (AdapterNumber < 0) {
844:
845: return(ERROR_INVALID_PARAMETER);
846:
847: }
848:
849: if ((NetcardId % 100) != 0) {
850:
851: return(ERROR_INVALID_PARAMETER);
852:
853: }
854:
855: //
856: // Now we find the number of drivers this DLL is supporting.
857: //
858: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER);
859:
860: //
861: // Iterate through index until we find the the adapter indicated above.
862: //
863:
864: CurrentDriver = 0;
865:
866: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) {
867:
868: //
869: // See if the one we want is in here
870: //
871:
872: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) {
873:
874: //
875: // Yes, so call to get the right one.
876: //
877:
878: ReturnValue =
879: (*(DetectAdapters[CurrentDriver].NcDetectQueryMaskHandler))(
880: ((AdapterNumber + 10) * 100),
881: Buffer,
882: BuffSize
883: );
884:
885: return(ReturnValue);
886:
887: } else {
888:
889: //
890: // No, move on to next driver.
891: //
892:
893: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters;
894:
895: }
896:
897: }
898:
899: return(ERROR_INVALID_PARAMETER);
900: }
901:
902: LONG
903: NcDetectParamRange(
904: IN LONG NetcardId,
905: IN WCHAR *Param,
906: OUT LONG *Values,
907: OUT LONG *BuffSize
908: )
909:
910: /*++
911:
912: Routine Description:
913:
914: This routine returns a list of valid values for a given parameter name
915: for a given card.
916:
917: Arguments:
918:
919: NetcardId - The Id of the card desired.
920:
921: Param - A WCHAR string of the parameter name to query the values of.
922:
923: Values - A pointer to a list of LONGs into which we store valid values
924: for the parameter.
925:
926: BuffSize - At entry, the length of plValues in LONGs. At exit, the
927: number of LONGs stored in plValues.
928:
929: Return Value:
930:
931: 0 if nothing went wrong, else the appropriate WINERROR.H value.
932:
933: --*/
934:
935: {
936: LONG SupportedDrivers;
937: LONG CurrentDriver;
938: LONG ReturnValue;
939: LONG AdapterNumber = (NetcardId / 100) - 10;
940:
941: if (AdapterNumber < 0) {
942:
943: return(ERROR_INVALID_PARAMETER);
944:
945: }
946:
947: if ((NetcardId % 100) != 0) {
948:
949: return(ERROR_INVALID_PARAMETER);
950:
951: }
952:
953: //
954: // Now we find the number of drivers this DLL is supporting.
955: //
956: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER);
957:
958: //
959: // Iterate through index until we find the the adapter indicated above.
960: //
961:
962: CurrentDriver = 0;
963:
964: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) {
965:
966: //
967: // See if the one we want is in here
968: //
969:
970: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) {
971:
972: //
973: // Yes, so call to get the right one.
974: //
975:
976: ReturnValue =
977: (*(DetectAdapters[CurrentDriver].NcDetectParamRangeHandler))(
978: ((AdapterNumber + 10) * 100),
979: Param,
980: Values,
981: BuffSize
982: );
983:
984: return(ReturnValue);
985:
986: } else {
987:
988: //
989: // No, move on to next driver.
990: //
991:
992: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters;
993:
994: }
995:
996: }
997:
998: return(ERROR_INVALID_PARAMETER);
999: }
1000:
1001:
1002:
1003: LONG
1004: NcDetectQueryParameterName(
1005: IN WCHAR *Param,
1006: OUT WCHAR *Buffer,
1007: IN LONG BufferSize
1008: )
1009:
1010: /*++
1011:
1012: Routine Description:
1013:
1014: Returns a localized, displayable name for a specific parameter.
1015:
1016: Arguments:
1017:
1018: Param - The parameter to be queried.
1019:
1020: Buffer - The buffer to store the result into.
1021:
1022: BufferSize - The length of Buffer in WCHARs.
1023:
1024: Return Value:
1025:
1026: 0 if nothing went wrong, else the appropriate WINERROR.H value.
1027:
1028: --*/
1029:
1030: {
1031: LONG SupportedDrivers;
1032: LONG CurrentDriver;
1033: LONG ReturnValue;
1034:
1035: //
1036: // Now we find the number of drivers this DLL is supporting.
1037: //
1038: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER);
1039:
1040: //
1041: // Iterate through index until we find the the adapter indicated above.
1042: //
1043:
1044: CurrentDriver = 0;
1045:
1046: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) {
1047:
1048: //
1049: // No way to tell where this came from -- guess until success.
1050: //
1051:
1052: ReturnValue =
1053: (*(DetectAdapters[CurrentDriver].NcDetectQueryParameterNameHandler))(
1054: Param,
1055: Buffer,
1056: BufferSize
1057: );
1058:
1059: if (ReturnValue == 0) {
1060:
1061: return(0);
1062:
1063: }
1064:
1065: }
1066:
1067: return(ERROR_INVALID_PARAMETER);
1068: }
1069:
1070:
1071: LONG
1072: NcDetectResourceClaim(
1073: IN INTERFACE_TYPE InterfaceType,
1074: IN ULONG BusNumber,
1075: IN ULONG Type,
1076: IN ULONG Value,
1077: IN ULONG Length,
1078: IN ULONG Flags,
1079: IN BOOL Claim
1080: )
1081:
1082: /*++
1083:
1084: Routine Description:
1085:
1086: Attempts to claim a resources, failing if there is a conflict.
1087:
1088: Arguments:
1089:
1090: InterfaceType - Any type.
1091:
1092: BusNumber - The bus number of the bus to search.
1093:
1094: Type - The type of resource, Irq, Memory, Port, Dma
1095:
1096: Value - The starting value
1097:
1098: Length - The Length of the resource from starting value to end.
1099:
1100: Flags - If Type is IRQ, this defines if this is Latched or LevelSensitive.
1101:
1102: Claim - TRUE if we are to permanently claim the resource, else FALSE.
1103:
1104: Return Value:
1105:
1106: 0 if nothing went wrong, else the appropriate WINERROR.H value.
1107:
1108: --*/
1109:
1110: {
1111: ULONG i;
1112: NTSTATUS NtStatus;
1113:
1114: //
1115: // Check the resources we've claimed for ourselves
1116: //
1117:
1118: for (i = 0; i < NumberOfResources; i++) {
1119:
1120: if ((ResourceList[i].InterfaceType == InterfaceType) &&
1121: (ResourceList[i].BusNumber == BusNumber) &&
1122: (ResourceList[i].Type == Type)) {
1123:
1124: if (Value < ResourceList[i].Value) {
1125:
1126: if ((Value + Length) > ResourceList[i].Value) {
1127:
1128: return(ERROR_SHARING_VIOLATION);
1129:
1130: }
1131:
1132: } else if (Value == ResourceList[i].Value) {
1133:
1134: return(ERROR_SHARING_VIOLATION);
1135:
1136: } else if (Value < (ResourceList[i].Value + ResourceList[i].Length)) {
1137:
1138: return(ERROR_SHARING_VIOLATION);
1139:
1140: }
1141:
1142: }
1143:
1144: }
1145:
1146: //
1147: // Make sure resource list has space for this one.
1148: //
1149:
1150: if (NumberOfResources == NumberOfAllocatedResourceSlots) {
1151:
1152: PVOID TmpList;
1153:
1154: //
1155: // Get more space
1156: //
1157:
1158: TmpList = DetectAllocateHeap((NumberOfAllocatedResourceSlots + 32) *
1159: sizeof(NETDTECT_RESOURCE)
1160: );
1161:
1162: //
1163: // Copy data
1164: //
1165:
1166: memcpy(TmpList,
1167: ResourceList,
1168: (NumberOfAllocatedResourceSlots * sizeof(NETDTECT_RESOURCE))
1169: );
1170:
1171: //
1172: // Update counter
1173: //
1174:
1175: NumberOfAllocatedResourceSlots += 32;
1176:
1177: //
1178: // Free old space
1179: //
1180:
1181: DetectFreeHeap(ResourceList);
1182:
1183: ResourceList = (PNETDTECT_RESOURCE)TmpList;
1184:
1185: }
1186:
1187: //
1188: // Add it to the list
1189: //
1190:
1191: ResourceList[NumberOfResources].InterfaceType = InterfaceType;
1192: ResourceList[NumberOfResources].BusNumber = BusNumber;
1193: ResourceList[NumberOfResources].Type = Type;
1194: ResourceList[NumberOfResources].Value = Value;
1195: ResourceList[NumberOfResources].Length = Length;
1196: ResourceList[NumberOfResources].Flags = Flags;
1197:
1198: //
1199: // Try to claim the resource
1200: //
1201:
1202: NtStatus = DetectClaimResource(
1203: NumberOfResources + 1,
1204: (PVOID)ResourceList
1205: );
1206:
1207:
1208: //
1209: // If failed, exit
1210: //
1211:
1212: if (NtStatus == STATUS_CONFLICTING_ADDRESSES) {
1213:
1214: //
1215: // Undo the claim
1216: //
1217:
1218: DetectClaimResource(
1219: NumberOfResources,
1220: (PVOID)ResourceList
1221: );
1222:
1223: return(ERROR_SHARING_VIOLATION);
1224:
1225: }
1226:
1227: if (NtStatus) {
1228:
1229: return(ERROR_NOT_ENOUGH_MEMORY);
1230:
1231: }
1232:
1233: if (!Claim) {
1234:
1235: //
1236: // Undo the claim
1237: //
1238:
1239: DetectClaimResource(
1240: NumberOfResources,
1241: (PVOID)ResourceList
1242: );
1243:
1244: } else {
1245:
1246: //
1247: // Adjust total count only if this is permanent
1248: //
1249:
1250: NumberOfResources++;
1251:
1252: }
1253:
1254: //
1255: // no error
1256: //
1257:
1258: return(0);
1259: }
1260:
1261:
1262:
1263:
1264:
1265: //
1266: // Support routines.
1267: //
1268: // These routines are common routines used within each detection module.
1269: //
1270:
1271:
1272:
1273:
1274:
1275:
1276: ULONG
1277: UnicodeStrLen(
1278: IN WCHAR *String
1279: )
1280:
1281: /*++
1282:
1283: Routine Description:
1284:
1285: This routine returns the number of Unicode characters in a NULL
1286: terminated Unicode string.
1287:
1288: Arguments:
1289:
1290: String - The string.
1291:
1292: Return Value:
1293:
1294: The length in number of unicode characters
1295:
1296: --*/
1297:
1298:
1299: {
1300: ULONG Length;
1301:
1302: for (Length=0; ; Length++) {
1303:
1304: if (String[Length] == L'\0') {
1305:
1306: return Length;
1307:
1308: }
1309:
1310: }
1311:
1312: }
1313:
1314: WCHAR *
1315: FindParameterString(
1316: IN WCHAR *String1,
1317: IN WCHAR *String2
1318: )
1319:
1320: /*++
1321:
1322: Routine Description:
1323:
1324: This routine returns a pointer to the first instance of String2
1325: in String1. It assumes that String1 is a parameter list where
1326: each parameter name is terminated with a NULL and the entire
1327: string terminated by two consecutive NULLs.
1328:
1329: Arguments:
1330:
1331: String1 -- String to search.
1332:
1333: String2 -- Substring to search for.
1334:
1335: Return Value:
1336:
1337: Pointer to place in String1 of first character of String2 if it
1338: exists, else NULL.
1339:
1340: --*/
1341:
1342:
1343: {
1344: ULONG Length1;
1345: ULONG Length2;
1346: WCHAR *Place = String1;
1347:
1348: Length2 = UnicodeStrLen(String2) + 1;
1349:
1350: Length1 = UnicodeStrLen(String1) + 1;
1351:
1352: //
1353: // While not the NULL only
1354: //
1355:
1356: while (Length1 != 1) {
1357:
1358: //
1359: // Are these the same?
1360: //
1361:
1362: if (memcmp(Place, String2, Length2 * sizeof(WCHAR)) == 0) {
1363:
1364: //
1365: // Yes.
1366: //
1367:
1368: return(Place);
1369:
1370: }
1371:
1372: Place = (WCHAR *)(Place + Length1);
1373:
1374: Length1 = UnicodeStrLen(Place) + 1;
1375:
1376: }
1377:
1378: return(NULL);
1379:
1380: }
1381:
1382:
1383: VOID
1384: ScanForNumber(
1385: IN WCHAR *Place,
1386: OUT ULONG *Value,
1387: OUT BOOLEAN *Found
1388: )
1389:
1390: /*++
1391:
1392: Routine Description:
1393:
1394: This routine does a sscanf(Place, "%d", Value) on a unicode string.
1395:
1396: Arguments:
1397:
1398: Place - String to read from
1399:
1400: Value - Pointer to place to store the result.
1401:
1402: Found - Pointer to tell if the routine failed to find an integer.
1403:
1404: Return Value:
1405:
1406: None.
1407:
1408: --*/
1409:
1410:
1411: {
1412: ULONG Tmp;
1413:
1414: *Value = 0;
1415: *Found = FALSE;
1416:
1417: //
1418: // Skip leading blanks
1419: //
1420:
1421: while (*Place == L' ') {
1422:
1423: Place++;
1424:
1425: }
1426:
1427:
1428: //
1429: // Is this a hex number?
1430: //
1431:
1432: if ((Place[0] == L'0') &&
1433: (Place[1] == L'x')) {
1434:
1435: //
1436: // Yes, parse it as a hex number
1437: //
1438:
1439: *Found = TRUE;
1440:
1441: //
1442: // Skip leading '0x'
1443: //
1444:
1445: Place += 2;
1446:
1447: //
1448: // Convert a hex number
1449: //
1450:
1451: while (TRUE) {
1452:
1453: if ((*Place >= L'0') && (*Place <= L'9')) {
1454:
1455: Tmp = ((ULONG)*Place) - ((ULONG)L'0');
1456:
1457: } else {
1458:
1459: switch (*Place) {
1460:
1461: case L'a':
1462: case L'A':
1463:
1464: Tmp = 10;
1465: break;
1466:
1467: case L'b':
1468: case L'B':
1469:
1470: Tmp = 11;
1471: break;
1472:
1473: case L'c':
1474: case L'C':
1475:
1476: Tmp = 12;
1477: break;
1478:
1479: case L'd':
1480: case L'D':
1481:
1482: Tmp = 13;
1483: break;
1484:
1485: case L'e':
1486: case L'E':
1487:
1488: Tmp = 14;
1489: break;
1490:
1491: case L'f':
1492: case L'F':
1493:
1494: Tmp = 15;
1495: break;
1496:
1497: default:
1498:
1499: return;
1500:
1501: }
1502:
1503: }
1504:
1505: (*Value) *= 16;
1506: (*Value) += Tmp;
1507:
1508: Place++;
1509:
1510: }
1511:
1512: } else if ((*Place >= L'0') && (*Place <= L'9')) {
1513:
1514: //
1515: // Parse it as an int
1516: //
1517:
1518: *Found = TRUE;
1519:
1520: //
1521: // Convert a base 10 number
1522: //
1523:
1524: while (TRUE) {
1525:
1526: if ((*Place >= L'0') && (*Place <= L'9')) {
1527:
1528: Tmp = ((ULONG)*Place) - ((ULONG)L'0');
1529:
1530: } else {
1531:
1532: return;
1533:
1534: }
1535:
1536: (*Value) *= 10;
1537: (*Value) += Tmp;
1538:
1539: Place++;
1540:
1541: }
1542:
1543: }
1544:
1545: }
1546:
1547: BOOLEAN
1548: CheckFor8390(
1549: IN INTERFACE_TYPE InterfaceType,
1550: IN ULONG BusNumber,
1551: IN ULONG IoBaseAddress
1552: )
1553:
1554: /*++
1555:
1556: Routine Description:
1557:
1558: This routine checks for the existence of an 8390 NIC.
1559:
1560: Arguments:
1561:
1562: InterfaceType - Any bus type.
1563:
1564: BusNumber - The bus number of the bus in the system.
1565:
1566: IoBaseAddress - The IoBaseAddress to check.
1567:
1568: Return Value:
1569:
1570: None.
1571:
1572: --*/
1573:
1574: {
1575: UCHAR Value;
1576: UCHAR IMRValue;
1577: NTSTATUS NtStatus;
1578: UCHAR SavedOffset0;
1579: UCHAR SavedOffset3;
1580: UCHAR SavedOffsetF;
1581: BOOLEAN Status = TRUE;
1582:
1583: //
1584: // If the IoBaseAddress is the address of the DMA register on the NE2000
1585: // adapter, then this routine will hang the card and the machine. To avoid
1586: // this, we first write to the Ne2000's reset port.
1587: //
1588:
1589: NtStatus = DetectReadPortUchar(InterfaceType,
1590: BusNumber,
1591: IoBaseAddress + 0xF,
1592: &SavedOffsetF
1593: );
1594:
1595: if (NtStatus != STATUS_SUCCESS) {
1596:
1597: Status = FALSE;
1598: goto Fail;
1599:
1600: }
1601:
1602: NtStatus = DetectWritePortUchar(InterfaceType,
1603: BusNumber,
1604: IoBaseAddress + 0xF,
1605: 0xFF
1606: );
1607:
1608: if (NtStatus != STATUS_SUCCESS) {
1609:
1610: Status = FALSE;
1611: goto Fail;
1612:
1613: }
1614:
1615: //
1616: // Write STOP bit
1617: //
1618:
1619: NtStatus = DetectReadPortUchar(InterfaceType,
1620: BusNumber,
1621: IoBaseAddress,
1622: &SavedOffset0
1623: );
1624:
1625: if (NtStatus != STATUS_SUCCESS) {
1626:
1627: Status = FALSE;
1628: goto Restore1;
1629:
1630: }
1631:
1632: NtStatus = DetectWritePortUchar(InterfaceType,
1633: BusNumber,
1634: IoBaseAddress,
1635: 0x21
1636: );
1637:
1638: if (NtStatus != STATUS_SUCCESS) {
1639:
1640: Status = FALSE;
1641: goto Restore1;
1642:
1643: }
1644:
1645: //
1646: // Read boundary
1647: //
1648:
1649: NtStatus = DetectReadPortUchar(InterfaceType,
1650: BusNumber,
1651: IoBaseAddress + 0x3,
1652: &Value
1653: );
1654:
1655: if (NtStatus != STATUS_SUCCESS) {
1656:
1657: Status = FALSE;
1658: goto Restore2;
1659:
1660: }
1661:
1662: SavedOffset3 = Value;
1663:
1664: //
1665: // Write a different boundary
1666: //
1667:
1668: NtStatus = DetectWritePortUchar(InterfaceType,
1669: BusNumber,
1670: IoBaseAddress + 0x3,
1671: (UCHAR)(Value + 1)
1672: );
1673:
1674: if (NtStatus != STATUS_SUCCESS) {
1675:
1676: Status = FALSE;
1677: goto Restore2;
1678:
1679: }
1680:
1681: //
1682: // Did it stick?
1683: //
1684:
1685: NtStatus = DetectReadPortUchar(InterfaceType,
1686: BusNumber,
1687: IoBaseAddress + 0x3,
1688: &IMRValue
1689: );
1690:
1691: if (NtStatus != STATUS_SUCCESS) {
1692:
1693: Status = FALSE;
1694: goto Restore3;
1695:
1696: }
1697:
1698: if (IMRValue != (UCHAR)(Value + 1)) {
1699:
1700: Status = FALSE;
1701: goto Restore3;
1702:
1703: }
1704:
1705: //
1706: // Write IMR
1707: //
1708:
1709: NtStatus = DetectWritePortUchar(InterfaceType,
1710: BusNumber,
1711: IoBaseAddress + 0xF,
1712: 0x3F
1713: );
1714:
1715: if (NtStatus != STATUS_SUCCESS) {
1716:
1717: Status = FALSE;
1718: goto Restore3;
1719:
1720: }
1721:
1722:
1723: //
1724: // switch to page 2
1725: //
1726:
1727: NtStatus = DetectWritePortUchar(InterfaceType,
1728: BusNumber,
1729: IoBaseAddress,
1730: 0xA1
1731: );
1732:
1733: if (NtStatus != STATUS_SUCCESS) {
1734:
1735: //
1736: // Change to page 0
1737: //
1738:
1739: DetectWritePortUchar(InterfaceType,
1740: BusNumber,
1741: IoBaseAddress,
1742: 0x21
1743: );
1744:
1745: Status = FALSE;
1746: goto Restore3;
1747:
1748: }
1749:
1750: //
1751: // Read the IMR
1752: //
1753:
1754: NtStatus = DetectReadPortUchar(InterfaceType,
1755: BusNumber,
1756: IoBaseAddress + 0xF,
1757: &IMRValue
1758: );
1759:
1760: if (NtStatus != STATUS_SUCCESS) {
1761:
1762: //
1763: // Change to page 0
1764: //
1765:
1766: DetectWritePortUchar(InterfaceType,
1767: BusNumber,
1768: IoBaseAddress,
1769: 0x21
1770: );
1771:
1772: Status = FALSE;
1773: goto Restore3;
1774:
1775: }
1776:
1777: //
1778: // Remove bits added by NIC
1779: //
1780:
1781: IMRValue &= 0x3F;
1782:
1783: //
1784: // switch to page 0
1785: //
1786:
1787: NtStatus = DetectWritePortUchar(InterfaceType,
1788: BusNumber,
1789: IoBaseAddress,
1790: 0x21
1791: );
1792:
1793: if (NtStatus != STATUS_SUCCESS) {
1794:
1795: Status = FALSE;
1796: goto Restore3;
1797:
1798: }
1799:
1800: //
1801: // Write IMR
1802: //
1803:
1804: NtStatus = DetectWritePortUchar(InterfaceType,
1805: BusNumber,
1806: IoBaseAddress + 0xF,
1807: (UCHAR)(IMRValue)
1808: );
1809:
1810: if (NtStatus != STATUS_SUCCESS) {
1811:
1812: Status = FALSE;
1813: goto Restore3;
1814:
1815: }
1816:
1817: //
1818: // switch to page 1
1819: //
1820:
1821: NtStatus = DetectWritePortUchar(InterfaceType,
1822: BusNumber,
1823: IoBaseAddress,
1824: 0x61
1825: );
1826:
1827: if (NtStatus != STATUS_SUCCESS) {
1828:
1829: //
1830: // Change to page 0
1831: //
1832:
1833: DetectWritePortUchar(InterfaceType,
1834: BusNumber,
1835: IoBaseAddress,
1836: 0x21
1837: );
1838:
1839: Status = FALSE;
1840: goto Restore3;
1841:
1842: }
1843:
1844: //
1845: // Write ~IMR
1846: //
1847:
1848: NtStatus = DetectWritePortUchar(InterfaceType,
1849: BusNumber,
1850: IoBaseAddress + 0xF,
1851: (UCHAR)(~IMRValue)
1852: );
1853:
1854: if (NtStatus != STATUS_SUCCESS) {
1855:
1856: //
1857: // Change to page 0
1858: //
1859:
1860: DetectWritePortUchar(InterfaceType,
1861: BusNumber,
1862: IoBaseAddress,
1863: 0x21
1864: );
1865:
1866: Status = FALSE;
1867: goto Restore3;
1868:
1869: }
1870:
1871: //
1872: // switch to page 2
1873: //
1874:
1875: NtStatus = DetectWritePortUchar(InterfaceType,
1876: BusNumber,
1877: IoBaseAddress,
1878: 0xA1
1879: );
1880:
1881: if (NtStatus != STATUS_SUCCESS) {
1882:
1883: //
1884: // Change to page 0
1885: //
1886:
1887: DetectWritePortUchar(InterfaceType,
1888: BusNumber,
1889: IoBaseAddress,
1890: 0x21
1891: );
1892:
1893: Status = FALSE;
1894: goto Restore3;
1895:
1896: }
1897:
1898: //
1899: // Read IMR
1900: //
1901:
1902: NtStatus = DetectReadPortUchar(InterfaceType,
1903: BusNumber,
1904: IoBaseAddress + 0xF,
1905: &Value
1906: );
1907:
1908: if (NtStatus != STATUS_SUCCESS) {
1909:
1910: //
1911: // Change to page 0
1912: //
1913:
1914: DetectWritePortUchar(InterfaceType,
1915: BusNumber,
1916: IoBaseAddress,
1917: 0x21
1918: );
1919:
1920: Status = FALSE;
1921: goto Restore3;
1922:
1923: }
1924:
1925: //
1926: // Are they the same?
1927: //
1928:
1929: if ((UCHAR)(Value & 0x3F) == (UCHAR)(IMRValue)) {
1930:
1931: Status = FALSE;
1932:
1933: }
1934:
1935: //
1936: // Change to page 0
1937: //
1938:
1939: DetectWritePortUchar(InterfaceType,
1940: BusNumber,
1941: IoBaseAddress,
1942: 0x21
1943: );
1944:
1945: Restore3:
1946:
1947: DetectWritePortUchar(InterfaceType,
1948: BusNumber,
1949: IoBaseAddress + 0x3,
1950: SavedOffset3
1951: );
1952:
1953: Restore2:
1954:
1955: DetectWritePortUchar(InterfaceType,
1956: BusNumber,
1957: IoBaseAddress,
1958: SavedOffset0
1959: );
1960:
1961: Restore1:
1962:
1963: DetectWritePortUchar(InterfaceType,
1964: BusNumber,
1965: IoBaseAddress + 0xF,
1966: SavedOffsetF
1967: );
1968:
1969: Fail:
1970:
1971: return(Status);
1972:
1973: }
1974:
1975: VOID
1976: Send8390Packet(
1977: IN INTERFACE_TYPE InterfaceType,
1978: IN ULONG BusNumber,
1979: IN ULONG IoBaseAddress,
1980: IN ULONG MemoryBaseAddress,
1981: IN COPY_ROUTINE CardCopyDownBuffer,
1982: IN UCHAR *NetworkAddress
1983: )
1984:
1985: /*++
1986:
1987: Routine Description:
1988:
1989: This routine creates an interrupt on an 8390 chip. The only way to
1990: do this is to actually transmit a packet. So, we put the card in
1991: loopback mode and let 'er rip.
1992:
1993: Arguments:
1994:
1995: InterfaceType - Any bus type.
1996:
1997: BusNumber - The bus number of the bus in the system.
1998:
1999: IoBaseAddress - The IoBaseAddress to check.
2000:
2001: MemoryBaseAddress - The MemoryBaseAddress (if applicable) to copy a p
2002: packet to for transmission.
2003:
2004: CardCopyDownBuffer - A routine for copying a packet onto a card.
2005:
2006: NetworkAddress - The network address of the machine.
2007:
2008: Return Value:
2009:
2010: None.
2011:
2012: --*/
2013:
2014: {
2015:
2016: #define TEST_LEN 60
2017: #define MAGIC_NUM 0x92
2018:
2019: NTSTATUS NtStatus;
2020:
2021: UCHAR TestPacket[TEST_LEN] = {0}; // a dummy packet.
2022:
2023: memcpy(TestPacket, NetworkAddress, 6);
2024: memcpy(TestPacket+6, NetworkAddress, 6);
2025: TestPacket[12] = 0x00;
2026: TestPacket[13] = 0x00;
2027: TestPacket[TEST_LEN-1] = MAGIC_NUM;
2028:
2029: //
2030: // First construct TestPacket.
2031: //
2032:
2033: TestPacket[TEST_LEN-1] = MAGIC_NUM;
2034:
2035: //
2036: // Now copy down TestPacket and start the transmission.
2037: //
2038:
2039: (*CardCopyDownBuffer)(InterfaceType,
2040: BusNumber,
2041: IoBaseAddress,
2042: MemoryBaseAddress,
2043: TestPacket,
2044: TEST_LEN
2045: );
2046:
2047: NtStatus = DetectWritePortUchar(InterfaceType,
2048: BusNumber,
2049: IoBaseAddress + 0x4,
2050: (UCHAR)(MemoryBaseAddress >> 8)
2051: );
2052:
2053:
2054: if (NtStatus != STATUS_SUCCESS) {
2055: return;
2056: }
2057:
2058:
2059: NtStatus = DetectWritePortUchar(InterfaceType,
2060: BusNumber,
2061: IoBaseAddress + 0x6,
2062: 0x0
2063: );
2064:
2065:
2066: if (NtStatus != STATUS_SUCCESS) {
2067: return;
2068: }
2069:
2070:
2071: NtStatus = DetectWritePortUchar(InterfaceType,
2072: BusNumber,
2073: IoBaseAddress + 0x5,
2074: (UCHAR)(TEST_LEN)
2075: );
2076:
2077:
2078: if (NtStatus != STATUS_SUCCESS) {
2079: return;
2080: }
2081:
2082: NtStatus = DetectWritePortUchar(InterfaceType,
2083: BusNumber,
2084: IoBaseAddress,
2085: 0x26
2086: );
2087:
2088:
2089: if (NtStatus != STATUS_SUCCESS) {
2090: return;
2091: }
2092:
2093: //
2094: // We pause here to allow the xmit to complete so that we can ACK
2095: // it below - leaving the card in a valid state.
2096: //
2097:
2098: {
2099: UCHAR i;
2100: UCHAR RegValue;
2101:
2102: for (i=0;i != 0xFF;i++) {
2103:
2104: //
2105: // check for send completion
2106: //
2107:
2108: NtStatus = DetectReadPortUchar(InterfaceType,
2109: BusNumber,
2110: IoBaseAddress + 0x7,
2111: &RegValue
2112: );
2113:
2114:
2115: if (NtStatus != STATUS_SUCCESS) {
2116: return;
2117: }
2118:
2119: if (RegValue & 0xA) {
2120: break;
2121: }
2122:
2123: }
2124:
2125: }
2126:
2127: //
2128: // Turn off any interrupts
2129: //
2130:
2131: NtStatus = DetectWritePortUchar(InterfaceType,
2132: BusNumber,
2133: IoBaseAddress + 0xF,
2134: 0x00
2135: );
2136:
2137:
2138: if (NtStatus != STATUS_SUCCESS) {
2139: return;
2140: }
2141:
2142: //
2143: // Acknowledge any interrupts that are floating around.
2144: //
2145:
2146: NtStatus = DetectWritePortUchar(InterfaceType,
2147: BusNumber,
2148: IoBaseAddress + 0xE,
2149: 0xFF
2150: );
2151:
2152:
2153: if (NtStatus != STATUS_SUCCESS) {
2154: return;
2155: }
2156:
2157: return;
2158:
2159: }
2160:
2161: PVOID
2162: DetectAllocateHeap(
2163: IN ULONG Size
2164: )
2165: {
2166: PVOID pv = malloc( Size ) ;
2167: if ( Size )
2168: memset( pv, 0, Size ) ;
2169: return pv ;
2170: }
2171:
2172: VOID
2173: DetectFreeHeap(
2174: IN PVOID BaseAddress
2175: )
2176: {
2177: free( BaseAddress ) ;
2178: }
2179:
2180:
2181:
2182: // End of MSNCDET.C
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.