69 lines
2.4 KiB
C
69 lines
2.4 KiB
C
// Network stack registry. This file owns the single active stack provider binding.
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <ntlite/ddi/net_stack.h>
|
|
#include <ntlite/ddi/net_device.h>
|
|
#include <kernel/ke_debug.h>
|
|
#include <kernel/ke_spinlock.h>
|
|
#include <ntlite/ddi/io_driver.h>
|
|
|
|
static const NET_STACK_PROVIDER* gNetStackProvider = 0;
|
|
static SPINLOCK gNetStackLock = SPINLOCK_INIT;
|
|
|
|
// Implements the net Validate Stack Provider operation.
|
|
static KSTATUS NetValidateStackProvider(const NET_STACK_PROVIDER* p) {
|
|
if (!p || p->Version != NET_STACK_PROVIDER_VERSION || !p->Name)
|
|
return NTLSTATUS_INVALID_PARAMETER;
|
|
|
|
if (!p->StackDevice || !p->AttachDevice || !p->ReceiveFrame)
|
|
return NTLSTATUS_INVALID_PARAMETER;
|
|
|
|
if (!p->StackDevice->DriverObject ||
|
|
!p->StackDevice->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL])
|
|
return NTLSTATUS_INVALID_PARAMETER;
|
|
|
|
return NTLSTATUS_SUCCESS;
|
|
}
|
|
|
|
// Implements the net Register Stack Provider operation.
|
|
__declspec(dllexport) KSTATUS NetRegisterStackProvider(const NET_STACK_PROVIDER* provider) {
|
|
KSTATUS st = NetValidateStackProvider(provider);
|
|
if (!KSUCCESS(st))
|
|
return st;
|
|
|
|
uintptr_t flags = KeAcquireSpinlock(&gNetStackLock);
|
|
if (gNetStackProvider) {
|
|
KeReleaseSpinlock(&gNetStackLock, flags);
|
|
return NTLSTATUS_ALREADY_EXISTS;
|
|
}
|
|
gNetStackProvider = provider;
|
|
KeReleaseSpinlock(&gNetStackLock, flags);
|
|
|
|
DbgPrint("NET: registered stack provider %s\n", provider->Name);
|
|
|
|
// Stack drivers usually load before NIC drivers, but support the other
|
|
// order so driver.ini remains simple while the loader is still flat.
|
|
uint32_t count = NetGetDeviceCount();
|
|
for (uint32_t i = 0; i < count; ++i) {
|
|
NET_DEVICE* dev = NetGetDevice(i);
|
|
if (!dev)
|
|
continue;
|
|
KSTATUS attach = provider->AttachDevice(dev);
|
|
if (!KSUCCESS(attach)) {
|
|
DbgPrint("NET: provider %s attach for %s failed: 0x%x\n",
|
|
provider->Name, dev->Name, attach);
|
|
}
|
|
}
|
|
|
|
return NTLSTATUS_SUCCESS;
|
|
}
|
|
|
|
// Implements the net Get Stack Provider operation.
|
|
__declspec(dllexport) const NET_STACK_PROVIDER* NetGetStackProvider(void) {
|
|
uintptr_t flags = KeAcquireSpinlock(&gNetStackLock);
|
|
const NET_STACK_PROVIDER* p = gNetStackProvider;
|
|
KeReleaseSpinlock(&gNetStackLock, flags);
|
|
return p;
|
|
}
|