mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
Commit of the rest of Gunnars file locking patch.
svn path=/trunk/; revision=3751
This commit is contained in:
parent
84831891ce
commit
e2d799f080
5 changed files with 1308 additions and 161 deletions
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue