📄 eventsys.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 1995 - 2003 OSR Open Systems Resources, Inc.
// All Rights Reserved
//
// This sofware is supplied for instructional purposes only.
//
// OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
// for this software. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
// THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
// PURPOSE. THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
// WITH YOU. OSR's entire liability and your exclusive remedy shall not
// exceed the price paid for this material. In no event shall OSR or its
// suppliers be liable for any damages whatsoever (including, without
// limitation, damages for loss of business profit, business interruption,
// loss of business information, or any other pecuniary loss) arising out
// of the use or inability to use this software, even if OSR has been
// advised of the possibility of such damages. Because some states/
// jurisdictions do not allow the exclusion or limitation of liability for
// consequential or incidental damages, the above limitation may not apply
// to you.
//
// OSR Open Systems Resources, Inc.
// 105 Route 101A Suite 19
// Amherst, NH 03031 (603) 595-6500 FAX: (603) 595-6503
// email bugs to: bugs@osr.com
//
//
// MODULE:
//
// EventShare.C -- Event Share example kernel mode component
//
// ABSTRACT:
//
// This is a legacy device driver that simply gets a handle to and
// sets a named event that is created by a user mode application
//
// AUTHOR(S):
//
// OSR Open Systems Resources, Inc.
//
// REVISION:
//
//
///////////////////////////////////////////////////////////////////////////////
#include <ntddk.h>
#include <eventioctl.h>
//
// Global Variables
//
//
// Our Device Object
//
PDEVICE_OBJECT DeviceObject = NULL;
//
// Handle to the shared event
//
HANDLE SharedEventHandle = NULL;
//
// The actual shared event object
//
PKEVENT SharedEvent = NULL;
///////////////////////////////////////////////////////////////////////////////
//
// EventSysTimerCallback
//
// This is the callback routine in which we'll actually signal the event
//
//
// INPUTS:
//
// DeviceObject - Address of the DEVICE_OBJECT for our device.
//
// Context - Not used
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// None
//
// IRQL:
//
// This routine is called at IRQL DISPATCH_LEVEL.
//
// NOTES:
//
///////////////////////////////////////////////////////////////////////////////
VOID
EventSysTimerCallback (
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context
)
{
#if DBG
DbgPrint("EventSysTimerCallback: Entered...\n");
#endif
//
// Set the event so that the user mode application's wait will
// be satisfied. Note that the third parameter, Wait, must be
// set to FALSE since we're running at DISPATCH_LEVEL
//
KeSetEvent(SharedEvent, 0, FALSE);
#if DBG
DbgPrint("EventSysTimerCallback: Exited...\n");
#endif
}
///////////////////////////////////////////////////////////////////////////////
//
// EventSysCreateClose
//
// This is the dispatch entry point for processing both IRP_MJ_CREATE
// and IRP_MJ_CLOSE functions. Since this is a simple device driver,
// there's really nothing to do here by complete the requests with success.
//
//
// INPUTS:
//
// DeviceObject - Address of the DEVICE_OBJECT for our device.
//
// Irp - Address of the IRP representing the IRP_MJ_CREATE or IRP_MJ_CLOSE
// call.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS. We never fail this function.
//
// IRQL:
//
// This routine is called at IRQL PASSIVE_LEVEL.
//
// NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS EventSysCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp);
#if DBG
DbgPrint("EventSysCreateClose: Entered\n");
#endif
//
// Nothing much to do....
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
#if DBG
DbgPrint("EventSysCreateClose: Exited...\n");
#endif
return(STATUS_SUCCESS);
}
///////////////////////////////////////////////////////////////////////////////
//
// EventSysDeviceControl
//
// This is the dispatch entry point for processing IRP_MJ_DEVICE_CONTROL
// Irps.
//
//
// INPUTS:
//
// DeviceObject - Address of the DEVICE_OBJECT for our device.
//
// Irp - Address of the IRP representing the IRP_MJ_DEVICE_CONTROL call.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS if success, otherwise an appropriate status is returned.
//
// IRQL:
//
// This routine is called at IRQL_PASSIVE_LEVEL.
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS EventSysDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
ULONG operation;
PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS Status;
KIRQL Irql;
UNICODE_STRING EventName;
HANDLE UserHandle;
#if DBG
DbgPrint("EventSysDeviceControl: Entered...\n");
#endif
operation = ioStack->Parameters.DeviceIoControl.IoControlCode;
//
// Set the status field to zero for completion
//
Irp->IoStatus.Information = 0;
switch (operation) {
//
// IOCTL to open the handle the CORRECT way
//
case IOCTL_OPEN_EVENT:
#if DBG
DbgPrint("EventSysDeviceControl: Received IOCTL_OPEN_EVENT\n");
#endif
//
// When you create a named event in user mode \BaseNamedObjects\ is
// prepended to the name specified in the call to CreateEvent
//
RtlInitUnicodeString(&EventName, L"\\BaseNamedObjects\\SharedEvent");
//
// Get a pointer to a KEVENT object that is associated with this
// named event
//
SharedEvent = IoCreateNotificationEvent(&EventName, &SharedEventHandle);
if (SharedEvent != NULL) {
//
// Take a reference out on the object so that
// it does not go away if the application
// goes away unexpectedly
//
ObReferenceObject(SharedEvent);
Status = STATUS_SUCCESS;
//
// Start the timer that signals the event
//
IoStartTimer(DeviceObject);
} else {
Status = STATUS_UNSUCCESSFUL;
}
break;
//
// IOCTL to open the handle the undesirable way
//
case IOCTL_EVENT_HANDLE:
#if DBG
DbgPrint("EventSysDeviceControl: Received IOCTL_EVENT_HANDLE\n");
#endif
//
// Get the user's handle
//
UserHandle = *(HANDLE *)Irp->AssociatedIrp.SystemBuffer;
//
// Passing *ExEventObjectType validates that this is indeed and event
// handle
//
// Passing UserMode performs all necessary access checks to make sure
// the calling application has appropriate security access to the handle
//
Status = ObReferenceObjectByHandle(
UserHandle,
EVENT_ALL_ACCESS,
*ExEventObjectType,
UserMode,
&SharedEvent,
NULL
);
if (NT_SUCCESS(Status)) {
//
// Start the timer that signals the event
//
IoStartTimer(DeviceObject);
}
break;
default:
//
// This is the case for a bogus request code.
//
Status = STATUS_INVALID_PARAMETER;
#if DBG
DbgPrint("EventSysDeviceControl: Invalid IOCTL code 0x%0x\n", operation);
#endif
break;
}
//
// Complete the I/O Request
//
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
#if DBG
DbgPrint("EventSysDeviceControl: Exited...\n");
#endif
return(Status);
}
///////////////////////////////////////////////////////////////////////////////
//
// EventSysUnload
//
// This is the dispatch entry point for processing the unloading of the driver
//
//
// INPUTS:
//
// DriverObject - Address of the DRIVER_OBJECT for our device.
//
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// None.
//
// IRQL:
//
// This routine is called at IRQL_PASSIVE_LEVEL.
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID EventSysUnload( IN PDRIVER_OBJECT DriverObject )
{
UNICODE_STRING DeviceLinkName;
#if DBG
DbgPrint(("EventSysDriverUnload: Entered...\n"));
#endif
if (SharedEventHandle != NULL) {
//
// Close our handle
//
ZwClose(SharedEventHandle);
}
if (SharedEvent != NULL) {
//
// Release our reference.
//
ObDereferenceObject(SharedEvent);
}
RtlInitUnicodeString(&DeviceLinkName, L"\\DosDevices\\EventShare");
//
// Delete the symbolic link for our device
//
IoDeleteSymbolicLink(&DeviceLinkName);
//
// Stop our timer before we delete our device object
//
IoStopTimer(DriverObject->DeviceObject);
//
// Delete the device object
//
IoDeleteDevice(DriverObject->DeviceObject);
#if DBG
DbgPrint(("EventSysDriverUnload: Deleted devices\n"));
#endif
}
///////////////////////////////////////////////////////////////////////////////
//
// DriverEntry
//
// This routine is called by NT when the driver is first loaded. It is the
// responsibility of this routine to create whatever
// device objects it needs.
//
// INPUTS:
//
// DriverObj - Address of the DRIVER_OBJECT created by NT for this driver.
//
// RegistryPath - UNICODE_STRING which represents this drivers KEY in the
// Registry.
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS. Otherwise an error indicating why the driver could not
// load.
//
// IRQL:
//
// This routine is called at IRQL_PASSIVE_LEVEL.
//
// NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
NTSTATUS Status;
UNICODE_STRING DeviceName;
UNICODE_STRING DeviceLinkName;
#if DBG
DbgPrint ("EventSysDriverEntry: Entered...\n");
#endif
RtlInitUnicodeString(&DeviceName, L"\\Device\\EventShare");
//
// Set up the device used for GUI communications
//
Status = IoCreateDevice (
DriverObject,
0,
&DeviceName,
FILE_DEVICE_EVENTSYS,
0,
TRUE,
&DeviceObject
);
if (NT_SUCCESS(Status)) {
RtlInitUnicodeString (&DeviceLinkName,
L"\\DosDevices\\EventShare");
//
// Create a symbolic link that a user mode application can specify
// in a call to CreateFile to retrieve a handle to our device
//
Status = IoCreateSymbolicLink (
&DeviceLinkName,
&DeviceName
);
if (!NT_SUCCESS(Status)) {
//
// If we can't create a symbolic link there's not much we can do...
//
#if DBG
DbgPrint ("EventSysDriverEntry: IoCreateSymbolicLink failed! -- 0x%8.8x\n",
Status);
#endif
return Status;
}
//
// Create dispatch points for all routines that must be handled
//
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] = EventSysCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = EventSysDeviceControl;
DriverObject->DriverUnload = EventSysUnload;
}
if (!NT_SUCCESS(Status)) {
//
// Something went seriously wrong so just get outta here...
//
#if DBG
DbgPrint("EventSysDriverEntry: Failed to create our device! -- 0x%8.8x\n", Status);
#endif
return Status;
}
//
// Initialize our timer that will signal the event. We'll wait to start it
// until we've received an IOCTL from the user mode application letting
// us know that the event has been created.
//
IoInitializeTimer(DeviceObject, EventSysTimerCallback, NULL);
//
// We're Done! Our device has successfully loaded
//
#if DBG
DbgPrint ("EventSysDriverEntry: Exited...\n");
#endif
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -