ReactOS 0.4.15-dev-8109-gd7be748
iofunc.c File Reference
#include <ntoskrnl.h>
#include <ioevent.h>
#include <debug.h>
#include "internal/io_i.h"
Include dependency graph for iofunc.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define CHECK_LENGTH(class, struct)
 

Functions

VOID NTAPI IopCleanupAfterException (IN PFILE_OBJECT FileObject, IN PIRP Irp OPTIONAL, IN PKEVENT Event OPTIONAL, IN PKEVENT LocalEvent OPTIONAL)
 
NTSTATUS NTAPI IopFinalizeAsynchronousIo (IN NTSTATUS SynchStatus, IN PKEVENT Event, IN PIRP Irp, IN KPROCESSOR_MODE PreviousMode, IN PIO_STATUS_BLOCK KernelIosb, OUT PIO_STATUS_BLOCK IoStatusBlock)
 
NTSTATUS NTAPI IopPerformSynchronousRequest (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PFILE_OBJECT FileObject, IN BOOLEAN Deferred, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SynchIo, IN IOP_TRANSFER_TYPE TransferType)
 
NTSTATUS NTAPI IopDeviceFsIoControl (IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength OPTIONAL, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength OPTIONAL, IN BOOLEAN IsDevIoCtl)
 
NTSTATUS NTAPI IopQueryDeviceInformation (IN PFILE_OBJECT FileObject, IN ULONG InformationClass, IN ULONG Length, OUT PVOID Information, OUT PULONG ReturnedLength, IN BOOLEAN File)
 
NTSTATUS NTAPI IopGetFileInformation (IN PFILE_OBJECT FileObject, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInfoClass, OUT PVOID Buffer, OUT PULONG ReturnedLength)
 
NTSTATUS NTAPI IopGetBasicInformationFile (IN PFILE_OBJECT FileObject, OUT PFILE_BASIC_INFORMATION BasicInfo)
 
NTSTATUS NTAPI IopOpenLinkOrRenameTarget (OUT PHANDLE Handle, IN PIRP Irp, IN PFILE_RENAME_INFORMATION RenameInfo, IN PFILE_OBJECT FileObject)
 
static ULONG IopGetFileMode (IN PFILE_OBJECT FileObject)
 
static BOOLEAN IopGetMountFlag (IN PDEVICE_OBJECT DeviceObject)
 
static BOOLEAN IopVerifyDriverObjectOnStack (IN PDEVICE_OBJECT DeviceObject, IN PDRIVER_OBJECT DriverObject)
 
static NTSTATUS IopGetDriverPathInformation (IN PFILE_OBJECT FileObject, IN PFILE_FS_DRIVER_PATH_INFORMATION DriverPathInfo, IN ULONG Length)
 
NTSTATUS NTAPI IoSynchronousPageWrite (IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
 
NTSTATUS NTAPI IoPageRead (IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
 
NTSTATUS NTAPI IoQueryFileInformation (IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, OUT PVOID FileInformation, OUT PULONG ReturnedLength)
 
NTSTATUS NTAPI IoQueryVolumeInformation (IN PFILE_OBJECT FileObject, IN FS_INFORMATION_CLASS FsInformationClass, IN ULONG Length, OUT PVOID FsInformation, OUT PULONG ReturnedLength)
 
NTSTATUS NTAPI IoSetInformation (IN PFILE_OBJECT FileObject, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG Length, IN PVOID FileInformation)
 
NTSTATUS NTAPI NtDeviceIoControlFile (IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength OPTIONAL, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength OPTIONAL)
 
NTSTATUS NTAPI NtFsControlFile (IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength OPTIONAL, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength OPTIONAL)
 
NTSTATUS NTAPI NtFlushBuffersFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock)
 
NTSTATUS NTAPI NtNotifyChangeDirectoryFile (IN HANDLE FileHandle, IN HANDLE EventHandle OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG BufferSize, IN ULONG CompletionFilter, IN BOOLEAN WatchTree)
 
NTSTATUS NTAPI NtLockFile (IN HANDLE FileHandle, IN HANDLE EventHandle OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER ByteOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN BOOLEAN FailImmediately, IN BOOLEAN ExclusiveLock)
 
NTSTATUS NTAPI NtQueryDirectoryFile (IN HANDLE FileHandle, IN HANDLE EventHandle OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass, IN BOOLEAN ReturnSingleEntry, IN PUNICODE_STRING FileName OPTIONAL, IN BOOLEAN RestartScan)
 
NTSTATUS NTAPI NtQueryEaFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN BOOLEAN ReturnSingleEntry, IN PVOID EaList OPTIONAL, IN ULONG EaListLength, IN PULONG EaIndex OPTIONAL, IN BOOLEAN RestartScan)
 
NTSTATUS NTAPI NtQueryInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass)
 
NTSTATUS NTAPI NtQueryQuotaInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN BOOLEAN ReturnSingleEntry, IN PVOID SidList OPTIONAL, IN ULONG SidListLength, IN PSID StartSid OPTIONAL, IN BOOLEAN RestartScan)
 
NTSTATUS NTAPI NtReadFile (IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PULONG Key OPTIONAL)
 
NTSTATUS NTAPI NtReadFileScatter (IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK UserIoStatusBlock, IN FILE_SEGMENT_ELEMENT BufferDescription[], IN ULONG BufferLength, IN PLARGE_INTEGER ByteOffset, IN PULONG Key OPTIONAL)
 
NTSTATUS NTAPI NtSetEaFile (IN HANDLE FileHandle, IN PIO_STATUS_BLOCK IoStatusBlock, IN PVOID EaBuffer, IN ULONG EaBufferSize)
 
NTSTATUS NTAPI NtSetInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass)
 
NTSTATUS NTAPI NtSetQuotaInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID Buffer, IN ULONG BufferLength)
 
NTSTATUS NTAPI NtUnlockFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER ByteOffset, IN PLARGE_INTEGER Length, IN ULONG Key OPTIONAL)
 
NTSTATUS NTAPI NtWriteFile (IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PULONG Key OPTIONAL)
 
NTSTATUS NTAPI NtWriteFileGather (IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK UserIoStatusBlock, IN FILE_SEGMENT_ELEMENT BufferDescription[], IN ULONG BufferLength, IN PLARGE_INTEGER ByteOffset, IN PULONG Key OPTIONAL)
 
NTSTATUS NTAPI NtQueryVolumeInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FsInformation, IN ULONG Length, IN FS_INFORMATION_CLASS FsInformationClass)
 
NTSTATUS NTAPI NtSetVolumeInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID FsInformation, IN ULONG Length, IN FS_INFORMATION_CLASS FsInformationClass)
 
NTSTATUS NTAPI NtCancelDeviceWakeupRequest (IN HANDLE DeviceHandle)
 
NTSTATUS NTAPI NtRequestDeviceWakeup (IN HANDLE DeviceHandle)
 

Variables

volatile LONG IoPageReadIrpAllocationFailure = 0
 
volatile LONG IoPageReadNonPagefileIrpAllocationFailure = 0
 

Macro Definition Documentation

◆ CHECK_LENGTH

#define CHECK_LENGTH (   class,
  struct 
)
Value:
case class: \
if (Length < sizeof(struct)) \
break
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file iofunc.c.

Function Documentation

◆ IoPageRead()

NTSTATUS NTAPI IoPageRead ( IN PFILE_OBJECT  FileObject,
IN PMDL  Mdl,
IN PLARGE_INTEGER  Offset,
IN PKEVENT  Event,
IN PIO_STATUS_BLOCK  StatusBlock 
)

Definition at line 1201 of file iofunc.c.

1206{
1207 PIRP Irp;
1208 PIO_STACK_LOCATION StackPtr;
1210 IOTRACE(IO_API_DEBUG, "FileObject: %p. Mdl: %p. Offset: %p\n",
1212
1213 /* Get the Device Object */
1215
1216 /* Allocate IRP */
1217 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1218 /* If allocation failed, try to see whether we can use
1219 * the reserve IRP
1220 */
1221 if (Irp == NULL)
1222 {
1223 /* We will use it only for paging file */
1225 {
1228 }
1229 else
1230 {
1232 }
1233
1234 /* If allocation failed (not a paging file or too big stack size)
1235 * Fail for real
1236 */
1237 if (Irp == NULL)
1238 {
1240 }
1241 }
1242
1243 /* Get the Stack */
1244 StackPtr = IoGetNextIrpStackLocation(Irp);
1245
1246 /* Create the IRP Settings */
1247 Irp->MdlAddress = Mdl;
1248 Irp->UserBuffer = MmGetMdlVirtualAddress(Mdl);
1249 Irp->UserIosb = StatusBlock;
1250 Irp->UserEvent = Event;
1251 Irp->RequestorMode = KernelMode;
1252 Irp->Flags = IRP_PAGING_IO |
1253 IRP_NOCACHE |
1256 Irp->Tail.Overlay.OriginalFileObject = FileObject;
1257 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1258
1259 /* Set the Stack Settings */
1260 StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
1261 StackPtr->Parameters.Read.ByteOffset = *Offset;
1262 StackPtr->MajorFunction = IRP_MJ_READ;
1263 StackPtr->FileObject = FileObject;
1264
1265 /* Call the Driver */
1266 return IoCallDriver(DeviceObject, Irp);
1267}
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define InterlockedExchangeAdd
Definition: interlocked.h:181
volatile LONG IoPageReadIrpAllocationFailure
Definition: iofunc.c:20
volatile LONG IoPageReadNonPagefileIrpAllocationFailure
Definition: iofunc.c:21
#define KernelMode
Definition: asm.h:34
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
PIRP NTAPI IopAllocateReserveIrp(IN CCHAR StackSize)
Definition: irp.c:573
#define IO_API_DEBUG
Definition: io.h:21
#define IOTRACE(x, fmt,...)
Definition: io.h:47
BOOLEAN NTAPI MmIsFileObjectAPagingFile(PFILE_OBJECT FileObject)
Definition: pagefile.c:119
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
#define IRP_MJ_READ
Definition: rdpdr.c:46
struct _IO_STACK_LOCATION::@3983::@3987 Read
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1568 Parameters
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IRP_INPUT_OPERATION
#define IRP_PAGING_IO
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_NOCACHE
#define MmGetMdlByteCount(_Mdl)
#define MmGetMdlVirtualAddress(_Mdl)

Referenced by MiReadFilePage(), MiReadPageFile(), and MmMakeSegmentResident().

◆ IopCleanupAfterException()

VOID NTAPI IopCleanupAfterException ( IN PFILE_OBJECT  FileObject,
IN PIRP Irp  OPTIONAL,
IN PKEVENT Event  OPTIONAL,
IN PKEVENT LocalEvent  OPTIONAL 
)

Definition at line 27 of file iofunc.c.

31{
32 PAGED_CODE();
33 IOTRACE(IO_API_DEBUG, "IRP: %p. FO: %p\n", Irp, FileObject);
34
35 if (Irp)
36 {
37 /* Check if we had a buffer */
38 if (Irp->AssociatedIrp.SystemBuffer)
39 {
40 /* Free it */
41 ExFreePool(Irp->AssociatedIrp.SystemBuffer);
42 }
43
44 /* Free the mdl */
45 if (Irp->MdlAddress) IoFreeMdl(Irp->MdlAddress);
46
47 /* Free the IRP */
49 }
50
51 /* Check if we had a file lock */
52 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
53 {
54 /* Release it */
56 }
57
58 /* Check if we had an event */
60
61 /* Check if we had a local event */
62 if (LocalEvent) ExFreePool(LocalEvent);
63
64 /* Derefenrce the FO */
66}
#define PAGED_CODE()
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IoFreeMdl
Definition: fxmdl.h:89
static __inline VOID IopUnlockFileObject(IN PFILE_OBJECT FileObject)
Definition: io_x.h:36
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by IopDeviceFsIoControl(), NtLockFile(), NtQueryDirectoryFile(), NtQueryInformationFile(), NtQueryVolumeInformationFile(), NtReadFile(), NtSetInformationFile(), NtSetVolumeInformationFile(), NtUnlockFile(), and NtWriteFile().

◆ IopDeviceFsIoControl()

NTSTATUS NTAPI IopDeviceFsIoControl ( IN HANDLE  DeviceHandle,
IN HANDLE Event  OPTIONAL,
IN PIO_APC_ROUTINE UserApcRoutine  OPTIONAL,
IN PVOID UserApcContext  OPTIONAL,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
IN ULONG  IoControlCode,
IN PVOID  InputBuffer,
IN ULONG InputBufferLength  OPTIONAL,
OUT PVOID  OutputBuffer,
IN ULONG OutputBufferLength  OPTIONAL,
IN BOOLEAN  IsDevIoCtl 
)

Definition at line 197 of file iofunc.c.

208{
212 PIRP Irp;
213 PIO_STACK_LOCATION StackPtr;
214 PKEVENT EventObject = NULL;
215 BOOLEAN LockedForSynch = FALSE;
216 ULONG AccessType;
222
223 PAGED_CODE();
224
225 IOTRACE(IO_CTL_DEBUG, "Handle: %p. CTL: %lx. Type: %lx\n",
226 DeviceHandle, IoControlCode, IsDevIoCtl);
227
228 /* Get the access type */
230
231 /* Check if we came from user mode */
233 {
235 {
236 /* Probe the status block */
238
239 /* Check if this is buffered I/O */
240 if (AccessType == METHOD_BUFFERED)
241 {
242 /* Check if we have an output buffer */
243 if (OutputBuffer)
244 {
245 /* Probe the output buffer */
248 sizeof(CHAR));
249 }
250 else
251 {
252 /* Make sure the caller can't fake this as we depend on this */
254 }
255 }
256
257 /* Check if we we have an input buffer I/O */
258 if (AccessType != METHOD_NEITHER)
259 {
260 /* Check if we have an input buffer */
261 if (InputBuffer)
262 {
263 /* Probe the input buffer */
265 }
266 else
267 {
268 /* Make sure the caller can't fake this as we depend on this */
270 }
271 }
272 }
274 {
275 /* Return the exception code */
277 }
278 _SEH2_END;
279 }
280
281 /* Don't check for access rights right now, KernelMode can do anything */
283 0,
286 (PVOID*)&FileObject,
288 if (!NT_SUCCESS(Status)) return Status;
289
290 /* Can't use an I/O completion port and an APC at the same time */
291 if ((FileObject->CompletionContext) && (UserApcRoutine))
292 {
293 /* Fail */
296 }
297
298 /* Check if we from user mode */
300 {
301 /* Get the access mask */
302 DesiredAccess = (ACCESS_MASK)((IoControlCode >> 14) & 3);
303
304 /* Check if we can open it */
306 (HandleInformation.GrantedAccess & DesiredAccess) != DesiredAccess)
307 {
308 /* Dereference the file object and fail */
311 }
312 }
313
314 /* Check for an event */
315 if (Event)
316 {
317 /* Reference it */
322 (PVOID*)&EventObject,
323 NULL);
324 if (!NT_SUCCESS(Status))
325 {
326 /* Dereference the file object and fail */
328 return Status;
329 }
330
331 /* Clear it */
332 KeClearEvent(EventObject);
333 }
334
335 /* Check if this is a file that was opened for Synch I/O */
336 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
337 {
338 /* Lock it */
340 if (Status != STATUS_SUCCESS)
341 {
342 if (EventObject) ObDereferenceObject(EventObject);
344 return Status;
345 }
346
347 /* Remember to unlock later */
348 LockedForSynch = TRUE;
349 }
350
351 /* Check if this is a direct open or not */
353 {
354 /* It's a direct open, get the attached device */
356 }
357 else
358 {
359 /* Otherwise get the related device */
361 }
362
363 /* If this is a device I/O, try to do it with FastIO path */
364 if (IsDevIoCtl)
365 {
366 PFAST_IO_DISPATCH FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
367
368 /* Check whether FSD is FastIO aware and provide an appropriate routine */
370 {
371 IO_STATUS_BLOCK KernelIosb;
372
373 /* If we have an output buffer coming from usermode */
375 {
376 /* Probe it according to its usage */
378 {
379 if (AccessType == METHOD_IN_DIRECT)
380 {
382 }
383 else if (AccessType == METHOD_OUT_DIRECT)
384 {
386 }
387 }
389 {
390 /* Cleanup after exception and return */
392
393 /* Return the exception code */
395 }
396 _SEH2_END;
397 }
398
399 /* If we are dismounting a volume, increase the dismount count */
401 {
402 InterlockedIncrement((PLONG)&SharedUserData->DismountCount);
403 }
404
405 /* Call the FSD */
407 TRUE,
413 &KernelIosb,
415 {
416 IO_COMPLETION_CONTEXT CompletionInfo = { NULL, NULL };
417
418 /* Write the IOSB back */
420 {
421 *IoStatusBlock = KernelIosb;
422
423 }
425 {
426 KernelIosb.Status = _SEH2_GetExceptionCode();
427 }
428 _SEH2_END;
429
430 /* Backup our complete context in case it exists */
431 if (FileObject->CompletionContext)
432 {
433 CompletionInfo = *(FileObject->CompletionContext);
434 }
435
436 /* If we had an event, signal it */
437 if (Event)
438 {
439 KeSetEvent(EventObject, IO_NO_INCREMENT, FALSE);
440 ObDereferenceObject(EventObject);
441 }
442
443 /* If FO was locked, unlock it */
444 if (LockedForSynch)
445 {
447 }
448
449 /* Set completion if required */
450 if (CompletionInfo.Port != NULL && UserApcContext != NULL)
451 {
452 if (!NT_SUCCESS(IoSetIoCompletion(CompletionInfo.Port,
453 CompletionInfo.Key,
454 UserApcContext,
455 KernelIosb.Status,
456 KernelIosb.Information,
457 TRUE)))
458 {
460 }
461 }
462
463 /* We're done with FastIO! */
465 return KernelIosb.Status;
466 }
467 }
468 }
469
470 /* Clear the event */
471 KeClearEvent(&FileObject->Event);
472
473 /* Allocate IRP */
474 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
475 if (!Irp) return IopCleanupFailedIrp(FileObject, EventObject, NULL);
476
477 /* Setup the IRP */
478 Irp->UserIosb = IoStatusBlock;
479 Irp->UserEvent = EventObject;
480 Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
481 Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
482 Irp->Cancel = FALSE;
483 Irp->CancelRoutine = NULL;
484 Irp->PendingReturned = FALSE;
485 Irp->RequestorMode = PreviousMode;
486 Irp->MdlAddress = NULL;
487 Irp->AssociatedIrp.SystemBuffer = NULL;
488 Irp->Flags = 0;
489 Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
490 Irp->Tail.Overlay.OriginalFileObject = FileObject;
491 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
492
493 /* Set stack location settings */
494 StackPtr = IoGetNextIrpStackLocation(Irp);
495 StackPtr->FileObject = FileObject;
496 StackPtr->MajorFunction = IsDevIoCtl ?
499 StackPtr->MinorFunction = 0; /* Minor function 0 is IRP_MN_USER_FS_REQUEST */
500 StackPtr->Control = 0;
501 StackPtr->Flags = 0;
502 StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
503
504 /* Set the IOCTL Data */
505 StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
506 StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
507 StackPtr->Parameters.DeviceIoControl.OutputBufferLength =
509
511
512 /* Handle the Methods */
513 switch (AccessType)
514 {
515 /* Buffered I/O */
516 case METHOD_BUFFERED:
517
518 /* Enter SEH for allocations */
520 {
521 /* Select the right Buffer Length */
524
525 /* Make sure there is one */
526 if (BufferLength)
527 {
528 /* Allocate the System Buffer */
529 Irp->AssociatedIrp.SystemBuffer =
533
534 /* Check if we got a buffer */
535 if (InputBuffer)
536 {
537 /* Copy into the System Buffer */
538 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
541 }
542
543 /* Write the flags */
545 if (OutputBuffer) Irp->Flags |= IRP_INPUT_OPERATION;
546
547 /* Save the Buffer */
548 Irp->UserBuffer = OutputBuffer;
549 }
550 else
551 {
552 /* Clear the Flags and Buffer */
553 Irp->UserBuffer = NULL;
554 }
555 }
557 {
558 /* Cleanup after exception and return */
561 }
562 _SEH2_END;
563 break;
564
565 /* Direct I/O */
566 case METHOD_IN_DIRECT:
568
569 /* Enter SEH */
571 {
572 /* Check if we got an input buffer */
574 {
575 /* Allocate the System Buffer */
576 Irp->AssociatedIrp.SystemBuffer =
580
581 /* Copy into the System Buffer */
582 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
585
586 /* Write the flags */
588 }
589
590 /* Check if we got an output buffer */
592 {
593 /* Allocate the System Buffer */
594 Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
596 FALSE,
597 FALSE,
598 Irp);
599 if (!Irp->MdlAddress)
600 {
601 /* Raise exception we'll catch */
603 }
604
605 /* Do the probe */
606 MmProbeAndLockPages(Irp->MdlAddress,
608 (AccessType == METHOD_IN_DIRECT) ?
610 }
611 }
613 {
614 /* Cleanup after exception and return */
617 }
618 _SEH2_END;
619 break;
620
621 case METHOD_NEITHER:
622
623 /* Just save the Buffer */
624 Irp->UserBuffer = OutputBuffer;
625 StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
626 }
627
628 /* Use deferred completion for FS I/O */
629 if (!IsDevIoCtl)
630 {
632 }
633
634 /* If we are dismounting a volume, increaase the dismount count */
636 {
637 InterlockedIncrement((PLONG)&SharedUserData->DismountCount);
638 }
639
640 /* Perform the call */
642 Irp,
644 !IsDevIoCtl,
646 LockedForSynch,
648}
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define NonPagedPoolCacheAligned
Definition: env_spec_w32.h:310
#define NonPagedPool
Definition: env_spec_w32.h:307
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define ExGetPreviousMode
Definition: ex.h:140
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define IoAllocateMdl
Definition: fxmdl.h:88
Status
Definition: gdiplustypes.h:25
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
static __inline NTSTATUS IopLockFileObject(_In_ PFILE_OBJECT FileObject, _In_ KPROCESSOR_MODE WaitMode)
Definition: io_x.h:12
NTSTATUS NTAPI IopPerformSynchronousRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PFILE_OBJECT FileObject, IN BOOLEAN Deferred, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SynchIo, IN IOP_TRANSFER_TYPE TransferType)
Definition: iofunc.c:119
VOID NTAPI IopCleanupAfterException(IN PFILE_OBJECT FileObject, IN PIRP Irp OPTIONAL, IN PKEVENT Event OPTIONAL, IN PKEVENT LocalEvent OPTIONAL)
Definition: iofunc.c:27
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define IO_METHOD_FROM_CTL_CODE(C)
Definition: mup.h:11
#define METHOD_NEITHER
Definition: nt_native.h:597
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define METHOD_OUT_DIRECT
Definition: nt_native.h:596
#define FILE_ANY_ACCESS
Definition: nt_native.h:609
#define METHOD_BUFFERED
Definition: nt_native.h:594
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
#define METHOD_IN_DIRECT
Definition: nt_native.h:595
POBJECT_TYPE ExEventObjectType
Definition: event.c:18
NTSTATUS NTAPI IopCleanupFailedIrp(IN PFILE_OBJECT FileObject, IN PKEVENT EventObject, IN PVOID Buffer OPTIONAL)
Definition: irp.c:45
@ IopOtherTransfer
Definition: io.h:263
NTSTATUS NTAPI IoSetIoCompletion(IN PVOID IoCompletion, IN PVOID KeyContext, IN PVOID ApcContext, IN NTSTATUS IoStatus, IN ULONG_PTR IoStatusInformation, IN BOOLEAN Quota)
Definition: iocomp.c:147
#define IO_CTL_DEBUG
Definition: io.h:22
#define ExRaiseStatus
Definition: ntoskrnl.h:114
PDEVICE_OBJECT NTAPI IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1385
FAST_IO_DISPATCH FastIoDispatch
Definition: null.c:15
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define ProbeForWriteIoStatusBlock(Ptr)
Definition: probe.h:52
#define SharedUserData
#define STATUS_SUCCESS
Definition: shellext.h:65
PFAST_IO_DEVICE_CONTROL FastIoDeviceControl
Definition: iotypes.h:1743
struct _IO_STACK_LOCATION::@1568::@1569 DeviceIoControl
#define TAG_SYS_BUF
Definition: tag.h:87
INT POOL_TYPE
Definition: typedefs.h:78
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
#define EVENT_MODIFY_STATE
Definition: winbase.h:163
#define ExAllocatePoolWithQuotaTag(a, b, c)
Definition: exfuncs.h:530
#define IRP_DEALLOCATE_BUFFER
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_DEFER_IO_COMPLETION
#define FO_DIRECT_DEVICE_OPEN
Definition: iotypes.h:1787
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_BUFFERED_IO
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
@ IoReadAccess
Definition: ketypes.h:863
@ IoWriteAccess
Definition: ketypes.h:864
_In_ ACCESS_MASK _In_opt_ POBJECT_TYPE _In_ KPROCESSOR_MODE _Out_ PVOID _Out_opt_ POBJECT_HANDLE_INFORMATION HandleInformation
Definition: obfuncs.h:44
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
char CHAR
Definition: xmlstorage.h:175

Referenced by NtDeviceIoControlFile(), and NtFsControlFile().

◆ IopFinalizeAsynchronousIo()

NTSTATUS NTAPI IopFinalizeAsynchronousIo ( IN NTSTATUS  SynchStatus,
IN PKEVENT  Event,
IN PIRP  Irp,
IN KPROCESSOR_MODE  PreviousMode,
IN PIO_STATUS_BLOCK  KernelIosb,
OUT PIO_STATUS_BLOCK  IoStatusBlock 
)

Definition at line 70 of file iofunc.c.

76{
77 NTSTATUS FinalStatus = SynchStatus;
78 PAGED_CODE();
79 IOTRACE(IO_API_DEBUG, "IRP: %p. Status: %lx\n", Irp, SynchStatus);
80
81 /* Make sure the IRP was completed, but returned pending */
82 if (FinalStatus == STATUS_PENDING)
83 {
84 /* Wait for the IRP */
85 FinalStatus = KeWaitForSingleObject(Event,
88 FALSE,
89 NULL);
90 if (FinalStatus == STATUS_USER_APC)
91 {
92 /* Abort the request */
94 }
95
96 /* Set the final status */
97 FinalStatus = KernelIosb->Status;
98 }
99
100 /* Wrap potential user-mode write in SEH */
102 {
103 *IoStatusBlock = *KernelIosb;
104 }
106 {
107 /* Get the exception code */
108 FinalStatus = _SEH2_GetExceptionCode();
109 }
110 _SEH2_END;
111
112 /* Free the event and return status */
114 return FinalStatus;
115}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
VOID NTAPI IopAbortInterruptedIrp(IN PKEVENT EventObject, IN PIRP Irp)
Definition: irp.c:67
#define STATUS_USER_APC
Definition: ntstatus.h:78
#define STATUS_PENDING
Definition: ntstatus.h:82
@ Executive
Definition: ketypes.h:415

Referenced by NtFlushBuffersFile(), NtQueryVolumeInformationFile(), NtSetVolumeInformationFile(), and NtUnlockFile().

◆ IopGetBasicInformationFile()

NTSTATUS NTAPI IopGetBasicInformationFile ( IN PFILE_OBJECT  FileObject,
OUT PFILE_BASIC_INFORMATION  BasicInfo 
)

Definition at line 839 of file iofunc.c.

841{
845
846 PAGED_CODE();
847
848 /* Try to do it the fast way if possible */
850 if (DeviceObject->DriverObject->FastIoDispatch != NULL &&
851 DeviceObject->DriverObject->FastIoDispatch->FastIoQueryBasicInfo != NULL &&
852 DeviceObject->DriverObject->FastIoDispatch->FastIoQueryBasicInfo(FileObject,
853 ((FileObject->Flags & FO_SYNCHRONOUS_IO) != 0),
854 BasicInfo,
857 {
858 return IoStatusBlock.Status;
859 }
860
861 /* In case it failed, fall back to IRP-based method */
863}
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
@ FileBasicInformation
Definition: from_kernel.h:65
NTSTATUS NTAPI IopGetFileInformation(IN PFILE_OBJECT FileObject, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInfoClass, OUT PVOID Buffer, OUT PULONG ReturnedLength)
Definition: iofunc.c:777

Referenced by IopOpenLinkOrRenameTarget().

◆ IopGetDriverPathInformation()

static NTSTATUS IopGetDriverPathInformation ( IN PFILE_OBJECT  FileObject,
IN PFILE_FS_DRIVER_PATH_INFORMATION  DriverPathInfo,
IN ULONG  Length 
)
static

Definition at line 1084 of file iofunc.c.

1087{
1088 KIRQL OldIrql;
1090 UNICODE_STRING DriverName;
1092
1093 /* Make sure the structure is consistent (ie, driver name fits into the buffer) */
1094 if (Length - FIELD_OFFSET(FILE_FS_DRIVER_PATH_INFORMATION, DriverName) < DriverPathInfo->DriverNameLength)
1095 {
1097 }
1098
1099 /* Setup the whole driver name */
1100 DriverName.Length = DriverPathInfo->DriverNameLength;
1101 DriverName.MaximumLength = DriverPathInfo->DriverNameLength;
1102 DriverName.Buffer = &DriverPathInfo->DriverName[0];
1103
1104 /* Ask Ob for such driver */
1105 Status = ObReferenceObjectByName(&DriverName,
1107 NULL,
1108 0,
1110 KernelMode,
1111 NULL,
1112 (PVOID*)&DriverObject);
1113 /* No such driver, bail out */
1114 if (!NT_SUCCESS(Status))
1115 {
1116 return Status;
1117 }
1118
1119 /* Lock the devices database, we'll browse it */
1121 /* If we have a VPB, browse the stack from the volume */
1122 if (FileObject->Vpb != NULL && FileObject->Vpb->DeviceObject != NULL)
1123 {
1124 DriverPathInfo->DriverInPath = IopVerifyDriverObjectOnStack(FileObject->Vpb->DeviceObject, DriverObject);
1125 }
1126 /* Otherwise, do it from the normal device */
1127 else
1128 {
1129 DriverPathInfo->DriverInPath = IopVerifyDriverObjectOnStack(FileObject->DeviceObject, DriverObject);
1130 }
1132
1133 /* No longer needed */
1135
1136 return STATUS_SUCCESS;
1137}
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static BOOLEAN IopVerifyDriverObjectOnStack(IN PDEVICE_OBJECT DeviceObject, IN PDRIVER_OBJECT DriverObject)
Definition: iofunc.c:1059
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:34
NTSTATUS NTAPI ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, OUT PVOID *ObjectPtr)
Definition: obref.c:409
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ LockQueueIoDatabaseLock
Definition: ketypes.h:668

Referenced by NtQueryVolumeInformationFile().

◆ IopGetFileInformation()

NTSTATUS NTAPI IopGetFileInformation ( IN PFILE_OBJECT  FileObject,
IN ULONG  Length,
IN FILE_INFORMATION_CLASS  FileInfoClass,
OUT PVOID  Buffer,
OUT PULONG  ReturnedLength 
)

Definition at line 777 of file iofunc.c.

782{
783 PIRP Irp;
789
790 PAGED_CODE();
791
792 /* Allocate an IRP */
795 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
796 if (Irp == NULL)
797 {
800 }
801
802 /* Init event */
804
805 /* Setup the IRP */
806 Irp->UserIosb = &IoStatusBlock;
807 Irp->UserEvent = &Event;
808 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
809 Irp->RequestorMode = KernelMode;
810 Irp->AssociatedIrp.SystemBuffer = Buffer;
812 Irp->Tail.Overlay.OriginalFileObject = FileObject;
813 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
814
816 Stack->MajorFunction = IRP_MJ_QUERY_INFORMATION;
817 Stack->FileObject = FileObject;
818 Stack->Parameters.QueryFile.FileInformationClass = FileInfoClass;
819 Stack->Parameters.QueryFile.Length = Length;
820
821
822 /* Queue the IRP */
824
825 /* Call the driver */
827 if (Status == STATUS_PENDING)
828 {
831 }
832
834 return Status;
835}
Definition: bufpool.h:45
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
FORCEINLINE VOID IopQueueIrpToThread(IN PIRP Irp)
Definition: io_x.h:49
@ SynchronizationEvent
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define IRP_SYNCHRONOUS_API
#define IRP_OB_QUERY_NAME
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by IopGetBasicInformationFile(), and IopQueryNameInternal().

◆ IopGetFileMode()

static ULONG IopGetFileMode ( IN PFILE_OBJECT  FileObject)
static

Definition at line 1004 of file iofunc.c.

1005{
1006 ULONG Mode = 0;
1007
1008 if (FileObject->Flags & FO_WRITE_THROUGH)
1010
1011 if (FileObject->Flags & FO_SEQUENTIAL_ONLY)
1013
1016
1017 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1018 {
1019 if (FileObject->Flags & FO_ALERTABLE_IO)
1021 else
1023 }
1024
1025 if (FileObject->Flags & FO_DELETE_ON_CLOSE)
1027
1028 return Mode;
1029}
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
_In_ ULONG Mode
Definition: hubbusif.h:303
#define FO_SEQUENTIAL_ONLY
Definition: iotypes.h:1780
#define FO_ALERTABLE_IO
Definition: iotypes.h:1777
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1778
#define FO_DELETE_ON_CLOSE
Definition: iotypes.h:1792

Referenced by NtQueryInformationFile().

◆ IopGetMountFlag()

static BOOLEAN IopGetMountFlag ( IN PDEVICE_OBJECT  DeviceObject)
static

Definition at line 1033 of file iofunc.c.

1034{
1035 KIRQL OldIrql;
1036 PVPB Vpb;
1037 BOOLEAN Mounted;
1038
1039 /* Assume not mounted */
1040 Mounted = FALSE;
1041
1042 /* Check whether we have the mount flag */
1044
1045 Vpb = DeviceObject->Vpb;
1046 if (Vpb != NULL &&
1047 BooleanFlagOn(Vpb->Flags, VPB_MOUNTED))
1048 {
1049 Mounted = TRUE;
1050 }
1051
1053
1054 return Mounted;
1055}
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
PVPB Vpb
Definition: cdstruc.h:511
Definition: iotypes.h:189
#define VPB_MOUNTED
Definition: iotypes.h:1807

Referenced by NtQueryVolumeInformationFile().

◆ IopOpenLinkOrRenameTarget()

NTSTATUS NTAPI IopOpenLinkOrRenameTarget ( OUT PHANDLE  Handle,
IN PIRP  Irp,
IN PFILE_RENAME_INFORMATION  RenameInfo,
IN PFILE_OBJECT  FileObject 
)

Definition at line 867 of file iofunc.c.

871{
876 PFILE_OBJECT TargetFileObject;
878 FILE_BASIC_INFORMATION BasicInfo;
882
883 PAGED_CODE();
884
885 /* First, establish whether our target is a directory */
886 if (!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN))
887 {
889 if (!NT_SUCCESS(Status))
890 {
891 return Status;
892 }
893
896 }
897 }
898
899 /* Setup the string to the target */
900 FileName.Buffer = RenameInfo->FileName;
901 FileName.Length = RenameInfo->FileNameLength;
902 FileName.MaximumLength = RenameInfo->FileNameLength;
903
905 &FileName,
907 RenameInfo->RootDirectory,
908 NULL);
909
910 /* And open its parent directory
911 * Use hint if specified
912 */
914 {
915 PFILE_OBJECT_EXTENSION FileObjectExtension;
916
918
919 FileObjectExtension = FileObject->FileObjectExtension;
924 NULL,
925 0,
927 FILE_OPEN,
929 NULL,
930 0,
932 NULL,
934 FileObjectExtension->TopDeviceObjectHint);
935 }
936 else
937 {
942 NULL,
943 0,
945 FILE_OPEN,
947 NULL,
948 0,
950 NULL,
952 }
953
954 if (!NT_SUCCESS(Status))
955 {
956 return Status;
957 }
958
959 /* Once open, continue only if:
960 * Target exists and we're allowed to overwrite it
961 */
963 if (Stack->Parameters.SetFile.FileInformationClass == FileLinkInformation &&
964 !RenameInfo->ReplaceIfExists &&
966 {
969 }
970
971 /* Now, we'll get the associated device of the target, to check for same device location
972 * So, get the FO first
973 */
978 (PVOID *)&TargetFileObject,
980 if (!NT_SUCCESS(Status))
981 {
983 return Status;
984 }
985
986 /* We can dereference, we have the handle */
987 ObDereferenceObject(TargetFileObject);
988 /* If we're not on the same device, error out **/
990 {
993 }
994
995 /* Return parent directory file object and handle */
996 Stack->Parameters.SetFile.FileObject = TargetFileObject;
998
999 return STATUS_SUCCESS;
1000}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FILE_SHARE_READ
Definition: compat.h:136
struct _FileName FileName
Definition: fatprocs.h:896
@ FileLinkInformation
Definition: from_kernel.h:72
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
ULONG Handle
Definition: gdb_input.c:15
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSTATUS NTAPI IopGetBasicInformationFile(IN PFILE_OBJECT FileObject, OUT PFILE_BASIC_INFORMATION BasicInfo)
Definition: iofunc.c:839
#define ASSERT(a)
Definition: mode.c:44
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define FO_FILE_OBJECT_HAS_EXTENSION
Definition: iotypes.h:144
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:431
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_EXISTS
Definition: nt_native.h:772
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
NTSTATUS NTAPI IoCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options)
Definition: file.c:3010
NTSTATUS NTAPI IoCreateFileSpecifyDeviceObjectHint(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options, IN PVOID DeviceObject)
Definition: file.c:3050
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
PDEVICE_OBJECT TopDeviceObjectHint
Definition: io.h:102
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define IO_FORCE_ACCESS_CHECK
Definition: iotypes.h:540
#define IO_OPEN_TARGET_DIRECTORY
Definition: iotypes.h:7352
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:541
#define FO_OPENED_CASE_SENSITIVE
Definition: iotypes.h:1793
@ CreateFileTypeNone
Definition: iotypes.h:535

Referenced by NtSetInformationFile().

◆ IopPerformSynchronousRequest()

NTSTATUS NTAPI IopPerformSynchronousRequest ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PFILE_OBJECT  FileObject,
IN BOOLEAN  Deferred,
IN KPROCESSOR_MODE  PreviousMode,
IN BOOLEAN  SynchIo,
IN IOP_TRANSFER_TYPE  TransferType 
)

Definition at line 119 of file iofunc.c.

126{
128 PKNORMAL_ROUTINE NormalRoutine;
129 PVOID NormalContext = NULL;
131 PAGED_CODE();
132 IOTRACE(IO_API_DEBUG, "IRP: %p. DO: %p. FO: %p\n",
134
135 /* Queue the IRP */
137
138 /* Update operation counts */
139 IopUpdateOperationCount(TransferType);
140
141 /* Call the driver */
143
144 /* Check if we're optimizing this case */
145 if (Deferred)
146 {
147 /* We are! Check if the IRP wasn't completed */
148 if (Status != STATUS_PENDING)
149 {
150 /* Complete it ourselves */
151 NormalRoutine = NULL;
152 NormalContext = NULL;
153 ASSERT(!Irp->PendingReturned);
155 IopCompleteRequest(&Irp->Tail.Apc,
156 &NormalRoutine,
157 &NormalContext,
158 (PVOID*)&FileObject,
159 &NormalContext);
161 }
162 }
163
164 /* Check if this was synch I/O */
165 if (SynchIo)
166 {
167 /* Make sure the IRP was completed, but returned pending */
168 if (Status == STATUS_PENDING)
169 {
170 /* Wait for the IRP */
172 Executive,
174 (FileObject->Flags &
175 FO_ALERTABLE_IO) != 0,
176 NULL);
178 {
179 /* Abort the request */
181 }
182
183 /* Set the final status */
184 Status = FileObject->FinalStatus;
185 }
186
187 /* Release the file lock */
189 }
190
191 /* Return status */
192 return Status;
193}
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
static __inline VOID IopUpdateOperationCount(IN IOP_TRANSFER_TYPE Type)
Definition: io_x.h:82
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:744
VOID NTAPI IopCompleteRequest(IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
Definition: irp.c:238
#define STATUS_ALERTED
Definition: ntstatus.h:80

Referenced by IopDeviceFsIoControl(), NtFlushBuffersFile(), NtLockFile(), NtNotifyChangeDirectoryFile(), NtQueryDirectoryFile(), NtQueryVolumeInformationFile(), NtReadFile(), NtSetVolumeInformationFile(), NtUnlockFile(), and NtWriteFile().

◆ IopQueryDeviceInformation()

NTSTATUS NTAPI IopQueryDeviceInformation ( IN PFILE_OBJECT  FileObject,
IN ULONG  InformationClass,
IN ULONG  Length,
OUT PVOID  Information,
OUT PULONG  ReturnedLength,
IN BOOLEAN  File 
)

Definition at line 652 of file iofunc.c.

658{
660 PIRP Irp;
662 PIO_STACK_LOCATION StackPtr;
663 BOOLEAN LocalEvent = FALSE;
666 PAGED_CODE();
667 IOTRACE(IO_API_DEBUG, "Handle: %p. CTL: %lx. Type: %lx\n",
669
670 /* Reference the object */
672
673 /* Check if this is a file that was opened for Synch I/O */
674 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
675 {
676 /* Lock it */
678
679 /* Use File Object event */
680 KeClearEvent(&FileObject->Event);
681 }
682 else
683 {
684 /* Use local event */
686 LocalEvent = TRUE;
687 }
688
689 /* Get the Device Object */
691
692 /* Allocate the IRP */
693 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
695
696 /* Set the IRP */
697 Irp->Tail.Overlay.OriginalFileObject = FileObject;
698 Irp->RequestorMode = KernelMode;
699 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
700 Irp->UserIosb = &IoStatusBlock;
701 Irp->UserEvent = (LocalEvent) ? &Event : NULL;
702 Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
703 Irp->Flags |= IRP_BUFFERED_IO;
704 Irp->AssociatedIrp.SystemBuffer = Information;
705 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
706
707 /* Set the Stack Data */
708 StackPtr = IoGetNextIrpStackLocation(Irp);
711 StackPtr->FileObject = FileObject;
712
713 /* Check which type this is */
714 if (File)
715 {
716 /* Set Parameters */
717 StackPtr->Parameters.QueryFile.FileInformationClass = InformationClass;
718 StackPtr->Parameters.QueryFile.Length = Length;
719 }
720 else
721 {
722 /* Set Parameters */
723 StackPtr->Parameters.QueryVolume.FsInformationClass = InformationClass;
724 StackPtr->Parameters.QueryVolume.Length = Length;
725 }
726
727 /* Queue the IRP */
729
730 /* Call the Driver */
732
733 /* Check if this was synch I/O */
734 if (!LocalEvent)
735 {
736 /* Check if the request is pending */
737 if (Status == STATUS_PENDING)
738 {
739 /* Wait on the file object */
741 Executive,
743 (FileObject->Flags &
744 FO_ALERTABLE_IO) != 0,
745 NULL);
746 if (Status == STATUS_ALERTED)
747 {
748 /* Abort the operation */
750 }
751
752 /* Get the final status */
753 Status = FileObject->FinalStatus;
754 }
755
756 /* Release the file lock */
758 }
759 else if (Status == STATUS_PENDING)
760 {
761 /* Wait on the local event and get the final status */
763 Executive,
765 FALSE,
766 NULL);
768 }
769
770 /* Return the Length and Status. ReturnedLength is NOT optional */
772 return Status;
773}
Definition: File.h:16
_In_ FILTER_INFORMATION_CLASS InformationClass
Definition: fltkernel.h:1713
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
struct _IO_STACK_LOCATION::@3983::@3996 QueryVolume
struct _IO_STACK_LOCATION::@3983::@3992 QueryFile
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049

Referenced by IoQueryFileInformation(), and IoQueryVolumeInformation().

◆ IopVerifyDriverObjectOnStack()

static BOOLEAN IopVerifyDriverObjectOnStack ( IN PDEVICE_OBJECT  DeviceObject,
IN PDRIVER_OBJECT  DriverObject 
)
static

Definition at line 1059 of file iofunc.c.

1061{
1062 PDEVICE_OBJECT StackDO;
1063
1064 /* Browse our whole device stack, trying to find the appropriate driver */
1066 while (StackDO != NULL)
1067 {
1068 /* We've found the driver, return success */
1069 if (StackDO->DriverObject == DriverObject)
1070 {
1071 return TRUE;
1072 }
1073
1074 /* Move to the next */
1075 StackDO = StackDO->AttachedDevice;
1076 }
1077
1078 /* We only reach there if driver was not found */
1079 return FALSE;
1080}
PDEVICE_OBJECT NTAPI IopGetDeviceAttachmentBase(IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:1486

Referenced by IopGetDriverPathInformation().

◆ IoQueryFileInformation()

NTSTATUS NTAPI IoQueryFileInformation ( IN PFILE_OBJECT  FileObject,
IN FILE_INFORMATION_CLASS  FileInformationClass,
IN ULONG  Length,
OUT PVOID  FileInformation,
OUT PULONG  ReturnedLength 
)

Definition at line 1274 of file iofunc.c.

1279{
1280 /* Call the shared routine */
1283 Length,
1286 TRUE);
1287}
NTSTATUS NTAPI IopQueryDeviceInformation(IN PFILE_OBJECT FileObject, IN ULONG InformationClass, IN ULONG Length, OUT PVOID Information, OUT PULONG ReturnedLength, IN BOOLEAN File)
Definition: iofunc.c:652
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75

Referenced by IopParseDevice(), and IopQueryNameInternal().

◆ IoQueryVolumeInformation()

NTSTATUS NTAPI IoQueryVolumeInformation ( IN PFILE_OBJECT  FileObject,
IN FS_INFORMATION_CLASS  FsInformationClass,
IN ULONG  Length,
OUT PVOID  FsInformation,
OUT PULONG  ReturnedLength 
)

Definition at line 1294 of file iofunc.c.

1299{
1300 /* Call the shared routine */
1303 Length,
1304 FsInformation,
1306 FALSE);
1307}
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FS_INFORMATION_CLASS FsInformationClass
Definition: fltkernel.h:1330

Referenced by NtCreatePagingFile().

◆ IoSetInformation()

NTSTATUS NTAPI IoSetInformation ( IN PFILE_OBJECT  FileObject,
IN FILE_INFORMATION_CLASS  FileInformationClass,
IN ULONG  Length,
IN PVOID  FileInformation 
)

Definition at line 1314 of file iofunc.c.

1318{
1320 PIRP Irp;
1322 PIO_STACK_LOCATION StackPtr;
1323 BOOLEAN LocalEvent = FALSE;
1324 KEVENT Event;
1326 PAGED_CODE();
1327 IOTRACE(IO_API_DEBUG, "FileObject: %p. Class: %lx. Length: %lx\n",
1329
1330 /* Reference the object */
1332
1333 /* Check if this is a file that was opened for Synch I/O */
1334 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1335 {
1336 /* Lock it */
1338
1339 /* Use File Object event */
1340 KeClearEvent(&FileObject->Event);
1341 }
1342 else
1343 {
1344 /* Use local event */
1346 LocalEvent = TRUE;
1347 }
1348
1349 /* Get the Device Object */
1351
1352 /* Allocate the IRP */
1353 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1354 if (!Irp) return IopCleanupFailedIrp(FileObject, NULL, NULL);
1355
1356 /* Set the IRP */
1357 Irp->Tail.Overlay.OriginalFileObject = FileObject;
1358 Irp->RequestorMode = KernelMode;
1359 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
1360 Irp->UserIosb = &IoStatusBlock;
1361 Irp->UserEvent = (LocalEvent) ? &Event : NULL;
1362 Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
1363 Irp->Flags |= IRP_BUFFERED_IO;
1364 Irp->AssociatedIrp.SystemBuffer = FileInformation;
1365 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1366
1367 /* Set the Stack Data */
1368 StackPtr = IoGetNextIrpStackLocation(Irp);
1370 StackPtr->FileObject = FileObject;
1371
1372 /* Set Parameters */
1373 StackPtr->Parameters.SetFile.FileInformationClass = FileInformationClass;
1374 StackPtr->Parameters.SetFile.Length = Length;
1375
1376 /* Queue the IRP */
1378
1379 /* Call the Driver */
1381
1382 /* Check if this was synch I/O */
1383 if (!LocalEvent)
1384 {
1385 /* Check if the request is pending */
1386 if (Status == STATUS_PENDING)
1387 {
1388 /* Wait on the file object */
1390 Executive,
1391 KernelMode,
1392 (FileObject->Flags &
1393 FO_ALERTABLE_IO) != 0,
1394 NULL);
1395 if (Status == STATUS_ALERTED)
1396 {
1397 /* Abort the operation */
1399 }
1400
1401 /* Get the final status */
1402 Status = FileObject->FinalStatus;
1403 }
1404
1405 /* Release the file lock */
1407 }
1408 else if (Status == STATUS_PENDING)
1409 {
1410 /* Wait on the local event and get the final status */
1412 Executive,
1413 KernelMode,
1414 FALSE,
1415 NULL);
1417 }
1418
1419 /* Return the status */
1420 return Status;
1421}
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
struct _IO_STACK_LOCATION::@3983::@3993 SetFile

Referenced by MmCreateDataFileSection().

◆ IoSynchronousPageWrite()

NTSTATUS NTAPI IoSynchronousPageWrite ( IN PFILE_OBJECT  FileObject,
IN PMDL  Mdl,
IN PLARGE_INTEGER  Offset,
IN PKEVENT  Event,
IN PIO_STATUS_BLOCK  StatusBlock 
)

Definition at line 1146 of file iofunc.c.

1151{
1152 PIRP Irp;
1153 PIO_STACK_LOCATION StackPtr;
1155 IOTRACE(IO_API_DEBUG, "FileObject: %p. Mdl: %p. Offset: %p\n",
1157
1158 /* Is the write originating from Cc? */
1159 if (FileObject->SectionObjectPointer != NULL &&
1160 FileObject->SectionObjectPointer->SharedCacheMap != NULL)
1161 {
1162 ++CcDataFlushes;
1164 }
1165
1166 /* Get the Device Object */
1168
1169 /* Allocate IRP */
1170 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1172
1173 /* Get the Stack */
1174 StackPtr = IoGetNextIrpStackLocation(Irp);
1175
1176 /* Create the IRP Settings */
1177 Irp->MdlAddress = Mdl;
1178 Irp->UserBuffer = MmGetMdlVirtualAddress(Mdl);
1179 Irp->UserIosb = StatusBlock;
1180 Irp->UserEvent = Event;
1181 Irp->RequestorMode = KernelMode;
1183 Irp->Tail.Overlay.OriginalFileObject = FileObject;
1184 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1185
1186 /* Set the Stack Settings */
1187 StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);
1188 StackPtr->Parameters.Write.ByteOffset = *Offset;
1189 StackPtr->MajorFunction = IRP_MJ_WRITE;
1190 StackPtr->FileObject = FileObject;
1191
1192 /* Call the Driver */
1193 return IoCallDriver(DeviceObject, Irp);
1194}
ULONG CcDataPages
Definition: copy.c:43
ULONG CcDataFlushes
Definition: copy.c:44
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
struct _IO_STACK_LOCATION::@3983::@3988 Write
#define BYTES_TO_PAGES(Size)

Referenced by CcZeroData(), MiWritePage(), and MmWriteToSwapPage().

◆ NtCancelDeviceWakeupRequest()

NTSTATUS NTAPI NtCancelDeviceWakeupRequest ( IN HANDLE  DeviceHandle)

Definition at line 4631 of file iofunc.c.

4632{
4635}
#define UNIMPLEMENTED
Definition: debug.h:118
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

Referenced by CancelDeviceWakeupRequest().

◆ NtDeviceIoControlFile()

NTSTATUS NTAPI NtDeviceIoControlFile ( IN HANDLE  DeviceHandle,
IN HANDLE Event  OPTIONAL,
IN PIO_APC_ROUTINE UserApcRoutine  OPTIONAL,
IN PVOID UserApcContext  OPTIONAL,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
IN ULONG  IoControlCode,
IN PVOID  InputBuffer,
IN ULONG InputBufferLength  OPTIONAL,
OUT PVOID  OutputBuffer,
IN ULONG OutputBufferLength  OPTIONAL 
)

Definition at line 1430 of file iofunc.c.

1440{
1441 /* Call the Generic Function */
1443 Event,
1444 UserApcRoutine,
1445 UserApcContext,
1452 TRUE);
1453}
NTSTATUS NTAPI IopDeviceFsIoControl(IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength OPTIONAL, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength OPTIONAL, IN BOOLEAN IsDevIoCtl)
Definition: iofunc.c:197

◆ NtFlushBuffersFile()

NTSTATUS NTAPI NtFlushBuffersFile ( IN HANDLE  FileHandle,
OUT PIO_STATUS_BLOCK  IoStatusBlock 
)

Definition at line 1487 of file iofunc.c.

1489{
1491 PIRP Irp;
1492 PIO_STACK_LOCATION StackPtr;
1495 PKEVENT Event = NULL;
1496 BOOLEAN LocalEvent = FALSE;
1497 OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
1499 IO_STATUS_BLOCK KernelIosb;
1500 PAGED_CODE();
1501 IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
1502
1503 if (PreviousMode != KernelMode)
1504 {
1505 /* Protect probes */
1506 _SEH2_TRY
1507 {
1508 /* Probe the I/O Status block */
1510 }
1512 {
1513 /* Return the exception code */
1515 }
1516 _SEH2_END;
1517 }
1518
1519 /* Get the File Object */
1521 0,
1524 (PVOID*)&FileObject,
1525 &ObjectHandleInfo);
1526 if (!NT_SUCCESS(Status)) return Status;
1527
1528 /*
1529 * Check if the handle has either FILE_WRITE_DATA or FILE_APPEND_DATA was
1530 * granted. However, if this is a named pipe, make sure we don't ask for
1531 * FILE_APPEND_DATA as it interferes with the FILE_CREATE_PIPE_INSTANCE
1532 * access right!
1533 */
1534 if (!(ObjectHandleInfo.GrantedAccess &
1535 ((!(FileObject->Flags & FO_NAMED_PIPE) ? FILE_APPEND_DATA : 0) |
1537 {
1538 /* We failed */
1540 return STATUS_ACCESS_DENIED;
1541 }
1542
1543 /* Check if we should use Sync IO or not */
1544 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1545 {
1546 /* Lock it */
1548 if (Status != STATUS_SUCCESS)
1549 {
1551 return Status;
1552 }
1553 }
1554 else
1555 {
1556 /* Use local event */
1558 if (!Event)
1559 {
1560 /* We failed */
1563 }
1565 LocalEvent = TRUE;
1566 }
1567
1568 /* Get the Device Object */
1570
1571 /* Clear the event */
1572 KeClearEvent(&FileObject->Event);
1573
1574 /* Allocate the IRP */
1575 Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
1577
1578 /* Set up the IRP */
1579 Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
1580 Irp->UserIosb = (LocalEvent) ? &KernelIosb : IoStatusBlock;
1581 Irp->UserEvent = (LocalEvent) ? Event : NULL;
1582 Irp->RequestorMode = PreviousMode;
1583 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1584 Irp->Tail.Overlay.OriginalFileObject = FileObject;
1585 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
1586
1587 /* Set up Stack Data */
1588 StackPtr = IoGetNextIrpStackLocation(Irp);
1590 StackPtr->FileObject = FileObject;
1591
1592 /* Call the Driver */
1594 Irp,
1595 FileObject,
1596 FALSE,
1598 !LocalEvent,
1600
1601 /* Check if this was async I/O */
1602 if (LocalEvent)
1603 {
1604 /* It was, finalize this request */
1606 Event,
1607 Irp,
1609 &KernelIosb,
1611 }
1612
1613 /* Return the Status */
1614 return Status;
1615}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
NTSTATUS NTAPI IopFinalizeAsynchronousIo(IN NTSTATUS SynchStatus, IN PKEVENT Event, IN PIRP Irp, IN KPROCESSOR_MODE PreviousMode, IN PIO_STATUS_BLOCK KernelIosb, OUT PIO_STATUS_BLOCK IoStatusBlock)
Definition: iofunc.c:70
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define FILE_APPEND_DATA
Definition: nt_native.h:634
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
#define TAG_IO
Definition: tag.h:80
#define FO_NAMED_PIPE
Definition: iotypes.h:1782
#define IRP_MJ_FLUSH_BUFFERS

Referenced by FlushFileBuffers(), LogfpFlushFile(), and START_TEST().

◆ NtFsControlFile()

NTSTATUS NTAPI NtFsControlFile ( IN HANDLE  DeviceHandle,
IN HANDLE Event  OPTIONAL,
IN PIO_APC_ROUTINE UserApcRoutine  OPTIONAL,
IN PVOID UserApcContext  OPTIONAL,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
IN ULONG  IoControlCode,
IN PVOID  InputBuffer,
IN ULONG InputBufferLength  OPTIONAL,
OUT PVOID  OutputBuffer,
IN ULONG OutputBufferLength  OPTIONAL 
)

Definition at line 1460 of file iofunc.c.

1470{
1471 /* Call the Generic Function */
1473 Event,
1474 UserApcRoutine,
1475 UserApcContext,
1482 FALSE);
1483}

◆ NtLockFile()

NTSTATUS NTAPI NtLockFile ( IN HANDLE  FileHandle,
IN HANDLE EventHandle  OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine  OPTIONAL,
IN PVOID ApcContext  OPTIONAL,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
IN PLARGE_INTEGER  ByteOffset,
IN PLARGE_INTEGER  Length,
IN ULONG  Key,
IN BOOLEAN  FailImmediately,
IN BOOLEAN  ExclusiveLock 
)

Definition at line 1764 of file iofunc.c.

1774{
1776 PLARGE_INTEGER LocalLength = NULL;
1777 PIRP Irp;
1778 PIO_STACK_LOCATION StackPtr;
1780 PKEVENT Event = NULL;
1781 BOOLEAN LockedForSync = FALSE;
1783 LARGE_INTEGER CapturedByteOffset, CapturedLength;
1787 PAGED_CODE();
1788 CapturedByteOffset.QuadPart = 0;
1789 CapturedLength.QuadPart = 0;
1790 IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
1791
1792 /* Get File Object */
1794 0,
1797 (PVOID*)&FileObject,
1799 if (!NT_SUCCESS(Status)) return Status;
1800
1801 /* Check if we're called from user mode */
1802 if (PreviousMode != KernelMode)
1803 {
1804 /* Can't use an I/O completion port and an APC at the same time */
1805 if ((FileObject->CompletionContext) && (ApcRoutine))
1806 {
1807 /* Fail */
1810 }
1811
1812 /* Must have either FILE_READ_DATA or FILE_WRITE_DATA access */
1813 if (!(HandleInformation.GrantedAccess &
1815 {
1817 return STATUS_ACCESS_DENIED;
1818 }
1819
1820 /* Enter SEH for probing */
1821 _SEH2_TRY
1822 {
1823 /* Probe the I/O STatus block */
1825
1826 /* Probe and capture the large integers */
1827 CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
1828 CapturedLength = ProbeForReadLargeInteger(Length);
1829 }
1831 {
1832 /* Dereference the object and return exception code */
1835 }
1836 _SEH2_END;
1837 }
1838 else
1839 {
1840 /* Otherwise, capture them directly */
1841 CapturedByteOffset = *ByteOffset;
1842 CapturedLength = *Length;
1843 }
1844
1845 /* Check if we have an event handle */
1846 if (EventHandle)
1847 {
1848 /* Reference it */
1853 (PVOID *)&Event,
1854 NULL);
1855 if (Status != STATUS_SUCCESS) return Status;
1857 }
1858
1859 /* Get the device object */
1861
1862 /* Try to do it the FastIO way if possible */
1863 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
1865 {
1866 IO_STATUS_BLOCK KernelIosb;
1867
1869 &CapturedByteOffset,
1870 &CapturedLength,
1872 Key,
1875 &KernelIosb,
1876 DeviceObject))
1877 {
1878 /* Write the IOSB back */
1879 _SEH2_TRY
1880 {
1881 *IoStatusBlock = KernelIosb;
1882 }
1884 {
1885 KernelIosb.Status = _SEH2_GetExceptionCode();
1886 }
1887 _SEH2_END;
1888
1889 /* If we had an event, signal it */
1890 if (EventHandle)
1891 {
1894 }
1895
1896 /* Set completion if required */
1897 if (FileObject->CompletionContext != NULL && ApcContext != NULL)
1898 {
1899 if (!NT_SUCCESS(IoSetIoCompletion(FileObject->CompletionContext->Port,
1900 FileObject->CompletionContext->Key,
1901 ApcContext,
1902 KernelIosb.Status,
1903 KernelIosb.Information,
1904 TRUE)))
1905 {
1907 }
1908 }
1909
1910 FileObject->LockOperation = TRUE;
1911
1912 /* We're done with FastIO! */
1914 return KernelIosb.Status;
1915 }
1916 }
1917
1918 /* Check if we should use Sync IO or not */
1919 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1920 {
1921 /* Lock it */
1923 if (Status != STATUS_SUCCESS)
1924 {
1927 return Status;
1928 }
1929 LockedForSync = TRUE;
1930 }
1931
1932 /* Clear File Object event */
1933 KeClearEvent(&FileObject->Event);
1934 FileObject->LockOperation = TRUE;
1935
1936 /* Allocate the IRP */
1937 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1939
1940 /* Set up the IRP */
1941 Irp->RequestorMode = PreviousMode;
1942 Irp->UserIosb = IoStatusBlock;
1943 Irp->UserEvent = Event;
1944 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1945 Irp->Tail.Overlay.OriginalFileObject = FileObject;
1946 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
1947 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
1948
1949 /* Set up Stack Data */
1950 StackPtr = IoGetNextIrpStackLocation(Irp);
1952 StackPtr->MinorFunction = IRP_MN_LOCK;
1953 StackPtr->FileObject = FileObject;
1954
1955 /* Allocate local buffer */
1956 LocalLength = ExAllocatePoolWithTag(NonPagedPool,
1957 sizeof(LARGE_INTEGER),
1958 TAG_LOCK);
1959 if (!LocalLength)
1960 {
1961 /* Allocating failed, clean up and return failure */
1964 }
1965
1966 /* Set the length */
1967 *LocalLength = CapturedLength;
1968 Irp->Tail.Overlay.AuxiliaryBuffer = (PVOID)LocalLength;
1969 StackPtr->Parameters.LockControl.Length = LocalLength;
1970
1971 /* Set Parameters */
1972 StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
1973 StackPtr->Parameters.LockControl.Key = Key;
1974
1975 /* Set Flags */
1976 if (FailImmediately) StackPtr->Flags = SL_FAIL_IMMEDIATELY;
1977 if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
1978
1979 /* Perform the call */
1981 Irp,
1982 FileObject,
1983 FALSE,
1985 LockedForSync,
1987}
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG BOOLEAN BOOLEAN ExclusiveLock
Definition: fatprocs.h:2714
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG BOOLEAN FailImmediately
Definition: fatprocs.h:2713
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:727
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:726
#define FILE_READ_DATA
Definition: nt_native.h:628
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
PFAST_IO_LOCK FastIoLock
Definition: iotypes.h:1739
struct _IO_STACK_LOCATION::@3983::@3999 LockControl
#define TAG_LOCK
Definition: tag.h:63
void * PVOID
Definition: typedefs.h:50
LONGLONG QuadPart
Definition: typedefs.h:114
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857
#define IRP_MN_LOCK
Definition: iotypes.h:4410
#define SL_FAIL_IMMEDIATELY
Definition: iotypes.h:1832
#define SL_EXCLUSIVE_LOCK
Definition: iotypes.h:1833
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by LockFile(), and LockFileEx().

◆ NtNotifyChangeDirectoryFile()

NTSTATUS NTAPI NtNotifyChangeDirectoryFile ( IN HANDLE  FileHandle,
IN HANDLE EventHandle  OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine  OPTIONAL,
IN PVOID ApcContext  OPTIONAL,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
OUT PVOID  Buffer,
IN ULONG  BufferSize,
IN ULONG  CompletionFilter,
IN BOOLEAN  WatchTree 
)

Definition at line 1622 of file iofunc.c.

1631{
1632 PIRP Irp;
1633 PKEVENT Event = NULL;
1636 PIO_STACK_LOCATION IoStack;
1639 BOOLEAN LockedForSync = FALSE;
1640 PAGED_CODE();
1641 IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
1642
1643 /* Check if we're called from user mode */
1644 if (PreviousMode != KernelMode)
1645 {
1646 /* Enter SEH for probing */
1647 _SEH2_TRY
1648 {
1649 /* Probe the I/O STatus block */
1651
1652 /* Probe the buffer */
1654 }
1656 {
1657 /* Return the exception code */
1659 }
1660 _SEH2_END;
1661
1662 /* Check if CompletionFilter is valid */
1664 {
1666 }
1667 }
1668
1669 /* Get File Object */
1674 (PVOID*)&FileObject,
1675 NULL);
1676 if (!NT_SUCCESS(Status)) return Status;
1677
1678 /* Can't use an I/O completion port and an APC at the same time */
1679 if ((FileObject->CompletionContext) && (ApcRoutine))
1680 {
1681 /* Fail */
1684 }
1685
1686 /* Check if we have an event handle */
1687 if (EventHandle)
1688 {
1689 /* Reference it */
1694 (PVOID *)&Event,
1695 NULL);
1696 if (Status != STATUS_SUCCESS)
1697 {
1699 return Status;
1700 }
1702 }
1703
1704 /* Check if we should use Sync IO or not */
1705 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
1706 {
1707 /* Lock it */
1709 if (Status != STATUS_SUCCESS)
1710 {
1713 return Status;
1714 }
1715 LockedForSync = TRUE;
1716 }
1717
1718 /* Clear File Object event */
1719 KeClearEvent(&FileObject->Event);
1720
1721 /* Get the device object */
1723
1724 /* Allocate the IRP */
1725 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1727
1728 /* Set up the IRP */
1729 Irp->RequestorMode = PreviousMode;
1730 Irp->UserIosb = IoStatusBlock;
1731 Irp->UserEvent = Event;
1732 Irp->UserBuffer = Buffer;
1733 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
1734 Irp->Tail.Overlay.OriginalFileObject = FileObject;
1735 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
1736 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
1737
1738 /* Set up Stack Data */
1739 IoStack = IoGetNextIrpStackLocation(Irp);
1742 IoStack->FileObject = FileObject;
1743
1744 /* Set parameters */
1745 IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
1746 IoStack->Parameters.NotifyDirectory.Length = BufferSize;
1747 if (WatchTree) IoStack->Flags = SL_WATCH_TREE;
1748
1749 /* Perform the call */
1751 Irp,
1752 FileObject,
1753 FALSE,
1755 LockedForSync,
1757}
#define BufferSize
Definition: mmc.h:75
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG CompletionFilter
Definition: fltkernel.h:2243
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN WatchTree
Definition: fltkernel.h:2241
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
struct _IO_STACK_LOCATION::@3983::@3990 NotifyDirectory
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
#define SL_WATCH_TREE
Definition: iotypes.h:1839
#define FILE_NOTIFY_VALID_MASK

Referenced by FindFirstChangeNotificationW(), FindNextChangeNotification(), and ReadDirectoryChangesW().

◆ NtQueryDirectoryFile()

NTSTATUS NTAPI NtQueryDirectoryFile ( IN HANDLE  FileHandle,
IN HANDLE EventHandle  OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine  OPTIONAL,
IN PVOID ApcContext  OPTIONAL,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
OUT PVOID  FileInformation,
IN ULONG  Length,
IN FILE_INFORMATION_CLASS  FileInformationClass,
IN BOOLEAN  ReturnSingleEntry,
IN PUNICODE_STRING FileName  OPTIONAL,
IN BOOLEAN  RestartScan 
)

Definition at line 1994 of file iofunc.c.

2005{
2006 PIRP Irp;
2009 PIO_STACK_LOCATION StackPtr;
2012 BOOLEAN LockedForSynch = FALSE;
2013 PKEVENT Event = NULL;
2014 volatile PVOID AuxBuffer = NULL;
2015 PMDL Mdl;
2016 UNICODE_STRING CapturedFileName;
2017 PUNICODE_STRING SearchPattern;
2018 PAGED_CODE();
2019 IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
2020
2021 /* Check if we came from user mode */
2022 if (PreviousMode != KernelMode)
2023 {
2024 /* Enter SEH for probing */
2025 _SEH2_TRY
2026 {
2027 /* Probe the I/O Status Block */
2029
2030 /* Probe the file information */
2032
2033 /* Check if we have a file name */
2034 if (FileName)
2035 {
2036 /* Capture it */
2037 CapturedFileName = ProbeForReadUnicodeString(FileName);
2038 if (CapturedFileName.Length)
2039 {
2040 /* Probe its buffer */
2041 ProbeForRead(CapturedFileName.Buffer,
2042 CapturedFileName.Length,
2043 1);
2044 }
2045
2046 /* Allocate the auxiliary buffer */
2048 CapturedFileName.Length +
2049 sizeof(UNICODE_STRING),
2050 TAG_SYSB);
2051 RtlCopyMemory((PVOID)((ULONG_PTR)AuxBuffer +
2052 sizeof(UNICODE_STRING)),
2053 CapturedFileName.Buffer,
2054 CapturedFileName.Length);
2055
2056 /* Setup the search pattern */
2057 SearchPattern = (PUNICODE_STRING)AuxBuffer;
2058 SearchPattern->Buffer = (PWCHAR)((ULONG_PTR)AuxBuffer +
2059 sizeof(UNICODE_STRING));
2060 SearchPattern->Length = CapturedFileName.Length;
2061 SearchPattern->MaximumLength = CapturedFileName.Length;
2062 }
2063 }
2065 {
2066 /* Free buffer and return the exception code */
2067 if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB);
2069 }
2070 _SEH2_END;
2071 }
2072
2073 /* Check input parameters */
2074
2075 switch (FileInformationClass)
2076 {
2077#define CHECK_LENGTH(class, struct) \
2078 case class: \
2079 if (Length < sizeof(struct)) \
2080 return STATUS_INFO_LENGTH_MISMATCH; \
2081 break
2088 default:
2089 break;
2090#undef CHECK_LENGTH
2091 }
2092
2093 /* Get File Object */
2098 (PVOID *)&FileObject,
2099 NULL);
2100 if (!NT_SUCCESS(Status))
2101 {
2102 /* Fail */
2103 if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB);
2104 return Status;
2105 }
2106
2107 /* Are there two associated completion routines? */
2108 if (FileObject->CompletionContext != NULL && ApcRoutine != NULL)
2109 {
2111 if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB);
2113 }
2114
2115 /* Check if we have an even handle */
2116 if (EventHandle)
2117 {
2118 /* Get its pointer */
2123 (PVOID *)&Event,
2124 NULL);
2125 if (!NT_SUCCESS(Status))
2126 {
2127 /* Fail */
2128 if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB);
2130 return Status;
2131 }
2132
2133 /* Clear it */
2135 }
2136
2137 /* Check if this is a file that was opened for Synch I/O */
2138 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
2139 {
2140 /* Lock it */
2142 if (Status != STATUS_SUCCESS)
2143 {
2146 if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB);
2147 return Status;
2148 }
2149
2150 /* Remember to unlock later */
2151 LockedForSynch = TRUE;
2152 }
2153
2154 /* Get the device object */
2156
2157 /* Clear the File Object's event */
2158 KeClearEvent(&FileObject->Event);
2159
2160 /* Allocate the IRP */
2161 Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
2162 if (!Irp) return IopCleanupFailedIrp(FileObject, EventHandle, AuxBuffer);
2163
2164 /* Set up the IRP */
2165 Irp->RequestorMode = PreviousMode;
2166 Irp->UserIosb = IoStatusBlock;
2167 Irp->UserEvent = Event;
2168 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
2169 Irp->Tail.Overlay.OriginalFileObject = FileObject;
2170 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
2171 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
2172 Irp->MdlAddress = NULL;
2173 Irp->Tail.Overlay.AuxiliaryBuffer = AuxBuffer;
2174 Irp->AssociatedIrp.SystemBuffer = NULL;
2175
2176 /* Check if this is buffered I/O */
2177 if (DeviceObject->Flags & DO_BUFFERED_IO)
2178 {
2179 /* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
2180 _SEH2_TRY
2181 {
2182 /* Allocate a buffer */
2183 Irp->AssociatedIrp.SystemBuffer =
2185 }
2187 {
2188 /* Allocating failed, clean up and return the exception code */
2190 if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB);
2191
2192 /* Return the exception code */
2193 return _SEH2_GetExceptionCode();
2194 }
2195 _SEH2_END;
2196
2197 /* Set the buffer and flags */
2198 Irp->UserBuffer = FileInformation;
2199 Irp->Flags = (IRP_BUFFERED_IO |
2202 }
2203 else if (DeviceObject->Flags & DO_DIRECT_IO)
2204 {
2205 _SEH2_TRY
2206 {
2207 /* Allocate an MDL */
2211 }
2213 {
2214 /* Allocating failed, clean up and return the exception code */
2217 }
2218 _SEH2_END;
2219 }
2220 else
2221 {
2222 /* No allocation flags, and use the buffer directly */
2223 Irp->UserBuffer = FileInformation;
2224 }
2225
2226 /* Set up Stack Data */
2227 StackPtr = IoGetNextIrpStackLocation(Irp);
2228 StackPtr->FileObject = FileObject;
2231
2232 /* Set Parameters */
2233 StackPtr->Parameters.QueryDirectory.FileInformationClass =
2235 StackPtr->Parameters.QueryDirectory.FileName = AuxBuffer;
2236 StackPtr->Parameters.QueryDirectory.FileIndex = 0;
2237 StackPtr->Parameters.QueryDirectory.Length = Length;
2238 StackPtr->Flags = 0;
2239 if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN;
2241
2242 /* Set deferred I/O */
2243 Irp->Flags |= IRP_DEFER_IO_COMPLETION;
2244
2245 /* Perform the call */
2247 Irp,
2248 FileObject,
2249 TRUE,
2251 LockedForSynch,
2253}
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
struct _UNICODE_STRING UNICODE_STRING
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2299
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN ReturnSingleEntry
Definition: fltkernel.h:2295
@ FileDirectoryInformation
Definition: from_kernel.h:62
@ FileIdBothDirectoryInformation
Definition: from_kernel.h:98
@ FileNamesInformation
Definition: from_kernel.h:73
@ FileFullDirectoryInformation
Definition: from_kernel.h:63
@ FileBothDirectoryInformation
Definition: from_kernel.h:64
@ FileIdFullDirectoryInformation
Definition: from_kernel.h:99
#define CHECK_LENGTH(class, struct)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
struct _IO_STACK_LOCATION::@3983::@3989 QueryDirectory
#define TAG_SYSB
Definition: tag.h:96
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1836
#define SL_RESTART_SCAN
Definition: iotypes.h:1835

Referenced by FindFirstFileExW(), FindNextFileW(), GetFileInformationByHandleEx(), and lookup_manifest_file().

◆ NtQueryEaFile()

NTSTATUS NTAPI NtQueryEaFile ( IN HANDLE  FileHandle,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
OUT PVOID  Buffer,
IN ULONG  Length,
IN BOOLEAN  ReturnSingleEntry,
IN PVOID EaList  OPTIONAL,
IN ULONG  EaListLength,
IN PULONG EaIndex  OPTIONAL,
IN BOOLEAN  RestartScan 
)

Definition at line 2260 of file iofunc.c.

2269{
2272}

Referenced by CreateDirectoryExW(), and CreateFileW().

◆ NtQueryInformationFile()

NTSTATUS NTAPI NtQueryInformationFile ( IN HANDLE  FileHandle,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
IN PVOID  FileInformation,
IN ULONG  Length,
IN FILE_INFORMATION_CLASS  FileInformationClass 
)

Definition at line 2279 of file iofunc.c.

2284{
2288 PIRP Irp;
2290 PIO_STACK_LOCATION StackPtr;
2292 PKEVENT Event = NULL;
2293 BOOLEAN LocalEvent = FALSE;
2294 PKNORMAL_ROUTINE NormalRoutine;
2295 PVOID NormalContext;
2296 KIRQL OldIrql;
2297 IO_STATUS_BLOCK KernelIosb;
2298 BOOLEAN CallDriver = TRUE;
2299 PFILE_ACCESS_INFORMATION AccessBuffer;
2300 PFILE_MODE_INFORMATION ModeBuffer;
2301 PFILE_ALIGNMENT_INFORMATION AlignmentBuffer;
2302 PFILE_ALL_INFORMATION AllBuffer;
2304 PAGED_CODE();
2305 IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
2306
2307 /* Check if we're called from user mode */
2308 if (PreviousMode != KernelMode)
2309 {
2310 /* Validate the information class */
2311 if ((FileInformationClass < 0) ||
2314 {
2315 /* Invalid class */
2317 }
2318
2319 /* Validate the length */
2321 {
2322 /* Invalid length */
2324 }
2325
2326 /* Enter SEH for probing */
2327 _SEH2_TRY
2328 {
2329 /* Probe the I/O Status block */
2331
2332 /* Probe the information */
2334 }
2336 {
2337 /* Return the exception code */
2339 }
2340 _SEH2_END;
2341 }
2342#if DBG
2343 else
2344 {
2345 /* Validate the information class */
2346 if ((FileInformationClass < 0) ||
2349 {
2350 /* Invalid class */
2352 }
2353
2354 /* Validate the length */
2356 {
2357 /* Invalid length */
2359 }
2360 }
2361#endif
2362
2363 /* Reference the Handle */
2369 (PVOID *)&FileObject,
2371 if (!NT_SUCCESS(Status)) return Status;
2372
2373 /* Check if this is a direct open or not */
2374 if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
2375 {
2376 /* Get the device object */
2378 }
2379 else
2380 {
2381 /* Get the device object */
2383 }
2384
2385 /* Check if this is a file that was opened for Synch I/O */
2386 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
2387 {
2388 /* Lock it */
2390 if (Status != STATUS_SUCCESS)
2391 {
2393 return Status;
2394 }
2395
2396 /* Check if the caller just wants the position */
2398 {
2399 /* Protect write in SEH */
2400 _SEH2_TRY
2401 {
2402 /* Write the offset */
2404 CurrentByteOffset = FileObject->CurrentByteOffset;
2405
2406 /* Fill out the I/O Status Block */
2409 }
2411 {
2412 /* Get the exception code */
2414 }
2415 _SEH2_END;
2416
2417 /* Release the file lock, dereference the file and return */
2420 return Status;
2421 }
2422 }
2423 else
2424 {
2425 /* Use local event */
2427 if (!Event)
2428 {
2431 }
2433 LocalEvent = TRUE;
2434 }
2435
2436 /* Check if FastIO is possible for the two available information classes */
2437 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
2438 if (FastIoDispatch != NULL &&
2441 {
2443
2445 {
2448 &KernelIosb,
2449 DeviceObject);
2450 }
2451 else
2452 {
2455 &KernelIosb,
2456 DeviceObject);
2457 }
2458
2459 /* If call succeed */
2460 if (Success)
2461 {
2462 /* Write the IOSB back */
2463 _SEH2_TRY
2464 {
2465 *IoStatusBlock = KernelIosb;
2466 }
2468 {
2469 KernelIosb.Status = _SEH2_GetExceptionCode();
2470 }
2471 _SEH2_END;
2472
2473 /* Free the event if we had one */
2474 if (LocalEvent)
2475 {
2477 }
2478
2479 /* If FO was locked, unlock it */
2480 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
2481 {
2483 }
2484
2485 /* We're done with FastIO! */
2487 return KernelIosb.Status;
2488 }
2489 }
2490
2491 /* Clear the File Object event */
2492 KeClearEvent(&FileObject->Event);
2493
2494 /* Allocate the IRP */
2495 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
2497
2498 /* Set the IRP */
2499 Irp->Tail.Overlay.OriginalFileObject = FileObject;
2500 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
2501 Irp->RequestorMode = PreviousMode;
2502 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
2503 Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
2504 Irp->UserIosb = (LocalEvent) ? &KernelIosb : IoStatusBlock;
2505 Irp->UserEvent = (LocalEvent) ? Event : NULL;
2506 Irp->AssociatedIrp.SystemBuffer = NULL;
2507 Irp->MdlAddress = NULL;
2508 Irp->UserBuffer = FileInformation;
2509
2510 /* Set the Stack Data */
2511 StackPtr = IoGetNextIrpStackLocation(Irp);
2513 StackPtr->FileObject = FileObject;
2514
2515 /* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
2516 _SEH2_TRY
2517 {
2518 /* Allocate a buffer */
2519 Irp->AssociatedIrp.SystemBuffer =
2521 }
2523 {
2524 /* Allocating failed, clean up and return the exception code */
2527 }
2528 _SEH2_END;
2529
2530 /* Set the flags */
2531 Irp->Flags |= (IRP_BUFFERED_IO |
2535
2536 /* Set the Parameters */
2537 StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass;
2538 StackPtr->Parameters.QueryFile.Length = Length;
2539
2540 /* Queue the IRP */
2542
2543 /* Update operation counts */
2545
2546 /* Fill in file information before calling the driver.
2547 See 'File System Internals' page 485.*/
2549 {
2550 AccessBuffer = Irp->AssociatedIrp.SystemBuffer;
2551 AccessBuffer->AccessFlags = HandleInformation.GrantedAccess;
2552 Irp->IoStatus.Information = sizeof(FILE_ACCESS_INFORMATION);
2553 CallDriver = FALSE;
2554 }
2556 {
2557 ModeBuffer = Irp->AssociatedIrp.SystemBuffer;
2558 ModeBuffer->Mode = IopGetFileMode(FileObject);
2559 Irp->IoStatus.Information = sizeof(FILE_MODE_INFORMATION);
2560 CallDriver = FALSE;
2561 }
2563 {
2564 AlignmentBuffer = Irp->AssociatedIrp.SystemBuffer;
2565 AlignmentBuffer->AlignmentRequirement = DeviceObject->AlignmentRequirement;
2566 Irp->IoStatus.Information = sizeof(FILE_ALIGNMENT_INFORMATION);
2567 CallDriver = FALSE;
2568 }
2570 {
2571 AllBuffer = Irp->AssociatedIrp.SystemBuffer;
2572 AllBuffer->AccessInformation.AccessFlags = HandleInformation.GrantedAccess;
2574 AllBuffer->AlignmentInformation.AlignmentRequirement = DeviceObject->AlignmentRequirement;
2575 Irp->IoStatus.Information = sizeof(FILE_ACCESS_INFORMATION) +
2576 sizeof(FILE_MODE_INFORMATION) +
2578 }
2579
2580 /* Call the Driver */
2581 if (CallDriver)
2582 {
2584 }
2585 else
2586 {
2588 Irp->IoStatus.Status = STATUS_SUCCESS;
2589 }
2590
2591 if (Status == STATUS_PENDING)
2592 {
2593 /* Check if this was async I/O */
2594 if (LocalEvent)
2595 {
2596 /* Then to a non-alertable wait */
2598 Executive,
2600 FALSE,
2601 NULL);
2602 if (Status == STATUS_USER_APC)
2603 {
2604 /* Abort the request */
2606 }
2607
2608 /* Set the final status */
2609 Status = KernelIosb.Status;
2610
2611 /* Enter SEH to write the IOSB back */
2612 _SEH2_TRY
2613 {
2614 /* Write it back to the caller */
2615 *IoStatusBlock = KernelIosb;
2616 }
2618 {
2619 /* Get the exception code */
2621 }
2622 _SEH2_END;
2623
2624 /* Free the event */
2626 }
2627 else
2628 {
2629 /* Wait for the IRP */
2631 Executive,
2633 (FileObject->Flags &
2634 FO_ALERTABLE_IO) != 0,
2635 NULL);
2637 {
2638 /* Abort the request */
2640 }
2641
2642 /* Set the final status */
2643 Status = FileObject->FinalStatus;
2644
2645 /* Release the file lock */
2647 }
2648 }
2649 else
2650 {
2651 /* Free the event if we had one */
2652 if (LocalEvent)
2653 {
2654 /* Clear it in the IRP for completion */
2655 Irp->UserEvent = NULL;
2657 }
2658
2659 /* Set the caller IOSB */
2660 Irp->UserIosb = IoStatusBlock;
2661
2662 /* The IRP wasn't completed, complete it ourselves */
2663 NormalRoutine = NULL;
2664 NormalContext = NULL;
2666 IopCompleteRequest(&Irp->Tail.Apc,
2667 &NormalRoutine,
2668 &NormalContext,
2669 (PVOID*)&FileObject,
2670 &NormalContext);
2672
2673 /* Release the file object if we had locked it*/
2674 if (!LocalEvent) IopUnlockFileObject(FileObject);
2675 }
2676
2677 /* Return the Status */
2678 return Status;
2679}
@ Success
Definition: eventcreate.c:712
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileMaximumInformation
Definition: from_kernel.h:112
@ FileAllInformation
Definition: from_kernel.h:79
@ FileAlignmentInformation
Definition: from_kernel.h:78
@ FileModeInformation
Definition: from_kernel.h:77
struct _FILE_MODE_INFORMATION FILE_MODE_INFORMATION
UCHAR IopQueryOperationLength[]
Definition: io_i.h:12
ACCESS_MASK IopQueryOperationAccess[]
Definition: io_i.h:115
static ULONG IopGetFileMode(IN PFILE_OBJECT FileObject)
Definition: iofunc.c:1004
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
struct _FILE_ALIGNMENT_INFORMATION FILE_ALIGNMENT_INFORMATION
struct _FILE_POSITION_INFORMATION * PFILE_POSITION_INFORMATION
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
struct _FILE_ACCESS_INFORMATION FILE_ACCESS_INFORMATION
#define FileAccessInformation
Definition: propsheet.cpp:51
#define FileStandardInformation
Definition: propsheet.cpp:61
PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo
Definition: iotypes.h:1738
PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo
Definition: iotypes.h:1737
FILE_MODE_INFORMATION ModeInformation
Definition: winternl.h:802
FILE_ALIGNMENT_INFORMATION AlignmentInformation
Definition: winternl.h:803
FILE_ACCESS_INFORMATION AccessInformation
Definition: winternl.h:800

◆ NtQueryQuotaInformationFile()

NTSTATUS NTAPI NtQueryQuotaInformationFile ( IN HANDLE  FileHandle,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
OUT PVOID  Buffer,
IN ULONG  Length,
IN BOOLEAN  ReturnSingleEntry,
IN PVOID SidList  OPTIONAL,
IN ULONG  SidListLength,
IN PSID StartSid  OPTIONAL,
IN BOOLEAN  RestartScan 
)

Definition at line 2686 of file iofunc.c.

2695{
2698}

◆ NtQueryVolumeInformationFile()

NTSTATUS NTAPI NtQueryVolumeInformationFile ( IN HANDLE  FileHandle,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
OUT PVOID  FsInformation,
IN ULONG  Length,
IN FS_INFORMATION_CLASS  FsInformationClass 
)

Definition at line 4151 of file iofunc.c.

4156{
4158 PIRP Irp;
4159 PIO_STACK_LOCATION StackPtr;
4161 PKEVENT Event = NULL;
4162 BOOLEAN LocalEvent = FALSE;
4165 IO_STATUS_BLOCK KernelIosb;
4166 PAGED_CODE();
4167 IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
4168
4169 /* Check if we're called from user mode */
4170 if (PreviousMode != KernelMode)
4171 {
4172 /* Validate the information class */
4173 if ((FsInformationClass < 0) ||
4176 {
4177 /* Invalid class */
4179 }
4180
4181 /* Validate the length */
4183 {
4184 /* Invalid length */
4186 }
4187
4188 /* Enter SEH for probing */
4189 _SEH2_TRY
4190 {
4191 /* Probe the I/O Status block */
4193
4194 /* Probe the information */
4195 ProbeForWrite(FsInformation, Length, sizeof(ULONG));
4196 }
4198 {
4199 /* Return the exception code */
4201 }
4202 _SEH2_END;
4203 }
4204
4205 /* Get File Object */
4211 (PVOID*)&FileObject,
4212 NULL);
4213 if (!NT_SUCCESS(Status)) return Status;
4214
4215 /* Only allow direct device open for FileFsDeviceInformation */
4218 {
4221 }
4222
4223 /* Check if we should use Sync IO or not */
4224 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
4225 {
4226 /* Lock it */
4228 if (Status != STATUS_SUCCESS)
4229 {
4231 return Status;
4232 }
4233 }
4234
4235 /*
4236 * Quick path for FileFsDeviceInformation - the kernel has enough
4237 * info to reply instead of the driver, excepted for network file systems
4238 */
4241 {
4242 PFILE_FS_DEVICE_INFORMATION FsDeviceInfo = FsInformation;
4243 DeviceObject = FileObject->DeviceObject;
4244
4245 _SEH2_TRY
4246 {
4247 FsDeviceInfo->DeviceType = DeviceObject->DeviceType;
4248
4249 /* Complete characteristcs with mount status if relevant */
4250 FsDeviceInfo->Characteristics = DeviceObject->Characteristics;
4252 {
4254 }
4255
4258 }
4260 {
4261 /* Check if we had a file lock */
4263 {
4264 /* Release it */
4266 }
4267
4268 /* Dereference the FO */
4270
4272 }
4273 _SEH2_END;
4274
4275 /* Check if we had a file lock */
4277 {
4278 /* Release it */
4280 }
4281
4282 /* Dereference the FO */
4284
4285 return STATUS_SUCCESS;
4286 }
4287 /* This is to be handled by the kernel, not by FSD */
4289 {
4291
4292 /* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
4293 _SEH2_TRY
4294 {
4295 /* Allocate our local structure */
4297
4298 /* And copy back caller data */
4299 RtlCopyMemory(DriverPathInfo, FsInformation, Length);
4300
4301 /* Is the driver in the IO path? */
4303 (PFILE_FS_DRIVER_PATH_INFORMATION)DriverPathInfo,
4304 Length);
4305 /* We failed, don't continue execution */
4306 if (!NT_SUCCESS(Status))
4307 {
4309 }
4310
4311 /* We succeed, copy back info */
4312 ((PFILE_FS_DRIVER_PATH_INFORMATION)FsInformation)->DriverInPath = DriverPathInfo->DriverInPath;
4313
4314 /* We're done */
4317 }
4319 {
4321 }
4322 _SEH2_END;
4323
4324 /* Don't leak */
4325 if (DriverPathInfo != NULL)
4326 {
4327 ExFreePoolWithTag(DriverPathInfo, TAG_IO);
4328 }
4329
4330 /* Check if we had a file lock */
4332 {
4333 /* Release it */
4335 }
4336
4337 /* Dereference the FO */
4339
4340 return Status;
4341 }
4342
4344 {
4345 /* Use local event */
4347 if (!Event)
4348 {
4351 }
4353 LocalEvent = TRUE;
4354 }
4355
4356 /* Get the device object */
4358
4359 /* Clear File Object event */
4360 KeClearEvent(&FileObject->Event);
4361
4362 /* Allocate the IRP */
4363 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
4365
4366 /* Set up the IRP */
4367 Irp->RequestorMode = PreviousMode;
4368 Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
4369 Irp->UserIosb = (LocalEvent) ? &KernelIosb : IoStatusBlock;
4370 Irp->UserEvent = (LocalEvent) ? Event : NULL;
4371 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
4372 Irp->Tail.Overlay.OriginalFileObject = FileObject;
4373 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
4374 Irp->UserBuffer = FsInformation;
4375 Irp->AssociatedIrp.SystemBuffer = NULL;
4376 Irp->MdlAddress = NULL;
4377
4378 /* Set up Stack Data */
4379 StackPtr = IoGetNextIrpStackLocation(Irp);
4381 StackPtr->FileObject = FileObject;
4382
4383 /* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
4384 _SEH2_TRY
4385 {
4386 /* Allocate a buffer */
4387 Irp->AssociatedIrp.SystemBuffer =
4389 }
4391 {
4392 /* Allocating failed, clean up and return the exception code */
4395 }
4396 _SEH2_END;
4397
4398 /* Set the flags for this buffered + deferred I/O */
4399 Irp->Flags |= (IRP_BUFFERED_IO |
4403
4404 /* Set Parameters */
4405 StackPtr->Parameters.QueryVolume.Length = Length;
4406 StackPtr->Parameters.QueryVolume.FsInformationClass = FsInformationClass;
4407
4408 /* Call the Driver */
4410 Irp,
4411 FileObject,
4412 TRUE,
4414 !LocalEvent,
4416
4417 /* Check if this was async I/O */
4418 if (LocalEvent)
4419 {
4420 /* It was, finalize this request */
4422 Event,
4423 Irp,
4425 &KernelIosb,
4427 }
4428
4429 /* Return status */
4430 return Status;
4431}
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsMaximumInformation
Definition: from_kernel.h:229
ULONG IopQueryFsOperationAccess[]
Definition: io_i.h:246
UCHAR IopQueryFsOperationLength[]
Definition: io_i.h:210
static BOOLEAN IopGetMountFlag(IN PDEVICE_OBJECT DeviceObject)
Definition: iofunc.c:1033
static NTSTATUS IopGetDriverPathInformation(IN PFILE_OBJECT FileObject, IN PFILE_FS_DRIVER_PATH_INFORMATION DriverPathInfo, IN ULONG Length)
Definition: iofunc.c:1084
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
struct _FILE_FS_DEVICE_INFORMATION FILE_FS_DEVICE_INFORMATION
#define FILE_DEVICE_IS_MOUNTED
Definition: nt_native.h:812
#define FileFsDriverPathInformation
Definition: ntifs_ex.h:391
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:126
#define _SEH2_VOLATILE
Definition: pseh2_64.h:169
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
struct _FILE_FS_DRIVER_PATH_INFORMATION FILE_FS_DRIVER_PATH_INFORMATION
struct _FILE_FS_DRIVER_PATH_INFORMATION * PFILE_FS_DRIVER_PATH_INFORMATION

◆ NtReadFile()

NTSTATUS NTAPI NtReadFile ( IN HANDLE  FileHandle,
IN HANDLE Event  OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine  OPTIONAL,
IN PVOID ApcContext  OPTIONAL,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
OUT PVOID  Buffer,
IN ULONG  Length,
IN PLARGE_INTEGER ByteOffset  OPTIONAL,
IN PULONG Key  OPTIONAL 
)

Definition at line 2705 of file iofunc.c.

2714{
2717 PIRP Irp;
2719 PIO_STACK_LOCATION StackPtr;
2721 PKEVENT EventObject = NULL;
2722 LARGE_INTEGER CapturedByteOffset;
2723 ULONG CapturedKey = 0;
2724 BOOLEAN Synchronous = FALSE;
2725 PMDL Mdl;
2727 IO_STATUS_BLOCK KernelIosb;
2729
2730 PAGED_CODE();
2731 CapturedByteOffset.QuadPart = 0;
2732 IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
2733
2734 /* Get File Object */
2739 (PVOID*)&FileObject,
2740 NULL);
2741 if (!NT_SUCCESS(Status)) return Status;
2742
2743 /* Get the device object */
2745
2746 /* Validate User-Mode Buffers */
2747 if (PreviousMode != KernelMode)
2748 {
2749 _SEH2_TRY
2750 {
2751 /* Probe the status block */
2753
2754 /* Probe the read buffer */
2756
2757 /* Check if we got a byte offset */
2758 if (ByteOffset)
2759 {
2760 /* Capture and probe it */
2761 CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
2762 }
2763
2764 /* Can't use an I/O completion port and an APC at the same time */
2765 if ((FileObject->CompletionContext) && (ApcRoutine))
2766 {
2767 /* Fail */
2770 }
2771
2772 /* Perform additional checks for non-cached file access */
2774 {
2775 /* Fail if Length is not sector size aligned
2776 * Perform a quick check for 2^ sector sizes
2777 * If it fails, try a more standard way
2778 */
2779 if ((DeviceObject->SectorSize != 0) &&
2780 ((DeviceObject->SectorSize - 1) & Length) != 0)
2781 {
2782 if (Length % DeviceObject->SectorSize != 0)
2783 {
2784 /* Release the file object and and fail */
2787 }
2788 }
2789
2790 /* Fail if buffer doesn't match alignment requirements */
2791 if (((ULONG_PTR)Buffer & DeviceObject->AlignmentRequirement) != 0)
2792 {
2793 /* Release the file object and and fail */
2796 }
2797
2798 if (ByteOffset)
2799 {
2800 /* Fail if ByteOffset is not sector size aligned */
2801 if ((DeviceObject->SectorSize != 0) &&
2802 (CapturedByteOffset.QuadPart % DeviceObject->SectorSize != 0))
2803 {
2804 /* Release the file object and and fail */
2807 }
2808 }
2809 }
2810
2811 /* Capture and probe the key */
2812 if (Key) CapturedKey = ProbeForReadUlong(Key);
2813 }
2815 {
2816 /* Release the file object and return the exception code */
2819 }
2820 _SEH2_END;
2821 }
2822 else
2823 {
2824 /* Kernel mode: capture directly */
2825 if (ByteOffset) CapturedByteOffset = *ByteOffset;
2826 if (Key) CapturedKey = *Key;
2827 }
2828
2829 /* Check for invalid offset */
2830 if ((CapturedByteOffset.QuadPart < 0) && (CapturedByteOffset.QuadPart != -2))
2831 {
2832 /* -2 is FILE_USE_FILE_POINTER_POSITION */
2835 }
2836
2837 /* Check for event */
2838 if (Event)
2839 {
2840 /* Reference it */
2845 (PVOID*)&EventObject,
2846 NULL);
2847 if (!NT_SUCCESS(Status))
2848 {
2849 /* Fail */
2851 return Status;
2852 }
2853
2854 /* Otherwise reset the event */
2855 KeClearEvent(EventObject);
2856 }
2857
2858 /* Check if we should use Sync IO or not */
2859 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
2860 {
2861 /* Lock the file object */
2863 if (Status != STATUS_SUCCESS)
2864 {
2865 if (EventObject) ObDereferenceObject(EventObject);
2867 return Status;
2868 }
2869
2870 /* Check if we don't have a byte offset available */
2871 if (!(ByteOffset) ||
2872 ((CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION) &&
2873 (CapturedByteOffset.u.HighPart == -1)))
2874 {
2875 /* Use the Current Byte Offset instead */
2876 CapturedByteOffset = FileObject->CurrentByteOffset;
2877 }
2878
2879 /* If the file is cached, try fast I/O */
2880 if (FileObject->PrivateCacheMap)
2881 {
2882 /* Perform fast read */
2883 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
2885
2887 &CapturedByteOffset,
2888 Length,
2889 TRUE,
2890 CapturedKey,
2891 Buffer,
2892 &KernelIosb,
2893 DeviceObject);
2894
2895 /* Only accept the result if we got a straightforward status */
2896 if (Success &&
2897 (KernelIosb.Status == STATUS_SUCCESS ||
2898 KernelIosb.Status == STATUS_BUFFER_OVERFLOW ||
2899 KernelIosb.Status == STATUS_END_OF_FILE))
2900 {
2901 /* Fast path -- update transfer & operation counts */
2904 (ULONG)KernelIosb.Information);
2905
2906 /* Enter SEH to write the IOSB back */
2907 _SEH2_TRY
2908 {
2909 /* Write it back to the caller */
2910 *IoStatusBlock = KernelIosb;
2911 }
2913 {
2914 /* The caller's IOSB was invalid, so fail */
2915 if (EventObject) ObDereferenceObject(EventObject);
2919 }
2920 _SEH2_END;
2921
2922 /* Signal the completion event */
2923 if (EventObject)
2924 {
2925 KeSetEvent(EventObject, 0, FALSE);
2926 ObDereferenceObject(EventObject);
2927 }
2928
2929 /* Clean up */
2932 return KernelIosb.Status;
2933 }
2934 }
2935
2936 /* Remember we are sync */
2937 Synchronous = TRUE;
2938 }
2939 else if (!(ByteOffset) &&
2940 !(FileObject->Flags & (FO_NAMED_PIPE | FO_MAILSLOT)))
2941 {
2942 /* Otherwise, this was async I/O without a byte offset, so fail */
2943 if (EventObject) ObDereferenceObject(EventObject);
2946 }
2947
2948 /* Clear the File Object's event */
2949 KeClearEvent(&FileObject->Event);
2950
2951 /* Allocate the IRP */
2952 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
2953 if (!Irp) return IopCleanupFailedIrp(FileObject, EventObject, NULL);
2954
2955 /* Set the IRP */
2956 Irp->Tail.Overlay.OriginalFileObject = FileObject;
2957 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
2958 Irp->RequestorMode = PreviousMode;
2959 Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
2960 Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
2961 Irp->UserIosb = IoStatusBlock;
2962 Irp->UserEvent = EventObject;
2963 Irp->PendingReturned = FALSE;
2964 Irp->Cancel = FALSE;
2965 Irp->CancelRoutine = NULL;
2966 Irp->AssociatedIrp.SystemBuffer = NULL;
2967 Irp->MdlAddress = NULL;
2968
2969 /* Set the Stack Data */
2970 StackPtr = IoGetNextIrpStackLocation(Irp);
2971 StackPtr->MajorFunction = IRP_MJ_READ;
2972 StackPtr->FileObject = FileObject;
2973 StackPtr->Parameters.Read.Key = CapturedKey;
2974 StackPtr->Parameters.Read.Length = Length;
2975 StackPtr->Parameters.Read.ByteOffset = CapturedByteOffset;
2976
2977 /* Check if this is buffered I/O */
2978 if (DeviceObject->Flags & DO_BUFFERED_IO)
2979 {
2980 /* Check if we have a buffer length */
2981 if (Length)
2982 {
2983 /* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
2984 _SEH2_TRY
2985 {
2986 /* Allocate a buffer */
2987 Irp->AssociatedIrp.SystemBuffer =
2989 }
2991 {
2992 /* Allocating failed, clean up and return the exception code */
2995 }
2996 _SEH2_END;
2997
2998 /* Set the buffer and flags */
2999 Irp->UserBuffer = Buffer;
3000 Irp->Flags = (IRP_BUFFERED_IO |
3003 }
3004 else
3005 {
3006 /* Not reading anything */
3008 }
3009 }
3010 else if (DeviceObject->Flags & DO_DIRECT_IO)
3011 {
3012 /* Check if we have a buffer length */
3013 if (Length)
3014 {
3015 _SEH2_TRY
3016 {
3017 /* Allocate an MDL */
3019 if (!Mdl)
3022 }
3024 {
3025 /* Allocating failed, clean up and return the exception code */
3028 }
3029 _SEH2_END;
3030
3031 }
3032
3033 /* No allocation flags */
3034 Irp->Flags = 0;
3035 }
3036 else
3037 {
3038 /* No allocation flags, and use the buffer directly */
3039 Irp->Flags = 0;
3040 Irp->UserBuffer = Buffer;
3041 }
3042
3043 /* Now set the deferred read flags */
3045
3047
3048 /* Perform the call */
3050 Irp,
3051 FileObject,
3052 TRUE,
3054 Synchronous,
3056}
static __inline VOID IopUpdateTransferCount(IN IOP_TRANSFER_TYPE Type, IN ULONG TransferCount)
Definition: io_x.h:116
#define FILE_USE_FILE_POINTER_POSITION
Definition: nt_native.h:780
@ IopReadTransfer
Definition: io.h:261
#define ProbeForReadUlong(Ptr)
Definition: probe.h:65
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
PFAST_IO_READ FastIoRead
Definition: iotypes.h:1735
struct _LARGE_INTEGER::@2300 u
#define IRP_READ_OPERATION
#define FO_MAILSLOT
Definition: iotypes.h:1784

◆ NtReadFileScatter()

NTSTATUS NTAPI NtReadFileScatter ( IN HANDLE  FileHandle,
IN HANDLE Event  OPTIONAL,
IN PIO_APC_ROUTINE UserApcRoutine  OPTIONAL,
IN PVOID UserApcContext  OPTIONAL,
OUT PIO_STATUS_BLOCK  UserIoStatusBlock,
IN FILE_SEGMENT_ELEMENT  BufferDescription[],
IN ULONG  BufferLength,
IN PLARGE_INTEGER  ByteOffset,
IN PULONG Key  OPTIONAL 
)

Definition at line 3063 of file iofunc.c.

3072{
3075}

Referenced by ReadFileScatter().

◆ NtRequestDeviceWakeup()

NTSTATUS NTAPI NtRequestDeviceWakeup ( IN HANDLE  DeviceHandle)

Definition at line 4642 of file iofunc.c.

4643{
4646}

Referenced by RequestDeviceWakeup().

◆ NtSetEaFile()

NTSTATUS NTAPI NtSetEaFile ( IN HANDLE  FileHandle,
IN PIO_STATUS_BLOCK  IoStatusBlock,
IN PVOID  EaBuffer,
IN ULONG  EaBufferSize 
)

Definition at line 3082 of file iofunc.c.

3086{
3089}

◆ NtSetInformationFile()

NTSTATUS NTAPI NtSetInformationFile ( IN HANDLE  FileHandle,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
IN PVOID  FileInformation,
IN ULONG  Length,
IN FILE_INFORMATION_CLASS  FileInformationClass 
)

Definition at line 3096 of file iofunc.c.

3101{
3104 PIRP Irp;
3106 PIO_STACK_LOCATION StackPtr;
3108 PKEVENT Event = NULL;
3109 BOOLEAN LocalEvent = FALSE;
3110 PKNORMAL_ROUTINE NormalRoutine;
3111 PVOID NormalContext;
3112 KIRQL OldIrql;
3113 IO_STATUS_BLOCK KernelIosb;
3114 PVOID Queue;
3117 PFILE_RENAME_INFORMATION RenameInfo;
3119 PAGED_CODE();
3120 IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
3121
3122 /* Check if we're called from user mode */
3123 if (PreviousMode != KernelMode)
3124 {
3125 /* Validate the information class */
3126 if ((FileInformationClass < 0) ||
3129 {
3130 /* Invalid class */
3132 }
3133
3134 /* Validate the length */
3136 {
3137 /* Invalid length */
3139 }
3140
3141 /* Enter SEH for probing */
3142 _SEH2_TRY
3143 {
3144 /* Probe the I/O Status block */
3146
3147 /* Probe the information */
3149 Length,
3150 (Length == sizeof(BOOLEAN)) ?
3151 sizeof(BOOLEAN) : sizeof(ULONG));
3152 }
3154 {
3155 /* Return the exception code */
3157 }
3158 _SEH2_END;
3159 }
3160 else
3161 {
3162 /* Validate the information class */
3163 if ((FileInformationClass < 0) ||
3166 {
3167 /* Invalid class */
3169 }
3170
3171 /* Validate the length */
3173 {
3174 /* Invalid length */
3176 }
3177 }
3178
3179 /* Reference the Handle */
3185 (PVOID *)&FileObject,
3186 NULL);
3187 if (!NT_SUCCESS(Status)) return Status;
3188
3189 /* Check if this is a direct open or not */
3190 if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
3191 {
3192 /* Get the device object */
3194 }
3195 else
3196 {
3197 /* Get the device object */
3199 }
3200
3201 DPRINT("Will call: %p\n", DeviceObject);
3202 DPRINT("Associated driver: %p (%wZ)\n", DeviceObject->DriverObject, &DeviceObject->DriverObject->DriverName);
3203
3204 /* Check if this is a file that was opened for Synch I/O */
3205 if (FileObject->Flags & FO_SYNCHRONOUS_IO)
3206 {
3207 /* Lock it */
3209 if (Status != STATUS_SUCCESS)
3210 {
3212 return Status;
3213 }
3214
3215 /* Check if the caller just wants the position */
3217 {
3218 /* Protect write in SEH */
3219 _SEH2_TRY
3220 {
3221 /* Write the offset */
3222 FileObject->CurrentByteOffset =
3224 CurrentByteOffset;
3225
3226 /* Fill out the I/O Status Block */
3229 }
3231 {
3232 /* Get the exception code */
3234 }
3235 _SEH2_END;
3236
3237 /* Update transfer count */
3239
3240 /* Release the file lock, dereference the file and return */
3243 return Status;
3244 }
3245 }
3246 else
3247 {
3248 /* Use local event */
3250 if (!Event)
3251 {
3254 }
3255
3257 LocalEvent = TRUE;
3258 }
3259
3260 /* Clear the File Object event */
3261 KeClearEvent(&FileObject->Event);
3262
3263 /* Allocate the IRP */
3264 Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
3266
3267 /* Set the IRP */
3268 Irp->Tail.Overlay.OriginalFileObject = FileObject;
3269 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
3270 Irp->RequestorMode = PreviousMode;
3271 Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
3272 Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
3273 Irp->UserIosb = (LocalEvent) ? &KernelIosb : IoStatusBlock;
3274 Irp->UserEvent = (LocalEvent) ? Event : NULL;
3275 Irp->AssociatedIrp.SystemBuffer = NULL;
3276 Irp->MdlAddress = NULL;
3277 Irp->UserBuffer = FileInformation;
3278
3279 /* Set the Stack Data */
3280 StackPtr = IoGetNextIrpStackLocation(Irp);
3282 StackPtr->FileObject = FileObject;
3283
3284 /* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
3285 _SEH2_TRY
3286 {
3287 /* Allocate a buffer */
3288 Irp->AssociatedIrp.SystemBuffer =
3290
3291 /* Copy the data into it */
3292 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
3294 Length);
3295 }
3297 {
3298 /* Allocating failed, clean up and return the exception code */
3301 }
3302 _SEH2_END;
3303
3304 /* Set the flags */
3305 Irp->Flags |= (IRP_BUFFERED_IO |
3308
3309 /* Set the Parameters */
3310 StackPtr->Parameters.SetFile.FileInformationClass = FileInformationClass;
3311 StackPtr->Parameters.SetFile.Length = Length;
3312
3313 /* Queue the IRP */
3315
3316 /* Update operation counts */
3318
3319 /* FIXME: Later, we can implement a lot of stuff here and avoid a driver call */
3320 /* Handle IO Completion Port quickly */
3322 {
3323 /* Check if the file object already has a completion port */
3324 if ((FileObject->Flags & FO_SYNCHRONOUS_IO) ||
3325 (FileObject->CompletionContext))
3326 {
3327 /* Fail */
3329 }
3330 else
3331 {
3332 /* Reference the Port */
3333 CompletionInfo = Irp->AssociatedIrp.SystemBuffer;
3334 Status = ObReferenceObjectByHandle(CompletionInfo->Port,
3338 (PVOID*)&Queue,
3339 NULL);
3340 if (NT_SUCCESS(Status))
3341 {
3342 /* Allocate the Context */
3344 sizeof(IO_COMPLETION_CONTEXT),
3345 IOC_TAG);
3346 if (Context)
3347 {
3348 /* Set the Data */
3349 Context->Key = CompletionInfo->Key;
3350 Context->Port = Queue;
3353 Context,
3354 NULL))
3355 {
3356 /*
3357 * Someone else set the completion port in the
3358 * meanwhile, so dereference the port and fail.
3359 */
3363 }
3364 }
3365 else
3366 {
3367 /* Dereference the Port now */
3370 }
3371 }
3372 }
3373
3374 /* Set the IRP Status */
3375 Irp->IoStatus.Status = Status;
3376 Irp->IoStatus.Information = 0;
3377 }
3381 {
3382 /* Get associated information */
3383 RenameInfo = Irp->AssociatedIrp.SystemBuffer;
3384
3385 /* Only rename if:
3386 * -> We have a name
3387 * -> In unicode
3388 * -> sizes are valid
3389 */
3390 if (RenameInfo->FileNameLength != 0 &&
3391 !(RenameInfo->FileNameLength & 1) &&
3393 {
3394 /* Properly set information received */
3396 {
3397 StackPtr->Parameters.SetFile.ClusterCount = ((PFILE_MOVE_CLUSTER_INFORMATION)RenameInfo)->ClusterCount;
3398 }
3399 else
3400 {
3401 StackPtr->Parameters.SetFile.ReplaceIfExists = RenameInfo->ReplaceIfExists;
3402 }
3403
3404 /* If we got fully path OR relative target, attempt a parent directory open */
3405 if (RenameInfo->FileName[0] == OBJ_NAME_PATH_SEPARATOR || RenameInfo->RootDirectory)
3406 {
3408 if (!NT_SUCCESS(Status))
3409 {
3410 Irp->IoStatus.Status = Status;
3411 }
3412 else
3413 {
3414 /* Call the Driver */
3416 }
3417 }
3418 else
3419 {
3420 /* Call the Driver */
3422 }
3423 }
3424 else
3425 {
3427 Irp->IoStatus.Status =