|
|
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.