Synchronize up to trunk's revision r57756.
[reactos.git] / ntoskrnl / fsrtl / pnp.c
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 }