POBJECT_TYPE ParentObjectType;
NTSTATUS Status;
- DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %S)\n",
- ObjectBody,
- Parent,
- RemainingPath);
+ DPRINT("IopCreateFile(ObjectBody 0x%p, Parent 0x%p, RemainingPath %S)\n",
+ ObjectBody,
+ Parent,
+ RemainingPath);
if (NULL == Parent)
{
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)->NameInfo->Name,
- BODY_TO_HEADER(Parent)->Type->Name.Buffer,
- RemainingPath);
+ &HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Parent))->Name,
+ BODY_TO_HEADER(Parent)->Type->Name.Buffer,
+ RemainingPath);
return(STATUS_UNSUCCESSFUL);
}
Status = ObReferenceObjectByPointer(Parent,
- STANDARD_RIGHTS_REQUIRED,
- ParentObjectType,
- UserMode);
+ STANDARD_RIGHTS_REQUIRED,
+ ParentObjectType,
+ UserMode);
if (!NT_SUCCESS(Status))
{
- CPRINT("Failed to reference parent object %x\n", Parent);
+ CPRINT("Failed to reference parent object 0x%p\n", Parent);
return(Status);
}
{
/* Parent is a devce object */
DeviceObject = IoGetAttachedDevice((PDEVICE_OBJECT)Parent);
- DPRINT("DeviceObject %x\n", DeviceObject);
+ DPRINT("DeviceObject 0x%p\n", DeviceObject);
if (RemainingPath == NULL)
- {
- FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
- FileObject->FileName.Buffer = 0;
- FileObject->FileName.Length = FileObject->FileName.MaximumLength = 0;
- }
+ {
+ 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_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);
- }
+ 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);
+ }
+ RtlCreateUnicodeString(&FileObject->FileName, RemainingPath);
+ }
}
else
{
/* Parent is a file object */
if (RemainingPath == NULL)
- {
- CPRINT("Device is unnamed\n");
- return STATUS_UNSUCCESSFUL;
- }
+ {
+ CPRINT("Device is unnamed\n");
+ return STATUS_UNSUCCESSFUL;
+ }
DeviceObject = ((PFILE_OBJECT)Parent)->DeviceObject;
- DPRINT("DeviceObject %x\n", DeviceObject);
+ DPRINT("DeviceObject 0x%p\n", DeviceObject);
FileObject->RelatedFileObject = (PFILE_OBJECT)Parent;
- RtlpCreateUnicodeString(&(FileObject->FileName),
- RemainingPath, NonPagedPool);
+ RtlCreateUnicodeString(&FileObject->FileName, RemainingPath);
}
DPRINT("FileObject->FileName %wZ\n",
- &FileObject->FileName);
+ &FileObject->FileName);
FileObject->DeviceObject = DeviceObject;
- DPRINT("FileObject %x DeviceObject %x\n",
- FileObject,
- DeviceObject);
+ DPRINT("FileObject 0x%p DeviceObject 0x%p\n",
+ FileObject,
+ DeviceObject);
FileObject->Vpb = DeviceObject->Vpb;
FileObject->Type = IO_TYPE_FILE;
SECURITY_OPERATION_CODE OperationCode,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
- PULONG BufferLength)
+ PULONG BufferLength,
+ PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
+ POOL_TYPE PoolType,
+ PGENERIC_MAPPING GenericMapping)
{
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION StackPtr;
/* Set Stack Parameters */
StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->MajorFunction = MajorFunction;
StackPtr->FileObject = FileObject;
/* Set Parameters */
ULONG Length,
PULONG ReturnLength)
{
- PVOID LocalInfo;
+ POBJECT_NAME_INFORMATION LocalInfo;
PFILE_OBJECT FileObject;
ULONG LocalReturnLength;
NTSTATUS Status;
/* Write Device Path */
Status = RtlAppendUnicodeStringToString(&ObjectNameInfo->Name,
- &((POBJECT_NAME_INFORMATION)LocalInfo)->Name);
+ &(LocalInfo)->Name);
/* Query the File name */
Status = IoQueryFileInformation(FileObject,
BOOLEAN LocalEvent = FALSE;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
- DPRINT("IopDeviceFsIoControl(DeviceHandle %x Event %x UserApcRoutine %x "
- "UserApcContext %x IoStatusBlock %x IoControlCode %x "
- "InputBuffer %x InputBufferLength %x OutputBuffer %x "
- "OutputBufferLength %x)\n",
+ DPRINT("IopDeviceFsIoControl(DeviceHandle 0x%p Event 0x%p UserApcRoutine 0x%p "
+ "UserApcContext 0x%p IoStatusBlock 0x%p IoControlCode %x "
+ "InputBuffer 0x%p InputBufferLength %x OutputBuffer 0x%p "
+ "OutputBufferLength 0x%p)\n",
DeviceHandle,Event,UserApcRoutine,UserApcContext,IoStatusBlock,
IoControlCode,InputBuffer,InputBufferLength,OutputBuffer,
OutputBufferLength);
PFILE_OBJECT FileObject = NULL;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
- PIO_STACK_LOCATION StackLoc;
+ PEXTENDED_IO_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;
+ AUX_DATA AuxData;
+ ACCESS_STATE AccessState;
- DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
- "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
- FileHandle,DesiredAccess,ObjectAttributes,
- ObjectAttributes->ObjectName->Buffer);
+ DPRINT("IoCreateFile(FileHandle 0x%p, DesiredAccess %x, "
+ "ObjectAttributes 0x%p ObjectAttributes->ObjectName->Buffer %S)\n",
+ FileHandle,DesiredAccess,ObjectAttributes,
+ ObjectAttributes->ObjectName->Buffer);
ASSERT_IRQL(PASSIVE_LEVEL);
{
_SEH_TRY
{
- ProbeForWrite(FileHandle,
- sizeof(HANDLE),
- sizeof(ULONG));
+ ProbeForWriteHandle(FileHandle);
ProbeForWrite(IoStatusBlock,
sizeof(IO_STATUS_BLOCK),
sizeof(ULONG));
if(AllocationSize != NULL)
{
- ProbeForRead(AllocationSize,
- sizeof(LARGE_INTEGER),
- sizeof(ULONG));
- SafeAllocationSize = *AllocationSize;
+ SafeAllocationSize = ProbeForReadLargeInteger(AllocationSize);
}
else
SafeAllocationSize.QuadPart = 0;
DPRINT1("FIXME: IO_CHECK_CREATE_PARAMETERS not yet supported!\n");
}
- if (CreateDisposition == FILE_OPEN ||
- CreateDisposition == FILE_OPEN_IF)
- {
+ /* First try to open an existing named object */
+ Status = ObOpenObjectByName(ObjectAttributes,
+ NULL,
+ NULL,
+ AccessMode,
+ DesiredAccess,
+ NULL,
+ &LocalHandle);
- Status = ObOpenObjectByName(ObjectAttributes,
- NULL,
- NULL,
- AccessMode,
- DesiredAccess,
- NULL,
- &LocalHandle);
+ if (NT_SUCCESS(Status))
+ {
+ OBJECT_CREATE_INFORMATION ObjectCreateInfo;
+ OBJECT_ATTRIBUTES tmpObjectAttributes;
+ UNICODE_STRING ObjectName;
+
+ Status = ObReferenceObjectByHandle(LocalHandle,
+ DesiredAccess,
+ NULL,
+ AccessMode,
+ (PVOID*)&DeviceObject,
+ NULL);
+ ZwClose(LocalHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ if (BODY_TO_HEADER(DeviceObject)->Type != IoDeviceObjectType)
+ {
+ ObDereferenceObject (DeviceObject);
+ return STATUS_OBJECT_NAME_COLLISION;
+ }
- if (NT_SUCCESS(Status))
+ Status = ObpCaptureObjectAttributes(ObjectAttributes,
+ AccessMode,
+ NULL,
+ &ObjectCreateInfo,
+ &ObjectName);
+ 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)->Type != IoDeviceObjectType)
- {
- ObDereferenceObject (DeviceObject);
- return STATUS_OBJECT_NAME_COLLISION;
- }
- /* FIXME: wt... */
- FileObject = IoCreateStreamFileObject(NULL, DeviceObject);
- /* HACK */
- FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
- DPRINT("%wZ\n", ObjectAttributes->ObjectName);
-
- ObDereferenceObject (DeviceObject);
+ ObDereferenceObject (DeviceObject);
+ return Status;
}
+
+ InitializeObjectAttributes(&tmpObjectAttributes,
+ NULL,
+ ObjectCreateInfo.Attributes & OBJ_INHERIT,
+ 0,
+ NULL);
+ ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+ if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+
+
+ /* FIXME: wt... */
+ Status = ObCreateObject(KernelMode,
+ IoFileObjectType,
+ &tmpObjectAttributes,
+ KernelMode,
+ NULL,
+ sizeof(FILE_OBJECT),
+ 0,
+ 0,
+ (PVOID*)&FileObject);
+
+
+ /* Set File Object Data */
+ FileObject->DeviceObject = IoGetAttachedDevice(DeviceObject);
+ FileObject->Vpb = FileObject->DeviceObject->Vpb;
+
+ /* HACK */
+ FileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
+ DPRINT("%wZ\n", ObjectAttributes->ObjectName);
+
+ ObDereferenceObject (DeviceObject);
}
if (FileObject == NULL)
{
Status = ObCreateObject(AccessMode,
- IoFileObjectType,
- ObjectAttributes,
- AccessMode,
- NULL,
- sizeof(FILE_OBJECT),
- 0,
- 0,
- (PVOID*)&FileObject);
+ IoFileObjectType,
+ ObjectAttributes,
+ AccessMode,
+ NULL,
+ sizeof(FILE_OBJECT),
+ 0,
+ 0,
+ (PVOID*)&FileObject);
if (!NT_SUCCESS(Status))
{
- DPRINT("ObCreateObject() failed! (Status %lx)\n", Status);
- return Status;
+ DPRINT("ObCreateObject() failed! (Status %lx)\n", Status);
+ return Status;
}
}
RtlMapGenericMask(&DesiredAccess,
- &BODY_TO_HEADER(FileObject)->Type->TypeInfo.GenericMapping);
+ &BODY_TO_HEADER(FileObject)->Type->TypeInfo.GenericMapping);
Status = ObInsertObject ((PVOID)FileObject,
- NULL,
- DesiredAccess,
- 0,
- NULL,
- &LocalHandle);
+ NULL,
+ DesiredAccess,
+ 0,
+ NULL,
+ &LocalHandle);
if (!NT_SUCCESS(Status))
{
- DPRINT("ObInsertObject() failed! (Status %lx)\n", Status);
- ObDereferenceObject (FileObject);
- return Status;
+ DPRINT("ObInsertObject() failed! (Status %lx)\n", Status);
+ ObMakeTemporaryObject(FileObject);
+ ObDereferenceObject (FileObject);
+ return Status;
}
if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
{
- FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
+ FileObject->Flags |= (FO_ALERTABLE_IO | FO_SYNCHRONOUS_IO);
}
if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
{
- FileObject->Flags |= FO_SYNCHRONOUS_IO;
+ FileObject->Flags |= FO_SYNCHRONOUS_IO;
}
if (CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)
FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
+ /*
+ * FIXME: We should get the access state from Ob once this function becomes
+ * a parse routine once the Ob is refactored.
+ */
+ SeCreateAccessState(&AccessState, &AuxData, FILE_ALL_ACCESS, NULL);
+
SecurityContext.SecurityQos = NULL; /* ?? */
- SecurityContext.AccessState = NULL; /* ?? */
+ SecurityContext.AccessState = &AccessState;
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);
+ DPRINT("FileObject 0x%p\n", FileObject);
+ DPRINT("FileObject->DeviceObject 0x%p\n", FileObject->DeviceObject);
/*
* Create a new IRP to hand to
* the FS driver: this may fail
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
if (Irp == NULL)
{
- ZwClose(LocalHandle);
- return STATUS_UNSUCCESSFUL;
+ ZwClose(LocalHandle);
+ return STATUS_UNSUCCESSFUL;
}
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = AccessMode;
- Irp->UserIosb = &LocalIoStatusBlock;
+ Irp->UserIosb = IoStatusBlock;
Irp->AssociatedIrp.SystemBuffer = SystemEaBuffer;
Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
* Get the stack location for the new
* IRP and prepare it.
*/
- StackLoc = IoGetNextIrpStackLocation(Irp);
+ StackLoc = (PEXTENDED_IO_STACK_LOCATION)IoGetNextIrpStackLocation(Irp);
StackLoc->MinorFunction = 0;
StackLoc->Flags = (UCHAR)Options;
StackLoc->Control = 0;
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;
+ 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;
}
/*
if (Status == STATUS_PENDING)
{
- KeWaitForSingleObject(&FileObject->Event,
- Executive,
- AccessMode,
- FALSE,
- NULL);
- Status = LocalIoStatusBlock.Status;
+ KeWaitForSingleObject(&FileObject->Event,
+ Executive,
+ AccessMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock->Status;
}
if (!NT_SUCCESS(Status))
{
- DPRINT("Failing create request with status %x\n", Status);
- FileObject->DeviceObject = NULL;
- FileObject->Vpb = NULL;
+ DPRINT("Failing create request with status %x\n", Status);
+ FileObject->DeviceObject = NULL;
+ FileObject->Vpb = NULL;
- ZwClose(LocalHandle);
+ ZwClose(LocalHandle);
}
else
{
- _SEH_TRY
- {
- *FileHandle = LocalHandle;
- *IoStatusBlock = LocalIoStatusBlock;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
+ _SEH_TRY
+ {
+ *FileHandle = LocalHandle;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
}
/* cleanup EABuffer if captured */
ASSERT_IRQL(PASSIVE_LEVEL);
- DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
+ DPRINT("Finished IoCreateFile() (*FileHandle) 0x%p\n", (*FileHandle));
return Status;
}
reason. These hacks need to be removed.
*/
- DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
+ DPRINT("IoCreateStreamFileObject(FileObject 0x%p, DeviceObject 0x%p)\n",
FileObject, DeviceObject);
PAGED_CODE();
/* Choose Device Object */
if (FileObject) DeviceObject = FileObject->DeviceObject;
- DPRINT("DeviceObject %x\n", DeviceObject);
+ DPRINT("DeviceObject 0x%p\n", DeviceObject);
/* HACK */
DeviceObject = IoGetAttachedDevice(DeviceObject);
KernelMode);
if (!NT_SUCCESS(Status)) return(Status);
- DPRINT("FileObject %x\n", FileObject);
+ DPRINT("FileObject 0x%p\n", FileObject);
/* Get the Device Object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
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;
+ KPROCESSOR_MODE PreviousMode;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ PAGED_CODE();
- if ((ULONG_PTR)IoStatusBlock >= MmUserProbeAddress &&
- KeGetPreviousMode() == UserMode)
- return STATUS_ACCESS_VIOLATION;
+ PreviousMode = KeGetPreviousMode();
- Status = ObReferenceObjectByHandle(FileHandle, 0, IoFileObjectType,
- KeGetPreviousMode(), (PVOID*)&FileObject,
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status)) return Status;
+ }
+
+ Status = ObReferenceObjectByHandle(FileHandle,
+ 0,
+ IoFileObjectType,
+ PreviousMode,
+ (PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
return Status;
*/
Thread = PsGetCurrentThread();
- for (IrpEntry = Thread->IrpList.Flink;
- IrpEntry != &Thread->IrpList;
- IrpEntry = IrpEntry->Flink)
+
+ LIST_FOR_EACH(Irp, &Thread->IrpList, IRP, ThreadListEntry)
{
- Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
{
IoCancelIrp(Irp);
* forever.
*/
- for (IrpEntry = Thread->IrpList.Flink;
- IrpEntry != &Thread->IrpList;
- IrpEntry = IrpEntry->Flink)
+ LIST_FOR_EACH(Irp, &Thread->IrpList, IRP, ThreadListEntry)
{
- Irp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
if (Irp->Tail.Overlay.OriginalFileObject == FileObject)
{
OurIrpsInList = TRUE;
{
MAILSLOT_CREATE_PARAMETERS Buffer;
- DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, "
- "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
- FileHandle,DesiredAccess,ObjectAttributes,
- ObjectAttributes->ObjectName->Buffer);
+ DPRINT("NtCreateMailslotFile(FileHandle 0x%p, DesiredAccess %x, "
+ "ObjectAttributes 0x%p)\n",
+ FileHandle,DesiredAccess,ObjectAttributes);
+
PAGED_CODE();
/* Check for Timeout */
- if (TimeOut)
+ if (TimeOut != NULL)
{
- /* Enable it */
- Buffer.TimeoutSpecified = TRUE;
+ if (KeGetPreviousMode() != KernelMode)
+ {
+ NTSTATUS Status = STATUS_SUCCESS;
- /* FIXME: Add SEH */
- Buffer.ReadTimeout = *TimeOut;
+ _SEH_TRY
+ {
+ Buffer.ReadTimeout = ProbeForReadLargeInteger(TimeOut);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status)) return Status;
+ }
+ else
+ {
+ Buffer.ReadTimeout = *TimeOut;
+ }
+
+ Buffer.TimeoutSpecified = TRUE;
}
else
{
- /* No timeout */
Buffer.TimeoutSpecified = FALSE;
}
{
NAMED_PIPE_CREATE_PARAMETERS Buffer;
- DPRINT("NtCreateNamedPipeFile(FileHandle %x, DesiredAccess %x, "
- "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
- FileHandle,DesiredAccess,ObjectAttributes,
- ObjectAttributes->ObjectName->Buffer);
+ DPRINT("NtCreateNamedPipeFile(FileHandle 0x%p, DesiredAccess %x, "
+ "ObjectAttributes 0x%p)\n",
+ FileHandle,DesiredAccess,ObjectAttributes);
+
PAGED_CODE();
/* Check for Timeout */
- if (DefaultTimeout)
+ if (DefaultTimeout != NULL)
{
- /* Enable it */
- Buffer.TimeoutSpecified = TRUE;
+ if (KeGetPreviousMode() != KernelMode)
+ {
+ NTSTATUS Status = STATUS_SUCCESS;
- /* FIXME: Add SEH */
- Buffer.DefaultTimeout = *DefaultTimeout;
+ _SEH_TRY
+ {
+ Buffer.DefaultTimeout = ProbeForReadLargeInteger(DefaultTimeout);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status)) return Status;
+ }
+ else
+ {
+ Buffer.DefaultTimeout = *DefaultTimeout;
+ }
+
+ Buffer.TimeoutSpecified = TRUE;
}
else
- {
- /* No timeout */
Buffer.TimeoutSpecified = FALSE;
- }
/* Set Settings */
Buffer.NamedPipeType = NamedPipeType;
STDCALL
NtFlushWriteBuffer(VOID)
{
+ PAGED_CODE();
+
KeFlushWriteBuffer();
return STATUS_SUCCESS;
}
PFILE_OBJECT FileObject = NULL;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject;
KEVENT Event;
BOOLEAN LocalEvent = FALSE;
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ ACCESS_MASK DesiredAccess = FILE_WRITE_DATA;
+ OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
+ KPROCESSOR_MODE PreviousMode;
+
+ PAGED_CODE();
+
+ PreviousMode = KeGetPreviousMode();
+
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status)) return Status;
+ }
/* Get the File Object */
Status = ObReferenceObjectByHandle(FileHandle,
- FILE_WRITE_DATA,
- NULL,
+ 0,
+ IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
- NULL);
- if (Status != STATUS_SUCCESS) return(Status);
+ &ObjectHandleInfo);
+ if (!NT_SUCCESS(Status)) return(Status);
+
+ /* check if the handle has either FILE_WRITE_DATA or FILE_APPEND_DATA was
+ granted. However, if this is a named pipe, make sure we don't ask for
+ FILE_APPEND_DATA as it interferes with the FILE_CREATE_PIPE_INSTANCE
+ access right! */
+ if (!(FileObject->Flags & FO_NAMED_PIPE))
+ DesiredAccess |= FILE_APPEND_DATA;
+ if (!RtlAreAnyAccessesGranted(ObjectHandleInfo.GrantedAccess,
+ DesiredAccess))
+ {
+ ObDereferenceObject(FileObject);
+ return STATUS_ACCESS_DENIED;
+ }
/* Check if this is a direct open or not */
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (Irp==NULL)
{
- ObDereferenceObject(FileObject);
- return STATUS_UNSUCCESSFUL;
+ ObDereferenceObject(FileObject);
+ return STATUS_UNSUCCESSFUL;
}
if (Event == NULL)
if (WatchTree)
{
- IoStack->Flags = SL_WATCH_TREE;
+ IoStack->Flags = SL_WATCH_TREE;
}
IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER ByteOffset,
IN PLARGE_INTEGER Length,
- IN PULONG Key,
+ IN ULONG Key,
IN BOOLEAN FailImmediately,
IN BOOLEAN ExclusiveLock)
{
PDEVICE_OBJECT DeviceObject;
PKEVENT Event = NULL;
BOOLEAN LocalEvent = FALSE;
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ KPROCESSOR_MODE PreviousMode;
+ LARGE_INTEGER CapturedByteOffset, CapturedLength;
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_HANDLE_INFORMATION HandleInformation;
-
- /* FIXME: instead of this, use SEH */
- if (!Length || !ByteOffset) return STATUS_INVALID_PARAMETER;
+
+ PAGED_CODE();
+
+ PreviousMode = KeGetPreviousMode();
+
+ CapturedByteOffset.QuadPart = 0;
+ CapturedLength.QuadPart = 0;
/* Get File Object */
Status = ObReferenceObjectByHandle(FileHandle,
&HandleInformation);
if (!NT_SUCCESS(Status)) return Status;
- /* Must have FILE_READ_DATA | FILE_WRITE_DATA access */
- if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
+ if (PreviousMode != KernelMode)
{
- DPRINT1("Invalid access rights\n");
- ObDereferenceObject(FileObject);
- return STATUS_ACCESS_DENIED;
+ /* Must have either FILE_READ_DATA or FILE_WRITE_DATA access unless
+ we're in KernelMode! */
+ if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
+ {
+ DPRINT1("Invalid access rights\n");
+ ObDereferenceObject(FileObject);
+ return STATUS_ACCESS_DENIED;
+ }
+
+ _SEH_TRY
+ {
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
+ CapturedLength = ProbeForReadLargeInteger(Length);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+ }
+ else
+ {
+ CapturedByteOffset = *ByteOffset;
+ CapturedLength = *Length;
}
/* Get Event Object */
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
- *LocalLength = *Length;
+ *LocalLength = CapturedLength;
/* Set up the IRP */
Irp->RequestorMode = PreviousMode;
/* Set Parameters */
StackPtr->Parameters.LockControl.Length = LocalLength;
- StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
- StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
+ StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
+ StackPtr->Parameters.LockControl.Key = Key;
/* Set Flags */
if (FailImmediately) StackPtr->Flags = SL_FAIL_IMMEDIATELY;
}
NTSTATUS
-STDCALL
-NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
- OUT PFILE_BASIC_INFORMATION FileInformation)
+IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN FILE_INFORMATION_CLASS FileInformationClass,
+ OUT PVOID FileInformation)
{
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle;
NTSTATUS Status;
+ KPROCESSOR_MODE AccessMode;
+ UNICODE_STRING ObjectName;
+ OBJECT_CREATE_INFORMATION ObjectCreateInfo;
+ OBJECT_ATTRIBUTES LocalObjectAttributes;
+ ULONG BufferSize;
+ union
+ {
+ FILE_BASIC_INFORMATION BasicInformation;
+ FILE_NETWORK_OPEN_INFORMATION NetworkOpenInformation;
+ }LocalFileInformation;
+
+ if (FileInformationClass == FileBasicInformation)
+ {
+ BufferSize = sizeof(FILE_BASIC_INFORMATION);
+ }
+ else if (FileInformationClass == FileNetworkOpenInformation)
+ {
+ BufferSize = sizeof(FILE_NETWORK_OPEN_INFORMATION);
+ }
+ else
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ AccessMode = ExGetPreviousMode();
+
+ if (AccessMode != KernelMode)
+ {
+ Status = STATUS_SUCCESS;
+ _SEH_TRY
+ {
+ ProbeForWrite(FileInformation,
+ BufferSize,
+ sizeof(ULONG));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ if (NT_SUCCESS(Status))
+ {
+ Status = ObpCaptureObjectAttributes(ObjectAttributes,
+ AccessMode,
+ NULL,
+ &ObjectCreateInfo,
+ &ObjectName);
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ InitializeObjectAttributes(&LocalObjectAttributes,
+ &ObjectName,
+ ObjectCreateInfo.Attributes,
+ ObjectCreateInfo.RootDirectory,
+ ObjectCreateInfo.SecurityDescriptor);
+ }
/* Open the file */
Status = ZwOpenFile(&FileHandle,
SYNCHRONIZE | FILE_READ_ATTRIBUTES,
- ObjectAttributes,
+ AccessMode == KernelMode ? ObjectAttributes : &LocalObjectAttributes,
&IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ 0,
FILE_SYNCHRONOUS_IO_NONALERT);
+ if (AccessMode != KernelMode)
+ {
+ ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+ ExFreePool(ObjectName.Buffer);
+ }
if (!NT_SUCCESS (Status))
{
DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
/* Get file attributes */
Status = ZwQueryInformationFile(FileHandle,
&IoStatusBlock,
- FileInformation,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
+ AccessMode == KernelMode ? FileInformation : &LocalFileInformation,
+ BufferSize,
+ FileInformationClass);
if (!NT_SUCCESS (Status))
{
DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
}
-
ZwClose(FileHandle);
+
+ if (NT_SUCCESS(Status) && AccessMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ memcpy(FileInformation, &LocalFileInformation, BufferSize);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
return Status;
}
+NTSTATUS
+STDCALL
+NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
+ OUT PFILE_BASIC_INFORMATION FileInformation)
+{
+ return IopQueryAttributesFile(ObjectAttributes,
+ FileBasicInformation,
+ FileInformation);
+}
+
+static NTSTATUS NTAPI
+IopQueryDirectoryFileCompletion(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
+{
+ ASSERT (Context);
+
+ DPRINT("IopQueryDirectoryFileCompletion was called for \'%wZ\'\n", Context);
+
+ ExFreePool(Context);
+
+ return STATUS_SUCCESS;
+}
+
+
/*
* @implemented
*
{
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
- PFILE_OBJECT FileObject;
+ PFILE_OBJECT FileObject = NULL;
PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN LocalEvent = FALSE;
PKEVENT Event = NULL;
+ PUNICODE_STRING SearchPattern = NULL;
DPRINT("NtQueryDirectoryFile()\n");
PAGED_CODE();
ProbeForWrite(FileInformation,
Length,
sizeof(ULONG));
+ if (FileName)
+ {
+ UNICODE_STRING CapturedFileName;
+
+ CapturedFileName = ProbeForReadUnicodeString(FileName);
+ ProbeForRead(CapturedFileName.Buffer,
+ CapturedFileName.MaximumLength,
+ 1);
+ SearchPattern = ExAllocatePool(NonPagedPool, CapturedFileName.Length + sizeof(WCHAR) + sizeof(UNICODE_STRING));
+ if (SearchPattern == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ _SEH_LEAVE;
+ }
+ SearchPattern->Buffer = (PWCHAR)((ULONG_PTR)SearchPattern + sizeof(UNICODE_STRING));
+ SearchPattern->MaximumLength = CapturedFileName.Length + sizeof(WCHAR);
+ RtlCopyUnicodeString(SearchPattern, &CapturedFileName);
+ }
}
_SEH_HANDLE
{
}
_SEH_END;
- if(!NT_SUCCESS(Status)) return Status;
+ if(!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
}
/* Get File Object */
PreviousMode,
(PVOID *)&FileObject,
NULL);
- if (Status != STATUS_SUCCESS) return(Status);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
/* Get Event Object */
if (PEvent)
PreviousMode,
(PVOID *)&Event,
NULL);
- if (Status != STATUS_SUCCESS) return(Status);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Cleanup;
+ }
+
KeClearEvent(Event);
}
/* Allocate the IRP */
if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE)))
{
- ObDereferenceObject(FileObject);
- return STATUS_INSUFFICIENT_RESOURCES;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Cleanup;
}
/* Set up the IRP */
/* Set Parameters */
StackPtr->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;
- StackPtr->Parameters.QueryDirectory.FileName = FileName;
+ StackPtr->Parameters.QueryDirectory.FileName = SearchPattern ? SearchPattern : FileName;
StackPtr->Parameters.QueryDirectory.FileIndex = 0;
StackPtr->Parameters.QueryDirectory.Length = Length;
StackPtr->Flags = 0;
if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN;
if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY;
+ if (SearchPattern)
+ {
+ IoSetCompletionRoutine(Irp,
+ IopQueryDirectoryFileCompletion,
+ SearchPattern,
+ TRUE,
+ TRUE,
+ TRUE);
+ }
+
/* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
}
}
+
+ return Status;
+
+Cleanup:
+ if (FileObject != NULL)
+ {
+ ObDereferenceObject(FileObject);
+ }
+ if (Event != NULL)
+ {
+ ObDereferenceObject(Event);
+ }
+ if (SearchPattern != NULL)
+ {
+ ExFreePool(SearchPattern);
+ }
+
/* Return the Status */
return Status;
}
NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
{
- IO_STATUS_BLOCK IoStatusBlock;
- HANDLE FileHandle;
- NTSTATUS Status;
-
- /* Open the file */
- Status = ZwOpenFile(&FileHandle,
- SYNCHRONIZE | FILE_READ_ATTRIBUTES,
- ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS (Status))
- {
- DPRINT ("ZwOpenFile() failed (Status %lx)\n", Status);
- return Status;
- }
-
- /* Get file attributes */
- Status = ZwQueryInformationFile(FileHandle,
- &IoStatusBlock,
- FileInformation,
- sizeof(FILE_NETWORK_OPEN_INFORMATION),
- FileNetworkOpenInformation);
- if (!NT_SUCCESS (Status))
- {
- DPRINT ("ZwQueryInformationFile() failed (Status %lx)\n", Status);
- }
-
- ZwClose (FileHandle);
- return Status;
+ return IopQueryAttributesFile(ObjectAttributes,
+ FileNetworkOpenInformation,
+ FileInformation);
}
/*
ASSERT(IoStatusBlock != NULL);
ASSERT(FileInformation != NULL);
- DPRINT("NtQueryInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
+ DPRINT("NtQueryInformationFile(Handle 0x%p StatBlk 0x%p FileInfo 0x%p Length %d "
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
Length, FileInformationClass);
Failed = TRUE;
break;
- case FileAlignmentInformation:
- if (!(FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING))
- Failed = TRUE;
- break;
-
default:
break;
}
return STATUS_ACCESS_DENIED;
}
- DPRINT("FileObject %x\n", FileObject);
+ if (FileInformationClass == FilePositionInformation)
+ {
+ if (Length < sizeof(FILE_POSITION_INFORMATION))
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ _SEH_TRY
+ {
+ ((PFILE_POSITION_INFORMATION)FileInformation)->CurrentByteOffset = FileObject->CurrentByteOffset;
+ IoStatusBlock->Information = sizeof(FILE_POSITION_INFORMATION);
+ Status = IoStatusBlock->Status = STATUS_SUCCESS;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+
+ DPRINT("FileObject 0x%p\n", FileObject);
/* Check if this is a direct open or not */
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
+ if (FileInformationClass == FileAlignmentInformation)
+ {
+ if (Length < sizeof(FILE_ALIGNMENT_INFORMATION))
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ _SEH_TRY
+ {
+ ((PFILE_ALIGNMENT_INFORMATION)FileInformation)->AlignmentRequirement = DeviceObject->AlignmentRequirement;
+ IoStatusBlock->Information = sizeof(FILE_ALIGNMENT_INFORMATION);
+ Status = IoStatusBlock->Status = STATUS_SUCCESS;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
- IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
+ IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL)
{
NTSTATUS Status = STATUS_SUCCESS;
PIRP Irp = NULL;
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION StackPtr;
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ KPROCESSOR_MODE PreviousMode;
BOOLEAN LocalEvent = FALSE;
PKEVENT EventObject = NULL;
+ LARGE_INTEGER CapturedByteOffset;
- DPRINT("NtReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
- "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
+ DPRINT("NtReadFile(FileHandle 0x%p Buffer 0x%p Length %x ByteOffset 0x%p, "
+ "IoStatusBlock 0x%p)\n", FileHandle, Buffer, Length, ByteOffset,
IoStatusBlock);
+
PAGED_CODE();
+
+ PreviousMode = KeGetPreviousMode();
+ CapturedByteOffset.QuadPart = 0;
/* Validate User-Mode Buffers */
if(PreviousMode != KernelMode)
ProbeForWrite(IoStatusBlock,
sizeof(IO_STATUS_BLOCK),
sizeof(ULONG));
- #if 0
ProbeForWrite(Buffer,
Length,
- sizeof(ULONG));
- #endif
+ 1);
+ if (ByteOffset != NULL)
+ {
+ CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
+ }
+ /* FIXME - probe other pointers and capture information */
}
_SEH_HANDLE
{
if(!NT_SUCCESS(Status)) return Status;
}
+ else
+ {
+ if (ByteOffset != NULL)
+ {
+ CapturedByteOffset = *ByteOffset;
+ }
+ }
/* Get File Object */
Status = ObReferenceObjectByHandle(FileHandle,
if (!NT_SUCCESS(Status)) return Status;
/* Check the Byte Offset */
- if (!ByteOffset ||
- (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
- ByteOffset->u.HighPart == 0xffffffff))
+ if (ByteOffset == NULL ||
+ (CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
+ CapturedByteOffset.u.HighPart == -1))
{
/* a valid ByteOffset is required if asynch. op. */
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
}
/* Use the Current Byte OFfset */
- ByteOffset = &FileObject->CurrentByteOffset;
+ CapturedByteOffset = FileObject->CurrentByteOffset;
}
/* Check for event */
DeviceObject,
Buffer,
Length,
- ByteOffset,
+ &CapturedByteOffset,
EventObject,
IoStatusBlock);
if (Irp == NULL)
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
BOOLEAN Failed = FALSE;
- ASSERT(IoStatusBlock != NULL);
- ASSERT(FileInformation != NULL);
-
- DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
+ DPRINT("NtSetInformationFile(Handle 0x%p StatBlk 0x%p FileInfo 0x%p Length %d "
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
Length, FileInformationClass);
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ if (IoStatusBlock != NULL)
+ {
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ }
+
+ if (Length != 0)
+ {
+ ProbeForRead(FileInformation,
+ Length,
+ 1);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else
+ {
+ ASSERT(IoStatusBlock != NULL);
+ ASSERT(FileInformation != NULL);
+ }
+
/* Get the file object from the file handle */
Status = ObReferenceObjectByHandle(FileHandle,
0,
return STATUS_ACCESS_DENIED;
}
- DPRINT("FileObject %x\n", FileObject);
+ DPRINT("FileObject 0x%p\n", FileObject);
+
+ if (FileInformationClass == FilePositionInformation)
+ {
+ if (Length < sizeof(FILE_POSITION_INFORMATION))
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ _SEH_TRY
+ {
+ FileObject->CurrentByteOffset = ((PFILE_POSITION_INFORMATION)FileInformation)->CurrentByteOffset;
+ IoStatusBlock->Information = 0;
+ Status = IoStatusBlock->Status = STATUS_SUCCESS;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
/* FIXME: Later, we can implement a lot of stuff here and avoid a driver call */
/* Handle IO Completion Port quickly */
PVOID Queue;
PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
PIO_COMPLETION_CONTEXT Context;
-
- if (Length < sizeof(FILE_COMPLETION_INFORMATION))
+
+ if (FileObject->Flags & FO_SYNCHRONOUS_IO || FileObject->CompletionContext != NULL)
{
- Status = STATUS_INFO_LENGTH_MISMATCH;
+ Status = STATUS_INVALID_PARAMETER;
}
else
{
- /* Reference the Port */
- Status = ObReferenceObjectByHandle(CompletionInfo->IoCompletionHandle,
- IO_COMPLETION_MODIFY_STATE,
- IoCompletionType,
- PreviousMode,
- (PVOID*)&Queue,
- NULL);
- if (NT_SUCCESS(Status))
+ if (Length < sizeof(FILE_COMPLETION_INFORMATION))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ else
{
- /* Allocate the Context */
- Context = ExAllocatePoolWithTag(PagedPool,
- sizeof(IO_COMPLETION_CONTEXT),
- TAG('I', 'o', 'C', 'p'));
-
- /* Set the Data */
- Context->Key = CompletionInfo->CompletionKey;
- Context->Port = Queue;
- FileObject->CompletionContext = Context;
-
- /* Dereference the Port now */
- ObDereferenceObject(Queue);
+ /* Reference the Port */
+ Status = ObReferenceObjectByHandle(CompletionInfo->Port, /* FIXME - protect with SEH! */
+ IO_COMPLETION_MODIFY_STATE,
+ IoCompletionType,
+ PreviousMode,
+ (PVOID*)&Queue,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* Allocate the Context */
+ Context = ExAllocatePoolWithTag(PagedPool,
+ sizeof(IO_COMPLETION_CONTEXT),
+ TAG('I', 'o', 'C', 'p'));
+
+ if (Context != NULL)
+ {
+ /* Set the Data */
+ Context->Key = CompletionInfo->Key; /* FIXME - protect with SEH! */
+ Context->Port = Queue;
+
+ if (InterlockedCompareExchangePointer(&FileObject->CompletionContext,
+ Context,
+ NULL) != NULL)
+ {
+ /* someone else set the completion port in the
+ meanwhile, fail */
+ ExFreePool(Context);
+ ObDereferenceObject(Queue);
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ /* Dereference the Port now */
+ ObDereferenceObject(Queue);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
}
}
Length,
TAG_SYSB)))
{
- IoFreeIrp(Irp);
- ObDereferenceObject(FileObject);
- return STATUS_INSUFFICIENT_RESOURCES;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto failfreeirp;
}
/* Copy the data inside */
- MmSafeCopyFromUser(Irp->AssociatedIrp.SystemBuffer, FileInformation, Length);
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ /* no need to probe again */
+ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
+ FileInformation,
+ Length);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer,
+ TAG_SYSB);
+ Irp->AssociatedIrp.SystemBuffer = NULL;
+failfreeirp:
+ IoFreeIrp(Irp);
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+ }
+ else
+ {
+ RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
+ FileInformation,
+ Length);
+ }
/* Set up the IRP */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
- Status = IoStatusBlock->Status;
+ _SEH_TRY
+ {
+ Status = IoStatusBlock->Status;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
}
else
{
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
- Status = FileObject->FinalStatus;
+ _SEH_TRY
+ {
+ Status = FileObject->FinalStatus;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
}
}
STDCALL
NtSetQuotaInformationFile(HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
- PFILE_USER_QUOTA_INFORMATION Buffer,
+ PVOID Buffer,
ULONG BufferLength)
{
UNIMPLEMENTED;
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER ByteOffset,
IN PLARGE_INTEGER Length,
- OUT PULONG Key OPTIONAL)
+ IN ULONG Key OPTIONAL)
{
PFILE_OBJECT FileObject = NULL;
PLARGE_INTEGER LocalLength = NULL;
PDEVICE_OBJECT DeviceObject;
KEVENT Event;
BOOLEAN LocalEvent = FALSE;
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
+ LARGE_INTEGER CapturedByteOffset, CapturedLength;
OBJECT_HANDLE_INFORMATION HandleInformation;
-
- /* FIXME: instead of this, use SEH */
- if (!Length || !ByteOffset) return STATUS_INVALID_PARAMETER;
+
+ PAGED_CODE();
+
+ PreviousMode = KeGetPreviousMode();
+
+ CapturedByteOffset.QuadPart = 0;
+ CapturedLength.QuadPart = 0;
/* Get File Object */
Status = ObReferenceObjectByHandle(FileHandle,
&HandleInformation);
if (!NT_SUCCESS(Status)) return Status;
- /* Must have FILE_READ_DATA | FILE_WRITE_DATA access */
- if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
+ if (PreviousMode != KernelMode)
{
- DPRINT1("Invalid access rights\n");
- ObDereferenceObject(FileObject);
- return STATUS_ACCESS_DENIED;
+ /* Must have either FILE_READ_DATA or FILE_WRITE_DATA access unless we're
+ in KernelMode! */
+ if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_READ_DATA)))
+ {
+ DPRINT1("Invalid access rights\n");
+ ObDereferenceObject(FileObject);
+ return STATUS_ACCESS_DENIED;
+ }
+
+ _SEH_TRY
+ {
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
+ CapturedLength = ProbeForReadLargeInteger(Length);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+ }
+ else
+ {
+ CapturedByteOffset = *ByteOffset;
+ CapturedLength = *Length;
}
/* Check if this is a direct open or not */
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
- *LocalLength = *Length;
+ *LocalLength = CapturedLength;
/* Set up the IRP */
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
/* Set Parameters */
StackPtr->Parameters.LockControl.Length = LocalLength;
- StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
- StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
+ StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
+ StackPtr->Parameters.LockControl.Key = Key;
/* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp);
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
IN PULONG Key OPTIONAL)
{
- OBJECT_HANDLE_INFORMATION HandleInformation;
+ OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
NTSTATUS Status = STATUS_SUCCESS;
PFILE_OBJECT FileObject;
PIRP Irp = NULL;
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION StackPtr;
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ KPROCESSOR_MODE PreviousMode;
BOOLEAN LocalEvent = FALSE;
PKEVENT EventObject = NULL;
+ LARGE_INTEGER CapturedByteOffset;
+ ULONG CapturedKey = 0;
+ ACCESS_MASK DesiredAccess = FILE_WRITE_DATA;
- DPRINT("NtWriteFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
- "IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
+ DPRINT("NtWriteFile(FileHandle 0x%p Buffer 0x%p Length %x ByteOffset 0x%p, "
+ "IoStatusBlock 0x%p)\n", FileHandle, Buffer, Length, ByteOffset,
IoStatusBlock);
+ PAGED_CODE();
+
+ PreviousMode = KeGetPreviousMode();
+ CapturedByteOffset.QuadPart = 0;
+
/* Validate User-Mode Buffers */
if(PreviousMode != KernelMode)
{
_SEH_TRY
{
- #if 0
ProbeForWrite(IoStatusBlock,
sizeof(IO_STATUS_BLOCK),
sizeof(ULONG));
ProbeForRead(Buffer,
Length,
- sizeof(ULONG));
- #endif
+ 1);
+ if (ByteOffset != NULL)
+ {
+ CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
+ }
+
+ if (Key != NULL)
+ {
+ CapturedKey = ProbeForReadUlong(Key);
+ }
}
_SEH_HANDLE
{
if(!NT_SUCCESS(Status)) return Status;
}
+ else
+ {
+ if (ByteOffset != NULL)
+ {
+ CapturedByteOffset = *ByteOffset;
+ }
+ if (Key != NULL)
+ {
+ CapturedKey = *Key;
+ }
+ }
/* Get File Object */
Status = ObReferenceObjectByHandle(FileHandle,
IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
- &HandleInformation);
+ &ObjectHandleInfo);
if (!NT_SUCCESS(Status)) return Status;
- /* Must have FILE_WRITE_DATA | FILE_APPEND_DATA access */
- if (!(HandleInformation.GrantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
+ /* check if the handle has either FILE_WRITE_DATA or FILE_APPEND_DATA was
+ granted. However, if this is a named pipe, make sure we don't ask for
+ FILE_APPEND_DATA as it interferes with the FILE_CREATE_PIPE_INSTANCE
+ access right! */
+ if (!(FileObject->Flags & FO_NAMED_PIPE))
+ DesiredAccess |= FILE_APPEND_DATA;
+ if (!RtlAreAnyAccessesGranted(ObjectHandleInfo.GrantedAccess,
+ DesiredAccess))
{
- DPRINT1("Invalid access rights\n");
ObDereferenceObject(FileObject);
return STATUS_ACCESS_DENIED;
}
/* Check if we got write Access */
- if (HandleInformation.GrantedAccess & FILE_WRITE_DATA)
+ if (ObjectHandleInfo.GrantedAccess & FILE_WRITE_DATA)
{
/* Check the Byte Offset */
- if (!ByteOffset ||
- (ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
- ByteOffset->u.HighPart == 0xffffffff))
+ if (ByteOffset == NULL ||
+ (CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
+ CapturedByteOffset.u.HighPart == -1))
{
/* a valid ByteOffset is required if asynch. op. */
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
}
/* Use the Current Byte OFfset */
- ByteOffset = &FileObject->CurrentByteOffset;
+ CapturedByteOffset = FileObject->CurrentByteOffset;
}
}
- else if (HandleInformation.GrantedAccess & FILE_APPEND_DATA)
+ else if ((ObjectHandleInfo.GrantedAccess & FILE_APPEND_DATA) &&
+ !(FileObject->Flags & FO_NAMED_PIPE))
{
/* a valid ByteOffset is required if asynch. op. */
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
}
/* Give the drivers somethign to understand */
- ByteOffset->u.LowPart = FILE_WRITE_TO_END_OF_FILE;
- ByteOffset->u.HighPart = 0xffffffff;
+ CapturedByteOffset.u.LowPart = FILE_WRITE_TO_END_OF_FILE;
+ CapturedByteOffset.u.HighPart = 0xffffffff;
}
/* Check if we got an event */
DeviceObject,
Buffer,
Length,
- ByteOffset,
+ &CapturedByteOffset,
EventObject,
IoStatusBlock);
if (Irp == NULL)
/* Setup Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
- StackPtr->Parameters.Write.Key = Key ? *Key : 0;
+ StackPtr->Parameters.Write.Key = CapturedKey;
if (FileObject->Flags & FO_WRITE_THROUGH) StackPtr->Flags = SL_WRITE_THROUGH;
/* Call the Driver */