mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +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
|
@ -3059,34 +3059,57 @@ NtSetInformationFile(HANDLE FileHandle,
|
|||
PVOID Queue;
|
||||
PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
|
||||
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
|
||||
{
|
||||
/* Reference the Port */
|
||||
Status = ObReferenceObjectByHandle(CompletionInfo->Port,
|
||||
IO_COMPLETION_MODIFY_STATE,
|
||||
IoCompletionType,
|
||||
PreviousMode,
|
||||
(PVOID*)&Queue,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
if (Length < sizeof(FILE_COMPLETION_INFORMATION))
|
||||
{
|
||||
/* Allocate the Context */
|
||||
Context = ExAllocatePoolWithTag(PagedPool,
|
||||
sizeof(IO_COMPLETION_CONTEXT),
|
||||
TAG('I', 'o', 'C', 'p'));
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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 */
|
||||
Context->Key = CompletionInfo->Key;
|
||||
Context->Port = Queue;
|
||||
FileObject->CompletionContext = Context;
|
||||
|
||||
/* Dereference the Port now */
|
||||
ObDereferenceObject(Queue);
|
||||
if (Context != NULL)
|
||||
{
|
||||
/* Set the Data */
|
||||
Context->Key = CompletionInfo->Key; /* FIXME - protect with SEH! */
|
||||
Context->Port = Queue;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue