miniport.c
上传用户:zhuzhu0204
上传日期:2020-07-13
资源大小:13165k
文件大小:42k
开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 1992-2000  Microsoft Corporation
  3. Module Name:
  4.     miniport.c
  5. Abstract:
  6.     Ndis Intermediate Miniport driver sample. This is a passthru driver.
  7. Author:
  8. Environment:
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. NDIS_STATUS
  14. MPInitialize(
  15.     OUT PNDIS_STATUS             OpenErrorStatus,
  16.     OUT PUINT                    SelectedMediumIndex,
  17.     IN  PNDIS_MEDIUM             MediumArray,
  18.     IN  UINT                     MediumArraySize,
  19.     IN  NDIS_HANDLE              MiniportAdapterHandle,
  20.     IN  NDIS_HANDLE              WrapperConfigurationContext
  21.     )
  22. /*++
  23. Routine Description:
  24.     This is the initialize handler which gets called as a result of
  25.     the BindAdapter handler calling NdisIMInitializeDeviceInstanceEx.
  26.     The context parameter which we pass there is the adapter structure
  27.     which we retrieve here.
  28.     Arguments:
  29.     OpenErrorStatus            Not used by us.
  30.     SelectedMediumIndex        Place-holder for what media we are using
  31.     MediumArray                Array of ndis media passed down to us to pick from
  32.     MediumArraySize            Size of the array
  33.     MiniportAdapterHandle    The handle NDIS uses to refer to us
  34.     WrapperConfigurationContext    For use by NdisOpenConfiguration
  35. Return Value:
  36.     NDIS_STATUS_SUCCESS unless something goes wrong
  37. --*/
  38. {
  39.     UINT            i;
  40.     PADAPT          pAdapt;
  41.     NDIS_STATUS     Status = NDIS_STATUS_FAILURE;
  42.     NDIS_MEDIUM     Medium;
  43.     UNREFERENCED_PARAMETER(WrapperConfigurationContext);
  44.     
  45.     do
  46.     {
  47.         //
  48.         // Start off by retrieving our adapter context and storing
  49.         // the Miniport handle in it.
  50.         //
  51.         pAdapt = NdisIMGetDeviceContext(MiniportAdapterHandle);
  52.         pAdapt->MiniportHandle = MiniportAdapterHandle;
  53.         DBGPRINT(("==> Miniport Initialize: Adapt %pn", pAdapt));
  54.         //
  55.         // Usually we export the medium type of the adapter below as our
  56.         // virtual miniport's medium type. However if the adapter below us
  57.         // is a WAN device, then we claim to be of medium type 802.3.
  58.         //
  59.         Medium = pAdapt->Medium;
  60.         if (Medium == NdisMediumWan)
  61.         {
  62.             Medium = NdisMedium802_3;
  63.         }
  64.         for (i = 0; i < MediumArraySize; i++)
  65.         {
  66.             if (MediumArray[i] == Medium)
  67.             {
  68.                 *SelectedMediumIndex = i;
  69.                 break;
  70.             }
  71.         }
  72.         if (i == MediumArraySize)
  73.         {
  74.             Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
  75.             break;
  76.         }
  77.         //
  78.         // Set the attributes now. NDIS_ATTRIBUTE_DESERIALIZE enables us
  79.         // to make up-calls to NDIS without having to call NdisIMSwitchToMiniport
  80.         // or NdisIMQueueCallBack. This also forces us to protect our data using
  81.         // spinlocks where appropriate. Also in this case NDIS does not queue
  82.         // packets on our behalf. Since this is a very simple pass-thru
  83.         // miniport, we do not have a need to protect anything. However in
  84.         // a general case there will be a need to use per-adapter spin-locks
  85.         // for the packet queues at the very least.
  86.         //
  87.         NdisMSetAttributesEx(MiniportAdapterHandle,
  88.                              pAdapt,
  89.                              0,                                        // CheckForHangTimeInSeconds
  90.                              NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT    |
  91.                                 NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT|
  92.                                 NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER |
  93.                                 NDIS_ATTRIBUTE_DESERIALIZE |
  94.                                 NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
  95.                              0);
  96.         //
  97.         // Initialize LastIndicatedStatus to be NDIS_STATUS_MEDIA_CONNECT
  98.         //
  99.         pAdapt->LastIndicatedStatus = NDIS_STATUS_MEDIA_CONNECT;
  100.         
  101.         //
  102.         // Initialize the power states for both the lower binding (PTDeviceState)
  103.         // and our miniport edge to Powered On.
  104.         //
  105.         pAdapt->MPDeviceState = NdisDeviceStateD0;
  106.         pAdapt->PTDeviceState = NdisDeviceStateD0;
  107.         //
  108.         // Add this adapter to the global pAdapt List
  109.         //
  110.         NdisAcquireSpinLock(&GlobalLock);
  111.         pAdapt->Next = pAdaptList;
  112.         pAdaptList = pAdapt;
  113.         NdisReleaseSpinLock(&GlobalLock);
  114.         
  115.         //
  116.         // Create an ioctl interface
  117.         //
  118.         (VOID)PtRegisterDevice();
  119.         Status = NDIS_STATUS_SUCCESS;
  120.     }
  121.     while (FALSE);
  122.     //
  123.     // If we had received an UnbindAdapter notification on the underlying
  124.     // adapter, we would have blocked that thread waiting for the IM Init
  125.     // process to complete. Wake up any such thread.
  126.     //
  127.     ASSERT(pAdapt->MiniportInitPending == TRUE);
  128.     pAdapt->MiniportInitPending = FALSE;
  129.     NdisSetEvent(&pAdapt->MiniportInitEvent);
  130.     DBGPRINT(("<== Miniport Initialize: Adapt %p, Status %xn", pAdapt, Status));
  131.     *OpenErrorStatus = Status;
  132.     
  133.     return Status;
  134. }
  135. NDIS_STATUS
  136. MPSend(
  137.     IN NDIS_HANDLE             MiniportAdapterContext,
  138.     IN PNDIS_PACKET            Packet,
  139.     IN UINT                    Flags
  140.     )
  141. /*++
  142. Routine Description:
  143.     Send Packet handler. Either this or our SendPackets (array) handler is called
  144.     based on which one is enabled in our Miniport Characteristics.
  145. Arguments:
  146.     MiniportAdapterContext    Pointer to the adapter
  147.     Packet                    Packet to send
  148.     Flags                     Unused, passed down below
  149. Return Value:
  150.     Return code from NdisSend
  151. --*/
  152. {
  153.     PADAPT              pAdapt = (PADAPT)MiniportAdapterContext;
  154.     NDIS_STATUS         Status;
  155.     PNDIS_PACKET        MyPacket;
  156.     PVOID               MediaSpecificInfo = NULL;
  157.     ULONG               MediaSpecificInfoSize = 0;
  158.     //
  159.     // The driver should fail the send if the virtual miniport is in low 
  160.     // power state
  161.     //
  162.     if (pAdapt->MPDeviceState > NdisDeviceStateD0)
  163.     {
  164.          return NDIS_STATUS_FAILURE;
  165.     }
  166. // BEGIN_PTEX_FILTER
  167.    //
  168.    // 调用过滤发送封包的函数,调用者运行在DISPATCH_LEVEL IRQL级别
  169.    //
  170.    if(!FltFilterSendPacket(pAdapt,Packet,TRUE))
  171.    {
  172.    //
  173.    // 如果拒绝的话,就欺骗上层,说已经发送成功了(虽然并没有真正地发送)
  174.    //
  175.    return NDIS_STATUS_SUCCESS;
  176.    }
  177. // END_PTEX_FILTER
  178. #ifdef NDIS51
  179.     //
  180.     // Use NDIS 5.1 packet stacking:
  181.     //
  182.     {
  183.         PNDIS_PACKET_STACK        pStack;
  184.         BOOLEAN                   Remaining;
  185.         //
  186.         // Packet stacks: Check if we can use the same packet for sending down.
  187.         //
  188.         pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining);
  189.         if (Remaining)
  190.         {
  191.             //
  192.             // We can reuse "Packet".
  193.             //
  194.             // NOTE: if we needed to keep per-packet information in packets
  195.             // sent down, we can use pStack->IMReserved[].
  196.             //
  197.             ASSERT(pStack);
  198.             //
  199.             // If the below miniport is going to low power state, stop sending down any packet.
  200.             //
  201.             NdisAcquireSpinLock(&pAdapt->Lock);
  202.             if (pAdapt->PTDeviceState > NdisDeviceStateD0)
  203.             {
  204.                 NdisReleaseSpinLock(&pAdapt->Lock);
  205.                 return NDIS_STATUS_FAILURE;
  206.             }
  207.             pAdapt->OutstandingSends++;
  208.             NdisReleaseSpinLock(&pAdapt->Lock);
  209.             NdisSend(&Status,
  210.                      pAdapt->BindingHandle,
  211.                      Packet);
  212.             if (Status != NDIS_STATUS_PENDING)
  213.             {
  214.                 ADAPT_DECR_PENDING_SENDS(pAdapt);
  215.             }
  216.             return(Status);
  217.         }
  218.     }
  219. #endif // NDIS51
  220.     //
  221.     // We are either not using packet stacks, or there isn't stack space
  222.     // in the original packet passed down to us. Allocate a new packet
  223.     // to wrap the data with.
  224.     //
  225.     //
  226.     // If the below miniport is going to low power state, stop sending down any packet.
  227.     //
  228.     NdisAcquireSpinLock(&pAdapt->Lock);
  229.     if (pAdapt->PTDeviceState > NdisDeviceStateD0)
  230.     {
  231.         NdisReleaseSpinLock(&pAdapt->Lock);
  232.         return NDIS_STATUS_FAILURE;
  233.     
  234.     }
  235.     pAdapt->OutstandingSends++;
  236.     NdisReleaseSpinLock(&pAdapt->Lock);
  237.     
  238.     NdisAllocatePacket(&Status,
  239.                        &MyPacket,
  240.                        pAdapt->SendPacketPoolHandle);
  241.     if (Status == NDIS_STATUS_SUCCESS)
  242.     {
  243.         PSEND_RSVD            SendRsvd;
  244.         //
  245.         // Save a pointer to the original packet in our reserved
  246.         // area in the new packet. This is needed so that we can
  247.         // get back to the original packet when the new packet's send
  248.         // is completed.
  249.         //
  250.         SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
  251.         SendRsvd->OriginalPkt = Packet;
  252.         MyPacket->Private.Flags = Flags;
  253.         //
  254.         // Set up the new packet so that it describes the same
  255.         // data as the original packet.
  256.         //
  257.         MyPacket->Private.Head = Packet->Private.Head;
  258.         MyPacket->Private.Tail = Packet->Private.Tail;
  259. #ifdef WIN9X
  260.         //
  261.         // Work around the fact that NDIS does not initialize this
  262.         // to FALSE on Win9x.
  263.         //
  264.         MyPacket->Private.ValidCounts = FALSE;
  265. #endif
  266.         //
  267.         // Copy the OOB Offset from the original packet to the new
  268.         // packet.
  269.         //
  270.         NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
  271.                        NDIS_OOB_DATA_FROM_PACKET(Packet),
  272.                        sizeof(NDIS_PACKET_OOB_DATA));
  273. #ifndef WIN9X
  274.         //
  275.         // Copy the right parts of per packet info into the new packet.
  276.         // This API is not available on Win9x since task offload is
  277.         // not supported on that platform.
  278.         //
  279.         NdisIMCopySendPerPacketInfo(MyPacket, Packet);
  280. #endif
  281.         
  282.         //
  283.         // Copy the Media specific information
  284.         //
  285.         NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
  286.                                             &MediaSpecificInfo,
  287.                                             &MediaSpecificInfoSize);
  288.         if (MediaSpecificInfo || MediaSpecificInfoSize)
  289.         {
  290.             NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
  291.                                                 MediaSpecificInfo,
  292.                                                 MediaSpecificInfoSize);
  293.         }
  294.         NdisSend(&Status,
  295.                  pAdapt->BindingHandle,
  296.                  MyPacket);
  297.         if (Status != NDIS_STATUS_PENDING)
  298.         {
  299. #ifndef WIN9X
  300.             NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
  301. #endif
  302.             NdisFreePacket(MyPacket);
  303.             ADAPT_DECR_PENDING_SENDS(pAdapt);
  304.         }
  305.     }
  306.     else
  307.     {
  308.         ADAPT_DECR_PENDING_SENDS(pAdapt);
  309.         //
  310.         // We are out of packets. Silently drop it. Alternatively we can deal with it:
  311.         //    - By keeping separate send and receive pools
  312.         //    - Dynamically allocate more pools as needed and free them when not needed
  313.         //
  314.     }
  315.     return(Status);
  316. }
  317. VOID
  318. MPSendPackets(
  319.     IN NDIS_HANDLE             MiniportAdapterContext,
  320.     IN PPNDIS_PACKET           PacketArray,
  321.     IN UINT                    NumberOfPackets
  322.     )
  323. /*++
  324. Routine Description:
  325.     Send Packet Array handler. Either this or our SendPacket handler is called
  326.     based on which one is enabled in our Miniport Characteristics.
  327. Arguments:
  328.     MiniportAdapterContext     Pointer to our adapter
  329.     PacketArray                Set of packets to send
  330.     NumberOfPackets            Self-explanatory
  331. Return Value:
  332.     None
  333. --*/
  334. {
  335.     PADAPT              pAdapt = (PADAPT)MiniportAdapterContext;
  336.     NDIS_STATUS         Status;
  337.     UINT                i;
  338.     PVOID               MediaSpecificInfo = NULL;
  339.     UINT                MediaSpecificInfoSize = 0;
  340.     
  341.     for (i = 0; i < NumberOfPackets; i++)
  342.     {
  343.         PNDIS_PACKET    Packet, MyPacket;
  344.         Packet = PacketArray[i];
  345.         //
  346.         // The driver should fail the send if the virtual miniport is in low 
  347.         // power state
  348.         //
  349.         if (pAdapt->MPDeviceState > NdisDeviceStateD0)
  350.         {
  351.             NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
  352.                             Packet,
  353.                             NDIS_STATUS_FAILURE);
  354.             continue;
  355.         }
  356. // BEGIN_PTEX_FILTER
  357.    //
  358.    // 调用过滤发送封包的函数,调用者运行在IRQL <= DISPATCH_LEVEL级别
  359.    //
  360.    if(!FltFilterSendPacket(pAdapt,Packet,FALSE))
  361.    { 
  362.    //
  363.    // 如果拒绝的话,就欺骗上层,说已经发送成功了(虽然并没有真正地发送)
  364.    //
  365.    NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
  366.                             Packet,
  367.                             NDIS_STATUS_SUCCESS);
  368.    continue;
  369.    }
  370. // END_PTEX_FILTER
  371. #ifdef NDIS51
  372.         //
  373.         // Use NDIS 5.1 packet stacking:
  374.         //
  375.         {
  376.             PNDIS_PACKET_STACK        pStack;
  377.             BOOLEAN                   Remaining;
  378.             //
  379.             // Packet stacks: Check if we can use the same packet for sending down.
  380.             //
  381.             pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining);
  382.             if (Remaining)
  383.             {
  384.                 //
  385.                 // We can reuse "Packet".
  386.                 //
  387.                 // NOTE: if we needed to keep per-packet information in packets
  388.                 // sent down, we can use pStack->IMReserved[].
  389.                 //
  390.                 ASSERT(pStack);
  391.                 //
  392.                 // If the below miniport is going to low power state, stop sending down any packet.
  393.                 //
  394.                 NdisAcquireSpinLock(&pAdapt->Lock);
  395.                 if (pAdapt->PTDeviceState > NdisDeviceStateD0)
  396.                 {
  397.                     NdisReleaseSpinLock(&pAdapt->Lock);
  398.                     NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
  399.                                         Packet,
  400.                                         NDIS_STATUS_FAILURE);
  401.                 }
  402.                 else
  403.                 {
  404.                     pAdapt->OutstandingSends++;
  405.                     NdisReleaseSpinLock(&pAdapt->Lock);
  406.                 
  407.                     NdisSend(&Status,
  408.                               pAdapt->BindingHandle,
  409.                               Packet);
  410.         
  411.                     if (Status != NDIS_STATUS_PENDING)
  412.                     {
  413.                         NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
  414.                                             Packet,
  415.                                             Status);
  416.                    
  417.                         ADAPT_DECR_PENDING_SENDS(pAdapt);
  418.                     }
  419.                 }
  420.                 continue;
  421.             }
  422.         }
  423. #endif
  424.         do 
  425.         {
  426.             NdisAcquireSpinLock(&pAdapt->Lock);
  427.             //
  428.             // If the below miniport is going to low power state, stop sending down any packet.
  429.             //
  430.             if (pAdapt->PTDeviceState > NdisDeviceStateD0)
  431.             {
  432.                 NdisReleaseSpinLock(&pAdapt->Lock);
  433.                 Status = NDIS_STATUS_FAILURE;
  434.                 break;
  435.             }
  436.             pAdapt->OutstandingSends++;
  437.             NdisReleaseSpinLock(&pAdapt->Lock);
  438.             
  439.             NdisAllocatePacket(&Status,
  440.                                &MyPacket,
  441.                                pAdapt->SendPacketPoolHandle);
  442.             if (Status == NDIS_STATUS_SUCCESS)
  443.             {
  444.                 PSEND_RSVD        SendRsvd;
  445.                 SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
  446.                 SendRsvd->OriginalPkt = Packet;
  447.                 MyPacket->Private.Flags = NdisGetPacketFlags(Packet);
  448.                 MyPacket->Private.Head = Packet->Private.Head;
  449.                 MyPacket->Private.Tail = Packet->Private.Tail;
  450. #ifdef WIN9X
  451.                 //
  452.                 // Work around the fact that NDIS does not initialize this
  453.                 // to FALSE on Win9x.
  454.                 //
  455.                 MyPacket->Private.ValidCounts = FALSE;
  456. #endif // WIN9X
  457.                 //
  458.                 // Copy the OOB data from the original packet to the new
  459.                 // packet.
  460.                 //
  461.                 NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
  462.                             NDIS_OOB_DATA_FROM_PACKET(Packet),
  463.                             sizeof(NDIS_PACKET_OOB_DATA));
  464.                 //
  465.                 // Copy relevant parts of the per packet info into the new packet
  466.                 //
  467. #ifndef WIN9X
  468.                 NdisIMCopySendPerPacketInfo(MyPacket, Packet);
  469. #endif
  470.                 //
  471.                 // Copy the Media specific information
  472.                 //
  473.                 NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
  474.                                                     &MediaSpecificInfo,
  475.                                                     &MediaSpecificInfoSize);
  476.                 if (MediaSpecificInfo || MediaSpecificInfoSize)
  477.                 {
  478.                     NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
  479.                                                         MediaSpecificInfo,
  480.                                                         MediaSpecificInfoSize);
  481.                 }
  482.                 NdisSend(&Status,
  483.                          pAdapt->BindingHandle,
  484.                          MyPacket);
  485.                 if (Status != NDIS_STATUS_PENDING)
  486.                 {
  487. #ifndef WIN9X
  488.                     NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
  489. #endif
  490.                     NdisFreePacket(MyPacket);
  491.                     ADAPT_DECR_PENDING_SENDS(pAdapt);
  492.                 }
  493.             }
  494.             else
  495.             {
  496.                 //
  497.                 // The driver cannot allocate a packet.
  498.                 // 
  499.                 ADAPT_DECR_PENDING_SENDS(pAdapt);
  500.             }
  501.         }
  502.         while (FALSE);
  503.         if (Status != NDIS_STATUS_PENDING)
  504.         {
  505.             NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
  506.                               Packet,
  507.                               Status);
  508.         }
  509.     }
  510. }
  511. NDIS_STATUS
  512. MPQueryInformation(
  513.     IN NDIS_HANDLE                MiniportAdapterContext,
  514.     IN NDIS_OID                   Oid,
  515.     IN PVOID                      InformationBuffer,
  516.     IN ULONG                      InformationBufferLength,
  517.     OUT PULONG                    BytesWritten,
  518.     OUT PULONG                    BytesNeeded
  519.     )
  520. /*++
  521. Routine Description:
  522.     Entry point called by NDIS to query for the value of the specified OID.
  523.     Typical processing is to forward the query down to the underlying miniport.
  524.     The following OIDs are filtered here:
  525.     OID_PNP_QUERY_POWER - return success right here
  526.     OID_GEN_SUPPORTED_GUIDS - do not forward, otherwise we will show up
  527.     multiple instances of private GUIDs supported by the underlying miniport.
  528.     OID_PNP_CAPABILITIES - we do send this down to the lower miniport, but
  529.     the values returned are postprocessed before we complete this request;
  530.     see PtRequestComplete.
  531.     NOTE on OID_TCP_TASK_OFFLOAD - if this IM driver modifies the contents
  532.     of data it passes through such that a lower miniport may not be able
  533.     to perform TCP task offload, then it should not forward this OID down,
  534.     but fail it here with the status NDIS_STATUS_NOT_SUPPORTED. This is to
  535.     avoid performing incorrect transformations on data.
  536.     If our miniport edge (upper edge) is at a low-power state, fail the request.
  537.     If our protocol edge (lower edge) has been notified of a low-power state,
  538.     we pend this request until the miniport below has been set to D0. Since
  539.     requests to miniports are serialized always, at most a single request will
  540.     be pended.
  541. Arguments:
  542.     MiniportAdapterContext    Pointer to the adapter structure
  543.     Oid                       Oid for this query
  544.     InformationBuffer         Buffer for information
  545.     InformationBufferLength   Size of this buffer
  546.     BytesWritten              Specifies how much info is written
  547.     BytesNeeded               In case the buffer is smaller than what we need, tell them how much is needed
  548. Return Value:
  549.     Return code from the NdisRequest below.
  550. --*/
  551. {
  552.     PADAPT        pAdapt = (PADAPT)MiniportAdapterContext;
  553.     NDIS_STATUS   Status = NDIS_STATUS_FAILURE;
  554.     do
  555.     {
  556.         if (Oid == OID_PNP_QUERY_POWER)
  557.         {
  558.             //
  559.             //  Do not forward this.
  560.             //
  561.             Status = NDIS_STATUS_SUCCESS;
  562.             break;
  563.         }
  564.         if (Oid == OID_GEN_SUPPORTED_GUIDS)
  565.         {
  566.             //
  567.             //  Do not forward this, otherwise we will end up with multiple
  568.             //  instances of private GUIDs that the underlying miniport
  569.             //  supports.
  570.             //
  571.             Status = NDIS_STATUS_NOT_SUPPORTED;
  572.             break;
  573.         }
  574.         if (Oid == OID_TCP_TASK_OFFLOAD)
  575.         {
  576.             //
  577.             // Fail this -if- this driver performs data transformations
  578.             // that can interfere with a lower driver's ability to offload
  579.             // TCP tasks.
  580.             //
  581.             // Status = NDIS_STATUS_NOT_SUPPORTED;
  582.             // break;
  583.             //
  584.         }
  585.         //
  586.         // If the miniport below is unbinding, just fail any request
  587.         //
  588.         NdisAcquireSpinLock(&pAdapt->Lock);
  589.         if (pAdapt->UnbindingInProcess == TRUE)
  590.         {
  591.             NdisReleaseSpinLock(&pAdapt->Lock);
  592.             Status = NDIS_STATUS_FAILURE;
  593.             break;
  594.         }
  595.         NdisReleaseSpinLock(&pAdapt->Lock);
  596.         //
  597.         // All other queries are failed, if the miniport is not at D0,
  598.         //
  599.         if (pAdapt->MPDeviceState > NdisDeviceStateD0) 
  600.         {
  601.             Status = NDIS_STATUS_FAILURE;
  602.             break;
  603.         }
  604.         pAdapt->Request.RequestType = NdisRequestQueryInformation;
  605.         pAdapt->Request.DATA.QUERY_INFORMATION.Oid = Oid;
  606.         pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
  607.         pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
  608.         pAdapt->BytesNeeded = BytesNeeded;
  609.         pAdapt->BytesReadOrWritten = BytesWritten;
  610.         //
  611.         // If the miniport below is binding, fail the request
  612.         //
  613.         NdisAcquireSpinLock(&pAdapt->Lock);
  614.             
  615.         if (pAdapt->UnbindingInProcess == TRUE)
  616.         {
  617.             NdisReleaseSpinLock(&pAdapt->Lock);
  618.             Status = NDIS_STATUS_FAILURE;
  619.             break;
  620.         }
  621.         //
  622.         // If the Protocol device state is OFF, mark this request as being 
  623.         // pended. We queue this until the device state is back to D0. 
  624.         //
  625.         if ((pAdapt->PTDeviceState > NdisDeviceStateD0) 
  626.                 && (pAdapt->StandingBy == FALSE))
  627.         {
  628.             pAdapt->QueuedRequest = TRUE;
  629.             NdisReleaseSpinLock(&pAdapt->Lock);
  630.             Status = NDIS_STATUS_PENDING;
  631.             break;
  632.         }
  633.         //
  634.         // This is in the process of powering down the system, always fail the request
  635.         // 
  636.         if (pAdapt->StandingBy == TRUE)
  637.         {
  638.             NdisReleaseSpinLock(&pAdapt->Lock);
  639.             Status = NDIS_STATUS_FAILURE;
  640.             break;
  641.         }
  642.         pAdapt->OutstandingRequests = TRUE;
  643.         
  644.         NdisReleaseSpinLock(&pAdapt->Lock);
  645.         //
  646.         // default case, most requests will be passed to the miniport below
  647.         //
  648.         NdisRequest(&Status,
  649.                     pAdapt->BindingHandle,
  650.                     &pAdapt->Request);
  651.         if (Status != NDIS_STATUS_PENDING)
  652.         {
  653.             PtRequestComplete(pAdapt, &pAdapt->Request, Status);
  654.             Status = NDIS_STATUS_PENDING;
  655.         }
  656.     } while (FALSE);
  657.     return(Status);
  658. }
  659. VOID
  660. MPQueryPNPCapabilities(
  661.     IN OUT PADAPT            pAdapt,
  662.     OUT PNDIS_STATUS         pStatus
  663.     )
  664. /*++
  665. Routine Description:
  666.     Postprocess a request for OID_PNP_CAPABILITIES that was forwarded
  667.     down to the underlying miniport, and has been completed by it.
  668. Arguments:
  669.     pAdapt - Pointer to the adapter structure
  670.     pStatus - Place to return final status
  671. Return Value:
  672.     None.
  673. --*/
  674. {
  675.     PNDIS_PNP_CAPABILITIES           pPNPCapabilities;
  676.     PNDIS_PM_WAKE_UP_CAPABILITIES    pPMstruct;
  677.     if (pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof(NDIS_PNP_CAPABILITIES))
  678.     {
  679.         pPNPCapabilities = (PNDIS_PNP_CAPABILITIES)(pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer);
  680.         //
  681.         // The following fields must be overwritten by an IM driver.
  682.         //
  683.         pPMstruct= & pPNPCapabilities->WakeUpCapabilities;
  684.         pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
  685.         pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;
  686.         pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
  687.         *pAdapt->BytesReadOrWritten = sizeof(NDIS_PNP_CAPABILITIES);
  688.         *pAdapt->BytesNeeded = 0;
  689.         //
  690.         // Setting our internal flags
  691.         // Default, device is ON
  692.         //
  693.         pAdapt->MPDeviceState = NdisDeviceStateD0;
  694.         pAdapt->PTDeviceState = NdisDeviceStateD0;
  695.         *pStatus = NDIS_STATUS_SUCCESS;
  696.     }
  697.     else
  698.     {
  699.         *pAdapt->BytesNeeded= sizeof(NDIS_PNP_CAPABILITIES);
  700.         *pStatus = NDIS_STATUS_RESOURCES;
  701.     }
  702. }
  703. NDIS_STATUS
  704. MPSetInformation(
  705.     IN NDIS_HANDLE             MiniportAdapterContext,
  706.     IN NDIS_OID                Oid,
  707.     IN PVOID                   InformationBuffer,
  708.     IN ULONG                   InformationBufferLength,
  709.     OUT PULONG                 BytesRead,
  710.     OUT PULONG                 BytesNeeded
  711.     )
  712. /*++
  713. Routine Description:
  714.     Miniport SetInfo handler.
  715.     In the case of OID_PNP_SET_POWER, record the power state and return the OID.    
  716.     Do not pass below
  717.     If the device is suspended, do not block the SET_POWER_OID 
  718.     as it is used to reactivate the Passthru miniport
  719.     
  720.     PM- If the MP is not ON (DeviceState > D0) return immediately  (except for 'query power' and 'set power')
  721.          If MP is ON, but the PT is not at D0, then queue the queue the request for later processing
  722.     Requests to miniports are always serialized
  723. Arguments:
  724.     MiniportAdapterContext    Pointer to the adapter structure
  725.     Oid                       Oid for this query
  726.     InformationBuffer         Buffer for information
  727.     InformationBufferLength   Size of this buffer
  728.     BytesRead                 Specifies how much info is read
  729.     BytesNeeded               In case the buffer is smaller than what we need, tell them how much is needed
  730. Return Value:
  731.     Return code from the NdisRequest below.
  732. --*/
  733. {
  734.     PADAPT        pAdapt = (PADAPT)MiniportAdapterContext;
  735.     NDIS_STATUS   Status;
  736.     Status = NDIS_STATUS_FAILURE;
  737.     do
  738.     {
  739.         //
  740.         // The Set Power should not be sent to the miniport below the Passthru, but is handled internally
  741.         //
  742.         if (Oid == OID_PNP_SET_POWER)
  743.         {
  744.             MPProcessSetPowerOid(&Status, 
  745.                                  pAdapt, 
  746.                                  InformationBuffer, 
  747.                                  InformationBufferLength, 
  748.                                  BytesRead, 
  749.                                  BytesNeeded);
  750.             break;
  751.         }
  752.         //
  753.         // If the miniport below is unbinding, fail the request
  754.         //
  755.         NdisAcquireSpinLock(&pAdapt->Lock);     
  756.         if (pAdapt->UnbindingInProcess == TRUE)
  757.         {
  758.             NdisReleaseSpinLock(&pAdapt->Lock);
  759.             Status = NDIS_STATUS_FAILURE;
  760.             break;
  761.         }
  762.         NdisReleaseSpinLock(&pAdapt->Lock);
  763.         //
  764.         // All other Set Information requests are failed, if the miniport is
  765.         // not at D0 or is transitioning to a device state greater than D0.
  766.         //
  767.         if (pAdapt->MPDeviceState > NdisDeviceStateD0)
  768.         {
  769.             Status = NDIS_STATUS_FAILURE;
  770.             break;
  771.         }
  772.         // Set up the Request and return the result
  773.         pAdapt->Request.RequestType = NdisRequestSetInformation;
  774.         pAdapt->Request.DATA.SET_INFORMATION.Oid = Oid;
  775.         pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
  776.         pAdapt->Request.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
  777.         pAdapt->BytesNeeded = BytesNeeded;
  778.         pAdapt->BytesReadOrWritten = BytesRead;
  779.         //
  780.         // If the miniport below is unbinding, fail the request
  781.         //
  782.         NdisAcquireSpinLock(&pAdapt->Lock);     
  783.         if (pAdapt->UnbindingInProcess == TRUE)
  784.         {
  785.             NdisReleaseSpinLock(&pAdapt->Lock);
  786.             Status = NDIS_STATUS_FAILURE;
  787.             break;
  788.         }
  789.             
  790.         //
  791.         // If the device below is at a low power state, we cannot send it the
  792.         // request now, and must pend it.
  793.         //
  794.         if ((pAdapt->PTDeviceState > NdisDeviceStateD0) 
  795.                 && (pAdapt->StandingBy == FALSE))
  796.         {
  797.             pAdapt->QueuedRequest = TRUE;
  798.             NdisReleaseSpinLock(&pAdapt->Lock);
  799.             Status = NDIS_STATUS_PENDING;
  800.             break;
  801.         }
  802.         //
  803.         // This is in the process of powering down the system, always fail the request
  804.         // 
  805.         if (pAdapt->StandingBy == TRUE)
  806.         {
  807.             NdisReleaseSpinLock(&pAdapt->Lock);
  808.             Status = NDIS_STATUS_FAILURE;
  809.             break;
  810.         }
  811.         pAdapt->OutstandingRequests = TRUE;
  812.         
  813.         NdisReleaseSpinLock(&pAdapt->Lock);
  814.         //
  815.         // Forward the request to the device below.
  816.         //
  817.         NdisRequest(&Status,
  818.                     pAdapt->BindingHandle,
  819.                     &pAdapt->Request);
  820.         if (Status != NDIS_STATUS_PENDING)
  821.         {
  822.             *BytesRead = pAdapt->Request.DATA.SET_INFORMATION.BytesRead;
  823.             *BytesNeeded = pAdapt->Request.DATA.SET_INFORMATION.BytesNeeded;
  824.             pAdapt->OutstandingRequests = FALSE;
  825.         }
  826.     } while (FALSE);
  827.     return(Status);
  828. }
  829. VOID
  830. MPProcessSetPowerOid(
  831.     IN OUT PNDIS_STATUS          pNdisStatus,
  832.     IN PADAPT                    pAdapt,
  833.     IN PVOID                     InformationBuffer,
  834.     IN ULONG                     InformationBufferLength,
  835.     OUT PULONG                   BytesRead,
  836.     OUT PULONG                   BytesNeeded
  837.     )
  838. /*++
  839. Routine Description:
  840.     This routine does all the procssing for a request with a SetPower Oid
  841.     The miniport shoud accept  the Set Power and transition to the new state
  842.     The Set Power should not be passed to the miniport below
  843.     If the IM miniport is going into a low power state, then there is no guarantee if it will ever
  844.     be asked go back to D0, before getting halted. No requests should be pended or queued.
  845.     
  846. Arguments:
  847.     pNdisStatus           - Status of the operation
  848.     pAdapt                - The Adapter structure
  849.     InformationBuffer     - The New DeviceState
  850.     InformationBufferLength
  851.     BytesRead             - No of bytes read
  852.     BytesNeeded           -  No of bytes needed
  853. Return Value:
  854.     Status  - NDIS_STATUS_SUCCESS if all the wait events succeed.
  855. --*/
  856. {
  857.     
  858.     NDIS_DEVICE_POWER_STATE NewDeviceState;
  859.     DBGPRINT(("==>MPProcessSetPowerOid: Adapt %pn", pAdapt)); 
  860.     ASSERT (InformationBuffer != NULL);
  861.     *pNdisStatus = NDIS_STATUS_FAILURE;
  862.     do 
  863.     {
  864.         //
  865.         // Check for invalid length
  866.         //
  867.         if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))
  868.         {
  869.             *pNdisStatus = NDIS_STATUS_INVALID_LENGTH;
  870.             break;
  871.         }
  872.         NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);
  873.         //
  874.         // Check for invalid device state
  875.         //
  876.         if ((pAdapt->MPDeviceState > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0))
  877.         {
  878.             //
  879.             // If the miniport is in a non-D0 state, the miniport can only receive a Set Power to D0
  880.             //
  881.             ASSERT (!(pAdapt->MPDeviceState > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0));
  882.             *pNdisStatus = NDIS_STATUS_FAILURE;
  883.             break;
  884.         }    
  885.         //
  886.         // Is the miniport transitioning from an On (D0) state to an Low Power State (>D0)
  887.         // If so, then set the StandingBy Flag - (Block all incoming requests)
  888.         //
  889.         if (pAdapt->MPDeviceState == NdisDeviceStateD0 && NewDeviceState > NdisDeviceStateD0)
  890.         {
  891.             pAdapt->StandingBy = TRUE;
  892.         }
  893.         //
  894.         // If the miniport is transitioning from a low power state to ON (D0), then clear the StandingBy flag
  895.         // All incoming requests will be pended until the physical miniport turns ON.
  896.         //
  897.         if (pAdapt->MPDeviceState > NdisDeviceStateD0 &&  NewDeviceState == NdisDeviceStateD0)
  898.         {
  899.             pAdapt->StandingBy = FALSE;
  900.         }
  901.         
  902.         //
  903.         // Now update the state in the pAdapt structure;
  904.         //
  905.         pAdapt->MPDeviceState = NewDeviceState;
  906.         
  907.         *pNdisStatus = NDIS_STATUS_SUCCESS;
  908.     
  909.     } while (FALSE);    
  910.         
  911.     if (*pNdisStatus == NDIS_STATUS_SUCCESS)
  912.     {
  913.         //
  914.         // The miniport resume from low power state
  915.         // 
  916.         if (pAdapt->StandingBy == FALSE)
  917.         {
  918.             //
  919.             // If we need to indicate the media connect state
  920.             // 
  921.             if (pAdapt->LastIndicatedStatus != pAdapt->LatestUnIndicateStatus)
  922.             {
  923.                NdisMIndicateStatus(pAdapt->MiniportHandle,
  924.                                         pAdapt->LatestUnIndicateStatus,
  925.                                         (PVOID)NULL,
  926.                                         0);
  927.                NdisMIndicateStatusComplete(pAdapt->MiniportHandle);
  928.                pAdapt->LastIndicatedStatus = pAdapt->LatestUnIndicateStatus;
  929.             }
  930.         }
  931.         else
  932.         {
  933.             //
  934.             // Initialize LatestUnIndicatedStatus
  935.             //
  936.             pAdapt->LatestUnIndicateStatus = pAdapt->LastIndicatedStatus;
  937.         }
  938.         *BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
  939.         *BytesNeeded = 0;
  940.     }
  941.     else
  942.     {
  943.         *BytesRead = 0;
  944.         *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
  945.     }
  946.     DBGPRINT(("<==MPProcessSetPowerOid: Adapt %pn", pAdapt)); 
  947. }
  948. VOID
  949. MPReturnPacket(
  950.     IN NDIS_HANDLE             MiniportAdapterContext,
  951.     IN PNDIS_PACKET            Packet
  952.     )
  953. /*++
  954. Routine Description:
  955.     NDIS Miniport entry point called whenever protocols are done with
  956.     a packet that we had indicated up and they had queued up for returning
  957.     later.
  958. Arguments:
  959.     MiniportAdapterContext    - pointer to ADAPT structure
  960.     Packet    - packet being returned.
  961. Return Value:
  962.     None.
  963. --*/
  964. {
  965.     PADAPT            pAdapt = (PADAPT)MiniportAdapterContext;
  966. #ifdef NDIS51
  967.     //
  968.     // Packet stacking: Check if this packet belongs to us.
  969.     //
  970.     if (NdisGetPoolFromPacket(Packet) != pAdapt->RecvPacketPoolHandle)
  971.     {
  972.         //
  973.         // We reused the original packet in a receive indication.
  974.         // Simply return it to the miniport below us.
  975.         //
  976.         NdisReturnPackets(&Packet, 1);
  977.     }
  978.     else
  979. #endif // NDIS51
  980.     {
  981.         //
  982.         // This is a packet allocated from this IM's receive packet pool.
  983.         // Reclaim our packet, and return the original to the driver below.
  984.         //
  985.         PNDIS_PACKET    MyPacket;
  986.         PRECV_RSVD      RecvRsvd;
  987.     
  988.         RecvRsvd = (PRECV_RSVD)(Packet->MiniportReserved);
  989.         MyPacket = RecvRsvd->OriginalPkt;
  990.     
  991.         NdisFreePacket(Packet);
  992.         NdisReturnPackets(&MyPacket, 1);
  993.     }
  994. }
  995. NDIS_STATUS
  996. MPTransferData(
  997.     OUT PNDIS_PACKET            Packet,
  998.     OUT PUINT                   BytesTransferred,
  999.     IN NDIS_HANDLE              MiniportAdapterContext,
  1000.     IN NDIS_HANDLE              MiniportReceiveContext,
  1001.     IN UINT                     ByteOffset,
  1002.     IN UINT                     BytesToTransfer
  1003.     )
  1004. /*++
  1005. Routine Description:
  1006.     Miniport's transfer data handler.
  1007. Arguments:
  1008.     Packet                    Destination packet
  1009.     BytesTransferred          Place-holder for how much data was copied
  1010.     MiniportAdapterContext    Pointer to the adapter structure
  1011.     MiniportReceiveContext    Context
  1012.     ByteOffset                Offset into the packet for copying data
  1013.     BytesToTransfer           How much to copy.
  1014. Return Value:
  1015.     Status of transfer
  1016. --*/
  1017. {
  1018.     PADAPT        pAdapt = (PADAPT)MiniportAdapterContext;
  1019.     NDIS_STATUS   Status;
  1020.     //
  1021.     // Return, if the device is OFF
  1022.     //
  1023.     if (IsIMDeviceStateOn(pAdapt) == FALSE)
  1024.     {
  1025.         return NDIS_STATUS_FAILURE;
  1026.     }
  1027.     NdisTransferData(&Status,
  1028.                      pAdapt->BindingHandle,
  1029.                      MiniportReceiveContext,
  1030.                      ByteOffset,
  1031.                      BytesToTransfer,
  1032.                      Packet,
  1033.                      BytesTransferred);
  1034.     return(Status);
  1035. }
  1036. VOID
  1037. MPHalt(
  1038.     IN NDIS_HANDLE                MiniportAdapterContext
  1039.     )
  1040. /*++
  1041. Routine Description:
  1042.     Halt handler. All the hard-work for clean-up is done here.
  1043. Arguments:
  1044.     MiniportAdapterContext    Pointer to the Adapter
  1045. Return Value:
  1046.     None.
  1047. --*/
  1048. {
  1049.     PADAPT             pAdapt = (PADAPT)MiniportAdapterContext;
  1050.     NDIS_STATUS        Status;
  1051.     PADAPT            *ppCursor;
  1052.     DBGPRINT(("==>MiniportHalt: Adapt %pn", pAdapt));
  1053.     //
  1054.     // Remove this adapter from the global list
  1055.     //
  1056.     NdisAcquireSpinLock(&GlobalLock);
  1057.     for (ppCursor = &pAdaptList; *ppCursor != NULL; ppCursor = &(*ppCursor)->Next)
  1058.     {
  1059.         if (*ppCursor == pAdapt)
  1060.         {
  1061.             *ppCursor = pAdapt->Next;
  1062.             break;
  1063.         }
  1064.     }
  1065.     NdisReleaseSpinLock(&GlobalLock);
  1066.     //
  1067.     // Delete the ioctl interface that was created when the miniport
  1068.     // was created.
  1069.     //
  1070.     (VOID)PtDeregisterDevice();
  1071.     //
  1072.     // If we have a valid bind, close the miniport below the protocol
  1073.     //
  1074.     if (pAdapt->BindingHandle != NULL)
  1075.     {
  1076.         //
  1077.         // Close the binding below. and wait for it to complete
  1078.         //
  1079.         NdisResetEvent(&pAdapt->Event);
  1080.         NdisCloseAdapter(&Status, pAdapt->BindingHandle);
  1081.         if (Status == NDIS_STATUS_PENDING)
  1082.         {
  1083.             NdisWaitEvent(&pAdapt->Event, 0);
  1084.             Status = pAdapt->Status;
  1085.         }
  1086.         ASSERT (Status == NDIS_STATUS_SUCCESS);
  1087.         pAdapt->BindingHandle = NULL;
  1088.     }
  1089.     //
  1090.     //  Free all resources on this adapter structure.
  1091.     //
  1092. // BEGIN_PTUSERIO
  1093. // 移除对适配器的引用
  1094. PtDerefAdapter(pAdapt);
  1095. // END_PTUSERIO
  1096.     DBGPRINT(("<== MiniportHalt: pAdapt %pn", pAdapt));
  1097. }
  1098. #ifdef NDIS51_MINIPORT
  1099. VOID
  1100. MPCancelSendPackets(
  1101.     IN NDIS_HANDLE            MiniportAdapterContext,
  1102.     IN PVOID                  CancelId
  1103.     )
  1104. /*++
  1105. Routine Description:
  1106.     The miniport entry point to handle cancellation of all send packets
  1107.     that match the given CancelId. If we have queued any packets that match
  1108.     this, then we should dequeue them and call NdisMSendComplete for all
  1109.     such packets, with a status of NDIS_STATUS_REQUEST_ABORTED.
  1110.     We should also call NdisCancelSendPackets in turn, on each lower binding
  1111.     that this adapter corresponds to. This is to let miniports below cancel
  1112.     any matching packets.
  1113. Arguments:
  1114.     MiniportAdapterContext    - pointer to ADAPT structure
  1115.     CancelId    - ID of packets to be cancelled.
  1116. Return Value:
  1117.     None
  1118. --*/
  1119. {
  1120.     PADAPT    pAdapt = (PADAPT)MiniportAdapterContext;
  1121.     //
  1122.     // If we queue packets on our adapter structure, this would be 
  1123.     // the place to acquire a spinlock to it, unlink any packets whose
  1124.     // Id matches CancelId, release the spinlock and call NdisMSendComplete
  1125.     // with NDIS_STATUS_REQUEST_ABORTED for all unlinked packets.
  1126.     //
  1127.     //
  1128.     // Next, pass this down so that we let the miniport(s) below cancel
  1129.     // any packets that they might have queued.
  1130.     //
  1131.     NdisCancelSendPackets(pAdapt->BindingHandle, CancelId);
  1132.     return;
  1133. }
  1134. VOID
  1135. MPDevicePnPEvent(
  1136.     IN NDIS_HANDLE              MiniportAdapterContext,
  1137.     IN NDIS_DEVICE_PNP_EVENT    DevicePnPEvent,
  1138.     IN PVOID                    InformationBuffer,
  1139.     IN ULONG                    InformationBufferLength
  1140.     )
  1141. /*++
  1142. Routine Description:
  1143.     This handler is called to notify us of PnP events directed to
  1144.     our miniport device object.
  1145. Arguments:
  1146.     MiniportAdapterContext    - pointer to ADAPT structure
  1147.     DevicePnPEvent - the event
  1148.     InformationBuffer - Points to additional event-specific information
  1149.     InformationBufferLength - length of above
  1150. Return Value:
  1151.     None
  1152. --*/
  1153. {
  1154.     // TBD - add code/comments about processing this.
  1155.     UNREFERENCED_PARAMETER(MiniportAdapterContext);
  1156.     UNREFERENCED_PARAMETER(DevicePnPEvent);
  1157.     UNREFERENCED_PARAMETER(InformationBuffer);
  1158.     UNREFERENCED_PARAMETER(InformationBufferLength);
  1159.     
  1160.     return;
  1161. }
  1162. VOID
  1163. MPAdapterShutdown(
  1164.     IN NDIS_HANDLE                MiniportAdapterContext
  1165.     )
  1166. /*++
  1167. Routine Description:
  1168.     This handler is called to notify us of an impending system shutdown.
  1169. Arguments:
  1170.     MiniportAdapterContext    - pointer to ADAPT structure
  1171. Return Value:
  1172.     None
  1173. --*/
  1174. {
  1175.     UNREFERENCED_PARAMETER(MiniportAdapterContext);
  1176.     
  1177.     return;
  1178. }
  1179. #endif
  1180. VOID
  1181. MPFreeAllPacketPools(
  1182.     IN PADAPT                    pAdapt
  1183.     )
  1184. /*++
  1185. Routine Description:
  1186.     Free all packet pools on the specified adapter.
  1187.     
  1188. Arguments:
  1189.     pAdapt    - pointer to ADAPT structure
  1190. Return Value:
  1191.     None
  1192. --*/
  1193. {
  1194.     if (pAdapt->RecvPacketPoolHandle != NULL)
  1195.     {
  1196.         //
  1197.         // Free the packet pool that is used to indicate receives
  1198.         //
  1199.         NdisFreePacketPool(pAdapt->RecvPacketPoolHandle);
  1200.         pAdapt->RecvPacketPoolHandle = NULL;
  1201.     }
  1202.     if (pAdapt->SendPacketPoolHandle != NULL)
  1203.     {
  1204.         //
  1205.         //  Free the packet pool that is used to send packets below
  1206.         //
  1207.         NdisFreePacketPool(pAdapt->SendPacketPoolHandle);
  1208.         pAdapt->SendPacketPoolHandle = NULL;
  1209.     }
  1210. }