xref: /reactos/drivers/network/ndis/ndis/misc.c (revision 378642eb)
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS NDIS library
4  * FILE:        ndis/misc.c
5  */
6 
7 #include "ndissys.h"
8 
9 extern LONG CancelId;
10 
11 /*
12  * @implemented
13  */
14 #undef NdisInterlockedAddUlong
15 VOID
16 EXPORT
NdisInterlockedAddUlong(IN PULONG Addend,IN ULONG Increment,IN PNDIS_SPIN_LOCK SpinLock)17 NdisInterlockedAddUlong (
18     IN  PULONG          Addend,
19     IN  ULONG           Increment,
20     IN  PNDIS_SPIN_LOCK SpinLock)
21 {
22    ExInterlockedAddUlong ( Addend, Increment, &SpinLock->SpinLock );
23 }
24 
25 /*
26  * @implemented
27  */
28 VOID
29 EXPORT
NdisInterlockedAddLargeInteger(IN PLARGE_INTEGER Addend,IN LARGE_INTEGER Increment,IN PNDIS_SPIN_LOCK SpinLock)30 NdisInterlockedAddLargeInteger(
31     IN PLARGE_INTEGER Addend,
32     IN LARGE_INTEGER Increment,
33     IN PNDIS_SPIN_LOCK SpinLock)
34 {
35     /* This needs to be verified. The documentation
36      * seems to be missing but it is exported by
37      * NDIS 5.1 so I'm implementing it like the other
38      * interlocked routines
39      */
40 
41     ExInterlockedAddLargeInteger(Addend, Increment, &SpinLock->SpinLock);
42 }
43 
44 /*
45  * @implemented
46  */
47 LONG
48 EXPORT
NdisCompareAnsiString(IN PNDIS_ANSI_STRING String1,IN PNDIS_ANSI_STRING String2,BOOLEAN CaseInSensitive)49 NdisCompareAnsiString(
50     IN PNDIS_ANSI_STRING String1,
51     IN PNDIS_ANSI_STRING String2,
52     BOOLEAN CaseInSensitive)
53 {
54     /* This one needs to be verified also. See the
55      * comment in NdisInterlockedAddLargeInteger
56      */
57 
58     return RtlCompareString(String1, String2, CaseInSensitive);
59 }
60 
61 /*
62  * @implemented
63  */
64 LONG
65 EXPORT
NdisCompareUnicodeString(IN PNDIS_STRING String1,IN PNDIS_STRING String2,IN BOOLEAN CaseInSensitive)66 NdisCompareUnicodeString(
67     IN PNDIS_STRING String1,
68     IN PNDIS_STRING String2,
69     IN BOOLEAN CaseInSensitive)
70 {
71     /* This one needs to be verified also. See the
72      * comment in NdisInterlockedAddLargeInteger
73      */
74 
75     return RtlCompareUnicodeString(String1, String2, CaseInSensitive);
76 }
77 
78 /*
79  * @implemented
80  */
81 #undef NdisInterlockedInsertHeadList
82 PLIST_ENTRY
83 EXPORT
NdisInterlockedInsertHeadList(IN PLIST_ENTRY ListHead,IN PLIST_ENTRY ListEntry,IN PNDIS_SPIN_LOCK SpinLock)84 NdisInterlockedInsertHeadList(
85     IN  PLIST_ENTRY     ListHead,
86     IN  PLIST_ENTRY     ListEntry,
87     IN  PNDIS_SPIN_LOCK SpinLock)
88 {
89   return ExInterlockedInsertHeadList ( ListHead, ListEntry, &SpinLock->SpinLock );
90 }
91 
92 /*
93  * @implemented
94  */
95 #undef NdisInterlockedInsertTailList
96 PLIST_ENTRY
97 EXPORT
NdisInterlockedInsertTailList(IN PLIST_ENTRY ListHead,IN PLIST_ENTRY ListEntry,IN PNDIS_SPIN_LOCK SpinLock)98 NdisInterlockedInsertTailList(
99     IN  PLIST_ENTRY     ListHead,
100     IN  PLIST_ENTRY     ListEntry,
101     IN  PNDIS_SPIN_LOCK SpinLock)
102 {
103   return ExInterlockedInsertTailList ( ListHead, ListEntry, &SpinLock->SpinLock );
104 }
105 
106 
107 /*
108  * @implemented
109  */
110 #undef NdisInterlockedRemoveHeadList
111 PLIST_ENTRY
112 EXPORT
NdisInterlockedRemoveHeadList(IN PLIST_ENTRY ListHead,IN PNDIS_SPIN_LOCK SpinLock)113 NdisInterlockedRemoveHeadList(
114     IN  PLIST_ENTRY     ListHead,
115     IN  PNDIS_SPIN_LOCK SpinLock)
116 {
117   return ExInterlockedRemoveHeadList ( ListHead, &SpinLock->SpinLock );
118 }
119 
120 typedef struct _NDIS_HANDLE_OBJECT
121 {
122   HANDLE FileHandle;
123   BOOLEAN Mapped;
124   ULONG FileLength;
125   PVOID MapBuffer;
126 } NDIS_HANDLE_OBJECT, *PNDIS_HANDLE_OBJECT;
127 
128 FORCEINLINE
129 PNDIS_HANDLE_OBJECT
NDIS_HANDLE_TO_POBJECT(NDIS_HANDLE handle)130 NDIS_HANDLE_TO_POBJECT ( NDIS_HANDLE handle )
131 {
132   return (PNDIS_HANDLE_OBJECT)handle;
133 }
134 
135 FORCEINLINE
136 NDIS_HANDLE
NDIS_POBJECT_TO_HANDLE(PNDIS_HANDLE_OBJECT obj)137 NDIS_POBJECT_TO_HANDLE ( PNDIS_HANDLE_OBJECT obj )
138 {
139   return (NDIS_HANDLE)obj;
140 }
141 
142 static const WCHAR NDIS_FILE_FOLDER[] = L"\\SystemRoot\\System32\\Drivers\\";
143 
144 /*
145  * @implemented
146  */
147 VOID
148 EXPORT
NdisMapFile(OUT PNDIS_STATUS Status,OUT PVOID * MappedBuffer,IN NDIS_HANDLE FileHandle)149 NdisMapFile(
150     OUT PNDIS_STATUS    Status,
151     OUT PVOID           *MappedBuffer,
152     IN  NDIS_HANDLE     FileHandle)
153 {
154   PNDIS_HANDLE_OBJECT HandleObject = (PNDIS_HANDLE_OBJECT) FileHandle;
155 
156   NDIS_DbgPrint(MAX_TRACE, ("called: FileHandle 0x%x\n", FileHandle));
157 
158   if (HandleObject->Mapped)
159   {
160       /* If a file already mapped we will return an error code */
161       NDIS_DbgPrint(MIN_TRACE, ("File already mapped\n"));
162       *Status = NDIS_STATUS_ALREADY_MAPPED;
163       return;
164   }
165 
166   HandleObject->Mapped = TRUE;
167   *MappedBuffer = HandleObject->MapBuffer;
168 
169   /* Set returned status */
170   *Status = STATUS_SUCCESS;
171 }
172 
173 /*
174  * @implemented
175  */
176 VOID
177 EXPORT
NdisUnmapFile(IN NDIS_HANDLE FileHandle)178 NdisUnmapFile(
179     IN  NDIS_HANDLE FileHandle)
180 {
181   PNDIS_HANDLE_OBJECT HandleObject = (PNDIS_HANDLE_OBJECT) FileHandle;
182 
183   NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
184 
185   HandleObject->Mapped = FALSE;
186 }
187 
188 /*
189  * @implemented
190  */
191 VOID
192 EXPORT
NdisCloseFile(IN NDIS_HANDLE FileHandle)193 NdisCloseFile(
194     IN  NDIS_HANDLE FileHandle)
195 {
196   PNDIS_HANDLE_OBJECT FileHandleObject;
197 
198   ASSERT_IRQL(PASSIVE_LEVEL);
199 
200   NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
201 
202   ASSERT ( FileHandle );
203 
204   FileHandleObject = NDIS_HANDLE_TO_POBJECT(FileHandle);
205 
206   ASSERT ( FileHandleObject->FileHandle );
207 
208   if ( FileHandleObject->Mapped )
209     NdisUnmapFile ( FileHandle );
210 
211   ZwClose ( FileHandleObject->FileHandle );
212 
213   memset ( FileHandleObject, 0, sizeof(NDIS_HANDLE_OBJECT) );
214 
215   ExFreePool ( FileHandleObject );
216 }
217 
218 
219 /*
220  * @implemented
221  */
222 VOID
223 EXPORT
NdisOpenFile(OUT PNDIS_STATUS Status,OUT PNDIS_HANDLE FileHandle,OUT PUINT FileLength,IN PNDIS_STRING FileName,IN NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress)224 NdisOpenFile(
225     OUT PNDIS_STATUS            Status,
226     OUT PNDIS_HANDLE            FileHandle,
227     OUT PUINT                   FileLength,
228     IN  PNDIS_STRING            FileName,
229     IN  NDIS_PHYSICAL_ADDRESS   HighestAcceptableAddress)
230 {
231   NDIS_STRING FullFileName;
232   OBJECT_ATTRIBUTES ObjectAttributes;
233   PNDIS_HANDLE_OBJECT FileHandleObject = NULL;
234   IO_STATUS_BLOCK IoStatusBlock;
235 
236   ASSERT_IRQL(PASSIVE_LEVEL);
237 
238   NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
239 
240   ASSERT ( Status && FileName );
241 
242   *Status = NDIS_STATUS_SUCCESS;
243   FullFileName.Buffer = NULL;
244 
245   FullFileName.Length = sizeof(NDIS_FILE_FOLDER) - sizeof(UNICODE_NULL);
246   FullFileName.MaximumLength = FileName->MaximumLength + FullFileName.Length;
247   FullFileName.Buffer = ExAllocatePool ( NonPagedPool, FullFileName.MaximumLength );
248 
249   if ( !FullFileName.Buffer )
250   {
251     NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
252     *Status = NDIS_STATUS_RESOURCES;
253     goto cleanup;
254   }
255 
256   FileHandleObject = ExAllocatePool ( NonPagedPool, sizeof(NDIS_HANDLE_OBJECT) );
257   if ( !FileHandleObject )
258   {
259     NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
260     *Status = NDIS_STATUS_RESOURCES;
261     goto cleanup;
262   }
263   memset ( FileHandleObject, 0, sizeof(NDIS_HANDLE_OBJECT) );
264 
265   memmove ( FullFileName.Buffer, NDIS_FILE_FOLDER, FullFileName.Length );
266   *Status = RtlAppendUnicodeStringToString ( &FullFileName, FileName );
267   if ( !NT_SUCCESS(*Status) )
268   {
269     NDIS_DbgPrint(MIN_TRACE, ("RtlAppendUnicodeStringToString failed (%x)\n", *Status));
270     *Status = NDIS_STATUS_FAILURE;
271     goto cleanup;
272   }
273 
274   InitializeObjectAttributes ( &ObjectAttributes,
275     &FullFileName,
276     OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
277     NULL,
278     NULL );
279 
280   *Status = ZwCreateFile (
281     &FileHandleObject->FileHandle,
282     FILE_READ_DATA|SYNCHRONIZE,
283     &ObjectAttributes,
284     &IoStatusBlock,
285     NULL, // PLARGE_INTEGER AllocationSize
286     0, // ULONG FileAttributes
287     FILE_SHARE_READ, // ULONG ShareAccess
288     FILE_OPEN, // ULONG CreateDisposition
289     FILE_SYNCHRONOUS_IO_NONALERT, // ULONG CreateOptions
290     0, // PVOID EaBuffer
291     0 ); // ULONG EaLength
292 
293   if ( !NT_SUCCESS(*Status) )
294   {
295     NDIS_DbgPrint(MIN_TRACE, ("ZwCreateFile failed (%x) Name %wZ\n", *Status, FileName));
296     *Status = NDIS_STATUS_FAILURE;
297   }
298 
299 cleanup:
300   if ( FullFileName.Buffer != NULL )
301   {
302     ExFreePool ( FullFileName.Buffer );
303     FullFileName.Buffer = NULL;
304   }
305   if ( !NT_SUCCESS(*Status) )
306   {
307     if( FileHandleObject ) {
308 	ExFreePool ( FileHandleObject );
309 	FileHandleObject = NULL;
310     }
311     *FileHandle = NULL;
312   }
313   else
314     *FileHandle = NDIS_POBJECT_TO_HANDLE(FileHandleObject);
315 
316   return;
317 }
318 
319 /*
320  * @implemented
321  */
322 CCHAR
323 EXPORT
NdisSystemProcessorCount(VOID)324 NdisSystemProcessorCount(
325     VOID)
326 {
327 	return KeNumberProcessors;
328 }
329 
330 
331 /*
332  * @implemented
333  */
334 VOID
335 EXPORT
NdisGetCurrentProcessorCounts(OUT PULONG pIdleCount,OUT PULONG pKernelAndUser,OUT PULONG pIndex)336 NdisGetCurrentProcessorCounts(
337     OUT PULONG  pIdleCount,
338     OUT PULONG  pKernelAndUser,
339     OUT PULONG  pIndex)
340 /*
341  * FUNCTION:
342  * ARGUMENTS:
343  * NOTES:
344  *    NDIS 5.0
345  */
346 {
347     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
348 
349     ExGetCurrentProcessorCounts( (PULONG) pIdleCount, (PULONG) pKernelAndUser, (PULONG) pIndex);
350 }
351 
352 
353 /*
354  * @implemented
355  */
356 VOID
357 EXPORT
NdisGetSystemUpTime(OUT PULONG pSystemUpTime)358 NdisGetSystemUpTime(OUT PULONG pSystemUpTime)
359 {
360     ULONG Increment;
361     LARGE_INTEGER TickCount;
362 
363     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
364 
365     /* Get the increment and current tick count */
366     Increment = KeQueryTimeIncrement();
367     KeQueryTickCount(&TickCount);
368 
369     /* Convert to milliseconds and return */
370     TickCount.QuadPart *= Increment;
371     TickCount.QuadPart /= (10 * 1000);
372     *pSystemUpTime = TickCount.LowPart;
373 }
374 
375 /*
376  * @implemented
377  */
378 #undef NdisInterlockedDecrement
379 LONG
380 EXPORT
NdisInterlockedDecrement(IN PLONG Addend)381 NdisInterlockedDecrement(
382     IN  PLONG   Addend)
383 /*
384  * FUNCTION:
385  * ARGUMENTS:
386  * NOTES:
387  *    NDIS 5.0
388  */
389 {
390   return InterlockedDecrement ( Addend );
391 }
392 
393 
394 /*
395  * @implemented
396  */
397 #undef NdisInterlockedIncrement
398 LONG
399 EXPORT
NdisInterlockedIncrement(IN PLONG Addend)400 NdisInterlockedIncrement(
401     IN  PLONG   Addend)
402 /*
403  * FUNCTION:
404  * ARGUMENTS:
405  * NOTES:
406  *    NDIS 5.0
407  */
408 {
409   return InterlockedIncrement ( Addend );
410 }
411 
412 
413 /*
414  * @implemented
415  */
416 #undef NdisInterlockedPopEntrySList
417 PSINGLE_LIST_ENTRY
418 EXPORT
NdisInterlockedPopEntrySList(IN PSLIST_HEADER ListHead,IN PKSPIN_LOCK Lock)419 NdisInterlockedPopEntrySList(
420     IN  PSLIST_HEADER   ListHead,
421     IN  PKSPIN_LOCK     Lock)
422 /*
423  * FUNCTION:
424  * ARGUMENTS:
425  * NOTES:
426  *    NDIS 5.0
427  */
428 {
429   return (PSINGLE_LIST_ENTRY)ExInterlockedPopEntrySList ( ListHead, Lock );
430 }
431 
432 
433 /*
434  * @implemented
435  */
436 #undef NdisInterlockedPushEntrySList
437 PSINGLE_LIST_ENTRY
438 EXPORT
NdisInterlockedPushEntrySList(IN PSLIST_HEADER ListHead,IN PSINGLE_LIST_ENTRY ListEntry,IN PKSPIN_LOCK Lock)439 NdisInterlockedPushEntrySList(
440     IN  PSLIST_HEADER       ListHead,
441     IN  PSINGLE_LIST_ENTRY  ListEntry,
442     IN  PKSPIN_LOCK         Lock)
443 /*
444  * FUNCTION:
445  * ARGUMENTS:
446  * NOTES:
447  *    NDIS 5.0
448  */
449 {
450   return (PSINGLE_LIST_ENTRY)ExInterlockedPushEntrySList ( ListHead, (PSLIST_ENTRY)ListEntry, Lock );
451 }
452 
453 
454 VOID
455 NTAPI
ndisProcWorkItemHandler(PVOID pContext)456 ndisProcWorkItemHandler(PVOID pContext)
457 {
458     PNDIS_WORK_ITEM pNdisItem = (PNDIS_WORK_ITEM)pContext;
459 
460     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
461 
462     pNdisItem->Routine(pNdisItem, pNdisItem->Context);
463 }
464 
465 NDIS_STATUS
466 EXPORT
NdisScheduleWorkItem(IN PNDIS_WORK_ITEM pWorkItem)467 NdisScheduleWorkItem(
468     IN PNDIS_WORK_ITEM  pWorkItem)
469 {
470     PWORK_QUEUE_ITEM pntWorkItem = (PWORK_QUEUE_ITEM)pWorkItem->WrapperReserved;
471 
472     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
473 
474     ExInitializeWorkItem(pntWorkItem, ndisProcWorkItemHandler, pWorkItem);
475     ExQueueWorkItem(pntWorkItem, DelayedWorkQueue);
476     return NDIS_STATUS_SUCCESS;
477 }
478 
479 /*
480  * @implemented
481  */
482 VOID
483 EXPORT
NdisGetCurrentProcessorCpuUsage(PULONG pCpuUsage)484 NdisGetCurrentProcessorCpuUsage(
485     PULONG  pCpuUsage)
486 /*
487  * FUNCTION: Returns how busy the current processor is as a percentage
488  * ARGUMENTS:
489  *     pCpuUsage = Pointer to a buffer to place CPU usage
490  */
491 {
492     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
493 
494     ExGetCurrentProcessorCpuUsage(pCpuUsage);
495 }
496 
497 /*
498  * @implemented
499  */
500 ULONG
501 EXPORT
NdisGetSharedDataAlignment(VOID)502 NdisGetSharedDataAlignment(VOID)
503 {
504     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
505 
506     return KeGetRecommendedSharedDataAlignment();
507 }
508 
509 /*
510  * @implemented
511  */
512 UINT
513 EXPORT
NdisGetVersion(VOID)514 NdisGetVersion(VOID)
515 {
516     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
517 
518     return NDIS_VERSION;
519 }
520 
521 /*
522  * @implemented
523  */
524 UCHAR
525 EXPORT
NdisGeneratePartialCancelId(VOID)526 NdisGeneratePartialCancelId(VOID)
527 {
528     UCHAR PartialCancelId;
529 
530     PartialCancelId = (UCHAR)InterlockedIncrement(&CancelId);
531 
532     NDIS_DbgPrint(MAX_TRACE, ("Cancel ID %u\n", PartialCancelId));
533 
534     return PartialCancelId;
535 }
536 
537 /* EOF */
538