Added exports to def/edf files and modified some pnp functions.
[reactos.git] / reactos / ntoskrnl / io / irp.c
1 /* $Id: irp.c,v 1.45 2002/10/03 19:39:56 robd Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/irp.c
6 * PURPOSE: Handle IRPs
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * 24/05/98: Created
10 */
11
12 /* NOTES *******************************************************************
13 *
14 * Layout of an IRP
15 *
16 * ################
17 * # Headers #
18 * ################
19 * # #
20 * # Variable #
21 * # length list #
22 * # of io stack #
23 * # locations #
24 * # #
25 * ################
26 *
27 *
28 *
29 */
30
31 /* INCLUDES ****************************************************************/
32
33 #include <ddk/ntddk.h>
34 #include <internal/io.h>
35 #include <internal/ps.h>
36 #include <internal/pool.h>
37
38 #define NDEBUG
39 #include <internal/debug.h>
40
41 /* GLOBALS *******************************************************************/
42
43 #define TAG_IRP TAG('I', 'R', 'P', ' ')
44
45
46 /* FUNCTIONS ****************************************************************/
47
48
49 VOID STDCALL
50 IoFreeIrp(PIRP Irp)
51 /*
52 * FUNCTION: Releases a caller allocated irp
53 * ARGUMENTS:
54 * Irp = Irp to free
55 */
56 {
57 ExFreePool(Irp);
58 }
59
60
61 PIRP STDCALL
62 IoMakeAssociatedIrp(PIRP Irp,
63 CCHAR StackSize)
64 /*
65 * FUNCTION: Allocates and initializes an irp to associated with a master irp
66 * ARGUMENTS:
67 * Irp = Master irp
68 * StackSize = Number of stack locations to be allocated in the irp
69 * RETURNS: The irp allocated
70 */
71 {
72 PIRP AssocIrp;
73
74 AssocIrp = IoAllocateIrp(StackSize,FALSE);
75 UNIMPLEMENTED;
76 }
77
78
79 VOID STDCALL
80 IoInitializeIrp(PIRP Irp,
81 USHORT PacketSize,
82 CCHAR StackSize)
83 /*
84 * FUNCTION: Initalizes an irp allocated by the caller
85 * ARGUMENTS:
86 * Irp = IRP to initalize
87 * PacketSize = Size in bytes of the IRP
88 * StackSize = Number of stack locations in the IRP
89 */
90 {
91 assert(Irp != NULL);
92
93 memset(Irp, 0, PacketSize);
94 Irp->Size = PacketSize;
95 Irp->StackCount = StackSize;
96 Irp->CurrentLocation = StackSize;
97 Irp->Tail.Overlay.CurrentStackLocation = &Irp->Stack[(ULONG)StackSize];
98 }
99
100
101 NTSTATUS FASTCALL
102 IofCallDriver(PDEVICE_OBJECT DeviceObject,
103 PIRP Irp)
104 /*
105 * FUNCTION: Sends an IRP to the next lower driver
106 */
107 {
108 NTSTATUS Status;
109 PDRIVER_OBJECT DriverObject;
110 PIO_STACK_LOCATION Param;
111
112 DPRINT("IofCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
113
114 assert(Irp);
115 assert(DeviceObject);
116
117 DriverObject = DeviceObject->DriverObject;
118
119 assert(DriverObject);
120
121 Param = IoGetNextIrpStackLocation(Irp);
122
123 DPRINT("IrpSp 0x%X\n", Param);
124
125 Irp->Tail.Overlay.CurrentStackLocation--;
126 Irp->CurrentLocation--;
127
128 DPRINT("MajorFunction %d\n", Param->MajorFunction);
129 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
130 DriverObject->MajorFunction[Param->MajorFunction]);
131 Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject,
132 Irp);
133
134 return(Status);
135 }
136
137
138 NTSTATUS
139 STDCALL
140 IoCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
141 {
142 return(IofCallDriver(DeviceObject,
143 Irp));
144 }
145
146
147 PIRP STDCALL
148 IoAllocateIrp(CCHAR StackSize,
149 BOOLEAN ChargeQuota)
150 /*
151 * FUNCTION: Allocates an IRP
152 * ARGUMENTS:
153 * StackSize = the size of the stack required for the irp
154 * ChargeQuota = Charge allocation to current threads quota
155 * RETURNS: Irp allocated
156 */
157 {
158 PIRP Irp;
159
160 #if 0
161 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
162 StackSize,
163 ChargeQuota);
164 KeDumpStackFrames(0,8);
165 #endif
166
167 if (ChargeQuota)
168 {
169 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
170 Irp = ExAllocatePoolWithTag(NonPagedPool,
171 IoSizeOfIrp(StackSize),
172 TAG_IRP);
173 }
174 else
175 {
176 Irp = ExAllocatePoolWithTag(NonPagedPool,
177 IoSizeOfIrp(StackSize),
178 TAG_IRP);
179 }
180
181 if (Irp==NULL)
182 {
183 return(NULL);
184 }
185
186 IoInitializeIrp(Irp,
187 IoSizeOfIrp(StackSize),
188 StackSize);
189
190 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
191
192 return(Irp);
193 }
194
195
196 VOID STDCALL
197 IopCompleteRequest(struct _KAPC* Apc,
198 PKNORMAL_ROUTINE* NormalRoutine,
199 PVOID* NormalContext,
200 PVOID* SystemArgument1,
201 PVOID* SystemArgument2)
202 {
203 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, (*SystemArgument1) %x\n",
204 Apc,
205 SystemArgument1,
206 *SystemArgument1);
207 IoSecondStageCompletion((PIRP)(*SystemArgument1),
208 (KPRIORITY)(*SystemArgument2));
209 }
210
211
212 VOID FASTCALL
213 IofCompleteRequest(PIRP Irp,
214 CCHAR PriorityBoost)
215 /*
216 * FUNCTION: Indicates the caller has finished all processing for a given
217 * I/O request and is returning the given IRP to the I/O manager
218 * ARGUMENTS:
219 * Irp = Irp to be cancelled
220 * PriorityBoost = Increment by which to boost the priority of the
221 * thread making the request
222 */
223 {
224 unsigned int i;
225 NTSTATUS Status;
226
227 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
228 Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
229
230 for (i=Irp->CurrentLocation;i<Irp->StackCount;i++)
231 {
232 if (Irp->Stack[i].CompletionRoutine != NULL)
233 {
234 Status = Irp->Stack[i].CompletionRoutine(
235 Irp->Stack[i].DeviceObject,
236 Irp,
237 Irp->Stack[i].CompletionContext);
238 if (Status == STATUS_MORE_PROCESSING_REQUIRED)
239 {
240 return;
241 }
242 }
243 if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
244 {
245 Irp->PendingReturned = TRUE;
246 }
247 if (Irp->CurrentLocation < Irp->StackCount - 1)
248 {
249 IoSkipCurrentIrpStackLocation(Irp);
250 }
251 }
252 if (Irp->PendingReturned)
253 {
254 DPRINT("Dispatching APC\n");
255 KeInitializeApc(&Irp->Tail.Apc,
256 &Irp->Tail.Overlay.Thread->Tcb,
257 0,
258 IopCompleteRequest,
259 NULL,
260 (PKNORMAL_ROUTINE)
261 NULL,
262 KernelMode,
263 NULL);
264 KeInsertQueueApc(&Irp->Tail.Apc,
265 (PVOID)Irp,
266 (PVOID)(ULONG)PriorityBoost,
267 KernelMode);
268 DPRINT("Finished dispatching APC\n");
269 }
270 else
271 {
272 DPRINT("Calling completion routine directly\n");
273 IoSecondStageCompletion(Irp,PriorityBoost);
274 DPRINT("Finished completition routine\n");
275 }
276 }
277
278
279 VOID STDCALL
280 IoCompleteRequest(PIRP Irp,
281 CCHAR PriorityBoost)
282 {
283 IofCompleteRequest(Irp,
284 PriorityBoost);
285 }
286
287
288 /**********************************************************************
289 * NAME EXPORTED
290 * IoIsOperationSynchronous@4
291 *
292 * DESCRIPTION
293 * Check if the I/O operation associated with the given IRP
294 * is synchronous.
295 *
296 * ARGUMENTS
297 * Irp Packet to check.
298 *
299 * RETURN VALUE
300 * TRUE if Irp's operation is synchronous; otherwise FALSE.
301 */
302 BOOLEAN STDCALL
303 IoIsOperationSynchronous(IN PIRP Irp)
304 {
305 PFILE_OBJECT FileObject = NULL;
306 ULONG Flags = 0;
307
308 /* Check the FILE_OBJECT's flags first. */
309 FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
310 if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
311 {
312 /* Check IRP's flags. */
313 Flags = Irp->Flags;
314 if (!((IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO) & Flags))
315 {
316 return(FALSE);
317 }
318 }
319
320 /* Check more IRP's flags. */
321 Flags = Irp->Flags;
322 if (!(IRP_PAGING_IO & Flags)
323 || (IRP_SYNCHRONOUS_PAGING_IO & Flags))
324 {
325 return(TRUE);
326 }
327
328 /* Otherwise, it is an asynchronous operation. */
329 return(FALSE);
330 }
331
332
333 VOID STDCALL
334 IoEnqueueIrp(IN PIRP Irp)
335 {
336 UNIMPLEMENTED;
337 }
338
339
340 VOID STDCALL
341 IoSetTopLevelIrp(IN PIRP Irp)
342 {
343 PETHREAD Thread;
344
345 Thread = PsGetCurrentThread();
346 Thread->TopLevelIrp->TopLevelIrp = Irp;
347 }
348
349
350 PIRP STDCALL
351 IoGetTopLevelIrp(VOID)
352 {
353 return(PsGetCurrentThread()->TopLevelIrp->TopLevelIrp);
354 }
355
356
357 VOID STDCALL
358 IoQueueThreadIrp(IN PIRP Irp)
359 {
360 UNIMPLEMENTED;
361 }
362
363 /*
364 NTSTATUS
365 STDCALL
366 IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
367 {
368 UNIMPLEMENTED;
369 return 0;
370 }
371
372 NTSTATUS
373 STDCALL
374 IoGetDeviceProperty(
375 IN PDEVICE_OBJECT DeviceObject,
376 IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
377 IN ULONG BufferLength,
378 OUT PVOID PropertyBuffer,
379 OUT PULONG ResultLength)
380 {
381 UNIMPLEMENTED;
382 return 0;
383 }
384
385 NTSTATUS
386 STDCALL
387 IoOpenDeviceRegistryKey(
388 IN PDEVICE_OBJECT DeviceObject,
389 IN ULONG DevInstKeyType,
390 IN ACCESS_MASK DesiredAccess,
391 OUT PHANDLE DevInstRegKey)
392 {
393 UNIMPLEMENTED;
394 return 0;
395 }
396 */
397 /* EOF */