mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 15:36:24 +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,6 +3060,12 @@ NtSetInformationFile(HANDLE FileHandle,
|
||||||
PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
|
PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation;
|
||||||
PIO_COMPLETION_CONTEXT Context;
|
PIO_COMPLETION_CONTEXT Context;
|
||||||
|
|
||||||
|
if (FileObject->Flags & FO_SYNCHRONOUS_IO || FileObject->CompletionContext != NULL)
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (Length < sizeof(FILE_COMPLETION_INFORMATION))
|
if (Length < sizeof(FILE_COMPLETION_INFORMATION))
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
@ -3067,7 +3073,7 @@ NtSetInformationFile(HANDLE FileHandle,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Reference the Port */
|
/* Reference the Port */
|
||||||
Status = ObReferenceObjectByHandle(CompletionInfo->Port,
|
Status = ObReferenceObjectByHandle(CompletionInfo->Port, /* FIXME - protect with SEH! */
|
||||||
IO_COMPLETION_MODIFY_STATE,
|
IO_COMPLETION_MODIFY_STATE,
|
||||||
IoCompletionType,
|
IoCompletionType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
|
@ -3080,13 +3086,30 @@ NtSetInformationFile(HANDLE FileHandle,
|
||||||
sizeof(IO_COMPLETION_CONTEXT),
|
sizeof(IO_COMPLETION_CONTEXT),
|
||||||
TAG('I', 'o', 'C', 'p'));
|
TAG('I', 'o', 'C', 'p'));
|
||||||
|
|
||||||
|
if (Context != NULL)
|
||||||
|
{
|
||||||
/* Set the Data */
|
/* Set the Data */
|
||||||
Context->Key = CompletionInfo->Key;
|
Context->Key = CompletionInfo->Key; /* FIXME - protect with SEH! */
|
||||||
Context->Port = Queue;
|
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 */
|
/* Dereference the Port now */
|
||||||
ObDereferenceObject(Queue);
|
ObDereferenceObject(Queue);
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue