|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1992 Microsoft Corporation
4:
5: Module Name:
6:
7: Detect.c
8:
9: Abstract:
10:
11: This is the main file for the autodetection DLL for all the net cards
12: which MS is shipping with Windows NT.
13:
14: --*/
15:
16: #include <ntddk.h>
17: #include <ntddnetd.h>
18:
19: #include <windef.h>
20:
21: // FUDGE the definition of LPSECURITY_ATTRIBUTES
22: typedef void * LPSECURITY_ATTRIBUTES ;
23:
24: //
25: // File System time stamps are represented with the following structure:
26: //
27:
28: typedef struct _FILETIME {
29: DWORD dwLowDateTime;
30: DWORD dwHighDateTime;
31: } FILETIME, *PFILETIME, *LPFILETIME;
32:
33: // Prototype "borrowed" from WINUSER.H
34: extern int WINAPIV wsprintfW(LPWSTR, LPCWSTR, ...);
35: // Prototype "borrowed" from WINBASE.H
36: VOID WINAPI Sleep( DWORD dwMilliseconds );
37:
38: #include <winreg.h>
39:
40: #include <stdio.h>
41: #include <stdlib.h>
42: #include <string.h>
43: #include "detect.h"
44:
45:
46: #if DBG
47: #define STATIC
48: #else
49: #define STATIC static
50: #endif
51:
52:
53: #define MAX_BUS_INFO_SIZE 0x4000 // 16kb
54:
55: STATIC
56: BOOLEAN
57: GetBusTypeKey(
58: IN ULONG BusNumber,
59: const CHAR * BusTypeName,
60: INT InterfaceType,
61: OUT PVOID *InfoHandle
62: )
63:
64: /*++
65:
66: Routine Description:
67:
68: This routine finds the Microchannel bus with BusNumber in the
69: registry and returns a handle for the config information.
70:
71: Arguments:
72:
73: BusNumber - The bus number of the bus to search for.
74: BusTypeName - String name of bus type to search for
75: InterfaceType - Interface type numeric id.
76: InfoHandle - The resulting root in the registry.
77:
78: Return Value:
79:
80: TRUE if nothing went wrong, else FALSE.
81:
82: --*/
83: {
84: static PSTR BusTypePathBase = "Hardware\\Description\\System\\";
85: static PSTR ConfigData = "Configuration Data";
86: CHAR BusTypePath [MAX_PATH] ;
87: PUCHAR BufferPointer = NULL ;
88: char SubkeyName [MAX_PATH] ;
89: PCM_FULL_RESOURCE_DESCRIPTOR FullResource;
90: HKEY BusTypeHandle = NULL,
91: BusHandle = NULL ;
92: FILETIME LastWrite ;
93: ULONG Index;
94: DWORD Type,
95: BufferSize,
96: NameSize ;
97: LONG err ;
98: BOOL Result = FALSE ;
99:
100: *InfoHandle = NULL;
101:
102: if (BusNumber > 98)
103: return FALSE;
104:
105: //
106: // Open the root.
107: //
108: strcpy( BusTypePath, BusTypePathBase ) ;
109: strcat( BusTypePath, BusTypeName );
110:
111: if ( err = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
112: BusTypePath,
113: 0,
114: KEY_READ,
115: & BusTypeHandle ) )
116: {
117: return FALSE ;
118: }
119:
120: for ( Index = 0 ; ! Result ; Index++ )
121: {
122: if ( BufferPointer )
123: {
124: free( BufferPointer ) ;
125: BufferPointer = NULL ;
126: }
127: if ( BusHandle )
128: {
129: RegCloseKey( BusHandle ) ;
130: BusHandle = NULL ;
131: }
132:
133: //
134: // Enumerate through keys, searching for the proper bus number
135: //
136: NameSize = sizeof SubkeyName ;
137: err = RegEnumKeyExA( BusTypeHandle,
138: Index,
139: SubkeyName,
140: & NameSize,
141: 0,
142: NULL,
143: 0,
144: & LastWrite ) ;
145: if ( err )
146: {
147: break ;
148: }
149:
150: //
151: // Open the BusType root + Bus Number
152: //
153:
154: err = RegOpenKeyExA( BusTypeHandle,
155: SubkeyName,
156: 0,
157: KEY_READ,
158: & BusHandle ) ;
159: if ( err )
160: {
161: continue ;
162: }
163:
164: BufferPointer = (PUCHAR) malloc( BufferSize = MAX_BUS_INFO_SIZE ) ;
165: if ( BufferPointer == NULL )
166: {
167: break ;
168: }
169:
170: err = RegQueryValueExA( BusHandle,
171: ConfigData,
172: NULL,
173: & Type,
174: BufferPointer,
175: & BufferSize ) ;
176: if ( err )
177: {
178: break ;
179: }
180:
181: //
182: // Search for our bus number and type
183: //
184: FullResource = (PCM_FULL_RESOURCE_DESCRIPTOR) BufferPointer;
185:
186: Result = FullResource->InterfaceType == InterfaceType
187: && FullResource->BusNumber == BusNumber ;
188: }
189:
190: if ( BusTypeHandle )
191: RegCloseKey( BusTypeHandle ) ;
192: if ( BusHandle )
193: RegCloseKey( BusHandle ) ;
194:
195: if ( Result )
196: {
197: *InfoHandle = BufferPointer ;
198: }
199: else
200: if ( BufferPointer )
201: {
202: free( BufferPointer ) ;
203: }
204:
205: return Result ;
206:
207: }
208:
209:
210:
211: BOOLEAN
212: GetMcaKey(
213: IN ULONG BusNumber,
214: OUT PVOID *InfoHandle
215: )
216:
217: /*++
218:
219: Routine Description:
220:
221: This routine finds the Microchannel bus with BusNumber in the
222: registry and returns a handle for the config information.
223:
224: Arguments:
225:
226: BusNumber - The bus number of the bus to search for.
227:
228: InfoHandle - The resulting root in the registry.
229:
230: Return Value:
231:
232: TRUE if nothing went wrong, else FALSE.
233:
234: --*/
235: {
236: return GetBusTypeKey( BusNumber,
237: "MultifunctionAdapter",
238: MicroChannel,
239: InfoHandle ) ;
240: }
241:
242:
243: BOOLEAN
244: GetMcaPosId(
245: IN PVOID BusHandle,
246: IN ULONG SlotNumber,
247: OUT PULONG PosId
248: )
249:
250: /*++
251:
252: Routine Description:
253:
254: This routine returns the PosId of an adapter in SlotNumber of an MCA bus.
255:
256: Arguments:
257:
258: BusHandle - Handle returned by GetMcaKey().
259:
260: SlotNumber - the desired slot number
261:
262: PosId - the PosId.
263:
264: Return Value:
265:
266: TRUE if nothing went wrong, else FALSE.
267:
268: --*/
269:
270: {
271: PCM_FULL_RESOURCE_DESCRIPTOR FullResource;
272: PCM_PARTIAL_RESOURCE_LIST ResourceList;
273: ULONG i;
274: ULONG TotalSlots;
275: PCM_MCA_POS_DATA PosData;
276:
277: FullResource = (PCM_FULL_RESOURCE_DESCRIPTOR) BusHandle ;
278: ResourceList = &FullResource->PartialResourceList;
279:
280: //
281: // Find the device-specific information, which is where the POS data is.
282: //
283: for ( i = 0 ; i < ResourceList->Count; i++ )
284: {
285: if (ResourceList->PartialDescriptors[i].Type == CmResourceTypeDeviceSpecific)
286: break;
287: }
288:
289: if (i == ResourceList->Count) {
290:
291: //
292: // Couldn't find device-specific information.
293: //
294:
295: return FALSE;
296: }
297:
298: TotalSlots = ResourceList->PartialDescriptors[i].u.DeviceSpecificData.DataSize;
299:
300: TotalSlots = TotalSlots / sizeof(CM_MCA_POS_DATA);
301:
302: if (SlotNumber <= TotalSlots) {
303:
304: PosData = (PCM_MCA_POS_DATA)(&ResourceList->PartialDescriptors[i+1]);
305: PosData += (SlotNumber - 1);
306:
307: *PosId = PosData->AdapterId;
308: return(TRUE);
309:
310: }
311:
312: return(FALSE);
313:
314: }
315:
316:
317: VOID
318: DeleteMcaKey(
319: IN PVOID BusHandle
320: )
321:
322: /*++
323:
324: Routine Description:
325:
326: This routine frees resources associated with an MCA handle.
327:
328: Arguments:
329:
330: BusHandle - Handle returned by GetMcaKey().
331:
332: Return Value:
333:
334: None.
335:
336: --*/
337: {
338: free( BusHandle ) ;
339: }
340:
341:
342: BOOLEAN
343: GetEisaKey(
344: IN ULONG BusNumber,
345: OUT PVOID *InfoHandle
346: )
347:
348: /*++
349:
350: Routine Description:
351:
352: This routine finds the Eisa bus with BusNumber in the
353: registry and returns a handle for the config information.
354:
355: Arguments:
356:
357: BusNumber - The bus number of the bus to search for.
358:
359: InfoHandle - The resulting root in the registry.
360:
361: Return Value:
362:
363: TRUE if nothing went wrong, else FALSE.
364:
365: --*/
366: {
367: return GetBusTypeKey( BusNumber,
368: "EisaAdapter",
369: Eisa,
370: InfoHandle ) ;
371: }
372:
373:
374: BOOLEAN
375: GetEisaCompressedId(
376: IN PVOID BusHandle,
377: IN ULONG SlotNumber,
378: OUT PULONG CompressedId
379: )
380:
381: /*++
382:
383: Routine Description:
384:
385: This routine returns the PosId of an adapter in SlotNumber of an MCA bus.
386:
387: Arguments:
388:
389: BusHandle - Handle returned by GetEisaKey().
390:
391: SlotNumber - the desired slot number
392:
393: CompressedId - EISA Id in the slot desired.
394:
395: Return Value:
396:
397: TRUE if nothing went wrong, else FALSE.
398:
399: --*/
400:
401: {
402: PCM_FULL_RESOURCE_DESCRIPTOR FullResource;
403: PCM_PARTIAL_RESOURCE_LIST ResourceList;
404: PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
405: ULONG i;
406: ULONG TotalDataSize;
407: ULONG SlotDataSize;
408: PCM_EISA_SLOT_INFORMATION SlotInformation;
409:
410: FullResource = (PCM_FULL_RESOURCE_DESCRIPTOR) BusHandle;
411: ResourceList = &FullResource->PartialResourceList;
412:
413: //
414: // Find the device-specific information, which is where the POS data is.
415: //
416: for (i=0; i<ResourceList->Count; i++) {
417: if (ResourceList->PartialDescriptors[i].Type == CmResourceTypeDeviceSpecific) {
418: break;
419: }
420: }
421:
422: if (i == ResourceList->Count) {
423:
424: //
425: // Couldn't find device-specific information.
426: //
427:
428: return FALSE;
429: }
430:
431:
432: //
433: // Bingo!
434: //
435:
436: ResourceDescriptor = &(ResourceList->PartialDescriptors[i]);
437:
438: TotalDataSize = ResourceDescriptor->u.DeviceSpecificData.DataSize;
439:
440: SlotInformation = (PCM_EISA_SLOT_INFORMATION)
441: ((PUCHAR)ResourceDescriptor +
442: sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
443:
444: while (((LONG)TotalDataSize) > 0) {
445:
446: if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) {
447:
448: SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION);
449:
450: } else {
451:
452: SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) +
453: SlotInformation->NumberFunctions *
454: sizeof(CM_EISA_FUNCTION_INFORMATION);
455: }
456:
457: if (SlotDataSize > TotalDataSize) {
458:
459: //
460: // Something is wrong again
461: //
462:
463: return FALSE;
464:
465: }
466:
467: if (SlotNumber != 0) {
468:
469: SlotNumber--;
470:
471: SlotInformation = (PCM_EISA_SLOT_INFORMATION)
472: ((PUCHAR)SlotInformation + SlotDataSize);
473:
474: TotalDataSize -= SlotDataSize;
475:
476: continue;
477:
478: }
479:
480: //
481: // This is our slot
482: //
483:
484: break;
485:
486: }
487:
488: if ((SlotNumber != 0) || (TotalDataSize == 0)) {
489:
490: //
491: // No such slot number
492: //
493:
494: return(FALSE);
495:
496: }
497:
498: //
499: // End loop
500: //
501:
502: *CompressedId = SlotInformation->CompressedId & 0x00FFFFFF;
503:
504: return(TRUE);
505:
506: }
507:
508: VOID
509: DeleteEisaKey(
510: IN PVOID BusHandle
511: )
512:
513: /*++
514:
515: Routine Description:
516:
517: This routine frees resources associated with an EISA handle.
518:
519: Arguments:
520:
521: BusHandle - Handle returned by GetEisaKey().
522:
523: Return Value:
524:
525: None.
526:
527: --*/
528: {
529: free( BusHandle ) ;
530: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.