snpnt32.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,155 行 · 第 1/2 页
C
1,155 行
Arguments:
This - Context pointer.
HeaderSize - Optional parameter and is a pointer to the header portion of
the data received.
BuffSize - Pointer to the length of the Buffer on entry and contains
the length of the received data on return
Buffer - Pointer to the memory for the received data
SourceAddr - Optional parameter, is a pointer to contain the source
ethernet address on return
DestinationAddr - Optional parameter, is a pointer to contain the destination
ethernet address on return.
Protocol - Optional parameter, is a pointer to contain the Protocol type
from the ethernet header on return.
Returns:
EFI_SUCCESS - A packet is received and put into the buffer.
EFI_BUFFER_TOO_SMALL - The provided buffer is too small to receive the packet.
EFI_NOT_READY - There is no packet received.
--*/
{
SNPNT32_INSTANCE_DATA *Instance;
SNPNT32_GLOBAL_DATA *GlobalData;
INT32 ReturnValue;
Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
GlobalData = Instance->GlobalData;
ASSERT (GlobalData->NtNetUtilityTable.Receive != NULL);
if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {
return EFI_ACCESS_DENIED;
}
ReturnValue = GlobalData->NtNetUtilityTable.Receive (
Instance->InterfaceInfo.InterfaceIndex,
BuffSize,
Buffer
);
NET_UNLOCK (&GlobalData->Lock);
if (ReturnValue < 0) {
if (ReturnValue == -100) {
return EFI_BUFFER_TOO_SMALL;
}
return EFI_DEVICE_ERROR;
} else if (ReturnValue == 0) {
return EFI_NOT_READY;
}
if (HeaderSize != NULL) {
*HeaderSize = 14;
}
if (SourceAddr != NULL) {
NetZeroMem (SourceAddr, sizeof (EFI_MAC_ADDRESS));
NetCopyMem (SourceAddr, ((UINT8 *) Buffer) + 6, 6);
}
if (DestinationAddr != NULL) {
NetZeroMem (DestinationAddr, sizeof (EFI_MAC_ADDRESS));
NetCopyMem (DestinationAddr, ((UINT8 *) Buffer), 6);
}
if (Protocol != NULL) {
*Protocol = *((UINT16 *) (((UINT8 *) Buffer) + 12));
}
return EFI_SUCCESS;
}
SNPNT32_INSTANCE_DATA gSnpNt32InstanceTemplate = {
SNP_NT32_INSTANCE_SIGNATURE, // Signature
{
NULL,
NULL
}, // Entry
NULL, // GlobalData
NULL, // DeviceHandle
NULL, // DevicePath
{ // Snp
EFI_SIMPLE_NETWORK_PROTOCOL_REVISION, // Revision
SnpNt32Start, // Start
SnpNt32Stop, // Stop
SnpNt32Initialize, // Initialize
SnpNt32Reset, // Reset
SnpNt32Shutdown, // Shutdown
SnpNt32ReceiveFilters, // ReceiveFilters
SnpNt32StationAddress, // StationAddress
SnpNt32Statistics, // Statistics
SnpNt32McastIptoMac, // MCastIpToMac
SnpNt32Nvdata, // NvData
SnpNt32GetStatus, // GetStatus
SnpNt32Transmit, // Transmit
SnpNt32Receive, // Receive
NULL, // WaitForPacket
NULL // Mode
},
{ // Mode
EfiSimpleNetworkInitialized, // State
NET_ETHER_ADDR_LEN, // HwAddressSize
NET_ETHER_HEADER_SIZE, // MediaHeaderSize
1500, // MaxPacketSize
0, // NvRamSize
0, // NvRamAccessSize
0, // ReceiveFilterMask
0, // ReceiveFilterSetting
MAX_MCAST_FILTER_CNT, // MaxMCastFilterCount
0, // MCastFilterCount
{
0
}, // MCastFilter
{
0
}, // CurrentAddress
{
0
}, // BroadcastAddress
{
0
}, // PermanentAddress
NET_IFTYPE_ETHERNET, // IfType
FALSE, // MacAddressChangeable
FALSE, // MultipleTxSupported
FALSE, // MediaPresentSupported
TRUE // MediaPresent
},
{
0
} // InterfaceInfo
};
EFI_STATUS
SnpNt32InitializeGlobalData (
IN SNPNT32_GLOBAL_DATA *This
)
/*++
Routine Description:
Initialize the driver's global data.
Arguments:
This - Pointer to the global context data.
Returns:
EFI_SUCCESS - The global data is initialized.
EFI_NOT_FOUND - The required DLL is not found.
--*/
{
EFI_STATUS Status;
CHAR16 *DllFileNameU;
UINT32 Index;
INT32 ReturnValue;
BOOLEAN NetUtilityLibInitDone;
NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer[MAX_INTERFACE_INFO_NUMBER];
SNPNT32_INSTANCE_DATA *Instance;
NET_LIST_ENTRY *Entry;
UINT32 InterfaceCount;
ASSERT (This != NULL);
NetUtilityLibInitDone = FALSE;
InterfaceCount = MAX_INTERFACE_INFO_NUMBER;
NetListInit (&This->InstanceList);
NET_GLOBAL_LOCK_INIT (&This->Lock);
//
// Get the WinNT thunk
//
Status = gBS->LocateProtocol (&gEfiWinNtThunkProtocolGuid, NULL, &This->WinNtThunk);
if (EFI_ERROR (Status)) {
return Status;
}
ASSERT (This->WinNtThunk != NULL);
DllFileNameU = NETWORK_LIBRARY_NAME_U;
//
// Load network utility library
//
This->NetworkLibraryHandle = This->WinNtThunk->LoadLibraryEx (DllFileNameU, NULL, 0);
if (NULL == This->NetworkLibraryHandle) {
return EFI_NOT_FOUND;
}
This->NtNetUtilityTable.Initialize = (NT_NET_INITIALIZE) This->WinNtThunk->GetProcAddress (
This->NetworkLibraryHandle,
NETWORK_LIBRARY_INITIALIZE
);
if (NULL == This->NtNetUtilityTable.Initialize) {
Status = EFI_NOT_FOUND;
goto ErrorReturn;
}
This->NtNetUtilityTable.Finalize = (NT_NET_FINALIZE) This->WinNtThunk->GetProcAddress (
This->NetworkLibraryHandle,
NETWORK_LIBRARY_FINALIZE
);
if (NULL == This->NtNetUtilityTable.Finalize) {
Status = EFI_NOT_FOUND;
goto ErrorReturn;
}
This->NtNetUtilityTable.SetReceiveFilter = (NT_NET_SET_RECEIVE_FILTER) This->WinNtThunk->GetProcAddress (
This->NetworkLibraryHandle,
NETWORK_LIBRARY_SET_RCV_FILTER
);
if (NULL == This->NtNetUtilityTable.SetReceiveFilter) {
Status = EFI_NOT_FOUND;
goto ErrorReturn;
}
This->NtNetUtilityTable.Receive = (NT_NET_RECEIVE) This->WinNtThunk->GetProcAddress (
This->NetworkLibraryHandle,
NETWORK_LIBRARY_RECEIVE
);
if (NULL == This->NtNetUtilityTable.Receive) {
Status = EFI_NOT_FOUND;
goto ErrorReturn;
}
This->NtNetUtilityTable.Transmit = (NT_NET_TRANSMIT) This->WinNtThunk->GetProcAddress (
This->NetworkLibraryHandle,
NETWORK_LIBRARY_TRANSMIT
);
if (NULL == This->NtNetUtilityTable.Transmit) {
Status = EFI_NOT_FOUND;
goto ErrorReturn;
}
//
// Initialize the network utility library
// And enumerate the interfaces in NT32 host
//
ReturnValue = This->NtNetUtilityTable.Initialize (&InterfaceCount, &NetInterfaceInfoBuffer[0]);
if (ReturnValue <= 0) {
Status = EFI_DEVICE_ERROR;
goto ErrorReturn;
}
NetUtilityLibInitDone = TRUE;
if (InterfaceCount == 0) {
Status = EFI_NOT_FOUND;
goto ErrorReturn;
}
//
// Create fake SNP instances
//
for (Index = 0; Index < InterfaceCount; Index++) {
Instance = NetAllocatePool (sizeof (SNPNT32_INSTANCE_DATA));
if (NULL == Instance) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorReturn;
}
//
// Copy the content from a template
//
NetCopyMem (Instance, &gSnpNt32InstanceTemplate, sizeof (SNPNT32_INSTANCE_DATA));
//
// Set the interface information.
//
Instance->InterfaceInfo = NetInterfaceInfoBuffer[Index];
//
// Initialize this instance
//
Status = This->InitializeInstanceData (This, Instance);
if (EFI_ERROR (Status)) {
NetFreePool (Instance);
goto ErrorReturn;
}
//
// Insert this instance into the instance list
//
NetListInsertTail (&This->InstanceList, &Instance->Entry);
}
return EFI_SUCCESS;
ErrorReturn:
while (!NetListIsEmpty (&This->InstanceList)) {
Entry = This->InstanceList.ForwardLink;
Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
NetListRemoveEntry (Entry);
This->CloseInstance (This, Instance);
NetFreePool (Instance);
}
if (NetUtilityLibInitDone) {
ASSERT (This->WinNtThunk != NULL);
if (This->NtNetUtilityTable.Finalize != NULL) {
This->NtNetUtilityTable.Finalize ();
This->NtNetUtilityTable.Finalize = NULL;
}
}
return Status;
}
EFI_STATUS
SnpNt32InitializeInstanceData (
IN SNPNT32_GLOBAL_DATA *This,
IN SNPNT32_INSTANCE_DATA *Instance
)
/*++
Routine Description:
Initialize the snpnt32 driver instance.
Arguments:
This - Pointer to the SnpNt32 global data.
Instance - Pointer to the instance context data.
Returns:
EFI_SUCCESS - The driver instance is initialized.
--*/
{
EFI_STATUS Status;
EFI_DEV_PATH Node;
Instance->GlobalData = This;
Instance->Snp.Mode = &Instance->Mode;
//
// Set broadcast address
//
EfiCommonLibSetMem (&Instance->Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);
//
// Copy Current/PermanentAddress MAC address
//
Instance->Mode.CurrentAddress = Instance->InterfaceInfo.MacAddr;
Instance->Mode.PermanentAddress = Instance->InterfaceInfo.MacAddr;
//
// Since the fake SNP is based on a real NIC, to avoid conflict with the host
// NIC network stack, we use a different MAC address.
// So just change the last byte of the MAC address for the real NIC.
//
Instance->Mode.CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++;
//
// Create a fake device path for the instance
//
NetZeroMem (&Node, sizeof (Node));
Node.DevPath.Type = MESSAGING_DEVICE_PATH;
Node.DevPath.SubType = MSG_MAC_ADDR_DP;
SetDevicePathNodeLength (&Node.DevPath, sizeof (MAC_ADDR_DEVICE_PATH));
NetCopyMem (
&Node.MacAddr.MacAddress,
&Instance->Mode.CurrentAddress,
sizeof (EFI_MAC_ADDRESS)
);
Node.MacAddr.IfType = Instance->Mode.IfType;
Instance->DevicePath = EfiAppendDevicePathNode (
NULL,
&Node.DevPath
);
//
// Create a fake device handle for the fake SNP
//
Status = gBS->InstallMultipleProtocolInterfaces (
&Instance->DeviceHandle,
&gEfiSimpleNetworkProtocolGuid,
&Instance->Snp,
&gEfiDevicePathProtocolGuid,
Instance->DevicePath,
NULL
);
if (EFI_ERROR (Status)) {
goto ErrorReturn;
}
return EFI_SUCCESS;
ErrorReturn:
return Status;
}
EFI_STATUS
SnpNt32CloseInstance (
IN SNPNT32_GLOBAL_DATA *This,
IN SNPNT32_INSTANCE_DATA *Instance
)
/*++
Routine Description:
Close the SnpNt32 driver instance.
Arguments:
This - Pointer to the SnpNt32 global data.
Instance - Pointer to the instance context data.
Returns:
EFI_SUCCESS - The instance is closed.
--*/
{
ASSERT (This != NULL);
ASSERT (Instance != NULL);
gBS->UninstallMultipleProtocolInterfaces (
Instance->DeviceHandle,
&gEfiSimpleNetworkProtocolGuid,
&Instance->Snp,
&gEfiDevicePathProtocolGuid,
Instance->DevicePath,
NULL
);
if (Instance->DevicePath != NULL) {
gBS->FreePool (Instance->DevicePath);
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
SnpNt32Unload (
IN EFI_HANDLE ImageHandle
)
/*++
Routine Description:
Unload the SnpNt32 driver.
Arguments:
ImageHandle - The handle of the driver image.
Returns:
EFI_SUCCESS - The driver is unloaded.
other - Some error occurs.
--*/
{
EFI_STATUS Status;
SNPNT32_GLOBAL_DATA *This;
NET_LIST_ENTRY *Entry;
SNPNT32_INSTANCE_DATA *Instance;
This = &gSnpNt32GlobalData;
Status = NetLibDefaultUnload (ImageHandle);
if (EFI_ERROR (Status)) {
return Status;
}
while (!NetListIsEmpty (&This->InstanceList)) {
//
// Walkthrough the interfaces and remove all the SNP instance
//
Entry = This->InstanceList.ForwardLink;
Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
NetListRemoveEntry (Entry);
This->CloseInstance (This, Instance);
NetFreePool (Instance);
}
if (This->NtNetUtilityTable.Finalize != NULL) {
This->NtNetUtilityTable.Finalize ();
}
This->WinNtThunk->FreeLibrary (This->NetworkLibraryHandle);
return EFI_SUCCESS;
}
EFI_DRIVER_ENTRY_POINT (InitializeSnpNt32river)
EFI_STATUS
InitializeSnpNt32river (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Install DriverBinding Protocol for the Win NT Bus driver on the drivers
image handle.
Arguments:
ImageHandle - The handle of this image.
SystemTable - Pointer to the EFI system table.
Returns:
EFI_SUCEESS - The protocols are installed and the SnpNt32 is initialized.
other - Some error occurs.
--*/
{
EFI_STATUS Status;
Status = EfiInitializeDriverLib (ImageHandle, SystemTable);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Install the Driver Protocols
//
Status = NetLibInstallAllDriverProtocolsWithUnload (
ImageHandle,
SystemTable,
&gSnpNt32DriverBinding,
ImageHandle,
&gSnpNt32DriverComponentName,
NULL,
NULL,
SnpNt32Unload
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Initialize the global data
//
Status = SnpNt32InitializeGlobalData (&gSnpNt32GlobalData);
if (EFI_ERROR (Status)) {
SnpNt32Unload (ImageHandle);
}
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?