don't dereference the port in NtSetInformationFile with information class FileCompletionInformation. The Also make setting the completion port thread-safe. This might fix bug 816

svn path=/trunk/; revision=18137
This commit is contained in:
Thomas Bluemel 2005-09-28 17:15:57 +00:00
parent 294680db96
commit 56b2e53628

View file

@ -3060,6 +3060,12 @@ NtSetInformationFile(HANDLE FileHandle,
PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
PIO_COMPLETION_CONTEXT Context;
if (FileObject->Flags & FO_SYNCHRONOUS_IO || FileObject->CompletionContext != NULL)
{
Status = STATUS_INVALID_PARAMETER;
}
else
{
if (Length < sizeof(FILE_COMPLETION_INFORMATION))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
@ -3067,7 +3073,7 @@ NtSetInformationFile(HANDLE FileHandle,
else
{
/* Reference the Port */
Status = ObReferenceObjectByHandle(CompletionInfo->Port,
Status = ObReferenceObjectByHandle(CompletionInfo->Port, /* FIXME - protect with SEH! */
IO_COMPLETION_MODIFY_STATE,
IoCompletionType,
PreviousMode,
@ -3080,13 +3086,30 @@ NtSetInformationFile(HANDLE FileHandle,
sizeof(IO_COMPLETION_CONTEXT),
TAG('I', 'o', 'C', 'p'));
if (Context != NULL)
{
/* Set the Data */
Context->Key = CompletionInfo->Key;
Context->Key = CompletionInfo->Key; /* FIXME - protect with SEH! */
Context->Port = Queue;
FileObject->CompletionContext = Context;
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;
}
}
}
}