mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-24 17:32:29 -05:00
sys: FspFsvolDeviceInsertContext: can no longer fail because of low memory
This commit is contained in:
parent
bdc7033740
commit
df340872f7
@ -346,6 +346,20 @@ VOID FspFsvolCreateComplete(
|
|||||||
{
|
{
|
||||||
FSP_ENTER_IOC(PAGED_CODE());
|
FSP_ENTER_IOC(PAGED_CODE());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE:
|
||||||
|
* In the following we may have to close the just opened file object. But we must
|
||||||
|
* never close a file we just created, because this will leave an orphan file on
|
||||||
|
* the disk.
|
||||||
|
*
|
||||||
|
* Files may have to be closed if a security access or share access check fails. In
|
||||||
|
* both those cases we were opening an existing file and so it is safe to close it.
|
||||||
|
*
|
||||||
|
* Because of how IRP_MJ_CREATE works in Windows, it is difficult to improve on this
|
||||||
|
* scheme without introducing a 2-phase Create protocol, which is undesirable as it
|
||||||
|
* means two trips into user-mode for a single Create request.
|
||||||
|
*/
|
||||||
|
|
||||||
PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject;
|
PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
||||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension =
|
||||||
@ -400,11 +414,11 @@ VOID FspFsvolCreateComplete(
|
|||||||
goto reparse_fail;
|
goto reparse_fail;
|
||||||
}
|
}
|
||||||
ExFreePool(FileObject->FileName.Buffer);
|
ExFreePool(FileObject->FileName.Buffer);
|
||||||
FileObject->FileName.Length = 0;
|
|
||||||
FileObject->FileName.MaximumLength = ReparseFileName.Length;
|
FileObject->FileName.MaximumLength = ReparseFileName.Length;
|
||||||
FileObject->FileName.Buffer = Buffer;
|
FileObject->FileName.Buffer = Buffer;
|
||||||
RtlCopyUnicodeString(&FileObject->FileName, &ReparseFileName);
|
|
||||||
}
|
}
|
||||||
|
FileObject->FileName.Length = 0;
|
||||||
|
RtlCopyUnicodeString(&FileObject->FileName, &ReparseFileName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (IO_REMOUNT == Response->IoStatus.Information)
|
if (IO_REMOUNT == Response->IoStatus.Information)
|
||||||
@ -471,13 +485,11 @@ VOID FspFsvolCreateComplete(
|
|||||||
ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->Base.Resource, TRUE);
|
ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->Base.Resource, TRUE);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
/* attempt to insert the newly created FsContext into our generic table */
|
/* insert the newly created FsContext into our generic table */
|
||||||
FsContext = FspFsvolDeviceInsertContext(DeviceObject,
|
FsContext = FspFsvolDeviceInsertContext(DeviceObject,
|
||||||
FsContext->UserContext, FsContext, &Inserted);
|
FsContext->UserContext, FsContext, &FsContext->ElementStorage, &Inserted);
|
||||||
if (0 == FsContext)
|
ASSERT(0 != FsContext);
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* share access check */
|
/* share access check */
|
||||||
if (Inserted)
|
if (Inserted)
|
||||||
{
|
{
|
||||||
@ -505,9 +517,11 @@ VOID FspFsvolCreateComplete(
|
|||||||
Result = IoCheckShareAccess(AccessState->PreviouslyGrantedAccess,
|
Result = IoCheckShareAccess(AccessState->PreviouslyGrantedAccess,
|
||||||
ShareAccess, FileObject, &FsContext->ShareAccess, TRUE);
|
ShareAccess, FileObject, &FsContext->ShareAccess, TRUE);
|
||||||
if (NT_SUCCESS(Result))
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFileContextRetain(FsContext);
|
||||||
FspFileContextOpen(FsContext);
|
FspFileContextOpen(FsContext);
|
||||||
ExReleaseResourceLite(FsContext->Header.Resource);
|
|
||||||
}
|
}
|
||||||
|
ExReleaseResourceLite(FsContext->Header.Resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -515,7 +529,7 @@ VOID FspFsvolCreateComplete(
|
|||||||
ExReleaseResourceLite(&FsvolDeviceExtension->Base.Resource);
|
ExReleaseResourceLite(&FsvolDeviceExtension->Base.Resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* did we fail to insert? */
|
/* did we fail our share access checks? */
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
ASSERT(!Inserted);
|
ASSERT(!Inserted);
|
||||||
|
@ -26,7 +26,7 @@ VOID FspFsctlDeviceVolumeCreated(PDEVICE_OBJECT DeviceObject);
|
|||||||
VOID FspFsctlDeviceVolumeDeleted(PDEVICE_OBJECT DeviceObject);
|
VOID FspFsctlDeviceVolumeDeleted(PDEVICE_OBJECT DeviceObject);
|
||||||
PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier);
|
PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier);
|
||||||
PVOID FspFsvolDeviceInsertContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier, PVOID Context,
|
PVOID FspFsvolDeviceInsertContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier, PVOID Context,
|
||||||
PBOOLEAN PInserted);
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT *ElementStorage, PBOOLEAN PInserted);
|
||||||
VOID FspFsvolDeviceDeleteContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier,
|
VOID FspFsvolDeviceDeleteContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier,
|
||||||
PBOOLEAN PDeleted);
|
PBOOLEAN PDeleted);
|
||||||
static RTL_AVL_COMPARE_ROUTINE FspFsvolDeviceCompareElement;
|
static RTL_AVL_COMPARE_ROUTINE FspFsvolDeviceCompareElement;
|
||||||
@ -61,12 +61,6 @@ VOID FspDeviceDeleteAll(VOID);
|
|||||||
#pragma alloc_text(PAGE, FspDeviceDeleteAll)
|
#pragma alloc_text(PAGE, FspDeviceDeleteAll)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UINT64 Identifier;
|
|
||||||
PVOID Context;
|
|
||||||
} FSP_DEVICE_GENERIC_TABLE_ELEMENT;
|
|
||||||
|
|
||||||
NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
|
NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
|
||||||
PUNICODE_STRING DeviceName, DEVICE_TYPE DeviceType,
|
PUNICODE_STRING DeviceName, DEVICE_TYPE DeviceType,
|
||||||
PUNICODE_STRING DeviceSddl, LPCGUID DeviceClassGuid,
|
PUNICODE_STRING DeviceSddl, LPCGUID DeviceClassGuid,
|
||||||
@ -236,7 +230,7 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
|
|||||||
* Enumerate and delete all entries in the GenericTable.
|
* Enumerate and delete all entries in the GenericTable.
|
||||||
* There is no need to protect accesses to the table as we are in the device destructor.
|
* There is no need to protect accesses to the table as we are in the device destructor.
|
||||||
*/
|
*/
|
||||||
FSP_DEVICE_GENERIC_TABLE_ELEMENT *Element;
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT_DATA *Element;
|
||||||
while (0 != (Element = RtlGetElementGenericTableAvl(&FsvolDeviceExtension->GenericTable, 0)))
|
while (0 != (Element = RtlGetElementGenericTableAvl(&FsvolDeviceExtension->GenericTable, 0)))
|
||||||
RtlDeleteElementGenericTableAvl(&FsvolDeviceExtension->GenericTable, &Element->Identifier);
|
RtlDeleteElementGenericTableAvl(&FsvolDeviceExtension->GenericTable, &Element->Identifier);
|
||||||
|
|
||||||
@ -318,7 +312,7 @@ PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier
|
|||||||
ASSERT(FspFsvolDeviceExtensionKind == FsvolDeviceExtension->Base.Kind);
|
ASSERT(FspFsvolDeviceExtensionKind == FsvolDeviceExtension->Base.Kind);
|
||||||
ASSERT(ExIsResourceAcquiredExclusiveLite(&FsvolDeviceExtension->Base.Resource));
|
ASSERT(ExIsResourceAcquiredExclusiveLite(&FsvolDeviceExtension->Base.Resource));
|
||||||
|
|
||||||
FSP_DEVICE_GENERIC_TABLE_ELEMENT *Result;
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT_DATA *Result;
|
||||||
|
|
||||||
Result = RtlLookupElementGenericTableAvl(&FsvolDeviceExtension->GenericTable, &Identifier);
|
Result = RtlLookupElementGenericTableAvl(&FsvolDeviceExtension->GenericTable, &Identifier);
|
||||||
|
|
||||||
@ -326,7 +320,7 @@ PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier
|
|||||||
}
|
}
|
||||||
|
|
||||||
PVOID FspFsvolDeviceInsertContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier, PVOID Context,
|
PVOID FspFsvolDeviceInsertContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier, PVOID Context,
|
||||||
PBOOLEAN PInserted)
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT *ElementStorage, PBOOLEAN PInserted)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
@ -334,12 +328,14 @@ PVOID FspFsvolDeviceInsertContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier
|
|||||||
ASSERT(FspFsvolDeviceExtensionKind == FsvolDeviceExtension->Base.Kind);
|
ASSERT(FspFsvolDeviceExtensionKind == FsvolDeviceExtension->Base.Kind);
|
||||||
ASSERT(ExIsResourceAcquiredExclusiveLite(&FsvolDeviceExtension->Base.Resource));
|
ASSERT(ExIsResourceAcquiredExclusiveLite(&FsvolDeviceExtension->Base.Resource));
|
||||||
|
|
||||||
FSP_DEVICE_GENERIC_TABLE_ELEMENT *Result, Element = { 0 };
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT_DATA *Result, Element = { 0 };
|
||||||
Element.Identifier = Identifier;
|
Element.Identifier = Identifier;
|
||||||
Element.Context = Context;
|
Element.Context = Context;
|
||||||
|
|
||||||
|
FsvolDeviceExtension->GenericTableElementStorage = ElementStorage;
|
||||||
Result = RtlInsertElementGenericTableAvl(&FsvolDeviceExtension->GenericTable,
|
Result = RtlInsertElementGenericTableAvl(&FsvolDeviceExtension->GenericTable,
|
||||||
&Element, sizeof Element, PInserted);
|
&Element, sizeof Element, PInserted);
|
||||||
|
FsvolDeviceExtension->GenericTableElementStorage = 0;
|
||||||
|
|
||||||
return 0 != Result ? Result->Context : 0;
|
return 0 != Result ? Result->Context : 0;
|
||||||
}
|
}
|
||||||
@ -380,15 +376,18 @@ static PVOID NTAPI FspFsvolDeviceAllocateElement(
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
return ExAllocatePoolWithTag(PagedPool, ByteSize, FSP_TAG);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
|
||||||
|
CONTAINING_RECORD(Table, FSP_FSVOL_DEVICE_EXTENSION, GenericTable);
|
||||||
|
|
||||||
|
ASSERT(sizeof(FSP_DEVICE_GENERIC_TABLE_ELEMENT) == ByteSize);
|
||||||
|
|
||||||
|
return FsvolDeviceExtension->GenericTableElementStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID NTAPI FspFsvolDeviceFreeElement(
|
static VOID NTAPI FspFsvolDeviceFreeElement(
|
||||||
PRTL_AVL_TABLE Table, PVOID Buffer)
|
PRTL_AVL_TABLE Table, PVOID Buffer)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
ExFreePoolWithTag(Buffer, FSP_TAG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspDeviceCopyList(
|
NTSTATUS FspDeviceCopyList(
|
||||||
|
@ -305,7 +305,18 @@ typedef struct
|
|||||||
FSP_DEVICE_EXTENSION Base;
|
FSP_DEVICE_EXTENSION Base;
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||||
RTL_AVL_TABLE GenericTable;
|
RTL_AVL_TABLE GenericTable;
|
||||||
|
PVOID GenericTableElementStorage;
|
||||||
} FSP_FSVOL_DEVICE_EXTENSION;
|
} FSP_FSVOL_DEVICE_EXTENSION;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UINT64 Identifier;
|
||||||
|
PVOID Context;
|
||||||
|
} FSP_DEVICE_GENERIC_TABLE_ELEMENT_DATA;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
RTL_BALANCED_LINKS Header;
|
||||||
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT_DATA Data;
|
||||||
|
} FSP_DEVICE_GENERIC_TABLE_ELEMENT;
|
||||||
static inline
|
static inline
|
||||||
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
@ -343,7 +354,7 @@ VOID FspFsctlDeviceVolumeCreated(PDEVICE_OBJECT DeviceObject);
|
|||||||
VOID FspFsctlDeviceVolumeDeleted(PDEVICE_OBJECT DeviceObject);
|
VOID FspFsctlDeviceVolumeDeleted(PDEVICE_OBJECT DeviceObject);
|
||||||
PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier);
|
PVOID FspFsvolDeviceLookupContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier);
|
||||||
PVOID FspFsvolDeviceInsertContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier, PVOID Context,
|
PVOID FspFsvolDeviceInsertContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier, PVOID Context,
|
||||||
PBOOLEAN PInserted);
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT *ElementStorage, PBOOLEAN PInserted);
|
||||||
VOID FspFsvolDeviceDeleteContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier,
|
VOID FspFsvolDeviceDeleteContext(PDEVICE_OBJECT DeviceObject, UINT64 Identifier,
|
||||||
PBOOLEAN PDeleted);
|
PBOOLEAN PDeleted);
|
||||||
NTSTATUS FspDeviceCopyList(
|
NTSTATUS FspDeviceCopyList(
|
||||||
@ -370,6 +381,7 @@ typedef struct
|
|||||||
SHARE_ACCESS ShareAccess;
|
SHARE_ACCESS ShareAccess;
|
||||||
BOOLEAN DeletePending;
|
BOOLEAN DeletePending;
|
||||||
/* read-only after creation */
|
/* read-only after creation */
|
||||||
|
FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage;
|
||||||
UINT64 UserContext;
|
UINT64 UserContext;
|
||||||
UNICODE_STRING FileName;
|
UNICODE_STRING FileName;
|
||||||
WCHAR FileNameBuf[];
|
WCHAR FileNameBuf[];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user