|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.