mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
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:
parent
612461644d
commit
defaccea55
33 changed files with 4495 additions and 5067 deletions
|
@ -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 =
|
||||
|
|
|
@ -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 = \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
KeInitializeSpinLock(&CancelSpinLock);
|
||||
}
|
||||
|
||||
#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)
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
IoInitShutdownNotification (VOID)
|
||||
{
|
||||
KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
|
||||
}
|
||||
InitializeListHead(&ShutdownListHead);
|
||||
KeInitializeSpinLock(&ShutdownListLock);
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
IopDeleteFile(PVOID ObjectBody)
|
||||
{
|
||||
PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("IopDeleteFile()\n");
|
||||
|
||||
if (FileObject->DeviceObject)
|
||||
{
|
||||
#if 0
|
||||
//NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
|
||||
|
||||
ObReferenceObjectByPointer(ObjectBody,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
IoFileObjectType,
|
||||
UserMode);
|
||||
#endif
|
||||
KeResetEvent( &FileObject->Event );
|
||||
|
||||
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, TRUE);
|
||||
if (Irp == NULL)
|
||||
{
|
||||
/*
|
||||
* FIXME: This case should eventually be handled. We should wait
|
||||
* until enough memory is available to allocate the IRP.
|
||||
*/
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
Irp->UserEvent = &FileObject->Event;
|
||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||
Irp->Flags |= IRP_CLOSE_OPERATION;
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->MajorFunction = IRP_MJ_CLOSE;
|
||||
StackPtr->DeviceObject = FileObject->DeviceObject;
|
||||
StackPtr->FileObject = FileObject;
|
||||
|
||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (FileObject->FileName.Buffer != NULL)
|
||||
{
|
||||
ExFreePool(FileObject->FileName.Buffer);
|
||||
FileObject->FileName.Buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
PULONG BufferLength)
|
||||
{
|
||||
ULONG_PTR Current;
|
||||
ULONG SidSize;
|
||||
ULONG SdSize;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("IopSetDefaultSecurityDescriptor() called\n");
|
||||
|
||||
if (SecurityInformation == 0)
|
||||
{
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
SidSize = RtlLengthSid(SeWorldSid);
|
||||
SdSize = sizeof(SECURITY_DESCRIPTOR) + (2 * SidSize);
|
||||
|
||||
if (*BufferLength < SdSize)
|
||||
{
|
||||
*BufferLength = SdSize;
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
*BufferLength = SdSize;
|
||||
|
||||
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
|
||||
SECURITY_DESCRIPTOR_REVISION);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
SecurityDescriptor->Control |= SE_SELF_RELATIVE;
|
||||
Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR);
|
||||
|
||||
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
|
||||
{
|
||||
RtlCopyMemory((PVOID)Current,
|
||||
SeWorldSid,
|
||||
SidSize);
|
||||
SecurityDescriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
|
||||
Current += SidSize;
|
||||
}
|
||||
|
||||
if (SecurityInformation & GROUP_SECURITY_INFORMATION)
|
||||
{
|
||||
RtlCopyMemory((PVOID)Current,
|
||||
SeWorldSid,
|
||||
SidSize);
|
||||
SecurityDescriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
|
||||
Current += SidSize;
|
||||
}
|
||||
|
||||
if (SecurityInformation & DACL_SECURITY_INFORMATION)
|
||||
{
|
||||
SecurityDescriptor->Control |= SE_DACL_PRESENT;
|
||||
}
|
||||
|
||||
if (SecurityInformation & SACL_SECURITY_INFORMATION)
|
||||
{
|
||||
SecurityDescriptor->Control |= SE_SACL_PRESENT;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IopSecurityFile(PVOID ObjectBody,
|
||||
SECURITY_OPERATION_CODE OperationCode,
|
||||
SECURITY_INFORMATION SecurityInformation,
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
PULONG BufferLength)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
PFILE_OBJECT FileObject;
|
||||
PIRP Irp;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("IopSecurityFile() called\n");
|
||||
|
||||
FileObject = (PFILE_OBJECT)ObjectBody;
|
||||
|
||||
switch (OperationCode)
|
||||
{
|
||||
case SetSecurityDescriptor:
|
||||
DPRINT("Set security descriptor\n");
|
||||
KeResetEvent(&FileObject->Event);
|
||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SET_SECURITY,
|
||||
FileObject->DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
&FileObject->Event,
|
||||
&IoStatusBlock);
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->FileObject = FileObject;
|
||||
|
||||
StackPtr->Parameters.SetSecurity.SecurityInformation = SecurityInformation;
|
||||
StackPtr->Parameters.SetSecurity.SecurityDescriptor = SecurityDescriptor;
|
||||
|
||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&FileObject->Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
if (Status == STATUS_INVALID_DEVICE_REQUEST)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
|
||||
case QuerySecurityDescriptor:
|
||||
DPRINT("Query security descriptor\n");
|
||||
KeResetEvent(&FileObject->Event);
|
||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_SECURITY,
|
||||
FileObject->DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
&FileObject->Event,
|
||||
&IoStatusBlock);
|
||||
|
||||
Irp->UserBuffer = SecurityDescriptor;
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->FileObject = FileObject;
|
||||
|
||||
StackPtr->Parameters.QuerySecurity.SecurityInformation = SecurityInformation;
|
||||
StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
|
||||
|
||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&FileObject->Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
if (Status == STATUS_INVALID_DEVICE_REQUEST)
|
||||
{
|
||||
Status = IopSetDefaultSecurityDescriptor(SecurityInformation,
|
||||
SecurityDescriptor,
|
||||
BufferLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Is this correct?? */
|
||||
*BufferLength = IoStatusBlock.Information;
|
||||
}
|
||||
return Status;
|
||||
|
||||
case DeleteSecurityDescriptor:
|
||||
DPRINT("Delete security descriptor\n");
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case AssignSecurityDescriptor:
|
||||
DPRINT("Assign security descriptor\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IopQueryNameFile(PVOID ObjectBody,
|
||||
POBJECT_NAME_INFORMATION ObjectNameInfo,
|
||||
ULONG Length,
|
||||
PULONG ReturnLength)
|
||||
{
|
||||
POBJECT_NAME_INFORMATION LocalInfo;
|
||||
PFILE_NAME_INFORMATION FileNameInfo;
|
||||
PFILE_OBJECT FileObject;
|
||||
ULONG LocalReturnLength;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("IopQueryNameFile() called\n");
|
||||
|
||||
FileObject = (PFILE_OBJECT)ObjectBody;
|
||||
|
||||
LocalInfo = ExAllocatePool (NonPagedPool,
|
||||
sizeof(OBJECT_NAME_INFORMATION) +
|
||||
MAX_PATH * sizeof(WCHAR));
|
||||
if (LocalInfo == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Status = ObQueryNameString (FileObject->DeviceObject->Vpb->RealDevice,
|
||||
LocalInfo,
|
||||
MAX_PATH * sizeof(WCHAR),
|
||||
&LocalReturnLength);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
ExFreePool (LocalInfo);
|
||||
return Status;
|
||||
}
|
||||
DPRINT ("Device path: %wZ\n", &LocalInfo->Name);
|
||||
|
||||
Status = RtlAppendUnicodeStringToString (&ObjectNameInfo->Name,
|
||||
&LocalInfo->Name);
|
||||
|
||||
ExFreePool (LocalInfo);
|
||||
|
||||
FileNameInfo = ExAllocatePool (NonPagedPool,
|
||||
MAX_PATH * sizeof(WCHAR) + sizeof(ULONG));
|
||||
if (FileNameInfo == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Status = IoQueryFileInformation (FileObject,
|
||||
FileNameInformation,
|
||||
MAX_PATH * sizeof(WCHAR) + sizeof(ULONG),
|
||||
FileNameInfo,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
ExFreePool (FileNameInfo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = RtlAppendUnicodeToString (&ObjectNameInfo->Name,
|
||||
FileNameInfo->FileName);
|
||||
|
||||
DPRINT ("Total path: %wZ\n", &ObjectNameInfo->Name);
|
||||
|
||||
ExFreePool (FileNameInfo);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID 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
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -106,20 +106,6 @@ KeSetDmaIoCoherency(
|
|||
KiDmaIoCoherency = Coherency;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
STDCALL
|
||||
PKDEVICE_QUEUE_ENTRY
|
||||
KeRemoveByKeyDeviceQueueIfBusy (
|
||||
IN PKDEVICE_QUEUE DeviceQueue,
|
||||
IN ULONG SortKey
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue