📄 vmini.c
字号:
NDIS_STATUS Status;
HKEY hkRoot = NULL;
DWORD dwErr;
DWORD dwThreadPriority = DEFAULT_RX_THREAD_PRIORITY;
DEBUGMSG (ZONE_INIT, (TEXT("VMini:: VMiniMInitialize()...\r\n")));
if (VMini.vm_bHalt != TRUE)
{
RETAILMSG (1,
(TEXT("VMini:: Only 1 instance allowed!!\r\n")));
return NDIS_STATUS_FAILURE;
}
//
// Search for correct medium and report back in SelectedMediumIndex...
// We look for 802_3 medium...
//
for (; MediumArraySize > 0; MediumArraySize--)
{
if (MediumArray[MediumArraySize - 1] == NdisMedium802_3)
{
MediumArraySize--;
break;
}
}
if (MediumArray[MediumArraySize] != NdisMedium802_3)
{
DEBUGMSG (ZONE_INIT, (TEXT("VMini:: Error!! ABORT: NDIS_STATUS_UNSUPPORTED_MEDIA...\r\n")));
return NDIS_STATUS_UNSUPPORTED_MEDIA;
}
*SelectedMediumIndex = MediumArraySize;
//
// Save driver hanldles...
//
VMini.vm_VMiniportHandle = VMiniportHandle;
#ifndef NDIS50_MINIPORT
/////////////////////////////////////////////////////////////////////////////
// Register the ADAPTER with NDIS.
// Wrapper basically update the miniport handle, i.e.
// MiniportAdapterContext <-- Adapter
// as well as the BusInterface and DMA Master capability...
// So, we are pretending PCI with BusMaster capability...
//
NdisMSetAttributes(
VMini.vm_VMiniportHandle,
(NDIS_HANDLE)&VMini,
TRUE,
NdisInterfacePci
);
#else
NdisMSetAttributesEx(
VMini.vm_VMiniportHandle,
(NDIS_HANDLE)&VMini,
0,
NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT |
NDIS_ATTRIBUTE_DESERIALIZE |
NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
0);
#endif
//
// Set Network ID...
//
if (!KernelIoControl (
IOCTL_VBRIDGE_GET_ETHERNET_MAC,
NULL,
0,
VMini.vm_PermanentNetworkAddress,
6,
&dwReturnedBytes))
{
//
// Okay, something is wrong!
// The kernel call fails to retrieve the MAC.
// Let's just bail out of here.
//
return NDIS_STATUS_ADAPTER_NOT_FOUND;
}
RETAILMSG (1, (TEXT("Virtual Mini MAC = %x-%x-%x-%x-%x-%x.\r\n"),
(UCHAR)VMini.vm_PermanentNetworkAddress[0],
(UCHAR)VMini.vm_PermanentNetworkAddress[1],
(UCHAR)VMini.vm_PermanentNetworkAddress[2],
(UCHAR)VMini.vm_PermanentNetworkAddress[3],
(UCHAR)VMini.vm_PermanentNetworkAddress[4],
(UCHAR)VMini.vm_PermanentNetworkAddress[5]));
NdisMoveMemory (
VMini.vm_CurrentNetworkAddress,
VMini.vm_PermanentNetworkAddress,
6);
//
// These are currently hardcoded here for simplicity..
// We don't want too many KernelIoControl() calls.
// This is meant to be a bare minimum miniport that is still useful..
//
VMini.vm_MaxListSize = DEFAULT_MULTICASTLIST_MAX;
//
// To serialize the Send routine in this deserialized driver..
// VBridge can't handle multiple accesses..
//
InitializeCriticalSection(&g_csSend);
//
// Prepare our one and only NdisPacket and its accompanying
// NdisBuffer.
//
NdisAllocatePacketPool(
&Status,
&VMini.NdisPacketPool,
1,
0x00);
NdisAllocateBufferPool(
&Status,
&VMini.NdisBufferPool,
1);
NdisAllocatePacket(
&Status,
&VMini.pNdisPacket,
VMini.NdisPacketPool);
#if 0
///
// Register Adapter Shutdown handler...
//
NdisMRegisterAdapterShutdownHandler(
VMiniportHandle,
(PVOID)&VMini,
VMiniMShutdownHandler
);
#endif
VMini.vm_bHalt = FALSE;
//
// Reset the VBridge buffer to start from beginning..
//
dwTxPA = 0x00;
dwRxPA = 0x00;
KernelIoControl(
IOCTL_VBRIDGE_WILD_CARD,
(PVOID)IOCTL_VBRIDGE_WILD_CARD_RESET_BUFFER,
0x00,
NULL,
0x00,
NULL);
//
// Now start the RX thread..
// and set the thread priority according to "Priority256" in
// [HKLM\Comm\VMini]
//
dwErr = RegOpenKeyEx (
HKEY_LOCAL_MACHINE,
TEXT("Comm\\VMini"),
0,
0,
&hkRoot);
if (dwErr == ERROR_SUCCESS)
{
DWORD dwReadPriority;
DWORD dwType;
DWORD dwSize = sizeof(DWORD);
dwErr = RegQueryValueEx(
hkRoot,
TEXT("Priority256"),
0,
&dwType,
(LPBYTE)&dwReadPriority,
&dwSize);
if (dwErr == ERROR_SUCCESS &&
dwSize == sizeof(DWORD) &&
dwType == REG_DWORD)
{
DEBUGMSG (ZONE_INIT,
(TEXT("VMini:: Registry specifies Thread Priority = [%d]\r\n"),
dwReadPriority));
dwThreadPriority = dwReadPriority;
}
RegCloseKey(hkRoot);
}
VMini.vm_hRxThread = CreateThread(
0,
0,
(LPTHREAD_START_ROUTINE)VirtMiniISR,
NULL,
0,
NULL );
RETAILMSG (1,
(TEXT("VMini:: RX thread priority set to: [%d]\r\n"),
dwThreadPriority));
CeSetThreadPriority(
VMini.vm_hRxThread,
dwThreadPriority);
DEBUGMSG (ZONE_INIT, (TEXT("VMini:: VMiniMInitialize() completed successfully..\r\n")));
return NDIS_STATUS_SUCCESS;
} // VMiniMInitialize
////////////////////////////////////////////////////////////////////////////////
// VMiniMQueryInformation()
//
// Routine description:
//
// Returns information about capabilities and status of the driver.
//
// Arguments:
//
// Look at MSDN MiniportQueryInformation() description.
//
// return values:
//
// NDIS_STATUS_XXX
//
NDIS_STATUS
VMiniMQueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
{
return InternalVMiniQueryInformation(
MiniportAdapterContext,
Oid,
InformationBuffer,
InformationBufferLength,
BytesWritten,
BytesNeeded);
} // VMiniMQueryInformation()
////////////////////////////////////////////////////////////////////////////////
// VMiniMSetInformation()
//
// Routine description:
//
// Set/Change the state information that miniport maintains for
// particular OIDs.
//
// Arguments:
//
// Look at MSDN MiniportSetInformation() description.
//
// return values:
//
// NDIS_STATUS_XXX
//
NDIS_STATUS
VMiniMSetInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
{
DEBUGMSG (ZONE_SET, (TEXT("VMiniMSetInformation():: \r\n")));
return InternalVMiniSetInformation(
MiniportAdapterContext,
Oid,
InformationBuffer,
InformationBufferLength,
BytesRead,
BytesNeeded);
} // VMiniMSetInformation()
////////////////////////////////////////////////////////////////////////////////
// CopyFromNdisPacket()
//
// Routine description:
//
// Extract the Ndis Buffer and copy that to pBuffer.
//
// Arguments:
//
// pPacket :: NDIS_PACKET to extract information from.
//
// pBuffer :: Flat buffer to store the extracted information.
//
// pdwTotalLength :: Total length extracted.
//
//
// return values:
//
// None.
//
void
CopyFromNdisPacket(
PNDIS_PACKET pPacket,
PUCHAR pBuffer,
DWORD *pdwTotalLength)
{
PNDIS_BUFFER pCurrentNdisBuffer;
PUCHAR pCurrentBuffer;
DWORD dwCurrentBufferLength;
DWORD dwTotalNdisBuffer;
DWORD dwTotalCopied = 0x00;
DWORD dwTotalPacketLength;
*pdwTotalLength = 0x00;
///
// Get the first buffer.
//
NdisQueryPacket(
pPacket,
NULL,
&dwTotalNdisBuffer,
&pCurrentNdisBuffer,
&dwTotalPacketLength
);
DEBUGMSG (ZONE_SEND, (TEXT("CopyFromNdisPacket():: #Buffer = [%d] -- Total length = [%d] bytes.\r\n"),
dwTotalNdisBuffer,
dwTotalPacketLength));
while (dwTotalNdisBuffer--)
{
//
// Get the buffer...
//
NdisQueryBuffer(
pCurrentNdisBuffer,
&pCurrentBuffer,
&dwCurrentBufferLength
);
if (pCurrentBuffer)
{
memcpy(
pBuffer + dwTotalCopied,
pCurrentBuffer,
dwCurrentBufferLength);
dwTotalCopied += dwCurrentBufferLength;
}
NdisGetNextBuffer(
pCurrentNdisBuffer,
&pCurrentNdisBuffer);
}
DEBUGMSG (ZONE_SEND, (TEXT("CopyFromNdisPacket():: Copied [%d] bytes.\r\n"),
dwTotalCopied));
*pdwTotalLength = dwTotalCopied;
} // CopyFromNdisPacket()
////////////////////////////////////////////////////////////////////////////////
// VMiniMSend()
//
// Routine description:
//
// Implement MiniportSend() function.
//
// Arguments:
//
// Look at MSDN MiniportSend() description.
//
// return values:
//
// None.
//
NDIS_STATUS
VMiniMSend(
IN NDIS_HANDLE MiniPortAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT SendFlags
)
{
DWORD BufferAddress;
PBYTE pVA;
DWORD dwReturnedBytes;
DWORD dwTotalLength;
BOOL bConvert = FALSE;
DEBUGMSG (0, (TEXT("VMiniMSend():: \r\n")));
NdisQueryPacket(
Packet,
NULL,
NULL,
NULL,
&dwTotalLength);
//
// Because VMini & EDBG share the same IP address, we can't allow the
// DHCP release packet to be sent.
// Sending the DHCP release packet will potentially get the DHCP server
// to allocate the IP for other device, hence conflicting with EDBG..
//
if (IsDhcpRelease(Packet))
return NDIS_STATUS_SUCCESS;
EnterCriticalSection (&g_csSend);
if (!KernelIoControl (
IOCTL_VBRIDGE_GET_TX_PACKET,
NULL,
dwTotalLength,
&BufferAddress,
sizeof(DWORD),
&dwReturnedBytes))
{
DEBUGMSG (ZONE_WARNING, (TEXT("VMini:: Warning! UNABLE TO OBTAIN TX BUFFER.. tossing packet.\r\n")));
LeaveCriticalSection(&g_csSend);
return NDIS_STATUS_SUCCESS;
}
//
// Make sure we get 0x8xxxxxxx region since on x86 the 0xAxxxxxxx
// will not work if you pass it into VirtualCopy.
//
if (BufferAddress & 0x20000000)
{
bConvert = TRUE;
BufferAddress &= ~0x20000000;
}
if (!(pVA = PA2VA(BufferAddress, TRUE)))
{
//
// In theory should never fail..
// If we do, let's just exhaust the VBridge's TX buffers..
// i.e we are not returning the buffer we obtained above..
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -