mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 19:23:50 +08: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
@ -152,16 +152,16 @@ CdfsGetNameInformation(PFILE_OBJECT FileObject,
|
||||
ASSERT(Fcb != NULL);
|
||||
|
||||
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;
|
||||
|
||||
NameInfo->FileNameLength = NameLength;
|
||||
RtlCopyMemory(NameInfo->FileName,
|
||||
Fcb->PathName,
|
||||
NameLength + sizeof(WCHAR));
|
||||
|
||||
*BufferLength -=
|
||||
(sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
|
||||
(FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + NameLength);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -9,10 +9,7 @@
|
||||
// Failure to respect this will *ACHIEVE NOTHING*.
|
||||
//
|
||||
// Io:
|
||||
// - Fix double-reference in IopCreateFile.
|
||||
// - 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 a generic Cleanup/Exception Routine (iofunc).
|
||||
// - Add another parameter to IopCleanupFailedIrp.
|
||||
|
@ -69,7 +69,12 @@ IopParseDevice(IN PVOID ParseObject,
|
||||
|
||||
/* Reference the DO */
|
||||
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 */
|
||||
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 */
|
||||
if (!UseDummyFile)
|
||||
{
|
||||
@ -153,6 +237,21 @@ IopParseDevice(IN PVOID ParseObject,
|
||||
0,
|
||||
0,
|
||||
(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));
|
||||
|
||||
/* 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 */
|
||||
if (OpenPacket->CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)
|
||||
{
|
||||
@ -226,95 +332,10 @@ IopParseDevice(IN PVOID ParseObject,
|
||||
FileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
|
||||
}
|
||||
|
||||
/* Setup the security context */
|
||||
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 */
|
||||
/* Now set the file object */
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
if (RemainingName->Length)
|
||||
{
|
||||
@ -347,9 +368,6 @@ IopParseDevice(IN PVOID ParseObject,
|
||||
/* Copy the name */
|
||||
RtlCopyUnicodeString(&FileObject->FileName, RemainingName);
|
||||
|
||||
/* Reference the file object */
|
||||
ObReferenceObject(FileObject);
|
||||
|
||||
/* Initialize the File Object event and set the FO */
|
||||
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
|
||||
OpenPacket->FileObject = FileObject;
|
||||
@ -373,6 +391,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||
{
|
||||
/* We'll have to complete it ourselves */
|
||||
ASSERT(!Irp->PendingReturned);
|
||||
ASSERT(!Irp->MdlAddress );
|
||||
|
||||
/* Completion happens at APC_LEVEL */
|
||||
KeRaiseIrql(APC_LEVEL, &OldIrql);
|
||||
@ -385,8 +404,8 @@ IopParseDevice(IN PVOID ParseObject,
|
||||
FileObject->Event.Header.SignalState = 1;
|
||||
|
||||
/* Now that we've signaled the events, de-associate the IRP */
|
||||
RemoveEntryList(&Irp->ThreadListEntry);
|
||||
InitializeListHead(&Irp->ThreadListEntry);
|
||||
//RemoveEntryList(&Irp->ThreadListEntry);
|
||||
//InitializeListHead(&Irp->ThreadListEntry);
|
||||
|
||||
/* Check if the IRP had an input buffer */
|
||||
if ((Irp->Flags & IRP_BUFFERED_IO) &&
|
||||
|
@ -2159,7 +2159,7 @@ NtSetInformationFile(IN HANDLE FileHandle,
|
||||
if (LocalEvent)
|
||||
{
|
||||
/* Then to a non-alertable wait */
|
||||
Status = KeWaitForSingleObject(&Event,
|
||||
Status = KeWaitForSingleObject(Event,
|
||||
Executive,
|
||||
PreviousMode,
|
||||
FALSE,
|
||||
|
@ -155,7 +155,8 @@ MmspCompleteAndReleasePageOp(PMM_PAGEOP PageOp)
|
||||
static NTSTATUS
|
||||
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);
|
||||
if (Segment == NULL)
|
||||
{
|
||||
KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
||||
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
||||
ObDereferenceObject(Section);
|
||||
ObDereferenceObject(FileObject);
|
||||
return(STATUS_NO_MEMORY);
|
||||
@ -2531,7 +2532,7 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
|
||||
Section->FileObject = FileObject;
|
||||
Section->MaximumSize = MaximumSize;
|
||||
CcRosReferenceCache(FileObject);
|
||||
KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
||||
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
||||
*SectionObject = Section;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
@ -3362,7 +3363,7 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
|
||||
}
|
||||
Section->FileObject = FileObject;
|
||||
CcRosReferenceCache(FileObject);
|
||||
KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
||||
//KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
|
||||
*SectionObject = Section;
|
||||
return(Status);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user