1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 ModuleName:
6 
7     MxGeneralUm.h
8 
9 Abstract:
10 
11     User mode implementation for general OS
12     functions defined in MxGeneral.h
13 
14 Author:
15 
16 
17 
18 Revision History:
19 
20 
21 
22 --*/
23 
24 #pragma once
25 
26 #define MAKE_MX_FUNC_NAME(x)    x
27 
28 
29 
30 
31 
32 
33 
34 
35 #define REMOVE_LOCK_RELEASE_TIMEOUT_IN_SECONDS 45
36 
37 typedef VOID THREADPOOL_WAIT_CALLBACK (
38     __inout     PTP_CALLBACK_INSTANCE Instance,
39     __inout_opt PVOID                 Context,
40     __inout     PTP_WAIT              Wait,
41     __in        TP_WAIT_RESULT        WaitResult
42     );
43 
44 typedef THREADPOOL_WAIT_CALLBACK MdInterruptServiceRoutineType, *MdInterruptServiceRoutine;
45 
46 typedef
47 BOOLEAN
48 InterruptSynchronizeRoutine (
49     __in PVOID SynchronizeContext
50     );
51 
52 typedef InterruptSynchronizeRoutine MdInterruptSynchronizeRoutineType, *MdInterruptSynchronizeRoutine;
53 
54 typedef struct _CALLBACK_OBJECT *PCALLBACK_OBJECT;
55 
56 typedef
57 VOID
58 CALLBACK_FUNCTION(
59         __in PVOID CallbackContext,
60         __in_opt PVOID Argument1,
61         __in_opt PVOID Argument2
62         );
63 
64 typedef CALLBACK_FUNCTION       MdCallbackFunctionType, *MdCallbackFunction;
65 
66 //
67 // Define PnP notification event categories
68 //
69 
70 typedef enum _IO_NOTIFICATION_EVENT_CATEGORY {
71     EventCategoryReserved,
72     EventCategoryHardwareProfileChange,
73     EventCategoryDeviceInterfaceChange,
74     EventCategoryTargetDeviceChange
75 } IO_NOTIFICATION_EVENT_CATEGORY;
76 
77 #include "MxGeneral.h"
78 
79 __inline
80 BOOLEAN
81 Mx::IsUM(
82     )
83 {
84     return TRUE;
85 }
86 
87 __inline
88 BOOLEAN
89 Mx::IsKM(
90     )
91 {
92     return FALSE;
93 }
94 
95 __inline
96 MxThread
97 Mx::MxGetCurrentThread(
98     )
99 {
100     //
101     // We can't use GetCurrentThread as it returns a pseudo handle
102     // which would have same numeric value for different threads
103     // We could use DuplicateHandle to get real handle but that has the
104     // following problems:
105     //    1) It returns different handle values for the same thread
106     //       if called again without closing handle.
107     //    2) Makes the caller call CloseHandle making it inconvenient to
108     //       call this function just to get an identifier for the thread
109     //    3) More expensive than GetCurrentThreadId
110     //
111     // Since framework uses the thread only for comparison, logging
112     // purposes GetCurrentThreadId works well.
113     // It is cast to PVOID to match the pointer type PKTHREAD otherwise
114     // trace functions complain of data type mismatch
115     //
116 
117     return (PVOID) ::GetCurrentThreadId();
118 }
119 
120 __inline
121 MdEThread
122 Mx::GetCurrentEThread(
123     )
124 {
125     //
126     // See comments in MxGetCurrentThread.
127     //
128     return (PVOID) MxGetCurrentThread();
129 }
130 
131 __inline
132 NTSTATUS
133 Mx::MxTerminateCurrentThread(
134     __in NTSTATUS Status
135     )
136 {
137     #pragma prefast(suppress:__WARNING_USINGTERMINATETHREAD, "TerminateThread is the intent.");
138     if (!TerminateThread(::GetCurrentThread(), HRESULT_FROM_NT(Status))) {
139         DWORD err = GetLastError();
140         return WinErrorToNtStatus(err);
141     }
142     return STATUS_SUCCESS;
143 }
144 
145 __inline
146 KIRQL
147 Mx::MxGetCurrentIrql(
148     )
149 {
150     return PASSIVE_LEVEL;
151 }
152 
153 __inline
154 VOID
155 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
156 Mx::MxRaiseIrql(
157     __in KIRQL  NewIrql,
158     __out PKIRQL  OldIrql
159     )
160 {
161     UNREFERENCED_PARAMETER(NewIrql);
162     UNREFERENCED_PARAMETER(OldIrql);
163 
164     DO_NOTHING();
165 }
166 
167 __inline
168 VOID
169 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
170 Mx::MxLowerIrql(
171     __in KIRQL  NewIrql
172     )
173 {
174     UNREFERENCED_PARAMETER(NewIrql);
175 
176     DO_NOTHING();
177 }
178 
179 __inline
180 VOID
181 Mx::MxQueryTickCount(
182     __out PLARGE_INTEGER  TickCount
183     )
184 {
185     TickCount->QuadPart = GetTickCount();
186 }
187 
188 __inline
189 ULONG
190 Mx::MxQueryTimeIncrement(
191     )
192 {
193     //
194     // The way to get absolute time is TickCount * TimeIncrement.
195     // In UM, TickCount is expressed in miliseconds, so this
196     // conversion ensures that absolute time is expressed
197     // in 100ns units as it is in KM.
198     //
199     return 1000 * 10;
200 }
201 
202 __inline
203 VOID
204 Mx::MxDbgBreakPoint(
205     )
206 {
207     DebugBreak();
208 }
209 
210 __inline
211 VOID
212 Mx::MxAssert(
213     __in BOOLEAN Condition
214     )
215 {
216     if (!Condition)
217     {
218 
219 
220 
221         DebugBreak();
222     }
223 }
224 
225 __inline
226 VOID
227 Mx::MxAssertMsg(
228     __in LPSTR Message,
229     __in BOOLEAN Condition
230     )
231 {
232     UNREFERENCED_PARAMETER(Message);
233 
234     if (!Condition)
235     {
236 
237 
238 
239         DebugBreak();
240     }
241 }
242 
243 __inline
244 VOID
245 #pragma prefast(suppress:__WARNING_UNMATCHED_DEFN, "Can't apply kernel mode annotations.");
246 Mx::MxEnterCriticalRegion(
247     )
248 {
249 
250 
251 
252 
253 
254     // DO_NOTHING();
255 }
256 
257 __inline
258 VOID
259 #pragma prefast(suppress:__WARNING_UNMATCHED_DEFN, "Can't apply kernel mode annotations.");
260 Mx::MxLeaveCriticalRegion(
261     )
262 {
263 
264 
265 
266 
267 
268     // DO_NOTHING();
269 }
270 
271 __inline
272 VOID
273 Mx::MxDelayExecutionThread(
274     __in KPROCESSOR_MODE  WaitMode,
275     __in BOOLEAN  Alertable,
276     __in PLARGE_INTEGER  Interval
277     )
278 {
279     UNREFERENCED_PARAMETER(WaitMode);
280     ASSERTMSG("Interval must be relative\n", Interval->QuadPart <= 0);
281 
282     LARGE_INTEGER intervalMillisecond;
283 
284     //
285     // This function uses KeDelayExecutionThread's contract, where relative
286     // intervals are negative numbers expressed in 100ns units. We must
287     // flip the sign and convert to ms units before calling SleepEx.
288     //
289     intervalMillisecond.QuadPart = -1 * Interval->QuadPart;
290     intervalMillisecond.QuadPart /= 10 * 1000;
291 
292     SleepEx((DWORD)intervalMillisecond.QuadPart, Alertable);
293 }
294 
295 __inline
296 PVOID
297 Mx::MxGetSystemRoutineAddress(
298     __in MxFuncName FuncName
299     )
300 /*++
301 Description:
302 
303     This function is meant to be called only by mode agnostic code
304     System routine is assumed to be in ntdll.dll.
305 
306     This is because system routines (Rtl*) that can be used both
307     in kernel mode as well as user mode reside in ntdll.dll.
308     Kernel32.dll contains the user mode only Win32 API.
309 
310 Arguments:
311 
312     MxFuncName FuncName -
313 
314 Return Value:
315 
316     NTSTATUS Status code.
317 --*/
318 {
319     HMODULE hMod;
320 
321     hMod = GetModuleHandleW(L"ntdll.dll");
322 
323     return GetProcAddress(hMod, FuncName);
324 }
325 
326 __inline
327 VOID
328 Mx::MxReferenceObject(
329     __in PVOID Object
330     )
331 {
332     UNREFERENCED_PARAMETER(Object);
333 
334 
335 
336 
337 
338 
339     // DO_NOTHING();
340 }
341 
342 __inline
343 VOID
344 Mx::MxDereferenceObject(
345     __in PVOID Object
346     )
347 {
348     UNREFERENCED_PARAMETER(Object);
349 
350 
351 
352 
353 
354 
355     // DO_NOTHING();
356 }
357 
358 __inline
359 VOID
360 Mx::MxInitializeRemoveLock(
361     __in MdRemoveLock  Lock,
362     __in ULONG  AllocateTag,
363     __in ULONG  MaxLockedMinutes,
364     __in ULONG  HighWatermark
365     )
366 {
367     UNREFERENCED_PARAMETER(AllocateTag);
368     UNREFERENCED_PARAMETER(MaxLockedMinutes);
369     UNREFERENCED_PARAMETER(HighWatermark);
370 
371     ZeroMemory(Lock, sizeof(*Lock));
372     Lock->IoCount = 1;
373     Lock->Removed = FALSE;
374     Lock->RemoveEvent = NULL;
375     Lock->ReleaseRemLockAndWaitStatus = (DWORD)-1;
376 }
377 
378 __inline
379 NTSTATUS
380 Mx::MxAcquireRemoveLock(
381     __in MdRemoveLock  RemoveLock,
382     __in_opt PVOID  Tag
383     )
384 {
385     UNREFERENCED_PARAMETER(Tag);
386     LONG lockValue;
387     NTSTATUS status;
388 
389     lockValue = InterlockedIncrement(&RemoveLock->IoCount);
390 
391     ASSERT(lockValue > 0);
392 
393     if (! RemoveLock->Removed) {
394         return STATUS_SUCCESS;
395     }
396     else {
397         if (0 == InterlockedDecrement(&RemoveLock->IoCount)) {
398             if (! SetEvent(RemoveLock->RemoveEvent)) {
399                 Mx::MxBugCheckEx(WDF_VIOLATION,
400                                 0, 0, 0, 0);
401             }
402         }
403         status = STATUS_DELETE_PENDING;
404     }
405 
406     return status;
407 }
408 
409 __inline
410 VOID
411 Mx::MxReleaseRemoveLock(
412     __in MdRemoveLock  RemoveLock,
413     __in PVOID  Tag
414     )
415 {
416     UNREFERENCED_PARAMETER(Tag);
417     LONG lockValue;
418 
419     lockValue = InterlockedDecrement(&RemoveLock->IoCount);
420 
421     ASSERT(0 <= lockValue);
422 
423     if (0 == lockValue) {
424         ASSERT (RemoveLock->Removed);
425 
426         //
427         // The device needs to be removed.  Signal the remove event
428         // that it's safe to go ahead.
429         //
430         if (! SetEvent(RemoveLock->RemoveEvent)) {
431             Mx::MxBugCheckEx(WDF_VIOLATION,
432                             0, 0, 0, 0);
433         }
434     }
435 }
436 
437 __inline
438 VOID
439 Mx::MxReleaseRemoveLockAndWait(
440     __in MdRemoveLock  RemoveLock,
441     __in PVOID  Tag
442     )
443 {
444     UNREFERENCED_PARAMETER(Tag);
445     LONG ioCount;
446     DWORD retVal = ERROR_SUCCESS;
447 
448     RemoveLock->Removed = TRUE;
449 
450     ioCount = InterlockedDecrement (&RemoveLock->IoCount);
451     ASSERT(0 < ioCount);
452 
453     if (0 < InterlockedDecrement (&RemoveLock->IoCount)) {
454         retVal = WaitForSingleObject(RemoveLock->RemoveEvent,
455                         REMOVE_LOCK_RELEASE_TIMEOUT_IN_SECONDS*1000);
456         ASSERT(retVal == WAIT_OBJECT_0);
457     }
458 
459     // This only serves as a debugging aid.
460     RemoveLock->ReleaseRemLockAndWaitStatus = retVal;
461 }
462 
463 __inline
464 BOOLEAN
465 Mx::MxHasEnoughRemainingThreadStack(
466     VOID
467     )
468 {
469 
470 
471 
472 
473     //
474     // Thread stack is not so scarce in UM so return TRUE always
475     //
476     return TRUE;
477 }
478 
479 __inline
480 VOID
481 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
482 Mx::ReleaseCancelSpinLock(
483     __in KIRQL  Irql
484     )
485 {
486     UNREFERENCED_PARAMETER(Irql);
487 
488     //
489     // UMDF Host doesn't have cancel spinlock equivalent concept so do nothing.
490     //
491     DO_NOTHING();
492 }
493 
494 __inline
495 NTSTATUS
496 Mx::CreateCallback(
497     __out PCALLBACK_OBJECT  *CallbackObject,
498     __in POBJECT_ATTRIBUTES  ObjectAttributes,
499     __in BOOLEAN  Create,
500     __in BOOLEAN  AllowMultipleCallbacks
501     )
502 {
503     UNREFERENCED_PARAMETER(CallbackObject);
504     UNREFERENCED_PARAMETER(ObjectAttributes);
505     UNREFERENCED_PARAMETER(Create);
506     UNREFERENCED_PARAMETER(AllowMultipleCallbacks);
507 
508     return STATUS_UNSUCCESSFUL;
509 }
510 
511 __inline
512 PVOID
513 Mx::RegisterCallback(
514     __in PCALLBACK_OBJECT  CallbackObject,
515     __in MdCallbackFunction  CallbackFunction,
516     __in PVOID  CallbackContext
517     )
518 {
519     UNREFERENCED_PARAMETER(CallbackObject);
520     UNREFERENCED_PARAMETER(CallbackFunction);
521     UNREFERENCED_PARAMETER(CallbackContext);
522 
523     ASSERTMSG("Not implemented for UMDF\n", FALSE);
524 
525     return NULL;
526 }
527 
528 __inline
529 VOID
530 Mx::UnregisterCallback(
531     __in PVOID  CbRegistration
532     )
533 {
534     UNREFERENCED_PARAMETER(CbRegistration);
535 
536     ASSERTMSG("Not implemented for UMDF\n", FALSE);
537 }
538 
539 __inline
540 VOID
541 Mx::MxUnlockPages(
542     __in PMDL Mdl
543     )
544 {
545     UNREFERENCED_PARAMETER(Mdl);
546 
547     ASSERTMSG("Not implemented for UMDF\n", FALSE);
548 }
549 
550 __inline
551 PVOID
552 Mx::MxGetSystemAddressForMdlSafe(
553     __inout PMDL Mdl,
554     __in    ULONG Priority
555     )
556 {
557     UNREFERENCED_PARAMETER(Mdl);
558     UNREFERENCED_PARAMETER(Priority);
559 
560     ASSERTMSG("Not implemented for UMDF\n", FALSE);
561 
562     return NULL;
563 }
564 
565 __inline
566 VOID
567 Mx::MxBuildMdlForNonPagedPool(
568     __inout PMDL Mdl
569     )
570 {
571     UNREFERENCED_PARAMETER(Mdl);
572 
573     ASSERTMSG("Not implemented for UMDF\n", FALSE);
574 }
575 
576 __inline
577 PVOID
578 Mx::MxGetDriverObjectExtension(
579     __in MdDriverObject DriverObject,
580     __in PVOID ClientIdentificationAddress
581     )
582 {
583     UNREFERENCED_PARAMETER(DriverObject);
584     UNREFERENCED_PARAMETER(ClientIdentificationAddress);
585 
586     ASSERTMSG("Not implemented for UMDF\n", FALSE);
587 
588     return NULL;
589 }
590 
591 __inline
592 NTSTATUS
593 Mx::MxAllocateDriverObjectExtension(
594     _In_  MdDriverObject DriverObject,
595     _In_  PVOID ClientIdentificationAddress,
596     _In_  ULONG DriverObjectExtensionSize,
597     // When successful, this always allocates already-aliased memory.
598     _Post_ _At_(*DriverObjectExtension, _When_(return==0,
599     __drv_aliasesMem __drv_allocatesMem(Mem) _Post_notnull_))
600     _When_(return == 0, _Outptr_result_bytebuffer_(DriverObjectExtensionSize))
601     PVOID *DriverObjectExtension
602     )
603 {
604     UNREFERENCED_PARAMETER(DriverObject);
605     UNREFERENCED_PARAMETER(ClientIdentificationAddress);
606     UNREFERENCED_PARAMETER(DriverObjectExtensionSize);
607     UNREFERENCED_PARAMETER(DriverObjectExtension);
608 
609     ASSERTMSG("Not implemented for UMDF\n", FALSE);
610 
611     return STATUS_UNSUCCESSFUL;
612 }
613 
614 __inline
615 MdDeviceObject
616 Mx::MxGetAttachedDeviceReference(
617     __in MdDeviceObject DriverObject
618     )
619 {
620     UNREFERENCED_PARAMETER(DriverObject);
621 
622     ASSERTMSG("Not implemented for UMDF\n", FALSE);
623 
624     return NULL;
625 }
626 
627 __inline
628 VOID
629 Mx::MxDeleteSymbolicLink(
630     __in PUNICODE_STRING Value
631     )
632 {
633     UNREFERENCED_PARAMETER(Value);
634 
635     ASSERTMSG("Not implemented for UMDF\n", FALSE);
636 }
637 
638 __inline
639 VOID
640 Mx::MxDeleteNPagedLookasideList(
641     _In_ PNPAGED_LOOKASIDE_LIST LookasideList
642     )
643 {
644     UNREFERENCED_PARAMETER(LookasideList);
645 }
646 
647 __inline
648 VOID
649 Mx::MxDeletePagedLookasideList(
650     _In_ PPAGED_LOOKASIDE_LIST LookasideList
651     )
652 {
653     UNREFERENCED_PARAMETER(LookasideList);
654 
655     ASSERTMSG("Not implemented for UMDF\n", FALSE);
656 }
657 
658 __inline
659 VOID
660 Mx::MxInitializeNPagedLookasideList(
661     _Out_     PNPAGED_LOOKASIDE_LIST Lookaside,
662     _In_opt_  PALLOCATE_FUNCTION Allocate,
663     _In_opt_  PFREE_FUNCTION Free,
664     _In_      ULONG Flags,
665     _In_      SIZE_T Size,
666     _In_      ULONG Tag,
667     _In_      USHORT Depth
668     )
669 {
670 
671     UNREFERENCED_PARAMETER(Lookaside);
672     UNREFERENCED_PARAMETER(Allocate);
673     UNREFERENCED_PARAMETER(Free);
674     UNREFERENCED_PARAMETER(Flags);
675     UNREFERENCED_PARAMETER(Size);
676     UNREFERENCED_PARAMETER(Tag);
677     UNREFERENCED_PARAMETER(Depth);
678 
679     //ASSERTMSG("Not implemented for UMDF\n", FALSE);
680 
681 }
682 
683 __inline
684 VOID
685 Mx::MxInitializePagedLookasideList(
686     _Out_     PPAGED_LOOKASIDE_LIST Lookaside,
687     _In_opt_  PALLOCATE_FUNCTION Allocate,
688     _In_opt_  PFREE_FUNCTION Free,
689     _In_      ULONG Flags,
690     _In_      SIZE_T Size,
691     _In_      ULONG Tag,
692     _In_      USHORT Depth
693     )
694 {
695 
696     UNREFERENCED_PARAMETER(Lookaside);
697     UNREFERENCED_PARAMETER(Allocate);
698     UNREFERENCED_PARAMETER(Free);
699     UNREFERENCED_PARAMETER(Flags);
700     UNREFERENCED_PARAMETER(Size);
701     UNREFERENCED_PARAMETER(Tag);
702     UNREFERENCED_PARAMETER(Depth);
703 
704     //ASSERTMSG("Not implemented for UMDF\n", FALSE);
705 
706 }
707 
708 __inline
709 VOID
710 Mx::MxDeleteDevice(
711     _In_ MdDeviceObject Device
712     )
713 {
714     UNREFERENCED_PARAMETER(Device);
715 
716 
717 
718 
719     //
720     // Host's device stack object holds the only reference to the host devices.
721     // The infrastructure controls the device object's lifetime.
722     //
723     DO_NOTHING();
724 }
725 
726 __inline
727 NTSTATUS
728 Mx::MxCreateDeviceSecure(
729       _In_      MdDriverObject DriverObject,
730       _In_      ULONG DeviceExtensionSize,
731       _In_opt_  PUNICODE_STRING DeviceName,
732       _In_      DEVICE_TYPE DeviceType,
733       _In_      ULONG DeviceCharacteristics,
734       _In_      BOOLEAN Exclusive,
735       _In_      PCUNICODE_STRING DefaultSDDLString,
736       _In_opt_  LPCGUID DeviceClassGuid,
737       _Out_opt_     MdDeviceObject *DeviceObject
738     )
739 {
740     UNREFERENCED_PARAMETER(DriverObject);
741     UNREFERENCED_PARAMETER(DeviceExtensionSize);
742     UNREFERENCED_PARAMETER(DeviceName);
743     UNREFERENCED_PARAMETER(DeviceType);
744     UNREFERENCED_PARAMETER(Exclusive);
745     UNREFERENCED_PARAMETER(DeviceCharacteristics);
746     UNREFERENCED_PARAMETER(DefaultSDDLString);
747     UNREFERENCED_PARAMETER(DeviceClassGuid);
748     UNREFERENCED_PARAMETER(DeviceObject);
749 
750     ASSERTMSG("Not implemented for UMDF\n", FALSE);
751 
752     return STATUS_SUCCESS;
753 }
754 
755 __inline
756 MdDeviceObject
757 Mx::MxAttachDeviceToDeviceStack(
758     _In_ MdDeviceObject SourceDevice,
759     _In_ MdDeviceObject TargetDevice
760     )
761 {
762 
763     UNREFERENCED_PARAMETER(SourceDevice);
764     UNREFERENCED_PARAMETER(TargetDevice);
765 
766     ASSERTMSG("Not implemented for UMDF\n", FALSE);
767 
768     return NULL;
769 }
770 
771 __inline
772 NTSTATUS
773 Mx::MxCreateDevice(
774     _In_      MdDriverObject DriverObject,
775     _In_      ULONG DeviceExtensionSize,
776     _In_opt_  PUNICODE_STRING DeviceName,
777     _In_      DEVICE_TYPE DeviceType,
778     _In_      ULONG DeviceCharacteristics,
779     _In_      BOOLEAN Exclusive,
780     _Out_opt_     MdDeviceObject *DeviceObject
781     )
782 {
783     UNREFERENCED_PARAMETER(DriverObject);
784     UNREFERENCED_PARAMETER(DeviceExtensionSize);
785     UNREFERENCED_PARAMETER(DeviceName);
786     UNREFERENCED_PARAMETER(DeviceType);
787     UNREFERENCED_PARAMETER(DeviceCharacteristics);
788     UNREFERENCED_PARAMETER(Exclusive);
789     UNREFERENCED_PARAMETER(DeviceObject);
790 
791     ASSERTMSG("Not implemented for UMDF\n", FALSE);
792 
793     return STATUS_SUCCESS;
794 
795 }
796 
797 __inline
798 NTSTATUS
799 Mx::MxCreateSymbolicLink(
800     _In_ PUNICODE_STRING SymbolicLinkName,
801     _In_ PUNICODE_STRING DeviceName
802     )
803 {
804     UNREFERENCED_PARAMETER(SymbolicLinkName);
805     UNREFERENCED_PARAMETER(DeviceName);
806 
807     ASSERTMSG("Not implemented for UMDF\n", FALSE);
808 
809     return STATUS_NOT_IMPLEMENTED;
810 }
811 
812 __inline
813 VOID
814 Mx::MxFlushQueuedDpcs(
815     )
816 {
817     //
818     // Not supported for UMDF
819     //
820 }
821 
822 __inline
823 NTSTATUS
824 Mx::MxOpenKey(
825     _In_ PHANDLE KeyHandle,
826     _In_ ACCESS_MASK DesiredAccess,
827     _In_ POBJECT_ATTRIBUTES ObjectAttributes
828     )
829 {
830     UNREFERENCED_PARAMETER(KeyHandle);
831     UNREFERENCED_PARAMETER(DesiredAccess);
832     UNREFERENCED_PARAMETER(ObjectAttributes);
833 
834     ASSERTMSG("Not implemented for UMDF\n", FALSE);
835 
836     return STATUS_NOT_IMPLEMENTED;
837 }
838 
839 __inline
840 NTSTATUS
841 Mx::MxSetDeviceInterfaceState(
842     _In_ PUNICODE_STRING SymbolicLinkName,
843     _In_ BOOLEAN Enable
844     )
845 {
846     UNREFERENCED_PARAMETER(SymbolicLinkName);
847     UNREFERENCED_PARAMETER(Enable);
848 
849     ASSERTMSG("Not implemented for UMDF\n", FALSE);
850 
851     return STATUS_NOT_IMPLEMENTED;
852 }
853 
854 
855 __inline
856 NTSTATUS
857 Mx::MxRegisterDeviceInterface(
858     _In_      PDEVICE_OBJECT PhysicalDeviceObject,
859     _In_      const GUID *InterfaceClassGuid,
860     _In_opt_  PUNICODE_STRING ReferenceString,
861     _Out_     PUNICODE_STRING SymbolicLinkName
862     )
863 {
864     UNREFERENCED_PARAMETER(PhysicalDeviceObject);
865     UNREFERENCED_PARAMETER(InterfaceClassGuid);
866     UNREFERENCED_PARAMETER(ReferenceString);
867     UNREFERENCED_PARAMETER(SymbolicLinkName);
868 
869     ASSERTMSG("Not implemented for UMDF\n", FALSE);
870 
871     return STATUS_NOT_IMPLEMENTED;
872 }
873 
874 __inline
875 NTSTATUS
876 Mx::MxDeleteKey(
877     _In_ HANDLE KeyHandle
878     )
879 
880 {
881     UNREFERENCED_PARAMETER(KeyHandle);
882 
883     ASSERTMSG("Not implemented for UMDF\n", FALSE);
884 
885     return STATUS_NOT_IMPLEMENTED;
886 }
887 
888 __inline
889 VOID
890 Mx::MxInitializeMdl(
891     _In_  PMDL MemoryDescriptorList,
892     _In_  PVOID BaseVa,
893     _In_  SIZE_T Length
894     )
895 {
896     UNREFERENCED_PARAMETER(MemoryDescriptorList);
897     UNREFERENCED_PARAMETER(BaseVa);
898     UNREFERENCED_PARAMETER(Length);
899 
900     ASSERTMSG("Not implemented for UMDF\n", FALSE);
901 
902 }
903 
904 __inline
905 PVOID
906 Mx::MxGetMdlVirtualAddress(
907     _In_ PMDL Mdl
908     )
909 {
910     UNREFERENCED_PARAMETER(Mdl);
911 
912     ASSERTMSG("Not implemented for UMDF\n", FALSE);
913 
914     return NULL;
915 }
916 
917 __inline
918 VOID
919 Mx::MxBuildPartialMdl(
920     _In_     PMDL SourceMdl,
921     _Inout_  PMDL TargetMdl,
922     _In_     PVOID VirtualAddress,
923     _In_     ULONG Length
924     )
925 {
926     UNREFERENCED_PARAMETER(SourceMdl);
927     UNREFERENCED_PARAMETER(TargetMdl);
928     UNREFERENCED_PARAMETER(VirtualAddress);
929     UNREFERENCED_PARAMETER(Length);
930 
931     ASSERTMSG("Not implemented for UMDF\n", FALSE);
932 }
933 
934 __inline
935 VOID
936 Mx::MxQuerySystemTime(
937     _Out_ PLARGE_INTEGER CurrentTime
938     )
939 {
940     UNREFERENCED_PARAMETER(CurrentTime);
941 
942     ASSERTMSG("Not implemented for UMDF\n", FALSE);
943 }
944 
945 __inline
946 NTSTATUS
947 Mx::MxSetValueKey(
948     _In_      HANDLE KeyHandle,
949     _In_      PUNICODE_STRING ValueName,
950     _In_opt_  ULONG TitleIndex,
951     _In_      ULONG Type,
952     _In_opt_  PVOID Data,
953     _In_      ULONG DataSize
954     )
955 {
956     UNREFERENCED_PARAMETER(KeyHandle);
957     UNREFERENCED_PARAMETER(ValueName);
958     UNREFERENCED_PARAMETER(TitleIndex);
959     UNREFERENCED_PARAMETER(Type);
960     UNREFERENCED_PARAMETER(Data);
961     UNREFERENCED_PARAMETER(DataSize);
962 
963     ASSERTMSG("Not implemented for UMDF\n", FALSE);
964 
965     return STATUS_NOT_IMPLEMENTED;
966 }
967 
968 __inline
969 NTSTATUS
970 Mx::MxQueryValueKey(
971     _In_       HANDLE KeyHandle,
972     _In_       PUNICODE_STRING ValueName,
973     _In_       KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
974     _Out_opt_  PVOID KeyValueInformation,
975     _In_       ULONG Length,
976     _Out_      PULONG ResultLength
977 )
978 {
979     UNREFERENCED_PARAMETER(KeyHandle);
980     UNREFERENCED_PARAMETER(ValueName);
981     UNREFERENCED_PARAMETER(KeyValueInformationClass);
982     UNREFERENCED_PARAMETER(KeyValueInformation);
983     UNREFERENCED_PARAMETER(Length);
984     UNREFERENCED_PARAMETER(ResultLength);
985 
986     ASSERTMSG("Not implemented for UMDF\n", FALSE);
987 
988     return STATUS_NOT_IMPLEMENTED;
989 }
990 
991 __inline
992 NTSTATUS
993 Mx::MxUnRegisterPlugPlayNotification(
994     __in __drv_freesMem(Pool) PVOID NotificationEntry
995     )
996 {
997     UNREFERENCED_PARAMETER(NotificationEntry);
998 
999     ASSERTMSG("Not implemented for UMDF\n", FALSE);
1000 
1001     return STATUS_NOT_IMPLEMENTED;
1002 }
1003 
1004 __inline
1005 NTSTATUS
1006 Mx::MxReferenceObjectByHandle(
1007     __in HANDLE Handle,
1008     __in ACCESS_MASK DesiredAccess,
1009     __in_opt POBJECT_TYPE ObjectType,
1010     __in KPROCESSOR_MODE AccessMode,
1011     __out  PVOID *Object,
1012     __out_opt POBJECT_HANDLE_INFORMATION HandleInformation
1013     )
1014 {
1015     UNREFERENCED_PARAMETER(Handle);
1016     UNREFERENCED_PARAMETER(DesiredAccess);
1017     UNREFERENCED_PARAMETER(ObjectType);
1018     UNREFERENCED_PARAMETER(AccessMode);
1019     UNREFERENCED_PARAMETER(Object);
1020     UNREFERENCED_PARAMETER(HandleInformation);
1021 
1022     ASSERTMSG("Not implemented for UMDF\n", FALSE);
1023 
1024     return STATUS_NOT_IMPLEMENTED;
1025 }
1026 
1027 __inline
1028 NTSTATUS
1029 Mx::MxClose(
1030     __in HANDLE Handle
1031     )
1032 {
1033     CloseHandle(Handle);
1034 
1035     return STATUS_SUCCESS;
1036 }
1037 
1038 __inline
1039 KIRQL
1040 Mx::MxAcquireInterruptSpinLock(
1041     _Inout_ PKINTERRUPT Interrupt
1042     )
1043 {
1044     UNREFERENCED_PARAMETER(Interrupt);
1045 
1046     ASSERTMSG("Not implemented for UMDF\n", FALSE);
1047     return PASSIVE_LEVEL;
1048 }
1049 
1050 __inline
1051 VOID
1052 Mx::MxReleaseInterruptSpinLock(
1053     _Inout_ PKINTERRUPT Interrupt,
1054     _In_ KIRQL OldIrql
1055     )
1056 {
1057     UNREFERENCED_PARAMETER(Interrupt);
1058     UNREFERENCED_PARAMETER(OldIrql);
1059 
1060     ASSERTMSG("Not implemented for UMDF\n", FALSE);
1061 }
1062 
1063 __inline
1064 BOOLEAN
1065 Mx::MxInsertQueueDpc(
1066   __inout   PRKDPC Dpc,
1067   __in_opt  PVOID SystemArgument1,
1068   __in_opt  PVOID SystemArgument2
1069 )
1070 {
1071     UNREFERENCED_PARAMETER(Dpc);
1072     UNREFERENCED_PARAMETER(SystemArgument1);
1073     UNREFERENCED_PARAMETER(SystemArgument2);
1074 
1075     ASSERTMSG("Not implemented for UMDF\n", FALSE);
1076     return FALSE;
1077 }
1078 
1079