Annotation of ntddk/src/mmedia/soundlib/dispatch.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1992  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     dispatch.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This module contains code for the function dispatcher.
                     12: 
                     13: Author:
                     14: 
                     15:     Robin Speed (RobinSp) 22-Oct-1992
                     16: 
                     17: Environment:
                     18: 
                     19:     Kernel mode
                     20: 
                     21: Revision History:
                     22: 
                     23:     Robin Speed (RobinSp) 29-Jan-1992 - Add extra IOCTLs and access control
                     24: 
                     25: --*/
                     26: 
                     27: #include <string.h>
                     28: #include <soundlib.h>          // Definition of what's in here
                     29: 
                     30: /**************************************************************************
                     31:  *
                     32:  *
                     33:  *    Function dispatch
                     34:  *
                     35:  *
                     36:  **************************************************************************/
                     37: 
                     38: 
                     39: NTSTATUS
                     40: SoundSetShareAccess(
                     41:     IN OUT PLOCAL_DEVICE_INFO pLDI,
                     42:     IN     PIO_STACK_LOCATION IrpStack
                     43: )
                     44: /*++
                     45: 
                     46: Routine Description:
                     47: 
                     48:     Tests if access is allowed to the device on the basis of the sharing
                     49:     requested.
                     50: 
                     51:     Also sets the PreventVolumeSetting flag up in the local device info
                     52: 
                     53:     If write access required and the device is already in use we return
                     54:     STATUS_DEVICE_BUSY.
                     55: 
                     56:     If shared write was requested set the flag to say that others can
                     57:     set the volume
                     58: 
                     59: Arguments:
                     60: 
                     61:     pLDI - Local device info
                     62:     pIrp - Pointer to IO request packet
                     63:     IrpStack - stack location info
                     64: 
                     65: Return Value:
                     66: 
                     67:     Return status from dispatched routine
                     68: 
                     69: --*/
                     70: {
                     71:     NTSTATUS Status;
                     72: 
                     73:     //
                     74:     // Get the system to update the file object access flags
                     75:     //
                     76:     {
                     77:         SHARE_ACCESS ShareAccess;
                     78:         IoSetShareAccess(IrpStack->Parameters.Create.SecurityContext->DesiredAccess,
                     79:                          (ULONG)IrpStack->Parameters.Create.ShareAccess,
                     80:                          IrpStack->FileObject,
                     81:                          &ShareAccess);
                     82:     }
                     83:     //
                     84:     // Always allow non-write access.  For neatness we'll require
                     85:     // that read access was requested
                     86:     //
                     87:     if (IrpStack->Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA) {
                     88:         if (IrpStack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA) {
                     89:             ASSERT(IrpStack->FileObject->WriteAccess);
                     90:             dprintf2(("Trying to open device %4.4s for write",
                     91:                      (char *)&pLDI->Key));
                     92: 
                     93:             if (!(*pLDI->DeviceInit->ExclusionRoutine)(
                     94:                       pLDI, SoundExcludeOpen)) {
                     95:                 Status = STATUS_DEVICE_BUSY;
                     96:             } else {
                     97:                 Status = STATUS_SUCCESS;
                     98:             }
                     99: 
                    100:             //
                    101:             // Note that if share for write is given this is a way
                    102:             // of saying that others can set our volume with just read
                    103:             // access
                    104:             //
                    105:             pLDI->PreventVolumeSetting = FALSE;
                    106:             if (NT_SUCCESS(Status)) {
                    107:                 if (IrpStack->FileObject->SharedWrite) {
                    108:                 } else {
                    109:                     pLDI->PreventVolumeSetting = TRUE;
                    110:                 }
                    111:             }
                    112:         } else {
                    113:             Status = STATUS_SUCCESS;
                    114:         }
                    115:     } else {
                    116:         Status = STATUS_ACCESS_DENIED;
                    117:     }
                    118: 
                    119:     return Status;
                    120: }
                    121: 
                    122: 
                    123: NTSTATUS
                    124: SoundDispatch(
                    125:     IN    PDEVICE_OBJECT pDO,
                    126:     IN    PIRP pIrp
                    127: )
                    128: /*++
                    129: 
                    130: Routine Description:
                    131: 
                    132:     Driver function dispatch routine
                    133: 
                    134: Arguments:
                    135: 
                    136:     pDO - Pointer to device object
                    137:     pIrp - Pointer to IO request packet
                    138: 
                    139: Return Value:
                    140: 
                    141:     Return status from dispatched routine
                    142: 
                    143: --*/
                    144: {
                    145:     PLOCAL_DEVICE_INFO pLDI;
                    146:     PIO_STACK_LOCATION pIrpStack;
                    147:     NTSTATUS Status;
                    148: 
                    149:     Status = STATUS_SUCCESS;
                    150: 
                    151:     //
                    152:     // Initialize the irp information field.
                    153:     //
                    154: 
                    155:     pIrp->IoStatus.Information = 0;
                    156: 
                    157:     //
                    158:     // get the address of the local info structure in the device extension
                    159:     //
                    160: 
                    161:     pLDI = (PLOCAL_DEVICE_INFO)pDO->DeviceExtension;
                    162: 
                    163:     //
                    164:     // Acquire the device mutant - we need to do this for some
                    165:     // devices anyway because we have to execute waits for slow
                    166:     // operations to complete
                    167:     //
                    168: 
                    169:     if (!(*pLDI->DeviceInit->ExclusionRoutine)(pLDI, SoundExcludeEnter)) {
                    170:         Status = STATUS_DEVICE_BUSY;
                    171:     } else {
                    172:         //
                    173:         // Dispatch the function based on the major function code
                    174:         //
                    175: 
                    176:         pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
                    177: 
                    178: #ifdef VOLUME_NOTIFY
                    179: 
                    180:        /**********************************************************************
                    181:         *
                    182:         *   Do general volume stuff here
                    183:         *
                    184:         **********************************************************************/
                    185: 
                    186:         //
                    187:         // Free anyone waiting for the volume to change
                    188:         //
                    189: 
                    190:         if (pIrpStack->MajorFunction == IRP_MJ_CLEANUP) {
                    191: 
                    192:             int i;
                    193:             KIRQL OldIrql;
                    194: 
                    195:             //
                    196:             // Free anyone waiting for the volume to change whose file object
                    197:             // is the one about to be closed.
                    198:             //
                    199: 
                    200:             PLIST_ENTRY ListEntry, Next;
                    201: 
                    202:             //
                    203:             // Our list is cancellable so do this under the cancel spin
                    204:             // lock
                    205:             //
                    206: 
                    207:             IoAcquireCancelSpinLock(&OldIrql);
                    208: 
                    209:             for (ListEntry = pLDI->VolumeQueue.Flink;
                    210:                  ListEntry != &pLDI->VolumeQueue;
                    211:                  ListEntry = Next) {
                    212: 
                    213:                 PIRP IrpList;
                    214:                 IrpList = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
                    215: 
                    216:                 Next = ListEntry->Flink;
                    217: 
                    218:                 ASSERT(IoGetCurrentIrpStackLocation(IrpList)->MajorFunction ==
                    219:                            IRP_MJ_DEVICE_CONTROL &&
                    220:                        IoGetCurrentIrpStackLocation(IrpList)->
                    221:                            Parameters.DeviceIoControl.IoControlCode ==
                    222:                            IOCTL_SOUND_GET_CHANGED_VOLUME);
                    223: 
                    224:                 if (pIrpStack->FileObject ==
                    225:                         IoGetCurrentIrpStackLocation(IrpList)->FileObject) {
                    226: 
                    227:                     RemoveEntryList(ListEntry);
                    228: 
                    229:                     //
                    230:                     // Make sure our cancel routine doesn't get in!
                    231:                     //
                    232: 
                    233:                     IoSetCancelRoutine(IrpList, NULL);
                    234: 
                    235: 
                    236:                     //
                    237:                     // Free the spin lock in case IoCompleteRequest doesn't
                    238:                     // like us to hold it
                    239:                     //
                    240: 
                    241:                     IoReleaseCancelSpinLock(OldIrql);
                    242: 
                    243:                     IrpList->IoStatus.Status = STATUS_SUCCESS;
                    244:                     IoCompleteRequest(IrpList, IO_NO_INCREMENT);
                    245: 
                    246:                     IoAcquireCancelSpinLock(&OldIrql);
                    247: 
                    248:                     //
                    249:                     // The world may have changed so restart
                    250:                     //
                    251: 
                    252:                     Next = pLDI->VolumeQueue.Flink;
                    253:                 }
                    254:             }
                    255: 
                    256:             IoReleaseCancelSpinLock(OldIrql);
                    257:         }
                    258: 
                    259: #endif // VOLUME_NOTIFY
                    260: 
                    261:         //
                    262:         // Call the real device code
                    263:         //
                    264: 
                    265:         if (NT_SUCCESS(Status)) {
                    266:             Status = (*pLDI->DeviceInit->DispatchRoutine)(pLDI, pIrp, pIrpStack);
                    267:         }
                    268: 
                    269:         //
                    270:         // Free the device
                    271:         //
                    272: 
                    273:         (*pLDI->DeviceInit->ExclusionRoutine)(pLDI, SoundExcludeLeave);
                    274:     }
                    275: 
                    276:     //
                    277:     // Tell the IO subsystem we're done.  If the Irp is pending we
                    278:     // don't touch it as it could be being processed by another
                    279:     // processor (or may even be complete already !).
                    280:     //
                    281: 
                    282:     if (Status != STATUS_PENDING) {
                    283:         pIrp->IoStatus.Status = Status;
                    284:         IoCompleteRequest(pIrp, IO_SOUND_INCREMENT );
                    285:     }
                    286: 
                    287:     return Status;
                    288: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.