222 lines
5.1 KiB
C
222 lines
5.1 KiB
C
|
/*++
|
|||
|
"@(#) 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;
|
|||
|
}
|