1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 ModuleName:
6 
7     MxGeneral.h
8 
9 Abstract:
10 
11     Mode agnostic definitions for general OS
12     functions used in framework code
13 
14     See MxGeneralKm.h and MxGeneralUm.h for mode
15     specific implementations
16 
17 Author:
18 
19 
20 
21 Revision History:
22 
23 
24 
25 --*/
26 
27 #pragma once
28 
29 //
30 // Placeholder macro for a no-op
31 //
32 #define DO_NOTHING()                            (0)
33 
34 //
35 // We need to make these static functions of the class
36 // to force common definition to apply to um and km versions
37 //
38 // If we don't do this, um and km definitions can diverge
39 //
40 class Mx
41 {
42 public:
43 
44     //
45     // IsUM/IsKM don't change at runtime
46     // but defining them as functions makes it more convenient to check
47     // for UM/KM as compared to using ifdef's in certain places
48     //
49     // Since they are forceinlined and return a constant value,
50     // optimized code is no different than using an ifdef
51     //
52     // See FxPoolAllocator in WdfPool.cpp for example of such usage
53     //
54     __inline
55     static
56     BOOLEAN
57     IsUM(
58         );
59 
60     __inline
61     static
62     BOOLEAN
63     IsKM(
64         );
65 
66     __inline
67     static
68     MxThread
69     MxGetCurrentThread(
70         );
71 
72     __inline
73     static
74     MdEThread
75     GetCurrentEThread(
76         );
77 
78     NTSTATUS
79     static
80     MxTerminateCurrentThread(
81         __in NTSTATUS Status
82         );
83 
84     __inline
85     static
86     KIRQL
87     MxGetCurrentIrql(
88         );
89 
90     __drv_maxIRQL(HIGH_LEVEL)
91     __drv_raisesIRQL(NewIrql)
92     __inline
93     static
94     VOID
95     MxRaiseIrql(
96         __in KIRQL                              NewIrql,
97         __out __deref __drv_savesIRQL PKIRQL    OldIrql
98         );
99 
100     __drv_maxIRQL(HIGH_LEVEL)
101     __inline
102     static
103     VOID
104     MxLowerIrql(
105         __in __drv_restoresIRQL __drv_nonConstant  KIRQL  NewIrql
106         );
107 
108     __inline
109     static
110     VOID
111     MxQueryTickCount(
112         __out PLARGE_INTEGER  TickCount
113         );
114 
115     __inline
116     static
117     ULONG
118     MxQueryTimeIncrement(
119         );
120 
121 
122 
123 
124 
125 
126 
127 
128     static
129     DECLSPEC_NORETURN
130     VOID
131     MxBugCheckEx(
132         __in ULONG  BugCheckCode,
133         __in ULONG_PTR  BugCheckParameter1,
134         __in ULONG_PTR  BugCheckParameter2,
135         __in ULONG_PTR  BugCheckParameter3,
136         __in ULONG_PTR  BugCheckParameter4
137     );
138 
139     __inline
140     static
141     VOID
142     MxDbgBreakPoint(
143         );
144 
145     static
146     VOID
147     MxDbgPrint(
148         __drv_formatString(printf)
149         __in PCSTR DebugMessage,
150         ...
151         );
152 
153     __inline
154     static
155     VOID
156     MxAssert(
157         __in BOOLEAN Condition
158         );
159 
160     __inline
161     static
162     VOID
163     MxAssertMsg(
164         __in LPSTR Message,
165         __in BOOLEAN Condition
166         );
167 
168     _Acquires_lock_(_Global_critical_region_)
169     __inline
170     static
171     VOID
172     MxEnterCriticalRegion(
173         );
174 
175     _Releases_lock_(_Global_critical_region_) //implies _Requires_lock_held_(_Global_critical_region_)
176     __inline
177     static
178     VOID
179     MxLeaveCriticalRegion(
180         );
181 
182     __inline
183     static
184     VOID
185     MxDelayExecutionThread(
186         __in KPROCESSOR_MODE  WaitMode,
187         __in BOOLEAN  Alertable,
188         __in PLARGE_INTEGER  Interval
189         );
190 
191     //
192     // Mode agnostic function to get address of a system function
193     // Should be used only for Rtl* functions applicable both to
194     // kernel mode and user mode
195     //
196     // User mode version is assumed to reside in ntdll.dll
197     //
198     // The argument type is MxFuncName so that it can be defined
199     // as LPCWSTR in kernel mode and LPCSTR in user mode
200     // which is what MmGetSystemRoutineAddress and GetProcAddress
201     // expect respectively
202     //
203     __inline
204     static
205     PVOID
206     MxGetSystemRoutineAddress(
207         __in MxFuncName FuncName
208         );
209 
210     __inline
211     static
212     VOID
213     MxReferenceObject(
214         __in PVOID Object
215         );
216 
217     __inline
218     static
219     VOID
220     MxDereferenceObject(
221         __in PVOID Object
222         );
223 
224     __inline
225     static
226     VOID
227     MxInitializeRemoveLock(
228         __in MdRemoveLock  Lock,
229         __in ULONG  AllocateTag,
230         __in ULONG  MaxLockedMinutes,
231         __in ULONG  HighWatermark
232         );
233 
234     __inline
235     static
236     NTSTATUS
237     MxAcquireRemoveLock(
238         __in MdRemoveLock  RemoveLock,
239         __in_opt PVOID  Tag
240         );
241 
242     __inline
243     static
244     VOID
245     MxReleaseRemoveLock(
246         __in MdRemoveLock  RemoveLock,
247         __in PVOID  Tag
248         );
249 
250     __inline
251     static
252     VOID
253     MxReleaseRemoveLockAndWait(
254         __in MdRemoveLock  RemoveLock,
255         __in PVOID  Tag
256         );
257 
258     __inline
259     static
260     BOOLEAN
261     MxHasEnoughRemainingThreadStack(
262         VOID
263         );
264 
265 
266     _Releases_lock_(_Global_cancel_spin_lock_) //implies _Requires_lock_held_(_Global_cancel_spin_lock_)
267     __drv_requiresIRQL(DISPATCH_LEVEL)
268     __inline
269     static
270     VOID
271     ReleaseCancelSpinLock(
272         __in __drv_restoresIRQL __drv_useCancelIRQL KIRQL  Irql
273         );
274 
275     __inline
276     static
277     NTSTATUS
278     CreateCallback(
279         __out PCALLBACK_OBJECT  *CallbackObject,
280         __in POBJECT_ATTRIBUTES  ObjectAttributes,
281         __in BOOLEAN  Create,
282         __in BOOLEAN  AllowMultipleCallbacks
283         );
284 
285     __inline
286     static
287     PVOID
288     RegisterCallback(
289         __in PCALLBACK_OBJECT  CallbackObject,
290         __in MdCallbackFunction  CallbackFunction,
291         __in PVOID  CallbackContext
292         );
293 
294     __inline
295     static
296     VOID
297     UnregisterCallback(
298         __in PVOID  CbRegistration
299         );
300 
301     static
302     VOID
303     MxGlobalInit(
304         VOID
305         );
306 
307     __inline
308     static
309     VOID
310     MxUnlockPages(
311         __in PMDL Mdl
312         );
313 
314     __inline
315     static
316     PVOID
317     MxGetSystemAddressForMdlSafe(
318         __inout PMDL Mdl,
319         __in    ULONG Priority
320         );
321 
322     __inline
323     static
324     VOID
325     MxBuildMdlForNonPagedPool(
326         __inout PMDL Mdl
327         );
328 
329     __inline
330     static
331     PVOID
332     MxGetDriverObjectExtension(
333         __in MdDriverObject DriverObject,
334         __in PVOID ClientIdentificationAddress
335         );
336 
337     __inline
338     static
339     NTSTATUS
340     MxAllocateDriverObjectExtension(
341         _In_  MdDriverObject DriverObject,
342         _In_  PVOID ClientIdentificationAddress,
343         _In_  ULONG DriverObjectExtensionSize,
344         // When successful, this always allocates already-aliased memory.
345         _Post_ _At_(*DriverObjectExtension, _When_(return==0,
346         __drv_aliasesMem __drv_allocatesMem(Mem) _Post_notnull_))
347         _When_(return == 0, _Outptr_result_bytebuffer_(DriverObjectExtensionSize))
348         PVOID *DriverObjectExtension
349         );
350 
351     __inline
352     static
353     MdDeviceObject
354     MxGetAttachedDeviceReference(
355         __in MdDeviceObject DriverObject
356         );
357 
358     __inline
359     static
360     VOID
361     MxDeleteSymbolicLink(
362         __in PUNICODE_STRING Link
363         );
364 
365     __inline
366     static
367     VOID
368     MxDeleteNPagedLookasideList(
369         _In_ PNPAGED_LOOKASIDE_LIST LookasideList
370         );
371 
372     __inline
373     static
374     VOID
375     MxDeletePagedLookasideList(
376         _In_ PPAGED_LOOKASIDE_LIST LookasideList
377         );
378 
379     __inline
380     static
381     VOID
382     MxInitializeNPagedLookasideList(
383         _Out_     PNPAGED_LOOKASIDE_LIST Lookaside,
384         _In_opt_  PALLOCATE_FUNCTION Allocate,
385         _In_opt_  PFREE_FUNCTION Free,
386         _In_      ULONG Flags,
387         _In_      SIZE_T Size,
388         _In_      ULONG Tag,
389         _In_      USHORT Depth
390         );
391 
392     __inline
393     static
394     VOID
395     MxInitializePagedLookasideList(
396         _Out_     PPAGED_LOOKASIDE_LIST Lookaside,
397         _In_opt_  PALLOCATE_FUNCTION Allocate,
398         _In_opt_  PFREE_FUNCTION Free,
399         _In_      ULONG Flags,
400         _In_      SIZE_T Size,
401         _In_      ULONG Tag,
402         _In_      USHORT Depth
403         );
404 
405     __inline
406     static
407     VOID
408     MxDeleteDevice(
409         _In_ MdDeviceObject Device
410         );
411 
412     static
413     VOID
414     MxDetachDevice(
415         _Inout_ MdDeviceObject Device
416         );
417 
418     __inline
419     static
420     MdDeviceObject
421     MxAttachDeviceToDeviceStack(
422         _In_ MdDeviceObject SourceDevice,
423         _In_ MdDeviceObject TargetDevice
424         );
425 
426     __inline
427     static
428     NTSTATUS
429     MxCreateDeviceSecure(
430         _In_      MdDriverObject DriverObject,
431         _In_      ULONG DeviceExtensionSize,
432         _In_opt_  PUNICODE_STRING DeviceName,
433         _In_      DEVICE_TYPE DeviceType,
434         _In_      ULONG DeviceCharacteristics,
435         _In_      BOOLEAN Exclusive,
436         _In_      PCUNICODE_STRING DefaultSDDLString,
437         _In_opt_  LPCGUID DeviceClassGuid,
438         _Out_     MdDeviceObject *DeviceObject
439         );
440 
441     __inline
442     static
443     NTSTATUS
444     MxCreateDevice(
445         _In_      MdDriverObject DriverObject,
446         _In_      ULONG DeviceExtensionSize,
447         _In_opt_  PUNICODE_STRING DeviceName,
448         _In_      DEVICE_TYPE DeviceType,
449         _In_      ULONG DeviceCharacteristics,
450         _In_      BOOLEAN Exclusive,
451         _Out_     MdDeviceObject *DeviceObject
452     );
453 
454     __inline
455     static
456     NTSTATUS
457     MxCreateSymbolicLink(
458         _In_ PUNICODE_STRING SymbolicLinkName,
459         _In_ PUNICODE_STRING DeviceName
460         );
461 
462     __inline
463     static
464     VOID
465     MxFlushQueuedDpcs(
466         );
467 
468     __inline
469     static
470     NTSTATUS
471     MxOpenKey(
472         _Out_ PHANDLE KeyHandle,
473         _In_ ACCESS_MASK DesiredAccess,
474         _In_ POBJECT_ATTRIBUTES ObjectAttributes
475         );
476 
477     __inline
478     static
479     NTSTATUS
480     MxSetDeviceInterfaceState(
481         _In_ PUNICODE_STRING SymbolicLinkName,
482         _In_ BOOLEAN Enable
483         );
484 
485     __inline
486     static
487     NTSTATUS
488     MxRegisterDeviceInterface(
489         _In_      PDEVICE_OBJECT PhysicalDeviceObject,
490         _In_      const GUID *InterfaceClassGuid,
491         _In_opt_  PUNICODE_STRING ReferenceString,
492         _Out_     PUNICODE_STRING SymbolicLinkName
493         );
494 
495     __inline
496     static
497     NTSTATUS
498     MxDeleteKey(
499         _In_ HANDLE KeyHandle
500         );
501 
502     __inline
503     static
504     VOID
505     MxInitializeMdl(
506         _In_  PMDL MemoryDescriptorList,
507         _In_  PVOID BaseVa,
508         _In_  SIZE_T Length
509         );
510 
511     __inline
512     static
513     PVOID
514     MxGetMdlVirtualAddress(
515         _In_ PMDL Mdl
516         );
517 
518     __inline
519     static
520     VOID
521     MxBuildPartialMdl(
522         _In_     PMDL SourceMdl,
523         _Inout_  PMDL TargetMdl,
524         _In_     PVOID VirtualAddress,
525         _In_     ULONG Length
526     );
527 
528     __inline
529     static
530     VOID
531     MxQuerySystemTime(
532         _Out_ PLARGE_INTEGER CurrentTime
533         );
534 
535     __inline
536     static
537     NTSTATUS
538     MxSetValueKey(
539         _In_      HANDLE KeyHandle,
540         _In_      PUNICODE_STRING ValueName,
541         _In_opt_  ULONG TitleIndex,
542         _In_      ULONG Type,
543         _In_opt_  PVOID Data,
544         _In_      ULONG DataSize
545         );
546 
547     __inline
548     static
549     NTSTATUS
550     MxQueryValueKey(
551         _In_       HANDLE KeyHandle,
552         _In_       PUNICODE_STRING ValueName,
553         _In_       KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
554         _Out_opt_  PVOID KeyValueInformation,
555         _In_       ULONG Length,
556         _Out_      PULONG ResultLength
557     );
558     __inline
559     static
560     NTSTATUS
561     MxReferenceObjectByHandle(
562         __in HANDLE Handle,
563         __in ACCESS_MASK DesiredAccess,
564         __in_opt POBJECT_TYPE ObjectType,
565         __in KPROCESSOR_MODE AccessMode,
566         __out  PVOID *Object,
567         __out_opt POBJECT_HANDLE_INFORMATION HandleInformation
568         );
569 
570     __inline
571     static
572     NTSTATUS
573     MxUnRegisterPlugPlayNotification(
574         __in __drv_freesMem(Pool) PVOID NotificationEntry
575         );
576 
577     __inline
578     static
579     NTSTATUS
580     MxClose (
581         __in HANDLE Handle
582         );
583 
584     __inline
585     static
586     KIRQL
587     MxAcquireInterruptSpinLock(
588         _Inout_ PKINTERRUPT Interrupt
589         );
590 
591     __inline
592     static
593     VOID
594     MxReleaseInterruptSpinLock(
595         _Inout_ PKINTERRUPT Interrupt,
596         _In_ KIRQL OldIrql
597         );
598 
599     __inline
600     static
601     BOOLEAN
602     MxInsertQueueDpc(
603       __inout   PRKDPC Dpc,
604       __in_opt  PVOID SystemArgument1,
605       __in_opt  PVOID SystemArgument2
606     );
607 };
608