NTSTATUS
BalloonEvtDeviceD0Entry(
    IN  WDFDEVICE Device,
    IN  WDF_POWER_DEVICE_STATE PreviousState
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PDEVICE_CONTEXT devCtx = GetDeviceContext(Device);

    UNREFERENCED_PARAMETER(PreviousState);
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s\n", __FUNCTION__);

    status = BalloonInit(Device);
    if(!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
           "BalloonInit failed with status 0x%08x\n", status);
        BalloonTerm(Device);
        return status;
    }

    status = BalloonCreateWorkerThread(Device);
    if(!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
           "BalloonCreateWorkerThread failed with status 0x%08x\n", status);
    } 

    devCtx->evLowMem = IoCreateNotificationEvent(
        (PUNICODE_STRING)&evLowMemString, &devCtx->hLowMem);

    return status;
}
Example #2
0
BOOLEAN
UserlandPostBootup()
{
    UNICODE_STRING  uszUserlandRequestEvent;


	ASSERT(BootingUp == FALSE);


	KeInitializeSpinLock(&gUserlandRequestListSpinLock);

	
	/* Create an event for userland agent service to monitor */
#define	USERLAND_REQUEST_EVENT_NAME	L"\\BaseNamedObjects\\OzoneUserlandRequestEvent"

    RtlInitUnicodeString(&uszUserlandRequestEvent, USERLAND_REQUEST_EVENT_NAME);


	if ((UserlandRequestUserEvent = IoCreateNotificationEvent(&uszUserlandRequestEvent, &UserlandRequestUserEventHandle)) == NULL)
	{
		LOG(LOG_SS_MISC, LOG_PRIORITY_DEBUG, ("UserlandPostBootup: IoCreateNotificationEvent failed\n"));
		return FALSE;
	}

	KeClearEvent(UserlandRequestUserEvent);


	return TRUE;
}
Example #3
0
NTSTATUS DriverExampleAddDevice(IN PDRIVER_OBJECT  DriverObject, IN PDEVICE_OBJECT  PhysicalDeviceObject)
{
	DbgPrint("Enter AddDevice\n");
	PDEVICE_OBJECT DeviceObject = NULL;
	PDriverExample_DEVICE_EXTENSION pExtension = NULL;
	NTSTATUS status;
	UNICODE_STRING uszDriverString;
	RtlInitUnicodeString(&uszDriverString, L"\\Device\\DriverExample");// Задача функции RtlInitUnicodeString измерить unicode-строку и заполнить 
	
	
	status = IoCreateDevice(DriverObject,
						    sizeof(DriverExample_DEVICE_EXTENSION),
							&uszDriverString,
							FILE_DEVICE_UNKNOWN,
							0,
							0,
							&DeviceObject);
	
	UNICODE_STRING uszDeviceString;

	RtlInitUnicodeString(&uszDeviceString, L"\\DosDevices\\DriverExample");
    //
	// Create symbolic link to the user-visible name

    status = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString);

	if (!NT_SUCCESS(status))
	{
		DbgPrint("Not success status \n");
		return status;
	}
	g_pDeviceObject = DeviceObject; //Save Device object

	pExtension = (PDriverExample_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

	pExtension->DeviceObject = DeviceObject;
	pExtension->PhysicalDeviceObject = PhysicalDeviceObject;
	pExtension->TargetDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);

	status = IoRegisterDeviceInterface(PhysicalDeviceObject, &GUID_DriverExampleInterface, NULL, &pExtension->DeviceInterface);
	ASSERT(NT_SUCCESS(status));

	UNICODE_STRING uszProcessEventString;
	HANDLE hProcessHandle;

	RtlInitUnicodeString(&uszProcessEventString,L"\\BaseNamedObjects\\ProcessEvent");
    pExtension->ProcessEvent = IoCreateNotificationEvent(&uszProcessEventString,	&hProcessHandle);
	//
    // Clear it out
	//
    KeClearEvent(pExtension->ProcessEvent);

	DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	DbgPrint("Exit AddDevice \n");
	return STATUS_SUCCESS;
}
Example #4
0
NTSTATUS DriverEntry(
	IN PDRIVER_OBJECT DriverObject, 
	IN PUNICODE_STRING RegistryPath
	)
{
    NTSTATUS        ntStatus;
    UNICODE_STRING  uszDriverString;
    UNICODE_STRING  uszDeviceString;
    UNICODE_STRING  uszProcessEventString;

    PDEVICE_OBJECT    pDeviceObject;
    PDEVICE_EXTENSION extension;
    
    RtlInitUnicodeString(&uszDriverString, DEVICE_NAME);

    ntStatus = IoCreateDevice(DriverObject,
										        sizeof(DEVICE_EXTENSION),
										        &uszDriverString,
										        FILE_DEVICE_UNKNOWN,
										        0,
										        FALSE,
										        &pDeviceObject);
	        
    if(ntStatus != STATUS_SUCCESS)
        return ntStatus;
    
    extension = pDeviceObject->DeviceExtension;

    RtlInitUnicodeString(&uszDeviceString, DEVICE_LINK_NAME);    
    ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString);
    if(ntStatus != STATUS_SUCCESS)
    {
        IoDeleteDevice(pDeviceObject);
        return ntStatus;
    }

    g_pDeviceObject = pDeviceObject;

    DriverObject->MajorFunction[IRP_MJ_CREATE]         = DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch;
		DriverObject->DriverUnload                         = UnloadDriver;

    
    RtlInitUnicodeString(&uszProcessEventString, MONITOR_PROCESS_EVENT);
    extension->ProcessEvent = IoCreateNotificationEvent (&uszProcessEventString, &extension->hProcessHandle);

    KeClearEvent(extension->ProcessEvent);

    ntStatus = PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);
    
    return ntStatus;
}
Example #5
0
NEO_EVENT *NeoNewEvent(char *name)
{
	UNICODE *unicode_name;
	NEO_EVENT *event;
	// Validate arguments
	if (name == NULL)
	{
		return NULL;
	}

	// Convert the name to Unicode
	unicode_name = NewUnicode(name);
	if (unicode_name == NULL)
	{
		return NULL;
	}

	// Memory allocation
	event = NeoZeroMalloc(sizeof(NEO_EVENT));
	if (event == NULL)
	{
		FreeUnicode(unicode_name);
		return NULL;
	}

	// Create an Event
	event->event = IoCreateNotificationEvent(GetUnicode(unicode_name), &event->event_handle);
	if (event->event == NULL)
	{
		NeoFree(event);
		FreeUnicode(unicode_name);
		return NULL;
	}

	// Initialize the event
	KeInitializeEvent(event->event, NotificationEvent, FALSE);
	KeClearEvent(event->event);

	// Release a string
	FreeUnicode(unicode_name);

	return event;
}
Example #6
0
// Create an event
SL_EVENT *SlNewEvent(char *name)
{
	SL_UNICODE *unicode_name;
	SL_EVENT *event;
	// Validate arguments
	if (name == NULL)
	{
		return NULL;
	}

	// Convert to Unicode name
	unicode_name = SlNewUnicode(name);
	if (unicode_name == NULL)
	{
		return NULL;
	}

	// Memory allocation
	event = SlZeroMalloc(sizeof(SL_EVENT));
	if (event == NULL)
	{
		SlFreeUnicode(unicode_name);
		return NULL;
	}

	// Create an event
	event->event = IoCreateNotificationEvent(SlGetUnicode(unicode_name), &event->event_handle);
	if (event->event == NULL)
	{
		SlFree(event);
		SlFreeUnicode(unicode_name);
		return NULL;
	}

	// Initialize the event
	KeInitializeEvent(event->event, NotificationEvent, FALSE);
	KeClearEvent(event->event);

	// Release the string
	SlFreeUnicode(unicode_name);

	return event;
}
/*	Main entry point into the driver, is called when the driver is loaded */
NTSTATUS DriverEntry(
	IN PDRIVER_OBJECT DriverObject, 
	IN PUNICODE_STRING RegistryPath
	)
{
    NTSTATUS        ntStatus;
    UNICODE_STRING  uszDriverString;
    UNICODE_STRING  uszDeviceString;
    UNICODE_STRING  uszProcessEventString;
    PDEVICE_OBJECT    pDeviceObject;
	PCAPTURE_PROCESS_MANAGER pProcessManager;
	int i;
    
	/* Point uszDriverString at the driver name */
    RtlInitUnicodeString(&uszDriverString, L"\\Device\\CaptureProcessMonitor");

    /* Create and initialise Process Monitor device object */
    ntStatus = IoCreateDevice(
		DriverObject,
        sizeof(CAPTURE_PROCESS_MANAGER),
        &uszDriverString,
        FILE_DEVICE_UNKNOWN,
        0,
        FALSE,
        &pDeviceObject
		);
    if(!NT_SUCCESS(ntStatus)) {
		DbgPrint("CaptureProcessMonitor: ERROR IoCreateDevice ->  \\Device\\CaptureProcessMonitor - %08x\n", ntStatus); 
        return ntStatus;
	}

	/* Point uszDeviceString at the device name */
    RtlInitUnicodeString(&uszDeviceString, L"\\DosDevices\\CaptureProcessMonitor");
    
	/* Create symbolic link to the user-visible name */
    ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString);

    if(!NT_SUCCESS(ntStatus))
    {
		DbgPrint("CaptureProcessMonitor: ERROR IoCreateSymbolicLink ->  \\DosDevices\\CaptureProcessMonitor - %08x\n", ntStatus); 
        IoDeleteDevice(pDeviceObject);
        return ntStatus;
    }

	/* Set global device object to newly created object */
	gpDeviceObject = pDeviceObject;

	/* Get the process manager from the extension of the device */
	pProcessManager = gpDeviceObject->DeviceExtension;

    /* Assign global pointer to the device object for use by the callback functions */
    pProcessManager->pDeviceObject = pDeviceObject;
	ExInitializeFastMutex(&pProcessManager->mProcessWaitingSpinLock);

	/* Create event for user-mode processes to monitor */
    RtlInitUnicodeString(&uszProcessEventString, L"\\BaseNamedObjects\\CaptureProcDrvProcessEvent");
    pProcessManager->eNewProcessEvent = IoCreateNotificationEvent (&uszProcessEventString, &pProcessManager->hNewProcessEvent);
	KeClearEvent(pProcessManager->eNewProcessEvent);

    /* Load structure to point to IRP handlers */
    DriverObject->DriverUnload                         = UnloadDriver;
    DriverObject->MajorFunction[IRP_MJ_CREATE]         = KDispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = KDispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KDispatchIoctl;

	pProcessManager->pCurrentProcessEvent = NULL;
    /* Register process callback function */
	ntStatus = PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);
	if(!NT_SUCCESS(ntStatus))
	{
		DbgPrint("CaptureProcessMonitor: ERROR PsSetCreateProcessNotifyRoutine - %08x\n", ntStatus); 
		return ntStatus;
	}

	/* Process Manager is ready to receive processes */
	pProcessManager->bReady = TRUE;
    
	DbgPrint("CaptureProcessMonitor: Successfully Loaded\n"); 
	
	/* Return success */
    return STATUS_SUCCESS;
}
Example #8
0
NTSTATUS
DriverEntry( DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath )
{
    VOID *processEventHandle = 0;
    VOID *threadEventHandle = 0;
    VOID *imageEventHandle = 0;
    NTSTATUS status;
    UNICODE_STRING DeviceNameU;
    UNICODE_STRING DeviceLinkU;
    UNICODE_STRING processEventName;
    UNICODE_STRING threadEventName;
    UNICODE_STRING imageEventName;

    DbgPrint("[PUSH] => (DriverEntry)\n");

    MmPageEntireDriver((PVOID)(ULONG_PTR) DriverEntry);

    MaxDevices = IMDISK_DEFAULT_MAX_DEVICES;

    lstMapInfo.Next=NULL;

    PushDriverObject = DriverObject;

    RtlInitUnicodeString(&DeviceNameU,  PUSH_DEVICE_BASE_NAME);
    RtlInitUnicodeString(&DeviceLinkU,  PUSH_SYMLINK_NAME);
    RtlInitUnicodeString(&processEventName, L"\\BaseNamedObjects\\" PUSH_PROCESS_EVENT_NAME);
    RtlInitUnicodeString(&threadEventName,  L"\\BaseNamedObjects\\" PUSH_THREAD_EVENT_NAME);
    RtlInitUnicodeString(&imageEventName,   L"\\BaseNamedObjects\\" PUSH_IMAGE_EVENT_NAME);

    //Create a device object
    status = IoCreateDevice(DriverObject,               //IN: Driver Object
                              sizeof(DEVICE_EXTENSION), //IN: Device Extension Size
                              &DeviceNameU,             //IN: Device Name
                              FILE_DEVICE_PUSH,         //IN: Device Type
                              0,                        //IN: Device Characteristics
                              FALSE,                    //IN: Exclusive
                              &g_DeviceObject);     //OUT:Created Device Object

    // The control device gets a device_number of -1 to make it easily
    // distinguishable from the actual created devices.
    //((PDEVICE_EXTENSION) g_DeviceObject->DeviceExtension)->device_number =
    //(ULONG) -1;

    //Dispatch functions
    DriverObject->MajorFunction[IRP_MJ_CREATE]          = DispatchCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]           = DispatchClose;
    DriverObject->MajorFunction[IRP_MJ_READ]            = ImDiskReadWrite;
    DriverObject->MajorFunction[IRP_MJ_WRITE]           = ImDiskReadWrite;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = DispatchIoCtl;
    DriverObject->MajorFunction[IRP_MJ_PNP]             = ImDiskDispatchPnP;

    DriverObject->DriverUnload = PushUnload;

    //Create a symbolic link
    IoCreateSymbolicLink(&DeviceLinkU, &DeviceNameU);

    ProcessEvent = IoCreateNotificationEvent(&processEventName, &processEventHandle);
    ThreadEvent = IoCreateNotificationEvent(&threadEventName, &threadEventHandle);
    ImageEvent = IoCreateNotificationEvent(&imageEventName, &imageEventHandle);

    KeClearEvent(ProcessEvent);
    KeClearEvent(ThreadEvent);
    KeClearEvent(ImageEvent);

    DbgPrint("[PUSH] <= (DriverEntry)\n");

    return status;
}
NTSTATUS CreateINTEvent(int Id, PKEVENT hR3Event)
{
#ifdef CREATE_SHARE_EVENT_UNDER_DRIVER
	UNICODE_STRING EventName;
	wchar_t wsEventNameBuf[] = L"\\BaseNamedObjects\\SusiWDTIntEvent0";
#endif

	NTSTATUS ntStatus = STATUS_SUCCESS;
	PWDTDev pDev;
	KIRQL IRQL_former;

	if (Id >= SUSI_ID_WATCHDOG_MAX)
		return STATUS_INVALID_PARAMETER;

	pDev = &gWDTDev[Id];

	KeAcquireSpinLock(&pDev->IRQ.SpinLock, &IRQL_former);

#ifdef CREATE_SHARE_EVENT_UNDER_DRIVER
	if (pDev->IRQ.SharedEventHandle != NULL)
	{
		goto exit;
	}

	// Replace index number
	wsEventNameBuf[wcslen(wsEventNameBuf) -1] = '0' + Id;
	RtlInitUnicodeString(&EventName, wsEventNameBuf);

	pDev->IRQ.hEvent = IoCreateNotificationEvent(&EventName, &pDev->IRQ.SharedEventHandle);

	if (pDev->IRQ.hEvent != NULL)
	{ 
		// Take a reference out on the object so that it does not go away if the application goes away unexpectedly
		ObReferenceObject(pDev->IRQ.hEvent);
		//DebugPrint(DBG_WDM, "[SUSI Drv][WDT] pDev->IRQ.hEvent = 0x%08X\n", pDev->IRQ.hEvent);
	}
	else
		return STATUS_UNSUCCESSFUL;

	if (pDev->IRQ.SharedEventHandle == NULL)
	{
		DebugPrint(DBG_KERNEL, "IoCreateNotificationEvent failed.\n");
		ntStatus = STATUS_UNSUCCESSFUL;
		goto exit;
	}

	KeClearEvent(pDev->IRQ.hEvent);
#else
	if (hR3Event)
	{
		if (pDev->IRQ.hEvent)
		{
			ObDereferenceObject(pDev->IRQ.hEvent);
			pDev->IRQ.hEvent = NULL;
		}

		ntStatus = ObReferenceObjectByHandle(hR3Event,
			EVENT_MODIFY_STATE,
			*ExEventObjectType,
			KernelMode,	//Irp->RequestorMode,
			(PVOID*)&pDev->IRQ.hEvent,
			NULL);

		if (!NT_SUCCESS(ntStatus))
		{
			ntStatus = STATUS_INVALID_PARAMETER;
		}
	}		
	else
	{
		pDev->IRQ.hEvent = NULL;
	}
#endif

#ifdef CREATE_SHARE_EVENT_UNDER_DRIVER
exit:
#endif
	KeReleaseSpinLock(&pDev->IRQ.SpinLock, IRQL_former); 
	return ntStatus;
}
Example #10
0
//==================================================================================
//===== Процедура Входа в драйвер
//==================================================================================
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
	
	UNICODE_STRING NameString, LinkString, ProcessEventName;
	PDEVICE_OBJECT DeviceObject;//переменная объекта устройства
	NTSTATUS Status;//код статуса
		PEXAMPLE_DEVICE_EXTENSION dx;
	PVOID pvWaitEvents[1];
	OBJECT_ATTRIBUTES oaUserEvent;
	gInited = FALSE;
	DbgPrint(" >MegaDriver: we are inda DriverEntry"); //открываем DbgView - он отлавливает DbgPrint - будем видеть что происходит


	//================================================================================================
	//===== Инитим указатели на функции
	//================================================================================================
	DriverObject->DriverUnload = (PDRIVER_UNLOAD)MyDriverUnload;
	DriverObject->MajorFunction[IRP_MJ_CREATE] = CreateMyDriver;//CreateFile
	DriverObject->MajorFunction[IRP_MJ_READ] = ReadMyDriver; //readfile
	DriverObject->MajorFunction[IRP_MJ_WRITE] = WriteMyDriver; //write...
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = CloseMyDriver; //CloseFile
	//DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ShutDownMyDriver;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoCtlMyDriver;


	//=================================================================================================
	//===== Создаём девайс
	//=================================================================================================
	//юникодим имя нашего драйвера
	RtlInitUnicodeString(&NameString, L"\\Device\\MegaDriver");
	//создаём девайс
	Status = IoCreateDevice(DriverObject, sizeof(65533), &NameString, 0, 0, FALSE, &DeviceObject);
	if(!NT_SUCCESS(Status)) 
	{
		DbgPrint(" >MegaDriver: DriverEntry-> IoCreateDevice - [failed]");
		return Status;
	}
	else DbgPrint(" >MegaDriver: DriverEntry-> IoCreateDevice - [ok]");

	//если всё гуд, то ставим флаги
	DeviceObject->Flags |= DO_DIRECT_IO;
	DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;


	// Получаем указатель на область, предназначенную под
	// структуру расширение устройства
	dx = (PEXAMPLE_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
	dx->fdo = DeviceObject; // Сохраняем обратный указатель



	//==========================================================================================
	//===== Создаём симболик линк
	//==========================================================================================
	//Юникодим имя линку
	RtlInitUnicodeString(&LinkString, L"\\DosDevices\\MegaDriver");
	//создаём символьную ссылку
	Status = IoCreateSymbolicLink(&LinkString, &NameString);

	//если краш, то удаляем девайс и выходим
	if(!NT_SUCCESS(Status))
	{
		DbgPrint(" >MegaDriver: DriverEntry-> IoCreateSymbolikLink - [failed]");
		IoDeleteDevice(DriverObject->DeviceObject);//сносим девайс
		return Status;
	} else DbgPrint(" >MegaDriver: DriverEntry-> IoCreateSymbolikLink - [ok]");



	//==================================================================================================
	//===== Создаём евент
	//==================================================================================================
	//RtlInitUnicodeString(&ProcessEventName, L"\\\\BaseNamedObjects\\Global\\EVENT_NAME");
	//gEvent = IoCreateNotificationEvent(&ProcessEventName, &ghProcessHandle);
	//if(ghProcessHandle!=NULL)
	//{
	//	KeClearEvent(gEvent); 
	//	DbgPrint(" >MegaDriver: DriverEntry-> EventCreated - [ok]");
	//}//хоть код и закоменчен, может пригодиться =) 
	RtlInitUnicodeString(&ProcessEventName,L"\\BaseNamedObjects\\DriverProcessEvent");//v draivere
	gEvent = IoCreateNotificationEvent(&ProcessEventName,&ghProcessHandle);
	if(ghProcessHandle!=NULL)
	{
		KeClearEvent(gEvent); 
		DbgPrint(" >MegaDriver: DriverEntry-> EventCreated - [ok]");
	}


	//BSOD
	//KeBugCheck(1);
	if(NT_SUCCESS(Status))
		DbgPrint(" >MegaDriver: DriverEntry-> all done - [ok]");

	return STATUS_SUCCESS;
}
//
// The main entry point of the driver module
//
NTSTATUS DriverEntry(
	IN PDRIVER_OBJECT DriverObject, 
	IN PUNICODE_STRING RegistryPath
	)
{
    NTSTATUS                  ntStatus;
    UNICODE_STRING            uszDriverString;
    UNICODE_STRING            uszDeviceString;
    UNICODE_STRING            uszProcessEventString;
    PDEVICE_OBJECT            pDeviceObject;
    PDEVICE_EXTENSION         extension;
	HANDLE                    hProcessHandle;

	//    
	// Point uszDriverString at the driver name
	//
    RtlInitUnicodeString(&uszDriverString, L"\\Device\\ProcObsrv");
	//
    // Create and initialize device object
	//
    ntStatus = IoCreateDevice(
		DriverObject,
        sizeof(DEVICE_EXTENSION),
        &uszDriverString,
        FILE_DEVICE_UNKNOWN,
        0,
        FALSE,
        &pDeviceObject
		);
    if(ntStatus != STATUS_SUCCESS)
        return ntStatus;
    //
	// Assign extension variable
	//
    extension = pDeviceObject->DeviceExtension;
    //
	// Point uszDeviceString at the device name
	//
    RtlInitUnicodeString(&uszDeviceString, L"\\DosDevices\\ProcObsrv");
    //
	// Create symbolic link to the user-visible name
	//
    ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString);

    if(ntStatus != STATUS_SUCCESS)
    {
		//
        // Delete device object if not successful
		//
        IoDeleteDevice(pDeviceObject);
        return ntStatus;
    }
	//
    // Assign global pointer to the device object for use by the callback functions
	//
    g_pDeviceObject = pDeviceObject;
	//
	// Setup initial state
	//
	g_ActivateInfo.bActivated = FALSE;
	//
    // Load structure to point to IRP handlers
	//
    DriverObject->DriverUnload                         = UnloadDriver;
    DriverObject->MajorFunction[IRP_MJ_CREATE]         = DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
	//
    // Create event for user-mode processes to monitor
	//
    RtlInitUnicodeString(
		&uszProcessEventString, 
		L"\\BaseNamedObjects\\ProcObsrvProcessEvent"
		);
    extension->ProcessEvent = IoCreateNotificationEvent(
		&uszProcessEventString, 
		&hProcessHandle
		);
	//
    // Clear it out
	//
    KeClearEvent(extension->ProcessEvent);
	//
    // Return success
	//
    return ntStatus;
}