ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

protocol.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:   See COPYING in the top level directory
00003  * PROJECT:     ReactOS NDIS User I/O driver
00004  * FILE:        protocol.c
00005  * PURPOSE:     Protocol stuff
00006  * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
00007  */
00008 
00009 #include "ndisuio.h"
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 VOID
00015 NTAPI
00016 NduOpenAdapterComplete(NDIS_HANDLE ProtocolBindingContext,
00017                        NDIS_STATUS Status,
00018                        NDIS_STATUS OpenStatus)
00019 {
00020     PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
00021 
00022     DPRINT("Asynchronous adapter open completed\n");
00023 
00024     /* Store the final status and signal the event */
00025     AdapterContext->AsyncStatus = Status;
00026     KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
00027 }
00028 
00029 VOID
00030 NTAPI
00031 NduCloseAdapterComplete(NDIS_HANDLE ProtocolBindingContext,
00032                         NDIS_STATUS Status)
00033 {
00034     PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
00035 
00036     DPRINT("Asynchronous adapter close completed\n");
00037 
00038     /* Store the final status and signal the event */
00039     AdapterContext->AsyncStatus = Status;
00040     KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
00041 }
00042 
00043 VOID
00044 NTAPI
00045 NduSendComplete(NDIS_HANDLE ProtocolBindingContext,
00046                 PNDIS_PACKET Packet,
00047                 NDIS_STATUS Status)
00048 {
00049     PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
00050     
00051     DPRINT("Asynchronous adapter send completed\n");
00052     
00053     /* Store the final status and signal the event */
00054     AdapterContext->AsyncStatus = Status;
00055     KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
00056 }
00057 
00058 VOID
00059 NTAPI
00060 NduTransferDataComplete(NDIS_HANDLE ProtocolBindingContext,
00061                         PNDIS_PACKET Packet,
00062                         NDIS_STATUS Status,
00063                         UINT BytesTransferred)
00064 {
00065     PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
00066 
00067     DPRINT("Asynchronous adapter transfer completed\n");
00068 
00069     /* Store the final status and signal the event */
00070     AdapterContext->AsyncStatus = Status;
00071     KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
00072 }
00073 
00074 VOID
00075 NTAPI
00076 NduResetComplete(NDIS_HANDLE ProtocolBindingContext,
00077                  NDIS_STATUS Status)
00078 {
00079     PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
00080 
00081     DPRINT("Asynchronous adapter reset completed\n");
00082 
00083     /* Store the final status and signal the event */
00084     AdapterContext->AsyncStatus = Status;
00085     KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
00086 }
00087 
00088 VOID
00089 NTAPI
00090 NduRequestComplete(NDIS_HANDLE ProtocolBindingContext,
00091                    PNDIS_REQUEST NdisRequest,
00092                    NDIS_STATUS Status)
00093 {
00094     PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
00095 
00096     DPRINT("Asynchronous adapter request completed\n");
00097 
00098     /* Store the final status and signal the event */
00099     AdapterContext->AsyncStatus = Status;
00100     KeSetEvent(&AdapterContext->AsyncEvent, IO_NO_INCREMENT, FALSE);
00101 }
00102 
00103 NDIS_STATUS
00104 NTAPI
00105 NduReceive(NDIS_HANDLE ProtocolBindingContext,
00106            NDIS_HANDLE MacReceiveContext,
00107            PVOID HeaderBuffer,
00108            UINT HeaderBufferSize,
00109            PVOID LookAheadBuffer,
00110            UINT LookaheadBufferSize,
00111            UINT PacketSize)
00112 {
00113     PNDISUIO_ADAPTER_CONTEXT AdapterContext = ProtocolBindingContext;
00114     PNDISUIO_PACKET_ENTRY PacketEntry;
00115     PVOID PacketBuffer;
00116     PNDIS_PACKET Packet;
00117     NDIS_STATUS Status;
00118     UINT BytesTransferred;
00119     
00120     DPRINT("Received a %d byte packet\n", PacketSize);
00121 
00122     /* Discard if nobody is waiting for it */
00123     if (AdapterContext->OpenCount == 0)
00124         return NDIS_STATUS_NOT_ACCEPTED;
00125     
00126     /* Allocate a buffer to hold the packet data and header */
00127     PacketBuffer = ExAllocatePool(NonPagedPool, PacketSize + HeaderBufferSize);
00128     if (!PacketBuffer)
00129         return NDIS_STATUS_NOT_ACCEPTED;
00130 
00131     /* Allocate the packet descriptor and buffer */
00132     Packet = CreatePacketFromPoolBuffer(AdapterContext,
00133                                         (PUCHAR)PacketBuffer + HeaderBufferSize,
00134                                         PacketSize);
00135     if (!Packet)
00136     {
00137         ExFreePool(PacketBuffer);
00138         return NDIS_STATUS_NOT_ACCEPTED;
00139     }
00140 
00141     /* Transfer the packet data into our data buffer */
00142     if (LookaheadBufferSize == PacketSize)
00143     {
00144         NdisCopyLookaheadData((PVOID)((PUCHAR)PacketBuffer + HeaderBufferSize),
00145                               LookAheadBuffer,
00146                               PacketSize,
00147                               AdapterContext->MacOptions);
00148         BytesTransferred = PacketSize;
00149     }
00150     else
00151     {
00152         NdisTransferData(&Status,
00153                          AdapterContext->BindingHandle,
00154                          MacReceiveContext,
00155                          0,
00156                          PacketSize,
00157                          Packet,
00158                          &BytesTransferred);
00159         if (Status == NDIS_STATUS_PENDING)
00160         {
00161             KeWaitForSingleObject(&AdapterContext->AsyncEvent,
00162                                   Executive,
00163                                   KernelMode,
00164                                   FALSE,
00165                                   NULL);
00166             Status = AdapterContext->AsyncStatus;
00167         }
00168         if (Status != NDIS_STATUS_SUCCESS)
00169         {
00170             DPRINT1("Failed to transfer data with status 0x%x\n", Status);
00171             CleanupAndFreePacket(Packet, TRUE);
00172             return NDIS_STATUS_NOT_ACCEPTED;
00173         }
00174     }
00175     
00176     /* Copy the header data */
00177     RtlCopyMemory(PacketBuffer, HeaderBuffer, HeaderBufferSize);
00178     
00179     /* Free the packet descriptor and buffers 
00180        but not the pool because we still need it */
00181     CleanupAndFreePacket(Packet, FALSE);
00182 
00183     /* Allocate a packet entry from pool */
00184     PacketEntry = ExAllocatePool(NonPagedPool, sizeof(NDISUIO_PACKET_ENTRY) + BytesTransferred + HeaderBufferSize - 1);
00185     if (!PacketEntry)
00186     {
00187         ExFreePool(PacketBuffer);
00188         return NDIS_STATUS_RESOURCES;
00189     }
00190 
00191     /* Initialize the packet entry and copy in packet data */
00192     PacketEntry->PacketLength = BytesTransferred + HeaderBufferSize;
00193     RtlCopyMemory(PacketEntry->PacketData, PacketBuffer, PacketEntry->PacketLength);
00194     
00195     /* Free the old buffer */
00196     ExFreePool(PacketBuffer);
00197 
00198     /* Insert the packet on the adapter's packet list */
00199     ExInterlockedInsertTailList(&AdapterContext->PacketList,
00200                                 &PacketEntry->ListEntry,
00201                                 &AdapterContext->Spinlock);
00202     
00203     /* Signal the read event */
00204     KeSetEvent(&AdapterContext->PacketReadEvent,
00205                IO_NETWORK_INCREMENT,
00206                FALSE);
00207 
00208     return NDIS_STATUS_SUCCESS;
00209 }
00210 
00211 VOID
00212 NTAPI
00213 NduReceiveComplete(NDIS_HANDLE ProtocolBindingContext)
00214 {
00215     /* No op */
00216 }
00217 
00218 VOID
00219 NTAPI
00220 NduStatus(NDIS_HANDLE ProtocolBindingContext,
00221           NDIS_STATUS GeneralStatus,
00222           PVOID StatusBuffer,
00223           UINT StatusBufferSize)
00224 {
00225     /* FIXME: Implement status tracking */
00226 }
00227 
00228 VOID
00229 NTAPI
00230 NduStatusComplete(NDIS_HANDLE ProtocolBindingContext)
00231 {
00232     /* FIXME: Implement status tracking */
00233 }
00234 
00235 static
00236 NDIS_STATUS
00237 UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
00238 {
00239     KIRQL OldIrql;
00240     PLIST_ENTRY CurrentEntry;
00241     PNDISUIO_OPEN_ENTRY OpenEntry;
00242     PNDISUIO_PACKET_ENTRY PacketEntry;
00243     NDIS_STATUS Status;
00244     
00245     DPRINT("Unbinding adapter %wZ\n", &AdapterContext->DeviceName);
00246     
00247     /* FIXME: We don't do anything with outstanding reads */
00248 
00249     /* Remove the adapter context from the global list */
00250     KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
00251     RemoveEntryList(&AdapterContext->ListEntry);
00252     KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
00253     
00254     /* Free the device name string */
00255     RtlFreeUnicodeString(&AdapterContext->DeviceName);
00256 
00257     /* Invalidate all handles to this adapter */
00258     CurrentEntry = AdapterContext->OpenEntryList.Flink;
00259     while (CurrentEntry != &AdapterContext->OpenEntryList)
00260     {
00261         OpenEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_OPEN_ENTRY, ListEntry);
00262 
00263         /* Make sure the entry is sane */
00264         ASSERT(OpenEntry->FileObject);
00265 
00266         /* Remove the adapter context pointer */
00267         ASSERT(AdapterContext == OpenEntry->FileObject->FsContext);
00268         OpenEntry->FileObject->FsContext = NULL;
00269         AdapterContext->OpenCount--;
00270 
00271         /* Remove the open entry pointer */
00272         ASSERT(OpenEntry == OpenEntry->FileObject->FsContext2);
00273         OpenEntry->FileObject->FsContext2 = NULL;
00274         
00275         /* Move to the next entry */
00276         CurrentEntry = CurrentEntry->Flink;
00277 
00278         /* Free the open entry */
00279         ExFreePool(OpenEntry);
00280     }
00281 
00282     /* If this fails, we have a refcount mismatch somewhere */
00283     ASSERT(AdapterContext->OpenCount == 0);
00284     
00285     /* Free all pending packet entries */
00286     CurrentEntry = AdapterContext->PacketList.Flink;
00287     while (CurrentEntry != &AdapterContext->PacketList)
00288     {
00289         PacketEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_PACKET_ENTRY, ListEntry);
00290 
00291         /* Move to the next entry */
00292         CurrentEntry = CurrentEntry->Flink;
00293 
00294         /* Free the packet entry */
00295         ExFreePool(PacketEntry);
00296     }
00297     
00298     /* Send the close request */
00299     NdisCloseAdapter(&Status,
00300                      AdapterContext->BindingHandle);
00301     
00302     /* Wait for a pending close */
00303     if (Status == NDIS_STATUS_PENDING)
00304     {
00305         KeWaitForSingleObject(&AdapterContext->AsyncEvent,
00306                               Executive,
00307                               KernelMode,
00308                               FALSE,
00309                               NULL);
00310         Status = AdapterContext->AsyncStatus;
00311     }
00312     
00313     /* Free the context */
00314     ExFreePool(AdapterContext);
00315     
00316     return Status;
00317 }
00318 
00319 static
00320 NDIS_STATUS
00321 BindAdapterByName(PNDIS_STRING DeviceName)
00322 {
00323     NDIS_STATUS OpenErrorStatus;
00324     PNDISUIO_ADAPTER_CONTEXT AdapterContext;
00325     NDIS_MEDIUM SupportedMedia[1] = {NdisMedium802_3};
00326     UINT SelectedMedium;
00327     NDIS_STATUS Status;
00328     NDIS_REQUEST Request;
00329 
00330     /* Allocate the adapter context */
00331     AdapterContext = ExAllocatePool(NonPagedPool, sizeof(*AdapterContext));
00332     if (!AdapterContext)
00333     {
00334         return NDIS_STATUS_RESOURCES;
00335     }
00336 
00337     /* Set up the adapter context */
00338     RtlZeroMemory(AdapterContext, sizeof(*AdapterContext));
00339     KeInitializeEvent(&AdapterContext->AsyncEvent, SynchronizationEvent, FALSE);
00340     KeInitializeEvent(&AdapterContext->PacketReadEvent, SynchronizationEvent, FALSE);
00341     KeInitializeSpinLock(&AdapterContext->Spinlock);
00342     InitializeListHead(&AdapterContext->PacketList);
00343     InitializeListHead(&AdapterContext->OpenEntryList);
00344     AdapterContext->OpenCount = 0;
00345 
00346     AdapterContext->DeviceName.Length =
00347     AdapterContext->DeviceName.MaximumLength = DeviceName->Length;
00348     AdapterContext->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceName->Length);
00349     if (!AdapterContext->DeviceName.Buffer)
00350     {
00351         ExFreePool(AdapterContext);
00352         return NDIS_STATUS_RESOURCES;
00353     }
00354 
00355     /* Copy the device name into the adapter context */
00356     RtlCopyMemory(AdapterContext->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
00357     
00358     DPRINT("Binding adapter %wZ\n", &AdapterContext->DeviceName);
00359 
00360     /* Create the buffer pool */
00361     NdisAllocateBufferPool(&Status,
00362                            &AdapterContext->BufferPoolHandle,
00363                            50);
00364     if (Status != NDIS_STATUS_SUCCESS)
00365     {
00366         DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status);
00367         RtlFreeUnicodeString(&AdapterContext->DeviceName);
00368         ExFreePool(AdapterContext);
00369         return Status;
00370     }
00371 
00372     /* Create the packet pool */
00373     NdisAllocatePacketPool(&Status,
00374                            &AdapterContext->PacketPoolHandle,
00375                            25,
00376                            PROTOCOL_RESERVED_SIZE_IN_PACKET);
00377     if (Status != NDIS_STATUS_SUCCESS)
00378     {
00379         DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status);
00380         NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
00381         RtlFreeUnicodeString(&AdapterContext->DeviceName);
00382         ExFreePool(AdapterContext);
00383         return Status;
00384     }
00385 
00386     /* Send the open request */
00387     NdisOpenAdapter(&Status,
00388                     &OpenErrorStatus,
00389                     &AdapterContext->BindingHandle,
00390                     &SelectedMedium,
00391                     SupportedMedia,
00392                     1,
00393                     GlobalProtocolHandle,
00394                     AdapterContext,
00395                     DeviceName,
00396                     0,
00397                     NULL);
00398     
00399     /* Wait for a pending open */
00400     if (Status == NDIS_STATUS_PENDING)
00401     {
00402         KeWaitForSingleObject(&AdapterContext->AsyncEvent,
00403                               Executive,
00404                               KernelMode,
00405                               FALSE,
00406                               NULL);
00407         Status = AdapterContext->AsyncStatus;
00408     }
00409     
00410     /* Check the final status */
00411     if (Status != NDIS_STATUS_SUCCESS)
00412     {
00413         DPRINT1("Failed to open adapter for bind with status 0x%x\n", Status);
00414         NdisFreePacketPool(AdapterContext->PacketPoolHandle);
00415         NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
00416         RtlFreeUnicodeString(&AdapterContext->DeviceName);
00417         ExFreePool(AdapterContext);
00418         return Status;
00419     }
00420     
00421     /* Get the MAC options */
00422     Request.RequestType = NdisRequestQueryInformation;
00423     Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAC_OPTIONS;
00424     Request.DATA.QUERY_INFORMATION.InformationBuffer = &AdapterContext->MacOptions;
00425     Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(ULONG);
00426     NdisRequest(&Status,
00427                 AdapterContext->BindingHandle,
00428                 &Request);
00429 
00430     /* Wait for a pending request */
00431     if (Status == NDIS_STATUS_PENDING)
00432     {
00433         KeWaitForSingleObject(&AdapterContext->AsyncEvent,
00434                               Executive,
00435                               KernelMode,
00436                               FALSE,
00437                               NULL);
00438         Status = AdapterContext->AsyncStatus;
00439     }
00440     
00441     /* Check the final status */
00442     if (Status != NDIS_STATUS_SUCCESS)
00443     {
00444         NDIS_STATUS CloseStatus;
00445 
00446         DPRINT1("Failed to get MAC options with status 0x%x\n", Status);
00447 
00448         NdisCloseAdapter(&CloseStatus,
00449                          AdapterContext->BindingHandle);
00450         if (CloseStatus == NDIS_STATUS_PENDING)
00451         {
00452             KeWaitForSingleObject(&AdapterContext->AsyncEvent,
00453                                   Executive,
00454                                   KernelMode,
00455                                   FALSE,
00456                                   NULL);
00457         }
00458 
00459         NdisFreePacketPool(AdapterContext->PacketPoolHandle);
00460         NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
00461         RtlFreeUnicodeString(&AdapterContext->DeviceName);
00462         ExFreePool(AdapterContext);
00463         return Status;
00464     }
00465     
00466     /* Add the adapter context to the global list */
00467     ExInterlockedInsertTailList(&GlobalAdapterList,
00468                                 &AdapterContext->ListEntry,
00469                                 &GlobalAdapterListLock);
00470 
00471     return STATUS_SUCCESS;
00472 }
00473 
00474 VOID
00475 NTAPI
00476 NduBindAdapter(PNDIS_STATUS Status,
00477                NDIS_HANDLE BindContext,
00478                PNDIS_STRING DeviceName,
00479                PVOID SystemSpecific1,
00480                PVOID SystemSpecific2)
00481 {
00482     /* Use our helper function to create a context for this adapter */
00483     *Status = BindAdapterByName(DeviceName);
00484 }
00485 
00486 VOID
00487 NTAPI
00488 NduUnbindAdapter(PNDIS_STATUS Status,
00489                  NDIS_HANDLE ProtocolBindingContext,
00490                  NDIS_HANDLE UnbindContext)
00491 {
00492     /* This is forced unbind. UnbindAdapterByContext() will take care of 
00493      * invalidating file handles pointer to this adapter for us */
00494     *Status = UnbindAdapterByContext(ProtocolBindingContext);
00495 }
00496 

Generated on Sun May 27 2012 04:24:17 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.