- Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of
one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some
objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third
system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile,
IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an
example).
- Cleaned up some IRP code and fixed a couple of bugs, mainly:
- Write I/O Type in IRP
- Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code)
- Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect
behaviour. Code should never depend on a buffer being zeroed!
- Remove a lot of duplicated code and helper/alternate functions that weren't really useful.
- Free MDL and IRP on some failures where we didn't
- Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted
in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the
old revision and copy/pasting the new code directly above it. The functions which we touched are:
- IoAllocateIrp
- IoBuild[A]SyncronousFsdRequest
- IoBuildDeviceIoControlRequest
- IoInitializeIrp
- IoPageRead, IoSynchronousPageWrite
svn path=/trunk/; revision=14837
UnitInfo = (PSCSI_INQUIRY_DATA)
((PUCHAR)AdapterBusInfo + sizeof(SCSI_ADAPTER_BUS_INFO) +
(sizeof(SCSI_BUS_DATA) * (AdapterBusInfo->NumberOfBuses - 1)));
+
+ /*
+ * RANT:
+ * Whoever originally coded this to depend on the IRP's System Buffer to be
+ * magically cleared for him should never be allowed to code drivers again.
+ */
+ RtlZeroMemory(UnitInfo, sizeof(*UnitInfo));
for (Bus = 0; Bus < AdapterBusInfo->NumberOfBuses; Bus++)
{
io/adapter.o \
io/arcname.o \
io/bootlog.o \
- io/buildirp.o \
- io/cancel.o \
- io/cleanup.o \
io/controller.o \
- io/create.o \
io/device.o \
io/deviface.o \
- io/dir.o \
+ io/disk.o \
io/driver.o \
io/efi.o \
io/error.o \
io/event.o \
io/file.o \
- io/flush.o \
io/fs.o \
io/iocomp.o \
- io/ioctrl.o \
io/iomgr.o \
io/iowork.o \
io/irp.o \
io/irq.o \
- io/lock.o \
- io/mailslot.o \
io/mdl.o \
- io/npipe.o \
- io/page.o \
- io/parttab.o \
io/plugplay.o \
- io/process.o \
io/pnpdma.o \
io/pnpmgr.o \
io/pnpnotify.o \
io/pnpreport.o \
io/pnproot.o \
- io/queue.o \
io/rawfs.o \
io/remlock.o \
io/resource.o \
- io/rw.o \
io/share.o \
- io/shutdown.o \
io/symlink.o \
io/timer.o \
io/vpb.o \
- io/wdm.o \
io/wmi.o \
- io/xhaldisp.o \
- io/xhaldrv.o
# Object Manager (Ob)
OBJECTS_OB = \
MmBuildMdlForNonPagedPool(Mdl);
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = IoPageWrite(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, &Event, &IoStatus);
+ Status = IoSynchronousPageWrite(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, &Event, &IoStatus);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
((PPFN_TYPE)(Mdl + 1))[i] = CcZeroPage;
}
KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = IoPageWrite(FileObject, Mdl, &WriteOffset, &Event, &Iosb);
+ Status = IoSynchronousPageWrite(FileObject, Mdl, &WriteOffset, &Event, &Iosb);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
VOID FASTCALL
IopReinitializeDrivers(VOID);
+/* file.c */
+NTSTATUS
+STDCALL
+IopCreateFile(PVOID ObjectBody,
+ PVOID Parent,
+ PWSTR RemainingPath,
+ POBJECT_ATTRIBUTES ObjectAttributes);
+
+VOID
+STDCALL
+IopDeleteFile(PVOID ObjectBody);
+
+NTSTATUS
+STDCALL
+IopSecurityFile(PVOID ObjectBody,
+ SECURITY_OPERATION_CODE OperationCode,
+ SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ PULONG BufferLength);
+
+NTSTATUS
+STDCALL
+IopQueryNameFile(PVOID ObjectBody,
+ POBJECT_NAME_INFORMATION ObjectNameInfo,
+ ULONG Length,
+ PULONG ReturnLength);
+
+VOID
+STDCALL
+IopCloseFile(PVOID ObjectBody,
+ ULONG HandleCount);
+
/* plugplay.c */
NTSTATUS INIT_FUNCTION
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/buildirp.c
- * PURPOSE: Building various types of irp
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS ******************************************************************/
-
-#define TAG_SYS_BUF TAG('S', 'B', 'U', 'F')
-
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS IoPrepareIrpBuffer(PIRP Irp,
- PDEVICE_OBJECT DeviceObject,
- PVOID Buffer,
- ULONG Length,
- ULONG MajorFunction)
-/*
- * FUNCTION: Prepares the buffer to be used for an IRP
- */
-{
- Irp->UserBuffer = Buffer;
- if (DeviceObject->Flags & DO_BUFFERED_IO)
- {
- DPRINT("Doing buffer i/o\n");
- Irp->AssociatedIrp.SystemBuffer =
- (PVOID)ExAllocatePoolWithTag(NonPagedPool,Length, TAG_SYS_BUF);
- if (Irp->AssociatedIrp.SystemBuffer==NULL)
- {
- return(STATUS_NOT_IMPLEMENTED);
- }
- /* FIXME: should copy buffer in on other ops */
- if (MajorFunction == IRP_MJ_WRITE)
- {
- RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length);
- }
- }
- if (DeviceObject->Flags & DO_DIRECT_IO)
- {
- DPRINT("Doing direct i/o\n");
-
- Irp->MdlAddress = MmCreateMdl(NULL,Buffer,Length);
- if(Irp->MdlAddress == NULL) {
- DPRINT("MmCreateMdl: Out of memory!");
- return(STATUS_NO_MEMORY);
- }
- if (MajorFunction == IRP_MJ_READ)
- {
- MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
- }
- else
- {
- MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoReadAccess);
- }
- Irp->UserBuffer = NULL;
- Irp->AssociatedIrp.SystemBuffer = NULL;
- }
- return(STATUS_SUCCESS);
-}
-
-
-/*
- * @implemented
- */
-PIRP STDCALL
-IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
- PDEVICE_OBJECT DeviceObject,
- PVOID Buffer,
- ULONG Length,
- PLARGE_INTEGER StartingOffset,
- PIO_STATUS_BLOCK IoStatusBlock)
-/*
- * FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
- * ARGUMENTS:
- * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
- * IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
- * DeviceObject = Device object to send the irp to
- * Buffer = Buffer into which data will be read or written
- * Length = Length in bytes of the irp to be allocated
- * StartingOffset = Starting offset on the device
- * IoStatusBlock (OUT) = Storage for the result of the operation
- * RETURNS: The IRP allocated on success, or
- * NULL on failure
- */
-{
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
-
- DPRINT("IoBuildAsynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
- "Buffer %x, Length %x, StartingOffset %x, "
- "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
- StartingOffset,IoStatusBlock);
-
- Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
- if (Irp==NULL)
- {
- return(NULL);
- }
-
- Irp->UserIosb = IoStatusBlock;
- DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = (UCHAR)MajorFunction;
- StackPtr->MinorFunction = 0;
- StackPtr->Flags = 0;
- StackPtr->Control = 0;
- StackPtr->DeviceObject = DeviceObject;
- StackPtr->FileObject = NULL;
- StackPtr->CompletionRoutine = NULL;
-
- if (Length > 0)
- {
- NTSTATUS Status = STATUS_SUCCESS;
-
- _SEH_FILTER(FreeAndGoOn)
- {
- IoFreeIrp(Irp);
- return EXCEPTION_CONTINUE_SEARCH;
- }
- _SEH_TRY_FILTER(FreeAndGoOn)
- {
- Status = IoPrepareIrpBuffer(Irp,
- DeviceObject,
- Buffer,
- Length,
- MajorFunction);
- }
- _SEH_HANDLE
- {
- KEBUGCHECK(0);
- }
- _SEH_END;
-
- if (!NT_SUCCESS(Status))
- {
- IoFreeIrp(Irp);
- return NULL;
- }
- }
-
- if (MajorFunction == IRP_MJ_READ)
- {
- StackPtr->Parameters.Read.Length = Length;
- if (StartingOffset!=NULL)
- {
- StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
- }
- else
- {
- StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
- }
- }
- else if (MajorFunction == IRP_MJ_WRITE)
- {
- StackPtr->Parameters.Write.Length = Length;
- if (StartingOffset!=NULL)
- {
- StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
- }
- else
- {
- StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
- }
- }
-
- return(Irp);
-}
-
-
-/*
- * @implemented
- */
-PIRP STDCALL
-IoBuildDeviceIoControlRequest(ULONG IoControlCode,
- PDEVICE_OBJECT DeviceObject,
- PVOID InputBuffer,
- ULONG InputBufferLength,
- PVOID OutputBuffer,
- ULONG OutputBufferLength,
- BOOLEAN InternalDeviceIoControl,
- PKEVENT Event,
- PIO_STATUS_BLOCK IoStatusBlock)
-/*
- * FUNCTION: Allocates and sets up an IRP to be sent to drivers
- * ARGUMENTS:
- * IoControlCode = Device io control code
- * DeviceObject = Device object to send the irp to
- * InputBuffer = Buffer from which data will be read by the driver
- * InputBufferLength = Length in bytes of the input buffer
- * OutputBuffer = Buffer into which data will be written by the driver
- * OutputBufferLength = Length in bytes of the output buffer
- * InternalDeviceIoControl = Determines weather
- * IRP_MJ_INTERNAL_DEVICE_CONTROL or
- * IRP_MJ_DEVICE_CONTROL will be used
- * Event = Event used to notify the caller of completion
- * IoStatusBlock (OUT) = Storage for the result of the operation
- * RETURNS: The IRP allocated on success, or
- * NULL on failure
- */
-{
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- ULONG BufferLength;
-
- DPRINT("IoBuildDeviceIoRequest(IoControlCode %x, DeviceObject %x, "
- "InputBuffer %x, InputBufferLength %x, OutputBuffer %x, "
- "OutputBufferLength %x, InternalDeviceIoControl %x "
- "Event %x, IoStatusBlock %x\n",IoControlCode,DeviceObject,
- InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength,
- InternalDeviceIoControl,Event,IoStatusBlock);
-
- Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
- if (Irp==NULL)
- {
- return(NULL);
- }
-
- Irp->UserEvent = Event;
- Irp->UserIosb = IoStatusBlock;
- DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = InternalDeviceIoControl ?
- IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
- StackPtr->MinorFunction = 0;
- StackPtr->Flags = 0;
- StackPtr->Control = 0;
- StackPtr->DeviceObject = DeviceObject;
- StackPtr->FileObject = NULL;
- StackPtr->CompletionRoutine = NULL;
- StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
- StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
- StackPtr->Parameters.DeviceIoControl.OutputBufferLength =
- OutputBufferLength;
-
- switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
- {
- case METHOD_BUFFERED:
- DPRINT("Using METHOD_BUFFERED!\n");
-
- if (InputBufferLength > OutputBufferLength)
- {
- BufferLength = InputBufferLength;
- }
- else
- {
- BufferLength = OutputBufferLength;
- }
- if (BufferLength)
- {
- Irp->AssociatedIrp.SystemBuffer = (PVOID)
- ExAllocatePoolWithTag(NonPagedPool,BufferLength, TAG_SYS_BUF);
-
- if (Irp->AssociatedIrp.SystemBuffer == NULL)
- {
- IoFreeIrp(Irp);
- return(NULL);
- }
- }
-
- if (InputBuffer && InputBufferLength)
- {
- RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
- InputBuffer,
- InputBufferLength);
- RtlZeroMemory((char*)Irp->AssociatedIrp.SystemBuffer + InputBufferLength,
- BufferLength - InputBufferLength);
- }
- else
- {
- RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer,
- BufferLength);
- }
- Irp->UserBuffer = OutputBuffer;
- break;
-
- case METHOD_IN_DIRECT:
- DPRINT("Using METHOD_IN_DIRECT!\n");
-
- /* build input buffer (control buffer) */
- if (InputBuffer && InputBufferLength)
- {
- Irp->AssociatedIrp.SystemBuffer = (PVOID)
- ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
- TAG_SYS_BUF);
-
- if (Irp->AssociatedIrp.SystemBuffer==NULL)
- {
- IoFreeIrp(Irp);
- return(NULL);
- }
-
- RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
- InputBuffer,
- InputBufferLength);
- }
-
- /* build output buffer (data transfer buffer) */
- if (OutputBuffer && OutputBufferLength)
- {
- Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
- OutputBufferLength,
- FALSE,
- FALSE,
- Irp);
- if (Irp->MdlAddress == NULL)
- {
- IoFreeIrp(Irp);
- return NULL;
- }
-
- _SEH_FILTER(FreeAndGoOn)
- {
- IoFreeIrp(Irp);
- return EXCEPTION_CONTINUE_SEARCH;
- }
- _SEH_TRY_FILTER(FreeAndGoOn)
- {
- MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoReadAccess);
- }
- _SEH_HANDLE
- {
- KEBUGCHECK(0);
- }
- _SEH_END;
-
- }
- break;
-
- case METHOD_OUT_DIRECT:
- DPRINT("Using METHOD_OUT_DIRECT!\n");
-
- /* build input buffer (control buffer) */
- if (InputBuffer && InputBufferLength)
- {
- Irp->AssociatedIrp.SystemBuffer = (PVOID)
- ExAllocatePoolWithTag(NonPagedPool,InputBufferLength,
- TAG_SYS_BUF);
-
- if (Irp->AssociatedIrp.SystemBuffer==NULL)
- {
- IoFreeIrp(Irp);
- return(NULL);
- }
-
- RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
- InputBuffer,
- InputBufferLength);
- }
-
- /* build output buffer (data transfer buffer) */
- if (OutputBuffer && OutputBufferLength)
- {
- Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
- OutputBufferLength,
- FALSE,
- FALSE,
- Irp);
- if (Irp->MdlAddress == NULL)
- {
- IoFreeIrp(Irp);
- return NULL;
- }
-
- _SEH_FILTER(FreeAndGoOn)
- {
- IoFreeIrp(Irp);
- return EXCEPTION_CONTINUE_SEARCH;
- }
- _SEH_TRY_FILTER(FreeAndGoOn)
- {
- MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
- }
- _SEH_HANDLE
- {
- KEBUGCHECK(0);
- }
- _SEH_END;
- }
- break;
-
- case METHOD_NEITHER:
- DPRINT("Using METHOD_NEITHER!\n");
-
- Irp->UserBuffer = OutputBuffer;
- StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
- break;
- }
-
- /* synchronous irp's are queued to requestor thread's irp cancel/cleanup list */
- IoQueueThreadIrp(Irp);
- return(Irp);
-}
-
-
-/*
- * @implemented
- */
-PIRP STDCALL
-IoBuildSynchronousFsdRequest(ULONG MajorFunction,
- PDEVICE_OBJECT DeviceObject,
- PVOID Buffer,
- ULONG Length,
- PLARGE_INTEGER StartingOffset,
- PKEVENT Event,
- PIO_STATUS_BLOCK IoStatusBlock)
-/*
- * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
- * level driver(s)
- * ARGUMENTS:
- * MajorFunction = Major function code, one of IRP_MJ_READ,
- * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
- * DeviceObject = Target device object
- * Buffer = Buffer containing data for a read or write
- * Length = Length in bytes of the information to be transferred
- * StartingOffset = Offset to begin the read/write from
- * Event (OUT) = Will be set when the operation is complete
- * IoStatusBlock (OUT) = Set to the status of the operation
- * RETURNS: The IRP allocated on success, or
- * NULL on failure
- */
-{
- PIRP Irp;
-
- DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
- "Buffer %x, Length %x, StartingOffset %x, Event %x, "
- "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
- StartingOffset,Event,IoStatusBlock);
-
- Irp = IoBuildAsynchronousFsdRequest(MajorFunction,
- DeviceObject,
- Buffer,
- Length,
- StartingOffset,
- IoStatusBlock );
- if (Irp==NULL)
- {
- return(NULL);
- }
-
- Irp->UserEvent = Event;
-
- /* synchronous irp's are queued to requestor thread's irp cancel/cleanup list */
- IoQueueThreadIrp(Irp);
- return(Irp);
-}
-
-
-PIRP
-IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
- PDEVICE_OBJECT DeviceObject,
- PMDL Mdl,
- PLARGE_INTEGER StartingOffset,
- PKEVENT Event,
- PIO_STATUS_BLOCK IoStatusBlock,
- BOOLEAN PagingIo)
-/*
- * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
- * level driver(s)
- * ARGUMENTS:
- * MajorFunction = Major function code, one of IRP_MJ_READ,
- * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
- * DeviceObject = Target device object
- * Buffer = Buffer containing data for a read or write
- * Length = Length in bytes of the information to be transferred
- * StartingOffset = Offset to begin the read/write from
- * Event (OUT) = Will be set when the operation is complete
- * IoStatusBlock (OUT) = Set to the status of the operation
- * RETURNS: The IRP allocated on success, or
- * NULL on failure
- */
-{
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
-
- DPRINT("IoBuildSynchronousFsdRequestWithMdl(MajorFunction %x, "
- "DeviceObject %x, "
- "Mdl %x, StartingOffset %x, Event %x, "
- "IoStatusBlock %x\n",MajorFunction,DeviceObject,Mdl,
- StartingOffset,Event,IoStatusBlock);
-
- Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
- if (Irp==NULL)
- {
- return(NULL);
- }
-
- Irp->UserEvent = Event;
- Irp->UserIosb = IoStatusBlock;
- DPRINT("Irp->UserIosb %x\n", Irp->UserIosb);
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- if (PagingIo)
- {
- Irp->Flags = IRP_PAGING_IO;
- }
- else
- {
- Irp->Flags = 0;
- }
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = (UCHAR)MajorFunction;
- StackPtr->MinorFunction = 0;
- StackPtr->Flags = 0;
- StackPtr->Control = 0;
- StackPtr->DeviceObject = DeviceObject;
- StackPtr->FileObject = NULL;
- StackPtr->CompletionRoutine = NULL;
-
- Irp->MdlAddress = Mdl;
- Irp->UserBuffer = MmGetMdlVirtualAddress(Mdl);
- Irp->AssociatedIrp.SystemBuffer = NULL;
-
- if (MajorFunction == IRP_MJ_READ)
- {
- if (StartingOffset != NULL)
- {
- StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
- }
- else
- {
- StackPtr->Parameters.Read.ByteOffset.QuadPart = 0;
- }
- StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
- }
- else
- {
- if (StartingOffset!=NULL)
- {
- StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
- }
- else
- {
- StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
- }
- StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);
- }
-
- return(Irp);
-}
-
-/* EOF */
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/cancel.c
- * PURPOSE: Cancel routine
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS *******************************************************************/
-
-static KSPIN_LOCK CancelSpinLock;
-
-/* FUNCTIONS *****************************************************************/
-
-/**
- * @name NtCancelIoFile
- *
- * Cancel all pending I/O operations in the current thread for specified
- * file object.
- *
- * @param FileHandle
- * Handle to file object to cancel requests for. No specific
- * access rights are needed.
- * @param IoStatusBlock
- * Pointer to status block which is filled with final completition
- * status on successful return.
- *
- * @return Status.
- *
- * @implemented
- */
-
-NTSTATUS STDCALL
-NtCancelIoFile(
- IN HANDLE FileHandle,
- OUT PIO_STATUS_BLOCK IoStatusBlock)
-{
- NTSTATUS Status;
- PFILE_OBJECT FileObject;
- PETHREAD Thread;
- PLIST_ENTRY IrpEntry;
- PIRP Irp;
- KIRQL OldIrql;
- BOOLEAN OurIrpsInList = FALSE;
- LARGE_INTEGER Interval;
-
- if ((ULONG_PTR)IoStatusBlock >= MmUserProbeAddress &&
- KeGetPreviousMode() == UserMode)
- return STATUS_ACCESS_VIOLATION;
-
- Status = ObReferenceObjectByHandle(FileHandle, 0, IoFileObjectType,
- KeGetPreviousMode(), (PVOID*)&FileObject,
- NULL);
- if (!NT_SUCCESS(Status))
- return Status;
-
- /* IRP cancellations are synchronized at APC_LEVEL. */
- OldIrql = KfRaiseIrql(APC_LEVEL);
-
- /*
- * Walk the list of active IRPs and cancel the ones that belong to
- * our file object.
- */
-
- Thread = PsGetCurrentThread();
- for (IrpEntry = Thread->IrpList.Flink;
- IrpEntry != &Thread->IrpList;
- IrpEntry = IrpEntry->Flink)
- {
- Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
- if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
- {
- IoCancelIrp(Irp);
- /* Don't break here, we want to cancel all IRPs for the file object. */
- OurIrpsInList = TRUE;
- }
- }
-
- KfLowerIrql(OldIrql);
-
- while (OurIrpsInList)
- {
- OurIrpsInList = FALSE;
-
- /* Wait a short while and then look if all our IRPs were completed. */
- Interval.QuadPart = -1000000; /* 100 milliseconds */
- KeDelayExecutionThread(KernelMode, FALSE, &Interval);
-
- OldIrql = KfRaiseIrql(APC_LEVEL);
-
- /*
- * Look in the list if all IRPs for the specified file object
- * are completed (or cancelled). If someone sends a new IRP
- * for our file object while we're here we can happily loop
- * forever.
- */
-
- for (IrpEntry = Thread->IrpList.Flink;
- IrpEntry != &Thread->IrpList;
- IrpEntry = IrpEntry->Flink)
- {
- Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
- if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
- {
- OurIrpsInList = TRUE;
- break;
- }
- }
-
- KfLowerIrql(OldIrql);
- }
-
- _SEH_TRY
- {
- IoStatusBlock->Status = STATUS_SUCCESS;
- IoStatusBlock->Information = 0;
- Status = STATUS_SUCCESS;
- }
- _SEH_HANDLE
- {
- Status = STATUS_UNSUCCESSFUL;
- }
- _SEH_END;
-
- ObDereferenceObject(FileObject);
-
- return Status;
-}
-
-/**
- * @name IoCancelThreadIo
- *
- * Cancel all pending I/O request associated with specified thread.
- *
- * @param Thread
- * Thread to cancel requests for.
- */
-
-VOID STDCALL
-IoCancelThreadIo(PETHREAD Thread)
-{
- PLIST_ENTRY IrpEntry;
- PIRP Irp;
- KIRQL OldIrql;
- ULONG Retries = 3000;
- LARGE_INTEGER Interval;
-
- OldIrql = KfRaiseIrql(APC_LEVEL);
-
- /*
- * Start by cancelling all the IRPs in the current thread queue.
- */
-
- for (IrpEntry = Thread->IrpList.Flink;
- IrpEntry != &Thread->IrpList;
- IrpEntry = IrpEntry->Flink)
- {
- Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
- IoCancelIrp(Irp);
- }
-
- /*
- * Wait till all the IRPs are completed or cancelled.
- */
-
- while (!IsListEmpty(&Thread->IrpList))
- {
- KfLowerIrql(OldIrql);
-
- /* Wait a short while and then look if all our IRPs were completed. */
- Interval.QuadPart = -1000000; /* 100 milliseconds */
- KeDelayExecutionThread(KernelMode, FALSE, &Interval);
-
- /*
- * Don't stay here forever if some broken driver doesn't complete
- * the IRP.
- */
-
- if (Retries-- == 0)
- {
- /* FIXME: Handle this gracefully. */
- DPRINT1("Thread with dead IRPs!");
- ASSERT(FALSE);
- }
-
- OldIrql = KfRaiseIrql(APC_LEVEL);
- }
-
- KfLowerIrql(OldIrql);
-}
-
-/*
- * @implemented
- */
-BOOLEAN STDCALL
-IoCancelIrp(PIRP Irp)
-{
- KIRQL oldlvl;
- PDRIVER_CANCEL CancelRoutine;
-
- DPRINT("IoCancelIrp(Irp %x)\n",Irp);
-
- IoAcquireCancelSpinLock(&oldlvl);
-
- Irp->Cancel = TRUE;
-
- CancelRoutine = IoSetCancelRoutine(Irp, NULL);
- if (CancelRoutine == NULL)
- {
- IoReleaseCancelSpinLock(oldlvl);
- return(FALSE);
- }
-
- Irp->CancelIrql = oldlvl;
- CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
- return(TRUE);
-}
-
-VOID INIT_FUNCTION
-IoInitCancelHandling(VOID)
-{
- KeInitializeSpinLock(&CancelSpinLock);
-}
-
-/*
- * @implemented
- */
-VOID STDCALL
-IoAcquireCancelSpinLock(PKIRQL Irql)
-{
- KeAcquireSpinLock(&CancelSpinLock,Irql);
-}
-
-/*
- * @implemented
- */
-VOID STDCALL
-IoReleaseCancelSpinLock(KIRQL Irql)
-{
- KeReleaseSpinLock(&CancelSpinLock,Irql);
-}
-
-/* EOF */
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/cleanup.c
- * PURPOSE: IRP cleanup
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS ***************************************************************/
-
-VOID IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PIO_STACK_LOCATION IoStack)
-{
- ULONG IoControlCode;
- ULONG OutputBufferLength;
-
- if (IoStack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL)
- {
- IoControlCode =
- IoStack->Parameters.FileSystemControl.FsControlCode;
- OutputBufferLength =
- IoStack->Parameters.FileSystemControl.OutputBufferLength;
- }
- else
- {
- IoControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
- if (NT_SUCCESS(Irp->IoStatus.Status))
- {
- OutputBufferLength = Irp->IoStatus.Information;
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < OutputBufferLength)
- {
- OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
- }
- }
- else
- {
- OutputBufferLength = 0;
- }
- }
-
- switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
- {
- case METHOD_BUFFERED:
- DPRINT ("Using METHOD_BUFFERED!\n");
-
- /* copy output buffer back and free it */
- if (Irp->AssociatedIrp.SystemBuffer)
- {
- if (OutputBufferLength)
- {
- RtlCopyMemory(Irp->UserBuffer,
- Irp->AssociatedIrp.SystemBuffer,
- OutputBufferLength);
- }
- ExFreePool (Irp->AssociatedIrp.SystemBuffer);
- }
- break;
-
- case METHOD_IN_DIRECT:
- DPRINT ("Using METHOD_IN_DIRECT!\n");
- /* use the same code as for METHOD_OUT_DIRECT */
-
- case METHOD_OUT_DIRECT:
- DPRINT ("Using METHOD_OUT_DIRECT!\n");
-
- /* free input buffer (control buffer) */
- if (Irp->AssociatedIrp.SystemBuffer)
- ExFreePool (Irp->AssociatedIrp.SystemBuffer);
-
- /* free output buffer (data transfer buffer) */
- if (Irp->MdlAddress)
- IoFreeMdl (Irp->MdlAddress);
- break;
-
- case METHOD_NEITHER:
- DPRINT ("Using METHOD_NEITHER!\n");
- /* nothing to do */
- break;
- }
-}
-
-VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PIO_STACK_LOCATION IoStack)
-{
- PFILE_OBJECT FileObject;
-
- FileObject = IoStack->FileObject;
-
- if (DeviceObject->Flags & DO_BUFFERED_IO)
- {
- if (IoStack->MajorFunction == IRP_MJ_READ)
- {
- DPRINT("Copying buffered io back to user\n");
- memcpy(Irp->UserBuffer,Irp->AssociatedIrp.SystemBuffer,
- IoStack->Parameters.Read.Length);
- }
- ExFreePool(Irp->AssociatedIrp.SystemBuffer);
- }
-
- if (DeviceObject->Flags & DO_DIRECT_IO)
- {
- if (Irp->MdlAddress)
- {
- IoFreeMdl(Irp->MdlAddress);
- }
- }
-}
-
-VOID IoVolumeInformationCompletion(PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PIO_STACK_LOCATION IoStack)
-{
-}
-
-
-VOID STDCALL
-IoSecondStageCompletion_KernelApcRoutine(
- IN PKAPC Apc,
- IN OUT PKNORMAL_ROUTINE *NormalRoutine,
- IN OUT PVOID *NormalContext,
- IN OUT PVOID *SystemArgument1,
- IN OUT PVOID *SystemArgument2
- )
-{
- PIRP Irp;
-
- Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
- IoFreeIrp(Irp);
-}
-
-
-VOID STDCALL
-IoSecondStageCompletion_RundownApcRoutine(
- IN PKAPC Apc
- )
-{
- PIRP Irp;
-
- Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
- IoFreeIrp(Irp);
-}
-
-
-/*
- * FUNCTION: Performs the second stage of irp completion for read/write irps
- *
- * Called as a special kernel APC kernel-routine or directly from IofCompleteRequest()
- */
-VOID STDCALL
-IoSecondStageCompletion(
- PKAPC Apc,
- PKNORMAL_ROUTINE* NormalRoutine,
- PVOID* NormalContext,
- PVOID* SystemArgument1,
- PVOID* SystemArgument2)
-
-{
- PIO_STACK_LOCATION IoStack;
- PDEVICE_OBJECT DeviceObject;
- PFILE_OBJECT OriginalFileObject;
- PIRP Irp;
-
- if (Apc) DPRINT("IoSecondStageCompletition with APC: %x\n", Apc);
-
- OriginalFileObject = (PFILE_OBJECT)(*SystemArgument1);
- DPRINT("OriginalFileObject: %x\n", OriginalFileObject);
-
- Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
- DPRINT("Irp: %x\n", Irp);
-
- /*
- * Note that we'll never see irp's flagged IRP_PAGING_IO (IRP_MOUNT_OPERATION)
- * or IRP_CLOSE_OPERATION (IRP_MJ_CLOSE and IRP_MJ_CLEANUP) here since their
- * cleanup/completion is fully taken care of in IoCompleteRequest.
- * -Gunnar
- */
-
- /*
- Remove synchronous irp's from the threads cleanup list.
- To synchronize with the code inserting the entry, this code must run
- at APC_LEVEL
- */
- if (!IsListEmpty(&Irp->ThreadListEntry))
- {
- RemoveEntryList(&Irp->ThreadListEntry);
- InitializeListHead(&Irp->ThreadListEntry);
- }
-
- IoStack = (PIO_STACK_LOCATION)(Irp+1) + Irp->CurrentLocation;
- DeviceObject = IoStack->DeviceObject;
-
- DPRINT("IoSecondStageCompletion(Irp %x, MajorFunction %x)\n", Irp, IoStack->MajorFunction);
-
- switch (IoStack->MajorFunction)
- {
- case IRP_MJ_CREATE:
- case IRP_MJ_FLUSH_BUFFERS:
- /* NOP */
- break;
-
- case IRP_MJ_READ:
- case IRP_MJ_WRITE:
- IoReadWriteCompletion(DeviceObject,Irp,IoStack);
- break;
-
- case IRP_MJ_DEVICE_CONTROL:
- case IRP_MJ_INTERNAL_DEVICE_CONTROL:
- case IRP_MJ_FILE_SYSTEM_CONTROL:
- IoDeviceControlCompletion(DeviceObject, Irp, IoStack);
- break;
-
- case IRP_MJ_QUERY_VOLUME_INFORMATION:
- case IRP_MJ_SET_VOLUME_INFORMATION:
- IoVolumeInformationCompletion(DeviceObject, Irp, IoStack);
- break;
-
- default:
- break;
- }
-
- if (Irp->UserIosb!=NULL)
- {
- if (Irp->RequestorMode == KernelMode)
- {
- *Irp->UserIosb = Irp->IoStatus;
- }
- else
- {
- DPRINT("Irp->RequestorMode == UserMode\n");
- MmSafeCopyToUser(Irp->UserIosb,
- &Irp->IoStatus,
- sizeof(IO_STATUS_BLOCK));
- }
- }
-
- if (Irp->UserEvent)
- {
- KeSetEvent(Irp->UserEvent,0,FALSE);
- }
-
- //Windows NT File System Internals, page 169
- if (OriginalFileObject)
- {
- if (Irp->UserEvent == NULL)
- {
- KeSetEvent(&OriginalFileObject->Event,0,FALSE);
- }
- else if (OriginalFileObject->Flags & FO_SYNCHRONOUS_IO && Irp->UserEvent != &OriginalFileObject->Event)
- {
- KeSetEvent(&OriginalFileObject->Event,0,FALSE);
- }
- }
-
- //Windows NT File System Internals, page 154
- if (OriginalFileObject)
- {
- // if the event is not the one in the file object, it needs dereferenced
- if (Irp->UserEvent && Irp->UserEvent != &OriginalFileObject->Event)
- {
- ObDereferenceObject(Irp->UserEvent);
- }
-
- ObDereferenceObject(OriginalFileObject);
- }
-
- if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
- {
- PKNORMAL_ROUTINE UserApcRoutine;
- PVOID UserApcContext;
-
- DPRINT("Dispatching user APC\n");
-
- UserApcRoutine = (PKNORMAL_ROUTINE)Irp->Overlay.AsynchronousParameters.UserApcRoutine;
- UserApcContext = (PVOID)Irp->Overlay.AsynchronousParameters.UserApcContext;
-
- KeInitializeApc( &Irp->Tail.Apc,
- KeGetCurrentThread(),
- CurrentApcEnvironment,
- IoSecondStageCompletion_KernelApcRoutine,
- IoSecondStageCompletion_RundownApcRoutine,
- UserApcRoutine,
- UserMode,
- UserApcContext);
-
- KeInsertQueueApc( &Irp->Tail.Apc,
- Irp->UserIosb,
- NULL,
- 2);
-
- //NOTE: kernel (or rundown) routine frees the IRP
-
- return;
-
- }
-
- if (NULL != IoStack->FileObject
- && NULL != IoStack->FileObject->CompletionContext
- && (0 != (Irp->Flags & IRP_SYNCHRONOUS_API)
- || 0 == (IoStack->FileObject->Flags & FO_SYNCHRONOUS_IO)))
- {
- PFILE_OBJECT FileObject = IoStack->FileObject;
- IoSetIoCompletion(FileObject->CompletionContext->Port,
- FileObject->CompletionContext->Key,
- Irp->Overlay.AsynchronousParameters.UserApcContext,
- Irp->IoStatus.Status,
- Irp->IoStatus.Information,
- FALSE);
- }
-
- IoFreeIrp(Irp);
-}
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/create.c
- * PURPOSE: Handling file create/open apis
- *
- * PROGRAMMERS: David Welch (welch@cwcom.net)
- */
-
-/* INCLUDES ***************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS *******************************************************************/
-
-#define TAG_FILE_NAME TAG('F', 'N', 'A', 'M')
-
-/* FUNCTIONS *************************************************************/
-
-/**********************************************************************
- * NAME EXPORTED
- * NtDeleteFile@4
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- * ObjectAttributes
- * ?
- *
- * RETURN VALUE
- *
- * REVISIONS
- *
- * @unimplemented
- */
-NTSTATUS STDCALL
-NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
-{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
-}
-
-
-/**********************************************************************
- * NAME INTERNAL
- * IopCreateFile
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *
- * RETURN VALUE
- *
- * REVISIONS
- */
-NTSTATUS STDCALL
-IopCreateFile(PVOID ObjectBody,
- PVOID Parent,
- PWSTR RemainingPath,
- POBJECT_ATTRIBUTES ObjectAttributes)
-{
- PDEVICE_OBJECT DeviceObject;
- PFILE_OBJECT FileObject = (PFILE_OBJECT) ObjectBody;
- POBJECT_TYPE ParentObjectType;
- NTSTATUS Status;
-
- DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
- ObjectBody,
- Parent,
- RemainingPath);
-
- if (NULL == Parent)
- {
- /* This is probably an attempt to create a meta fileobject (eg. for FAT)
- for the cache manager, so return STATUS_SUCCESS */
- DPRINT("Parent object was NULL\n");
- return(STATUS_SUCCESS);
- }
-
- ParentObjectType = BODY_TO_HEADER(Parent)->ObjectType;
-
- if (ParentObjectType != IoDeviceObjectType &&
- ParentObjectType != IoFileObjectType)
- {
- DPRINT("Parent [%wZ] is a %S which is neither a file type nor a device type ; remaining path = %S\n",
- &BODY_TO_HEADER(Parent)->Name,
- BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer,
- RemainingPath);
- return(STATUS_UNSUCCESSFUL);
- }
-
- Status = ObReferenceObjectByPointer(Parent,
- STANDARD_RIGHTS_REQUIRED,
- ParentObjectType,
- UserMode);
- if (!NT_SUCCESS(Status))
- {
- CPRINT("Failed to reference parent object %x\n", Parent);
- return(Status);
- }
-
- if (ParentObjectType == IoDeviceObjectType)
- {
- /* Parent is a devce object */
- DeviceObject = IoGetAttachedDevice((PDEVICE_OBJECT)Parent);
- DPRINT("DeviceObject %x\n", DeviceObject);
-
- if (RemainingPath == NULL)
- {
- FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
- FileObject->FileName.Buffer = 0;
- FileObject->FileName.Length = FileObject->FileName.MaximumLength = 0;
- }
- else
- {
- if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
- && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
- && (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
- && (DeviceObject->DeviceType != FILE_DEVICE_TAPE)
- && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
- && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
- && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
- {
- CPRINT("Device was wrong type\n");
- return(STATUS_UNSUCCESSFUL);
- }
-
- if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
- && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
- && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
- {
- if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
- {
- DPRINT("Mount the logical volume\n");
- Status = IoMountVolume(DeviceObject, FALSE);
- DPRINT("Status %x\n", Status);
- if (!NT_SUCCESS(Status))
- {
- CPRINT("Failed to mount logical volume (Status %x)\n",
- Status);
- return(Status);
- }
- }
- DeviceObject = DeviceObject->Vpb->DeviceObject;
- DPRINT("FsDeviceObject %lx\n", DeviceObject);
- }
- RtlpCreateUnicodeString(&(FileObject->FileName),
- RemainingPath, NonPagedPool);
- }
- }
- else
- {
- /* Parent is a file object */
- if (RemainingPath == NULL)
- {
- CPRINT("Device is unnamed\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- DeviceObject = ((PFILE_OBJECT)Parent)->DeviceObject;
- DPRINT("DeviceObject %x\n", DeviceObject);
-
- FileObject->RelatedFileObject = (PFILE_OBJECT)Parent;
-
- RtlpCreateUnicodeString(&(FileObject->FileName),
- RemainingPath, NonPagedPool);
- }
-
- DPRINT("FileObject->FileName %wZ\n",
- &FileObject->FileName);
- FileObject->DeviceObject = DeviceObject;
- DPRINT("FileObject %x DeviceObject %x\n",
- FileObject,
- DeviceObject);
- FileObject->Vpb = DeviceObject->Vpb;
- FileObject->Type = IO_TYPE_FILE;
-
- return(STATUS_SUCCESS);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * IoCreateStreamFileObject@8
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- * FileObject
- * ?
- *
- * DeviceObject
- * ?
- *
- * RETURN VALUE
- *
- * NOTE
- *
- * REVISIONS
- *
- * @implemented
- */
-PFILE_OBJECT STDCALL
-IoCreateStreamFileObject(PFILE_OBJECT FileObject,
- PDEVICE_OBJECT DeviceObject)
-{
- PFILE_OBJECT CreatedFileObject;
- NTSTATUS Status;
-
- DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
- FileObject, DeviceObject);
-
- ASSERT_IRQL(PASSIVE_LEVEL);
-
- Status = ObCreateObject(KernelMode,
- IoFileObjectType,
- NULL,
- KernelMode,
- NULL,
- sizeof(FILE_OBJECT),
- 0,
- 0,
- (PVOID*)&CreatedFileObject);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Could not create FileObject\n");
- return (NULL);
- }
-
- if (FileObject != NULL)
- {
- DeviceObject = FileObject->DeviceObject;
- }
- DeviceObject = IoGetAttachedDevice(DeviceObject);
-
- DPRINT("DeviceObject %x\n", DeviceObject);
-
- if (DeviceObject->Vpb &&
- DeviceObject->Vpb->DeviceObject)
- {
- CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject;
- }
- else
- {
- CreatedFileObject->DeviceObject = DeviceObject;
- }
- CreatedFileObject->Vpb = DeviceObject->Vpb;
- CreatedFileObject->Type = IO_TYPE_FILE;
- CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
-
- // shouldn't we initialize the lock event, and several other things here too?
- KeInitializeEvent(&CreatedFileObject->Event, NotificationEvent, FALSE);
- KeInitializeEvent(&CreatedFileObject->Lock, SynchronizationEvent, TRUE);
-
- return CreatedFileObject;
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * IoCreateFile@56
- *
- * DESCRIPTION
- * Either causes a new file or directory to be created, or it
- * opens an existing file, device, directory or volume, giving
- * the caller a handle for the file object. This handle can be
- * used by subsequent calls to manipulate data within the file
- * or the file object's state of attributes.
- *
- * ARGUMENTS
- * FileHandle (OUT)
- * Points to a variable which receives the file handle
- * on return;
- *
- * DesiredAccess
- * Desired access to the file;
- *
- * ObjectAttributes
- * Structure describing the file;
- *
- * IoStatusBlock (OUT)
- * Receives information about the operation on return;
- *
- * AllocationSize [OPTIONAL]
- * Initial size of the file in bytes;
- *
- * FileAttributes
- * Attributes to create the file with;
- *
- * ShareAccess
- * Type of shared access the caller would like to the
- * file;
- *
- * CreateDisposition
- * Specifies what to do, depending on whether the
- * file already exists;
- *
- * CreateOptions
- * Options for creating a new file;
- *
- * EaBuffer [OPTIONAL]
- * Undocumented;
- *
- * EaLength
- * Undocumented;
- *
- * CreateFileType
- * Type of file (normal, named pipe, mailslot) to create;
- *
- * ExtraCreateParameters [OPTIONAL]
- * Additional creation data for named pipe and mailsots;
- *
- * Options
- * Undocumented.
- *
- * RETURN VALUE
- * Status
- *
- * NOTE
- * Prototype taken from Bo Branten's ntifs.h v15.
- * Description taken from old NtCreateFile's which is
- * now a wrapper of this call.
- *
- * REVISIONS
- *
- * @implemented
- */
-NTSTATUS STDCALL
-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 CreateDisposition,
- IN ULONG CreateOptions,
- IN PVOID EaBuffer OPTIONAL,
- IN ULONG EaLength,
- IN CREATE_FILE_TYPE CreateFileType,
- IN PVOID ExtraCreateParameters OPTIONAL,
- IN ULONG Options)
-{
- PFILE_OBJECT FileObject = NULL;
- PDEVICE_OBJECT DeviceObject;
- PIRP Irp;
- PIO_STACK_LOCATION StackLoc;
- IO_SECURITY_CONTEXT SecurityContext;
- KPROCESSOR_MODE AccessMode;
- HANDLE LocalHandle;
- IO_STATUS_BLOCK LocalIoStatusBlock;
- LARGE_INTEGER SafeAllocationSize;
- PVOID SystemEaBuffer = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
-
- DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
- "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
- FileHandle,DesiredAccess,ObjectAttributes,
- ObjectAttributes->ObjectName->Buffer);
-
- ASSERT_IRQL(PASSIVE_LEVEL);
-
- if (IoStatusBlock == NULL || FileHandle == NULL)
- return STATUS_ACCESS_VIOLATION;
-
- LocalHandle = 0;
-
- if(Options & IO_NO_PARAMETER_CHECKING)
- AccessMode = KernelMode;
- else
- AccessMode = ExGetPreviousMode();
-
- if(AccessMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWrite(FileHandle,
- sizeof(HANDLE),
- sizeof(ULONG));
- ProbeForWrite(IoStatusBlock,
- sizeof(IO_STATUS_BLOCK),
- sizeof(ULONG));
- if(AllocationSize != NULL)
- {
- ProbeForRead(AllocationSize,
- sizeof(LARGE_INTEGER),
- sizeof(ULONG));
- SafeAllocationSize = *AllocationSize;
- }
- else
- SafeAllocationSize.QuadPart = 0;
-
- if(EaBuffer != NULL && EaLength > 0)
- {
- ProbeForRead(EaBuffer,
- EaLength,
- sizeof(ULONG));
-
- /* marshal EaBuffer */
- SystemEaBuffer = ExAllocatePool(NonPagedPool,
- EaLength);
- if(SystemEaBuffer == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- _SEH_LEAVE;
- }
-
- RtlCopyMemory(SystemEaBuffer,
- EaBuffer,
- EaLength);
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
- }
- else
- {
- if(AllocationSize != NULL)
- SafeAllocationSize = *AllocationSize;
- else
- SafeAllocationSize.QuadPart = 0;
-
- if(EaBuffer != NULL && EaLength > 0)
- {
- SystemEaBuffer = EaBuffer;
- }
- }
-
- if(Options & IO_CHECK_CREATE_PARAMETERS)
- {
- DPRINT1("FIXME: IO_CHECK_CREATE_PARAMETERS not yet supported!\n");
- }
-
- if (CreateDisposition == FILE_OPEN ||
- CreateDisposition == FILE_OPEN_IF)
- {
- Status = ObOpenObjectByName(ObjectAttributes,
- NULL,
- NULL,
- AccessMode,
- DesiredAccess,
- NULL,
- &LocalHandle);
- if (NT_SUCCESS(Status))
- {
- Status = ObReferenceObjectByHandle(LocalHandle,
- DesiredAccess,
- NULL,
- AccessMode,
- (PVOID*)&DeviceObject,
- NULL);
- ZwClose(LocalHandle);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
- if (BODY_TO_HEADER(DeviceObject)->ObjectType != IoDeviceObjectType)
- {
- ObDereferenceObject (DeviceObject);
- return STATUS_OBJECT_NAME_COLLISION;
- }
- FileObject = IoCreateStreamFileObject(NULL, DeviceObject);
- ObDereferenceObject (DeviceObject);
- }
- }
-
-
- if (FileObject == NULL)
- {
- Status = ObCreateObject(AccessMode,
- IoFileObjectType,
- ObjectAttributes,
- AccessMode,
- NULL,
- sizeof(FILE_OBJECT),
- 0,
- 0,
- (PVOID*)&FileObject);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ObCreateObject() failed! (Status %lx)\n", Status);
- return Status;
- }
- }
- RtlMapGenericMask(&DesiredAccess,
- BODY_TO_HEADER(FileObject)->ObjectType->Mapping);
-
- Status = ObInsertObject ((PVOID)FileObject,
- NULL,
- DesiredAccess,
- 0,
- NULL,
- &LocalHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ObInsertObject() failed! (Status %lx)\n", Status);
- ObDereferenceObject (FileObject);
- return Status;
- }
-
- if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
- {
- FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
- }
- if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
- {
- FileObject->Flags |= FO_SYNCHRONOUS_IO;
- }
-
- if (CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)
- FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
-
- SecurityContext.SecurityQos = NULL; /* ?? */
- SecurityContext.AccessState = NULL; /* ?? */
- SecurityContext.DesiredAccess = DesiredAccess;
- SecurityContext.FullCreateOptions = 0; /* ?? */
-
- KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
- KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
-
- DPRINT("FileObject %x\n", FileObject);
- DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
- /*
- * Create a new IRP to hand to
- * the FS driver: this may fail
- * due to resource shortage.
- */
- Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
- if (Irp == NULL)
- {
- ZwClose(LocalHandle);
- return STATUS_UNSUCCESSFUL;
- }
-
- //trigger FileObject/Event dereferencing
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = AccessMode;
- Irp->UserIosb = &LocalIoStatusBlock;
- Irp->AssociatedIrp.SystemBuffer = SystemEaBuffer;
- Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- Irp->UserEvent = &FileObject->Event;
- Irp->Overlay.AllocationSize = SafeAllocationSize;
-
- /*
- * Get the stack location for the new
- * IRP and prepare it.
- */
- StackLoc = IoGetNextIrpStackLocation(Irp);
- StackLoc->MinorFunction = 0;
- StackLoc->Flags = (UCHAR)Options;
- StackLoc->Control = 0;
- StackLoc->DeviceObject = FileObject->DeviceObject;
- StackLoc->FileObject = FileObject;
-
- switch (CreateFileType)
- {
- default:
- case CreateFileTypeNone:
- StackLoc->MajorFunction = IRP_MJ_CREATE;
- StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
- StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
- StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
- StackLoc->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
- StackLoc->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
- StackLoc->Parameters.Create.EaLength = SystemEaBuffer != NULL ? EaLength : 0;
- break;
-
- case CreateFileTypeNamedPipe:
- StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
- StackLoc->Parameters.CreatePipe.SecurityContext = &SecurityContext;
- StackLoc->Parameters.CreatePipe.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
- StackLoc->Parameters.CreatePipe.Options |= (CreateDisposition << 24);
- StackLoc->Parameters.CreatePipe.ShareAccess = (USHORT)ShareAccess;
- StackLoc->Parameters.CreatePipe.Parameters = ExtraCreateParameters;
- break;
-
- case CreateFileTypeMailslot:
- StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
- StackLoc->Parameters.CreateMailslot.SecurityContext = &SecurityContext;
- StackLoc->Parameters.CreateMailslot.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
- StackLoc->Parameters.CreateMailslot.Options |= (CreateDisposition << 24);
- StackLoc->Parameters.CreateMailslot.ShareAccess = (USHORT)ShareAccess;
- StackLoc->Parameters.CreateMailslot.Parameters = ExtraCreateParameters;
- break;
- }
-
- /*
- * Now call the driver and
- * possibly wait if it can
- * not complete the request
- * immediately.
- */
- Status = IofCallDriver(FileObject->DeviceObject, Irp );
-
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&FileObject->Event,
- Executive,
- AccessMode,
- FALSE,
- NULL);
- Status = LocalIoStatusBlock.Status;
- }
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Failing create request with status %x\n", Status);
- FileObject->DeviceObject = NULL;
- FileObject->Vpb = NULL;
-
- ZwClose(LocalHandle);
- }
- else
- {
- _SEH_TRY
- {
- *FileHandle = LocalHandle;
- *IoStatusBlock = LocalIoStatusBlock;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
- }
-
- /* cleanup EABuffer if captured */
- if(AccessMode != KernelMode && SystemEaBuffer != NULL)
- {
- ExFreePool(SystemEaBuffer);
- }
-
- ASSERT_IRQL(PASSIVE_LEVEL);
-
- DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
-
- return Status;
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * NtCreateFile@44
- *
- * DESCRIPTION
- * Entry point to call IoCreateFile with
- * default parameters.
- *
- * ARGUMENTS
- * See IoCreateFile.
- *
- * RETURN VALUE
- * See IoCreateFile.
- *
- * REVISIONS
- * 2000-03-25 (ea)
- * Code originally in NtCreateFile moved in IoCreateFile.
- *
- * @implemented
- */
-NTSTATUS STDCALL
-NtCreateFile(PHANDLE FileHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- PIO_STATUS_BLOCK IoStatusBlock,
- PLARGE_INTEGER AllocateSize,
- ULONG FileAttributes,
- ULONG ShareAccess,
- ULONG CreateDisposition,
- ULONG CreateOptions,
- PVOID EaBuffer,
- ULONG EaLength)
-{
- return IoCreateFile(FileHandle,
- DesiredAccess,
- ObjectAttributes,
- IoStatusBlock,
- AllocateSize,
- FileAttributes,
- ShareAccess,
- CreateDisposition,
- CreateOptions,
- EaBuffer,
- EaLength,
- CreateFileTypeNone,
- NULL,
- 0);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * NtOpenFile@24
- *
- * DESCRIPTION
- * Opens an existing file (simpler than NtCreateFile).
- *
- * ARGUMENTS
- * FileHandle (OUT)
- * Variable that receives the file handle on return;
- *
- * DesiredAccess
- * Access desired by the caller to the file;
- *
- * ObjectAttributes
- * Structue describing the file to be opened;
- *
- * IoStatusBlock (OUT)
- * Receives details about the result of the
- * operation;
- *
- * ShareAccess
- * Type of shared access the caller requires;
- *
- * OpenOptions
- * Options for the file open.
- *
- * RETURN VALUE
- * Status.
- *
- * NOTE
- * Undocumented.
- *
- * @implemented
- */
-NTSTATUS STDCALL
-NtOpenFile(PHANDLE FileHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- PIO_STATUS_BLOCK IoStatusBlock,
- ULONG ShareAccess,
- ULONG OpenOptions)
-{
- return IoCreateFile(FileHandle,
- DesiredAccess,
- ObjectAttributes,
- IoStatusBlock,
- NULL,
- 0,
- ShareAccess,
- FILE_OPEN,
- OpenOptions,
- NULL,
- 0,
- CreateFileTypeNone,
- NULL,
- 0);
-}
-
-/* EOF */
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS Kernel
* FILE: ntoskrnl/io/device.c
- * PURPOSE: Manage devices
+ * PURPOSE: Device Object Management, including Notifications and Queues.
*
- * PROGRAMMERS: David Welch (welch@cwcom.net)
+ * PROGRAMMERS: Alex Ionescu
+ * David Welch (welch@cwcom.net)
*/
/* INCLUDES *******************************************************************/
/* GLOBALS ********************************************************************/
#define TAG_DEVICE_EXTENSION TAG('D', 'E', 'X', 'T')
+#define TAG_SHUTDOWN_ENTRY TAG('S', 'H', 'U', 'T')
static ULONG IopDeviceObjectNumber = 0;
+typedef struct _SHUTDOWN_ENTRY
+{
+ LIST_ENTRY ShutdownList;
+ PDEVICE_OBJECT DeviceObject;
+} SHUTDOWN_ENTRY, *PSHUTDOWN_ENTRY;
+
+LIST_ENTRY ShutdownListHead;
+KSPIN_LOCK ShutdownListLock;
+
/* PRIVATE FUNCTIONS **********************************************************/
-NTSTATUS FASTCALL
-IopInitializeDevice(
- PDEVICE_NODE DeviceNode,
- PDRIVER_OBJECT DriverObject)
+VOID
+IoShutdownRegisteredDevices(VOID)
+{
+ PSHUTDOWN_ENTRY ShutdownEntry;
+ PLIST_ENTRY Entry;
+ IO_STATUS_BLOCK StatusBlock;
+ PIRP Irp;
+ KEVENT Event;
+ NTSTATUS Status;
+
+ Entry = ShutdownListHead.Flink;
+ while (Entry != &ShutdownListHead)
+ {
+ ShutdownEntry = CONTAINING_RECORD(Entry, SHUTDOWN_ENTRY, ShutdownList);
+
+ KeInitializeEvent (&Event,
+ NotificationEvent,
+ FALSE);
+
+ Irp = IoBuildSynchronousFsdRequest (IRP_MJ_SHUTDOWN,
+ ShutdownEntry->DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
+
+ Status = IoCallDriver (ShutdownEntry->DeviceObject,
+ Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject (&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
+
+ Entry = Entry->Flink;
+ }
+}
+
+NTSTATUS
+FASTCALL
+IopInitializeDevice(PDEVICE_NODE DeviceNode,
+ PDRIVER_OBJECT DriverObject)
{
IO_STATUS_BLOCK IoStatusBlock;
IO_STACK_LOCATION Stack;
*/
NTSTATUS
STDCALL
-IoRegisterLastChanceShutdownNotification(
- IN PDEVICE_OBJECT DeviceObject
- )
+IoRegisterLastChanceShutdownNotification(IN PDEVICE_OBJECT DeviceObject)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
+{
+ PSHUTDOWN_ENTRY Entry;
+
+ Entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_ENTRY),
+ TAG_SHUTDOWN_ENTRY);
+ if (Entry == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ Entry->DeviceObject = DeviceObject;
+
+ ExInterlockedInsertHeadList(&ShutdownListHead,
+ &Entry->ShutdownList,
+ &ShutdownListLock);
+
+ DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED;
+
+ return STATUS_SUCCESS;
}
/*
*/
VOID
STDCALL
-IoSetStartIoAttributes(
- IN PDEVICE_OBJECT DeviceObject,
- IN BOOLEAN DeferredStartIo,
- IN BOOLEAN NonCancelable
- )
+IoSetStartIoAttributes(IN PDEVICE_OBJECT DeviceObject,
+ IN BOOLEAN DeferredStartIo,
+ IN BOOLEAN NonCancelable)
+{
+ UNIMPLEMENTED;
+}
+
+/*
+ * @implemented
+ *
+ * FUNCTION: Dequeues the next packet from the given device object's
+ * associated device queue according to a specified sort-key value and calls
+ * the drivers StartIo routine with that IRP
+ * ARGUMENTS:
+ * DeviceObject = Device object for which the irp is to dequeued
+ * Cancelable = True if IRPs in the key can be canceled
+ * Key = Sort key specifing which entry to remove from the queue
+ */
+VOID
+STDCALL
+IoStartNextPacketByKey(PDEVICE_OBJECT DeviceObject,
+ BOOLEAN Cancelable,
+ ULONG Key)
+{
+ PKDEVICE_QUEUE_ENTRY entry;
+ PIRP Irp;
+
+ entry = KeRemoveByKeyDeviceQueue(&DeviceObject->DeviceQueue,
+ Key);
+
+ if (entry != NULL)
+ {
+ Irp = CONTAINING_RECORD(entry,
+ IRP,
+ Tail.Overlay.DeviceQueueEntry);
+ DeviceObject->CurrentIrp = Irp;
+ DPRINT("Next irp is %x\n", Irp);
+ DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
+ }
+ else
+ {
+ DPRINT("No next irp\n");
+ DeviceObject->CurrentIrp = NULL;
+ }
+}
+
+/*
+ * @implemented
+ *
+ * FUNCTION: Removes the next packet from the device's queue and calls
+ * the driver's StartIO
+ * ARGUMENTS:
+ * DeviceObject = Device
+ * Cancelable = True if irps in the queue can be canceled
+ */
+VOID
+STDCALL
+IoStartNextPacket(PDEVICE_OBJECT DeviceObject,
+ BOOLEAN Cancelable)
{
- UNIMPLEMENTED;
+ PKDEVICE_QUEUE_ENTRY entry;
+ PIRP Irp;
+
+ DPRINT("IoStartNextPacket(DeviceObject %x, Cancelable %d)\n",
+ DeviceObject,Cancelable);
+
+ entry = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
+
+ if (entry!=NULL)
+ {
+ Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
+ DeviceObject->CurrentIrp = Irp;
+ DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
+ }
+ else
+ {
+ DeviceObject->CurrentIrp = NULL;
+ }
+}
+
+/*
+ * @implemented
+ *
+ * FUNCTION: Either call the device's StartIO routine with the packet or,
+ * if the device is busy, queue it.
+ * ARGUMENTS:
+ * DeviceObject = Device to start the packet on
+ * Irp = Irp to queue
+ * Key = Where to insert the irp
+ * If zero then insert in the tail of the queue
+ * CancelFunction = Optional function to cancel the irqp
+ */
+VOID
+STDCALL
+IoStartPacket(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PULONG Key,
+ PDRIVER_CANCEL CancelFunction)
+{
+ BOOLEAN stat;
+ KIRQL oldirql;
+
+ DPRINT("IoStartPacket(Irp %x)\n", Irp);
+
+ ASSERT_IRQL(DISPATCH_LEVEL);
+
+ IoAcquireCancelSpinLock(&oldirql);
+
+ if (CancelFunction != NULL)
+ {
+ Irp->CancelRoutine = CancelFunction;
+ }
+
+ if (Key!=0)
+ {
+ stat = KeInsertByKeyDeviceQueue(&DeviceObject->DeviceQueue,
+ &Irp->Tail.Overlay.DeviceQueueEntry,
+ *Key);
+ }
+ else
+ {
+ stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
+ &Irp->Tail.Overlay.DeviceQueueEntry);
+ }
+
+
+ if (!stat)
+ {
+ IoReleaseCancelSpinLock(DISPATCH_LEVEL);
+ DeviceObject->CurrentIrp = Irp;
+ DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
+ if (oldirql < DISPATCH_LEVEL)
+ {
+ KeLowerIrql(oldirql);
+ }
+ }
+ else
+ {
+ IoReleaseCancelSpinLock(oldirql);
+ }
+
}
/*
*/
VOID
STDCALL
-IoSynchronousInvalidateDeviceRelations(
- IN PDEVICE_OBJECT DeviceObject,
- IN DEVICE_RELATION_TYPE Type
- )
+IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
+ IN DEVICE_RELATION_TYPE Type)
+{
+ UNIMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
{
- UNIMPLEMENTED;
+ PSHUTDOWN_ENTRY ShutdownEntry;
+ PLIST_ENTRY Entry;
+ KIRQL oldlvl;
+
+ Entry = ShutdownListHead.Flink;
+ while (Entry != &ShutdownListHead)
+ {
+ ShutdownEntry = CONTAINING_RECORD(Entry, SHUTDOWN_ENTRY, ShutdownList);
+ if (ShutdownEntry->DeviceObject == DeviceObject)
+ {
+ DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
+
+ KeAcquireSpinLock(&ShutdownListLock,&oldlvl);
+ RemoveEntryList(Entry);
+ KeReleaseSpinLock(&ShutdownListLock,oldlvl);
+
+ ExFreePool(Entry);
+ return;
+ }
+
+ Entry = Entry->Flink;
+ }
}
/*
*/
NTSTATUS
STDCALL
-IoValidateDeviceIoControlAccess(
- IN PIRP Irp,
- IN ULONG RequiredAccess
- )
+IoValidateDeviceIoControlAccess(IN PIRP Irp,
+ IN ULONG RequiredAccess)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+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 Status;
+ PFILE_OBJECT FileObject;
+ PDEVICE_OBJECT DeviceObject;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
+ PKEVENT EventObject;
+ KPROCESSOR_MODE PreviousMode;
+
+ DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
+ "UserApcContext %x IoStatusBlock %x IoControlCode %x "
+ "InputBuffer %x InputBufferLength %x OutputBuffer %x "
+ "OutputBufferLength %x)\n",
+ DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
+ IoControlCode,InputBuffer,InputBufferLength,OutputBuffer,
+ OutputBufferLength);
+
+ if (IoStatusBlock == NULL)
+ return STATUS_ACCESS_VIOLATION;
+
+ PreviousMode = ExGetPreviousMode();
+
+ /* Check granted access against the access rights from IoContolCode */
+ Status = ObReferenceObjectByHandle (DeviceHandle,
+ (IoControlCode >> 14) & 0x3,
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID *) &FileObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ if (Event != NULL)
+ {
+ Status = ObReferenceObjectByHandle (Event,
+ SYNCHRONIZE,
+ ExEventObjectType,
+ PreviousMode,
+ (PVOID*)&EventObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject (FileObject);
+ return Status;
+ }
+ }
+ else
+ {
+ EventObject = &FileObject->Event;
+ KeResetEvent (EventObject);
+ }
+
+ DeviceObject = FileObject->DeviceObject;
+
+ Irp = IoBuildDeviceIoControlRequest (IoControlCode,
+ DeviceObject,
+ InputBuffer,
+ InputBufferLength,
+ OutputBuffer,
+ OutputBufferLength,
+ FALSE,
+ EventObject,
+ IoStatusBlock);
+
+ /* Trigger FileObject/Event dereferencing */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+
+ Irp->RequestorMode = PreviousMode;
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
+
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = FileObject;
+ StackPtr->DeviceObject = DeviceObject;
+ StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
+ StackPtr->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
+
+ Status = IoCallDriver(DeviceObject,Irp);
+ if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ Status = KeWaitForSingleObject (EventObject,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ if (Status != STATUS_WAIT_0)
+ {
+ /* Wait failed. */
+ return Status;
+ }
+
+ Status = IoStatusBlock->Status;
+ }
+
+ return Status;
}
/* EOF */
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/dir.c
- * PURPOSE: Directory functions
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-NtNotifyChangeDirectoryFile (
- 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 BufferSize,
- IN ULONG CompletionFilter,
- IN BOOLEAN WatchTree
- )
-{
- PIRP Irp;
- PDEVICE_OBJECT DeviceObject;
- PFILE_OBJECT FileObject;
- PIO_STACK_LOCATION IoStack;
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status = STATUS_SUCCESS;
-
- DPRINT("NtNotifyChangeDirectoryFile()\n");
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- if(PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWrite(IoStatusBlock,
- sizeof(IO_STATUS_BLOCK),
- sizeof(ULONG));
- if(BufferSize != 0)
- {
- ProbeForWrite(Buffer,
- BufferSize,
- sizeof(ULONG));
- }
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
- }
-
- Status = ObReferenceObjectByHandle(FileHandle,
- FILE_LIST_DIRECTORY,
- IoFileObjectType,
- PreviousMode,
- (PVOID *)&FileObject,
- NULL);
-
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
- DeviceObject = FileObject->DeviceObject;
-
- Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
- if (Irp==NULL)
- {
- ObDereferenceObject(FileObject);
- return STATUS_UNSUCCESSFUL;
- }
-
- if (Event == NULL)
- {
- Event = &FileObject->Event;
- }
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = PreviousMode;
- Irp->UserIosb = IoStatusBlock;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- Irp->UserEvent = Event;
- KeResetEvent( Event );
- Irp->UserBuffer = Buffer;
- Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
- Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
-
- IoStack = IoGetNextIrpStackLocation(Irp);
-
- IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
- IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY;
- IoStack->Flags = 0;
- IoStack->Control = 0;
- IoStack->DeviceObject = DeviceObject;
- IoStack->FileObject = FileObject;
-
- if (WatchTree)
- {
- IoStack->Flags = SL_WATCH_TREE;
- }
-
- IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
- IoStack->Parameters.NotifyDirectory.Length = BufferSize;
-
- Status = IoCallDriver(FileObject->DeviceObject,Irp);
-
- /* FIXME: Should we wait here or not for synchronously opened files? */
-
- return Status;
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-NtQueryDirectoryFile(
- IN HANDLE FileHandle,
- IN HANDLE PEvent 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
- )
-/*
- * FUNCTION: Queries a directory file.
- * ARGUMENTS:
- * FileHandle = Handle to a directory file
- * EventHandle = Handle to the event signaled on completion
- * ApcRoutine = Asynchroneous procedure callback, called on completion
- * ApcContext = Argument to the apc.
- * IoStatusBlock = Caller supplies storage for extended status information.
- * FileInformation = Caller supplies storage for the resulting information.
- *
- * FileNameInformation FILE_NAMES_INFORMATION
- * FileDirectoryInformation FILE_DIRECTORY_INFORMATION
- * FileFullDirectoryInformation FILE_FULL_DIRECTORY_INFORMATION
- * FileBothDirectoryInformation FILE_BOTH_DIR_INFORMATION
- *
- * Length = Size of the storage supplied
- * FileInformationClass = Indicates the type of information requested.
- * ReturnSingleEntry = Specify true if caller only requests the first
- * directory found.
- * FileName = Initial directory name to query, that may contain wild
- * cards.
- * RestartScan = Number of times the action should be repeated
- * RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES,
- * STATUS_INVALID_PARAMETER, STATUS_INVALID_DEVICE_REQUEST, STATUS_BUFFER_OVERFLOW,
- * STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ]
- */
-{
- PIRP Irp;
- PDEVICE_OBJECT DeviceObject;
- PFILE_OBJECT FileObject;
- PIO_STACK_LOCATION IoStack;
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status = STATUS_SUCCESS;
-
- DPRINT("NtQueryDirectoryFile()\n");
-
- PAGED_CODE();
-
- PreviousMode = ExGetPreviousMode();
-
- if(PreviousMode != KernelMode)
- {
- _SEH_TRY
- {
- ProbeForWrite(IoStatusBlock,
- sizeof(IO_STATUS_BLOCK),
- sizeof(ULONG));
- ProbeForWrite(FileInformation,
- Length,
- sizeof(ULONG));
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
- }
-
- Status = ObReferenceObjectByHandle(FileHandle,
- FILE_LIST_DIRECTORY,
- IoFileObjectType,
- PreviousMode,
- (PVOID *)&FileObject,
- NULL);
-
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
- DeviceObject = FileObject->DeviceObject;
-
- Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
- if (Irp==NULL)
- {
- ObDereferenceObject(FileObject);
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = PreviousMode;
- Irp->UserIosb = IoStatusBlock;
- Irp->UserEvent = &FileObject->Event;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- KeResetEvent( &FileObject->Event );
- Irp->UserBuffer=FileInformation;
- Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
- Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
-
- IoStack = IoGetNextIrpStackLocation(Irp);
-
- IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
- IoStack->MinorFunction = IRP_MN_QUERY_DIRECTORY;
- IoStack->Flags = 0;
- IoStack->Control = 0;
- IoStack->DeviceObject = DeviceObject;
- IoStack->FileObject = FileObject;
-
- if (RestartScan)
- {
- IoStack->Flags = IoStack->Flags | SL_RESTART_SCAN;
- }
- if (ReturnSingleEntry)
- {
- IoStack->Flags = IoStack->Flags | SL_RETURN_SINGLE_ENTRY;
- }
- if (((PFILE_DIRECTORY_INFORMATION)FileInformation)->FileIndex != 0)
- {
- IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
- }
-
- IoStack->Parameters.QueryDirectory.FileInformationClass =
- FileInformationClass;
- IoStack->Parameters.QueryDirectory.FileName = FileName;
- IoStack->Parameters.QueryDirectory.Length = Length;
-
- Status = IoCallDriver(FileObject->DeviceObject,Irp);
- if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
- {
- KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- Status = IoStatusBlock->Status;
- }
-
- return(Status);
-}
-
-/* EOF */
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/xhaldrv.c
- * PURPOSE: Hal drive routines
+ * FILE: ntoskrnl/io/disk.c
+ * PURPOSE: I/O Support for Hal Disk (Partition Table/MBR) Routines.
*
* PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
EZ_Drive
} DISK_MANAGER;
+HAL_DISPATCH EXPORTED HalDispatchTable =
+{
+ HAL_DISPATCH_VERSION,
+ (pHalQuerySystemInformation) NULL, // HalQuerySystemInformation
+ (pHalSetSystemInformation) NULL, // HalSetSystemInformation
+ (pHalQueryBusSlots) NULL, // HalQueryBusSlots
+ 0,
+ (pHalExamineMBR) xHalExamineMBR,
+ (pHalIoAssignDriveLetters) xHalIoAssignDriveLetters,
+ (pHalIoReadPartitionTable) xHalIoReadPartitionTable,
+ (pHalIoSetPartitionInformation) xHalIoSetPartitionInformation,
+ (pHalIoWritePartitionTable) xHalIoWritePartitionTable,
+ (pHalHandlerForBus) NULL, // HalReferenceHandlerForBus
+ (pHalReferenceBusHandler) NULL, // HalReferenceBusHandler
+ (pHalReferenceBusHandler) NULL, // HalDereferenceBusHandler
+ (pHalInitPnpDriver) NULL, //HalInitPnpDriver;
+ (pHalInitPowerManagement) NULL, //HalInitPowerManagement;
+ (pHalGetDmaAdapter) NULL, //HalGetDmaAdapter;
+ (pHalGetInterruptTranslator) NULL, //HalGetInterruptTranslator;
+ (pHalStartMirroring) NULL, //HalStartMirroring;
+ (pHalEndMirroring) NULL, //HalEndMirroring;
+ (pHalMirrorPhysicalMemory) NULL, //HalMirrorPhysicalMemory;
+ (pHalEndOfBoot) NULL, //HalEndOfBoot;
+ (pHalMirrorVerify) NULL //HalMirrorVerify;
+};
+
+
+HAL_PRIVATE_DISPATCH EXPORTED HalPrivateDispatchTable =
+{
+ HAL_PRIVATE_DISPATCH_VERSION
+};
+
/* FUNCTIONS *****************************************************************/
NTSTATUS
return Status;
}
+/*
+ * @unimplemented
+ *
+STDCALL
+VOID
+IoAssignDriveLetters(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PSTRING NtDeviceName,
+ OUT PUCHAR NtSystemPath,
+ OUT PSTRING NtSystemPathString
+ )
+{
+ UNIMPLEMENTED;
+*/
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoCreateDisk(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN struct _CREATE_DISK* Disk
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoGetBootDiskInformation(
+ IN OUT PBOOTDISK_INFORMATION BootDiskInformation,
+ IN ULONG Size
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoReadDiskSignature(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG BytesPerSector,
+ OUT PDISK_SIGNATURE Signature
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoReadPartitionTableEx(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN struct _DRIVE_LAYOUT_INFORMATION_EX** DriveLayout
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoSetPartitionInformationEx(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG PartitionNumber,
+ IN struct _SET_PARTITION_INFORMATION_EX* PartitionInfo
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoSetSystemPartition(
+ PUNICODE_STRING VolumeNameString
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoVerifyPartitionTable(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN BOOLEAN FixErrors
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoVolumeDeviceToDosName(
+ IN PVOID VolumeDeviceObject,
+ OUT PUNICODE_STRING DosName
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoWritePartitionTableEx(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN struct _DRIVE_LAYOUT_INFORMATION_EX* DriveLayfout
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS FASTCALL
+IoReadPartitionTable(PDEVICE_OBJECT DeviceObject,
+ ULONG SectorSize,
+ BOOLEAN ReturnRecognizedPartitions,
+ PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
+{
+ return(HalIoReadPartitionTable(DeviceObject,
+ SectorSize,
+ ReturnRecognizedPartitions,
+ PartitionBuffer));
+}
+
+
+NTSTATUS FASTCALL
+IoSetPartitionInformation(PDEVICE_OBJECT DeviceObject,
+ ULONG SectorSize,
+ ULONG PartitionNumber,
+ ULONG PartitionType)
+{
+ return(HalIoSetPartitionInformation(DeviceObject,
+ SectorSize,
+ PartitionNumber,
+ PartitionType));
+}
+
+
+NTSTATUS FASTCALL
+IoWritePartitionTable(PDEVICE_OBJECT DeviceObject,
+ ULONG SectorSize,
+ ULONG SectorsPerTrack,
+ ULONG NumberOfHeads,
+ PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
+{
+ return(HalIoWritePartitionTable(DeviceObject,
+ SectorSize,
+ SectorsPerTrack,
+ NumberOfHeads,
+ PartitionBuffer));
+}
/* EOF */
return(FALSE);
}
+/**********************************************************************
+ * NAME EXPORTED
+ * IoSetThreadHardErrorMode@4
+ *
+ * ARGUMENTS
+ * HardErrorEnabled
+ * TRUE : enable hard errors processing;
+ * FALSE: do NOT process hard errors.
+ *
+ * RETURN VALUE
+ * Previous value for the current thread's hard errors
+ * processing policy.
+ *
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
+{
+ BOOLEAN PreviousHEM = (BOOLEAN)(NtCurrentTeb()->HardErrorDisabled);
+
+ NtCurrentTeb()->HardErrorDisabled = ((TRUE == HardErrorEnabled) ? FALSE : TRUE);
+
+ return((TRUE == PreviousHEM) ? FALSE : TRUE);
+}
+
/* EOF */
-/* $Id$
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/io/file.c
+ * PURPOSE: I/O File Object & NT File Handle Access/Managment of Files.
+ *
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS *******************************************************************/
+
+#define TAG_SYSB TAG('S', 'Y', 'S', 'B')
+#define TAG_LOCK TAG('F','l','c','k')
+#define TAG_FILE_NAME TAG('F', 'N', 'A', 'M')
+
+extern GENERIC_MAPPING IopFileMapping;
+
+/* INTERNAL FUNCTIONS ********************************************************/
+
+static
+NTSTATUS
+STDCALL
+IopLockFileCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
+{
+ ExFreePool(Context);
+ return STATUS_SUCCESS;
+ // FIXME: Should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED?
+}
+
+/*
+ * NAME INTERNAL
+ * IopCreateFile
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ */
+NTSTATUS
+STDCALL
+IopCreateFile(PVOID ObjectBody,
+ PVOID Parent,
+ PWSTR RemainingPath,
+ POBJECT_ATTRIBUTES ObjectAttributes)
+{
+ PDEVICE_OBJECT DeviceObject;
+ PFILE_OBJECT FileObject = (PFILE_OBJECT) ObjectBody;
+ POBJECT_TYPE ParentObjectType;
+ NTSTATUS Status;
+
+ DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
+ ObjectBody,
+ Parent,
+ RemainingPath);
+
+ if (NULL == Parent)
+ {
+ /* This is probably an attempt to create a meta fileobject (eg. for FAT)
+ for the cache manager, so return STATUS_SUCCESS */
+ DPRINT("Parent object was NULL\n");
+ return(STATUS_SUCCESS);
+ }
+
+ ParentObjectType = BODY_TO_HEADER(Parent)->ObjectType;
+
+ if (ParentObjectType != IoDeviceObjectType &&
+ ParentObjectType != IoFileObjectType)
+ {
+ DPRINT("Parent [%wZ] is a %S which is neither a file type nor a device type ; remaining path = %S\n",
+ &BODY_TO_HEADER(Parent)->Name,
+ BODY_TO_HEADER(Parent)->ObjectType->TypeName.Buffer,
+ RemainingPath);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ Status = ObReferenceObjectByPointer(Parent,
+ STANDARD_RIGHTS_REQUIRED,
+ ParentObjectType,
+ UserMode);
+ if (!NT_SUCCESS(Status))
+ {
+ CPRINT("Failed to reference parent object %x\n", Parent);
+ return(Status);
+ }
+
+ if (ParentObjectType == IoDeviceObjectType)
+ {
+ /* Parent is a devce object */
+ DeviceObject = IoGetAttachedDevice((PDEVICE_OBJECT)Parent);
+ DPRINT("DeviceObject %x\n", DeviceObject);
+
+ if (RemainingPath == NULL)
+ {
+ FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
+ FileObject->FileName.Buffer = 0;
+ FileObject->FileName.Length = FileObject->FileName.MaximumLength = 0;
+ }
+ else
+ {
+ if ((DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM)
+ && (DeviceObject->DeviceType != FILE_DEVICE_DISK)
+ && (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
+ && (DeviceObject->DeviceType != FILE_DEVICE_TAPE)
+ && (DeviceObject->DeviceType != FILE_DEVICE_NETWORK)
+ && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
+ && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
+ {
+ CPRINT("Device was wrong type\n");
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ if (DeviceObject->DeviceType != FILE_DEVICE_NETWORK
+ && (DeviceObject->DeviceType != FILE_DEVICE_NAMED_PIPE)
+ && (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
+ {
+ if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
+ {
+ DPRINT("Mount the logical volume\n");
+ Status = IoMountVolume(DeviceObject, FALSE);
+ DPRINT("Status %x\n", Status);
+ if (!NT_SUCCESS(Status))
+ {
+ CPRINT("Failed to mount logical volume (Status %x)\n",
+ Status);
+ return(Status);
+ }
+ }
+ DeviceObject = DeviceObject->Vpb->DeviceObject;
+ DPRINT("FsDeviceObject %lx\n", DeviceObject);
+ }
+ RtlpCreateUnicodeString(&(FileObject->FileName),
+ RemainingPath, NonPagedPool);
+ }
+ }
+ else
+ {
+ /* Parent is a file object */
+ if (RemainingPath == NULL)
+ {
+ CPRINT("Device is unnamed\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ DeviceObject = ((PFILE_OBJECT)Parent)->DeviceObject;
+ DPRINT("DeviceObject %x\n", DeviceObject);
+
+ FileObject->RelatedFileObject = (PFILE_OBJECT)Parent;
+
+ RtlpCreateUnicodeString(&(FileObject->FileName),
+ RemainingPath, NonPagedPool);
+ }
+
+ DPRINT("FileObject->FileName %wZ\n",
+ &FileObject->FileName);
+ FileObject->DeviceObject = DeviceObject;
+ DPRINT("FileObject %x DeviceObject %x\n",
+ FileObject,
+ DeviceObject);
+ FileObject->Vpb = DeviceObject->Vpb;
+ FileObject->Type = IO_TYPE_FILE;
+
+ return(STATUS_SUCCESS);
+}
+
+VOID
+STDCALL
+IopDeleteFile(PVOID ObjectBody)
+{
+ PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
+ NTSTATUS Status;
+
+ DPRINT("IopDeleteFile()\n");
+
+ if (FileObject->DeviceObject)
+ {
+#if 0
+//NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
+
+ ObReferenceObjectByPointer(ObjectBody,
+ STANDARD_RIGHTS_REQUIRED,
+ IoFileObjectType,
+ UserMode);
+#endif
+ KeResetEvent( &FileObject->Event );
+
+ Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, TRUE);
+ if (Irp == NULL)
+ {
+ /*
+ * FIXME: This case should eventually be handled. We should wait
+ * until enough memory is available to allocate the IRP.
+ */
+ ASSERT(FALSE);
+ }
+
+ Irp->UserEvent = &FileObject->Event;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ Irp->Flags |= IRP_CLOSE_OPERATION;
+
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = IRP_MJ_CLOSE;
+ StackPtr->DeviceObject = FileObject->DeviceObject;
+ StackPtr->FileObject = FileObject;
+
+ Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
+ }
+ }
+
+ if (FileObject->FileName.Buffer != NULL)
+ {
+ ExFreePool(FileObject->FileName.Buffer);
+ FileObject->FileName.Buffer = 0;
+ }
+}
+
+static
+NTSTATUS
+IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ PULONG BufferLength)
+{
+ ULONG_PTR Current;
+ ULONG SidSize;
+ ULONG SdSize;
+ NTSTATUS Status;
+
+ DPRINT("IopSetDefaultSecurityDescriptor() called\n");
+
+ if (SecurityInformation == 0)
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ SidSize = RtlLengthSid(SeWorldSid);
+ SdSize = sizeof(SECURITY_DESCRIPTOR) + (2 * SidSize);
+
+ if (*BufferLength < SdSize)
+ {
+ *BufferLength = SdSize;
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ *BufferLength = SdSize;
+
+ Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ SecurityDescriptor->Control |= SE_SELF_RELATIVE;
+ Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR);
+
+ if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+ {
+ RtlCopyMemory((PVOID)Current,
+ SeWorldSid,
+ SidSize);
+ SecurityDescriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
+ Current += SidSize;
+ }
+
+ if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+ {
+ RtlCopyMemory((PVOID)Current,
+ SeWorldSid,
+ SidSize);
+ SecurityDescriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
+ Current += SidSize;
+ }
+
+ if (SecurityInformation & DACL_SECURITY_INFORMATION)
+ {
+ SecurityDescriptor->Control |= SE_DACL_PRESENT;
+ }
+
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ {
+ SecurityDescriptor->Control |= SE_SACL_PRESENT;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+STDCALL
+IopSecurityFile(PVOID ObjectBody,
+ SECURITY_OPERATION_CODE OperationCode,
+ SECURITY_INFORMATION SecurityInformation,
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ PULONG BufferLength)
+{
+ IO_STATUS_BLOCK IoStatusBlock;
+ PIO_STACK_LOCATION StackPtr;
+ PFILE_OBJECT FileObject;
+ PIRP Irp;
+ NTSTATUS Status;
+
+ DPRINT("IopSecurityFile() called\n");
+
+ FileObject = (PFILE_OBJECT)ObjectBody;
+
+ switch (OperationCode)
+ {
+ case SetSecurityDescriptor:
+ DPRINT("Set security descriptor\n");
+ KeResetEvent(&FileObject->Event);
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SET_SECURITY,
+ FileObject->DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &FileObject->Event,
+ &IoStatusBlock);
+
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = FileObject;
+
+ StackPtr->Parameters.SetSecurity.SecurityInformation = SecurityInformation;
+ StackPtr->Parameters.SetSecurity.SecurityDescriptor = SecurityDescriptor;
+
+ Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ if (Status == STATUS_INVALID_DEVICE_REQUEST)
+ {
+ Status = STATUS_SUCCESS;
+ }
+ return Status;
+
+ case QuerySecurityDescriptor:
+ DPRINT("Query security descriptor\n");
+ KeResetEvent(&FileObject->Event);
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_SECURITY,
+ FileObject->DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &FileObject->Event,
+ &IoStatusBlock);
+
+ Irp->UserBuffer = SecurityDescriptor;
+
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = FileObject;
+
+ StackPtr->Parameters.QuerySecurity.SecurityInformation = SecurityInformation;
+ StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
+
+ Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ if (Status == STATUS_INVALID_DEVICE_REQUEST)
+ {
+ Status = IopSetDefaultSecurityDescriptor(SecurityInformation,
+ SecurityDescriptor,
+ BufferLength);
+ }
+ else
+ {
+ /* FIXME: Is this correct?? */
+ *BufferLength = IoStatusBlock.Information;
+ }
+ return Status;
+
+ case DeleteSecurityDescriptor:
+ DPRINT("Delete security descriptor\n");
+ return STATUS_SUCCESS;
+
+ case AssignSecurityDescriptor:
+ DPRINT("Assign security descriptor\n");
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+STDCALL
+IopQueryNameFile(PVOID ObjectBody,
+ POBJECT_NAME_INFORMATION ObjectNameInfo,
+ ULONG Length,
+ PULONG ReturnLength)
+{
+ POBJECT_NAME_INFORMATION LocalInfo;
+ PFILE_NAME_INFORMATION FileNameInfo;
+ PFILE_OBJECT FileObject;
+ ULONG LocalReturnLength;
+ NTSTATUS Status;
+
+ DPRINT ("IopQueryNameFile() called\n");
+
+ FileObject = (PFILE_OBJECT)ObjectBody;
+
+ LocalInfo = ExAllocatePool (NonPagedPool,
+ sizeof(OBJECT_NAME_INFORMATION) +
+ MAX_PATH * sizeof(WCHAR));
+ if (LocalInfo == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ Status = ObQueryNameString (FileObject->DeviceObject->Vpb->RealDevice,
+ LocalInfo,
+ MAX_PATH * sizeof(WCHAR),
+ &LocalReturnLength);
+ if (!NT_SUCCESS (Status))
+ {
+ ExFreePool (LocalInfo);
+ return Status;
+ }
+ DPRINT ("Device path: %wZ\n", &LocalInfo->Name);
+
+ Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
+ &LocalInfo->Name);
+
+ ExFreePool (LocalInfo);
+
+ FileNameInfo = ExAllocatePool (NonPagedPool,
+ MAX_PATH * sizeof(WCHAR) + sizeof(ULONG));
+ if (FileNameInfo == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ Status = IoQueryFileInformation (FileObject,
+ FileNameInformation,
+ MAX_PATH * sizeof(WCHAR) + sizeof(ULONG),
+ FileNameInfo,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ ExFreePool (FileNameInfo);
+ return Status;
+ }
+
+ Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
+ FileNameInfo->FileName);
+
+ DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
+
+ ExFreePool (FileNameInfo);
+
+ return Status;
+}
+
+VOID
+STDCALL
+IopCloseFile(PVOID ObjectBody,
+ ULONG HandleCount)
+{
+ PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
+ NTSTATUS Status;
+
+ DPRINT("IopCloseFile()\n");
+
+ if (HandleCount > 1 || FileObject->DeviceObject == NULL)
+ {
+ return;
+ }
+
+#if 0
+//NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
+ ObReferenceObjectByPointer(FileObject,
+ STANDARD_RIGHTS_REQUIRED,
+ IoFileObjectType,
+ UserMode);
+#endif
+
+ KeResetEvent( &FileObject->Event );
+
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
+ FileObject->DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &FileObject->Event,
+ NULL);
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = FileObject;
+
+ Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
+ }
+}
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoCheckQuerySetFileInformation(IN FILE_INFORMATION_CLASS FileInformationClass,
+ IN ULONG Length,
+ IN BOOLEAN SetOperation)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoCheckQuotaBufferValidity(IN PFILE_QUOTA_INFORMATION QuotaBuffer,
+ IN ULONG QuotaLength,
+ OUT PULONG ErrorOffset)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * NAME EXPORTED
+ * IoCreateFile@56
+ *
+ * DESCRIPTION
+ * Either causes a new file or directory to be created, or it
+ * opens an existing file, device, directory or volume, giving
+ * the caller a handle for the file object. This handle can be
+ * used by subsequent calls to manipulate data within the file
+ * or the file object's state of attributes.
+ *
+ * ARGUMENTS
+ * FileHandle (OUT)
+ * Points to a variable which receives the file handle
+ * on return;
+ *
+ * DesiredAccess
+ * Desired access to the file;
+ *
+ * ObjectAttributes
+ * Structure describing the file;
+ *
+ * IoStatusBlock (OUT)
+ * Receives information about the operation on return;
+ *
+ * AllocationSize [OPTIONAL]
+ * Initial size of the file in bytes;
+ *
+ * FileAttributes
+ * Attributes to create the file with;
+ *
+ * ShareAccess
+ * Type of shared access the caller would like to the
+ * file;
+ *
+ * CreateDisposition
+ * Specifies what to do, depending on whether the
+ * file already exists;
+ *
+ * CreateOptions
+ * Options for creating a new file;
+ *
+ * EaBuffer [OPTIONAL]
+ * Undocumented;
+ *
+ * EaLength
+ * Undocumented;
+ *
+ * CreateFileType
+ * Type of file (normal, named pipe, mailslot) to create;
+ *
+ * ExtraCreateParameters [OPTIONAL]
+ * Additional creation data for named pipe and mailsots;
+ *
+ * Options
+ * Undocumented.
+ *
+ * RETURN VALUE
+ * Status
+ *
+ * NOTE
+ * Prototype taken from Bo Branten's ntifs.h v15.
+ * Description taken from old NtCreateFile's which is
+ * now a wrapper of this call.
+ *
+ * REVISIONS
+ *
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+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 CreateDisposition,
+ IN ULONG CreateOptions,
+ IN PVOID EaBuffer OPTIONAL,
+ IN ULONG EaLength,
+ IN CREATE_FILE_TYPE CreateFileType,
+ IN PVOID ExtraCreateParameters OPTIONAL,
+ IN ULONG Options)
+{
+ PFILE_OBJECT FileObject = NULL;
+ PDEVICE_OBJECT DeviceObject;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLoc;
+ IO_SECURITY_CONTEXT SecurityContext;
+ KPROCESSOR_MODE AccessMode;
+ HANDLE LocalHandle;
+ IO_STATUS_BLOCK LocalIoStatusBlock;
+ LARGE_INTEGER SafeAllocationSize;
+ PVOID SystemEaBuffer = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
+ "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
+ FileHandle,DesiredAccess,ObjectAttributes,
+ ObjectAttributes->ObjectName->Buffer);
+
+ ASSERT_IRQL(PASSIVE_LEVEL);
+
+ if (IoStatusBlock == NULL || FileHandle == NULL)
+ return STATUS_ACCESS_VIOLATION;
+
+ LocalHandle = 0;
+
+ if(Options & IO_NO_PARAMETER_CHECKING)
+ AccessMode = KernelMode;
+ else
+ AccessMode = ExGetPreviousMode();
+
+ if(AccessMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWrite(FileHandle,
+ sizeof(HANDLE),
+ sizeof(ULONG));
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ if(AllocationSize != NULL)
+ {
+ ProbeForRead(AllocationSize,
+ sizeof(LARGE_INTEGER),
+ sizeof(ULONG));
+ SafeAllocationSize = *AllocationSize;
+ }
+ else
+ SafeAllocationSize.QuadPart = 0;
+
+ if(EaBuffer != NULL && EaLength > 0)
+ {
+ ProbeForRead(EaBuffer,
+ EaLength,
+ sizeof(ULONG));
+
+ /* marshal EaBuffer */
+ SystemEaBuffer = ExAllocatePool(NonPagedPool,
+ EaLength);
+ if(SystemEaBuffer == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ _SEH_LEAVE;
+ }
+
+ RtlCopyMemory(SystemEaBuffer,
+ EaBuffer,
+ EaLength);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else
+ {
+ if(AllocationSize != NULL)
+ SafeAllocationSize = *AllocationSize;
+ else
+ SafeAllocationSize.QuadPart = 0;
+
+ if(EaBuffer != NULL && EaLength > 0)
+ {
+ SystemEaBuffer = EaBuffer;
+ }
+ }
+
+ if(Options & IO_CHECK_CREATE_PARAMETERS)
+ {
+ DPRINT1("FIXME: IO_CHECK_CREATE_PARAMETERS not yet supported!\n");
+ }
+
+ if (CreateDisposition == FILE_OPEN ||
+ CreateDisposition == FILE_OPEN_IF)
+ {
+ Status = ObOpenObjectByName(ObjectAttributes,
+ NULL,
+ NULL,
+ AccessMode,
+ DesiredAccess,
+ NULL,
+ &LocalHandle);
+ if (NT_SUCCESS(Status))
+ {
+ Status = ObReferenceObjectByHandle(LocalHandle,
+ DesiredAccess,
+ NULL,
+ AccessMode,
+ (PVOID*)&DeviceObject,
+ NULL);
+ ZwClose(LocalHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ if (BODY_TO_HEADER(DeviceObject)->ObjectType != IoDeviceObjectType)
+ {
+ ObDereferenceObject (DeviceObject);
+ return STATUS_OBJECT_NAME_COLLISION;
+ }
+ FileObject = IoCreateStreamFileObject(NULL, DeviceObject);
+ ObDereferenceObject (DeviceObject);
+ }
+ }
+
+
+ if (FileObject == NULL)
+ {
+ Status = ObCreateObject(AccessMode,
+ IoFileObjectType,
+ ObjectAttributes,
+ AccessMode,
+ NULL,
+ sizeof(FILE_OBJECT),
+ 0,
+ 0,
+ (PVOID*)&FileObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ObCreateObject() failed! (Status %lx)\n", Status);
+ return Status;
+ }
+ }
+ RtlMapGenericMask(&DesiredAccess,
+ BODY_TO_HEADER(FileObject)->ObjectType->Mapping);
+
+ Status = ObInsertObject ((PVOID)FileObject,
+ NULL,
+ DesiredAccess,
+ 0,
+ NULL,
+ &LocalHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ObInsertObject() failed! (Status %lx)\n", Status);
+ ObDereferenceObject (FileObject);
+ return Status;
+ }
+
+ if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
+ {
+ FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
+ }
+ if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
+ {
+ FileObject->Flags |= FO_SYNCHRONOUS_IO;
+ }
+
+ if (CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)
+ FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
+
+ SecurityContext.SecurityQos = NULL; /* ?? */
+ SecurityContext.AccessState = NULL; /* ?? */
+ SecurityContext.DesiredAccess = DesiredAccess;
+ SecurityContext.FullCreateOptions = 0; /* ?? */
+
+ KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
+ KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
+
+ DPRINT("FileObject %x\n", FileObject);
+ DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
+ /*
+ * Create a new IRP to hand to
+ * the FS driver: this may fail
+ * due to resource shortage.
+ */
+ Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
+ if (Irp == NULL)
+ {
+ ZwClose(LocalHandle);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ //trigger FileObject/Event dereferencing
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->RequestorMode = AccessMode;
+ Irp->UserIosb = &LocalIoStatusBlock;
+ Irp->AssociatedIrp.SystemBuffer = SystemEaBuffer;
+ Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ Irp->UserEvent = &FileObject->Event;
+ Irp->Overlay.AllocationSize = SafeAllocationSize;
+
+ /*
+ * Get the stack location for the new
+ * IRP and prepare it.
+ */
+ StackLoc = IoGetNextIrpStackLocation(Irp);
+ StackLoc->MinorFunction = 0;
+ StackLoc->Flags = (UCHAR)Options;
+ StackLoc->Control = 0;
+ StackLoc->DeviceObject = FileObject->DeviceObject;
+ StackLoc->FileObject = FileObject;
+
+ switch (CreateFileType)
+ {
+ default:
+ case CreateFileTypeNone:
+ StackLoc->MajorFunction = IRP_MJ_CREATE;
+ StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
+ StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
+ StackLoc->Parameters.Create.Options |= (CreateDisposition << 24);
+ StackLoc->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
+ StackLoc->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
+ StackLoc->Parameters.Create.EaLength = SystemEaBuffer != NULL ? EaLength : 0;
+ break;
+
+ case CreateFileTypeNamedPipe:
+ StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
+ StackLoc->Parameters.CreatePipe.SecurityContext = &SecurityContext;
+ StackLoc->Parameters.CreatePipe.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
+ StackLoc->Parameters.CreatePipe.Options |= (CreateDisposition << 24);
+ StackLoc->Parameters.CreatePipe.ShareAccess = (USHORT)ShareAccess;
+ StackLoc->Parameters.CreatePipe.Parameters = ExtraCreateParameters;
+ break;
+
+ case CreateFileTypeMailslot:
+ StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
+ StackLoc->Parameters.CreateMailslot.SecurityContext = &SecurityContext;
+ StackLoc->Parameters.CreateMailslot.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
+ StackLoc->Parameters.CreateMailslot.Options |= (CreateDisposition << 24);
+ StackLoc->Parameters.CreateMailslot.ShareAccess = (USHORT)ShareAccess;
+ StackLoc->Parameters.CreateMailslot.Parameters = ExtraCreateParameters;
+ break;
+ }
+
+ /*
+ * Now call the driver and
+ * possibly wait if it can
+ * not complete the request
+ * immediately.
+ */
+ Status = IofCallDriver(FileObject->DeviceObject, Irp );
+
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ AccessMode,
+ FALSE,
+ NULL);
+ Status = LocalIoStatusBlock.Status;
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Failing create request with status %x\n", Status);
+ FileObject->DeviceObject = NULL;
+ FileObject->Vpb = NULL;
+
+ ZwClose(LocalHandle);
+ }
+ else
+ {
+ _SEH_TRY
+ {
+ *FileHandle = LocalHandle;
+ *IoStatusBlock = LocalIoStatusBlock;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+
+ /* cleanup EABuffer if captured */
+ if(AccessMode != KernelMode && SystemEaBuffer != NULL)
+ {
+ ExFreePool(SystemEaBuffer);
+ }
+
+ ASSERT_IRQL(PASSIVE_LEVEL);
+
+ DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
+
+ return Status;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+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)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * NAME EXPORTED
+ * IoCreateStreamFileObject@8
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ * FileObject
+ * ?
+ *
+ * DeviceObject
+ * ?
+ *
+ * RETURN VALUE
+ *
+ * NOTE
+ *
+ * REVISIONS
+ *
+ * @implemented
+ */
+PFILE_OBJECT
+STDCALL
+IoCreateStreamFileObject(PFILE_OBJECT FileObject,
+ PDEVICE_OBJECT DeviceObject)
+{
+ PFILE_OBJECT CreatedFileObject;
+ NTSTATUS Status;
+
+ DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
+ FileObject, DeviceObject);
+
+ ASSERT_IRQL(PASSIVE_LEVEL);
+
+ Status = ObCreateObject(KernelMode,
+ IoFileObjectType,
+ NULL,
+ KernelMode,
+ NULL,
+ sizeof(FILE_OBJECT),
+ 0,
+ 0,
+ (PVOID*)&CreatedFileObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Could not create FileObject\n");
+ return (NULL);
+ }
+
+ if (FileObject != NULL)
+ {
+ DeviceObject = FileObject->DeviceObject;
+ }
+ DeviceObject = IoGetAttachedDevice(DeviceObject);
+
+ DPRINT("DeviceObject %x\n", DeviceObject);
+
+ if (DeviceObject->Vpb &&
+ DeviceObject->Vpb->DeviceObject)
+ {
+ CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject;
+ }
+ else
+ {
+ CreatedFileObject->DeviceObject = DeviceObject;
+ }
+ CreatedFileObject->Vpb = DeviceObject->Vpb;
+ CreatedFileObject->Type = IO_TYPE_FILE;
+ CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
+
+ // shouldn't we initialize the lock event, and several other things here too?
+ KeInitializeEvent(&CreatedFileObject->Event, NotificationEvent, FALSE);
+ KeInitializeEvent(&CreatedFileObject->Lock, SynchronizationEvent, TRUE);
+
+ return CreatedFileObject;
+}
+
+/*
+ * @unimplemented
+ */
+PFILE_OBJECT
+STDCALL
+IoCreateStreamFileObjectEx(IN PFILE_OBJECT FileObject OPTIONAL,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+ OUT PHANDLE FileObjectHandle OPTIONAL)
+{
+ UNIMPLEMENTED;
+ return 0;
+}
+/*
+ * @unimplemented
+ */
+PFILE_OBJECT
+STDCALL
+IoCreateStreamFileObjectLite(IN PFILE_OBJECT FileObject OPTIONAL,
+ IN PDEVICE_OBJECT DeviceObject OPTIONAL)
+{
+ UNIMPLEMENTED;
+ return 0;
+}
+
+/*
+ * @implemented
+ */
+PGENERIC_MAPPING
+STDCALL
+IoGetFileObjectGenericMapping(VOID)
+{
+ return &IopFileMapping;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+IoIsFileOriginRemote(IN PFILE_OBJECT FileObject)
+{
+ /* Return the flag status */
+ return (FileObject->Flags & FO_REMOTE_ORIGIN);
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject,
+ OUT POBJECT_NAME_INFORMATION *ObjectNameInformation)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+IoQueryFileInformation(IN PFILE_OBJECT FileObject,
+ IN FILE_INFORMATION_CLASS FileInformationClass,
+ IN ULONG Length,
+ OUT PVOID FileInformation,
+ OUT PULONG ReturnedLength)
+{
+ IO_STATUS_BLOCK IoStatusBlock;
+ PIRP Irp;
+ PDEVICE_OBJECT DeviceObject;
+ PIO_STACK_LOCATION StackPtr;
+ NTSTATUS Status;
+
+ ASSERT(FileInformation != NULL);
+
+ Status = ObReferenceObjectByPointer(FileObject,
+ FILE_READ_ATTRIBUTES,
+ IoFileObjectType,
+ KernelMode);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+ DPRINT("FileObject %x\n", FileObject);
+
+ DeviceObject = FileObject->DeviceObject;
+
+ Irp = IoAllocateIrp(DeviceObject->StackSize,
+ TRUE);
+ if (Irp == NULL)
+ {
+ ObDereferenceObject(FileObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Trigger FileObject/Event dereferencing */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->RequestorMode = KernelMode;
+ Irp->AssociatedIrp.SystemBuffer = FileInformation;
+ Irp->UserIosb = &IoStatusBlock;
+ Irp->UserEvent = &FileObject->Event;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ KeResetEvent( &FileObject->Event );
+
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
+ StackPtr->MinorFunction = 0;
+ StackPtr->Flags = 0;
+ StackPtr->Control = 0;
+ StackPtr->DeviceObject = DeviceObject;
+ StackPtr->FileObject = FileObject;
+
+ StackPtr->Parameters.QueryFile.FileInformationClass =
+ FileInformationClass;
+ StackPtr->Parameters.QueryFile.Length = Length;
+
+ Status = IoCallDriver(FileObject->DeviceObject,
+ Irp);
+ if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ KernelMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ if (ReturnedLength != NULL)
+ {
+ *ReturnedLength = IoStatusBlock.Information;
+ }
+
+
+ return Status;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoSetFileOrigin(IN PFILE_OBJECT FileObject,
+ IN BOOLEAN Remote)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/**
+ * @name NtCancelIoFile
+ *
+ * Cancel all pending I/O operations in the current thread for specified
+ * file object.
+ *
+ * @param FileHandle
+ * Handle to file object to cancel requests for. No specific
+ * access rights are needed.
+ * @param IoStatusBlock
+ * Pointer to status block which is filled with final completition
+ * status on successful return.
+ *
+ * @return Status.
+ *
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+NtCancelIoFile(IN HANDLE FileHandle,
+ OUT PIO_STATUS_BLOCK IoStatusBlock)
+{
+ NTSTATUS Status;
+ PFILE_OBJECT FileObject;
+ PETHREAD Thread;
+ PLIST_ENTRY IrpEntry;
+ PIRP Irp;
+ KIRQL OldIrql;
+ BOOLEAN OurIrpsInList = FALSE;
+ LARGE_INTEGER Interval;
+
+ if ((ULONG_PTR)IoStatusBlock >= MmUserProbeAddress &&
+ KeGetPreviousMode() == UserMode)
+ return STATUS_ACCESS_VIOLATION;
+
+ Status = ObReferenceObjectByHandle(FileHandle, 0, IoFileObjectType,
+ KeGetPreviousMode(), (PVOID*)&FileObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* IRP cancellations are synchronized at APC_LEVEL. */
+ OldIrql = KfRaiseIrql(APC_LEVEL);
+
+ /*
+ * Walk the list of active IRPs and cancel the ones that belong to
+ * our file object.
+ */
+
+ Thread = PsGetCurrentThread();
+ for (IrpEntry = Thread->IrpList.Flink;
+ IrpEntry != &Thread->IrpList;
+ IrpEntry = IrpEntry->Flink)
+ {
+ Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
+ if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
+ {
+ IoCancelIrp(Irp);
+ /* Don't break here, we want to cancel all IRPs for the file object. */
+ OurIrpsInList = TRUE;
+ }
+ }
+
+ KfLowerIrql(OldIrql);
+
+ while (OurIrpsInList)
+ {
+ OurIrpsInList = FALSE;
+
+ /* Wait a short while and then look if all our IRPs were completed. */
+ Interval.QuadPart = -1000000; /* 100 milliseconds */
+ KeDelayExecutionThread(KernelMode, FALSE, &Interval);
+
+ OldIrql = KfRaiseIrql(APC_LEVEL);
+
+ /*
+ * Look in the list if all IRPs for the specified file object
+ * are completed (or cancelled). If someone sends a new IRP
+ * for our file object while we're here we can happily loop
+ * forever.
+ */
+
+ for (IrpEntry = Thread->IrpList.Flink;
+ IrpEntry != &Thread->IrpList;
+ IrpEntry = IrpEntry->Flink)
+ {
+ Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
+ if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
+ {
+ OurIrpsInList = TRUE;
+ break;
+ }
+ }
+
+ KfLowerIrql(OldIrql);
+ }
+
+ _SEH_TRY
+ {
+ IoStatusBlock->Status = STATUS_SUCCESS;
+ IoStatusBlock->Information = 0;
+ Status = STATUS_SUCCESS;
+ }
+ _SEH_HANDLE
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ _SEH_END;
+
+ ObDereferenceObject(FileObject);
+
+ return Status;
+}
+
+/*
+ * NAME EXPORTED
+ * NtCreateFile@44
+ *
+ * DESCRIPTION
+ * Entry point to call IoCreateFile with
+ * default parameters.
+ *
+ * ARGUMENTS
+ * See IoCreateFile.
+ *
+ * RETURN VALUE
+ * See IoCreateFile.
+ *
+ * REVISIONS
+ * 2000-03-25 (ea)
+ * Code originally in NtCreateFile moved in IoCreateFile.
+ *
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+NtCreateFile(PHANDLE FileHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PLARGE_INTEGER AllocateSize,
+ ULONG FileAttributes,
+ ULONG ShareAccess,
+ ULONG CreateDisposition,
+ ULONG CreateOptions,
+ PVOID EaBuffer,
+ ULONG EaLength)
+{
+ /* Call the I/O Function */
+ return IoCreateFile(FileHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ IoStatusBlock,
+ AllocateSize,
+ FileAttributes,
+ ShareAccess,
+ CreateDisposition,
+ CreateOptions,
+ EaBuffer,
+ EaLength,
+ CreateFileTypeNone,
+ NULL,
+ 0);
+}
+
+NTSTATUS
+STDCALL
+NtCreateMailslotFile(OUT PHANDLE FileHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN ULONG CreateOptions,
+ IN ULONG MailslotQuota,
+ IN ULONG MaxMessageSize,
+ IN PLARGE_INTEGER TimeOut)
+{
+ MAILSLOT_CREATE_PARAMETERS Buffer;
+
+ DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, "
+ "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
+ FileHandle,DesiredAccess,ObjectAttributes,
+ ObjectAttributes->ObjectName->Buffer);
+
+ ASSERT_IRQL(PASSIVE_LEVEL);
+
+ if (TimeOut != NULL)
+ {
+ Buffer.ReadTimeout.QuadPart = TimeOut->QuadPart;
+ Buffer.TimeoutSpecified = TRUE;
+ }
+ else
+ {
+ Buffer.TimeoutSpecified = FALSE;
+ }
+ Buffer.MailslotQuota = MailslotQuota;
+ Buffer.MaximumMessageSize = MaxMessageSize;
+
+ return IoCreateFile(FileHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_CREATE,
+ CreateOptions,
+ NULL,
+ 0,
+ CreateFileTypeMailslot,
+ (PVOID)&Buffer,
+ 0);
+}
+
+NTSTATUS
+STDCALL
+NtCreateNamedPipeFile(PHANDLE FileHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ ULONG ShareAccess,
+ ULONG CreateDisposition,
+ ULONG CreateOptions,
+ ULONG NamedPipeType,
+ ULONG ReadMode,
+ ULONG CompletionMode,
+ ULONG MaximumInstances,
+ ULONG InboundQuota,
+ ULONG OutboundQuota,
+ PLARGE_INTEGER DefaultTimeout)
+{
+ NAMED_PIPE_CREATE_PARAMETERS Buffer;
+
+ DPRINT("NtCreateNamedPipeFile(FileHandle %x, DesiredAccess %x, "
+ "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
+ FileHandle,DesiredAccess,ObjectAttributes,
+ ObjectAttributes->ObjectName->Buffer);
+
+ ASSERT_IRQL(PASSIVE_LEVEL);
+
+ if (DefaultTimeout != NULL)
+ {
+ Buffer.DefaultTimeout.QuadPart = DefaultTimeout->QuadPart;
+ Buffer.TimeoutSpecified = TRUE;
+ }
+ else
+ {
+ Buffer.TimeoutSpecified = FALSE;
+ }
+ Buffer.NamedPipeType = NamedPipeType;
+ Buffer.ReadMode = ReadMode;
+ Buffer.CompletionMode = CompletionMode;
+ Buffer.MaximumInstances = MaximumInstances;
+ Buffer.InboundQuota = InboundQuota;
+ Buffer.OutboundQuota = OutboundQuota;
+
+ return IoCreateFile(FileHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ ShareAccess,
+ CreateDisposition,
+ CreateOptions,
+ NULL,
+ 0,
+ CreateFileTypeNamedPipe,
+ (PVOID)&Buffer,
+ 0);
+}
+
+/*
+ * NAME EXPORTED
+ * NtDeleteFile@4
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ * ObjectAttributes
+ * ?
*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/file.c
- * PURPOSE: Graceful system shutdown if a bug is detected
+ * RETURN VALUE
+ *
+ * REVISIONS
*
- * PROGRAMMERS: David Welch (welch@mcmail.com)
+ * @unimplemented
*/
+NTSTATUS
+STDCALL
+NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
+{
+ UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
+}
-/* INCLUDES *****************************************************************/
+NTSTATUS
+STDCALL
+NtFlushWriteBuffer(VOID)
+{
+ KeFlushWriteBuffer();
+ return STATUS_SUCCESS;
+}
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
+NTSTATUS
+STDCALL
+NtFlushBuffersFile (IN HANDLE FileHandle,
+ OUT PIO_STATUS_BLOCK IoStatusBlock)
+/*
+ * FUNCTION: Flushes cached file data to disk
+ * ARGUMENTS:
+ * FileHandle = Points to the file
+ * IoStatusBlock = Caller must supply storage to receive the result of
+ * the flush buffers operation. The information field is
+ * set to number of bytes flushed to disk.
+ * RETURNS: Status
+ * REMARKS: This function maps to the win32 FlushFileBuffers
+ */
+{
+ PFILE_OBJECT FileObject = NULL;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
+ NTSTATUS Status;
+ KPROCESSOR_MODE PreviousMode;
+
+ PreviousMode = ExGetPreviousMode();
+ Status = ObReferenceObjectByHandle(FileHandle,
+ FILE_WRITE_DATA,
+ NULL,
+ PreviousMode,
+ (PVOID*)&FileObject,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+ KeResetEvent( &FileObject->Event );
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS,
+ FileObject->DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &FileObject->Event,
+ IoStatusBlock);
-/* GLOBALS *******************************************************************/
+ /* Trigger FileObject/Event dereferencing */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
-#define TAG_SYSB TAG('S', 'Y', 'S', 'B')
+ Irp->RequestorMode = PreviousMode;
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = FileObject;
-/* FUNCTIONS *****************************************************************/
+ Status = IoCallDriver(FileObject->DeviceObject,Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ Status = IoStatusBlock->Status;
+ }
+
+ return(Status);
+}
/*
* @implemented
*/
-NTSTATUS STDCALL
-NtQueryInformationFile(HANDLE FileHandle,
- PIO_STATUS_BLOCK IoStatusBlock,
- PVOID FileInformation,
- ULONG Length,
- FILE_INFORMATION_CLASS FileInformationClass)
+NTSTATUS
+STDCALL
+NtNotifyChangeDirectoryFile(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 BufferSize,
+ IN ULONG CompletionFilter,
+ IN BOOLEAN WatchTree)
{
- PFILE_OBJECT FileObject;
- NTSTATUS Status;
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
- PIO_STACK_LOCATION StackPtr;
- PVOID SystemBuffer;
+ PFILE_OBJECT FileObject;
+ PIO_STACK_LOCATION IoStack;
KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status = STATUS_SUCCESS;
- ASSERT(IoStatusBlock != NULL);
- ASSERT(FileInformation != NULL);
+ DPRINT("NtNotifyChangeDirectoryFile()\n");
- DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
- "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
- Length, FileInformationClass);
+ PAGED_CODE();
PreviousMode = ExGetPreviousMode();
+
+ if(PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ if(BufferSize != 0)
+ {
+ ProbeForWrite(Buffer,
+ BufferSize,
+ sizeof(ULONG));
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
Status = ObReferenceObjectByHandle(FileHandle,
- 0, /* FIXME - access depends on the information class! */
- IoFileObjectType,
- PreviousMode,
- (PVOID *)&FileObject,
- NULL);
- if (!NT_SUCCESS(Status))
+ FILE_LIST_DIRECTORY,
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID *)&FileObject,
+ NULL);
+
+ if (Status != STATUS_SUCCESS)
{
- return(Status);
+ return(Status);
}
- DPRINT("FileObject %x\n", FileObject);
-
DeviceObject = FileObject->DeviceObject;
- Irp = IoAllocateIrp(DeviceObject->StackSize,
- TRUE);
- if (Irp == NULL)
+ Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
+ if (Irp==NULL)
{
- ObDereferenceObject(FileObject);
- return STATUS_INSUFFICIENT_RESOURCES;
+ ObDereferenceObject(FileObject);
+ return STATUS_UNSUCCESSFUL;
}
- SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
- Length,
- TAG_SYSB);
- if (SystemBuffer == NULL)
+ if (Event == NULL)
{
- IoFreeIrp(Irp);
- ObDereferenceObject(FileObject);
- return(STATUS_INSUFFICIENT_RESOURCES);
+ Event = &FileObject->Event;
}
-
+
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
- Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
Irp->UserIosb = IoStatusBlock;
- Irp->UserEvent = &FileObject->Event;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- KeResetEvent( &FileObject->Event );
+ Irp->UserEvent = Event;
+ KeResetEvent( Event );
+ Irp->UserBuffer = Buffer;
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
- StackPtr->MinorFunction = 0;
- StackPtr->Flags = 0;
- StackPtr->Control = 0;
- StackPtr->DeviceObject = DeviceObject;
- StackPtr->FileObject = FileObject;
+ IoStack = IoGetNextIrpStackLocation(Irp);
- StackPtr->Parameters.QueryFile.FileInformationClass =
- FileInformationClass;
- StackPtr->Parameters.QueryFile.Length = Length;
+ IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
+ IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY;
+ IoStack->Flags = 0;
+ IoStack->Control = 0;
+ IoStack->DeviceObject = DeviceObject;
+ IoStack->FileObject = FileObject;
- Status = IoCallDriver(FileObject->DeviceObject,
- Irp);
- if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
+ if (WatchTree)
{
- KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- Status = IoStatusBlock->Status;
+ IoStack->Flags = SL_WATCH_TREE;
}
- if (NT_SUCCESS(Status))
- {
- DPRINT("Information %lu\n", IoStatusBlock->Information);
- MmSafeCopyToUser(FileInformation,
- SystemBuffer,
- IoStatusBlock->Information);
- }
+ IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
+ IoStack->Parameters.NotifyDirectory.Length = BufferSize;
+
+ Status = IoCallDriver(FileObject->DeviceObject,Irp);
- ExFreePool(SystemBuffer);
+ /* FIXME: Should we wait here or not for synchronously opened files? */
return Status;
}
*/
NTSTATUS
STDCALL
-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
- )
+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 PULONG Key,
+ IN BOOLEAN FailImmediatedly,
+ IN BOOLEAN ExclusiveLock
+ )
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
+ PFILE_OBJECT FileObject = NULL;
+ PLARGE_INTEGER LocalLength = NULL;
+ PKEVENT Event = NULL;
+ PIRP Irp = NULL;
+ PIO_STACK_LOCATION StackPtr;
+ PDEVICE_OBJECT DeviceObject;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status;
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-NtSetQuotaInformationFile(
- HANDLE FileHandle,
- PIO_STATUS_BLOCK IoStatusBlock,
- PFILE_USER_QUOTA_INFORMATION Buffer,
- ULONG BufferLength)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
+ // FIXME: instead of this, use SEH when available?
+ if (!Length || !ByteOffset)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+ PreviousMode = ExGetPreviousMode();
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoCheckQuerySetFileInformation(
- IN FILE_INFORMATION_CLASS FileInformationClass,
- IN ULONG Length,
- IN BOOLEAN SetOperation
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ Status = ObReferenceObjectByHandle(FileHandle,
+ 0,
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID*)&FileObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ goto fail;
+ }
+
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+ Irp = IoAllocateIrp(DeviceObject->StackSize,
+ TRUE);
+ if (Irp == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto fail;
+ }
+
+ if (EventHandle != NULL && !FailImmediatedly)
+ {
+ Status = ObReferenceObjectByHandle(EventHandle,
+ SYNCHRONIZE,
+ ExEventObjectType,
+ PreviousMode,
+ (PVOID*)&Event,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ goto fail;
+ }
+ }
+ else
+ {
+ Event = &FileObject->Event;
+ KeResetEvent(Event);
+ }
+
+ /* Trigger FileObject/Event dereferencing */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+
+ Irp->RequestorMode = PreviousMode;
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
+
+ Irp->UserEvent = Event;
+ Irp->UserIosb = IoStatusBlock;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
+ StackPtr->MinorFunction = IRP_MN_LOCK;
+ StackPtr->FileObject = FileObject;
+
+ if (ExclusiveLock)
+ StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
+
+ if (FailImmediatedly)
+ StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
+
+ LocalLength = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(LARGE_INTEGER),
+ TAG_LOCK);
+ if (!LocalLength)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto fail;
+ }
+
+ *LocalLength = *Length;
+
+ StackPtr->Parameters.LockControl.Length = LocalLength;
+ StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
+ StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
+
+ IoSetCompletionRoutine(Irp,
+ IopLockFileCompletionRoutine,
+ LocalLength,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ /* Can't touch FileObject after IoCallDriver since it might be freed */
+ Status = IofCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ Status = KeWaitForSingleObject(Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+
+ if (Status != STATUS_WAIT_0)
+ {
+ DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
+ /*
+ * FIXME: Should do some special processing here if alertable wait
+ * was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
+ */
+ return Status; /* Set status to something else? */
+ }
+
+ Status = IoStatusBlock->Status;
+ }
+
+ return Status;
+
+fail:;
+ if (LocalLength)
+ ExFreePool(LocalLength);
+
+ if (Irp)
+ IoFreeIrp(Irp);
+
+ if (Event)
+ ObDereferenceObject(Event);
+
+ if (FileObject)
+ ObDereferenceObject(FileObject);
+
+ return Status;
}
/*
- * @unimplemented
+ * NAME EXPORTED
+ * NtOpenFile@24
+ *
+ * DESCRIPTION
+ * Opens an existing file (simpler than NtCreateFile).
+ *
+ * ARGUMENTS
+ * FileHandle (OUT)
+ * Variable that receives the file handle on return;
+ *
+ * DesiredAccess
+ * Access desired by the caller to the file;
+ *
+ * ObjectAttributes
+ * Structue describing the file to be opened;
+ *
+ * IoStatusBlock (OUT)
+ * Receives details about the result of the
+ * operation;
+ *
+ * ShareAccess
+ * Type of shared access the caller requires;
+ *
+ * OpenOptions
+ * Options for the file open.
+ *
+ * RETURN VALUE
+ * Status.
+ *
+ * NOTE
+ * Undocumented.
+ *
+ * @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
-IoCheckQuerySetVolumeInformation(
- IN FS_INFORMATION_CLASS FsInformationClass,
- IN ULONG Length,
- IN BOOLEAN SetOperation
- )
+NtOpenFile(PHANDLE FileHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ ULONG ShareAccess,
+ ULONG OpenOptions)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ /* Call the I/O Function */
+ return IoCreateFile(FileHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ IoStatusBlock,
+ NULL,
+ 0,
+ ShareAccess,
+ FILE_OPEN,
+ OpenOptions,
+ NULL,
+ 0,
+ CreateFileTypeNone,
+ NULL,
+ 0);
}
-/*
- * @unimplemented
- */
-NTSTATUS
+NTSTATUS
STDCALL
-IoCheckQuotaBufferValidity(
- IN PFILE_QUOTA_INFORMATION QuotaBuffer,
- IN ULONG QuotaLength,
- OUT PULONG ErrorOffset
- )
+NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
+ OUT PFILE_BASIC_INFORMATION FileInformation)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE FileHandle;
+ NTSTATUS Status;
+
+ /* Open the file */
+ Status = ZwOpenFile (&FileHandle,
+ SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+ ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ /* Get file attributes */
+ Status = ZwQueryInformationFile (FileHandle,
+ &IoStatusBlock,
+ FileInformation,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
+ ZwClose (FileHandle);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
+ }
+
+ return Status;
}
/*
- * @unimplemented
+ * @implemented
+ *
+ * FUNCTION: Queries a directory file.
+ * ARGUMENTS:
+ * FileHandle = Handle to a directory file
+ * EventHandle = Handle to the event signaled on completion
+ * ApcRoutine = Asynchroneous procedure callback, called on completion
+ * ApcContext = Argument to the apc.
+ * IoStatusBlock = Caller supplies storage for extended status information.
+ * FileInformation = Caller supplies storage for the resulting information.
+ *
+ * FileNameInformation FILE_NAMES_INFORMATION
+ * FileDirectoryInformation FILE_DIRECTORY_INFORMATION
+ * FileFullDirectoryInformation FILE_FULL_DIRECTORY_INFORMATION
+ * FileBothDirectoryInformation FILE_BOTH_DIR_INFORMATION
+ *
+ * Length = Size of the storage supplied
+ * FileInformationClass = Indicates the type of information requested.
+ * ReturnSingleEntry = Specify true if caller only requests the first
+ * directory found.
+ * FileName = Initial directory name to query, that may contain wild
+ * cards.
+ * RestartScan = Number of times the action should be repeated
+ * RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES,
+ * STATUS_INVALID_PARAMETER, STATUS_INVALID_DEVICE_REQUEST, STATUS_BUFFER_OVERFLOW,
+ * STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ]
*/
NTSTATUS
-STDCALL
-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
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
+STDCALL
+NtQueryDirectoryFile(IN HANDLE FileHandle,
+ IN HANDLE PEvent 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
+ )
-/*
- * @unimplemented
- */
-PFILE_OBJECT
-STDCALL
-IoCreateStreamFileObjectEx(
- IN PFILE_OBJECT FileObject OPTIONAL,
- IN PDEVICE_OBJECT DeviceObject OPTIONAL,
- OUT PHANDLE FileObjectHandle OPTIONAL
- )
-{
- UNIMPLEMENTED;
- return 0;
-}
-/*
- * @unimplemented
- */
-PFILE_OBJECT
-STDCALL
-IoCreateStreamFileObjectLite(
- IN PFILE_OBJECT FileObject OPTIONAL,
- IN PDEVICE_OBJECT DeviceObject OPTIONAL
- )
{
- UNIMPLEMENTED;
- return 0;
+ PIRP Irp;
+ PDEVICE_OBJECT DeviceObject;
+ PFILE_OBJECT FileObject;
+ PIO_STACK_LOCATION IoStack;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("NtQueryDirectoryFile()\n");
+
+ PAGED_CODE();
+
+ PreviousMode = ExGetPreviousMode();
+
+ if(PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ ProbeForWrite(FileInformation,
+ Length,
+ sizeof(ULONG));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ Status = ObReferenceObjectByHandle(FileHandle,
+ FILE_LIST_DIRECTORY,
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID *)&FileObject,
+ NULL);
+
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+ DeviceObject = FileObject->DeviceObject;
+
+ Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
+ if (Irp==NULL)
+ {
+ ObDereferenceObject(FileObject);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Trigger FileObject/Event dereferencing */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->RequestorMode = PreviousMode;
+ Irp->UserIosb = IoStatusBlock;
+ Irp->UserEvent = &FileObject->Event;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ KeResetEvent( &FileObject->Event );
+ Irp->UserBuffer=FileInformation;
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
+
+ IoStack = IoGetNextIrpStackLocation(Irp);
+
+ IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
+ IoStack->MinorFunction = IRP_MN_QUERY_DIRECTORY;
+ IoStack->Flags = 0;
+ IoStack->Control = 0;
+ IoStack->DeviceObject = DeviceObject;
+ IoStack->FileObject = FileObject;
+
+ if (RestartScan)
+ {
+ IoStack->Flags = IoStack->Flags | SL_RESTART_SCAN;
+ }
+ if (ReturnSingleEntry)
+ {
+ IoStack->Flags = IoStack->Flags | SL_RETURN_SINGLE_ENTRY;
+ }
+ if (((PFILE_DIRECTORY_INFORMATION)FileInformation)->FileIndex != 0)
+ {
+ IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
+ }
+
+ IoStack->Parameters.QueryDirectory.FileInformationClass =
+ FileInformationClass;
+ IoStack->Parameters.QueryDirectory.FileName = FileName;
+ IoStack->Parameters.QueryDirectory.Length = Length;
+
+ Status = IoCallDriver(FileObject->DeviceObject,Irp);
+ if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ Status = IoStatusBlock->Status;
+ }
+
+ return(Status);
}
/*
- * @implemented
+ * @unimplemented
*/
-BOOLEAN
-STDCALL
-IoIsFileOriginRemote(IN PFILE_OBJECT FileObject)
+NTSTATUS STDCALL
+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)
{
- /* Return the flag status */
- return (FileObject->Flags & FO_REMOTE_ORIGIN);
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
-/*
- * @unimplemented
- */
-NTSTATUS
+NTSTATUS
STDCALL
-IoQueryFileDosDeviceName(
- IN PFILE_OBJECT FileObject,
- OUT POBJECT_NAME_INFORMATION *ObjectNameInformation
- )
+NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
+ OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE FileHandle;
+ NTSTATUS Status;
+
+ /* Open the file */
+ Status = ZwOpenFile (&FileHandle,
+ SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+ ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ /* Get file attributes */
+ Status = ZwQueryInformationFile (FileHandle,
+ &IoStatusBlock,
+ FileInformation,
+ sizeof(FILE_NETWORK_OPEN_INFORMATION),
+ FileNetworkOpenInformation);
+ ZwClose (FileHandle);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
+ }
+
+ return Status;
}
/*
* @implemented
*/
NTSTATUS STDCALL
-IoQueryFileInformation(IN PFILE_OBJECT FileObject,
- IN FILE_INFORMATION_CLASS FileInformationClass,
- IN ULONG Length,
- OUT PVOID FileInformation,
- OUT PULONG ReturnedLength)
+NtQueryInformationFile(HANDLE FileHandle,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PVOID FileInformation,
+ ULONG Length,
+ FILE_INFORMATION_CLASS FileInformationClass)
{
- IO_STATUS_BLOCK IoStatusBlock;
+ PFILE_OBJECT FileObject;
+ NTSTATUS Status;
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
+ PVOID SystemBuffer;
+ KPROCESSOR_MODE PreviousMode;
+ ASSERT(IoStatusBlock != NULL);
ASSERT(FileInformation != NULL);
- Status = ObReferenceObjectByPointer(FileObject,
- FILE_READ_ATTRIBUTES,
- IoFileObjectType,
- KernelMode);
+ DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
+ "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
+ Length, FileInformationClass);
+
+ PreviousMode = ExGetPreviousMode();
+
+ Status = ObReferenceObjectByHandle(FileHandle,
+ 0, /* FIXME - access depends on the information class! */
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID *)&FileObject,
+ NULL);
if (!NT_SUCCESS(Status))
{
- return(Status);
+ return(Status);
}
-
DPRINT("FileObject %x\n", FileObject);
DeviceObject = FileObject->DeviceObject;
Irp = IoAllocateIrp(DeviceObject->StackSize,
- TRUE);
+ TRUE);
if (Irp == NULL)
{
- ObDereferenceObject(FileObject);
- return STATUS_INSUFFICIENT_RESOURCES;
+ ObDereferenceObject(FileObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
-
+
+ SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
+ Length,
+ TAG_SYSB);
+ if (SystemBuffer == NULL)
+ {
+ IoFreeIrp(Irp);
+ ObDereferenceObject(FileObject);
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = KernelMode;
- Irp->AssociatedIrp.SystemBuffer = FileInformation;
- Irp->UserIosb = &IoStatusBlock;
+ Irp->RequestorMode = PreviousMode;
+ Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
+ Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = &FileObject->Event;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
KeResetEvent( &FileObject->Event );
StackPtr->Parameters.QueryFile.Length = Length;
Status = IoCallDriver(FileObject->DeviceObject,
- Irp);
- if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
+ Irp);
+ if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
- KeWaitForSingleObject(&FileObject->Event,
- Executive,
- KernelMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- Status = IoStatusBlock.Status;
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ Status = IoStatusBlock->Status;
}
-
- if (ReturnedLength != NULL)
+
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT("Information %lu\n", IoStatusBlock->Information);
+ MmSafeCopyToUser(FileInformation,
+ SystemBuffer,
+ IoStatusBlock->Information);
+ }
+
+ ExFreePool(SystemBuffer);
+
+ return Status;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+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)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * NAME EXPORTED
+ * NtReadFile
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+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, /* NOT optional for asynch. operations! */
+ IN PULONG Key OPTIONAL)
+{
+ NTSTATUS Status;
+ PFILE_OBJECT FileObject;
+ PIRP Irp = NULL;
+ PIO_STACK_LOCATION StackPtr;
+ KPROCESSOR_MODE PreviousMode;
+ PKEVENT EventObject = NULL;
+
+ DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
+ "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
+ IoStatusBlock);
+
+ if (IoStatusBlock == NULL)
+ return STATUS_ACCESS_VIOLATION;
+
+ PreviousMode = ExGetPreviousMode();
+
+ Status = ObReferenceObjectByHandle(FileHandle,
+ FILE_READ_DATA,
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID*)&FileObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ if (ByteOffset == NULL ||
+ (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
+ ByteOffset->u.HighPart == 0xffffffff))
+ {
+ /* a valid ByteOffset is required if asynch. op. */
+ if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ DPRINT1("NtReadFile: missing ByteOffset for asynch. op\n");
+ ObDereferenceObject(FileObject);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ ByteOffset = &FileObject->CurrentByteOffset;
+ }
+
+ if (Event != NULL)
+ {
+ Status = ObReferenceObjectByHandle(Event,
+ SYNCHRONIZE,
+ ExEventObjectType,
+ PreviousMode,
+ (PVOID*)&EventObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+
+ KeClearEvent(EventObject);
+ }
+
+ _SEH_TRY
+ {
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+ FileObject->DeviceObject,
+ Buffer,
+ Length,
+ ByteOffset,
+ EventObject,
+ IoStatusBlock);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status) || Irp == NULL)
+ {
+ if (Event)
{
- *ReturnedLength = IoStatusBlock.Information;
+ ObDereferenceObject(&EventObject);
}
-
-
- return Status;
+ ObDereferenceObject(FileObject);
+ if (Irp)
+ {
+ IoFreeIrp(Irp);
+ }
+ return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status;
+ }
+
+ KeClearEvent(&FileObject->Event);
+
+ /* Trigger FileObject/Event dereferencing */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+
+ Irp->RequestorMode = PreviousMode;
+
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
+
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = FileObject;
+ StackPtr->Parameters.Read.Key = Key ? *Key : 0;
+
+ Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ Status = KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ if (Status != STATUS_WAIT_0)
+ {
+ /* Wait failed. */
+ return Status;
+ }
+
+ Status = IoStatusBlock->Status;
+ }
+
+ return Status;
+}
+
+/*
+ * NAME EXPORTED
+ * NtReadFileScatter
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ */
+NTSTATUS
+STDCALL
+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)
+{
+ UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+NtSetEaFile(IN HANDLE FileHandle,
+ IN PIO_STATUS_BLOCK IoStatusBlock,
+ IN PVOID EaBuffer,
+ IN ULONG EaBufferSize)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
/*
* @implemented
*/
NTSTATUS STDCALL
NtSetInformationFile(HANDLE FileHandle,
- PIO_STATUS_BLOCK IoStatusBlock,
- PVOID FileInformation,
- ULONG Length,
- FILE_INFORMATION_CLASS FileInformationClass)
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PVOID FileInformation,
+ ULONG Length,
+ FILE_INFORMATION_CLASS FileInformationClass)
{
PIO_STACK_LOCATION StackPtr;
PFILE_OBJECT FileObject;
ASSERT(FileInformation != NULL);
DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
- "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
- Length, FileInformationClass);
+ "Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
+ Length, FileInformationClass);
PreviousMode = ExGetPreviousMode();
/* Get the file object from the file handle */
Status = ObReferenceObjectByHandle(FileHandle,
- 0, /* FIXME - depends on the information class */
- IoFileObjectType,
- PreviousMode,
- (PVOID *)&FileObject,
- NULL);
+ 0, /* FIXME - depends on the information class */
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID *)&FileObject,
+ NULL);
if (!NT_SUCCESS(Status))
{
- return Status;
+ return Status;
}
DPRINT("FileObject %x\n", FileObject);
DeviceObject = FileObject->DeviceObject;
Irp = IoAllocateIrp(DeviceObject->StackSize,
- TRUE);
+ TRUE);
if (Irp == NULL)
{
- ObDereferenceObject(FileObject);
- return STATUS_INSUFFICIENT_RESOURCES;
+ ObDereferenceObject(FileObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
- Length,
- TAG_SYSB);
+ Length,
+ TAG_SYSB);
if (SystemBuffer == NULL)
{
- IoFreeIrp(Irp);
- ObDereferenceObject(FileObject);
- return(STATUS_INSUFFICIENT_RESOURCES);
+ IoFreeIrp(Irp);
+ ObDereferenceObject(FileObject);
+ return(STATUS_INSUFFICIENT_RESOURCES);
}
MmSafeCopyFromUser(SystemBuffer,
- FileInformation,
- Length);
+ FileInformation,
+ Length);
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
*/
DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
Status = IoCallDriver(FileObject->DeviceObject,
- Irp);
+ Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
- KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- Status = IoStatusBlock->Status;
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ Status = IoStatusBlock->Status;
}
ExFreePool(SystemBuffer);
return Status;
}
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+NtSetQuotaInformationFile(HANDLE FileHandle,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PFILE_USER_QUOTA_INFORMATION Buffer,
+ ULONG BufferLength)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
-IoSetFileOrigin(
- IN PFILE_OBJECT FileObject,
- IN BOOLEAN Remote
- )
+NtUnlockFile(IN HANDLE FileHandle,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN PLARGE_INTEGER ByteOffset,
+ IN PLARGE_INTEGER Length,
+ OUT PULONG Key OPTIONAL)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PFILE_OBJECT FileObject = NULL;
+ PLARGE_INTEGER LocalLength = NULL;
+ PIRP Irp = NULL;
+ PIO_STACK_LOCATION StackPtr;
+ PDEVICE_OBJECT DeviceObject;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status;
+
+ // FIXME: instead of this, use SEH when available
+ if (!Length || !ByteOffset)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ PreviousMode = ExGetPreviousMode();
+
+ /*
+ * BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
+ * It should ONLY fail if we desire an access that conflict with granted access!
+ */
+ Status = ObReferenceObjectByHandle(FileHandle,
+ 0, //FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID*)&FileObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ goto fail;
+ }
+
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+ Irp = IoAllocateIrp(DeviceObject->StackSize,
+ TRUE);
+ if (Irp == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto fail;
+ }
+
+ /* Trigger FileObject/Event dereferencing */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->RequestorMode = PreviousMode;
+ Irp->UserIosb = IoStatusBlock;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
+ StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
+ StackPtr->DeviceObject = DeviceObject;
+ StackPtr->FileObject = FileObject;
+
+ LocalLength = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(LARGE_INTEGER),
+ TAG_LOCK);
+ if (!LocalLength)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto fail;
+ }
+
+ *LocalLength = *Length;
+
+ StackPtr->Parameters.LockControl.Length = LocalLength;
+ StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
+ StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
+
+ /* Allways synchronous */
+ Status = IofCallDriver(DeviceObject, Irp);
+
+ ExFreePool(LocalLength);
+
+ return Status;
+
+fail:;
+ if (LocalLength)
+ ExFreePool(LocalLength);
+
+ if (Irp)
+ IoFreeIrp(Irp);
+
+ if (FileObject)
+ ObDereferenceObject(FileObject);
+
+ return Status;
}
-NTSTATUS STDCALL
-NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
- OUT PFILE_BASIC_INFORMATION FileInformation)
+/*
+ * NAME EXPORTED
+ * NtWriteFile
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+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, /* NOT optional for asynch. operations! */
+ IN PULONG Key OPTIONAL)
{
- IO_STATUS_BLOCK IoStatusBlock;
- HANDLE FileHandle;
+ OBJECT_HANDLE_INFORMATION HandleInformation;
NTSTATUS Status;
+ PFILE_OBJECT FileObject;
+ PIRP Irp = NULL;
+ PIO_STACK_LOCATION StackPtr;
+ KPROCESSOR_MODE PreviousMode;
+ PKEVENT EventObject = NULL;
+ LARGE_INTEGER Offset;
- /* Open the file */
- Status = ZwOpenFile (&FileHandle,
- SYNCHRONIZE | FILE_READ_ATTRIBUTES,
- ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS (Status))
+ DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
+ "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
+ IoStatusBlock);
+
+ if (IoStatusBlock == NULL)
+ return STATUS_ACCESS_VIOLATION;
+
+ PreviousMode = ExGetPreviousMode();
+
+ Status = ObReferenceObjectByHandle(FileHandle,
+ 0,
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID*)&FileObject,
+ &HandleInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */
+ if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
+ {
+ DPRINT1("Invalid access rights\n");
+ ObDereferenceObject(FileObject);
+ return STATUS_ACCESS_DENIED;
+ }
+
+ if (HandleInformation.GrantedAccess & FILE_WRITE_DATA)
+ {
+ if (ByteOffset == NULL)
{
- DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
- return Status;
+ /* a valid ByteOffset is required if asynch. op. */
+ if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
+ ObDereferenceObject(FileObject);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ ByteOffset = &FileObject->CurrentByteOffset;
+ }
+ }
+ else if (HandleInformation.GrantedAccess & FILE_APPEND_DATA)
+ {
+ /* a valid ByteOffset is required if asynch. op. */
+ if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
+ ObDereferenceObject(FileObject);
+ return STATUS_INVALID_PARAMETER;
}
- /* Get file attributes */
- Status = ZwQueryInformationFile (FileHandle,
- &IoStatusBlock,
- FileInformation,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
- ZwClose (FileHandle);
- if (!NT_SUCCESS (Status))
+ Offset.u.LowPart = FILE_WRITE_TO_END_OF_FILE;
+ Offset.u.HighPart = 0xffffffff;
+ ByteOffset = &Offset;
+ }
+
+ if (Event != NULL)
+ {
+ Status = ObReferenceObjectByHandle(Event,
+ SYNCHRONIZE,
+ ExEventObjectType,
+ PreviousMode,
+ (PVOID*)&EventObject,
+ NULL);
+ if (!NT_SUCCESS(Status))
{
- DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
+ ObDereferenceObject(FileObject);
+ return Status;
}
- return Status;
-}
+ KeClearEvent(EventObject);
+ }
+ _SEH_TRY
+ {
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
+ FileObject->DeviceObject,
+ Buffer,
+ Length,
+ ByteOffset,
+ EventObject,
+ IoStatusBlock);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
-NTSTATUS STDCALL
-NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
- OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
-{
- IO_STATUS_BLOCK IoStatusBlock;
- HANDLE FileHandle;
- NTSTATUS Status;
+ if (!NT_SUCCESS(Status) || Irp == NULL)
+ {
+ if (Event)
+ {
+ ObDereferenceObject(&EventObject);
+ }
+ ObDereferenceObject(FileObject);
+ if (Irp)
+ {
+ IoFreeIrp(Irp);
+ }
+ return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status;
+ }
- /* Open the file */
- Status = ZwOpenFile (&FileHandle,
- SYNCHRONIZE | FILE_READ_ATTRIBUTES,
- ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS (Status))
+ KeClearEvent(&FileObject->Event);
+
+ /* Trigger FileObject/Event dereferencing */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+
+ Irp->RequestorMode = PreviousMode;
+
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
+
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = FileObject;
+ StackPtr->Parameters.Write.Key = Key ? *Key : 0;
+
+ Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
+ {
+ Status = KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
+ NULL);
+ if (Status != STATUS_WAIT_0)
{
- DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
+ /* Wait failed. */
return Status;
}
- /* Get file attributes */
- Status = ZwQueryInformationFile (FileHandle,
- &IoStatusBlock,
- FileInformation,
- sizeof(FILE_NETWORK_OPEN_INFORMATION),
- FileNetworkOpenInformation);
- ZwClose (FileHandle);
- if (!NT_SUCCESS (Status))
- {
- DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
- }
+ Status = IoStatusBlock->Status;
+ }
return Status;
}
-
-/*
- * @unimplemented
- */
-NTSTATUS STDCALL
-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)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-
/*
- * @unimplemented
+ * NAME EXPORTED
+ * NtWriteFileGather
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
*/
-NTSTATUS STDCALL
-NtSetEaFile(IN HANDLE FileHandle,
- IN PIO_STATUS_BLOCK IoStatusBlock,
- IN PVOID EaBuffer,
- IN ULONG EaBufferSize)
+NTSTATUS
+STDCALL
+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)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ UNIMPLEMENTED;
+ return(STATUS_NOT_IMPLEMENTED);
}
-
/* EOF */
+++ /dev/null
-/* $Id:$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/flush.c
- * PURPOSE: Flushing file buffer
- *
- * PROGRAMMERS: David Welch (welch@cwcom.net)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-
-NTSTATUS
-STDCALL
-NtFlushWriteBuffer(VOID)
-{
- KeFlushWriteBuffer();
- return STATUS_SUCCESS;
-}
-
-NTSTATUS
-STDCALL
-NtFlushBuffersFile (
- IN HANDLE FileHandle,
- OUT PIO_STATUS_BLOCK IoStatusBlock
- )
-/*
- * FUNCTION: Flushes cached file data to disk
- * ARGUMENTS:
- * FileHandle = Points to the file
- * IoStatusBlock = Caller must supply storage to receive the result of
- * the flush buffers operation. The information field is
- * set to number of bytes flushed to disk.
- * RETURNS: Status
- * REMARKS: This function maps to the win32 FlushFileBuffers
- */
-{
- PFILE_OBJECT FileObject = NULL;
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
- KPROCESSOR_MODE PreviousMode;
-
- PreviousMode = ExGetPreviousMode();
-
- Status = ObReferenceObjectByHandle(FileHandle,
- FILE_WRITE_DATA,
- NULL,
- PreviousMode,
- (PVOID*)&FileObject,
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
- KeResetEvent( &FileObject->Event );
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS,
- FileObject->DeviceObject,
- NULL,
- 0,
- NULL,
- &FileObject->Event,
- IoStatusBlock);
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
-
- Irp->RequestorMode = PreviousMode;
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
-
- Status = IoCallDriver(FileObject->DeviceObject,Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- Status = IoStatusBlock->Status;
- }
-
- return(Status);
-}
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/ioctrl.c
- * PURPOSE: Device IO control
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- * Eric Kohl (ekohl@rz-online.de)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-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 Status;
- PFILE_OBJECT FileObject;
- PDEVICE_OBJECT DeviceObject;
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- PKEVENT EventObject;
- KPROCESSOR_MODE PreviousMode;
-
- DPRINT("NtDeviceIoControlFile(DeviceHandle %x Event %x UserApcRoutine %x "
- "UserApcContext %x IoStatusBlock %x IoControlCode %x "
- "InputBuffer %x InputBufferLength %x OutputBuffer %x "
- "OutputBufferLength %x)\n",
- DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
- IoControlCode,InputBuffer,InputBufferLength,OutputBuffer,
- OutputBufferLength);
-
- if (IoStatusBlock == NULL)
- return STATUS_ACCESS_VIOLATION;
-
- PreviousMode = ExGetPreviousMode();
-
- /* Check granted access against the access rights from IoContolCode */
- Status = ObReferenceObjectByHandle (DeviceHandle,
- (IoControlCode >> 14) & 0x3,
- IoFileObjectType,
- PreviousMode,
- (PVOID *) &FileObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if (Event != NULL)
- {
- Status = ObReferenceObjectByHandle (Event,
- SYNCHRONIZE,
- ExEventObjectType,
- PreviousMode,
- (PVOID*)&EventObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject (FileObject);
- return Status;
- }
- }
- else
- {
- EventObject = &FileObject->Event;
- KeResetEvent (EventObject);
- }
-
- DeviceObject = FileObject->DeviceObject;
-
- Irp = IoBuildDeviceIoControlRequest (IoControlCode,
- DeviceObject,
- InputBuffer,
- InputBufferLength,
- OutputBuffer,
- OutputBufferLength,
- FALSE,
- EventObject,
- IoStatusBlock);
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
-
- Irp->RequestorMode = PreviousMode;
- Irp->Overlay.AsynchronousParameters.UserApcRoutine = UserApcRoutine;
- Irp->Overlay.AsynchronousParameters.UserApcContext = UserApcContext;
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
- StackPtr->DeviceObject = DeviceObject;
- StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
- StackPtr->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
-
- Status = IoCallDriver(DeviceObject,Irp);
- if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
- {
- Status = KeWaitForSingleObject (EventObject,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- if (Status != STATUS_WAIT_0)
- {
- /* Wait failed. */
- return Status;
- }
-
- Status = IoStatusBlock->Status;
- }
-
- return Status;
-}
-
-/* EOF */
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS Kernel
* FILE: ntoskrnl/io/iomgr.c
- * PURPOSE: Initializes the io manager
+ * PURPOSE: I/O Manager Initialization and Misc Utility Functions
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/* DATA ********************************************************************/
-
POBJECT_TYPE EXPORTED IoDeviceObjectType = NULL;
POBJECT_TYPE EXPORTED IoFileObjectType = NULL;
ULONG EXPORTED IoReadOperationCount = 0;
ULONGLONG IoOtherTransferCount = 0;
KSPIN_LOCK EXPORTED IoStatisticsLock = 0;
-static GENERIC_MAPPING IopFileMapping = {FILE_GENERIC_READ,
- FILE_GENERIC_WRITE,
- FILE_GENERIC_EXECUTE,
- FILE_ALL_ACCESS};
-
-/* FUNCTIONS ****************************************************************/
-
-VOID STDCALL
-IopCloseFile(PVOID ObjectBody,
- ULONG HandleCount)
-{
- PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
-
- DPRINT("IopCloseFile()\n");
-
- if (HandleCount > 1 || FileObject->DeviceObject == NULL)
- {
- return;
- }
-
-#if 0
-//NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
- ObReferenceObjectByPointer(FileObject,
- STANDARD_RIGHTS_REQUIRED,
- IoFileObjectType,
- UserMode);
-#endif
-
- KeResetEvent( &FileObject->Event );
-
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
- FileObject->DeviceObject,
- NULL,
- 0,
- NULL,
- &FileObject->Event,
- NULL);
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
-
- Status = IoCallDriver(FileObject->DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
- }
-}
-
-
-VOID STDCALL
-IopDeleteFile(PVOID ObjectBody)
-{
- PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
-
- DPRINT("IopDeleteFile()\n");
-
- if (FileObject->DeviceObject)
- {
-#if 0
-//NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
-
- ObReferenceObjectByPointer(ObjectBody,
- STANDARD_RIGHTS_REQUIRED,
- IoFileObjectType,
- UserMode);
-#endif
- KeResetEvent( &FileObject->Event );
-
- Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, TRUE);
- if (Irp == NULL)
- {
- /*
- * FIXME: This case should eventually be handled. We should wait
- * until enough memory is available to allocate the IRP.
- */
- ASSERT(FALSE);
- }
-
- Irp->UserEvent = &FileObject->Event;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
- Irp->Flags |= IRP_CLOSE_OPERATION;
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = IRP_MJ_CLOSE;
- StackPtr->DeviceObject = FileObject->DeviceObject;
- StackPtr->FileObject = FileObject;
-
- Status = IoCallDriver(FileObject->DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
- }
- }
-
- if (FileObject->FileName.Buffer != NULL)
- {
- ExFreePool(FileObject->FileName.Buffer);
- FileObject->FileName.Buffer = 0;
- }
-}
-
-
-static NTSTATUS
-IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
- PSECURITY_DESCRIPTOR SecurityDescriptor,
- PULONG BufferLength)
-{
- ULONG_PTR Current;
- ULONG SidSize;
- ULONG SdSize;
- NTSTATUS Status;
-
- DPRINT("IopSetDefaultSecurityDescriptor() called\n");
-
- if (SecurityInformation == 0)
- {
- return STATUS_ACCESS_DENIED;
- }
-
- SidSize = RtlLengthSid(SeWorldSid);
- SdSize = sizeof(SECURITY_DESCRIPTOR) + (2 * SidSize);
-
- if (*BufferLength < SdSize)
- {
- *BufferLength = SdSize;
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- *BufferLength = SdSize;
-
- Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
- SECURITY_DESCRIPTOR_REVISION);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- SecurityDescriptor->Control |= SE_SELF_RELATIVE;
- Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR);
-
- if (SecurityInformation & OWNER_SECURITY_INFORMATION)
- {
- RtlCopyMemory((PVOID)Current,
- SeWorldSid,
- SidSize);
- SecurityDescriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
- Current += SidSize;
- }
-
- if (SecurityInformation & GROUP_SECURITY_INFORMATION)
- {
- RtlCopyMemory((PVOID)Current,
- SeWorldSid,
- SidSize);
- SecurityDescriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
- Current += SidSize;
- }
+GENERIC_MAPPING IopFileMapping = {
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE,
+ FILE_GENERIC_EXECUTE,
+ FILE_ALL_ACCESS};
+
+static KSPIN_LOCK CancelSpinLock;
+extern LIST_ENTRY ShutdownListHead;
+extern KSPIN_LOCK ShutdownListLock;
- if (SecurityInformation & DACL_SECURITY_INFORMATION)
- {
- SecurityDescriptor->Control |= SE_DACL_PRESENT;
- }
+/* INIT FUNCTIONS ************************************************************/
- if (SecurityInformation & SACL_SECURITY_INFORMATION)
- {
- SecurityDescriptor->Control |= SE_SACL_PRESENT;
- }
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS STDCALL
-IopSecurityFile(PVOID ObjectBody,
- SECURITY_OPERATION_CODE OperationCode,
- SECURITY_INFORMATION SecurityInformation,
- PSECURITY_DESCRIPTOR SecurityDescriptor,
- PULONG BufferLength)
+VOID
+INIT_FUNCTION
+IoInitCancelHandling(VOID)
{
- IO_STATUS_BLOCK IoStatusBlock;
- PIO_STACK_LOCATION StackPtr;
- PFILE_OBJECT FileObject;
- PIRP Irp;
- NTSTATUS Status;
-
- DPRINT("IopSecurityFile() called\n");
-
- FileObject = (PFILE_OBJECT)ObjectBody;
-
- switch (OperationCode)
- {
- case SetSecurityDescriptor:
- DPRINT("Set security descriptor\n");
- KeResetEvent(&FileObject->Event);
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SET_SECURITY,
- FileObject->DeviceObject,
- NULL,
- 0,
- NULL,
- &FileObject->Event,
- &IoStatusBlock);
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
-
- StackPtr->Parameters.SetSecurity.SecurityInformation = SecurityInformation;
- StackPtr->Parameters.SetSecurity.SecurityDescriptor = SecurityDescriptor;
-
- Status = IoCallDriver(FileObject->DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&FileObject->Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- Status = IoStatusBlock.Status;
- }
-
- if (Status == STATUS_INVALID_DEVICE_REQUEST)
- {
- Status = STATUS_SUCCESS;
- }
- return Status;
-
- case QuerySecurityDescriptor:
- DPRINT("Query security descriptor\n");
- KeResetEvent(&FileObject->Event);
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_SECURITY,
- FileObject->DeviceObject,
- NULL,
- 0,
- NULL,
- &FileObject->Event,
- &IoStatusBlock);
-
- Irp->UserBuffer = SecurityDescriptor;
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
-
- StackPtr->Parameters.QuerySecurity.SecurityInformation = SecurityInformation;
- StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
-
- Status = IoCallDriver(FileObject->DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&FileObject->Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- Status = IoStatusBlock.Status;
- }
-
- if (Status == STATUS_INVALID_DEVICE_REQUEST)
- {
- Status = IopSetDefaultSecurityDescriptor(SecurityInformation,
- SecurityDescriptor,
- BufferLength);
- }
- else
- {
- /* FIXME: Is this correct?? */
- *BufferLength = IoStatusBlock.Information;
- }
- return Status;
-
- case DeleteSecurityDescriptor:
- DPRINT("Delete security descriptor\n");
- return STATUS_SUCCESS;
-
- case AssignSecurityDescriptor:
- DPRINT("Assign security descriptor\n");
- return STATUS_SUCCESS;
- }
-
- return STATUS_UNSUCCESSFUL;
+ KeInitializeSpinLock(&CancelSpinLock);
}
-
-NTSTATUS STDCALL
-IopQueryNameFile(PVOID ObjectBody,
- POBJECT_NAME_INFORMATION ObjectNameInfo,
- ULONG Length,
- PULONG ReturnLength)
+VOID
+INIT_FUNCTION
+IoInitShutdownNotification (VOID)
{
- POBJECT_NAME_INFORMATION LocalInfo;
- PFILE_NAME_INFORMATION FileNameInfo;
- PFILE_OBJECT FileObject;
- ULONG LocalReturnLength;
- NTSTATUS Status;
-
- DPRINT ("IopQueryNameFile() called\n");
-
- FileObject = (PFILE_OBJECT)ObjectBody;
-
- LocalInfo = ExAllocatePool (NonPagedPool,
- sizeof(OBJECT_NAME_INFORMATION) +
- MAX_PATH * sizeof(WCHAR));
- if (LocalInfo == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- Status = ObQueryNameString (FileObject->DeviceObject->Vpb->RealDevice,
- LocalInfo,
- MAX_PATH * sizeof(WCHAR),
- &LocalReturnLength);
- if (!NT_SUCCESS (Status))
- {
- ExFreePool (LocalInfo);
- return Status;
- }
- DPRINT ("Device path: %wZ\n", &LocalInfo->Name);
-
- Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
- &LocalInfo->Name);
-
- ExFreePool (LocalInfo);
-
- FileNameInfo = ExAllocatePool (NonPagedPool,
- MAX_PATH * sizeof(WCHAR) + sizeof(ULONG));
- if (FileNameInfo == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- Status = IoQueryFileInformation (FileObject,
- FileNameInformation,
- MAX_PATH * sizeof(WCHAR) + sizeof(ULONG),
- FileNameInfo,
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- ExFreePool (FileNameInfo);
- return Status;
- }
-
- Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
- FileNameInfo->FileName);
-
- DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
-
- ExFreePool (FileNameInfo);
-
- return Status;
+ InitializeListHead(&ShutdownListHead);
+ KeInitializeSpinLock(&ShutdownListLock);
}
-
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
IoInit (VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
PnpInit();
}
-
VOID
INIT_FUNCTION
IoInit2(BOOLEAN BootLog)
NULL);
}
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+IoAcquireCancelSpinLock(PKIRQL Irql)
+{
+ KeAcquireSpinLock(&CancelSpinLock,Irql);
+}
+
+/*
+ * @implemented
+ */
+PVOID
+STDCALL
+IoGetInitialStack(VOID)
+{
+ return(PsGetCurrentThread()->Tcb.InitialStack);
+}
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+IoGetStackLimits(OUT PULONG LowLimit,
+ OUT PULONG HighLimit)
+{
+ *LowLimit = (ULONG)NtCurrentTeb()->Tib.StackLimit;
+ *HighLimit = (ULONG)NtCurrentTeb()->Tib.StackBase;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+IoIsSystemThread(IN PETHREAD Thread)
+{
+ /* Call the Ps Function */
+ return PsIsSystemThread(Thread);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN STDCALL
+IoIsWdmVersionAvailable(IN UCHAR MajorVersion,
+ IN UCHAR MinorVersion)
+{
+ if (MajorVersion <= 1 && MinorVersion <= 10)
+ return TRUE;
+ return FALSE;
+}
+
/*
* @implemented
*/
-PGENERIC_MAPPING STDCALL
-IoGetFileObjectGenericMapping(VOID)
+VOID
+STDCALL
+IoReleaseCancelSpinLock(KIRQL Irql)
+{
+ KeReleaseSpinLock(&CancelSpinLock,Irql);
+}
+
+/*
+ * @implemented
+ */
+PEPROCESS
+STDCALL
+IoThreadToProcess(IN PETHREAD Thread)
{
- return(&IopFileMapping);
+ return(Thread->ThreadsProcess);
}
/* EOF */
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/irp.c
* PURPOSE: Handle IRPs
*
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* NOTES *******************************************************************
- *
- * Layout of an IRP
- *
- * ################
- * # Headers #
- * ################
- * # #
- * # Variable #
- * # length list #
- * # of io stack #
- * # locations #
- * # #
- * ################
- *
- *
- *
+ * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
+ * David Welch (welch@mcmail.com)
*/
/* INCLUDES ****************************************************************/
/* GLOBALS *******************************************************************/
-#define TAG_IRP TAG('I', 'R', 'P', ' ')
+#define TAG_IRP TAG('I', 'R', 'P', ' ')
+#define TAG_SYS_BUF TAG('I', 'o', ' ' , ' ')
-
-/* FUNCTIONS ****************************************************************/
+/* FUNCTIONS *****************************************************************/
/*
- * @unimplemented
+ * @implemented
+ *
+ * FUNCTION: Allocates an IRP
+ * ARGUMENTS:
+ * StackSize = the size of the stack required for the irp
+ * ChargeQuota = Charge allocation to current threads quota
+ * RETURNS: Irp allocated
*/
-BOOLEAN
+PIRP
STDCALL
-IoForwardIrpSynchronously(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
+IoAllocateIrp(CCHAR StackSize,
+ BOOLEAN ChargeQuota)
{
- UNIMPLEMENTED;
- return FALSE;
+ PIRP Irp;
+ USHORT Size = IoSizeOfIrp(StackSize);
+
+ /* Check if we shoudl charge quota */
+ if (ChargeQuota)
+ {
+ /* Irp = ExAllocatePoolWithQuotaTag(NonPagedPool,IoSizeOfIrp(StackSize), TAG_IRP); */
+ /* FIXME */
+ Irp = ExAllocatePoolWithTag(NonPagedPool,
+ Size,
+ TAG_IRP);
+ }
+ else
+ {
+ /* Allocate the IRP With no Quota charge */
+ Irp = ExAllocatePoolWithTag(NonPagedPool,
+ Size,
+ TAG_IRP);
+ }
+
+ /* Make sure it was sucessful */
+ if (Irp==NULL) return(NULL);
+
+ /* Now Initialize it */
+ IoInitializeIrp(Irp, Size, StackSize);
+
+ /* Return it */
+ return Irp;
}
/*
* @implemented
- */
-VOID STDCALL
-IoFreeIrp(PIRP Irp)
-/*
- * FUNCTION: Releases a caller allocated irp
+ *
+ * FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
* ARGUMENTS:
- * Irp = Irp to free
- */
-{
- ExFreePool(Irp);
-}
-
-/*
- * @unimplemented
+ * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
+ * IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
+ * DeviceObject = Device object to send the irp to
+ * Buffer = Buffer into which data will be read or written
+ * Length = Length in bytes of the irp to be allocated
+ * StartingOffset = Starting offset on the device
+ * IoStatusBlock (OUT) = Storage for the result of the operation
+ * RETURNS: The IRP allocated on success, or
+ * NULL on failure
*/
-BOOLEAN
+PIRP
STDCALL
-IoIsValidNameGraftingBuffer(
- IN PIRP Irp,
- IN PREPARSE_DATA_BUFFER ReparseBuffer
- )
+IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
+ PDEVICE_OBJECT DeviceObject,
+ PVOID Buffer,
+ ULONG Length,
+ PLARGE_INTEGER StartingOffset,
+ PIO_STATUS_BLOCK IoStatusBlock)
{
- UNIMPLEMENTED;
- return FALSE;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
+ LOCK_OPERATION AccessType;
+
+ DPRINT("IoBuildAsynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
+ "Buffer %x, Length %x, StartingOffset %x, "
+ "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
+ StartingOffset,IoStatusBlock);
+
+ /* Allocate IRP */
+ if (!(Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE))) return Irp;
+
+ /* Get the Stack */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+
+ /* Write the Major function and then deal with it */
+ StackPtr->MajorFunction = (UCHAR)MajorFunction;
+
+ /* Do not handle the following here */
+ if (MajorFunction != IRP_MJ_FLUSH_BUFFERS &&
+ MajorFunction != IRP_MJ_SHUTDOWN &&
+ MajorFunction != IRP_MJ_PNP)
+ {
+ /* Check if this is Buffered IO */
+ if (DeviceObject->Flags & DO_BUFFERED_IO)
+ {
+ /* Allocate the System Buffer */
+ Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
+ Length,
+ TAG_SYS_BUF);
+
+ /* Set flags */
+ Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
+
+ /* Handle special IRP_MJ_WRITE Case */
+ if (MajorFunction == IRP_MJ_WRITE)
+ {
+ /* Copy the buffer data */
+ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length);
+ }
+ else
+ {
+ /* Set the Input Operation flag and set this as a User Buffer */
+ Irp->Flags = IRP_INPUT_OPERATION;
+ Irp->UserBuffer = Buffer;
+ }
+ }
+ else if (DeviceObject->Flags & DO_DIRECT_IO)
+ {
+ /* Use an MDL for Direct I/O */
+ Irp->MdlAddress = MmCreateMdl(NULL, Buffer, Length);
+
+ /* Use the right Access Type */
+ if (MajorFunction == IRP_MJ_READ)
+ {
+ AccessType = IoReadAccess;
+ }
+ else
+ {
+ AccessType = IoWriteAccess;
+ }
+
+ /* Probe and Lock */
+ _SEH_FILTER(FreeAndGoOn)
+ {
+ /* Free the IRP and its MDL */
+ IoFreeMdl(Irp->MdlAddress);
+ IoFreeIrp(Irp);
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+ _SEH_TRY_FILTER(FreeAndGoOn)
+ {
+ /* Do the probe */
+ MmProbeAndLockPages(Irp->MdlAddress, KernelMode, AccessType);
+ }
+ _SEH_HANDLE
+ {
+ return NULL;
+ }
+ _SEH_END;
+ }
+ else
+ {
+ /* Neither, use the buffer */
+ Irp->UserBuffer = Buffer;
+ }
+
+ if (MajorFunction == IRP_MJ_READ)
+ {
+ StackPtr->Parameters.Read.Length = Length;
+ StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
+ }
+ else if (MajorFunction == IRP_MJ_WRITE)
+ {
+ StackPtr->Parameters.Write.Length = Length;
+ StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
+ }
+ }
+
+ /* Set the Current Thread and IOSB */
+ Irp->UserIosb = IoStatusBlock;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+
+ /* Set the Status Block after all is done */
+ return Irp;
}
/*
* @implemented
- */
-PIRP STDCALL
-IoMakeAssociatedIrp(PIRP Irp,
- CCHAR StackSize)
-/*
- * FUNCTION: Allocates and initializes an irp to associated with a master irp
+ *
+ * FUNCTION: Allocates and sets up an IRP to be sent to drivers
* ARGUMENTS:
- * Irp = Master irp
- * StackSize = Number of stack locations to be allocated in the irp
- * RETURNS: The irp allocated
- * NOTE: The caller is responsible for incrementing
- * Irp->AssociatedIrp.IrpCount.
+ * IoControlCode = Device io control code
+ * DeviceObject = Device object to send the irp to
+ * InputBuffer = Buffer from which data will be read by the driver
+ * InputBufferLength = Length in bytes of the input buffer
+ * OutputBuffer = Buffer into which data will be written by the driver
+ * OutputBufferLength = Length in bytes of the output buffer
+ * InternalDeviceIoControl = Determines weather
+ * IRP_MJ_INTERNAL_DEVICE_CONTROL or
+ * IRP_MJ_DEVICE_CONTROL will be used
+ * Event = Event used to notify the caller of completion
+ * IoStatusBlock (OUT) = Storage for the result of the operation
+ * RETURNS: The IRP allocated on success, or
+ * NULL on failure
*/
+PIRP
+STDCALL
+IoBuildDeviceIoControlRequest(ULONG IoControlCode,
+ PDEVICE_OBJECT DeviceObject,
+ PVOID InputBuffer,
+ ULONG InputBufferLength,
+ PVOID OutputBuffer,
+ ULONG OutputBufferLength,
+ BOOLEAN InternalDeviceIoControl,
+ PKEVENT Event,
+ PIO_STATUS_BLOCK IoStatusBlock)
{
- PIRP AssocIrp;
-
- /* Allocate the IRP */
- AssocIrp = IoAllocateIrp(StackSize,FALSE);
- if (AssocIrp == NULL)
- return NULL;
-
- /* Set the Flags */
- AssocIrp->Flags |= IRP_ASSOCIATED_IRP;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
+ ULONG BufferLength;
+ LOCK_OPERATION AccessType;
+
+ DPRINT("IoBuildDeviceIoRequest(IoControlCode %x, DeviceObject %x, "
+ "InputBuffer %x, InputBufferLength %x, OutputBuffer %x, "
+ "OutputBufferLength %x, InternalDeviceIoControl %x "
+ "Event %x, IoStatusBlock %x\n",IoControlCode,DeviceObject,
+ InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength,
+ InternalDeviceIoControl,Event,IoStatusBlock);
+
+ /* Allocate IRP */
+ if (!(Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE))) return Irp;
+
+ /* Get the Stack */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+
+ /* Set the DevCtl Type */
+ StackPtr->MajorFunction = InternalDeviceIoControl ?
+ IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
+
+ /* Set the IOCTL Data */
+ StackPtr->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
+ StackPtr->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
+ StackPtr->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
- /* Set the Thread */
- AssocIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
+ /* Handle the Methods */
+ switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
+ {
+ case METHOD_BUFFERED:
+ DPRINT("Using METHOD_BUFFERED!\n");
+
+ /* Select the right Buffer Length */
+ BufferLength = InputBufferLength > OutputBufferLength ? InputBufferLength : OutputBufferLength;
+
+ /* Make sure there is one */
+ if (BufferLength)
+ {
+ /* Allocate the System Buffer */
+ Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
+ BufferLength,
+ TAG_SYS_BUF);
+
+ /* Fail if we couldn't */
+ if (Irp->AssociatedIrp.SystemBuffer == NULL)
+ {
+ IoFreeIrp(Irp);
+ return(NULL);
+ }
+
+ /* Check if we got a buffer */
+ if (InputBuffer)
+ {
+ /* Copy into the System Buffer */
+ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
+ InputBuffer,
+ InputBufferLength);
+ }
+
+ /* Write the flags */
+ Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
+ if (OutputBuffer) Irp->Flags |= IRP_INPUT_OPERATION;
+
+ /* Save the Buffer */
+ Irp->UserBuffer = OutputBuffer;
+ }
+ else
+ {
+ /* Clear the Flags and Buffer */
+ Irp->Flags = 0;
+ Irp->UserBuffer = NULL;
+ }
+ break;
+
+ case METHOD_IN_DIRECT:
+ case METHOD_OUT_DIRECT:
+ DPRINT("Using METHOD_IN/OUT DIRECT!\n");
+
+ /* Check if we got an input buffer */
+ if (InputBuffer)
+ {
+ /* Allocate the System Buffer */
+ Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
+ InputBufferLength,
+ TAG_SYS_BUF);
+
+ /* Fail if we couldn't */
+ if (Irp->AssociatedIrp.SystemBuffer == NULL)
+ {
+ IoFreeIrp(Irp);
+ return(NULL);
+ }
+
+ /* Copy into the System Buffer */
+ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
+ InputBuffer,
+ InputBufferLength);
+
+ /* Write the flags */
+ Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
+ }
+ else
+ {
+ Irp->Flags = 0;
+ }
+
+ /* Check if we got an output buffer */
+ if (OutputBuffer)
+ {
+ /* Allocate the System Buffer */
+ Irp->MdlAddress = IoAllocateMdl(OutputBuffer,
+ OutputBufferLength,
+ FALSE,
+ FALSE,
+ Irp);
+
+ /* Fail if we couldn't */
+ if (Irp->MdlAddress == NULL)
+ {
+ IoFreeIrp(Irp);
+ return NULL;
+ }
+
+ /* Probe and Lock */
+ _SEH_FILTER(FreeAndGoOn)
+ {
+ /* Free the MDL and IRP */
+ IoFreeMdl(Irp->MdlAddress);
+ IoFreeIrp(Irp);
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+ _SEH_TRY_FILTER(FreeAndGoOn)
+ {
+ /* Use the right Access Type */
+ if (IO_METHOD_FROM_CTL_CODE(IoControlCode) == METHOD_IN_DIRECT)
+ {
+ AccessType = IoReadAccess;
+ }
+ else
+ {
+ AccessType = IoWriteAccess;
+ }
+
+ /* Do the probe */
+ MmProbeAndLockPages(Irp->MdlAddress, KernelMode, AccessType);
+ }
+ _SEH_HANDLE
+ {
+ return NULL;
+ }
+ _SEH_END;
+ }
+ break;
+
+ case METHOD_NEITHER:
+
+ /* Just save the Buffer */
+ Irp->UserBuffer = OutputBuffer;
+ StackPtr->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
+ break;
+ }
+
+ /* Now write the Event and IoSB */
+ Irp->UserIosb = IoStatusBlock;
+ Irp->UserEvent = Event;
- /* Associate them */
- AssocIrp->AssociatedIrp.MasterIrp = Irp;
-
- return AssocIrp;
+ /* Sync IRPs are queued to requestor thread's irp cancel/cleanup list */
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+ IoQueueThreadIrp(Irp);
+
+ /* Return the IRP */
+ return Irp;
}
-
/*
* @implemented
- */
-VOID STDCALL
-IoInitializeIrp(PIRP Irp,
- USHORT PacketSize,
- CCHAR StackSize)
-/*
- * FUNCTION: Initalizes an irp allocated by the caller
+ *
+ * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
+ * level driver(s)
* ARGUMENTS:
- * Irp = IRP to initalize
- * PacketSize = Size in bytes of the IRP
- * StackSize = Number of stack locations in the IRP
+ * MajorFunction = Major function code, one of IRP_MJ_READ,
+ * IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
+ * DeviceObject = Target device object
+ * Buffer = Buffer containing data for a read or write
+ * Length = Length in bytes of the information to be transferred
+ * StartingOffset = Offset to begin the read/write from
+ * Event (OUT) = Will be set when the operation is complete
+ * IoStatusBlock (OUT) = Set to the status of the operation
+ * RETURNS: The IRP allocated on success, or
+ * NULL on failure
*/
+PIRP
+STDCALL
+IoBuildSynchronousFsdRequest(ULONG MajorFunction,
+ PDEVICE_OBJECT DeviceObject,
+ PVOID Buffer,
+ ULONG Length,
+ PLARGE_INTEGER StartingOffset,
+ PKEVENT Event,
+ PIO_STATUS_BLOCK IoStatusBlock)
{
- ASSERT(Irp != NULL);
+ PIRP Irp;
+
+ DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
+ "Buffer %x, Length %x, StartingOffset %x, Event %x, "
+ "IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
+ StartingOffset,Event,IoStatusBlock);
+
+ /* Do the big work to set up the IRP */
+ Irp = IoBuildAsynchronousFsdRequest(MajorFunction,
+ DeviceObject,
+ Buffer,
+ Length,
+ StartingOffset,
+ IoStatusBlock );
+
+ /* Set the Event which makes it Syncronous */
+ Irp->UserEvent = Event;
- DPRINT("IoInitializeIrp(StackSize %x, Irp %x)\n",StackSize, Irp);
- memset(Irp, 0, PacketSize);
- Irp->Size = PacketSize;
- Irp->StackCount = StackSize;
- Irp->CurrentLocation = StackSize;
- InitializeListHead(&Irp->ThreadListEntry);
- Irp->Tail.Overlay.CurrentStackLocation = (PIO_STACK_LOCATION)(Irp + 1) + StackSize;
- DPRINT("Irp->Tail.Overlay.CurrentStackLocation %x\n", Irp->Tail.Overlay.CurrentStackLocation);
- Irp->ApcEnvironment = KeGetCurrentThread()->ApcStateIndex;
+ /* Sync IRPs are queued to requestor thread's irp cancel/cleanup list */
+ IoQueueThreadIrp(Irp);
+ return(Irp);
}
-
/*
* @implemented
*/
-NTSTATUS FASTCALL
-IofCallDriver(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-/*
- * FUNCTION: Sends an IRP to the next lower driver
+BOOLEAN
+STDCALL
+IoCancelIrp(PIRP Irp)
+{
+ KIRQL oldlvl;
+ PDRIVER_CANCEL CancelRoutine;
+
+ DPRINT("IoCancelIrp(Irp %x)\n",Irp);
+
+ IoAcquireCancelSpinLock(&oldlvl);
+
+ Irp->Cancel = TRUE;
+
+ CancelRoutine = IoSetCancelRoutine(Irp, NULL);
+ if (CancelRoutine == NULL)
+ {
+ IoReleaseCancelSpinLock(oldlvl);
+ return(FALSE);
+ }
+
+ Irp->CancelIrql = oldlvl;
+ CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
+ return(TRUE);
+}
+
+/**
+ * @name IoCancelThreadIo
+ *
+ * Cancel all pending I/O request associated with specified thread.
+ *
+ * @param Thread
+ * Thread to cancel requests for.
*/
+
+VOID
+STDCALL
+IoCancelThreadIo(PETHREAD Thread)
{
- PDRIVER_OBJECT DriverObject;
- PIO_STACK_LOCATION Param;
+ PLIST_ENTRY IrpEntry;
+ PIRP Irp;
+ KIRQL OldIrql;
+ ULONG Retries = 3000;
+ LARGE_INTEGER Interval;
- DPRINT("IofCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
+ OldIrql = KfRaiseIrql(APC_LEVEL);
- ASSERT(Irp);
- ASSERT(DeviceObject);
+ /*
+ * Start by cancelling all the IRPs in the current thread queue.
+ */
- DriverObject = DeviceObject->DriverObject;
+ for (IrpEntry = Thread->IrpList.Flink;
+ IrpEntry != &Thread->IrpList;
+ IrpEntry = IrpEntry->Flink)
+ {
+ Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
+ IoCancelIrp(Irp);
+ }
- ASSERT(DriverObject);
+ /*
+ * Wait till all the IRPs are completed or cancelled.
+ */
- IoSetNextIrpStackLocation(Irp);
- Param = IoGetCurrentIrpStackLocation(Irp);
+ while (!IsListEmpty(&Thread->IrpList))
+ {
+ KfLowerIrql(OldIrql);
- DPRINT("IrpSp 0x%X\n", Param);
+ /* Wait a short while and then look if all our IRPs were completed. */
+ Interval.QuadPart = -1000000; /* 100 milliseconds */
+ KeDelayExecutionThread(KernelMode, FALSE, &Interval);
- Param->DeviceObject = DeviceObject;
+ /*
+ * Don't stay here forever if some broken driver doesn't complete
+ * the IRP.
+ */
- DPRINT("MajorFunction %d\n", Param->MajorFunction);
- DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
- DriverObject->MajorFunction[Param->MajorFunction]);
+ if (Retries-- == 0)
+ {
+ /* FIXME: Handle this gracefully. */
+ DPRINT1("Thread with dead IRPs!");
+ ASSERT(FALSE);
+ }
+
+ OldIrql = KfRaiseIrql(APC_LEVEL);
+ }
- return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
+ KfLowerIrql(OldIrql);
}
#ifdef IoCallDriver
STDCALL
IoCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
- return(IofCallDriver(DeviceObject,
- Irp));
+ /* Call fast call */
+ return IofCallDriver(DeviceObject, Irp);
}
-
/*
* @implemented
*/
-PIRP STDCALL
-IoAllocateIrp(CCHAR StackSize,
- BOOLEAN ChargeQuota)
+VOID
+STDCALL
+IoCompleteRequest(PIRP Irp,
+ CCHAR PriorityBoost)
+{
+ /* Call the fastcall */
+ IofCompleteRequest(Irp, PriorityBoost);
+}
+
/*
- * FUNCTION: Allocates an IRP
- * ARGUMENTS:
- * StackSize = the size of the stack required for the irp
- * ChargeQuota = Charge allocation to current threads quota
- * RETURNS: Irp allocated
+ * @implemented
*/
+VOID
+STDCALL
+IoEnqueueIrp(IN PIRP Irp)
{
- PIRP Irp;
+ IoQueueThreadIrp(Irp);
+}
-#if 0
- DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
- StackSize,
- ChargeQuota);
- KeDumpStackFrames(0,8);
-#endif
-
- if (ChargeQuota)
- {
-// Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
- Irp = ExAllocatePoolWithTag(NonPagedPool,
- IoSizeOfIrp(StackSize),
- TAG_IRP);
- }
- else
- {
- Irp = ExAllocatePoolWithTag(NonPagedPool,
- IoSizeOfIrp(StackSize),
- TAG_IRP);
- }
+/*
+ * @implemented
+ *
+ * FUNCTION: Sends an IRP to the next lower driver
+ */
+NTSTATUS
+FASTCALL
+IofCallDriver(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
- if (Irp==NULL)
- {
- return(NULL);
- }
+{
+ PDRIVER_OBJECT DriverObject;
+ PIO_STACK_LOCATION Param;
- IoInitializeIrp(Irp,
- IoSizeOfIrp(StackSize),
- StackSize);
+ DPRINT("IofCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
-// DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
+ /* Get the Driver Object */
+ DriverObject = DeviceObject->DriverObject;
+
+ /* Set the Stack Location */
+ IoSetNextIrpStackLocation(Irp);
+
+ /* Get the current one */
+ Param = IoGetCurrentIrpStackLocation(Irp);
+
+ DPRINT("IrpSp 0x%X\n", Param);
- return(Irp);
+ /* Get the Device Object */
+ Param->DeviceObject = DeviceObject;
+
+ /* Call it */
+ return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
}
#ifdef IoCompleteRequest
}
}
+/*
+ * @unimplemented
+ */
+BOOLEAN
+STDCALL
+IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
/*
* @implemented
+ *
+ * FUNCTION: Releases a caller allocated irp
+ * ARGUMENTS:
+ * Irp = Irp to free
*/
-VOID STDCALL
-IoCompleteRequest(PIRP Irp,
- CCHAR PriorityBoost)
+VOID
+STDCALL
+IoFreeIrp(PIRP Irp)
+{
+ /* Free the pool memory associated with it */
+ ExFreePool(Irp);
+}
+
+/*
+ * @implemented
+ */
+PEPROCESS STDCALL
+IoGetRequestorProcess(IN PIRP Irp)
+{
+ return(Irp->Tail.Overlay.Thread->ThreadsProcess);
+}
+
+/*
+ * @implemented
+ */
+ULONG
+STDCALL
+IoGetRequestorProcessId(IN PIRP Irp)
+{
+ return (ULONG)(IoGetRequestorProcess(Irp)->UniqueProcessId);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+IoGetRequestorSessionId(IN PIRP Irp,
+ OUT PULONG pSessionId)
+{
+ *pSessionId = IoGetRequestorProcess(Irp)->SessionId;
+
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+PIRP
+STDCALL
+IoGetTopLevelIrp(VOID)
{
- IofCompleteRequest(Irp, PriorityBoost);
+ return(PsGetCurrentThread()->TopLevelIrp);
}
+/*
+ * @implemented
+ *
+ * FUNCTION: Initalizes an irp allocated by the caller
+ * ARGUMENTS:
+ * Irp = IRP to initalize
+ * PacketSize = Size in bytes of the IRP
+ * StackSize = Number of stack locations in the IRP
+ */
+VOID
+STDCALL
+IoInitializeIrp(PIRP Irp,
+ USHORT PacketSize,
+ CCHAR StackSize)
+{
+ ASSERT(Irp != NULL);
-/**********************************************************************
+ DPRINT("IoInitializeIrp(StackSize %x, Irp %x)\n",StackSize, Irp);
+
+ /* Clear it */
+ RtlZeroMemory(Irp, PacketSize);
+
+ /* Set the Header and other data */
+ Irp->Type = IO_TYPE_IRP;
+ Irp->Size = PacketSize;
+ Irp->StackCount = StackSize;
+ Irp->CurrentLocation = StackSize;
+ Irp->ApcEnvironment = KeGetCurrentThread()->ApcStateIndex;
+ Irp->Tail.Overlay.CurrentStackLocation = (PIO_STACK_LOCATION)(Irp + 1) + StackSize;
+
+ /* Initialize the Thread List */
+ InitializeListHead(&Irp->ThreadListEntry);
+
+ DPRINT("Irp->Tail.Overlay.CurrentStackLocation %x\n", Irp->Tail.Overlay.CurrentStackLocation);
+}
+
+/*
* NAME EXPORTED
* IoIsOperationSynchronous@4
*
*
* @implemented
*/
-BOOLEAN STDCALL
+BOOLEAN
+STDCALL
IoIsOperationSynchronous(IN PIRP Irp)
{
- PFILE_OBJECT FileObject = NULL;
-
- FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
-
- if (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO)
- {
- return TRUE;
- }
-
- if (Irp->Flags & IRP_PAGING_IO)
- {
- return FALSE;
- }
-
- //NOTE: Windows 2000 crash if IoStack->FileObject == NULL, so I guess we should too;-)
- if (Irp->Flags & IRP_SYNCHRONOUS_API || FileObject->Flags & FO_SYNCHRONOUS_IO)
- {
- return TRUE;
- }
+ /* Check the flags */
+ if ((Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ||
+ (Irp->Flags & IRP_SYNCHRONOUS_API) ||
+ (IoGetCurrentIrpStackLocation(Irp)->FileObject->Flags &
+ FO_SYNCHRONOUS_IO))
+ {
+ /* Synch API or Paging I/O is OK, as is Sync File I/O */
+ return TRUE;
+ }
- /* Otherwise, it is an asynchronous operation. */
- return FALSE;
+ /* Otherwise, it is an asynchronous operation. */
+ return FALSE;
}
-
/*
- * @implemented
+ * @unimplemented
*/
-VOID STDCALL
-IoEnqueueIrp(IN PIRP Irp)
+BOOLEAN
+STDCALL
+IoIsValidNameGraftingBuffer(IN PIRP Irp,
+ IN PREPARSE_DATA_BUFFER ReparseBuffer)
{
- IoQueueThreadIrp(Irp);
+ UNIMPLEMENTED;
+ return FALSE;
}
-
/*
* @implemented
+ *
+ * FUNCTION: Allocates and initializes an irp to associated with a master irp
+ * ARGUMENTS:
+ * Irp = Master irp
+ * StackSize = Number of stack locations to be allocated in the irp
+ * RETURNS: The irp allocated
+ * NOTE: The caller is responsible for incrementing
+ * Irp->AssociatedIrp.IrpCount.
*/
-VOID STDCALL
-IoSetTopLevelIrp(IN PIRP Irp)
+PIRP
+STDCALL
+IoMakeAssociatedIrp(PIRP Irp,
+ CCHAR StackSize)
{
- PETHREAD Thread;
+ PIRP AssocIrp;
- Thread = PsGetCurrentThread();
- Thread->TopLevelIrp = Irp;
-}
+ /* Allocate the IRP */
+ AssocIrp = IoAllocateIrp(StackSize,FALSE);
+ if (AssocIrp == NULL) return NULL;
+
+ /* Set the Flags */
+ AssocIrp->Flags |= IRP_ASSOCIATED_IRP;
+
+ /* Set the Thread */
+ AssocIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
+ /* Associate them */
+ AssocIrp->AssociatedIrp.MasterIrp = Irp;
+
+ return AssocIrp;
+}
/*
* @implemented
*/
-PIRP STDCALL
-IoGetTopLevelIrp(VOID)
+NTSTATUS
+STDCALL
+IoPageRead(PFILE_OBJECT FileObject,
+ PMDL Mdl,
+ PLARGE_INTEGER Offset,
+ PKEVENT Event,
+ PIO_STATUS_BLOCK StatusBlock)
{
- return(PsGetCurrentThread()->TopLevelIrp);
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
+ PDEVICE_OBJECT DeviceObject;
+
+ DPRINT("IoPageRead(FileObject %x, Mdl %x)\n",
+ FileObject, Mdl);
+
+ /* Get the Device Object */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+ /* Allocate IRP */
+ Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+
+ /* Get the Stack */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+
+ /* Create the IRP Settings */
+ Irp->MdlAddress = Mdl;
+ Irp->UserBuffer = MmGetMdlVirtualAddress(Mdl);
+ Irp->UserIosb = StatusBlock;
+ Irp->UserEvent = Event;
+ Irp->RequestorMode = KernelMode;
+ Irp->Flags = IRP_PAGING_IO | IRP_NOCACHE | IRP_SYNCHRONOUS_PAGING_IO | IRP_INPUT_OPERATION;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+
+ /* Set the Stack Settings */
+ StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
+ StackPtr->Parameters.Read.ByteOffset = *Offset;
+ StackPtr->MajorFunction = IRP_MJ_READ;
+ StackPtr->FileObject = FileObject;
+
+ /* Call the Driver */
+ return IofCallDriver(DeviceObject, Irp);
}
-
/*
* @implemented
*/
-VOID STDCALL
+VOID
+STDCALL
IoQueueThreadIrp(IN PIRP Irp)
{
- KIRQL OldIrql;
+ KIRQL OldIrql;
- OldIrql = KfRaiseIrql(APC_LEVEL);
+ /* Raise to APC */
+ OldIrql = KfRaiseIrql(APC_LEVEL);
/*
* Synchronous irp's are queued to requestor thread. If they are not
* completed when the thread exits, they are canceled (cleaned up).
* - Gunnar
*/
+ InsertTailList(&Irp->Tail.Overlay.Thread->IrpList, &Irp->ThreadListEntry);
+
+ /* Lower back */
+ KfLowerIrql(OldIrql);
+}
- InsertTailList(&Irp->Tail.Overlay.Thread->IrpList, &Irp->ThreadListEntry);
+/*
+ * @implemented
+ * Reference: Chris Cant's "Writing WDM Device Drivers"
+ */
+VOID
+STDCALL
+IoReuseIrp(IN OUT PIRP Irp,
+ IN NTSTATUS Status)
+{
+ UCHAR AllocationFlags;
+
+ /* Get the old flags */
+ AllocationFlags = Irp->AllocationFlags;
- KfLowerIrql(OldIrql);
+ /* Reinitialize the IRP */
+ IoInitializeIrp(Irp, Irp->Size, Irp->StackCount);
+
+ /* Duplicate the data */
+ Irp->IoStatus.Status = Status;
+ Irp->AllocationFlags = AllocationFlags;
}
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+IoSetTopLevelIrp(IN PIRP Irp)
+{
+ PsGetCurrentThread()->TopLevelIrp = Irp;
+}
/*
* @implemented
*/
+NTSTATUS
+STDCALL
+IoSynchronousPageWrite(PFILE_OBJECT FileObject,
+ PMDL Mdl,
+ PLARGE_INTEGER Offset,
+ PKEVENT Event,
+ PIO_STATUS_BLOCK StatusBlock)
+{
+ PIRP Irp;
+ PIO_STACK_LOCATION StackPtr;
+ PDEVICE_OBJECT DeviceObject;
+
+ DPRINT("IoSynchronousPageWrite(FileObject %x, Mdl %x)\n",
+ FileObject, Mdl);
+
+ /* Get the Device Object */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+ /* Allocate IRP */
+ Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+
+ /* Get the Stack */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+
+ /* Create the IRP Settings */
+ Irp->MdlAddress = Mdl;
+ Irp->UserBuffer = MmGetMdlVirtualAddress(Mdl);
+ Irp->UserIosb = StatusBlock;
+ Irp->UserEvent = Event;
+ Irp->RequestorMode = KernelMode;
+ Irp->Flags = IRP_PAGING_IO | IRP_NOCACHE | IRP_SYNCHRONOUS_PAGING_IO;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+
+ /* Set the Stack Settings */
+ StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);
+ StackPtr->Parameters.Write.ByteOffset = *Offset;
+ StackPtr->MajorFunction = IRP_MJ_WRITE;
+ StackPtr->FileObject = FileObject;
+
+ /* Call the Driver */
+ return IofCallDriver(DeviceObject, Irp);
+}
+
+VOID
+IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PIO_STACK_LOCATION IoStack)
+{
+ ULONG IoControlCode;
+ ULONG OutputBufferLength;
+
+ if (IoStack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL)
+ {
+ IoControlCode =
+ IoStack->Parameters.FileSystemControl.FsControlCode;
+ OutputBufferLength =
+ IoStack->Parameters.FileSystemControl.OutputBufferLength;
+ }
+ else
+ {
+ IoControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
+
+ if (NT_SUCCESS(Irp->IoStatus.Status))
+ {
+ OutputBufferLength = Irp->IoStatus.Information;
+
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < OutputBufferLength)
+ {
+ OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
+ }
+ }
+ else
+ {
+ OutputBufferLength = 0;
+ }
+ }
+
+ switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
+ {
+ case METHOD_BUFFERED:
+
+ /* copy output buffer back and free it */
+ if (Irp->AssociatedIrp.SystemBuffer)
+ {
+ if (OutputBufferLength)
+ {
+ RtlCopyMemory(Irp->UserBuffer,
+ Irp->AssociatedIrp.SystemBuffer,
+ OutputBufferLength);
+ }
+ ExFreePool (Irp->AssociatedIrp.SystemBuffer);
+ }
+ break;
+
+ case METHOD_IN_DIRECT:
+ DPRINT ("Using METHOD_IN_DIRECT!\n");
+ /* use the same code as for METHOD_OUT_DIRECT */
+
+ case METHOD_OUT_DIRECT:
+ DPRINT ("Using METHOD_OUT_DIRECT!\n");
+
+ /* free input buffer (control buffer) */
+ if (Irp->AssociatedIrp.SystemBuffer)
+ ExFreePool (Irp->AssociatedIrp.SystemBuffer);
+
+ /* free output buffer (data transfer buffer) */
+ if (Irp->MdlAddress)
+ IoFreeMdl (Irp->MdlAddress);
+ break;
+
+ case METHOD_NEITHER:
+ DPRINT ("Using METHOD_NEITHER!\n");
+ /* nothing to do */
+ break;
+ }
+}
+
+VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PIO_STACK_LOCATION IoStack)
+{
+ PFILE_OBJECT FileObject;
+
+ FileObject = IoStack->FileObject;
+
+ if (DeviceObject->Flags & DO_BUFFERED_IO)
+ {
+ if (IoStack->MajorFunction == IRP_MJ_READ)
+ {
+ DPRINT("Copying buffered io back to user\n");
+ memcpy(Irp->UserBuffer,Irp->AssociatedIrp.SystemBuffer,
+ IoStack->Parameters.Read.Length);
+ }
+ ExFreePool(Irp->AssociatedIrp.SystemBuffer);
+ }
+
+ if (DeviceObject->Flags & DO_DIRECT_IO)
+ {
+ if (Irp->MdlAddress)
+ {
+ IoFreeMdl(Irp->MdlAddress);
+ }
+ }
+}
+
+VOID IoVolumeInformationCompletion(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PIO_STACK_LOCATION IoStack)
+{
+}
+
+
VOID STDCALL
-IoReuseIrp(
- IN OUT PIRP Irp,
- IN NTSTATUS Status)
+IoSecondStageCompletion_KernelApcRoutine(
+ IN PKAPC Apc,
+ IN OUT PKNORMAL_ROUTINE *NormalRoutine,
+ IN OUT PVOID *NormalContext,
+ IN OUT PVOID *SystemArgument1,
+ IN OUT PVOID *SystemArgument2
+ )
{
+ PIRP Irp;
+
+ Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
+ IoFreeIrp(Irp);
+}
+
+
+VOID STDCALL
+IoSecondStageCompletion_RundownApcRoutine(
+ IN PKAPC Apc
+ )
+{
+ PIRP Irp;
+
+ Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
+ IoFreeIrp(Irp);
+}
+
+
+/*
+ * FUNCTION: Performs the second stage of irp completion for read/write irps
+ *
+ * Called as a special kernel APC kernel-routine or directly from IofCompleteRequest()
+ */
+VOID STDCALL
+IoSecondStageCompletion(
+ PKAPC Apc,
+ PKNORMAL_ROUTINE* NormalRoutine,
+ PVOID* NormalContext,
+ PVOID* SystemArgument1,
+ PVOID* SystemArgument2)
+
+{
+ PIO_STACK_LOCATION IoStack;
+ PDEVICE_OBJECT DeviceObject;
+ PFILE_OBJECT OriginalFileObject;
+ PIRP Irp;
+
+ if (Apc) DPRINT("IoSecondStageCompletition with APC: %x\n", Apc);
+
+ OriginalFileObject = (PFILE_OBJECT)(*SystemArgument1);
+ DPRINT("OriginalFileObject: %x\n", OriginalFileObject);
+
+ Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
+ DPRINT("Irp: %x\n", Irp);
+
+ /*
+ * Note that we'll never see irp's flagged IRP_PAGING_IO (IRP_MOUNT_OPERATION)
+ * or IRP_CLOSE_OPERATION (IRP_MJ_CLOSE and IRP_MJ_CLEANUP) here since their
+ * cleanup/completion is fully taken care of in IoCompleteRequest.
+ * -Gunnar
+ */
+
+ /*
+ Remove synchronous irp's from the threads cleanup list.
+ To synchronize with the code inserting the entry, this code must run
+ at APC_LEVEL
+ */
+ if (!IsListEmpty(&Irp->ThreadListEntry))
+ {
+ RemoveEntryList(&Irp->ThreadListEntry);
+ InitializeListHead(&Irp->ThreadListEntry);
+ }
+
+ IoStack = (PIO_STACK_LOCATION)(Irp+1) + Irp->CurrentLocation;
+ DeviceObject = IoStack->DeviceObject;
+
+ DPRINT("IoSecondStageCompletion(Irp %x, MajorFunction %x)\n", Irp, IoStack->MajorFunction);
+
+ switch (IoStack->MajorFunction)
+ {
+ case IRP_MJ_CREATE:
+ case IRP_MJ_FLUSH_BUFFERS:
+ /* NOP */
+ break;
+
+ case IRP_MJ_READ:
+ case IRP_MJ_WRITE:
+ IoReadWriteCompletion(DeviceObject,Irp,IoStack);
+ break;
+
+ case IRP_MJ_DEVICE_CONTROL:
+ case IRP_MJ_INTERNAL_DEVICE_CONTROL:
+ case IRP_MJ_FILE_SYSTEM_CONTROL:
+ IoDeviceControlCompletion(DeviceObject, Irp, IoStack);
+ break;
+
+ case IRP_MJ_QUERY_VOLUME_INFORMATION:
+ case IRP_MJ_SET_VOLUME_INFORMATION:
+ IoVolumeInformationCompletion(DeviceObject, Irp, IoStack);
+ break;
+
+ default:
+ break;
+ }
+
+ if (Irp->UserIosb!=NULL)
+ {
+ if (Irp->RequestorMode == KernelMode)
+ {
+ *Irp->UserIosb = Irp->IoStatus;
+ }
+ else
+ {
+ DPRINT("Irp->RequestorMode == UserMode\n");
+ MmSafeCopyToUser(Irp->UserIosb,
+ &Irp->IoStatus,
+ sizeof(IO_STATUS_BLOCK));
+ }
+ }
+
+ if (Irp->UserEvent)
+ {
+ KeSetEvent(Irp->UserEvent,0,FALSE);
+ }
+
+ //Windows NT File System Internals, page 169
+ if (OriginalFileObject)
+ {
+ if (Irp->UserEvent == NULL)
+ {
+ KeSetEvent(&OriginalFileObject->Event,0,FALSE);
+ }
+ else if (OriginalFileObject->Flags & FO_SYNCHRONOUS_IO && Irp->UserEvent != &OriginalFileObject->Event)
+ {
+ KeSetEvent(&OriginalFileObject->Event,0,FALSE);
+ }
+ }
+
+ //Windows NT File System Internals, page 154
+ if (OriginalFileObject)
+ {
+ // if the event is not the one in the file object, it needs dereferenced
+ if (Irp->UserEvent && Irp->UserEvent != &OriginalFileObject->Event)
+ {
+ ObDereferenceObject(Irp->UserEvent);
+ }
- UCHAR AllocationFlags;
-
- /* Reference: Chris Cant's "Writing WDM Device Drivers" */
- AllocationFlags = Irp->AllocationFlags;
- IoInitializeIrp(Irp, Irp->Size, Irp->StackCount);
- Irp->IoStatus.Status = Status;
- Irp->AllocationFlags = AllocationFlags;
+ ObDereferenceObject(OriginalFileObject);
+ }
+
+ if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
+ {
+ PKNORMAL_ROUTINE UserApcRoutine;
+ PVOID UserApcContext;
+
+ DPRINT("Dispatching user APC\n");
+
+ UserApcRoutine = (PKNORMAL_ROUTINE)Irp->Overlay.AsynchronousParameters.UserApcRoutine;
+ UserApcContext = (PVOID)Irp->Overlay.AsynchronousParameters.UserApcContext;
+
+ KeInitializeApc( &Irp->Tail.Apc,
+ KeGetCurrentThread(),
+ CurrentApcEnvironment,
+ IoSecondStageCompletion_KernelApcRoutine,
+ IoSecondStageCompletion_RundownApcRoutine,
+ UserApcRoutine,
+ UserMode,
+ UserApcContext);
+
+ KeInsertQueueApc( &Irp->Tail.Apc,
+ Irp->UserIosb,
+ NULL,
+ 2);
+
+ //NOTE: kernel (or rundown) routine frees the IRP
+
+ return;
+
+ }
+
+ if (NULL != IoStack->FileObject
+ && NULL != IoStack->FileObject->CompletionContext
+ && (0 != (Irp->Flags & IRP_SYNCHRONOUS_API)
+ || 0 == (IoStack->FileObject->Flags & FO_SYNCHRONOUS_IO)))
+ {
+ PFILE_OBJECT FileObject = IoStack->FileObject;
+ IoSetIoCompletion(FileObject->CompletionContext->Port,
+ FileObject->CompletionContext->Key,
+ Irp->Overlay.AsynchronousParameters.UserApcContext,
+ Irp->IoStatus.Status,
+ Irp->IoStatus.Information,
+ FALSE);
+ }
+
+ IoFreeIrp(Irp);
}
/* EOF */
+++ /dev/null
-/* $Id:$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/lock.c
- * PURPOSE: No purpose listed.
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-
-#define TAG_LOCK TAG('F','l','c','k')
-
-/* FUNCTIONS *****************************************************************/
-
-static NTSTATUS STDCALL
-IopLockFileCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
- ExFreePool(Context);
- return STATUS_SUCCESS;
- // FIXME: Should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED?
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-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 PULONG Key,
- IN BOOLEAN FailImmediatedly,
- IN BOOLEAN ExclusiveLock
- )
-{
- PFILE_OBJECT FileObject = NULL;
- PLARGE_INTEGER LocalLength = NULL;
- PKEVENT Event = NULL;
- PIRP Irp = NULL;
- PIO_STACK_LOCATION StackPtr;
- PDEVICE_OBJECT DeviceObject;
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status;
-
- // FIXME: instead of this, use SEH when available?
- if (!Length || !ByteOffset)
- {
- Status = STATUS_INVALID_PARAMETER;
- goto fail;
- }
-
- PreviousMode = ExGetPreviousMode();
-
- Status = ObReferenceObjectByHandle(FileHandle,
- 0,
- IoFileObjectType,
- PreviousMode,
- (PVOID*)&FileObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- goto fail;
- }
-
- DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
- Irp = IoAllocateIrp(DeviceObject->StackSize,
- TRUE);
- if (Irp == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto fail;
- }
-
- if (EventHandle != NULL && !FailImmediatedly)
- {
- Status = ObReferenceObjectByHandle(EventHandle,
- SYNCHRONIZE,
- ExEventObjectType,
- PreviousMode,
- (PVOID*)&Event,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- goto fail;
- }
- }
- else
- {
- Event = &FileObject->Event;
- KeResetEvent(Event);
- }
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
-
- Irp->RequestorMode = PreviousMode;
- Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
- Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
-
- Irp->UserEvent = Event;
- Irp->UserIosb = IoStatusBlock;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
- StackPtr->MinorFunction = IRP_MN_LOCK;
- StackPtr->FileObject = FileObject;
-
- if (ExclusiveLock)
- StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
-
- if (FailImmediatedly)
- StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
-
- LocalLength = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(LARGE_INTEGER),
- TAG_LOCK);
- if (!LocalLength)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto fail;
- }
-
- *LocalLength = *Length;
-
- StackPtr->Parameters.LockControl.Length = LocalLength;
- StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
- StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
-
- IoSetCompletionRoutine(Irp,
- IopLockFileCompletionRoutine,
- LocalLength,
- TRUE,
- TRUE,
- TRUE);
-
- /* Can't touch FileObject after IoCallDriver since it might be freed */
- Status = IofCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
- {
- Status = KeWaitForSingleObject(Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
-
- if (Status != STATUS_WAIT_0)
- {
- DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
- /*
- * FIXME: Should do some special processing here if alertable wait
- * was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
- */
- return Status; /* Set status to something else? */
- }
-
- Status = IoStatusBlock->Status;
- }
-
- return Status;
-
-fail:;
- if (LocalLength)
- ExFreePool(LocalLength);
-
- if (Irp)
- IoFreeIrp(Irp);
-
- if (Event)
- ObDereferenceObject(Event);
-
- if (FileObject)
- ObDereferenceObject(FileObject);
-
- return Status;
-}
-
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-NtUnlockFile (
- IN HANDLE FileHandle,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN PLARGE_INTEGER ByteOffset,
- IN PLARGE_INTEGER Length,
- OUT PULONG Key OPTIONAL
- )
-{
- PFILE_OBJECT FileObject = NULL;
- PLARGE_INTEGER LocalLength = NULL;
- PIRP Irp = NULL;
- PIO_STACK_LOCATION StackPtr;
- PDEVICE_OBJECT DeviceObject;
- KPROCESSOR_MODE PreviousMode;
- NTSTATUS Status;
-
- // FIXME: instead of this, use SEH when available
- if (!Length || !ByteOffset)
- {
- Status = STATUS_INVALID_PARAMETER;
- goto fail;
- }
-
- PreviousMode = ExGetPreviousMode();
-
- /*
- * BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
- * It should ONLY fail if we desire an access that conflict with granted access!
- */
- Status = ObReferenceObjectByHandle(FileHandle,
- 0, //FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
- IoFileObjectType,
- PreviousMode,
- (PVOID*)&FileObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- goto fail;
- }
-
- DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
- Irp = IoAllocateIrp(DeviceObject->StackSize,
- TRUE);
- if (Irp == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto fail;
- }
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = PreviousMode;
- Irp->UserIosb = IoStatusBlock;
- Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
- StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
- StackPtr->DeviceObject = DeviceObject;
- StackPtr->FileObject = FileObject;
-
- LocalLength = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(LARGE_INTEGER),
- TAG_LOCK);
- if (!LocalLength)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto fail;
- }
-
- *LocalLength = *Length;
-
- StackPtr->Parameters.LockControl.Length = LocalLength;
- StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
- StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
-
- /* Allways synchronous */
- Status = IofCallDriver(DeviceObject, Irp);
-
- ExFreePool(LocalLength);
-
- return Status;
-
-fail:;
- if (LocalLength)
- ExFreePool(LocalLength);
-
- if (Irp)
- IoFreeIrp(Irp);
-
- if (FileObject)
- ObDereferenceObject(FileObject);
-
- return Status;
-}
+++ /dev/null
-/* $Id:$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/mailslot.c
- * PURPOSE: No purpose listed.
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS STDCALL
-NtCreateMailslotFile(OUT PHANDLE FileHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN ULONG CreateOptions,
- IN ULONG MailslotQuota,
- IN ULONG MaxMessageSize,
- IN PLARGE_INTEGER TimeOut)
-{
- MAILSLOT_CREATE_PARAMETERS Buffer;
-
- DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, "
- "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
- FileHandle,DesiredAccess,ObjectAttributes,
- ObjectAttributes->ObjectName->Buffer);
-
- ASSERT_IRQL(PASSIVE_LEVEL);
-
- if (TimeOut != NULL)
- {
- Buffer.ReadTimeout.QuadPart = TimeOut->QuadPart;
- Buffer.TimeoutSpecified = TRUE;
- }
- else
- {
- Buffer.TimeoutSpecified = FALSE;
- }
- Buffer.MailslotQuota = MailslotQuota;
- Buffer.MaximumMessageSize = MaxMessageSize;
-
- return IoCreateFile(FileHandle,
- DesiredAccess,
- ObjectAttributes,
- IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_CREATE,
- CreateOptions,
- NULL,
- 0,
- CreateFileTypeMailslot,
- (PVOID)&Buffer,
- 0);
-}
-
-/* EOF */
+++ /dev/null
-/* $Id:$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/npipe.c
- * PURPOSE: Named pipe helper function
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS STDCALL
-NtCreateNamedPipeFile(PHANDLE FileHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- PIO_STATUS_BLOCK IoStatusBlock,
- ULONG ShareAccess,
- ULONG CreateDisposition,
- ULONG CreateOptions,
- ULONG NamedPipeType,
- ULONG ReadMode,
- ULONG CompletionMode,
- ULONG MaximumInstances,
- ULONG InboundQuota,
- ULONG OutboundQuota,
- PLARGE_INTEGER DefaultTimeout)
-{
- NAMED_PIPE_CREATE_PARAMETERS Buffer;
-
- DPRINT("NtCreateNamedPipeFile(FileHandle %x, DesiredAccess %x, "
- "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
- FileHandle,DesiredAccess,ObjectAttributes,
- ObjectAttributes->ObjectName->Buffer);
-
- ASSERT_IRQL(PASSIVE_LEVEL);
-
- if (DefaultTimeout != NULL)
- {
- Buffer.DefaultTimeout.QuadPart = DefaultTimeout->QuadPart;
- Buffer.TimeoutSpecified = TRUE;
- }
- else
- {
- Buffer.TimeoutSpecified = FALSE;
- }
- Buffer.NamedPipeType = NamedPipeType;
- Buffer.ReadMode = ReadMode;
- Buffer.CompletionMode = CompletionMode;
- Buffer.MaximumInstances = MaximumInstances;
- Buffer.InboundQuota = InboundQuota;
- Buffer.OutboundQuota = OutboundQuota;
-
- return IoCreateFile(FileHandle,
- DesiredAccess,
- ObjectAttributes,
- IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- ShareAccess,
- CreateDisposition,
- CreateOptions,
- NULL,
- 0,
- CreateFileTypeNamedPipe,
- (PVOID)&Buffer,
- 0);
-}
-
-/* EOF */
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/page.c
- * PURPOSE: No purpose listed.
- *
- * PROGRAMMERS: No programmer listed.
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS STDCALL
-IoPageWrite(PFILE_OBJECT FileObject,
- PMDL Mdl,
- PLARGE_INTEGER Offset,
- PKEVENT Event,
- PIO_STATUS_BLOCK StatusBlock)
-{
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
-
- DPRINT("IoPageWrite(FileObject %x, Mdl %x)\n",
- FileObject, Mdl);
-
- Irp = IoBuildSynchronousFsdRequestWithMdl(IRP_MJ_WRITE,
- FileObject->DeviceObject,
- Mdl,
- Offset,
- Event,
- StatusBlock,
- TRUE);
- if (Irp == NULL)
- {
- return (STATUS_INSUFFICIENT_RESOURCES);
- }
- Irp->Flags = IRP_NOCACHE|IRP_PAGING_IO;
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
- StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);
- DPRINT("Before IoCallDriver\n");
- Status = IofCallDriver(FileObject->DeviceObject,Irp);
- DPRINT("Status %d STATUS_PENDING %d\n",Status,STATUS_PENDING);
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-IoPageRead(PFILE_OBJECT FileObject,
- PMDL Mdl,
- PLARGE_INTEGER Offset,
- PKEVENT Event,
- PIO_STATUS_BLOCK StatusBlock)
-{
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
-
- DPRINT("IoPageRead(FileObject %x, Mdl %x)\n",
- FileObject, Mdl);
-
- Irp = IoBuildSynchronousFsdRequestWithMdl(IRP_MJ_READ,
- FileObject->DeviceObject,
- Mdl,
- Offset,
- Event,
- StatusBlock,
- TRUE);
- if (Irp == NULL)
- {
- return (STATUS_INSUFFICIENT_RESOURCES);
- }
- Irp->Flags = IRP_NOCACHE|IRP_PAGING_IO;
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
- StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
- DPRINT("Before IoCallDriver\n");
- Status = IofCallDriver(FileObject->DeviceObject, Irp);
- DPRINT("Status %d STATUS_PENDING %d\n",Status,STATUS_PENDING);
-
- return(Status);
-}
-
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-IoSynchronousPageWrite (PFILE_OBJECT FileObject,
- PMDL Mdl,
- PLARGE_INTEGER Offset,
- PKEVENT Event,
- PIO_STATUS_BLOCK StatusBlock)
-{
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
-
- DPRINT("IoSynchronousPageWrite(FileObject %x, Mdl %x)\n",
- FileObject, Mdl);
-
- Irp = IoBuildSynchronousFsdRequestWithMdl(IRP_MJ_WRITE,
- FileObject->DeviceObject,
- Mdl,
- Offset,
- Event,
- StatusBlock,
- TRUE);
- if (Irp == NULL)
- {
- return (STATUS_INSUFFICIENT_RESOURCES);
- }
- Irp->Flags = IRP_NOCACHE|IRP_PAGING_IO|IRP_SYNCHRONOUS_PAGING_IO;
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
- StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);
- DPRINT("Before IoCallDriver\n");
- Status = IofCallDriver(FileObject->DeviceObject,Irp);
- DPRINT("Status %d STATUS_PENDING %d\n",Status,STATUS_PENDING);
- return(Status);
-}
-
-
-/* EOF */
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/parttab.c
- * PURPOSE: Handling fixed disks (partition table functions)
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-NTSTATUS FASTCALL
-IoReadPartitionTable(PDEVICE_OBJECT DeviceObject,
- ULONG SectorSize,
- BOOLEAN ReturnRecognizedPartitions,
- PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
-{
- return(HalIoReadPartitionTable(DeviceObject,
- SectorSize,
- ReturnRecognizedPartitions,
- PartitionBuffer));
-}
-
-
-NTSTATUS FASTCALL
-IoSetPartitionInformation(PDEVICE_OBJECT DeviceObject,
- ULONG SectorSize,
- ULONG PartitionNumber,
- ULONG PartitionType)
-{
- return(HalIoSetPartitionInformation(DeviceObject,
- SectorSize,
- PartitionNumber,
- PartitionType));
-}
-
-
-NTSTATUS FASTCALL
-IoWritePartitionTable(PDEVICE_OBJECT DeviceObject,
- ULONG SectorSize,
- ULONG SectorsPerTrack,
- ULONG NumberOfHeads,
- PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
-{
- return(HalIoWritePartitionTable(DeviceObject,
- SectorSize,
- SectorsPerTrack,
- NumberOfHeads,
- PartitionBuffer));
-}
-
-/* EOF */
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/process.c
- * PURPOSE: Process functions that, bizarrely, are in the iomgr
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-PVOID
-STDCALL
-IoGetInitialStack(VOID)
-{
- return(PsGetCurrentThread()->Tcb.InitialStack);
-}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-IoGetStackLimits(OUT PULONG LowLimit,
- OUT PULONG HighLimit)
-{
- *LowLimit = (ULONG)NtCurrentTeb()->Tib.StackLimit;
- *HighLimit = (ULONG)NtCurrentTeb()->Tib.StackBase;
-}
-
-/*
- * @implemented
- */
-BOOLEAN
-STDCALL
-IoIsSystemThread(IN PETHREAD Thread)
-{
- /* Call the Ps Function */
- return PsIsSystemThread(Thread);
-}
-
-/*
- * @implemented
- */
-PEPROCESS
-STDCALL
-IoThreadToProcess(IN PETHREAD Thread)
-{
- return(Thread->ThreadsProcess);
-}
-
-
-/*
- * @implemented
- */
-PEPROCESS STDCALL
-IoGetRequestorProcess(IN PIRP Irp)
-{
- return(Irp->Tail.Overlay.Thread->ThreadsProcess);
-}
-
-/*
- * @implemented
- */
-ULONG
-STDCALL
-IoGetRequestorProcessId(IN PIRP Irp)
-{
- return (ULONG)(IoGetRequestorProcess(Irp)->UniqueProcessId);
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-IoGetRequestorSessionId(IN PIRP Irp,
- OUT PULONG pSessionId)
-{
- *pSessionId = IoGetRequestorProcess(Irp)->SessionId;
-
- return STATUS_SUCCESS;
-}
-
-/**********************************************************************
- * NAME EXPORTED
- * IoSetThreadHardErrorMode@4
- *
- * ARGUMENTS
- * HardErrorEnabled
- * TRUE : enable hard errors processing;
- * FALSE: do NOT process hard errors.
- *
- * RETURN VALUE
- * Previous value for the current thread's hard errors
- * processing policy.
- *
- * @implemented
- */
-BOOLEAN
-STDCALL
-IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
-{
- BOOLEAN PreviousHEM = (BOOLEAN)(NtCurrentTeb()->HardErrorDisabled);
-
- NtCurrentTeb()->HardErrorDisabled = ((TRUE == HardErrorEnabled) ? FALSE : TRUE);
-
- return((TRUE == PreviousHEM) ? FALSE : TRUE);
-}
-
-/* EOF */
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/queue.c
- * PURPOSE: Implement device queueing
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-IoStartNextPacketByKey(PDEVICE_OBJECT DeviceObject,
- BOOLEAN Cancelable,
- ULONG Key)
-/*
- * FUNCTION: Dequeues the next packet from the given device object's
- * associated device queue according to a specified sort-key value and calls
- * the drivers StartIo routine with that IRP
- * ARGUMENTS:
- * DeviceObject = Device object for which the irp is to dequeued
- * Cancelable = True if IRPs in the key can be canceled
- * Key = Sort key specifing which entry to remove from the queue
- */
-{
- PKDEVICE_QUEUE_ENTRY entry;
- PIRP Irp;
-
- entry = KeRemoveByKeyDeviceQueue(&DeviceObject->DeviceQueue,
- Key);
-
- if (entry != NULL)
- {
- Irp = CONTAINING_RECORD(entry,
- IRP,
- Tail.Overlay.DeviceQueueEntry);
- DeviceObject->CurrentIrp = Irp;
- DPRINT("Next irp is %x\n", Irp);
- DeviceObject->DriverObject->DriverStartIo(DeviceObject, Irp);
- }
- else
- {
- DPRINT("No next irp\n");
- DeviceObject->CurrentIrp = NULL;
- }
-}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-IoStartNextPacket(PDEVICE_OBJECT DeviceObject, BOOLEAN Cancelable)
-/*
- * FUNCTION: Removes the next packet from the device's queue and calls
- * the driver's StartIO
- * ARGUMENTS:
- * DeviceObject = Device
- * Cancelable = True if irps in the queue can be canceled
- */
-{
- PKDEVICE_QUEUE_ENTRY entry;
- PIRP Irp;
-
- DPRINT("IoStartNextPacket(DeviceObject %x, Cancelable %d)\n",
- DeviceObject,Cancelable);
-
- entry = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
-
- if (entry!=NULL)
- {
- Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
- DeviceObject->CurrentIrp = Irp;
- DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
- }
- else
- {
- DeviceObject->CurrentIrp = NULL;
- }
-}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-IoStartPacket(PDEVICE_OBJECT DeviceObject,
- PIRP Irp, PULONG Key, PDRIVER_CANCEL CancelFunction)
-/*
- * FUNCTION: Either call the device's StartIO routine with the packet or,
- * if the device is busy, queue it.
- * ARGUMENTS:
- * DeviceObject = Device to start the packet on
- * Irp = Irp to queue
- * Key = Where to insert the irp
- * If zero then insert in the tail of the queue
- * CancelFunction = Optional function to cancel the irqp
- */
-{
- BOOLEAN stat;
- KIRQL oldirql;
-
- DPRINT("IoStartPacket(Irp %x)\n", Irp);
-
- ASSERT_IRQL(DISPATCH_LEVEL);
-
- IoAcquireCancelSpinLock(&oldirql);
-
- if (CancelFunction != NULL)
- {
- Irp->CancelRoutine = CancelFunction;
- }
-
- if (Key!=0)
- {
- stat = KeInsertByKeyDeviceQueue(&DeviceObject->DeviceQueue,
- &Irp->Tail.Overlay.DeviceQueueEntry,
- *Key);
- }
- else
- {
- stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
- &Irp->Tail.Overlay.DeviceQueueEntry);
- }
-
-
- if (!stat)
- {
- IoReleaseCancelSpinLock(DISPATCH_LEVEL);
- DeviceObject->CurrentIrp = Irp;
- DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
- if (oldirql < DISPATCH_LEVEL)
- {
- KeLowerIrql(oldirql);
- }
- }
- else
- {
- IoReleaseCancelSpinLock(oldirql);
- }
-
-}
-
-
-/* EOF */
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/rw.c
- * PURPOSE: Implements read/write APIs
- *
- * PROGRAMMERS: David Welch (welch@cwcom.net)
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS ***************************************************************/
-
-
-/**********************************************************************
- * NAME EXPORTED
- * NtReadFile
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *
- * RETURN VALUE
- *
- * REVISIONS
- *
- * @implemented
- */
-NTSTATUS STDCALL
-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, /* NOT optional for asynch. operations! */
- IN PULONG Key OPTIONAL)
-{
- NTSTATUS Status;
- PFILE_OBJECT FileObject;
- PIRP Irp = NULL;
- PIO_STACK_LOCATION StackPtr;
- KPROCESSOR_MODE PreviousMode;
- PKEVENT EventObject = NULL;
-
- DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
- "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
- IoStatusBlock);
-
- if (IoStatusBlock == NULL)
- return STATUS_ACCESS_VIOLATION;
-
- PreviousMode = ExGetPreviousMode();
-
- Status = ObReferenceObjectByHandle(FileHandle,
- FILE_READ_DATA,
- IoFileObjectType,
- PreviousMode,
- (PVOID*)&FileObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if (ByteOffset == NULL ||
- (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
- ByteOffset->u.HighPart == 0xffffffff))
- {
- /* a valid ByteOffset is required if asynch. op. */
- if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
- {
- DPRINT1("NtReadFile: missing ByteOffset for asynch. op\n");
- ObDereferenceObject(FileObject);
- return STATUS_INVALID_PARAMETER;
- }
-
- ByteOffset = &FileObject->CurrentByteOffset;
- }
-
- if (Event != NULL)
- {
- Status = ObReferenceObjectByHandle(Event,
- SYNCHRONIZE,
- ExEventObjectType,
- PreviousMode,
- (PVOID*)&EventObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(FileObject);
- return Status;
- }
-
- KeClearEvent(EventObject);
- }
-
- _SEH_TRY
- {
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
- FileObject->DeviceObject,
- Buffer,
- Length,
- ByteOffset,
- EventObject,
- IoStatusBlock);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if (!NT_SUCCESS(Status) || Irp == NULL)
- {
- if (Event)
- {
- ObDereferenceObject(&EventObject);
- }
- ObDereferenceObject(FileObject);
- if (Irp)
- {
- IoFreeIrp(Irp);
- }
- return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status;
- }
-
- KeClearEvent(&FileObject->Event);
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
-
- Irp->RequestorMode = PreviousMode;
-
- Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
- Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
- StackPtr->Parameters.Read.Key = Key ? *Key : 0;
-
- Status = IoCallDriver(FileObject->DeviceObject, Irp);
- if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
- {
- Status = KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- if (Status != STATUS_WAIT_0)
- {
- /* Wait failed. */
- return Status;
- }
-
- Status = IoStatusBlock->Status;
- }
-
- return Status;
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * NtWriteFile
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *
- * RETURN VALUE
- *
- * REVISIONS
- *
- * @implemented
- */
-NTSTATUS STDCALL
-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, /* NOT optional for asynch. operations! */
- IN PULONG Key OPTIONAL)
-{
- OBJECT_HANDLE_INFORMATION HandleInformation;
- NTSTATUS Status;
- PFILE_OBJECT FileObject;
- PIRP Irp = NULL;
- PIO_STACK_LOCATION StackPtr;
- KPROCESSOR_MODE PreviousMode;
- PKEVENT EventObject = NULL;
- LARGE_INTEGER Offset;
-
- DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
- "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
- IoStatusBlock);
-
- if (IoStatusBlock == NULL)
- return STATUS_ACCESS_VIOLATION;
-
- PreviousMode = ExGetPreviousMode();
-
- Status = ObReferenceObjectByHandle(FileHandle,
- 0,
- IoFileObjectType,
- PreviousMode,
- (PVOID*)&FileObject,
- &HandleInformation);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */
- if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
- {
- DPRINT1("Invalid access rights\n");
- ObDereferenceObject(FileObject);
- return STATUS_ACCESS_DENIED;
- }
-
- if (HandleInformation.GrantedAccess & FILE_WRITE_DATA)
- {
- if (ByteOffset == NULL)
- {
- /* a valid ByteOffset is required if asynch. op. */
- if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
- {
- DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
- ObDereferenceObject(FileObject);
- return STATUS_INVALID_PARAMETER;
- }
-
- ByteOffset = &FileObject->CurrentByteOffset;
- }
- }
- else if (HandleInformation.GrantedAccess & FILE_APPEND_DATA)
- {
- /* a valid ByteOffset is required if asynch. op. */
- if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
- {
- DPRINT1("NtWriteFile: missing ByteOffset for asynch. op\n");
- ObDereferenceObject(FileObject);
- return STATUS_INVALID_PARAMETER;
- }
-
- Offset.u.LowPart = FILE_WRITE_TO_END_OF_FILE;
- Offset.u.HighPart = 0xffffffff;
- ByteOffset = &Offset;
- }
-
- if (Event != NULL)
- {
- Status = ObReferenceObjectByHandle(Event,
- SYNCHRONIZE,
- ExEventObjectType,
- PreviousMode,
- (PVOID*)&EventObject,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(FileObject);
- return Status;
- }
-
- KeClearEvent(EventObject);
- }
-
- _SEH_TRY
- {
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
- FileObject->DeviceObject,
- Buffer,
- Length,
- ByteOffset,
- EventObject,
- IoStatusBlock);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if (!NT_SUCCESS(Status) || Irp == NULL)
- {
- if (Event)
- {
- ObDereferenceObject(&EventObject);
- }
- ObDereferenceObject(FileObject);
- if (Irp)
- {
- IoFreeIrp(Irp);
- }
- return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status;
- }
-
- KeClearEvent(&FileObject->Event);
-
- /* Trigger FileObject/Event dereferencing */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
-
- Irp->RequestorMode = PreviousMode;
-
- Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
- Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
-
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
- StackPtr->Parameters.Write.Key = Key ? *Key : 0;
-
- Status = IoCallDriver(FileObject->DeviceObject, Irp);
- if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
- {
- Status = KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
- NULL);
- if (Status != STATUS_WAIT_0)
- {
- /* Wait failed. */
- return Status;
- }
-
- Status = IoStatusBlock->Status;
- }
-
- return Status;
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * NtReadFileScatter
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *
- * RETURN VALUE
- *
- * REVISIONS
- */
-NTSTATUS
-STDCALL
-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
- )
-{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * NtWriteFileGather
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *
- * RETURN VALUE
- *
- * REVISIONS
- */
-NTSTATUS
-STDCALL
-NtWriteFileGather (
- IN HANDLE FileHandle,
- IN HANDLE Event OPTIONAL,
- IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
- IN PVOID ApcContext OPTIONAL,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN FILE_SEGMENT_ELEMENT BufferDescription [],
- IN ULONG BufferLength,
- IN PLARGE_INTEGER ByteOffset,
- IN PULONG Key OPTIONAL
- )
-{
- UNIMPLEMENTED;
- return(STATUS_NOT_IMPLEMENTED);
-}
-
-
-/* EOF */
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/shutdown.c
- * PURPOSE: Implements shutdown notification
- *
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* LOCAL DATA ***************************************************************/
-
-typedef struct _SHUTDOWN_ENTRY
-{
- LIST_ENTRY ShutdownList;
- PDEVICE_OBJECT DeviceObject;
-} SHUTDOWN_ENTRY, *PSHUTDOWN_ENTRY;
-
-static LIST_ENTRY ShutdownListHead;
-static KSPIN_LOCK ShutdownListLock;
-
-#define TAG_SHUTDOWN_ENTRY TAG('S', 'H', 'U', 'T')
-
-/* FUNCTIONS *****************************************************************/
-
-VOID INIT_FUNCTION
-IoInitShutdownNotification (VOID)
-{
- InitializeListHead(&ShutdownListHead);
- KeInitializeSpinLock(&ShutdownListLock);
-}
-
-VOID IoShutdownRegisteredDevices(VOID)
-{
- PSHUTDOWN_ENTRY ShutdownEntry;
- PLIST_ENTRY Entry;
- IO_STATUS_BLOCK StatusBlock;
- PIRP Irp;
- KEVENT Event;
- NTSTATUS Status;
-
- Entry = ShutdownListHead.Flink;
- while (Entry != &ShutdownListHead)
- {
- ShutdownEntry = CONTAINING_RECORD(Entry, SHUTDOWN_ENTRY, ShutdownList);
-
- KeInitializeEvent (&Event,
- NotificationEvent,
- FALSE);
-
- Irp = IoBuildSynchronousFsdRequest (IRP_MJ_SHUTDOWN,
- ShutdownEntry->DeviceObject,
- NULL,
- 0,
- NULL,
- &Event,
- &StatusBlock);
-
- Status = IoCallDriver (ShutdownEntry->DeviceObject,
- Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject (&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- }
-
- Entry = Entry->Flink;
- }
-}
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
-{
- PSHUTDOWN_ENTRY Entry;
-
- Entry = ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_ENTRY),
- TAG_SHUTDOWN_ENTRY);
- if (Entry == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- Entry->DeviceObject = DeviceObject;
-
- ExInterlockedInsertHeadList(&ShutdownListHead,
- &Entry->ShutdownList,
- &ShutdownListLock);
-
- DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED;
-
- return STATUS_SUCCESS;
-}
-
-/*
- * @implemented
- */
-VOID STDCALL IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
-{
- PSHUTDOWN_ENTRY ShutdownEntry;
- PLIST_ENTRY Entry;
- KIRQL oldlvl;
-
- Entry = ShutdownListHead.Flink;
- while (Entry != &ShutdownListHead)
- {
- ShutdownEntry = CONTAINING_RECORD(Entry, SHUTDOWN_ENTRY, ShutdownList);
- if (ShutdownEntry->DeviceObject == DeviceObject)
- {
- DeviceObject->Flags &= ~DO_SHUTDOWN_REGISTERED;
-
- KeAcquireSpinLock(&ShutdownListLock,&oldlvl);
- RemoveEntryList(Entry);
- KeReleaseSpinLock(&ShutdownListLock,oldlvl);
-
- ExFreePool(Entry);
- return;
- }
-
- Entry = Entry->Flink;
- }
-}
-
-/* EOF */
Irql);
}
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoCheckQuerySetVolumeInformation(IN FS_INFORMATION_CLASS FsInformationClass,
+ IN ULONG Length,
+ IN BOOLEAN SetOperation)
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
/* EOF */
+++ /dev/null
-/* $Id:$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/wdm.c
- * PURPOSE: Various Windows Driver Model routines
- *
- * PROGRAMMERS: Filip Navara (xnavara@volny.cz)
- */
-
-#include <ntoskrnl.h>
-
-/*
- * @implemented
- */
-BOOLEAN STDCALL
-IoIsWdmVersionAvailable(
- IN UCHAR MajorVersion,
- IN UCHAR MinorVersion
- )
-{
- if (MajorVersion <= 1 && MinorVersion <= 10)
- return TRUE;
- return FALSE;
-}
+++ /dev/null
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/xhaldisp.c
- * PURPOSE: Hal dispatch tables
- *
- * PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-
-/* DATA **********************************************************************/
-
-
-HAL_DISPATCH EXPORTED HalDispatchTable =
-{
- HAL_DISPATCH_VERSION,
- (pHalQuerySystemInformation) NULL, // HalQuerySystemInformation
- (pHalSetSystemInformation) NULL, // HalSetSystemInformation
- (pHalQueryBusSlots) NULL, // HalQueryBusSlots
- 0,
- (pHalExamineMBR) xHalExamineMBR,
- (pHalIoAssignDriveLetters) xHalIoAssignDriveLetters,
- (pHalIoReadPartitionTable) xHalIoReadPartitionTable,
- (pHalIoSetPartitionInformation) xHalIoSetPartitionInformation,
- (pHalIoWritePartitionTable) xHalIoWritePartitionTable,
- (pHalHandlerForBus) NULL, // HalReferenceHandlerForBus
- (pHalReferenceBusHandler) NULL, // HalReferenceBusHandler
- (pHalReferenceBusHandler) NULL, // HalDereferenceBusHandler
- (pHalInitPnpDriver) NULL, //HalInitPnpDriver;
- (pHalInitPowerManagement) NULL, //HalInitPowerManagement;
- (pHalGetDmaAdapter) NULL, //HalGetDmaAdapter;
- (pHalGetInterruptTranslator) NULL, //HalGetInterruptTranslator;
- (pHalStartMirroring) NULL, //HalStartMirroring;
- (pHalEndMirroring) NULL, //HalEndMirroring;
- (pHalMirrorPhysicalMemory) NULL, //HalMirrorPhysicalMemory;
- (pHalEndOfBoot) NULL, //HalEndOfBoot;
- (pHalMirrorVerify) NULL //HalMirrorVerify;
-};
-
-
-HAL_PRIVATE_DISPATCH EXPORTED HalPrivateDispatchTable =
-{
- HAL_PRIVATE_DISPATCH_VERSION
- // HalHandlerForBus
- // HalHandlerForConfigSpace
- // HalCompleteDeviceControl
- // HalRegisterBusHandler
- // ??
- // ??
- // ??
- // ??
- // ??
-};
-
-/*
- * @unimplemented
- *
-STDCALL
-VOID
-IoAssignDriveLetters(
- IN PLOADER_PARAMETER_BLOCK LoaderBlock,
- IN PSTRING NtDeviceName,
- OUT PUCHAR NtSystemPath,
- OUT PSTRING NtSystemPathString
- )
-{
- UNIMPLEMENTED;
-*/
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoCreateDisk(
- IN PDEVICE_OBJECT DeviceObject,
- IN struct _CREATE_DISK* Disk
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoGetBootDiskInformation(
- IN OUT PBOOTDISK_INFORMATION BootDiskInformation,
- IN ULONG Size
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoReadDiskSignature(
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG BytesPerSector,
- OUT PDISK_SIGNATURE Signature
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoReadPartitionTableEx(
- IN PDEVICE_OBJECT DeviceObject,
- IN struct _DRIVE_LAYOUT_INFORMATION_EX** DriveLayout
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoSetPartitionInformationEx(
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG PartitionNumber,
- IN struct _SET_PARTITION_INFORMATION_EX* PartitionInfo
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoSetSystemPartition(
- PUNICODE_STRING VolumeNameString
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoVerifyPartitionTable(
- IN PDEVICE_OBJECT DeviceObject,
- IN BOOLEAN FixErrors
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoVolumeDeviceToDosName(
- IN PVOID VolumeDeviceObject,
- OUT PUNICODE_STRING DosName
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoWritePartitionTableEx(
- IN PDEVICE_OBJECT DeviceObject,
- IN struct _DRIVE_LAYOUT_INFORMATION_EX* DriveLayfout
- )
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-/* EOF */
KiDmaIoCoherency = Coherency;
}
-/*
- * @unimplemented
- */
-STDCALL
-PKDEVICE_QUEUE_ENTRY
-KeRemoveByKeyDeviceQueueIfBusy (
- IN PKDEVICE_QUEUE DeviceQueue,
- IN ULONG SortKey
- )
-{
- UNIMPLEMENTED;
- return 0;
-}
-
/*
* @implemented
*/
return ReturnEntry;
}
+/*
+ * @unimplemented
+ */
+STDCALL
+PKDEVICE_QUEUE_ENTRY
+KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue,
+ IN ULONG SortKey)
+{
+ UNIMPLEMENTED;
+ return 0;
+}
+
/*
* @implemented
*/
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = IoPageWrite(PagingFileList[i]->FileObject,
- Mdl,
- &file_offset,
- &Event,
- &Iosb);
+ Status = IoSynchronousPageWrite(PagingFileList[i]->FileObject,
+ Mdl,
+ &file_offset,
+ &Event,
+ &Iosb);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
MK_CPPFLAGS += -O2 -Wno-strict-aliasing
endif
endif
-
+
#
# Enable Tree-Wide Optimization if Debug is on.
# Protect uncompatible files here with an ifneq
ifneq ($(DBG),1)
MK_CFLAGS += -Os -Wno-strict-aliasing -ftracer -momit-leaf-frame-pointer
MK_CFLAGS += -mpreferred-stack-boundary=2
-
- CC_VERSION=$(word 1,$(shell gcc -dumpversion))
- ifeq ($(CC_VERSION),3.4.3)
MK_CFLAGS += -funit-at-a-time -fweb
- endif
#
# Remove Symbols if no debugging is used at all