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