mirror of
https://github.com/reactos/reactos.git
synced 2025-07-01 19:11:21 +00:00
[IOEVENT]
Added a library containing GUIDs for PnP notifications [BUGCODES] Added missing bugcheck code for PnP manager [NTOSKRNL] - Implemented FsRtlNotifyVolumeEvent() - Implemented IoReportTargetDeviceChange(), IoReportTargetDeviceChangeAsynchronous() - Craplemented PpSetCustomTargetEvent() to match our actual PnP manager notifications system. This is to be rewritten - Added support for custom notifications in IopNotifyPlugPlayNotification() - Added use of FsRtlNotifyVolumeEvent() in RawUserFsCtrl() to notify volume state changes - Added use of IoEvent library to ntoskrnl [FASTFAT] - Added use of FsRtlNotifyVolumeEvent() when successfully mounting a volume Finally, purpose of that patch is to implement volumes events notifications. Behaviour and implementation is correct till PpSetCustomTargetEvent(). The PnP notifications manager should be rewritten to match Microsoft's one. Furthermore, it appears that in Windows, those notifications are asynchronous. svn path=/trunk/; revision=47837
This commit is contained in:
parent
bbbbb74fd5
commit
22576dee05
11 changed files with 393 additions and 32 deletions
|
@ -585,6 +585,8 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
}
|
}
|
||||||
VolumeFcb->Flags |= VCB_IS_DIRTY;
|
VolumeFcb->Flags |= VCB_IS_DIRTY;
|
||||||
|
|
||||||
|
FsRtlNotifyVolumeEvent(DeviceExt->FATFileObject, FSRTL_VOLUME_MOUNT);
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
ByeBye:
|
ByeBye:
|
||||||
|
|
||||||
|
|
78
reactos/include/psdk/ioevent.h
Normal file
78
reactos/include/psdk/ioevent.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* ioevent.h
|
||||||
|
*
|
||||||
|
* PnP Event Notification GUIDs
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||||
|
*
|
||||||
|
* This source code is offered for use in the public domain. You may
|
||||||
|
* use, modify or distribute it freely.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful but
|
||||||
|
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||||
|
* DISCLAIMED. This includes but is not limited to warranties of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IOEVENT_H
|
||||||
|
#define _IOEVENT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_CHANGE,
|
||||||
|
0x7373654AL, 0x812A, 0x11D0, 0xBE, 0xC7, 0x08, 0x00, 0x2B, 0xE2, 0x09, 0x2F);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_DISMOUNT,
|
||||||
|
0xD16A55E8L, 0x1059, 0x11D2, 0x8F, 0xFD, 0x00, 0xA0, 0xC9, 0xA0, 0x6D, 0x32);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_DISMOUNT_FAILED,
|
||||||
|
0xE3C5B178L, 0x105D, 0x11D2, 0x8F, 0xFD, 0x00, 0xA0, 0xC9, 0xA0, 0x6D, 0x32);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_MOUNT,
|
||||||
|
0xB5804878L, 0x1A96, 0x11D2, 0x8F, 0xFD, 0x00, 0xA0, 0xC9, 0xA0, 0x6D, 0x32);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_LOCK,
|
||||||
|
0x50708874L, 0xC9AF, 0x11D1, 0x8F, 0xEF, 0x00, 0xA0, 0xC9, 0xA0, 0x6D, 0x32);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_LOCK_FAILED,
|
||||||
|
0xAE2EED10L, 0x0BA8, 0x11D2, 0x8F, 0xFB, 0x00, 0xA0, 0xC9, 0xA0, 0x6D, 0x32);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_UNLOCK,
|
||||||
|
0x9A8C3D68L, 0xD0CB, 0x11D1, 0x8F, 0xEF, 0x00, 0xA0, 0xC9, 0xA0, 0x6D, 0x32);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_NAME_CHANGE,
|
||||||
|
0x2DE97F83, 0x4C06, 0x11D2, 0xA5, 0x32, 0x00, 0x60, 0x97, 0x13, 0x05, 0x5A);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_PREPARING_EJECT,
|
||||||
|
0xC79EB16E, 0x0DAC, 0x4E7A, 0xA8, 0x6C, 0xB2, 0x5C, 0xEE, 0xAA, 0x88, 0xF6);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_PHYSICAL_CONFIGURATION_CHANGE,
|
||||||
|
0x2DE97F84, 0x4C06, 0x11D2, 0xA5, 0x32, 0x00, 0x60, 0x97, 0x13, 0x05, 0x5A);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_FVE_STATUS_CHANGE,
|
||||||
|
0x062998B2, 0xEE1F, 0x4B6A, 0xB8, 0x57, 0xE7, 0x6C, 0xBB, 0xE9, 0xA6, 0xDA);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_DEVICE_INTERFACE,
|
||||||
|
0x53F5630D, 0xB6BF, 0x11D0, 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B);
|
||||||
|
DEFINE_GUID(GUID_IO_VOLUME_CHANGE_SIZE,
|
||||||
|
0x3A1625BE, 0xAD03, 0x49F1, 0x8E, 0xF8, 0x6B, 0xBA, 0xC1, 0x82, 0xD1, 0xFD);
|
||||||
|
DEFINE_GUID(GUID_IO_MEDIA_ARRIVAL,
|
||||||
|
0xD07433C0, 0xA98E, 0x11D2, 0x91, 0x7A, 0x00, 0xA0, 0xC9, 0x06, 0x8F, 0xF3);
|
||||||
|
DEFINE_GUID(GUID_IO_MEDIA_REMOVAL,
|
||||||
|
0xD07433C1, 0xA98E, 0x11D2, 0x91, 0x7A, 0x00, 0xA0, 0xC9, 0x06, 0x8F, 0xF3);
|
||||||
|
DEFINE_GUID(GUID_IO_CDROM_EXCLUSIVE_LOCK,
|
||||||
|
0xBC56C139, 0x7A10, 0x47EE, 0xA2, 0x94, 0x4C, 0x6A, 0x38, 0xF0, 0x14, 0x9A);
|
||||||
|
DEFINE_GUID(GUID_IO_CDROM_EXCLUSIVE_UNLOCK,
|
||||||
|
0xA3B6D27D, 0x5E35, 0x4885, 0x81, 0xE5, 0xEE, 0x18, 0xC0, 0x0E, 0xD7, 0x79);
|
||||||
|
DEFINE_GUID(GUID_IO_DEVICE_BECOMING_READY,
|
||||||
|
0xD07433F0, 0xA98E, 0x11D2, 0x91, 0x7A, 0x00, 0xA0, 0xC9, 0x06, 0x8F, 0xF3);
|
||||||
|
DEFINE_GUID(GUID_IO_DEVICE_EXTERNAL_REQUEST,
|
||||||
|
0xD07433D0, 0xA98E, 0x11D2, 0x91, 0x7A, 0x00, 0xA0, 0xC9, 0x06, 0x8F, 0xF3);
|
||||||
|
DEFINE_GUID(GUID_IO_MEDIA_EJECT_REQUEST,
|
||||||
|
0xD07433D1, 0xA98E, 0x11D2, 0x91, 0x7A, 0x00, 0xA0, 0xC9, 0x06, 0x8F, 0xF3);
|
||||||
|
DEFINE_GUID(GUID_IO_DRIVE_REQUIRES_CLEANING,
|
||||||
|
0x7207877C, 0x90ED, 0x44E5, 0xA0, 0x00, 0x81, 0x42, 0x8D, 0x4C, 0x79, 0xBB);
|
||||||
|
DEFINE_GUID(GUID_IO_TAPE_ERASE,
|
||||||
|
0x852D11EB, 0x4BB8, 0x4507, 0x9D, 0x9B, 0x41, 0x7C, 0xC2, 0xB1, 0xB4, 0x38);
|
||||||
|
DEFINE_GUID(GUID_IO_DISK_CLONE_ARRIVAL,
|
||||||
|
0x6A61885B, 0x7C39, 0x43DD, 0x9B, 0x56, 0xB8, 0xAC, 0x22, 0xA5, 0x49, 0xAA);
|
||||||
|
DEFINE_GUID(GUID_IO_DISK_LAYOUT_CHANGE,
|
||||||
|
0x11DFF54C, 0x8469, 0x41F9, 0xB3, 0xDE, 0xEF, 0x83, 0x64, 0x87, 0xC5, 0x4A);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _IOEVENT_H */
|
|
@ -1265,6 +1265,14 @@ driver changing IRQL and not restoring it to its previous value when
|
||||||
it has finished its task.
|
it has finished its task.
|
||||||
.
|
.
|
||||||
|
|
||||||
|
MessageId=0xCA
|
||||||
|
Severity=Success
|
||||||
|
Facility=System
|
||||||
|
SymbolicName=PNP_DETECTED_FATAL_ERROR
|
||||||
|
Language=English
|
||||||
|
PNP_DETECTED_FATAL_ERROR
|
||||||
|
.
|
||||||
|
|
||||||
MessageId=0xCB
|
MessageId=0xCB
|
||||||
Severity=Success
|
Severity=Success
|
||||||
Facility=System
|
Facility=System
|
||||||
|
|
8
reactos/lib/sdk/ioevent/ioevent.c
Normal file
8
reactos/lib/sdk/ioevent/ioevent.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define COM_NO_WINDOWS_H
|
||||||
|
#include "initguid.h"
|
||||||
|
|
||||||
|
#include <ioevent.h>
|
||||||
|
|
||||||
|
/* EOF */
|
5
reactos/lib/sdk/ioevent/ioevent.rbuild
Normal file
5
reactos/lib/sdk/ioevent/ioevent.rbuild
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
|
||||||
|
<module name="ioevent" type="staticlibrary">
|
||||||
|
<file>ioevent.c</file>
|
||||||
|
</module>
|
|
@ -11,6 +11,9 @@
|
||||||
<directory name="dxguid">
|
<directory name="dxguid">
|
||||||
<xi:include href="dxguid/dxguid.rbuild" />
|
<xi:include href="dxguid/dxguid.rbuild" />
|
||||||
</directory>
|
</directory>
|
||||||
|
<directory name="ioevent">
|
||||||
|
<xi:include href="ioevent/ioevent.rbuild" />
|
||||||
|
</directory>
|
||||||
<directory name="nt">
|
<directory name="nt">
|
||||||
<xi:include href="nt/nt.rbuild" />
|
<xi:include href="nt/nt.rbuild" />
|
||||||
</directory>
|
</directory>
|
||||||
|
|
|
@ -3,12 +3,13 @@
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: ntoskrnl/fsrtl/pnp.c
|
* FILE: ntoskrnl/fsrtl/pnp.c
|
||||||
* PURPOSE: Manages PnP support routines for file system drivers.
|
* PURPOSE: Manages PnP support routines for file system drivers.
|
||||||
* PROGRAMMERS: None.
|
* PROGRAMMERS: Pierre Schweitzer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
|
#include <ioevent.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
@ -16,17 +17,18 @@
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
* @name FsRtlNotifyVolumeEvent
|
* @name FsRtlNotifyVolumeEvent
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*
|
*
|
||||||
* FILLME
|
* Notifies system (and applications) that something changed on volume.
|
||||||
|
* FSD should call it each time volume status changes.
|
||||||
*
|
*
|
||||||
* @param FileObject
|
* @param FileObject
|
||||||
* FILLME
|
* FileObject for the volume
|
||||||
*
|
*
|
||||||
* @param EventCode
|
* @param EventCode
|
||||||
* FILLME
|
* Event that occurs one the volume
|
||||||
*
|
*
|
||||||
* @return None
|
* @return STATUS_SUCCESS if notification went well
|
||||||
*
|
*
|
||||||
* @remarks Only present in NT 5+.
|
* @remarks Only present in NT 5+.
|
||||||
*
|
*
|
||||||
|
@ -36,7 +38,80 @@ NTAPI
|
||||||
FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject,
|
FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject,
|
||||||
IN ULONG EventCode)
|
IN ULONG EventCode)
|
||||||
{
|
{
|
||||||
/* Unimplemented */
|
NTSTATUS Status;
|
||||||
KeBugCheck(FILE_SYSTEM);
|
LPGUID Guid = NULL;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PDEVICE_OBJECT DeviceObject = NULL;
|
||||||
|
TARGET_DEVICE_CUSTOM_NOTIFICATION Notification;
|
||||||
|
|
||||||
|
Status = IoGetRelatedTargetDevice(FileObject, &DeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
Notification.Version = 1;
|
||||||
|
Notification.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION);
|
||||||
|
/* MSDN says that FileObject must be null
|
||||||
|
when calling IoReportTargetDeviceChangeAsynchronous */
|
||||||
|
Notification.FileObject = NULL;
|
||||||
|
Notification.NameBufferOffset = -1;
|
||||||
|
/* Find the good GUID associated with the event */
|
||||||
|
switch (EventCode)
|
||||||
|
{
|
||||||
|
case FSRTL_VOLUME_DISMOUNT:
|
||||||
|
{
|
||||||
|
Guid = (LPGUID)&GUID_IO_VOLUME_DISMOUNT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSRTL_VOLUME_DISMOUNT_FAILED:
|
||||||
|
{
|
||||||
|
Guid = (LPGUID)&GUID_IO_VOLUME_DISMOUNT_FAILED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSRTL_VOLUME_LOCK:
|
||||||
|
{
|
||||||
|
Guid = (LPGUID)&GUID_IO_VOLUME_LOCK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSRTL_VOLUME_LOCK_FAILED:
|
||||||
|
{
|
||||||
|
Guid = (LPGUID)&GUID_IO_VOLUME_LOCK_FAILED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSRTL_VOLUME_MOUNT:
|
||||||
|
{
|
||||||
|
Guid = (LPGUID)&GUID_IO_VOLUME_MOUNT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSRTL_VOLUME_UNLOCK:
|
||||||
|
{
|
||||||
|
Guid = (LPGUID)&GUID_IO_VOLUME_UNLOCK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Guid)
|
||||||
|
{
|
||||||
|
/* Copy GUID to notification structure and then report the change */
|
||||||
|
RtlCopyMemory(&(Notification.Event), Guid, sizeof(GUID));
|
||||||
|
|
||||||
|
if (EventCode == FSRTL_VOLUME_MOUNT)
|
||||||
|
{
|
||||||
|
IoReportTargetDeviceChangeAsynchronous(DeviceObject,
|
||||||
|
&Notification,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IoReportTargetDeviceChange(DeviceObject,
|
||||||
|
&Notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
ObfDereferenceObject(DeviceObject);
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -439,8 +439,26 @@ RawUserFsCtrl(IN PIO_STACK_LOCATION IoStackLocation,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock device and return */
|
/* Unlock device */
|
||||||
KeReleaseMutex(&Vcb->Mutex, FALSE);
|
KeReleaseMutex(&Vcb->Mutex, FALSE);
|
||||||
|
|
||||||
|
/* In case of status change, notify */
|
||||||
|
switch (IoStackLocation->Parameters.FileSystemControl.FsControlCode)
|
||||||
|
{
|
||||||
|
case FSCTL_LOCK_VOLUME:
|
||||||
|
FsRtlNotifyVolumeEvent(IoStackLocation->FileObject, (NT_SUCCESS(Status) ? FSRTL_VOLUME_LOCK : FSRTL_VOLUME_LOCK_FAILED));
|
||||||
|
break;
|
||||||
|
case FSCTL_UNLOCK_VOLUME:
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
FsRtlNotifyVolumeEvent(IoStackLocation->FileObject, FSRTL_VOLUME_UNLOCK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FSCTL_DISMOUNT_VOLUME:
|
||||||
|
FsRtlNotifyVolumeEvent(IoStackLocation->FileObject, (NT_SUCCESS(Status) ? FSRTL_VOLUME_DISMOUNT : FSRTL_VOLUME_DISMOUNT_FAILED));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* PURPOSE: Plug & Play notification functions
|
* PURPOSE: Plug & Play notification functions
|
||||||
* PROGRAMMERS: Filip Navara (xnavara@volny.cz)
|
* PROGRAMMERS: Filip Navara (xnavara@volny.cz)
|
||||||
* Hervé Poussineau (hpoussin@reactos.org)
|
* Hervé Poussineau (hpoussin@reactos.org)
|
||||||
|
* Pierre Schweitzer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -44,6 +45,7 @@ IopNotifyPlugPlayNotification(
|
||||||
BOOLEAN CallCurrentEntry;
|
BOOLEAN CallCurrentEntry;
|
||||||
UNICODE_STRING GuidString;
|
UNICODE_STRING GuidString;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PDEVICE_OBJECT EntryDeviceObject = NULL;
|
||||||
|
|
||||||
ASSERT(DeviceObject);
|
ASSERT(DeviceObject);
|
||||||
|
|
||||||
|
@ -100,6 +102,8 @@ IopNotifyPlugPlayNotification(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EventCategoryTargetDeviceChange:
|
case EventCategoryTargetDeviceChange:
|
||||||
|
{
|
||||||
|
if (Event != &GUID_PNP_CUSTOM_NOTIFICATION)
|
||||||
{
|
{
|
||||||
PTARGET_DEVICE_REMOVAL_NOTIFICATION NotificationInfos;
|
PTARGET_DEVICE_REMOVAL_NOTIFICATION NotificationInfos;
|
||||||
NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
|
NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
|
||||||
|
@ -115,6 +119,21 @@ IopNotifyPlugPlayNotification(
|
||||||
NotificationInfos->Size = sizeof(TARGET_DEVICE_REMOVAL_NOTIFICATION);
|
NotificationInfos->Size = sizeof(TARGET_DEVICE_REMOVAL_NOTIFICATION);
|
||||||
RtlCopyMemory(&NotificationInfos->Event, Event, sizeof(GUID));
|
RtlCopyMemory(&NotificationInfos->Event, Event, sizeof(GUID));
|
||||||
NotificationInfos->FileObject = (PFILE_OBJECT)EventCategoryData1;
|
NotificationInfos->FileObject = (PFILE_OBJECT)EventCategoryData1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationInfos;
|
||||||
|
NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
|
||||||
|
PagedPool,
|
||||||
|
sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION),
|
||||||
|
TAG_PNP_NOTIFY);
|
||||||
|
if (!NotificationInfos)
|
||||||
|
{
|
||||||
|
KeReleaseGuardedMutex(&PnpNotifyListLock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RtlCopyMemory(NotificationInfos, EventCategoryData1, sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -156,10 +175,25 @@ IopNotifyPlugPlayNotification(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EventCategoryTargetDeviceChange:
|
case EventCategoryTargetDeviceChange:
|
||||||
|
{
|
||||||
|
if (Event != &GUID_PNP_CUSTOM_NOTIFICATION)
|
||||||
{
|
{
|
||||||
if (ChangeEntry->FileObject == (PFILE_OBJECT)EventCategoryData1)
|
if (ChangeEntry->FileObject == (PFILE_OBJECT)EventCategoryData1)
|
||||||
CallCurrentEntry = TRUE;
|
CallCurrentEntry = TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = IoGetRelatedTargetDevice(ChangeEntry->FileObject, &EntryDeviceObject);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (DeviceObject == EntryDeviceObject)
|
||||||
|
{
|
||||||
|
((PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure)->FileObject = ChangeEntry->FileObject;
|
||||||
|
CallCurrentEntry = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
DPRINT1("IopNotifyPlugPlayNotification(): unknown EventCategory 0x%x UNIMPLEMENTED\n", EventCategory);
|
DPRINT1("IopNotifyPlugPlayNotification(): unknown EventCategory 0x%x UNIMPLEMENTED\n", EventCategory);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* FILE: ntoskrnl/io/pnpmgr/pnpreport.c
|
* FILE: ntoskrnl/io/pnpmgr/pnpreport.c
|
||||||
* PURPOSE: Device Changes Reporting Functions
|
* PURPOSE: Device Changes Reporting Functions
|
||||||
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
|
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
|
||||||
|
* Pierre Schweitzer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -12,6 +13,17 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* TYPES *******************************************************************/
|
||||||
|
|
||||||
|
typedef struct _INTERNAL_WORK_QUEUE_ITEM
|
||||||
|
{
|
||||||
|
WORK_QUEUE_ITEM WorkItem;
|
||||||
|
PDEVICE_OBJECT PhysicalDeviceObject;
|
||||||
|
PDEVICE_CHANGE_COMPLETE_CALLBACK Callback;
|
||||||
|
PVOID Context;
|
||||||
|
PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure;
|
||||||
|
} INTERNAL_WORK_QUEUE_ITEM, *PINTERNAL_WORK_QUEUE_ITEM;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
|
IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath,
|
||||||
|
@ -27,8 +39,15 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
||||||
PVOID Context);
|
PVOID Context);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
IopDetectResourceConflict(
|
IopDetectResourceConflict(IN PCM_RESOURCE_LIST ResourceList);
|
||||||
IN PCM_RESOURCE_LIST ResourceList);
|
|
||||||
|
NTSTATUS
|
||||||
|
PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN OUT PKEVENT SyncEvent OPTIONAL,
|
||||||
|
IN OUT PNTSTATUS SyncStatus OPTIONAL,
|
||||||
|
IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL,
|
||||||
|
IN PVOID Context OPTIONAL,
|
||||||
|
IN PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure);
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
@ -91,6 +110,37 @@ IopGetInterfaceTypeString(INTERFACE_TYPE IfType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
IopReportTargetDeviceChangeAsyncWorker(PVOID Context)
|
||||||
|
{
|
||||||
|
PINTERNAL_WORK_QUEUE_ITEM Item;
|
||||||
|
|
||||||
|
Item = (PINTERNAL_WORK_QUEUE_ITEM)Context;
|
||||||
|
PpSetCustomTargetEvent(Item->PhysicalDeviceObject, NULL, NULL, Item->Callback, Item->Context, Item->NotificationStructure);
|
||||||
|
ObDereferenceObject(Item->PhysicalDeviceObject);
|
||||||
|
ExFreePoolWithTag(Context, ' pP');
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN OUT PKEVENT SyncEvent OPTIONAL,
|
||||||
|
IN OUT PNTSTATUS SyncStatus OPTIONAL,
|
||||||
|
IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL,
|
||||||
|
IN PVOID Context OPTIONAL,
|
||||||
|
IN PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure)
|
||||||
|
{
|
||||||
|
ASSERT(NotificationStructure != NULL);
|
||||||
|
ASSERT(DeviceObject != NULL);
|
||||||
|
|
||||||
|
/* That call is totally wrong but notifications handler must be fixed first */
|
||||||
|
IopNotifyPlugPlayNotification(DeviceObject,
|
||||||
|
EventCategoryTargetDeviceChange,
|
||||||
|
&GUID_PNP_CUSTOM_NOTIFICATION,
|
||||||
|
NotificationStructure,
|
||||||
|
NULL);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -343,19 +393,57 @@ IopSetEvent(IN PVOID Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IoReportTargetDeviceChange(IN PDEVICE_OBJECT PhysicalDeviceObject,
|
IoReportTargetDeviceChange(IN PDEVICE_OBJECT PhysicalDeviceObject,
|
||||||
IN PVOID NotificationStructure)
|
IN PVOID NotificationStructure)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
KEVENT NotifyEvent;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
NTSTATUS Status, NotifyStatus;
|
||||||
|
PTARGET_DEVICE_CUSTOM_NOTIFICATION notifyStruct = (PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure;
|
||||||
|
|
||||||
|
ASSERT(notifyStruct);
|
||||||
|
|
||||||
|
/* Check for valid PDO */
|
||||||
|
if (!IopIsValidPhysicalDeviceObject(PhysicalDeviceObject))
|
||||||
|
{
|
||||||
|
KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG)PhysicalDeviceObject, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FileObject must be null. PnP will fill in it */
|
||||||
|
ASSERT(notifyStruct->FileObject == NULL);
|
||||||
|
|
||||||
|
/* Do not handle system PnP events */
|
||||||
|
if ((RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_QUERY_REMOVE), sizeof(GUID)) != sizeof(GUID)) ||
|
||||||
|
(RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_REMOVE_CANCELLED), sizeof(GUID)) != sizeof(GUID)) ||
|
||||||
|
(RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_REMOVE_COMPLETE), sizeof(GUID)) != sizeof(GUID)))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notifyStruct->Version != 1)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize even that will let us know when PnP will have finished notify */
|
||||||
|
KeInitializeEvent(&NotifyEvent, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
Status = PpSetCustomTargetEvent(PhysicalDeviceObject, &NotifyEvent, &NotifyStatus, NULL, NULL, notifyStruct);
|
||||||
|
/* If no error, wait for the notify to end and return the status of the notify and not of the event */
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeWaitForSingleObject(&NotifyEvent, Executive, KernelMode, FALSE, NULL);
|
||||||
|
Status = NotifyStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -364,6 +452,47 @@ IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject,
|
||||||
IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL,
|
IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL,
|
||||||
IN PVOID Context OPTIONAL)
|
IN PVOID Context OPTIONAL)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PINTERNAL_WORK_QUEUE_ITEM Item = NULL;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PTARGET_DEVICE_CUSTOM_NOTIFICATION notifyStruct = (PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure;
|
||||||
|
|
||||||
|
ASSERT(notifyStruct);
|
||||||
|
|
||||||
|
/* Check for valid PDO */
|
||||||
|
if (!IopIsValidPhysicalDeviceObject(PhysicalDeviceObject))
|
||||||
|
{
|
||||||
|
KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG)PhysicalDeviceObject, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FileObject must be null. PnP will fill in it */
|
||||||
|
ASSERT(notifyStruct->FileObject == NULL);
|
||||||
|
|
||||||
|
/* Do not handle system PnP events */
|
||||||
|
if ((RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_QUERY_REMOVE), sizeof(GUID)) != sizeof(GUID)) ||
|
||||||
|
(RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_REMOVE_CANCELLED), sizeof(GUID)) != sizeof(GUID)) ||
|
||||||
|
(RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_REMOVE_COMPLETE), sizeof(GUID)) != sizeof(GUID)))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notifyStruct->Version != 1)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We need to store all the data given by the caller with the WorkItem, so use our own struct */
|
||||||
|
Item = ExAllocatePoolWithTag(NonPagedPool, sizeof(INTERNAL_WORK_QUEUE_ITEM), ' pP');
|
||||||
|
if (!Item) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Initialize all stuff */
|
||||||
|
ObReferenceObject(PhysicalDeviceObject);
|
||||||
|
Item->NotificationStructure = notifyStruct;
|
||||||
|
Item->PhysicalDeviceObject = PhysicalDeviceObject;
|
||||||
|
Item->Callback = Callback;
|
||||||
|
Item->Context = Context;
|
||||||
|
ExInitializeWorkItem(&(Item->WorkItem), (PWORKER_THREAD_ROUTINE)IopReportTargetDeviceChangeAsyncWorker, Item);
|
||||||
|
|
||||||
|
/* Finally, queue the item, our work here is done */
|
||||||
|
ExQueueWorkItem(&(Item->WorkItem), DelayedWorkQueue);
|
||||||
|
|
||||||
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
<library>kdcom</library>
|
<library>kdcom</library>
|
||||||
<library>bootvid</library>
|
<library>bootvid</library>
|
||||||
<library>wdmguid</library>
|
<library>wdmguid</library>
|
||||||
|
<library>ioevent</library>
|
||||||
<dependency>bugcodes</dependency>
|
<dependency>bugcodes</dependency>
|
||||||
<directory name="include">
|
<directory name="include">
|
||||||
<pch>ntoskrnl.h</pch>
|
<pch>ntoskrnl.h</pch>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue