IO Manager Cleanup continues:

- 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
This commit is contained in:
Alex Ionescu 2005-04-28 00:54:59 +00:00
parent 612461644d
commit defaccea55
33 changed files with 4495 additions and 5067 deletions

View file

@ -2147,6 +2147,13 @@ SpiGetInquiryData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
((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++)
{
AdapterBusInfo->BusData[Bus].InitiatorBusId =

View file

@ -146,54 +146,36 @@ OBJECTS_IO = \
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 = \

View file

@ -263,7 +263,7 @@ WriteCacheSegment(PCACHE_SEGMENT CacheSeg)
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);
@ -643,7 +643,7 @@ CcZeroData (IN PFILE_OBJECT FileObject,
((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);

View file

@ -518,6 +518,38 @@ IopMarkLastReinitializeDriver(VOID);
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 */

View file

@ -1,555 +0,0 @@
/* $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 */

View file

@ -1,251 +0,0 @@
/* $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 */

View file

@ -1,321 +0,0 @@
/* $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);
}

View file

@ -1,761 +0,0 @@
/* $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 */

View file

@ -1,11 +1,11 @@
/* $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 *******************************************************************/
@ -17,14 +17,66 @@
/* 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,
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;
@ -815,26 +867,35 @@ IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
*/
NTSTATUS
STDCALL
IoRegisterLastChanceShutdownNotification(
IN PDEVICE_OBJECT DeviceObject
)
IoRegisterLastChanceShutdownNotification(IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/*
* @unimplemented
* @implemented
*/
VOID
NTSTATUS
STDCALL
IoSetStartIoAttributes(
IN PDEVICE_OBJECT DeviceObject,
IN BOOLEAN DeferredStartIo,
IN BOOLEAN NonCancelable
)
IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED;
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;
}
/*
@ -842,26 +903,314 @@ IoSetStartIoAttributes(
*/
VOID
STDCALL
IoSynchronousInvalidateDeviceRelations(
IN PDEVICE_OBJECT DeviceObject,
IN DEVICE_RELATION_TYPE Type
)
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)
{
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);
}
}
/*
* @unimplemented
*/
VOID
STDCALL
IoSynchronousInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject,
IN DEVICE_RELATION_TYPE Type)
{
UNIMPLEMENTED;
}
/*
* @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;
}
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
IoValidateDeviceIoControlAccess(
IN PIRP Irp,
IN ULONG RequiredAccess
)
IoValidateDeviceIoControlAccess(IN PIRP Irp,
IN ULONG RequiredAccess)
{
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 */

View file

@ -1,291 +0,0 @@
/* $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 */

View file

@ -1,9 +1,8 @@
/* $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)
@ -59,6 +58,38 @@ typedef enum _DISK_MANAGER
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
@ -1430,4 +1461,189 @@ xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
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 */

View file

@ -528,4 +528,30 @@ IoRaiseInformationalHardError(NTSTATUS ErrorStatus,
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 */

File diff suppressed because it is too large Load diff

View file

@ -1,92 +0,0 @@
/* $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);
}

View file

@ -1,133 +0,0 @@
/* $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 */

View file

@ -1,9 +1,8 @@
/* $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)
*/
@ -22,7 +21,6 @@
/* DATA ********************************************************************/
POBJECT_TYPE EXPORTED IoDeviceObjectType = NULL;
POBJECT_TYPE EXPORTED IoFileObjectType = NULL;
ULONG EXPORTED IoReadOperationCount = 0;
@ -33,358 +31,35 @@ ULONG IoOtherOperationCount = 0;
ULONGLONG IoOtherTransferCount = 0;
KSPIN_LOCK EXPORTED IoStatisticsLock = 0;
static GENERIC_MAPPING IopFileMapping = {FILE_GENERIC_READ,
GENERIC_MAPPING IopFileMapping = {
FILE_GENERIC_READ,
FILE_GENERIC_WRITE,
FILE_GENERIC_EXECUTE,
FILE_ALL_ACCESS};
/* FUNCTIONS ****************************************************************/
static KSPIN_LOCK CancelSpinLock;
extern LIST_ENTRY ShutdownListHead;
extern KSPIN_LOCK ShutdownListLock;
VOID STDCALL
IopCloseFile(PVOID ObjectBody,
ULONG HandleCount)
/* INIT FUNCTIONS ************************************************************/
VOID
INIT_FUNCTION
IoInitCancelHandling(VOID)
{
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);
}
KeInitializeSpinLock(&CancelSpinLock);
}
VOID STDCALL
IopDeleteFile(PVOID ObjectBody)
VOID
INIT_FUNCTION
IoInitShutdownNotification (VOID)
{
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;
}
InitializeListHead(&ShutdownListHead);
KeInitializeSpinLock(&ShutdownListLock);
}
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 INIT_FUNCTION
VOID
INIT_FUNCTION
IoInit (VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
@ -561,7 +236,6 @@ IoInit (VOID)
PnpInit();
}
VOID
INIT_FUNCTION
IoInit2(BOOLEAN BootLog)
@ -667,13 +341,81 @@ IoInit3(VOID)
NULL);
}
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
PGENERIC_MAPPING STDCALL
IoGetFileObjectGenericMapping(VOID)
VOID
STDCALL
IoAcquireCancelSpinLock(PKIRQL Irql)
{
return(&IopFileMapping);
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
*/
VOID
STDCALL
IoReleaseCancelSpinLock(KIRQL Irql)
{
KeReleaseSpinLock(&CancelSpinLock,Irql);
}
/*
* @implemented
*/
PEPROCESS
STDCALL
IoThreadToProcess(IN PETHREAD Thread)
{
return(Thread->ThreadsProcess);
}
/* EOF */

File diff suppressed because it is too large Load diff

View file

@ -1,296 +0,0 @@
/* $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;
}

View file

@ -1,66 +0,0 @@
/* $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 */

View file

@ -1,76 +0,0 @@
/* $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 */

View file

@ -1,134 +0,0 @@
/* $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 */

View file

@ -1,61 +0,0 @@
/* $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 */

View file

@ -1,120 +0,0 @@
/* $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 */

View file

@ -1,156 +0,0 @@
/* $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 */

View file

@ -1,405 +0,0 @@
/* $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 */

View file

@ -1,132 +0,0 @@
/* $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 */

View file

@ -376,4 +376,17 @@ IoReleaseVpbSpinLock(IN KIRQL Irql)
Irql);
}
/*
* @unimplemented
*/
NTSTATUS
STDCALL
IoCheckQuerySetVolumeInformation(IN FS_INFORMATION_CLASS FsInformationClass,
IN ULONG Length,
IN BOOLEAN SetOperation)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
/* EOF */

View file

@ -1,25 +0,0 @@
/* $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;
}

View file

@ -1,205 +0,0 @@
/* $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 */

View file

@ -106,20 +106,6 @@ KeSetDmaIoCoherency(
KiDmaIoCoherency = Coherency;
}
/*
* @unimplemented
*/
STDCALL
PKDEVICE_QUEUE_ENTRY
KeRemoveByKeyDeviceQueueIfBusy (
IN PKDEVICE_QUEUE DeviceQueue,
IN ULONG SortKey
)
{
UNIMPLEMENTED;
return 0;
}
/*
* @implemented
*/

View file

@ -242,6 +242,18 @@ KeRemoveByKeyDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue,
return ReturnEntry;
}
/*
* @unimplemented
*/
STDCALL
PKDEVICE_QUEUE_ENTRY
KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue,
IN ULONG SortKey)
{
UNIMPLEMENTED;
return 0;
}
/*
* @implemented
*/

View file

@ -224,7 +224,7 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Status = IoPageWrite(PagingFileList[i]->FileObject,
Status = IoSynchronousPageWrite(PagingFileList[i]->FileObject,
Mdl,
&file_offset,
&Event,

View file

@ -672,11 +672,7 @@ endif
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