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