⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eventsys.c

📁 Sample code that demostrates how to use shared events in Kernel mode.
💻 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 + -