NT4/private/ntos/dd/sound/necsnd/dispatch.c

222 lines
5.1 KiB
C
Raw Normal View History

2001-01-01 00:00:00 +01:00
/*++
"@(#) NEC dispatch.c 1.1 95/03/22 21:23:27"
Copyright (c) 1995 NEC Corporation.
Copyright (c) 1992 Microsoft Corporation
Module Name:
dispatch.c
Abstract:
This module contains code for the function dispatcher.
Environment:
Kernel mode
Revision History:
Robin Speed (RobinSp) 29-Jan-1992 - Add extra IOCTLs and access control
--*/
#include <string.h>
#include <soundlib.h> // Definition of what's in here
/**************************************************************************
*
*
* Function dispatch
*
*
**************************************************************************/
NTSTATUS
SoundSetShareAccess(
IN OUT PLOCAL_DEVICE_INFO pLDI,
IN PIO_STACK_LOCATION IrpStack
)
/*++
Routine Description:
Tests if access is allowed to the device on the basis of the sharing
requested.
Also sets the PreventVolumeSetting flag up in the local device info
If write access required and the device is already in use we return
STATUS_DEVICE_BUSY.
If shared write was requested set the flag to say that others can
set the volume
Arguments:
pLDI - Local device info
pIrp - Pointer to IO request packet
IrpStack - stack location info
Return Value:
Return status from dispatched routine
--*/
{
NTSTATUS Status;
//
// Get the system to update the file object access flags
//
{
SHARE_ACCESS ShareAccess;
IoSetShareAccess(IrpStack->Parameters.Create.SecurityContext->DesiredAccess,
(ULONG)IrpStack->Parameters.Create.ShareAccess,
IrpStack->FileObject,
&ShareAccess);
}
//
// Always allow non-write access. For neatness we'll require
// that read access was requested
//
if (IrpStack->Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA) {
if (IrpStack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA) {
ASSERT(IrpStack->FileObject->WriteAccess);
dprintf2(("Trying to open device %4.4s for write",
(char *)&pLDI->Key));
if (!(*pLDI->DeviceInit->ExclusionRoutine)(
pLDI, SoundExcludeOpen)) {
Status = STATUS_DEVICE_BUSY;
} else {
Status = STATUS_SUCCESS;
}
//
// Note that if share for write is given this is a way
// of saying that others can set our volume with just read
// access
//
pLDI->PreventVolumeSetting = FALSE;
if (NT_SUCCESS(Status)) {
if (IrpStack->FileObject->SharedWrite) {
} else {
pLDI->PreventVolumeSetting = TRUE;
}
}
} else {
Status = STATUS_SUCCESS;
}
} else {
Status = STATUS_ACCESS_DENIED;
}
return Status;
}
NTSTATUS
SoundDispatch(
IN PDEVICE_OBJECT pDO,
IN PIRP pIrp
)
/*++
Routine Description:
Driver function dispatch routine
Arguments:
pDO - Pointer to device object
pIrp - Pointer to IO request packet
Return Value:
Return status from dispatched routine
--*/
{
PLOCAL_DEVICE_INFO pLDI;
PIO_STACK_LOCATION IrpStack;
NTSTATUS Status;
Status = STATUS_SUCCESS;
//
// Initialize the irp information field.
//
pIrp->IoStatus.Information = 0;
//
// get the address of the local info structure in the device extension
//
pLDI = (PLOCAL_DEVICE_INFO)pDO->DeviceExtension;
//
// Acquire the device mutant - we need to do this for some
// devices anyway because we have to execute waits for slow
// operations to complete
//
if (!(*pLDI->DeviceInit->ExclusionRoutine)(pLDI, SoundExcludeEnter)) {
Status = STATUS_DEVICE_BUSY;
} else {
//
// Dispatch the function based on the major function code
//
IrpStack = IoGetCurrentIrpStackLocation(pIrp);
#ifdef VOLUME_NOTIFY
/**********************************************************************
*
* Do general volume stuff here
*
**********************************************************************/
//
// Free anyone waiting for the volume to change
//
if (IrpStack->MajorFunction == IRP_MJ_CLEANUP) {
SoundFreePendingIrps(&pLDI->VolumeQueue, IrpStack->FileObject);
}
#endif // VOLUME_NOTIFY
//
// Call the real device code
//
if (NT_SUCCESS(Status)) {
Status = (*pLDI->DeviceInit->DispatchRoutine)(pLDI, pIrp, IrpStack);
}
//
// Free the device
//
(*pLDI->DeviceInit->ExclusionRoutine)(pLDI, SoundExcludeLeave);
}
//
// Tell the IO subsystem we're done. If the Irp is pending we
// don't touch it as it could be being processed by another
// processor (or may even be complete already !).
//
if (Status != STATUS_PENDING) {
pIrp->IoStatus.Status = Status;
IoCompleteRequest(pIrp, IO_SOUND_INCREMENT );
}
return Status;
}