xref: /reactos/ntoskrnl/fsrtl/pnp.c (revision 845faec4)
1 /*
2  * PROJECT:         ReactOS Kernel
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            ntoskrnl/fsrtl/pnp.c
5  * PURPOSE:         Manages PnP support routines for file system drivers.
6  * PROGRAMMERS:     Pierre Schweitzer
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #include <ioevent.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* PUBLIC FUNCTIONS **********************************************************/
17 
18 /*++
19  * @name FsRtlNotifyVolumeEvent
20  * @implemented
21  *
22  * Notifies system (and applications) that something changed on volume.
23  * FSD should call it each time volume status changes.
24  *
25  * @param FileObject
26  *        FileObject for the volume
27  *
28  * @param EventCode
29  *        Event that occurs one the volume
30  *
31  * @return STATUS_SUCCESS if notification went well
32  *
33  * @remarks Only present in NT 5+.
34  *
35  *--*/
36 NTSTATUS
37 NTAPI
38 FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject,
39                        IN ULONG EventCode)
40 {
41     NTSTATUS Status;
42     LPGUID Guid = NULL;
43     PDEVICE_OBJECT DeviceObject = NULL;
44     TARGET_DEVICE_CUSTOM_NOTIFICATION Notification;
45 
46     Status = IoGetRelatedTargetDevice(FileObject, &DeviceObject);
47     if (!NT_SUCCESS(Status))
48     {
49         return Status;
50     }
51 
52     Status = STATUS_INVALID_PARAMETER;
53 
54     Notification.Version = 1;
55     Notification.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION);
56     /* MSDN says that FileObject must be null
57        when calling IoReportTargetDeviceChangeAsynchronous */
58     Notification.FileObject = NULL;
59     Notification.NameBufferOffset = -1;
60     /* Find the good GUID associated with the event */
61     switch (EventCode)
62     {
63         case FSRTL_VOLUME_DISMOUNT:
64         {
65             Guid = (LPGUID)&GUID_IO_VOLUME_DISMOUNT;
66             break;
67         }
68         case FSRTL_VOLUME_DISMOUNT_FAILED:
69         {
70             Guid = (LPGUID)&GUID_IO_VOLUME_DISMOUNT_FAILED;
71             break;
72         }
73         case FSRTL_VOLUME_LOCK:
74         {
75             Guid = (LPGUID)&GUID_IO_VOLUME_LOCK;
76             break;
77         }
78         case FSRTL_VOLUME_LOCK_FAILED:
79         {
80             Guid = (LPGUID)&GUID_IO_VOLUME_LOCK_FAILED;
81             break;
82         }
83         case FSRTL_VOLUME_MOUNT:
84         {
85             Guid = (LPGUID)&GUID_IO_VOLUME_MOUNT;
86             break;
87         }
88         case FSRTL_VOLUME_UNLOCK:
89         {
90             Guid = (LPGUID)&GUID_IO_VOLUME_UNLOCK;
91             break;
92         }
93     }
94     if (Guid)
95     {
96         /* Copy GUID to notification structure and then report the change */
97         RtlCopyMemory(&(Notification.Event), Guid, sizeof(GUID));
98 
99         if (EventCode == FSRTL_VOLUME_MOUNT)
100         {
101             IoReportTargetDeviceChangeAsynchronous(DeviceObject,
102                                                    &Notification,
103                                                    NULL,
104                                                    NULL);
105         }
106         else
107         {
108             IoReportTargetDeviceChange(DeviceObject,
109                                        &Notification);
110         }
111 
112         Status = STATUS_SUCCESS;
113     }
114     ObDereferenceObject(DeviceObject);
115 
116     return Status;
117 }
118