mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
798 lines
15 KiB
798 lines
15 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
detmips.c
|
|
|
|
Abstract:
|
|
|
|
This is the main file for the autodetection DLL for all the sonic.sys
|
|
which MS is shipping with Windows NT.
|
|
|
|
Author:
|
|
|
|
Sean Selitrennikoff (SeanSe) October 1992.
|
|
|
|
Environment:
|
|
|
|
|
|
Revision History:
|
|
|
|
5/15/96 kyleb Added support for the SNI box.
|
|
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
#include <windows.h>
|
|
#include <ntstatus.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "ntddnetd.h"
|
|
#include "detect.h"
|
|
|
|
|
|
static BOOLEAN fPrintDbgInfo = FALSE;
|
|
|
|
#if DBG
|
|
#define DBGPRINT(a) { if(fPrintDbgInfo) { DbgPrint a; }}
|
|
#else
|
|
#define DBGPRINT(a)
|
|
#endif
|
|
|
|
|
|
//
|
|
// Individual card detection routines
|
|
//
|
|
|
|
|
|
//
|
|
// List of all the adapters supported in this file, this cannot be > 256
|
|
// because of the way tokens are generated.
|
|
//
|
|
//
|
|
// NOTE : If you change the index of an adapter, be sure the change it in
|
|
// MipsQueryCfgHandler() and MipsVerifyCfgHandler() as well!
|
|
//
|
|
|
|
static ADAPTER_INFO Adapters[] =
|
|
{
|
|
{
|
|
1000,
|
|
L"SONIC",
|
|
L"\0",
|
|
NULL,
|
|
1000
|
|
},
|
|
{
|
|
1100,
|
|
L"SNIMACx00",
|
|
L"\0",
|
|
NULL,
|
|
1000
|
|
}
|
|
};
|
|
|
|
|
|
//
|
|
// Structure for holding a particular adapter's complete information
|
|
//
|
|
typedef struct _MIPS_ADAPTER
|
|
{
|
|
LONG CardType;
|
|
INTERFACE_TYPE InterfaceType;
|
|
ULONG BusNumber;
|
|
}
|
|
MIPS_ADAPTER,
|
|
*PMIPS_ADAPTER;
|
|
|
|
|
|
extern
|
|
LONG
|
|
MipsIdentifyHandler(
|
|
IN LONG lIndex,
|
|
IN WCHAR * pwchBuffer,
|
|
IN LONG cwchBuffSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns information about the netcards supported by
|
|
this file.
|
|
|
|
Arguments:
|
|
|
|
lIndex - The index of the netcard being address. The first
|
|
cards information is at index 1000, the second at 1100, etc.
|
|
|
|
pwchBuffer - Buffer to store the result into.
|
|
|
|
cwchBuffSize - Number of bytes in pwchBuffer
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
LONG NumberOfAdapters;
|
|
LONG Code = lIndex % 100;
|
|
LONG Length;
|
|
LONG i;
|
|
|
|
DBGPRINT(("==>MipsIdentifyHandler\n"));
|
|
|
|
NumberOfAdapters = sizeof(Adapters) / sizeof(ADAPTER_INFO);
|
|
|
|
DBGPRINT(("MipsIdentifyHandler: Number of adapters: %u\n", NumberOfAdapters));
|
|
|
|
lIndex = lIndex - Code;
|
|
|
|
DBGPRINT(("MipsIdentifyHandler: Index: %u, Code: %u\n", lIndex, Code));
|
|
|
|
if (((lIndex / 100) - 10) < NumberOfAdapters)
|
|
{
|
|
for (i = 0; i < NumberOfAdapters; i++)
|
|
{
|
|
if (Adapters[i].Index == lIndex)
|
|
{
|
|
switch (Code)
|
|
{
|
|
case 0:
|
|
//
|
|
// Find the string length
|
|
//
|
|
Length = UnicodeStrLen(Adapters[i].InfId);
|
|
|
|
Length ++;
|
|
|
|
if (cwchBuffSize < Length)
|
|
{
|
|
DBGPRINT(("MipsIdentifyHandler: cwchBuffSize too small\n"));
|
|
DBGPRINT(("<==MipsIdentifyHandler\n"));
|
|
|
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|
}
|
|
|
|
memcpy((PVOID)pwchBuffer, Adapters[i].InfId, Length * sizeof(WCHAR));
|
|
break;
|
|
|
|
case 3:
|
|
//
|
|
// Maximum value is 1000
|
|
//
|
|
if (cwchBuffSize < 5)
|
|
{
|
|
DBGPRINT(("MipsIdentifyHandler: cwchBuffSize too small\n"));
|
|
DBGPRINT(("<==MipsIdentifyHandler\n"));
|
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|
}
|
|
|
|
wsprintf((PVOID)pwchBuffer, L"%d", Adapters[i].SearchOrder);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DBGPRINT(("MipsIdentifyHandler: Invalid code\n"));
|
|
DBGPRINT(("<==MipsIdentifyHandler\n"));
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
DBGPRINT(("<==MipsIdentifyHandler\n"));
|
|
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
DBGPRINT(("MipsIdentifyHandler: Could not find adapter: %u\n", lIndex));
|
|
DBGPRINT(("<==MipsIdentifyHandler\n"));
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
DBGPRINT(("<==MipsIdentifyHandler\n"));
|
|
|
|
return(ERROR_NO_MORE_ITEMS);
|
|
}
|
|
|
|
|
|
extern
|
|
LONG
|
|
MipsFirstNextHandler(
|
|
IN LONG lNetcardId,
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber,
|
|
IN BOOL fFirst,
|
|
OUT PVOID *ppvToken,
|
|
OUT LONG *lConfidence
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine finds the instances of a physical adapter identified
|
|
by the NetcardId.
|
|
|
|
Arguments:
|
|
|
|
lNetcardId - The index of the netcard being address. The first
|
|
cards information is id 1000, the second id 1100, etc.
|
|
|
|
InterfaceType - Either Isa, or Eisa.
|
|
|
|
BusNumber - The bus number of the bus to search.
|
|
|
|
fFirst - TRUE is we are to search for the first instance of an
|
|
adapter, FALSE if we are to continue search from a previous stopping
|
|
point.
|
|
|
|
ppvToken - A pointer to a handle to return to identify the found
|
|
instance
|
|
|
|
lConfidence - A pointer to a long for storing the confidence factor
|
|
that the card exists.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
PWSTR MultifunctionAdapter = L"\\Registry\\Machine\\Hardware\\Description\\System\\MultifunctionAdapter\\0\\NetworkController\\0";
|
|
PWSTR BusName = L"SNI-Internal Bus";
|
|
UNICODE_STRING RootName;
|
|
HANDLE hRoot = NULL;
|
|
PWSTR Identifier = L"Identifier";
|
|
UNICODE_STRING Id;
|
|
UINT c;
|
|
NTSTATUS Status;
|
|
ULONG cbNeeded;
|
|
ULONG cbRead;
|
|
BOOLEAN fFailure;
|
|
PWSTR ValueData;
|
|
|
|
PKEY_VALUE_FULL_INFORMATION FullInfo = NULL;
|
|
|
|
DBGPRINT(("MipsFirstNextHandler\n"));
|
|
|
|
//
|
|
// I don't have any faith.
|
|
//
|
|
*lConfidence = 0;
|
|
|
|
if (InterfaceType != Internal)
|
|
{
|
|
DBGPRINT(("MipsFirstNextHandler: Invalid InterfaceType: %u\n", InterfaceType));
|
|
DBGPRINT(("<==MipsFirstNextHandler\n"));
|
|
|
|
return(0);
|
|
}
|
|
|
|
do
|
|
{
|
|
//
|
|
// Read the registry and see if this is an SNI adapter.
|
|
//
|
|
RtlInitUnicodeString(&RootName, MultifunctionAdapter);
|
|
|
|
//
|
|
// Initialize the attributes for the root.
|
|
//
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&RootName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
(HANDLE)NULL,
|
|
NULL);
|
|
|
|
//
|
|
// Open the root.
|
|
//
|
|
Status = NtOpenKey(&hRoot, KEY_READ, &ObjectAttributes);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DBGPRINT(("Failed to open the bus key\n"));
|
|
break;
|
|
}
|
|
|
|
RtlInitUnicodeString(&Id, Identifier);
|
|
|
|
//
|
|
// Get the value for the Identifier.
|
|
//
|
|
Status = NtQueryValueKey(
|
|
hRoot,
|
|
&Id,
|
|
KeyValueFullInformation,
|
|
NULL,
|
|
0,
|
|
&cbNeeded);
|
|
if (STATUS_OBJECT_NAME_NOT_FOUND == Status)
|
|
{
|
|
DBGPRINT(("Unable to query Identifier value\n"));
|
|
break;
|
|
}
|
|
|
|
FullInfo = DetectAllocateHeap(cbNeeded);
|
|
if (NULL == FullInfo)
|
|
{
|
|
DBGPRINT(("Failed to allocate memory for the identifier information\n"));
|
|
break;
|
|
}
|
|
|
|
Status = NtQueryValueKey(
|
|
hRoot,
|
|
&Id,
|
|
KeyValueFullInformation,
|
|
FullInfo,
|
|
cbNeeded,
|
|
&cbRead);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DBGPRINT(("Failed to read the information\n"));
|
|
break;
|
|
}
|
|
|
|
//
|
|
// First verify that this is the correct type of key.
|
|
//
|
|
if (REG_SZ == FullInfo->Type)
|
|
{
|
|
//
|
|
// Get a pointer to the name.
|
|
//
|
|
ValueData = (PWSTR)((PUCHAR)FullInfo + FullInfo->DataOffset);
|
|
|
|
//
|
|
// Check for the bus name...
|
|
//
|
|
if ((0 == _wcsicmp(ValueData, L"i82596CA")) ||
|
|
(0 == _wcsicmp(ValueData, L"i82596DX")))
|
|
{
|
|
//
|
|
// We've got an sni nic, let's see if that's what
|
|
// they're lookin' for.
|
|
//
|
|
if (1100 == lNetcardId)
|
|
{
|
|
*ppvToken = (PVOID)1;
|
|
*lConfidence = 100;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// It's NOT an sni bus. Are we looking for a sonic?
|
|
//
|
|
if (1000 == lNetcardId)
|
|
{
|
|
*ppvToken = (PVOID)0;
|
|
*lConfidence = 100;
|
|
}
|
|
}
|
|
}
|
|
} while (FALSE);
|
|
|
|
if (NULL != FullInfo)
|
|
{
|
|
DetectFreeHeap(FullInfo);
|
|
}
|
|
|
|
if (NULL != hRoot)
|
|
{
|
|
NtClose(hRoot);
|
|
}
|
|
|
|
DBGPRINT(("<==MipsFirstNextHandler\n"));
|
|
return(0);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
MipsOpenHandleHandler(
|
|
IN PVOID pvToken,
|
|
OUT PVOID *ppvHandle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine takes a token returned by FirstNext and converts it
|
|
into a permanent handle.
|
|
|
|
Arguments:
|
|
|
|
Token - The token.
|
|
|
|
ppvHandle - A pointer to the handle, so we can store the resulting
|
|
handle.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
PMIPS_ADAPTER Handle;
|
|
LONG AdapterNumber;
|
|
ULONG BusNumber;
|
|
INTERFACE_TYPE InterfaceType;
|
|
|
|
//
|
|
// Get info from the token
|
|
//
|
|
InterfaceType = Internal;
|
|
|
|
BusNumber = 0;
|
|
|
|
AdapterNumber = ((ULONG)pvToken) & 0xFF;
|
|
|
|
//
|
|
// Store information
|
|
//
|
|
Handle = (PMIPS_ADAPTER)DetectAllocateHeap(sizeof(MIPS_ADAPTER));
|
|
if (Handle == NULL)
|
|
{
|
|
return(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
|
|
//
|
|
// Copy across address
|
|
//
|
|
Handle->CardType = Adapters[AdapterNumber].Index;
|
|
Handle->InterfaceType = InterfaceType;
|
|
Handle->BusNumber = BusNumber;
|
|
|
|
*ppvHandle = (PVOID)Handle;
|
|
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
MipsCreateHandleHandler(
|
|
IN LONG lNetcardId,
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber,
|
|
OUT PVOID *ppvHandle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to force the creation of a handle for cases
|
|
where a card is not found via FirstNext, but the user says it does
|
|
exist.
|
|
|
|
Arguments:
|
|
|
|
lNetcardId - The id of the card to create the handle for.
|
|
|
|
InterfaceType - Internal.
|
|
|
|
BusNumber - The bus number of the bus in the system.
|
|
|
|
ppvHandle - A pointer to the handle, for storing the resulting handle.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
PMIPS_ADAPTER Handle;
|
|
LONG NumberOfAdapters;
|
|
LONG i;
|
|
|
|
if (InterfaceType != Internal)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
NumberOfAdapters = sizeof(Adapters) / sizeof(ADAPTER_INFO);
|
|
|
|
for (i = 0; i < NumberOfAdapters; i++)
|
|
{
|
|
if (Adapters[i].Index == lNetcardId)
|
|
{
|
|
//
|
|
// Store information
|
|
//
|
|
Handle = (PMIPS_ADAPTER)DetectAllocateHeap(sizeof(MIPS_ADAPTER));
|
|
if (Handle == NULL)
|
|
{
|
|
return(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
|
|
//
|
|
// Copy across memory address
|
|
//
|
|
Handle->CardType = lNetcardId;
|
|
Handle->InterfaceType = InterfaceType;
|
|
Handle->BusNumber = BusNumber;
|
|
|
|
*ppvHandle = (PVOID)Handle;
|
|
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
MipsCloseHandleHandler(
|
|
IN PVOID pvHandle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This frees any resources associated with a handle.
|
|
|
|
Arguments:
|
|
|
|
pvHandle - The handle.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
DetectFreeHeap( pvHandle);
|
|
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
MipsQueryCfgHandler(
|
|
IN PVOID pvHandle,
|
|
OUT WCHAR *pwchBuffer,
|
|
IN LONG cwchBuffSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine calls the appropriate driver's query config handler to
|
|
get the parameters for the adapter associated with the handle.
|
|
|
|
Arguments:
|
|
|
|
pvHandle - The handle.
|
|
|
|
pwchBuffer - The resulting parameter list.
|
|
|
|
cwchBuffSize - Length of the given buffer in WCHARs.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
PMIPS_ADAPTER Adapter = (PMIPS_ADAPTER)(pvHandle);
|
|
|
|
//
|
|
// Build resulting buffer
|
|
//
|
|
|
|
//
|
|
// Copy in final \0
|
|
//
|
|
if (cwchBuffSize < 2)
|
|
{
|
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|
}
|
|
|
|
pwchBuffer[0] = L'\0';
|
|
pwchBuffer[1] = L'\0';
|
|
|
|
return(0);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
MipsVerifyCfgHandler(
|
|
IN PVOID pvHandle,
|
|
IN WCHAR *pwchBuffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine verifys that a given parameter list is complete and
|
|
correct for the adapter associated with the handle.
|
|
|
|
Arguments:
|
|
|
|
pvHandle - The handle.
|
|
|
|
pwchBuffer - The parameter list.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
MipsQueryMaskHandler(
|
|
IN LONG lNetcardId,
|
|
OUT WCHAR *pwchBuffer,
|
|
IN LONG cwchBuffSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns the parameter list information for a specific
|
|
network card.
|
|
|
|
Arguments:
|
|
|
|
lNetcardId - The id of the desired netcard.
|
|
|
|
pwchBuffer - The buffer for storing the parameter information.
|
|
|
|
cwchBuffSize - Length of pwchBuffer in WCHARs.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
WCHAR *Result;
|
|
LONG Length;
|
|
LONG NumberOfAdapters;
|
|
LONG i;
|
|
|
|
//
|
|
// Find the adapter
|
|
//
|
|
NumberOfAdapters = sizeof(Adapters) / sizeof(ADAPTER_INFO);
|
|
|
|
for (i = 0; i < NumberOfAdapters; i++)
|
|
{
|
|
if (Adapters[i].Index == lNetcardId)
|
|
{
|
|
Result = Adapters[i].Parameters;
|
|
|
|
//
|
|
// Find the string length (Ends with 2 NULLs)
|
|
//
|
|
for (Length=0; ; Length++)
|
|
{
|
|
if (Result[Length] == L'\0')
|
|
{
|
|
++Length;
|
|
|
|
if (Result[Length] == L'\0')
|
|
{
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
Length++;
|
|
|
|
if (cwchBuffSize < Length)
|
|
{
|
|
return(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
|
|
memcpy((PVOID)pwchBuffer, Result, Length * sizeof(WCHAR));
|
|
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
MipsParamRangeHandler(
|
|
IN LONG lNetcardId,
|
|
IN WCHAR *pwchParam,
|
|
OUT LONG *plValues,
|
|
OUT LONG *plBuffSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns a list of valid values for a given parameter name
|
|
for a given card.
|
|
|
|
Arguments:
|
|
|
|
lNetcardId - The Id of the card desired.
|
|
|
|
pwchParam - A WCHAR string of the parameter name to query the values of.
|
|
|
|
plValues - A pointer to a list of LONGs into which we store valid values
|
|
for the parameter.
|
|
|
|
plBuffSize - At entry, the length of plValues in LONGs. At exit, the
|
|
number of LONGs stored in plValues.
|
|
|
|
Return Value:
|
|
|
|
0 if nothing went wrong, else the appropriate WINERROR.H value.
|
|
|
|
--*/
|
|
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
extern
|
|
LONG
|
|
MipsQueryParameterNameHandler(
|
|
IN WCHAR *pwchParam,
|
|
OUT WCHAR *pwchBuffer,
|
|
IN LONG cwchBufferSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns a localized, displayable name for a specific parameter. All the
|
|
parameters that this file uses are define by MS, so no strings are
|
|
needed here.
|
|
|
|
Arguments:
|
|
|
|
pwchParam - The parameter to be queried.
|
|
|
|
pwchBuffer - The buffer to store the result into.
|
|
|
|
cwchBufferSize - The length of pwchBuffer in WCHARs.
|
|
|
|
Return Value:
|
|
|
|
ERROR_INVALID_PARAMETER -- To indicate that the MS supplied strings
|
|
should be used.
|
|
|
|
--*/
|
|
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|