- 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:
Alex Ionescu 2006-07-27 22:26:40 +00:00
parent 27f7e69bf7
commit 3d97c16cd1
5 changed files with 120 additions and 103 deletions

View file

@ -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;
} }

View file

@ -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.

View file

@ -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) &&

View file

@ -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,

View file

@ -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);
} }