mirror of
https://github.com/reactos/reactos.git
synced 2025-07-23 20:24:01 +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) +
|
((PUCHAR)AdapterBusInfo + sizeof(SCSI_ADAPTER_BUS_INFO) +
|
||||||
(sizeof(SCSI_BUS_DATA) * (AdapterBusInfo->NumberOfBuses - 1)));
|
(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++)
|
for (Bus = 0; Bus < AdapterBusInfo->NumberOfBuses; Bus++)
|
||||||
{
|
{
|
||||||
AdapterBusInfo->BusData[Bus].InitiatorBusId =
|
AdapterBusInfo->BusData[Bus].InitiatorBusId =
|
||||||
|
|
|
@ -146,54 +146,36 @@ OBJECTS_IO = \
|
||||||
io/adapter.o \
|
io/adapter.o \
|
||||||
io/arcname.o \
|
io/arcname.o \
|
||||||
io/bootlog.o \
|
io/bootlog.o \
|
||||||
io/buildirp.o \
|
|
||||||
io/cancel.o \
|
|
||||||
io/cleanup.o \
|
|
||||||
io/controller.o \
|
io/controller.o \
|
||||||
io/create.o \
|
|
||||||
io/device.o \
|
io/device.o \
|
||||||
io/deviface.o \
|
io/deviface.o \
|
||||||
io/dir.o \
|
io/disk.o \
|
||||||
io/driver.o \
|
io/driver.o \
|
||||||
io/efi.o \
|
io/efi.o \
|
||||||
io/error.o \
|
io/error.o \
|
||||||
io/event.o \
|
io/event.o \
|
||||||
io/file.o \
|
io/file.o \
|
||||||
io/flush.o \
|
|
||||||
io/fs.o \
|
io/fs.o \
|
||||||
io/iocomp.o \
|
io/iocomp.o \
|
||||||
io/ioctrl.o \
|
|
||||||
io/iomgr.o \
|
io/iomgr.o \
|
||||||
io/iowork.o \
|
io/iowork.o \
|
||||||
io/irp.o \
|
io/irp.o \
|
||||||
io/irq.o \
|
io/irq.o \
|
||||||
io/lock.o \
|
|
||||||
io/mailslot.o \
|
|
||||||
io/mdl.o \
|
io/mdl.o \
|
||||||
io/npipe.o \
|
|
||||||
io/page.o \
|
|
||||||
io/parttab.o \
|
|
||||||
io/plugplay.o \
|
io/plugplay.o \
|
||||||
io/process.o \
|
|
||||||
io/pnpdma.o \
|
io/pnpdma.o \
|
||||||
io/pnpmgr.o \
|
io/pnpmgr.o \
|
||||||
io/pnpnotify.o \
|
io/pnpnotify.o \
|
||||||
io/pnpreport.o \
|
io/pnpreport.o \
|
||||||
io/pnproot.o \
|
io/pnproot.o \
|
||||||
io/queue.o \
|
|
||||||
io/rawfs.o \
|
io/rawfs.o \
|
||||||
io/remlock.o \
|
io/remlock.o \
|
||||||
io/resource.o \
|
io/resource.o \
|
||||||
io/rw.o \
|
|
||||||
io/share.o \
|
io/share.o \
|
||||||
io/shutdown.o \
|
|
||||||
io/symlink.o \
|
io/symlink.o \
|
||||||
io/timer.o \
|
io/timer.o \
|
||||||
io/vpb.o \
|
io/vpb.o \
|
||||||
io/wdm.o \
|
|
||||||
io/wmi.o \
|
io/wmi.o \
|
||||||
io/xhaldisp.o \
|
|
||||||
io/xhaldrv.o
|
|
||||||
|
|
||||||
# Object Manager (Ob)
|
# Object Manager (Ob)
|
||||||
OBJECTS_OB = \
|
OBJECTS_OB = \
|
||||||
|
|
|
@ -263,7 +263,7 @@ WriteCacheSegment(PCACHE_SEGMENT CacheSeg)
|
||||||
MmBuildMdlForNonPagedPool(Mdl);
|
MmBuildMdlForNonPagedPool(Mdl);
|
||||||
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
|
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
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)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
@ -643,7 +643,7 @@ CcZeroData (IN PFILE_OBJECT FileObject,
|
||||||
((PPFN_TYPE)(Mdl + 1))[i] = CcZeroPage;
|
((PPFN_TYPE)(Mdl + 1))[i] = CcZeroPage;
|
||||||
}
|
}
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
Status = IoPageWrite(FileObject, Mdl, &WriteOffset, &Event, &Iosb);
|
Status = IoSynchronousPageWrite(FileObject, Mdl, &WriteOffset, &Event, &Iosb);
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
|
@ -518,6 +518,38 @@ IopMarkLastReinitializeDriver(VOID);
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
IopReinitializeDrivers(VOID);
|
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 */
|
/* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS Kernel
|
||||||
* FILE: ntoskrnl/io/device.c
|
* 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 *******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
|
@ -17,14 +17,66 @@
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
#define TAG_DEVICE_EXTENSION TAG('D', 'E', 'X', 'T')
|
#define TAG_DEVICE_EXTENSION TAG('D', 'E', 'X', 'T')
|
||||||
|
#define TAG_SHUTDOWN_ENTRY TAG('S', 'H', 'U', 'T')
|
||||||
|
|
||||||
static ULONG IopDeviceObjectNumber = 0;
|
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 **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
VOID
|
||||||
IopInitializeDevice(
|
IoShutdownRegisteredDevices(VOID)
|
||||||
PDEVICE_NODE DeviceNode,
|
{
|
||||||
|
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)
|
PDRIVER_OBJECT DriverObject)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
@ -815,26 +867,35 @@ IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
IoRegisterLastChanceShutdownNotification(
|
IoRegisterLastChanceShutdownNotification(IN PDEVICE_OBJECT DeviceObject)
|
||||||
IN PDEVICE_OBJECT DeviceObject
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
IoSetStartIoAttributes(
|
IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN BOOLEAN DeferredStartIo,
|
|
||||||
IN BOOLEAN NonCancelable
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
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
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
IoSynchronousInvalidateDeviceRelations(
|
IoSetStartIoAttributes(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN BOOLEAN DeferredStartIo,
|
||||||
IN DEVICE_RELATION_TYPE Type
|
IN BOOLEAN NonCancelable)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
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
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
IoValidateDeviceIoControlAccess(
|
IoValidateDeviceIoControlAccess(IN PIRP Irp,
|
||||||
IN PIRP Irp,
|
IN ULONG RequiredAccess)
|
||||||
IN ULONG RequiredAccess
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
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 */
|
/* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/io/xhaldrv.c
|
* FILE: ntoskrnl/io/disk.c
|
||||||
* PURPOSE: Hal drive routines
|
* PURPOSE: I/O Support for Hal Disk (Partition Table/MBR) Routines.
|
||||||
*
|
*
|
||||||
* PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
|
* PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
|
||||||
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
* Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
|
@ -59,6 +58,38 @@ typedef enum _DISK_MANAGER
|
||||||
EZ_Drive
|
EZ_Drive
|
||||||
} DISK_MANAGER;
|
} 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 *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -1430,4 +1461,189 @@ xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
|
||||||
return Status;
|
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 */
|
/* EOF */
|
|
@ -528,4 +528,30 @@ IoRaiseInformationalHardError(NTSTATUS ErrorStatus,
|
||||||
return(FALSE);
|
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 */
|
/* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS Kernel
|
||||||
* FILE: ntoskrnl/io/iomgr.c
|
* 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)
|
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
||||||
*/
|
*/
|
||||||
|
@ -22,7 +21,6 @@
|
||||||
|
|
||||||
/* DATA ********************************************************************/
|
/* DATA ********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
POBJECT_TYPE EXPORTED IoDeviceObjectType = NULL;
|
POBJECT_TYPE EXPORTED IoDeviceObjectType = NULL;
|
||||||
POBJECT_TYPE EXPORTED IoFileObjectType = NULL;
|
POBJECT_TYPE EXPORTED IoFileObjectType = NULL;
|
||||||
ULONG EXPORTED IoReadOperationCount = 0;
|
ULONG EXPORTED IoReadOperationCount = 0;
|
||||||
|
@ -33,358 +31,35 @@ ULONG IoOtherOperationCount = 0;
|
||||||
ULONGLONG IoOtherTransferCount = 0;
|
ULONGLONG IoOtherTransferCount = 0;
|
||||||
KSPIN_LOCK EXPORTED IoStatisticsLock = 0;
|
KSPIN_LOCK EXPORTED IoStatisticsLock = 0;
|
||||||
|
|
||||||
static GENERIC_MAPPING IopFileMapping = {FILE_GENERIC_READ,
|
GENERIC_MAPPING IopFileMapping = {
|
||||||
|
FILE_GENERIC_READ,
|
||||||
FILE_GENERIC_WRITE,
|
FILE_GENERIC_WRITE,
|
||||||
FILE_GENERIC_EXECUTE,
|
FILE_GENERIC_EXECUTE,
|
||||||
FILE_ALL_ACCESS};
|
FILE_ALL_ACCESS};
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
static KSPIN_LOCK CancelSpinLock;
|
||||||
|
extern LIST_ENTRY ShutdownListHead;
|
||||||
|
extern KSPIN_LOCK ShutdownListLock;
|
||||||
|
|
||||||
VOID STDCALL
|
/* INIT FUNCTIONS ************************************************************/
|
||||||
IopCloseFile(PVOID ObjectBody,
|
|
||||||
ULONG HandleCount)
|
VOID
|
||||||
|
INIT_FUNCTION
|
||||||
|
IoInitCancelHandling(VOID)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
|
KeInitializeSpinLock(&CancelSpinLock);
|
||||||
PIRP Irp;
|
|
||||||
PIO_STACK_LOCATION StackPtr;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
DPRINT("IopCloseFile()\n");
|
|
||||||
|
|
||||||
if (HandleCount > 1 || FileObject->DeviceObject == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//NOTE: Allmost certain that the latest changes to I/O Mgr makes this redundant (OriginalFileObject case)
|
|
||||||
ObReferenceObjectByPointer(FileObject,
|
|
||||||
STANDARD_RIGHTS_REQUIRED,
|
|
||||||
IoFileObjectType,
|
|
||||||
UserMode);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KeResetEvent( &FileObject->Event );
|
|
||||||
|
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
|
|
||||||
FileObject->DeviceObject,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
&FileObject->Event,
|
|
||||||
NULL);
|
|
||||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
|
||||||
StackPtr->FileObject = FileObject;
|
|
||||||
|
|
||||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
VOID STDCALL
|
INIT_FUNCTION
|
||||||
IopDeleteFile(PVOID ObjectBody)
|
IoInitShutdownNotification (VOID)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
|
InitializeListHead(&ShutdownListHead);
|
||||||
PIRP Irp;
|
KeInitializeSpinLock(&ShutdownListLock);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
static NTSTATUS
|
INIT_FUNCTION
|
||||||
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
|
|
||||||
IoInit (VOID)
|
IoInit (VOID)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
@ -561,7 +236,6 @@ IoInit (VOID)
|
||||||
PnpInit();
|
PnpInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
IoInit2(BOOLEAN BootLog)
|
IoInit2(BOOLEAN BootLog)
|
||||||
|
@ -667,13 +341,81 @@ IoInit3(VOID)
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
PGENERIC_MAPPING STDCALL
|
VOID
|
||||||
IoGetFileObjectGenericMapping(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 */
|
/* 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);
|
Irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
IoCheckQuerySetVolumeInformation(IN FS_INFORMATION_CLASS FsInformationClass,
|
||||||
|
IN ULONG Length,
|
||||||
|
IN BOOLEAN SetOperation)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* 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;
|
KiDmaIoCoherency = Coherency;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
STDCALL
|
|
||||||
PKDEVICE_QUEUE_ENTRY
|
|
||||||
KeRemoveByKeyDeviceQueueIfBusy (
|
|
||||||
IN PKDEVICE_QUEUE DeviceQueue,
|
|
||||||
IN ULONG SortKey
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -242,6 +242,18 @@ KeRemoveByKeyDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue,
|
||||||
return ReturnEntry;
|
return ReturnEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
STDCALL
|
||||||
|
PKDEVICE_QUEUE_ENTRY
|
||||||
|
KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue,
|
||||||
|
IN ULONG SortKey)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -224,7 +224,7 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
|
||||||
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
|
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
|
||||||
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
Status = IoPageWrite(PagingFileList[i]->FileObject,
|
Status = IoSynchronousPageWrite(PagingFileList[i]->FileObject,
|
||||||
Mdl,
|
Mdl,
|
||||||
&file_offset,
|
&file_offset,
|
||||||
&Event,
|
&Event,
|
||||||
|
|
|
@ -672,11 +672,7 @@ endif
|
||||||
ifneq ($(DBG),1)
|
ifneq ($(DBG),1)
|
||||||
MK_CFLAGS += -Os -Wno-strict-aliasing -ftracer -momit-leaf-frame-pointer
|
MK_CFLAGS += -Os -Wno-strict-aliasing -ftracer -momit-leaf-frame-pointer
|
||||||
MK_CFLAGS += -mpreferred-stack-boundary=2
|
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
|
MK_CFLAGS += -funit-at-a-time -fweb
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Remove Symbols if no debugging is used at all
|
# Remove Symbols if no debugging is used at all
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue