1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS User I/O driver
4 * FILE: misc.c
5 * PURPOSE: Helper functions
6 * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
7 */
8
9 #include "ndisuio.h"
10
11 #define NDEBUG
12 #include <debug.h>
13
14 NDIS_STATUS
AllocateAndChainBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,PNDIS_PACKET Packet,PVOID Buffer,ULONG BufferSize,BOOLEAN Front)15 AllocateAndChainBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
16 PNDIS_PACKET Packet,
17 PVOID Buffer,
18 ULONG BufferSize,
19 BOOLEAN Front)
20 {
21 NDIS_STATUS Status;
22 PNDIS_BUFFER NdisBuffer;
23
24 /* Allocate the NDIS buffer mapping the pool */
25 NdisAllocateBuffer(&Status,
26 &NdisBuffer,
27 AdapterContext->BufferPoolHandle,
28 Buffer,
29 BufferSize);
30 if (Status != NDIS_STATUS_SUCCESS)
31 {
32 DPRINT1("No free buffer descriptors\n");
33 return Status;
34 }
35
36 if (Front)
37 {
38 /* Chain the buffer to front */
39 NdisChainBufferAtFront(Packet, NdisBuffer);
40 }
41 else
42 {
43 /* Chain the buffer to back */
44 NdisChainBufferAtBack(Packet, NdisBuffer);
45 }
46
47 /* Return success */
48 return NDIS_STATUS_SUCCESS;
49 }
50
51 PNDIS_PACKET
CreatePacketFromPoolBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,PVOID Buffer,ULONG BufferSize)52 CreatePacketFromPoolBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
53 PVOID Buffer,
54 ULONG BufferSize)
55 {
56 PNDIS_PACKET Packet;
57 NDIS_STATUS Status;
58
59 /* Allocate a packet descriptor */
60 NdisAllocatePacket(&Status,
61 &Packet,
62 AdapterContext->PacketPoolHandle);
63 if (Status != NDIS_STATUS_SUCCESS)
64 {
65 DPRINT1("No free packet descriptors\n");
66 return NULL;
67 }
68
69 /* Use the helper to chain the buffer */
70 Status = AllocateAndChainBuffer(AdapterContext, Packet,
71 Buffer, BufferSize, TRUE);
72 if (Status != NDIS_STATUS_SUCCESS)
73 {
74 NdisFreePacket(Packet);
75 return NULL;
76 }
77
78 /* Return the packet */
79 return Packet;
80 }
81
82 VOID
CleanupAndFreePacket(PNDIS_PACKET Packet,BOOLEAN FreePool)83 CleanupAndFreePacket(PNDIS_PACKET Packet, BOOLEAN FreePool)
84 {
85 PNDIS_BUFFER Buffer;
86 PVOID Data;
87 ULONG Length;
88
89 /* Free each buffer and its backing pool memory */
90 while (TRUE)
91 {
92 /* Unchain each buffer */
93 NdisUnchainBufferAtFront(Packet, &Buffer);
94 if (!Buffer)
95 break;
96
97 /* Get the backing memory */
98 NdisQueryBuffer(Buffer, &Data, &Length);
99
100 /* Free the buffer */
101 NdisFreeBuffer(Buffer);
102
103 if (FreePool)
104 {
105 /* Free the backing memory */
106 ExFreePool(Data);
107 }
108 }
109
110 /* Free the packet descriptor */
111 NdisFreePacket(Packet);
112 }
113
114 PNDISUIO_ADAPTER_CONTEXT
FindAdapterContextByName(PNDIS_STRING DeviceName)115 FindAdapterContextByName(PNDIS_STRING DeviceName)
116 {
117 KIRQL OldIrql;
118 PLIST_ENTRY CurrentEntry;
119 PNDISUIO_ADAPTER_CONTEXT AdapterContext;
120
121 KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
122 CurrentEntry = GlobalAdapterList.Flink;
123 while (CurrentEntry != &GlobalAdapterList)
124 {
125 AdapterContext = CONTAINING_RECORD(CurrentEntry, NDISUIO_ADAPTER_CONTEXT, ListEntry);
126
127 /* Check if the device name matches */
128 if (RtlEqualUnicodeString(&AdapterContext->DeviceName, DeviceName, TRUE))
129 {
130 KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
131 return AdapterContext;
132 }
133
134 CurrentEntry = CurrentEntry->Flink;
135 }
136 KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
137
138 return NULL;
139 }
140
141 VOID
ReferenceAdapterContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)142 ReferenceAdapterContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
143 {
144 /* Increment the open count */
145 AdapterContext->OpenCount++;
146 }
147
148 VOID
DereferenceAdapterContextWithOpenEntry(PNDISUIO_ADAPTER_CONTEXT AdapterContext,PNDISUIO_OPEN_ENTRY OpenEntry)149 DereferenceAdapterContextWithOpenEntry(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
150 PNDISUIO_OPEN_ENTRY OpenEntry)
151 {
152 KIRQL OldIrql;
153
154 /* Lock the adapter context */
155 KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
156
157 /* Decrement the open count */
158 AdapterContext->OpenCount--;
159
160 /* Cleanup the open entry if we were given one */
161 if (OpenEntry != NULL)
162 {
163 /* Remove the open entry */
164 RemoveEntryList(&OpenEntry->ListEntry);
165
166 /* Invalidate the FO */
167 OpenEntry->FileObject->FsContext = NULL;
168 OpenEntry->FileObject->FsContext2 = NULL;
169
170 /* Free the open entry */
171 ExFreePool(OpenEntry);
172 }
173
174 /* Release the adapter context lock */
175 KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
176 }
177