NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { NDIS_STATUS Status = NDIS_STATUS_FAILURE; NDIS_MINIPORT_DRIVER_CHARACTERISTICS MChars; ULONG ndisVersion; if (FailDriverEntry) { DbgPrint("FAILING DRIVER ENTRY\n"); return NDIS_STATUS_FAILURE; } #if DOT11_TRACE_ENABLED WPP_INIT_TRACING(DriverObject, RegistryPath); #endif MpTrace(COMP_INIT_PNP, DBG_SERIOUS, (__DATE__ " " __TIME__ " DriverEntry called!\n")); do { // // Identify the appropriate read/write lock API // Status = MpDetermineRWLockType(); if (Status != NDIS_STATUS_SUCCESS) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to determine type of read/write lock to use. Status = 0x%x\n", Status)); break; } NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS)); // // Set the type and version of this structure. We select the appropriate version & // driver functionality based on NDIS version. // ndisVersion = NdisGetVersion(); if (ndisVersion <= MP_NDIS_VERSION_NEEDS_COMPATIBILITY) { // NDIS Version 6.0 MChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS; MChars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1; MChars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1; MChars.MajorNdisVersion = MP_MAJOR_NDIS_VERSION; MChars.MinorNdisVersion = 0; } else { // NDIS Version 6.2 MChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS; MChars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2; MChars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2; MChars.MajorNdisVersion = MP_MAJOR_NDIS_VERSION; MChars.MinorNdisVersion = MP_MINOR_NDIS_VERSION; } MChars.MajorDriverVersion = HW11_MAJOR_DRIVER_VERSION; MChars.MinorDriverVersion = HW11_MINOR_DRIVER_VERSION; // // Init/PnP handlers // MChars.InitializeHandlerEx = MPInitialize; MChars.RestartHandler = MPRestart; MChars.PauseHandler = MPPause; MChars.ShutdownHandlerEx = MPAdapterShutdown; MChars.DevicePnPEventNotifyHandler = MPDevicePnPEvent; MChars.HaltHandlerEx = MPHalt; MChars.UnloadHandler = DriverUnload; // // Query/Set/Method requests handlers // MChars.OidRequestHandler = MPOidRequest; MChars.CancelOidRequestHandler = MPCancelOidRequest; // // Set optional miniport services handler // MChars.SetOptionsHandler = MPSetOptions; // // Send/Receive handlers // MChars.SendNetBufferListsHandler = MPSendNetBufferLists; MChars.CancelSendHandler = MPCancelSendNetBufferLists; MChars.ReturnNetBufferListsHandler = MPReturnNetBufferLists; // // Fault handling handlers // MChars.CheckForHangHandlerEx = MPCheckForHang; MChars.ResetHandlerEx = MPReset; // // Direct OID request handlers // MChars.DirectOidRequestHandler = MPDirectOidRequest; MChars.CancelDirectOidRequestHandler = MPCancelDirectOidRequest; // // Register the miniport driver with NDIS // Status = NdisMRegisterMiniportDriver( DriverObject, RegistryPath, GlobalDriverContext, &MChars, &GlobalDriverHandle ); if (Status != NDIS_STATUS_SUCCESS) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to register miniport with NDIS. Status = 0x%x\n", Status)); break; } #if DBG #if !DOT11_TRACE_ENABLED // // Read debug mask from registry // MpReadGlobalDebugMask(GlobalDriverHandle); #endif #endif } while (FALSE); if (Status != NDIS_STATUS_SUCCESS) { #if DOT11_TRACE_ENABLED WPP_CLEANUP(DriverObject); #endif } return(Status); }
NDIS_STATUS DriverEntry(PVOID obj,PVOID path) { NDIS_STATUS rc; NDIS_MINIPORT_DRIVER_CHARACTERISTICS c; WDF_DRIVER_CONFIG dc; NTSTATUS nrc; WDFDRIVER fw_handle; vlog("DriverEntry started"); if(NdisGetVersion() < ((VENET_NDIS_MAJOR_VERSION << 16) | VENET_NDIS_MINOR_VERSION)) { vlog("Invalid version!"); return NDIS_STATUS_FAILURE; } WDF_DRIVER_CONFIG_INIT(&dc, WDF_NO_EVENT_CALLBACK); dc.DriverInitFlags |= WdfDriverInitNoDispatchOverride; nrc = WdfDriverCreate(obj, path, WDF_NO_OBJECT_ATTRIBUTES, &dc, &fw_handle); if(!NT_SUCCESS(nrc)) { vlog("DriverEntry WdfDriverCreate: %d", nrc); return NDIS_STATUS_FAILURE; } /* For multiple instances */ NdisInitializeListHead(&adapterList); NdisAllocateSpinLock(&adapterListLock); NdisZeroMemory(&c, sizeof(c)); c.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS; c.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS); c.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1; c.Flags = NDIS_WDM_DRIVER; c.MajorNdisVersion = VENET_NDIS_MAJOR_VERSION; c.MinorNdisVersion = VENET_NDIS_MINOR_VERSION; c.MajorDriverVersion = VENET_MAJOR_VERSION; c.MinorDriverVersion = VENET_MINOR_VERSION; c.InitializeHandlerEx = VenetInitialize; c.PauseHandler = VenetPause; c.RestartHandler = VenetRestart; c.ShutdownHandlerEx = VenetShutdown; c.DevicePnPEventNotifyHandler = VenetDevicePnPEvent; c.HaltHandlerEx = VenetHalt; c.UnloadHandler = VenetUnload; c.OidRequestHandler = VenetOidRequest; c.CancelOidRequestHandler = VenetCancelOidRequest; c.SetOptionsHandler = VenetSetOptions; c.SendNetBufferListsHandler = VenetSendNetBufs; c.CancelSendHandler = VenetCancelSend; c.ReturnNetBufferListsHandler = VenetReturnNetBufs; c.CheckForHangHandlerEx = VenetCheckHang; c.ResetHandlerEx = VenetReset; rc = NdisMRegisterMiniportDriver(obj, path, (PNDIS_HANDLE) driver_context, &c, &mp_handle); vlog("DriverEntry return rc = %d", rc); return rc; }
NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath ) { NTSTATUS status; NDIS_HANDLE ndis_wrapper_handle = NULL; NDIS_MINIPORT_CHARACTERISTICS mini_chars; FUNCTION_ENTER(); KdPrint((__DRIVER_NAME " DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath)); NdisZeroMemory(&mini_chars, sizeof(mini_chars)); KdPrint((__DRIVER_NAME " NdisGetVersion = %x\n", NdisGetVersion())); KdPrint((__DRIVER_NAME " ndis_wrapper_handle = %p\n", ndis_wrapper_handle)); NdisMInitializeWrapper(&ndis_wrapper_handle, DriverObject, RegistryPath, NULL); KdPrint((__DRIVER_NAME " ndis_wrapper_handle = %p\n", ndis_wrapper_handle)); if (!ndis_wrapper_handle) { KdPrint((__DRIVER_NAME " NdisMInitializeWrapper failed\n")); return NDIS_STATUS_FAILURE; } KdPrint((__DRIVER_NAME " NdisMInitializeWrapper succeeded\n")); /* NDIS 5.1 driver */ mini_chars.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION; mini_chars.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION; KdPrint((__DRIVER_NAME " MajorNdisVersion = %d, MinorNdisVersion = %d\n", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION)); mini_chars.HaltHandler = XenNet_Halt; mini_chars.InitializeHandler = XenNet_Init; //mini_chars.ISRHandler = XenNet_InterruptIsr; //mini_chars.HandleInterruptHandler = XenNet_InterruptDpc; mini_chars.QueryInformationHandler = XenNet_QueryInformation; mini_chars.ResetHandler = XenNet_Reset; mini_chars.SetInformationHandler = XenNet_SetInformation; /* added in v.4 -- use multiple pkts interface */ mini_chars.ReturnPacketHandler = XenNet_ReturnPacket; mini_chars.SendPacketsHandler = XenNet_SendPackets; /* don't support cancel - no point as packets are never queued for long */ //mini_chars.CancelSendPacketsHandler = XenNet_CancelSendPackets; #ifdef NDIS51_MINIPORT /* added in v.5.1 */ mini_chars.PnPEventNotifyHandler = XenNet_PnPEventNotify; mini_chars.AdapterShutdownHandler = XenNet_Shutdown; #else // something else here #endif /* set up upper-edge interface */ KdPrint((__DRIVER_NAME " about to call NdisMRegisterMiniport\n")); status = NdisMRegisterMiniport(ndis_wrapper_handle, &mini_chars, sizeof(mini_chars)); KdPrint((__DRIVER_NAME " called NdisMRegisterMiniport\n")); if (!NT_SUCCESS(status)) { KdPrint((__DRIVER_NAME " NdisMRegisterMiniport failed, status = 0x%x\n", status)); NdisTerminateWrapper(ndis_wrapper_handle, NULL); return status; } FUNCTION_EXIT(); return status; }
/** This implementation picks the NDIS 6.2 Read/Write lock structures & API on OS versions where NDIS support those and would pick the older API on NDIS 6.0. Since the new API are not available on NDIS 6.0 OS, it does not link the new API into the binary, instead it dynamically loads the API address & uses them. This way the same binary can run on both NDIS 6.0 & 6.2 OSes, using the correct API for that OS. */ NDIS_STATUS MpDetermineRWLockType() { NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS; ULONG ndisVersion; NDIS_STRING allocateRoutineName; NDIS_STRING freeRoutineName; NDIS_STRING acquireReadRoutineName; NDIS_STRING acquireWriteRoutineName; NDIS_STRING releaseRoutineName; do { NdisZeroMemory(&GlobalRWLockHandlers, sizeof(MP_RW_LOCK_HANDLERS)); // Start with pre NDIS 6.2 using the old API. If this is NDIS 6.2+ and // we cannot find address of new API, we will fail GlobalRWLockHandlers.AllocateHandler = MpAllocateOldRWLock; GlobalRWLockHandlers.FreeHandler = MpFreeOldRWLock; GlobalRWLockHandlers.AcquireReadHandler = MpAcquireOldRWLockForRead; GlobalRWLockHandlers.AcquireWriteHandler = MpAcquireOldRWLockForWrite; GlobalRWLockHandlers.ReleaseHandler = MpReleaseOldRWLock; ndisVersion = NdisGetVersion(); if (ndisVersion > MP_NDIS_VERSION_NEEDS_COMPATIBILITY) { // NDIS 6.2 or above. Use the new API // Load the address of the new NDisRead/Write lock API NdisInitUnicodeString(&allocateRoutineName, L"NdisAllocateRWLock"); NdisInitUnicodeString(&freeRoutineName, L"NdisFreeRWLock"); NdisInitUnicodeString(&acquireReadRoutineName, L"NdisAcquireRWLockRead"); NdisInitUnicodeString(&acquireWriteRoutineName, L"NdisAcquireRWLockWrite"); NdisInitUnicodeString(&releaseRoutineName, L"NdisReleaseRWLock"); *((PVOID *)&MpNdisAllocateRWLock) = NdisGetRoutineAddress(&allocateRoutineName); if (MpNdisAllocateRWLock == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisAllocateRWLock\n")); break; } *((PVOID *)&MpNdisFreeRWLock) = NdisGetRoutineAddress(&freeRoutineName); if (MpNdisFreeRWLock == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisFreeRWLock\n")); break; } *((PVOID *)&MpNdisAcquireRWLockRead) = NdisGetRoutineAddress(&acquireReadRoutineName); if (MpNdisAcquireRWLockRead == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisAcquireRWLockRead\n")); break; } *((PVOID *)&MpNdisAcquireRWLockWrite) = NdisGetRoutineAddress(&acquireWriteRoutineName); if (MpNdisAcquireRWLockWrite == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisAcquireRWLockWrite\n")); break; } *((PVOID *)&MpNdisReleaseRWLock) = NdisGetRoutineAddress(&releaseRoutineName); if (MpNdisReleaseRWLock == NULL) { MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisReleaseRWLock\n")); break; } // Set our pointers GlobalRWLockHandlers.AllocateHandler = MpAllocateNewRWLock; GlobalRWLockHandlers.FreeHandler = MpFreeNewRWLock; GlobalRWLockHandlers.AcquireReadHandler = MpAcquireNewRWLockForRead; GlobalRWLockHandlers.AcquireWriteHandler = MpAcquireNewRWLockForWrite; GlobalRWLockHandlers.ReleaseHandler = MpReleaseNewRWLock; } }while (FALSE); return ndisStatus; }