mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +00:00
- Mega whammy jammy fix commit:
- Fix bootcd by fixing some bugs in CDFS (same as in VFAT). - Fix Broken Installers and other I/O programs that couldn't, for example, create temporary directories. - Fix Firefox installers and other apps crashing due to a bug in NtSetInformationFile. - Fix File Objects being referenced twice resulting in IRP_MJ_CLOSE/CLEANUP never being sent and several memory leaks. - Fix File Object Lock being incorrectly created and then misused by mm/section code. - Fix creation of File Object before setting up the IRP, to properly cleanup during failures. - Add failure code if ObCreateObject fails. svn path=/trunk/; revision=23328
This commit is contained in:
parent
27f7e69bf7
commit
3d97c16cd1
5 changed files with 120 additions and 103 deletions
|
@ -152,16 +152,16 @@ CdfsGetNameInformation(PFILE_OBJECT FileObject,
|
||||||
ASSERT(Fcb != NULL);
|
ASSERT(Fcb != NULL);
|
||||||
|
|
||||||
NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
|
NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
|
||||||
if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
|
NameInfo->FileNameLength = NameLength;
|
||||||
|
if (*BufferLength < (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + NameLength))
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
NameInfo->FileNameLength = NameLength;
|
|
||||||
RtlCopyMemory(NameInfo->FileName,
|
RtlCopyMemory(NameInfo->FileName,
|
||||||
Fcb->PathName,
|
Fcb->PathName,
|
||||||
NameLength + sizeof(WCHAR));
|
NameLength + sizeof(WCHAR));
|
||||||
|
|
||||||
*BufferLength -=
|
*BufferLength -=
|
||||||
(sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
|
(FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + NameLength);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,7 @@
|
||||||
// Failure to respect this will *ACHIEVE NOTHING*.
|
// Failure to respect this will *ACHIEVE NOTHING*.
|
||||||
//
|
//
|
||||||
// Io:
|
// Io:
|
||||||
// - Fix double-reference in IopCreateFile.
|
|
||||||
// - See why queueing IRPs and cancelling them causes crashes.
|
// - See why queueing IRPs and cancelling them causes crashes.
|
||||||
// - Find out why 7zip can't create temporary folders due to deferred I/O
|
|
||||||
// completion in IopParseDevice when creating a new File Object.
|
|
||||||
// - Add SEH to some places where it's missing (MDLs, etc) (iofunc).
|
// - Add SEH to some places where it's missing (MDLs, etc) (iofunc).
|
||||||
// - Add a generic Cleanup/Exception Routine (iofunc).
|
// - Add a generic Cleanup/Exception Routine (iofunc).
|
||||||
// - Add another parameter to IopCleanupFailedIrp.
|
// - Add another parameter to IopCleanupFailedIrp.
|
||||||
|
|
|
@ -69,7 +69,12 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
|
|
||||||
/* Reference the DO */
|
/* Reference the DO */
|
||||||
Status = IopReferenceDeviceObject(OriginalDeviceObject);
|
Status = IopReferenceDeviceObject(OriginalDeviceObject);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* We failed, return status */
|
||||||
|
OpenPacket->FinalStatus = Status;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Map the generic mask and set the new mapping in the access state */
|
/* Map the generic mask and set the new mapping in the access state */
|
||||||
RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
|
RtlMapGenericMask(&AccessState->RemainingDesiredAccess,
|
||||||
|
@ -135,6 +140,85 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate the IRP */
|
||||||
|
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
/* Dereference the device and VPB, then fail */
|
||||||
|
IopDereferenceDeviceObject(DeviceObject, FALSE);
|
||||||
|
if (Vpb) IopDereferenceVpb(Vpb);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now set the IRP data */
|
||||||
|
Irp->RequestorMode = AccessMode;
|
||||||
|
Irp->Flags = IRP_CREATE_OPERATION |
|
||||||
|
IRP_SYNCHRONOUS_API |
|
||||||
|
IRP_DEFER_IO_COMPLETION;
|
||||||
|
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||||
|
Irp->UserIosb = &IoStatusBlock;
|
||||||
|
Irp->MdlAddress = NULL;
|
||||||
|
Irp->PendingReturned = FALSE;
|
||||||
|
Irp->UserEvent = NULL;
|
||||||
|
Irp->Cancel = FALSE;
|
||||||
|
Irp->CancelRoutine = NULL;
|
||||||
|
Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
|
||||||
|
|
||||||
|
/* Setup the security context */
|
||||||
|
SecurityContext.SecurityQos = SecurityQos;
|
||||||
|
SecurityContext.AccessState = AccessState;
|
||||||
|
SecurityContext.DesiredAccess = AccessState->RemainingDesiredAccess;
|
||||||
|
SecurityContext.FullCreateOptions = OpenPacket->CreateOptions;
|
||||||
|
|
||||||
|
/* Get the I/O Stack location */
|
||||||
|
StackLoc = (PEXTENDED_IO_STACK_LOCATION)IoGetNextIrpStackLocation(Irp);
|
||||||
|
StackLoc->Control = 0;
|
||||||
|
|
||||||
|
/* Check what kind of file this is */
|
||||||
|
switch (OpenPacket->CreateFileType)
|
||||||
|
{
|
||||||
|
/* Normal file */
|
||||||
|
case CreateFileTypeNone:
|
||||||
|
|
||||||
|
/* Set the major function and EA Length */
|
||||||
|
StackLoc->MajorFunction = IRP_MJ_CREATE;
|
||||||
|
StackLoc->Parameters.Create.EaLength = OpenPacket->EaLength;
|
||||||
|
|
||||||
|
/* Set the flags */
|
||||||
|
StackLoc->Flags = OpenPacket->Options;
|
||||||
|
StackLoc->Flags |= !(Attributes & OBJ_CASE_INSENSITIVE) ?
|
||||||
|
SL_CASE_SENSITIVE: 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Named pipe */
|
||||||
|
case CreateFileTypeNamedPipe:
|
||||||
|
|
||||||
|
/* Set the named pipe MJ and set the parameters */
|
||||||
|
StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
|
||||||
|
StackLoc->Parameters.CreatePipe.Parameters =
|
||||||
|
OpenPacket->MailslotOrPipeParameters;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Mailslot */
|
||||||
|
case CreateFileTypeMailslot:
|
||||||
|
|
||||||
|
/* Set the mailslot MJ and set the parameters */
|
||||||
|
StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
|
||||||
|
StackLoc->Parameters.CreateMailslot.Parameters =
|
||||||
|
OpenPacket->MailslotOrPipeParameters;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the common data */
|
||||||
|
Irp->Overlay.AllocationSize = OpenPacket->AllocationSize;
|
||||||
|
Irp->AssociatedIrp.SystemBuffer = OpenPacket->EaBuffer;
|
||||||
|
StackLoc->Parameters.Create.Options = (OpenPacket->Disposition << 24) |
|
||||||
|
(OpenPacket->CreateOptions &
|
||||||
|
0xFFFFFF);
|
||||||
|
StackLoc->Parameters.Create.FileAttributes = OpenPacket->FileAttributes;
|
||||||
|
StackLoc->Parameters.Create.ShareAccess = OpenPacket->ShareAccess;
|
||||||
|
StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
|
||||||
|
|
||||||
/* Check if we really need to create an object */
|
/* Check if we really need to create an object */
|
||||||
if (!UseDummyFile)
|
if (!UseDummyFile)
|
||||||
{
|
{
|
||||||
|
@ -153,6 +237,21 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&FileObject);
|
(PVOID*)&FileObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Create failed, free the IRP */
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
|
||||||
|
/* Dereference the device and VPB */
|
||||||
|
IopDereferenceDeviceObject(DeviceObject, FALSE);
|
||||||
|
if (Vpb) IopDereferenceVpb(Vpb);
|
||||||
|
|
||||||
|
/* We failed, return status */
|
||||||
|
OpenPacket->FinalStatus = Status;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the file object */
|
||||||
RtlZeroMemory(FileObject, sizeof(FILE_OBJECT));
|
RtlZeroMemory(FileObject, sizeof(FILE_OBJECT));
|
||||||
|
|
||||||
/* Check if this is Synch I/O */
|
/* Check if this is Synch I/O */
|
||||||
|
@ -170,6 +269,13 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if this is synch I/O */
|
||||||
|
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
||||||
|
{
|
||||||
|
/* Initialize the event. FIXME: Should be FALSE */
|
||||||
|
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if the caller requested no intermediate buffering */
|
/* Check if the caller requested no intermediate buffering */
|
||||||
if (OpenPacket->CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)
|
if (OpenPacket->CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)
|
||||||
{
|
{
|
||||||
|
@ -226,95 +332,10 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
FileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
|
FileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup the security context */
|
/* Now set the file object */
|
||||||
SecurityContext.SecurityQos = SecurityQos;
|
|
||||||
SecurityContext.AccessState = AccessState;
|
|
||||||
SecurityContext.DesiredAccess = AccessState->RemainingDesiredAccess;
|
|
||||||
SecurityContext.FullCreateOptions = OpenPacket->CreateOptions;
|
|
||||||
|
|
||||||
/* Check if this is synch I/O */
|
|
||||||
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
|
||||||
{
|
|
||||||
/* Initialize the event */
|
|
||||||
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate the IRP */
|
|
||||||
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
/* Dereference the device and VPB, then fail */
|
|
||||||
IopDereferenceDeviceObject(DeviceObject, FALSE);
|
|
||||||
if (Vpb) IopDereferenceVpb(Vpb);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now set the IRP data */
|
|
||||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||||
Irp->RequestorMode = AccessMode;
|
|
||||||
Irp->Flags = IRP_CREATE_OPERATION |
|
|
||||||
IRP_SYNCHRONOUS_API |
|
|
||||||
IRP_DEFER_IO_COMPLETION;
|
|
||||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
|
||||||
Irp->UserEvent = &FileObject->Event;
|
|
||||||
Irp->UserIosb = &IoStatusBlock;
|
|
||||||
Irp->MdlAddress = NULL;
|
|
||||||
Irp->PendingReturned = FALSE;
|
|
||||||
Irp->UserEvent = NULL;
|
|
||||||
Irp->Cancel = FALSE;
|
|
||||||
Irp->CancelRoutine = NULL;
|
|
||||||
Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
|
|
||||||
|
|
||||||
/* Get the I/O Stack location */
|
|
||||||
StackLoc = (PEXTENDED_IO_STACK_LOCATION)IoGetNextIrpStackLocation(Irp);
|
|
||||||
StackLoc->Control = 0;
|
|
||||||
StackLoc->FileObject = FileObject;
|
StackLoc->FileObject = FileObject;
|
||||||
|
|
||||||
/* Check what kind of file this is */
|
|
||||||
switch (OpenPacket->CreateFileType)
|
|
||||||
{
|
|
||||||
/* Normal file */
|
|
||||||
case CreateFileTypeNone:
|
|
||||||
|
|
||||||
/* Set the major function and EA Length */
|
|
||||||
StackLoc->MajorFunction = IRP_MJ_CREATE;
|
|
||||||
StackLoc->Parameters.Create.EaLength = OpenPacket->EaLength;
|
|
||||||
|
|
||||||
/* Set the flags */
|
|
||||||
StackLoc->Flags = OpenPacket->Options;
|
|
||||||
StackLoc->Flags |= !(Attributes & OBJ_CASE_INSENSITIVE) ?
|
|
||||||
SL_CASE_SENSITIVE: 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Named pipe */
|
|
||||||
case CreateFileTypeNamedPipe:
|
|
||||||
|
|
||||||
/* Set the named pipe MJ and set the parameters */
|
|
||||||
StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
|
|
||||||
StackLoc->Parameters.CreatePipe.Parameters =
|
|
||||||
OpenPacket->MailslotOrPipeParameters;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Mailslot */
|
|
||||||
case CreateFileTypeMailslot:
|
|
||||||
|
|
||||||
/* Set the mailslot MJ and set the parameters */
|
|
||||||
StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
|
|
||||||
StackLoc->Parameters.CreateMailslot.Parameters =
|
|
||||||
OpenPacket->MailslotOrPipeParameters;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the common data */
|
|
||||||
Irp->Overlay.AllocationSize = OpenPacket->AllocationSize;
|
|
||||||
Irp->AssociatedIrp.SystemBuffer =OpenPacket->EaBuffer;
|
|
||||||
StackLoc->Parameters.Create.Options = (OpenPacket->Disposition << 24) |
|
|
||||||
(OpenPacket->CreateOptions &
|
|
||||||
0xFFFFFF);
|
|
||||||
StackLoc->Parameters.Create.FileAttributes = OpenPacket->FileAttributes;
|
|
||||||
StackLoc->Parameters.Create.ShareAccess = OpenPacket->ShareAccess;
|
|
||||||
StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
|
|
||||||
|
|
||||||
/* Check if the file object has a name */
|
/* Check if the file object has a name */
|
||||||
if (RemainingName->Length)
|
if (RemainingName->Length)
|
||||||
{
|
{
|
||||||
|
@ -347,9 +368,6 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
/* Copy the name */
|
/* Copy the name */
|
||||||
RtlCopyUnicodeString(&FileObject->FileName, RemainingName);
|
RtlCopyUnicodeString(&FileObject->FileName, RemainingName);
|
||||||
|
|
||||||
/* Reference the file object */
|
|
||||||
ObReferenceObject(FileObject);
|
|
||||||
|
|
||||||
/* Initialize the File Object event and set the FO */
|
/* Initialize the File Object event and set the FO */
|
||||||
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
|
||||||
OpenPacket->FileObject = FileObject;
|
OpenPacket->FileObject = FileObject;
|
||||||
|
@ -373,6 +391,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
{
|
{
|
||||||
/* We'll have to complete it ourselves */
|
/* We'll have to complete it ourselves */
|
||||||
ASSERT(!Irp->PendingReturned);
|
ASSERT(!Irp->PendingReturned);
|
||||||
|
ASSERT(!Irp->MdlAddress );
|
||||||
|
|
||||||
/* Completion happens at APC_LEVEL */
|
/* Completion happens at APC_LEVEL */
|
||||||
KeRaiseIrql(APC_LEVEL, &OldIrql);
|
KeRaiseIrql(APC_LEVEL, &OldIrql);
|
||||||
|
@ -385,8 +404,8 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
FileObject->Event.Header.SignalState = 1;
|
FileObject->Event.Header.SignalState = 1;
|
||||||
|
|
||||||
/* Now that we've signaled the events, de-associate the IRP */
|
/* Now that we've signaled the events, de-associate the IRP */
|
||||||
RemoveEntryList(&Irp->ThreadListEntry);
|
//RemoveEntryList(&Irp->ThreadListEntry);
|
||||||
InitializeListHead(&Irp->ThreadListEntry);
|
//InitializeListHead(&Irp->ThreadListEntry);
|
||||||
|
|
||||||
/* Check if the IRP had an input buffer */
|
/* Check if the IRP had an input buffer */
|
||||||
if ((Irp->Flags & IRP_BUFFERED_IO) &&
|
if ((Irp->Flags & IRP_BUFFERED_IO) &&
|
||||||
|
|
|
@ -2159,7 +2159,7 @@ NtSetInformationFile(IN HANDLE FileHandle,
|
||||||
if (LocalEvent)
|
if (LocalEvent)
|
||||||
{
|
{
|
||||||
/* Then to a non-alertable wait */
|
/* Then to a non-alertable wait */
|
||||||
Status = KeWaitForSingleObject(&Event,
|
Status = KeWaitForSingleObject(Event,
|
||||||
Executive,
|
Executive,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
|
|
@ -155,7 +155,8 @@ MmspCompleteAndReleasePageOp(PMM_PAGEOP PageOp)
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
MmspWaitForFileLock(PFILE_OBJECT File)
|
MmspWaitForFileLock(PFILE_OBJECT File)
|
||||||
{
|
{
|
||||||
return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL);
|
return STATUS_SUCCESS;
|
||||||
|
//return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2476,7 +2477,7 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
|
||||||
TAG_MM_SECTION_SEGMENT);
|
TAG_MM_SECTION_SEGMENT);
|
||||||
if (Segment == NULL)
|
if (Segment == NULL)
|
||||||
{
|
{
|
||||||
KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
||||||
ObDereferenceObject(Section);
|
ObDereferenceObject(Section);
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
return(STATUS_NO_MEMORY);
|
return(STATUS_NO_MEMORY);
|
||||||
|
@ -2531,7 +2532,7 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
|
||||||
Section->FileObject = FileObject;
|
Section->FileObject = FileObject;
|
||||||
Section->MaximumSize = MaximumSize;
|
Section->MaximumSize = MaximumSize;
|
||||||
CcRosReferenceCache(FileObject);
|
CcRosReferenceCache(FileObject);
|
||||||
KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
||||||
*SectionObject = Section;
|
*SectionObject = Section;
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -3362,7 +3363,7 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
|
||||||
}
|
}
|
||||||
Section->FileObject = FileObject;
|
Section->FileObject = FileObject;
|
||||||
CcRosReferenceCache(FileObject);
|
CcRosReferenceCache(FileObject);
|
||||||
KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
||||||
*SectionObject = Section;
|
*SectionObject = Section;
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue