/****************************************************** Required NDIS procedure Allocates and initializes adapter context Finally sets send and receive to Enabled state and reports connect Returns: NDIS_STATUS SUCCESS or some error code *******************************************************/ static NDIS_STATUS ParaNdis5_Initialize(OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE WrapperConfigurationContext) { NDIS_STATUS status = NDIS_STATUS_UNSUPPORTED_MEDIA; PARANDIS_ADAPTER *pContext = NULL; UINT i; for(i = 0; i < MediumArraySize; ++i) { if(MediumArray[i] == NdisMedium802_3) { *SelectedMediumIndex = i; status = NDIS_STATUS_SUCCESS; break; } } if (status == NDIS_STATUS_SUCCESS) { pContext = (PARANDIS_ADAPTER *)ParaNdis_AllocateMemory(NULL, sizeof(PARANDIS_ADAPTER)); if (!pContext) { status = NDIS_STATUS_RESOURCES; } } if (status == NDIS_STATUS_SUCCESS) { PVOID pResourceList = &status; UINT uSize = 0; NdisZeroMemory(pContext, sizeof(PARANDIS_ADAPTER)); pContext->ulUniqueID = InterlockedIncrement(&gID); pContext->DriverHandle = DriverHandle; pContext->MiniportHandle = MiniportAdapterHandle; pContext->WrapperConfigurationHandle = WrapperConfigurationContext; NdisMQueryAdapterResources(&status, WrapperConfigurationContext, pResourceList, &uSize); if (uSize > 0) pResourceList = ParaNdis_AllocateMemory(MiniportAdapterHandle, uSize); else pResourceList = NULL; if (!pResourceList) status = uSize > 0 ? NDIS_STATUS_RESOURCES : NDIS_STATUS_FAILURE; else { ULONG attributes; attributes = NDIS_ATTRIBUTE_DESERIALIZE | NDIS_ATTRIBUTE_BUS_MASTER; // in XP SP2, if this flag is NOT set, the NDIS halts miniport // upon transition to S1..S4. // it seems that XP SP3 ignores it and always sends SET_POWER to D3 #ifndef NO_XP_POWER_MANAGEMENT attributes |= NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; #endif #ifdef NDIS50_MINIPORT //TODO: this is wrong, I think // this API is for XP and // it should be used only if you never need virtual addresses of sent buffers // so I comment it out //attributes |= NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS; #endif NdisMSetAttributesEx( MiniportAdapterHandle, pContext, 0, attributes, NdisInterfacePci); NdisMQueryAdapterResources(&status, WrapperConfigurationContext, pResourceList, &uSize); status = ParaNdis_InitializeContext(pContext, (PNDIS_RESOURCE_LIST)pResourceList); NdisFreeMemory(pResourceList, 0, 0); } } if (status == NDIS_STATUS_SUCCESS) { status = ParaNdis_FinishInitialization(pContext); if (status == NDIS_STATUS_SUCCESS) { #ifdef NDIS50_MINIPORT NdisMRegisterAdapterShutdownHandler( MiniportAdapterHandle, pContext, (ADAPTER_SHUTDOWN_HANDLER)ParaNdis5_Shutdown); #endif //NDIS50_MINIPORT ParaNdis_DebugRegisterMiniport(pContext, TRUE); ParaNdis_IndicateConnect(pContext, FALSE, TRUE); ParaNdis5_StopSend(pContext, FALSE, NULL); ParaNdis5_StopReceive(pContext, FALSE, NULL); if (!pContext->ulMilliesToConnect) { ParaNdis_ReportLinkStatus(pContext, FALSE); } else { NdisSetTimer(&pContext->ConnectTimer, pContext->ulMilliesToConnect); } } else { ParaNdis_CleanupContext(pContext); } } if (status != NDIS_STATUS_SUCCESS && pContext) { NdisFreeMemory(pContext, 0, 0); } DEBUG_EXIT_STATUS(0, status); return status; }
NDIS_STATUS NICInitializeAdapter( IN PMP_ADAPTER Adapter, IN NDIS_HANDLE WrapperConfigurationContext ) /*++ Routine Description: Query assigned resources and initialize the adapter. Arguments: Adapter Pointer to our adapter Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_ADAPTER_NOT_FOUND --*/ { NDIS_STATUS Status = NDIS_STATUS_ADAPTER_NOT_FOUND; typedef __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) NicResourceCharBuf; NicResourceCharBuf resBuf[NIC_RESOURCE_BUF_SIZE]; PNDIS_RESOURCE_LIST resList = (PNDIS_RESOURCE_LIST)resBuf; UINT bufSize = NIC_RESOURCE_BUF_SIZE; PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDesc; ULONG index; DEBUGP(MP_TRACE, ("---> InitializeAdapter\n")); PAGED_CODE(); do { // // Get the resources assigned by the PNP manager. NDIS gets // these resources in IRP_MN_START_DEVICE request. // NdisMQueryAdapterResources( &Status, WrapperConfigurationContext, resList, &bufSize); if (Status == NDIS_STATUS_SUCCESS) { #pragma prefast(suppress: 8199, "resList is initialized by NdisMQueryAdapterResources") for (index=0; index < resList->Count; index++) { pResDesc = &resList->PartialDescriptors[index]; switch(pResDesc->Type) { case CmResourceTypePort: DEBUGP(MP_INFO, ("IoBaseAddress = 0x%x\n", NdisGetPhysicalAddressLow(pResDesc->u.Port.Start))); DEBUGP(MP_INFO, ("IoRange = x%x\n", pResDesc->u.Port.Length)); break; case CmResourceTypeInterrupt: DEBUGP(MP_INFO, ("InterruptLevel = x%x\n", pResDesc->u.Interrupt.Level)); break; case CmResourceTypeMemory: DEBUGP(MP_INFO, ("MemPhysAddress(Low) = 0x%0x\n", NdisGetPhysicalAddressLow(pResDesc->u.Memory.Start))); DEBUGP(MP_INFO, ("MemPhysAddress(High) = 0x%0x\n", NdisGetPhysicalAddressHigh(pResDesc->u.Memory.Start))); break; } } } Status = NDIS_STATUS_SUCCESS; // // Map bus-relative IO range to system IO space using // NdisMRegisterIoPortRange // // // Map bus-relative registers to virtual system-space // using NdisMMapIoSpace // // // Disable interrupts here as soon as possible // // // Register the interrupt using NdisMRegisterInterrupt // // // Initialize the hardware with mapped resources // #ifdef NDIS50_MINIPORT // // Register a shutdown handler for NDIS50 or earlier miniports // For NDIS51 miniports, set AdapterShutdownHandler. // NdisMRegisterAdapterShutdownHandler( Adapter->AdapterHandle, (PVOID) Adapter, (ADAPTER_SHUTDOWN_HANDLER) MPShutdown); #endif // // Enable the interrupt // } while (FALSE); DEBUGP(MP_TRACE, ("<--- InitializeAdapter, Status=%x\n", Status)); return Status; }
/************************************************************************* * SteMiniportinitialize() * * NDIS エントリポイント * ネットワーク I/O 操作のために NIC ドライバがネットワーク I/O 操作を * するために必要なリソースを確保する。 * * 引数: * * OpenErrorStatus OUT PNDIS_STATUS * SelectedMediumIndex OUT PUINT * MediumArray IN PNDIS_MEDIUM * MediumArraySize IN UINT * MiniportAdapterHandle IN NDIS_HANDLE * WrapperConfigurationContext IN NDIS_HANDLE * * 返り値: * * 正常時: NDIS_STATUS_SUCCESS * *************************************************************************/ NDIS_STATUS SteMiniportInitialize( OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE WrapperConfigurationContext ) { UINT i; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; STE_ADAPTER *Adapter = NULL; BOOLEAN MediaFound = FALSE; DEBUG_PRINT0(3, "SteMiniportInitialize called\n"); *SelectedMediumIndex = 0; for ( i = 0 ; i < MediumArraySize ; i++){ if (MediumArray[i] == NdisMedium802_3){ *SelectedMediumIndex = i; MediaFound = TRUE; break; } } // 途中で break するためだけの Do-While 文 do { if(!MediaFound){ // 上記の for 文で見つけられなかったようだ DEBUG_PRINT0(1, "SteMiniportInitialize: No Media much\n"); Status = NDIS_STATUS_UNSUPPORTED_MEDIA; break; } // // Adapter を確保し、初期化する // if ((Status = SteCreateAdapter(&Adapter)) != NDIS_STATUS_SUCCESS){ DEBUG_PRINT0(1, "SteMiniportInitialize: Can't allocate memory for STE_ADAPTER\n"); Status = NDIS_STATUS_RESOURCES; break; } DEBUG_PRINT1(3, "SteMiniportInitialize: Adapter = 0x%p\n", Adapter); Adapter->MiniportAdapterHandle = MiniportAdapterHandle; // // Registory を読む処理。...省略。 // NdisOpenConfiguration(); // NdisReadConfiguration(); // // NIC のためのハードウェアリソースのリストを得る。...省略。 // NdisMQueryAdapterResources() // // // NDIS に NIC の情報を伝える。 // かならず NdisXxx 関数を呼び出すより前に、以下の NdisMSetAttributesEx // を呼び出さなければならない。 // NdisMSetAttributesEx( MiniportAdapterHandle, //IN NDIS_HANDLE (NDIS_HANDLE) Adapter, //IN NDIS_HANDLE 0, //IN UINT NDIS_ATTRIBUTE_DESERIALIZE, //IN ULONG Deserialized ミニポートドライバ NdisInterfaceInternal //IN NDIS_INTERFACE_TYPE ); // // NDIS 5.0 の場合はかならず SHUTDOWN_HANDLER を登録しなければならない。 // NdisMRegisterAdapterShutdownHandler( MiniportAdapterHandle, // IN NDIS_HANDLE (PVOID) Adapter, // IN PVOID (ADAPTER_SHUTDOWN_HANDLER) SteMiniportShutdown // IN ADAPTER_SHUTDOWN_HANDLER ); // // 仮想 NIC デーモンからの IOCT/ReadFile/WriteFile 用の // デバイスを作成し、Dispatch ルーチンを登録する。 // SteRegisterDevice(Adapter); // // SteRecvTimerFunc() を呼ぶためのタイマーオブジェクトを初期化 // NdisInitializeTimer( &Adapter->RecvTimer, //IN OUT PNDIS_TIMER SteRecvTimerFunc, //IN PNDIS_TIMER_FUNCTION (PVOID)Adapter //IN PVOID ); // // SteResetTimerFunc() を呼ぶためのタイマーオブジェクトを初期化 // NdisInitializeTimer( &Adapter->ResetTimer, //IN OUT PNDIS_TIMER SteResetTimerFunc, //IN PNDIS_TIMER_FUNCTION (PVOID)Adapter //IN PVOID ); } while (FALSE); return(Status); }