[CLASSPNP]

- Make srb volatile, since it's assigned inside SEH and referenced in finally
[NTOSKRNL]
- FsRtlTeardownPerStreamContexts: make IsMutexLocked volatile (SEH)
- IoCreateFile: Make SystemEaBuffer volatile (SEH), save status and information in the caller's IoStatusBlock, cleanup and fail when IoCheckEaBufferValidity failed with PreviousMode == KernelMode, too.
- NtLockFile: Move ExAllocatePoolWithTag out of the SEH block. ExAllocatePoolWithTag does not raise an exception by default (unlike ExAllocatePoolWithQuotaTag). Get rid of this SEH block completely and check the return value instead.
- NtQueryDirectoryFile: make AuxBuffer volatile (SEH), again move ExAllocatePoolWithTag out of the SEH block and check return value instead.
IopCaptureUnicodeString: Make Name volatile (SEH)

svn path=/trunk/; revision=57437
This commit is contained in:
Timo Kreuzer 2012-09-29 22:44:48 +00:00
parent 1692f61539
commit db7101e3ed
5 changed files with 65 additions and 84 deletions

View file

@ -444,8 +444,8 @@ ClasspCleanupDisableMcn(
#if 1 #if 1
/* /*
* BUGBUG REMOVE this old function implementation as soon as the * BUGBUG REMOVE this old function implementation as soon as the
* boottime pagefile problems with the new one (below) * boottime pagefile problems with the new one (below)
* are resolved. * are resolved.
*/ */
NTSTATUS NTSTATUS
@ -460,10 +460,10 @@ ClasspEjectionControl(
PFUNCTIONAL_DEVICE_EXTENSION FdoExtension = Fdo->DeviceExtension; PFUNCTIONAL_DEVICE_EXTENSION FdoExtension = Fdo->DeviceExtension;
PCOMMON_DEVICE_EXTENSION commonExtension = PCOMMON_DEVICE_EXTENSION commonExtension =
(PCOMMON_DEVICE_EXTENSION) FdoExtension; (PCOMMON_DEVICE_EXTENSION) FdoExtension;
PFILE_OBJECT_EXTENSION fsContext = NULL; PFILE_OBJECT_EXTENSION fsContext = NULL;
NTSTATUS status; NTSTATUS status;
PSCSI_REQUEST_BLOCK srb = NULL; volatile PSCSI_REQUEST_BLOCK srb = NULL;
BOOLEAN countChanged = FALSE; BOOLEAN countChanged = FALSE;
PAGED_CODE(); PAGED_CODE();
@ -508,7 +508,7 @@ ClasspEjectionControl(
// //
if(LockType == SecureMediaLock) { if(LockType == SecureMediaLock) {
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT fileObject = irpStack->FileObject; PFILE_OBJECT fileObject = irpStack->FileObject;
@ -563,7 +563,7 @@ ClasspEjectionControl(
break; break;
} }
} }
} else { } else {
// //
@ -621,25 +621,25 @@ ClasspEjectionControl(
srb->CdbLength = 6; srb->CdbLength = 6;
cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL; cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
// //
// TRUE - prevent media removal. // TRUE - prevent media removal.
// FALSE - allow media removal. // FALSE - allow media removal.
// //
cdb->MEDIA_REMOVAL.Prevent = Lock; cdb->MEDIA_REMOVAL.Prevent = Lock;
// //
// Set timeout value. // Set timeout value.
// //
srb->TimeOutValue = FdoExtension->TimeOutValue; srb->TimeOutValue = FdoExtension->TimeOutValue;
// //
// The actual lock operation on the device isn't so important // The actual lock operation on the device isn't so important
// as the internal lock counts. Ignore failures. // as the internal lock counts. Ignore failures.
// //
status = ClassSendSrbSynchronous(FdoExtension->DeviceObject, status = ClassSendSrbSynchronous(FdoExtension->DeviceObject,
srb, srb,
NULL, NULL,
@ -653,7 +653,7 @@ ClasspEjectionControl(
DebugPrint((2, DebugPrint((2,
"ClasspEjectionControl: FAILED status %x -- " "ClasspEjectionControl: FAILED status %x -- "
"reverting lock counts\n", status)); "reverting lock counts\n", status));
if (countChanged) { if (countChanged) {
// //
@ -662,7 +662,7 @@ ClasspEjectionControl(
// //
if(Lock) { if(Lock) {
switch(LockType) { switch(LockType) {
case SimpleMediaLock: { case SimpleMediaLock: {
@ -755,9 +755,9 @@ ClasspEjectionControl(
BOOLEAN fileHandleOk = TRUE; BOOLEAN fileHandleOk = TRUE;
BOOLEAN countChanged = FALSE; BOOLEAN countChanged = FALSE;
NTSTATUS status; NTSTATUS status;
PAGED_CODE(); PAGED_CODE();
status = KeWaitForSingleObject( status = KeWaitForSingleObject(
&fdoExt->EjectSynchronizationEvent, &fdoExt->EjectSynchronizationEvent,
UserRequest, UserRequest,
@ -803,7 +803,7 @@ ClasspEjectionControl(
fdoExt->LockCount++; fdoExt->LockCount++;
countChanged = TRUE; countChanged = TRUE;
break; break;
case SecureMediaLock: case SecureMediaLock:
fsContext->LockCount++; fsContext->LockCount++;
fdoExt->ProtectedLockCount++; fdoExt->ProtectedLockCount++;
countChanged = TRUE; countChanged = TRUE;
@ -813,14 +813,14 @@ ClasspEjectionControl(
countChanged = TRUE; countChanged = TRUE;
break; break;
} }
} }
else { else {
/* /*
* This is an unlock command. If it's a secured one then make sure * This is an unlock command. If it's a secured one then make sure
* the caller has a lock outstanding or return an error. * the caller has a lock outstanding or return an error.
*/ */
switch (LockType){ switch (LockType){
case SimpleMediaLock: case SimpleMediaLock:
if (fdoExt->LockCount > 0){ if (fdoExt->LockCount > 0){
fdoExt->LockCount--; fdoExt->LockCount--;
countChanged = TRUE; countChanged = TRUE;
@ -859,7 +859,7 @@ ClasspEjectionControl(
(fdoExt->ProtectedLockCount || (fdoExt->ProtectedLockCount ||
fdoExt->InternalLockCount || fdoExt->InternalLockCount ||
fdoExt->LockCount)){ fdoExt->LockCount)){
/* /*
* The lock count is still positive, so don't unlock yet. * The lock count is still positive, so don't unlock yet.
*/ */
@ -873,14 +873,14 @@ ClasspEjectionControl(
} }
else { else {
TRANSFER_PACKET *pkt; TRANSFER_PACKET *pkt;
pkt = DequeueFreeTransferPacket(Fdo, TRUE); pkt = DequeueFreeTransferPacket(Fdo, TRUE);
if (pkt){ if (pkt){
KEVENT event; KEVENT event;
/* /*
* Store the number of packets servicing the irp (one) * Store the number of packets servicing the irp (one)
* inside the original IRP. It will be used to counted down * inside the original IRP. It will be used to counted down
* to zero when the packet completes. * to zero when the packet completes.
* Initialize the original IRP's status to success. * Initialize the original IRP's status to success.
* If the packet fails, we will set it to the error status. * If the packet fails, we will set it to the error status.
@ -893,10 +893,10 @@ ClasspEjectionControl(
* and wait for the packet to complete. The result * and wait for the packet to complete. The result
* status will be written to the original irp. * status will be written to the original irp.
*/ */
KeInitializeEvent(&event, SynchronizationEvent, FALSE); KeInitializeEvent(&event, SynchronizationEvent, FALSE);
SetupEjectionTransferPacket(pkt, Lock, &event, Irp); SetupEjectionTransferPacket(pkt, Lock, &event, Irp);
SubmitTransferPacket(pkt); SubmitTransferPacket(pkt);
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = Irp->IoStatus.Status; status = Irp->IoStatus.Status;
} }
else { else {
@ -961,7 +961,7 @@ ClasspEjectionControl(
} }
KeSetEvent(&fdoExt->EjectSynchronizationEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&fdoExt->EjectSynchronizationEvent, IO_NO_INCREMENT, FALSE);
return status; return status;

View file

@ -368,7 +368,7 @@ NTAPI
FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader) FsRtlTeardownPerStreamContexts(IN PFSRTL_ADVANCED_FCB_HEADER AdvFcbHeader)
{ {
PLIST_ENTRY NextEntry; PLIST_ENTRY NextEntry;
BOOLEAN IsMutexLocked = FALSE; volatile BOOLEAN IsMutexLocked = FALSE;
PFSRTL_PER_STREAM_CONTEXT PerStreamContext; PFSRTL_PER_STREAM_CONTEXT PerStreamContext;
_SEH2_TRY _SEH2_TRY

View file

@ -1700,8 +1700,8 @@ IoCreateFile(OUT PHANDLE FileHandle,
KPROCESSOR_MODE AccessMode; KPROCESSOR_MODE AccessMode;
HANDLE LocalHandle = 0; HANDLE LocalHandle = 0;
LARGE_INTEGER SafeAllocationSize; LARGE_INTEGER SafeAllocationSize;
PVOID SystemEaBuffer = NULL; volatile PVOID SystemEaBuffer = NULL;
NTSTATUS Status; NTSTATUS Status = STATUS_SUCCESS;
OPEN_PACKET OpenPacket; OPEN_PACKET OpenPacket;
ULONG EaErrorOffset; ULONG EaErrorOffset;
@ -1738,9 +1738,7 @@ IoCreateFile(OUT PHANDLE FileHandle,
if ((EaBuffer) && (EaLength)) if ((EaBuffer) && (EaLength))
{ {
ProbeForRead(EaBuffer, ProbeForRead(EaBuffer, EaLength, sizeof(ULONG));
EaLength,
sizeof(ULONG));
/* marshal EaBuffer */ /* marshal EaBuffer */
SystemEaBuffer = ExAllocatePoolWithTag(NonPagedPool, SystemEaBuffer = ExAllocatePoolWithTag(NonPagedPool,
@ -1757,24 +1755,14 @@ IoCreateFile(OUT PHANDLE FileHandle,
Status = IoCheckEaBufferValidity(SystemEaBuffer, Status = IoCheckEaBufferValidity(SystemEaBuffer,
EaLength, EaLength,
&EaErrorOffset); &EaErrorOffset);
if (!NT_SUCCESS(Status)) IoStatusBlock->Status = Status;
{ IoStatusBlock->Information = EaErrorOffset;
DPRINT1("FIXME: IoCheckEaBufferValidity() failed with "
"Status: %lx\n",Status);
/* Free EA Buffer and return the error */
ExFreePoolWithTag(SystemEaBuffer, TAG_EA);
_SEH2_YIELD(return Status);
}
} }
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
/* Free SystemEaBuffer if needed */
if (SystemEaBuffer) ExFreePoolWithTag(SystemEaBuffer, TAG_EA);
/* Return the exception code */ /* Return the exception code */
_SEH2_YIELD(return _SEH2_GetExceptionCode()); Status = _SEH2_GetExceptionCode();
} }
_SEH2_END; _SEH2_END;
} }
@ -1816,14 +1804,21 @@ IoCreateFile(OUT PHANDLE FileHandle,
Status = IoCheckEaBufferValidity(SystemEaBuffer, Status = IoCheckEaBufferValidity(SystemEaBuffer,
EaLength, EaLength,
&EaErrorOffset); &EaErrorOffset);
if (!NT_SUCCESS(Status)) IoStatusBlock->Status = Status;
{ IoStatusBlock->Information = EaErrorOffset;
DPRINT1("FIXME: IoCheckEaBufferValidity() failed with "
"Status: %lx\n",Status);
}
} }
} }
if (!NT_SUCCESS(Status))
{
DPRINT1("FIXME: IoCheckEaBufferValidity() failed with Status: %lx\n",
Status);
/* Free SystemEaBuffer if needed and return the error */
if (SystemEaBuffer) ExFreePoolWithTag(SystemEaBuffer, TAG_EA);
return Status;
}
/* Setup the Open Packet */ /* Setup the Open Packet */
RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET)); RtlZeroMemory(&OpenPacket, sizeof(OPEN_PACKET));
OpenPacket.Type = IO_TYPE_OPEN_PACKET; OpenPacket.Type = IO_TYPE_OPEN_PACKET;

View file

@ -1330,29 +1330,21 @@ NtLockFile(IN HANDLE FileHandle,
StackPtr->MinorFunction = IRP_MN_LOCK; StackPtr->MinorFunction = IRP_MN_LOCK;
StackPtr->FileObject = FileObject; StackPtr->FileObject = FileObject;
/* Enter SEH */ /* Allocate local buffer */
_SEH2_TRY LocalLength = ExAllocatePoolWithTag(NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK);
if (!LocalLength)
{ {
/* Allocate local buffer */ /* Allocating failed, clean up and return failure */
LocalLength = ExAllocatePoolWithTag(NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK);
/* Set the length */
*LocalLength = CapturedLength;
Irp->Tail.Overlay.AuxiliaryBuffer = (PVOID)LocalLength;
StackPtr->Parameters.LockControl.Length = LocalLength;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Allocating failed, clean up and return the exception code */
IopCleanupAfterException(FileObject, Irp, Event, NULL); IopCleanupAfterException(FileObject, Irp, Event, NULL);
if (LocalLength) ExFreePoolWithTag(LocalLength, TAG_LOCK); return STATUS_INSUFFICIENT_RESOURCES;
/* Return the exception code */
_SEH2_YIELD(return _SEH2_GetExceptionCode());
} }
_SEH2_END;
/* Set the length */
*LocalLength = CapturedLength;
Irp->Tail.Overlay.AuxiliaryBuffer = (PVOID)LocalLength;
StackPtr->Parameters.LockControl.Length = LocalLength;
/* Set Parameters */ /* Set Parameters */
StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset; StackPtr->Parameters.LockControl.ByteOffset = CapturedByteOffset;
@ -1397,7 +1389,7 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
NTSTATUS Status; NTSTATUS Status;
BOOLEAN LockedForSynch = FALSE; BOOLEAN LockedForSynch = FALSE;
PKEVENT Event = NULL; PKEVENT Event = NULL;
PVOID AuxBuffer = NULL; volatile PVOID AuxBuffer = NULL;
PMDL Mdl; PMDL Mdl;
UNICODE_STRING CapturedFileName; UNICODE_STRING CapturedFileName;
PUNICODE_STRING SearchPattern; PUNICODE_STRING SearchPattern;
@ -1526,25 +1518,19 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
/* Check if this is buffered I/O */ /* Check if this is buffered I/O */
if (DeviceObject->Flags & DO_BUFFERED_IO) if (DeviceObject->Flags & DO_BUFFERED_IO)
{ {
/* Enter SEH */ /* Allocate a buffer */
_SEH2_TRY Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
{ Length,
/* Allocate a buffer */ TAG_SYSB);
Irp->AssociatedIrp.SystemBuffer = if (!Irp->AssociatedIrp.SystemBuffer)
ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
/* Allocating failed, clean up and return the exception code */ /* Allocating failed, clean up and return the exception code */
IopCleanupAfterException(FileObject, Irp, Event, NULL); IopCleanupAfterException(FileObject, Irp, Event, NULL);
if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB); if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB);
/* Return the exception code */ /* Return the exception code */
_SEH2_YIELD(return _SEH2_GetExceptionCode()); return STATUS_INSUFFICIENT_RESOURCES;
} }
_SEH2_END;
/* Set the buffer and flags */ /* Set the buffer and flags */
Irp->UserBuffer = FileInformation; Irp->UserBuffer = FileInformation;

View file

@ -167,7 +167,7 @@ static NTSTATUS
IopCaptureUnicodeString(PUNICODE_STRING DstName, PUNICODE_STRING SrcName) IopCaptureUnicodeString(PUNICODE_STRING DstName, PUNICODE_STRING SrcName)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING Name; volatile UNICODE_STRING Name;
Name.Buffer = NULL; Name.Buffer = NULL;
_SEH2_TRY _SEH2_TRY