Commit of the rest of Gunnars file locking patch.

svn path=/trunk/; revision=3751
This commit is contained in:
Robert Dickenson 2002-11-13 06:01:12 +00:00
parent 84831891ce
commit e2d799f080
5 changed files with 1308 additions and 161 deletions

View file

@ -1001,8 +1001,8 @@ static BOOL HEAP_IsRealArena(
HANDLE STDCALL
RtlCreateHeap(ULONG flags,
PVOID BaseAddress,
ULONG initialSize,
ULONG maxSize,
ULONG initialSize,
PVOID Unknown,
PRTL_HEAP_DEFINITION Definition)
{

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,76 @@
#ifndef __INCLUDE_INTERNAL_IFS_H
#define __INCLUDE_INTERNAL_IFS_H
/* $Id: ifs.h,v 1.3 2002/09/08 10:23:21 chorns Exp $ */
/* $Id: ifs.h,v 1.4 2002/11/13 06:01:11 robd Exp $ */
#include <ddk/ntifs.h>
/* Look for "FSrt" in mem view */
#define IFS_POOL_TAG 0x74725346
VOID STDCALL
FsRtlpInitFileLockingImplementation(VOID);
VOID STDCALL
FsRtlpPendingFileLockCancelRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
BOOLEAN STDCALL
FsRtlpCheckLockForReadOrWriteAccess(
IN PFILE_LOCK FileLock,
IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length,
IN ULONG Key,
IN PFILE_OBJECT FileObject,
IN PEPROCESS Process,
IN BOOLEAN Read
);
NTSTATUS STDCALL
FsRtlpFastUnlockAllByKey(
IN PFILE_LOCK FileLock,
IN PFILE_OBJECT FileObject,
IN PEPROCESS Process,
IN DWORD Key, /* FIXME: guess */
IN BOOLEAN UseKey, /* FIXME: guess */
IN PVOID Context OPTIONAL
);
NTSTATUS STDCALL
FsRtlpAddLock(
IN PFILE_LOCK_TOC LockToc,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length,
IN PEPROCESS Process,
IN ULONG Key,
IN BOOLEAN ExclusiveLock
);
VOID STDCALL
FsRtlpTryCompletePendingLocks(
IN PFILE_LOCK FileLock,
IN PFILE_LOCK_TOC LockToc,
IN OUT PKIRQL oldirql
);
NTSTATUS STDCALL
FsRtlpUnlockSingle(
IN PFILE_LOCK FileLock,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length,
IN PEPROCESS Process,
IN ULONG Key,
IN PVOID Context OPTIONAL,
IN BOOLEAN AlreadySynchronized,
IN BOOLEAN CallUnlockRoutine
);
VOID STDCALL
FsRtlpDumpFileLocks(
IN PFILE_LOCK FileLock
);
#endif

View file

@ -10,20 +10,38 @@
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#define NDEBUG
#include <internal/debug.h>
#define TAG_LOCK TAG('F','l','c','k')
/* FUNCTIONS *****************************************************************/
NTSTATUS
STDCALL
NtLockFileCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
ExFreePool(Context);
return STATUS_SUCCESS;
//FIXME: should I call IoFreeIrp and return STATUS_MORE_PROCESSING_REQUIRED?
}
NTSTATUS
STDCALL
NtLockFile (
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN HANDLE EventHandle OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PIO_STATUS_BLOCK UserIoStatusBlock,
IN PLARGE_INTEGER ByteOffset,
IN PLARGE_INTEGER Length,
IN PULONG Key,
@ -31,19 +49,248 @@ NtLockFile (
IN BOOLEAN ExclusiveLock
)
{
UNIMPLEMENTED;
NTSTATUS Status;
PFILE_OBJECT FileObject = NULL;
PLARGE_INTEGER LocalLength = NULL;
PKEVENT Event = NULL;
PIRP Irp = NULL;
PIO_STACK_LOCATION StackPtr;
IO_STATUS_BLOCK LocalIoStatusBlock;
PIO_STATUS_BLOCK IoStatusBlock;
PDEVICE_OBJECT DeviceObject;
//FIXME: instead of this, use SEH when available?
if (!Length || !ByteOffset) {
Status = STATUS_INVALID_PARAMETER;
goto fail;
}
/*
BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode!
It should ONLY fail if we desire an access that conflict with granted access!
*/
Status = ObReferenceObjectByHandle(
FileHandle,
FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
IoFileObjectType,
ExGetPreviousMode(),
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status)){
goto fail;
}
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = IoAllocateIrp(
DeviceObject->StackSize,
TRUE
);
if (Irp == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
if (EventHandle != NULL && !FailImmediatedly) {
Status = ObReferenceObjectByHandle(
EventHandle,
SYNCHRONIZE,
ExEventObjectType,
ExGetPreviousMode(),
(PVOID*)&Event,
NULL);
if (!NT_SUCCESS(Status)) {
goto fail;
}
}
else {
Event = &FileObject->Event;
KeResetEvent(Event);
}
if ((FileObject->Flags & FO_SYNCHRONOUS_IO) || FailImmediatedly)
IoStatusBlock = &LocalIoStatusBlock;
else
IoStatusBlock = UserIoStatusBlock;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
Irp->UserEvent = Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
StackPtr->MinorFunction = IRP_MN_LOCK;
StackPtr->DeviceObject = DeviceObject;
StackPtr->FileObject = FileObject;
if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK;
if (FailImmediatedly) StackPtr->Flags |= SL_FAIL_IMMEDIATELY;
LocalLength = ExAllocatePoolWithTag(
NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK
);
if (!LocalLength){
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
*LocalLength = *Length;
StackPtr->Parameters.LockControl.Length = LocalLength;
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
IoSetCompletionRoutine(
Irp,
NtLockFileCompletionRoutine,
LocalLength,
TRUE,
TRUE,
TRUE );
Status = IofCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) {
Status = KeWaitForSingleObject(
Event,
Executive,
ExGetPreviousMode() ,
(FileObject->Flags & FO_ALERTABLE_IO) ? TRUE : FALSE,
NULL
);
if (Status != STATUS_WAIT_0) {
DPRINT1("NtLockFile -> KeWaitForSingleObject failed!\n");
/*
FIXME: should do some special processing here if alertable wait
was interupted by user apc or a thread alert (STATUS_ALERTED, STATUS_USER_APC)
*/
return Status; //set status to something else?
}
Status = LocalIoStatusBlock.Status;
}
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
*UserIoStatusBlock = LocalIoStatusBlock;
return Status;
fail:;
if (LocalLength) ExFreePool(LocalLength);
if (Irp) IoFreeIrp(Irp);
if (Event) ObDereferenceObject(Event);
if (FileObject) ObDereferenceObject(FileObject);
return Status;
}
NTSTATUS
STDCALL
NtUnlockFile (
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PIO_STATUS_BLOCK UserIoStatusBlock,
IN PLARGE_INTEGER ByteOffset,
IN PLARGE_INTEGER Length,
OUT PULONG Key OPTIONAL
)
{
UNIMPLEMENTED;
NTSTATUS Status;
PFILE_OBJECT FileObject = NULL;
PLARGE_INTEGER LocalLength = NULL;
PIRP Irp = NULL;
PIO_STACK_LOCATION StackPtr;
IO_STATUS_BLOCK LocalIoStatusBlock;
PDEVICE_OBJECT DeviceObject;
//FIXME: instead of this, use SEH when available
if (!Length || !ByteOffset) {
Status = STATUS_INVALID_PARAMETER;
goto fail;
}
/*
BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode
It should ONLY fail if we desire an access that conflict with granted access!
*/
Status = ObReferenceObjectByHandle(
FileHandle,
FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to!
IoFileObjectType,
ExGetPreviousMode(),
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status)){
goto fail;
}
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = IoAllocateIrp(
DeviceObject->StackSize,
TRUE
);
if (Irp == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
Irp->UserIosb = &LocalIoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL;
StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
StackPtr->DeviceObject = DeviceObject;
StackPtr->FileObject = FileObject;
LocalLength = ExAllocatePoolWithTag(
NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK
);
if (!LocalLength){
Status = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
*LocalLength = *Length;
StackPtr->Parameters.LockControl.Length = LocalLength;
StackPtr->Parameters.LockControl.ByteOffset = *ByteOffset;
StackPtr->Parameters.LockControl.Key = Key ? *Key : 0;
//allways syncronious
Status = IofCallDriver(DeviceObject, Irp);
*UserIoStatusBlock = LocalIoStatusBlock;
ExFreePool(LocalLength);
return Status;
fail:;
if (LocalLength) ExFreePool(LocalLength);
if (Irp) IoFreeIrp(Irp);
if (FileObject) ObDereferenceObject(FileObject);
return Status;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: main.c,v 1.140 2002/11/12 19:12:13 ekohl Exp $
/* $Id: main.c,v 1.141 2002/11/13 06:01:12 robd Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
@ -32,6 +32,7 @@
#include <internal/ntoskrnl.h>
#include <reactos/resource.h>
#include <internal/mm.h>
#include <internal/ifs.h>
#include <internal/module.h>
#include <internal/ldr.h>
#include <internal/ex.h>
@ -424,6 +425,7 @@ ExpInitializeExecutive(VOID)
MmInit3();
CcInit();
KdInit2();
FsRtlpInitFileLockingImplementation();
/* Report all resources used by hal */
HalReportResourceUsage();