mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:16:04 +00:00
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:
parent
294680db96
commit
56b2e53628
1 changed files with 45 additions and 22 deletions
|
@ -3060,33 +3060,56 @@ NtSetInformationFile(HANDLE FileHandle,
|
||||||
PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
|
PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
|
||||||
PIO_COMPLETION_CONTEXT Context;
|
PIO_COMPLETION_CONTEXT Context;
|
||||||
|
|
||||||
if (Length < sizeof(FILE_COMPLETION_INFORMATION))
|
if (FileObject->Flags & FO_SYNCHRONOUS_IO || FileObject->CompletionContext != NULL)
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Reference the Port */
|
if (Length < sizeof(FILE_COMPLETION_INFORMATION))
|
||||||
Status = ObReferenceObjectByHandle(CompletionInfo->Port,
|
|
||||||
IO_COMPLETION_MODIFY_STATE,
|
|
||||||
IoCompletionType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Queue,
|
|
||||||
NULL);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
/* Allocate the Context */
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
Context = ExAllocatePoolWithTag(PagedPool,
|
}
|
||||||
sizeof(IO_COMPLETION_CONTEXT),
|
else
|
||||||
TAG('I', 'o', 'C', 'p'));
|
{
|
||||||
|
/* Reference the Port */
|
||||||
|
Status = ObReferenceObjectByHandle(CompletionInfo->Port, /* FIXME - protect with SEH! */
|
||||||
|
IO_COMPLETION_MODIFY_STATE,
|
||||||
|
IoCompletionType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&Queue,
|
||||||
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Allocate the Context */
|
||||||
|
Context = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
sizeof(IO_COMPLETION_CONTEXT),
|
||||||
|
TAG('I', 'o', 'C', 'p'));
|
||||||
|
|
||||||
/* Set the Data */
|
if (Context != NULL)
|
||||||
Context->Key = CompletionInfo->Key;
|
{
|
||||||
Context->Port = Queue;
|
/* Set the Data */
|
||||||
FileObject->CompletionContext = Context;
|
Context->Key = CompletionInfo->Key; /* FIXME - protect with SEH! */
|
||||||
|
Context->Port = Queue;
|
||||||
|
|
||||||
/* Dereference the Port now */
|
if (InterlockedCompareExchangePointer(&FileObject->CompletionContext,
|
||||||
ObDereferenceObject(Queue);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue