- Don't load NT4 audio drivers by default anymore.

- Don't load beep.sys in non-setup mode.
- Improve beep driver by making it use device queues instead of instantly completing beep requests, and make it cancel-safe, unloadable, and thread-safe in regards to timers. Also reduce memory footprint by making the entire driver pageable and dynamically locking/unlocking the image section by keeping a reference count of opens.

svn path=/trunk/; revision=26254
This commit is contained in:
Alex Ionescu 2007-04-03 16:01:58 +00:00
parent 295322ab9b
commit ca95775748
2 changed files with 347 additions and 233 deletions

View file

@ -490,7 +490,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Group",0x00000000,"Video Init" HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Group",0x00000000,"Video Init"
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ImagePath",0x00020000,"system32\drivers\blue.sys" HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ImagePath",0x00020000,"system32\drivers\blue.sys"
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Start",0x00010001,0x00000004
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Type",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Type",0x00010001,0x00000001
; Cdfs (ISO96660) filesystem driver ; Cdfs (ISO96660) filesystem driver
@ -593,7 +593,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Class\{4D36E96B-E325-11CE-BFC1-08002BE103
HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Group",0x00000000,"Base" HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Group",0x00000000,"Base"
HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","ServiceType",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","ServiceType",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Type",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Start",0x00010001,0x00000004
HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","ErrorControl",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","ImagePath",0x00020000,"system32\drivers\sndblst.sys" HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","ImagePath",0x00020000,"system32\drivers\sndblst.sys"
;HKLM,"SYSTEM\CurrentControlSet\Services\sndblst\Parameters\Device0","DmaChannel",0x00010001,0x00000001 ;HKLM,"SYSTEM\CurrentControlSet\Services\sndblst\Parameters\Device0","DmaChannel",0x00010001,0x00000001
@ -608,7 +608,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\sndblst\Parameters\Device0\Devices","SBW
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Group",0x00000000,"Base" HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Group",0x00000000,"Base"
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ServiceType",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ServiceType",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Type",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Start",0x00010001,0x00000004
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ErrorControl",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ErrorControl",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ImagePath",0x00020000,"system32\drivers\mpu401.sys" HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ImagePath",0x00020000,"system32\drivers\mpu401.sys"

View file

@ -1,259 +1,365 @@
/* $Id$ /*
* * PROJECT: ReactOS Kernel
* COPYRIGHT: See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* PROJECT: ReactOS kernel * FILE: drivers/base/beep/beep.c
* FILE: services/dd/beep/beep.c * PURPOSE: Beep Device Driver
* PURPOSE: BEEP device driver * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* PROGRAMMER: Eric Kohl (ekohl@rz-online.de) * Eric Kohl (ekohl@rz-online.de)
* UPDATE HISTORY:
* 30/01/99 Created
* 16/10/99 Minor fixes
*/ */
/* INCLUDES ****************************************************************/ /* INCLUDES ******************************************************************/
#include <ntddk.h> #include <ntddk.h>
#include <ntddbeep.h> #include <ntddbeep.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
NTSTATUS STDCALL /* TYPES *********************************************************************/
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
/* TYEPEDEFS ***************************************************************/
typedef struct _BEEP_DEVICE_EXTENSION typedef struct _BEEP_DEVICE_EXTENSION
{ {
KDPC Dpc; LONG ReferenceCount;
FAST_MUTEX Mutex;
KTIMER Timer; KTIMER Timer;
KEVENT Event; LONG TimerActive;
BOOLEAN BeepOn; PVOID SectionHandle;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION; } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
/* FUNCTIONS *****************************************************************/
/* FUNCTIONS ***************************************************************/ VOID
NTAPI
static VOID STDCALL BeepDPC(IN PKDPC Dpc,
BeepDPC(PKDPC Dpc, IN PDEVICE_OBJECT DeviceObject,
PVOID DeferredContext, IN PVOID SystemArgument1,
PVOID SystemArgument1, IN PVOID SystemArgument2)
PVOID SystemArgument2)
{ {
PDEVICE_EXTENSION DeviceExtension = DeferredContext; PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
DPRINT("BeepDPC() called!\n");
/* Stop the beep */
HalMakeBeep(0); HalMakeBeep(0);
DeviceExtension->BeepOn = FALSE;
KeSetEvent(&DeviceExtension->Event,
0,
FALSE);
DPRINT("BeepDPC() finished!\n"); /* Disable the timer */
InterlockedDecrement(&DeviceExtension->TimerActive);
} }
NTSTATUS
static NTSTATUS STDCALL NTAPI
BeepCreate( BeepCreate(IN PDEVICE_OBJECT DeviceObject,
PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{ {
DPRINT("BeepCreate() called!\n"); PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
/* Acquire the mutex and increase reference count */
ExAcquireFastMutex(&DeviceExtension->Mutex);
if (++DeviceExtension->ReferenceCount == 1)
{
/* First reference, lock the data section */
DeviceExtension->SectionHandle = MmLockPagableDataSection(BeepCreate);
}
/* Release it */
ExReleaseFastMutex(&DeviceExtension->Mutex);
/* Complete the request */
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IoCompleteRequest(Irp, IO_NO_INCREMENT);
IO_NO_INCREMENT); return STATUS_SUCCESS;
return(STATUS_SUCCESS);
} }
NTSTATUS
static NTSTATUS STDCALL NTAPI
BeepClose(PDEVICE_OBJECT DeviceObject, BeepClose(IN PDEVICE_OBJECT DeviceObject,
PIRP Irp) IN PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{ {
PDEVICE_EXTENSION DeviceExtension; PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status;
DPRINT("BeepClose() called!\n"); /* Acquire the mutex and decrease reference count */
ExAcquireFastMutex(&DeviceExtension->Mutex);
DeviceExtension = DeviceObject->DeviceExtension; if (!(--DeviceExtension->ReferenceCount))
if (DeviceExtension->BeepOn == TRUE)
{ {
HalMakeBeep(0); /* Check for active timer */
DeviceExtension->BeepOn = FALSE; if (DeviceExtension->TimerActive)
KeCancelTimer(&DeviceExtension->Timer); {
/* Cancel it */
if (KeCancelTimer(&DeviceExtension->Timer))
{
/* Mark it as cancelled */
InterlockedDecrement(&DeviceExtension->TimerActive);
}
} }
Status = STATUS_SUCCESS; /* Page the driver */
MmUnlockPagableImageSection(DeviceExtension->SectionHandle);
}
Irp->IoStatus.Status = Status; /* Release the lock */
Irp->IoStatus.Information = 0; ExReleaseFastMutex(&DeviceExtension->Mutex);
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(Status);
}
static NTSTATUS STDCALL
BeepCleanup(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
DPRINT("BeepCleanup() called!\n");
/* Complete the request */
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IoCompleteRequest(Irp, IO_NO_INCREMENT);
IO_NO_INCREMENT); return STATUS_SUCCESS;
return(STATUS_SUCCESS);
} }
VOID
static NTSTATUS STDCALL NTAPI
BeepDeviceControl(PDEVICE_OBJECT DeviceObject, BeepCancel(IN PDEVICE_OBJECT DeviceObject,
PIRP Irp) IN PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{ {
PIO_STACK_LOCATION Stack; /* Check if this is the current request */
PDEVICE_EXTENSION DeviceExtension; if (Irp == DeviceObject->CurrentIrp)
PBEEP_SET_PARAMETERS BeepParam;
LARGE_INTEGER DueTime;
DPRINT("BeepDeviceControl() called!\n");
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
Irp->IoStatus.Information = 0;
if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)
{ {
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; /* Clear it */
IoCompleteRequest(Irp, DeviceObject->CurrentIrp = NULL;
IO_NO_INCREMENT);
return(STATUS_NOT_IMPLEMENTED);
}
if ((Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(BEEP_SET_PARAMETERS)) /* Release the cancel lock and start the next packet */
|| (BeepParam->Frequency < BEEP_FREQUENCY_MINIMUM) IoReleaseCancelSpinLock(Irp->CancelIrql);
|| (BeepParam->Frequency > BEEP_FREQUENCY_MAXIMUM)) IoStartNextPacket(DeviceObject, TRUE);
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(STATUS_INVALID_PARAMETER);
}
DueTime.QuadPart = 0;
/* do the beep!! */
DPRINT("Beep:\n Freq: %lu Hz\n Dur: %lu ms\n",
BeepParam->Frequency,
BeepParam->Duration);
if (BeepParam->Duration > 0)
{
DueTime.QuadPart = (LONGLONG)BeepParam->Duration * -10000;
KeSetTimer(&DeviceExtension->Timer,
DueTime,
&DeviceExtension->Dpc);
HalMakeBeep(BeepParam->Frequency);
DeviceExtension->BeepOn = TRUE;
KeWaitForSingleObject(&DeviceExtension->Event,
Executive,
KernelMode,
FALSE,
NULL);
}
else if (BeepParam->Duration == MAXULONG)
{
if (DeviceExtension->BeepOn == TRUE)
{
HalMakeBeep(0);
DeviceExtension->BeepOn = FALSE;
} }
else else
{ {
HalMakeBeep(BeepParam->Frequency); /* Otherwise, remove the packet from the queue and relelase the lock */
DeviceExtension->BeepOn = TRUE; KeRemoveEntryDeviceQueue(&DeviceObject->DeviceQueue,
} &Irp->Tail.Overlay.DeviceQueueEntry);
IoReleaseCancelSpinLock(Irp->CancelIrql);
} }
DPRINT("Did the beep!\n"); /* Complete the request */
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IoCompleteRequest (Irp, IO_NO_INCREMENT);
IO_NO_INCREMENT);
return(STATUS_SUCCESS);
} }
NTSTATUS
static VOID STDCALL NTAPI
BeepUnload(PDRIVER_OBJECT DriverObject) BeepCleanup(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
DPRINT("BeepUnload() called!\n"); KIRQL OldIrql, CancelIrql;
PKDEVICE_QUEUE_ENTRY Packet;
PIRP CurrentIrp;
/* Raise IRQL and acquire the cancel lock */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
IoAcquireCancelSpinLock(&CancelIrql);
/* Get the current IRP */
CurrentIrp = DeviceObject->CurrentIrp;
DeviceObject->CurrentIrp = NULL;
while (CurrentIrp)
{
/* Clear its cancel routine */
(VOID)IoSetCancelRoutine(CurrentIrp, NULL);
/* Cancel the IRP */
CurrentIrp->IoStatus.Status = STATUS_CANCELLED;
CurrentIrp->IoStatus.Information = 0;
/* Release the cancel lock and complete it */
IoReleaseCancelSpinLock(CancelIrql);
IoCompleteRequest(CurrentIrp, IO_NO_INCREMENT);
/* Reacquire the lock and get the next queue packet */
IoAcquireCancelSpinLock(&CancelIrql);
Packet = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
if (Packet)
{
/* Get the IRP */
CurrentIrp = CONTAINING_RECORD(Packet,
IRP,
Tail.Overlay.DeviceQueueEntry);
}
else
{
/* No more IRPs */
CurrentIrp = NULL;
}
}
/* Release lock and go back to low IRQL */
IoReleaseCancelSpinLock(CancelIrql);
KeLowerIrql(OldIrql);
/* Complete the IRP */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* Stop and beep and return */
HalMakeBeep(0);
return STATUS_SUCCESS;
} }
NTSTATUS
NTAPI
BeepDeviceControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION Stack;
PBEEP_SET_PARAMETERS BeepParam;
NTSTATUS Status;
NTSTATUS STDCALL /* Get the stack location and parameters */
DriverEntry(PDRIVER_OBJECT DriverObject, Stack = IoGetCurrentIrpStackLocation(Irp);
PUNICODE_STRING RegistryPath) BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
/*
* FUNCTION: Called by the system to initalize the driver /* We only support one IOCTL */
* ARGUMENTS: if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)
* DriverObject = object describing this driver {
* RegistryPath = path to our configuration entries /* Unsupported command */
* RETURNS: Success or failure Status = STATUS_NOT_IMPLEMENTED;
*/ }
else
{
/* Validate the input buffer length */
if (Stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(BEEP_SET_PARAMETERS))
{
/* Invalid buffer */
Status = STATUS_INVALID_PARAMETER;
}
else if ((BeepParam->Frequency != 0) && !(BeepParam->Duration))
{
/* No duration, return imemdiately */
Status = STATUS_SUCCESS;
}
else
{
/* We'll queue this request */
Status = STATUS_PENDING;
}
}
/* Set packet information */
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
/* Check if we're completing or queuing a packet */
if (Status == STATUS_PENDING)
{
/* Start the queue */
IoMarkIrpPending(Irp);
IoStartPacket(DeviceObject, Irp, NULL, BeepCancel);
}
else
{
/* Complete the request */
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
/* Return */
return Status;
}
VOID
NTAPI
BeepUnload(IN PDRIVER_OBJECT DriverObject)
{
PDEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT DeviceObject;
/* Get DO and DE */
DeviceObject = DriverObject->DeviceObject;
DeviceExtension = DeviceObject->DeviceExtension;
/* Check if the timer is active */
if (DeviceExtension->TimerActive)
{
/* Cancel it */
if (KeCancelTimer(&DeviceExtension->Timer))
{
/* All done */
InterlockedDecrement(&DeviceExtension->TimerActive);
}
}
/* Delete the object */
IoDeleteDevice(DeviceObject);
}
VOID
NTAPI
BeepStartIo(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
KIRQL CancelIrql;
PIO_STACK_LOCATION IoStack;
PBEEP_SET_PARAMETERS BeepParam;
LARGE_INTEGER DueTime;
NTSTATUS Status;
/* Acquire the cancel lock and make sure the IRP is valid */
IoAcquireCancelSpinLock(&CancelIrql);
if (!Irp)
{
/* It's not, release the lock and quit */
IoReleaseCancelSpinLock(CancelIrql);
return;
}
/* Remove the cancel routine and release the lock */
(VOID)IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(CancelIrql);
/* Get the I/O Stack and make sure the request is valid */
BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_BEEP_SET)
{
/* Check if we have an active timer */
if (DeviceExtension->TimerActive)
{
/* Cancel it */
if (KeCancelTimer(&DeviceExtension->Timer))
{
/* Set the state */
InterlockedDecrement(&DeviceExtension->TimerActive);
}
}
/* Make the beep */
if (HalMakeBeep(BeepParam->Frequency))
{
/* Beep successful, queue a DPC to stop it */
Status = STATUS_SUCCESS;
DueTime.QuadPart = BeepParam->Duration * -10000;
InterlockedIncrement(&DeviceExtension->TimerActive);
KeSetTimer(&DeviceExtension->Timer, DueTime, &DeviceObject->Dpc);
}
else
{
/* Beep has failed */
Status = STATUS_INVALID_PARAMETER;
}
}
else
{
/* Invalid request */
Status = STATUS_INVALID_PARAMETER;
}
/* Complete the request and start the next packet */
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoStartNextPacket(DeviceObject, TRUE);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
NTSTATUS
NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{ {
PDEVICE_EXTENSION DeviceExtension; PDEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Beep"); UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Beep");
NTSTATUS Status; NTSTATUS Status;
DPRINT("Beep Device Driver 0.0.3\n"); /* Create the device */
DriverObject->Flags = 0;
DriverObject->MajorFunction[IRP_MJ_CREATE] = BeepCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = BeepClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BeepCleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BeepDeviceControl;
DriverObject->DriverUnload = BeepUnload;
Status = IoCreateDevice(DriverObject, Status = IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION), sizeof(DEVICE_EXTENSION),
&DeviceName, &DeviceName,
@ -261,22 +367,30 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
0, 0,
FALSE, FALSE,
&DeviceObject); &DeviceObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status)) return Status;
return Status;
/* set up device extension */ /* Make it use buffered I/O */
DeviceObject->Flags |= DO_BUFFERED_IO;
/* Setup the Driver Object */
DriverObject->MajorFunction[IRP_MJ_CREATE] = BeepCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = BeepClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BeepCleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BeepDeviceControl;
DriverObject->DriverUnload = BeepUnload;
DriverObject->DriverStartIo = BeepStartIo;
/* Set up device extension */
DeviceExtension = DeviceObject->DeviceExtension; DeviceExtension = DeviceObject->DeviceExtension;
DeviceExtension->BeepOn = FALSE; DeviceExtension->ReferenceCount = 0;
DeviceExtension->TimerActive = FALSE;
KeInitializeDpc(&DeviceExtension->Dpc, IoInitializeDpcRequest(DeviceObject, BeepDPC);
BeepDPC,
DeviceExtension);
KeInitializeTimer(&DeviceExtension->Timer); KeInitializeTimer(&DeviceExtension->Timer);
KeInitializeEvent(&DeviceExtension->Event, ExInitializeFastMutex(&DeviceExtension->Mutex);
SynchronizationEvent,
FALSE);
return(STATUS_SUCCESS); /* Page the entire driver */
MmPageEntireDriver(DriverEntry);
return STATUS_SUCCESS;
} }
/* EOF */ /* EOF */