Commit in reactos on MAIN
include/ntos/file.h-71.7 -> 1.8
            /fstypes.h+7-11.1 -> 1.2
            /ntdef.h+141.9 -> 1.10
ntoskrnl/fs/filelock.c+231-2201.16 -> 1.17
ntoskrnl/include/internal/ifs.h+6-51.6 -> 1.7
+258-233
5 modified files
filelock.c: 
-general cleanup
-fix signed -> unsigned comparsion
-allow zero length unlocks to complete with success
-makes some more wine reg. tests pass
ntdef.h: add macros LIST_FOR_EACH and LIST_FOR_EACH_SAFE

reactos/include/ntos
file.h 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- file.h	25 Jul 2004 12:36:45 -0000	1.7
+++ file.h	30 Dec 2004 02:30:39 -0000	1.8
@@ -113,12 +113,5 @@
 
 #endif /* !__USE_W32API */
 
-typedef struct _FILE_LOCK_TOC {
-	KSPIN_LOCK			SpinLock;
-	LIST_ENTRY			GrantedListHead;
-	LIST_ENTRY			PendingListHead;
-	LIST_ENTRY			CompletedListHead;
-	LIST_ENTRY			UnlockedListHead;
-} FILE_LOCK_TOC, *PFILE_LOCK_TOC;
 
 #endif /* __INCLUDE_FILE_H */

reactos/include/ntos
fstypes.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- fstypes.h	14 Aug 2003 18:30:27 -0000	1.1
+++ fstypes.h	30 Dec 2004 02:30:39 -0000	1.2
@@ -27,9 +27,15 @@
 
 typedef struct _FILE_LOCK_GRANTED {
 	LIST_ENTRY			ListEntry;
-	FILE_LOCK_INFO		Lock;
+	FILE_LOCK_INFO			Lock;
+   PVOID             UnlockContext;
 } FILE_LOCK_GRANTED, *PFILE_LOCK_GRANTED;
 
 
+typedef struct _FILE_LOCK_TOC {
+	KSPIN_LOCK			SpinLock;
+	LIST_ENTRY			GrantedListHead;
+	LIST_ENTRY			PendingListHead;
+} FILE_LOCK_TOC, *PFILE_LOCK_TOC;
 
 #endif  /* __INCLUDE_DDK_FSTYPES_H */

reactos/include/ntos
ntdef.h 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- ntdef.h	6 Dec 2004 14:34:43 -0000	1.9
+++ ntdef.h	30 Dec 2004 02:30:39 -0000	1.10
@@ -39,6 +39,20 @@
 #define SECONDS_TO_100NS(seconds) (((LONGLONG)(seconds)) * MILLIS_TO_100NS(1000L))
 
 
+/* Helpers for enumarating lists */
+#define LIST_FOR_EACH(entry, head) \
+   for(entry = (head)->Flink; entry != (head); entry = entry->Flink)
+
+/* 
+Safe version which saves pointer to the next entry so the current ptr->field entry
+can be unlinked without corrupting the list. NOTE: Never unlink tmp_entry!!!!!!!!!
+*/
+#define LIST_FOR_EACH_SAFE(tmp_entry, head, ptr, type, field) \
+   for ((tmp_entry)=(head)->Flink; (tmp_entry)!=(head) && \
+        ((ptr) = CONTAINING_RECORD(tmp_entry,type,field)) && \
+        ((tmp_entry) = (tmp_entry)->Flink); )
+
+
 #ifndef __USE_W32API
 
 #define ANYSIZE_ARRAY	(1)

reactos/ntoskrnl/fs
filelock.c 1.16 -> 1.17
diff -u -r1.16 -r1.17
--- filelock.c	23 Dec 2004 12:30:48 -0000	1.16
+++ filelock.c	30 Dec 2004 02:30:40 -0000	1.17
@@ -1,4 +1,4 @@
-/* $Id: filelock.c,v 1.16 2004/12/23 12:30:48 ekohl Exp $
+/* $Id: filelock.c,v 1.17 2004/12/30 02:30:40 gdalsnes Exp $
  *
  * reactos/ntoskrnl/fs/filelock.c
  *
@@ -13,18 +13,54 @@
 I'm not using resource syncronization here, since FsRtlFastCheckLockForRead/Write
 are allowed to be called at DISPATCH_LEVEL. Must therefore use nonpaged memory for
 the lists.
+UPDATE: I'm not sure about this! -Gunnar
 */
 
-#define LOCK_START_OFF(Lock)  ((Lock).StartingByte.QuadPart)
-#define LOCK_END_OFF(Lock)    (((Lock).StartingByte.QuadPart) + ((Lock).Length.QuadPart) - 1)
-#define REQUEST_START_OFF     (FileOffset->QuadPart)
-#define REQUEST_END_OFF       ((FileOffset->QuadPart) + (Length->QuadPart) - 1)
-
 FAST_MUTEX              LockTocMutex;
 NPAGED_LOOKASIDE_LIST   GrantedLookaside;
 NPAGED_LOOKASIDE_LIST   LockTocLookaside;
 PAGED_LOOKASIDE_LIST    LockLookaside;
 
+
+
+inline BOOLEAN 
+IsOverlappingLock(
+   PFILE_LOCK_INFO Lock,
+   PLARGE_INTEGER StartOffset,
+   PLARGE_INTEGER EndOffset
+   )
+{
+   if ((ULONGLONG)StartOffset->QuadPart > (ULONGLONG)Lock->EndingByte.QuadPart)
+   {
+      return FALSE; 
+   }
+   
+   if ((ULONGLONG)EndOffset->QuadPart < (ULONGLONG)Lock->StartingByte.QuadPart)
+   {
+      return FALSE; 
+   }
+   
+   return TRUE;   
+}
+
+
+inline BOOLEAN 
+IsSurroundingLock(
+   PFILE_LOCK_INFO Lock,
+   PLARGE_INTEGER StartOffset,
+   PLARGE_INTEGER EndOffset
+   )
+{
+   if ((ULONGLONG)StartOffset->QuadPart >= (ULONGLONG)Lock->StartingByte.QuadPart && 
+       (ULONGLONG)EndOffset->QuadPart <= (ULONGLONG)Lock->EndingByte.QuadPart)
+   {
+      return TRUE; 
+   }
+   
+   return FALSE;   
+}
+
+
 /**********************************************************************
  * NAME							PRIVATE
  *	FsRtlpInitFileLockingImplementation
@@ -62,6 +98,7 @@
                                     );
 
    ExInitializeFastMutex(&LockTocMutex);
+   
 }
 
 /**********************************************************************
@@ -78,28 +115,22 @@
 {
    KIRQL                         oldIrql;
    PKSPIN_LOCK                   SpinLock;
-   PCOMPLETE_LOCK_IRP_ROUTINE    CompleteLockIrpRoutine;
 
    //don't need this since we have our own sync. protecting irp cancellation
    IoReleaseCancelSpinLock(Irp->CancelIrql); 
 
-   SpinLock = &((PFILE_LOCK_TOC)Irp->Tail.Overlay.DriverContext[1])->SpinLock;
+   SpinLock = Irp->Tail.Overlay.DriverContext[3];
 
    KeAcquireSpinLock(SpinLock, &oldIrql);
+   
    RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+   
    KeReleaseSpinLock(SpinLock, oldIrql);
 
    Irp->IoStatus.Status = STATUS_CANCELLED;
+   Irp->IoStatus.Information = 0;
 
-   CompleteLockIrpRoutine = ((PFILE_LOCK)Irp->Tail.Overlay.DriverContext[0])->CompleteLockIrpRoutine;
-   if (CompleteLockIrpRoutine)
-   {
-      CompleteLockIrpRoutine(Irp->Tail.Overlay.DriverContext[2], Irp);
-   }
-   else
-   {
-      IofCompleteRequest(Irp, IO_NO_INCREMENT);
-   }
+   IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
 }
 
@@ -107,6 +138,9 @@
  * NAME							PRIVATE
  *	FsRtlpCheckLockForReadOrWriteAccess
  *
+ * Return: 
+ *  TRUE: can read/write
+ *  FALSE: can't read/write
  */
 BOOLEAN
 FASTCALL
@@ -124,8 +158,10 @@
    PFILE_LOCK_TOC       LockToc;
    PFILE_LOCK_GRANTED   Granted;
    PLIST_ENTRY          EnumEntry;
-
+   LARGE_INTEGER        EndOffset;
+   
    ASSERT(FileLock);
+   
    LockToc = FileLock->LockInformation;
 
    if (LockToc == NULL || Length->QuadPart == 0) 
@@ -133,15 +169,16 @@
       return TRUE;
    }
 
+   EndOffset.QuadPart = FileOffset->QuadPart + Length->QuadPart - 1;
+
    KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
 
-   EnumEntry = LockToc->GrantedListHead.Flink;
-   while ( EnumEntry != &LockToc->GrantedListHead)
+   LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
    {
-      Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry );
+      Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED, ListEntry);
+      
       //if overlapping
-      if(!(REQUEST_START_OFF > LOCK_END_OFF(Granted->Lock) || 
-         REQUEST_END_OFF < LOCK_START_OFF(Granted->Lock))) 
+      if(IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset)) 
       {
          //No read conflict if (shared lock) OR (exclusive + our lock)
          //No write conflict if exclusive lock AND our lock
@@ -152,30 +189,26 @@
             Granted->Lock.Key == Key ) ) 
          {
             //AND if lock surround request region, stop searching and grant
-            if (REQUEST_START_OFF >= LOCK_START_OFF(Granted->Lock) && 
-               REQUEST_END_OFF <= LOCK_END_OFF(Granted->Lock))
+            if (IsSurroundingLock(&Granted->Lock, FileOffset, &EndOffset) )
             {
-               EnumEntry = &LockToc->GrantedListHead;//indicate no conflict
-               break;
+               KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+               return TRUE;
             }
+            
             //else continue searching for conflicts
+            continue;
          }
-         else //conflict
-         {
-            break;
-         }
-      }
-      EnumEntry = EnumEntry->Flink;
-   }
 
-   KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+         //found conflict
+         KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+         return FALSE;
+      }
 
-   if (EnumEntry == &LockToc->GrantedListHead) 
-   { //no conflict
-      return TRUE;
    }
 
-   return FALSE;
+   //no conflict
+   KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+   return TRUE;
 }
 
 
@@ -206,7 +239,7 @@
                                                 Stack->Parameters.Read.Key,
                                                 Stack->FileObject,
                                                 IoGetRequestorProcess(Irp),
-                                                TRUE//Read?
+                                                TRUE /* Read */
                                                 );
 }
 
@@ -238,7 +271,7 @@
                                                 Stack->Parameters.Write.Key,
                                                 Stack->FileObject,
                                                 IoGetRequestorProcess(Irp),
-                                                FALSE//Read?
+                                                FALSE /* Read */
                                                 );
 
 }
@@ -269,7 +302,7 @@
                                                 Key,
                                                 FileObject,
                                                 Process,
-                                                TRUE//Read?
+                                                TRUE /* Read */
                                                 );
 }
 
@@ -297,7 +330,7 @@
                                                 Key,
                                                 FileObject,
                                                 Process,
-                                                FALSE//Read?
+                                                FALSE /* Read */
                                                 );
 }
 
@@ -314,8 +347,8 @@
    IN PFILE_LOCK           FileLock,
    IN PFILE_OBJECT         FileObject,
    IN PEPROCESS            Process,
-   IN DWORD                Key,      /* FIXME: guess */
-   IN BOOLEAN              UseKey,   /* FIXME: guess */
+   IN DWORD                Key,
+   IN BOOLEAN              UseKey,
    IN PVOID                Context OPTIONAL
    )
 {
@@ -325,7 +358,8 @@
    PFILE_LOCK_GRANTED	Granted;
    BOOLEAN				   Unlock = FALSE;
    //must make local copy since FILE_LOCK struct is allowed to be paged
-   PUNLOCK_ROUTINE		GotUnlockRoutine;
+   BOOLEAN        		GotUnlockRoutine;
+   LIST_ENTRY           UnlockedListHead;
 
    ASSERT(FileLock);
    LockToc = FileLock->LockInformation;
@@ -335,15 +369,13 @@
       return STATUS_RANGE_NOT_LOCKED;
    }
 
-   GotUnlockRoutine = FileLock->UnlockRoutine;
+   InitializeListHead(&UnlockedListHead);
+   GotUnlockRoutine = FileLock->UnlockRoutine != NULL;
    KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
-
-   EnumEntry = LockToc->GrantedListHead.Flink;
-   while (EnumEntry != &LockToc->GrantedListHead ) 
+   
+   LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted, FILE_LOCK_GRANTED, ListEntry)
    {
-      Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry);
-      EnumEntry = EnumEntry->Flink;
-
+      
       if (Granted->Lock.Process == Process &&
          Granted->Lock.FileObject == FileObject &&
          (!UseKey || (UseKey && Granted->Lock.Key == Key)) )
@@ -357,7 +389,7 @@
             Put on unlocked list and call unlock routine for them afterwards.
             This way we don't have to restart enum after each call
             */
-            InsertHeadList(&LockToc->UnlockedListHead,&Granted->ListEntry);
+            InsertHeadList(&UnlockedListHead,&Granted->ListEntry);
          }
          else 
          {
@@ -366,21 +398,23 @@
       }
    }
 
+   KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+   
    if (Unlock)
    {
       //call unlock routine for each unlocked lock (if any)
-      while (!IsListEmpty(&LockToc->UnlockedListHead)) 
+      while (!IsListEmpty(&UnlockedListHead)) 
       {
-         EnumEntry = RemoveTailList(&LockToc->UnlockedListHead);
+         EnumEntry = RemoveTailList(&UnlockedListHead);
          Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry);
-         KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
-         FileLock->UnlockRoutine(Context,&Granted->Lock);
+         
+         FileLock->UnlockRoutine(Granted->UnlockContext, &Granted->Lock);
          ExFreeToNPagedLookasideList(&GrantedLookaside,Granted);
-         KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
       }
 
       //NOTE: holding spinlock while calling this
-      FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql);
+      KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
+      FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql, Context);
 
       if (IsListEmpty(&LockToc->GrantedListHead)) 
       {
@@ -391,10 +425,10 @@
       {
          KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
       }
+      
       return STATUS_SUCCESS;
    }
 
-   KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
    return STATUS_RANGE_NOT_LOCKED;
 }
 
@@ -416,9 +450,9 @@
    return FsRtlpFastUnlockAllByKey( FileLock,
                                     FileObject,
                                     Process,
-                                    0,     /* Key */
+                                    0,     /* Key is ignored */
                                     FALSE, /* Do NOT use Key */
-                                    Context
+                                    Context 
                                     );
 }
 
@@ -443,7 +477,7 @@
                                     Process,
                                     Key,
                                     TRUE, /* Use Key */
-                                    Context
+                                    Context 
                                     );
 }
 
@@ -455,7 +489,7 @@
  * NOTE
  *  Spinlock held at entry !!
  */
-NTSTATUS
+BOOLEAN
 FASTCALL
 FsRtlpAddLock(
    IN PFILE_LOCK_TOC		   LockToc,
@@ -464,58 +498,60 @@
    IN PLARGE_INTEGER       Length,
    IN PEPROCESS            Process,
    IN ULONG                Key,
-   IN BOOLEAN              ExclusiveLock
+   IN BOOLEAN              ExclusiveLock,
+   IN PVOID                Context
    )
 {
    PLIST_ENTRY          EnumEntry;
    PFILE_LOCK_GRANTED   Granted;
+   LARGE_INTEGER        EndOffset;
+     
+   EndOffset.QuadPart = FileOffset->QuadPart + Length->QuadPart - 1;
 
-   EnumEntry = LockToc->GrantedListHead.Flink;
-   while (EnumEntry != &LockToc->GrantedListHead) 
+   //loop and try to find conflicking locks
+   LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
    {
       Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry);
-      //if overlapping
-      if(!(REQUEST_START_OFF > LOCK_END_OFF(Granted->Lock) || 
-         REQUEST_END_OFF < LOCK_START_OFF(Granted->Lock))) 
+      
+      if (IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset))
       {
-         //never conflict if shared lock and we want to add a shared lock
+         //we found a locks that overlap with the new lock
+   
+         //if both locks are shared, we might have a fast path outa here...
          if (!Granted->Lock.ExclusiveLock && !ExclusiveLock) 
          {
-            //AND if lock surround region, stop searching and insert lock
-            if (REQUEST_START_OFF >= LOCK_START_OFF(Granted->Lock) && 
-               REQUEST_END_OFF <= LOCK_END_OFF(Granted->Lock))
+            //if existing lock surround new lock, we know that no other exclusive lock
+            //may overlap with our new lock;-D
+            if (IsSurroundingLock(&Granted->Lock, FileOffset, &EndOffset))
             {
-               EnumEntry = &LockToc->GrantedListHead;
                break;
             }
+            
             //else keep locking for conflicts
+            continue;
          }
-         else 
-         {//conflict if we want share access to excl. lock OR exlc. access to shared lock
-            break;//FAIL
-         }
+         
+         //we found a conflict: 
+         //we want shared access to an excl. lock OR exlc. access to a shared lock
+         return FALSE;
       }
-      EnumEntry = EnumEntry->Flink;
    }
 
-   if (EnumEntry == &LockToc->GrantedListHead) 
-   {//no conflict
-      Granted = ExAllocateFromNPagedLookasideList(&GrantedLookaside);
-
-      Granted->Lock.StartingByte = *FileOffset;
-      Granted->Lock.Length = *Length;
-      Granted->Lock.ExclusiveLock = ExclusiveLock;
-      Granted->Lock.Key = Key;
-      Granted->Lock.FileObject = FileObject;
-      Granted->Lock.Process = Process;
-      Granted->Lock.EndingByte.QuadPart = REQUEST_END_OFF;
+   Granted = ExAllocateFromNPagedLookasideList(&GrantedLookaside);
 
-      InsertHeadList(&LockToc->GrantedListHead,&Granted->ListEntry);
-      return TRUE;
-   }
-
-   return FALSE;
+   //starting offset
+   Granted->Lock.StartingByte = *FileOffset;
+   Granted->Lock.Length = *Length;
+   Granted->Lock.ExclusiveLock = ExclusiveLock;
+   Granted->Lock.Key = Key;
+   Granted->Lock.FileObject = FileObject;
+   Granted->Lock.Process = Process;
+   //ending offset
+   Granted->Lock.EndingByte = EndOffset;
+   Granted->UnlockContext = Context;
 
+   InsertHeadList(&LockToc->GrantedListHead,&Granted->ListEntry);
+   return TRUE;
 }
 
 
@@ -532,19 +568,20 @@
 FsRtlpCompletePendingLocks(
    IN       PFILE_LOCK     FileLock,
    IN       PFILE_LOCK_TOC LockToc,
-   IN OUT   PKIRQL         oldirql
+   IN OUT   PKIRQL         oldirql,
+   IN       PVOID          Context
    )
 {
    //walk pending list, FIFO order, try 2 complete locks
    PLIST_ENTRY                   EnumEntry;
    PIRP                          Irp;
    PIO_STACK_LOCATION            Stack;
-
-   EnumEntry = LockToc->PendingListHead.Blink;
-   while (EnumEntry != &LockToc->PendingListHead) 
+   LIST_ENTRY                    CompletedListHead;
+   
+   InitializeListHead(&CompletedListHead);
+   
+   LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->PendingListHead, Irp, IRP, Tail.Overlay.ListEntry) 
    {
-      Irp = CONTAINING_RECORD(EnumEntry,IRP, Tail.Overlay.ListEntry);
-
       Stack = IoGetCurrentIrpStackLocation(Irp);
       if (FsRtlpAddLock(LockToc,
                         Stack->FileObject,
@@ -552,55 +589,65 @@
                         Stack->Parameters.LockControl.Length,
                         IoGetRequestorProcess(Irp),
                         Stack->Parameters.LockControl.Key,
-                        Stack->Flags & SL_EXCLUSIVE_LOCK
+                        Stack->Flags & SL_EXCLUSIVE_LOCK,
+                        Irp->Tail.Overlay.DriverContext[2] //Context
                         ) ) 
       {
          RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
 
          if (!IoSetCancelRoutine(Irp, NULL))
          {
-            /*
-            Cancel routine WILL be called after we release the spinlock. It will try to remove 
-            the irp from the list and cancel/complete this irp. Since we allready removed it, 
-            make its ListEntry point to itself.
-            */
+            //irp is canceled and cancelroutine will run when we release the lock
             InitializeListHead(&Irp->Tail.Overlay.ListEntry);
+            continue;
          }
-         else
-         {
-            /*
-            Cancel routine will NOT be called, canceled or not.
 
-            Put on completed list and complete them all afterwards.
-            This way we don't have to restart enum after each completion.
-            */
-            Irp->IoStatus.Status = STATUS_SUCCESS;
-            Irp->IoStatus.Information = 0;
-            InsertHeadList(&LockToc->CompletedListHead,&Irp->Tail.Overlay.ListEntry);
-         }
+         /*
+         Put on completed list and complete them all afterwards.
+         This way we don't have to restart enum after each completion.
+         */
+         InsertHeadList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry);
       }
-      EnumEntry = EnumEntry->Blink;
    }
 
+   KeReleaseSpinLock(&LockToc->SpinLock, *oldirql);
+   
    //complete irp's (if any)
-   while (!IsListEmpty(&LockToc->CompletedListHead)) 
+   while (!IsListEmpty(&CompletedListHead)) 
    {
-      EnumEntry = RemoveTailList(&LockToc->CompletedListHead);
-      KeReleaseSpinLock(&LockToc->SpinLock, *oldirql);//fires cancel routine
+      EnumEntry = RemoveTailList(&CompletedListHead);
+      
       Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry);
 
+      Irp->IoStatus.Status = STATUS_SUCCESS;
+      Irp->IoStatus.Information = 0;
+
       if (FileLock->CompleteLockIrpRoutine)
       {
-         FileLock->CompleteLockIrpRoutine(Irp->Tail.Overlay.DriverContext[2], Irp);
+         if (FileLock->CompleteLockIrpRoutine(Context, Irp)!=STATUS_SUCCESS)
+         {
+            Stack = IoGetCurrentIrpStackLocation(Irp);
+               
+            //revert  
+            FsRtlpUnlockSingle ( FileLock,
+                                    Stack->FileObject,
+                                    &Stack->Parameters.LockControl.ByteOffset,
+                                    Stack->Parameters.LockControl.Length,
+                                    IoGetRequestorProcess(Irp),
+                                    Stack->Parameters.LockControl.Key,
+                                    NULL, /* unused context */
+                                    FALSE /* don't call unlock copletion rout.*/
+                                    );
+         }
       }
       else
       {
-         IofCompleteRequest(Irp, IO_NO_INCREMENT);
+         IoCompleteRequest(Irp, IO_NO_INCREMENT);
       }
 
-      KeAcquireSpinLock(&LockToc->SpinLock, oldirql);
    }
 
+   KeAcquireSpinLock(&LockToc->SpinLock, oldirql);
 }
 
 
@@ -620,7 +667,6 @@
    IN PEPROCESS            Process,
    IN ULONG                Key,
    IN PVOID                Context OPTIONAL,
-   IN BOOLEAN              AlreadySynchronized,
    IN BOOLEAN              CallUnlockRoutine
    )
 {
@@ -632,18 +678,16 @@
    ASSERT(FileLock);
    LockToc = FileLock->LockInformation;
 
-   if (LockToc == NULL || Length->QuadPart == 0)
+   if (LockToc == NULL)
    {
       return STATUS_RANGE_NOT_LOCKED;
    }
 
    KeAcquireSpinLock(&LockToc->SpinLock, &oldirql );
 
-   EnumEntry = LockToc->GrantedListHead.Flink;
-   while (EnumEntry != &LockToc->GrantedListHead) 
+   LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted,FILE_LOCK_GRANTED,ListEntry) 
    {
-      Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED,ListEntry);
-
+     
       //must be exact match
       if (FileOffset->QuadPart == Granted->Lock.StartingByte.QuadPart &&
          Length->QuadPart == Granted->Lock.Length.QuadPart &&
@@ -652,12 +696,13 @@
          Granted->Lock.Key == Key) 
       {
          RemoveEntryList(&Granted->ListEntry);
-         FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql);
+         FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql, Context);
 
          if (IsListEmpty(&LockToc->GrantedListHead))
          {
             KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
-            FsRtlAreThereCurrentFileLocks(FileLock) = FALSE;
+            
+            FsRtlAreThereCurrentFileLocks(FileLock) = FALSE; //paged data
          }
          else
          {
@@ -666,14 +711,13 @@
 
          if (FileLock->UnlockRoutine && CallUnlockRoutine)
          {
-            FileLock->UnlockRoutine(Context,&Granted->Lock);
+            FileLock->UnlockRoutine(Granted->UnlockContext, &Granted->Lock);
          }
 
-         ExFreeToNPagedLookasideList(&GrantedLookaside,Granted);
+         ExFreeToNPagedLookasideList(&GrantedLookaside, Granted);
 
          return STATUS_SUCCESS;
       }
-      EnumEntry = EnumEntry->Flink;
    }
 
    KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
@@ -710,8 +754,7 @@
                               Process,
                               Key,
                               Context,
-                              AlreadySynchronized,
-                              TRUE//CallUnlockRoutine
+                              TRUE /* call unlock copletion routine */
                               );
 }
 
@@ -747,11 +790,10 @@
 
    KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
 
-   EnumEntry = LockToc->GrantedListHead.Blink;
-   while ( EnumEntry != &LockToc->GrantedListHead)
+   LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
    {
-      Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry );
-
+      Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry);
+      
       DPRINT1("%s, start: %i, len: %i, end: %i, key: %i, proc: 0x%X, fob: 0x%X\n",
          Granted->Lock.ExclusiveLock ? "EXCL" : "SHRD",
          Granted->Lock.StartingByte.QuadPart,
@@ -762,16 +804,13 @@
          Granted->Lock.FileObject
          );
 
-      EnumEntry = EnumEntry->Blink;
    }
 
    DPRINT1("Dumping pending file locks, FIFO order\n");
 
-   EnumEntry = LockToc->PendingListHead.Blink;
-   while ( EnumEntry != &LockToc->PendingListHead)
+   LIST_FOR_EACH(EnumEntry, &LockToc->PendingListHead)
    {
-      Irp = CONTAINING_RECORD(EnumEntry, IRP , Tail.Overlay.ListEntry );
-
+      Irp = CONTAINING_RECORD(EnumEntry, IRP , Tail.Overlay.ListEntry);
       Stack = IoGetCurrentIrpStackLocation(Irp);
 
       DPRINT1("%s, start: %i, len: %i, end: %i, key: %i, proc: 0x%X, fob: 0x%X\n",
@@ -784,7 +823,6 @@
          Stack->FileObject
          );
 
-      EnumEntry = EnumEntry->Blink;
    }
 
    KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
@@ -939,7 +977,7 @@
    IN BOOLEAN              ExclusiveLock,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PIRP                 Irp OPTIONAL,
-   IN PVOID                Context,
+   IN PVOID                Context OPTIONAL,
    IN BOOLEAN              AlreadySynchronized
    )
 {
@@ -958,8 +996,6 @@
          KeInitializeSpinLock(&LockToc->SpinLock);
          InitializeListHead(&LockToc->GrantedListHead);
          InitializeListHead(&LockToc->PendingListHead);
-         InitializeListHead(&LockToc->CompletedListHead);
-         InitializeListHead(&LockToc->UnlockedListHead);
       }
       ExReleaseFastMutex(&LockTocMutex);
    }
@@ -974,43 +1010,36 @@
                      Length,
                      Process,
                      Key,
-                     ExclusiveLock
+                     ExclusiveLock,
+                     Context 
                      ) ) 
    {
       IoStatus->Status = STATUS_SUCCESS;
    }
    else if (Irp && !FailImmediately) 
-   {	//failed + irp + no fail = mk. pending
-      //for our cancel routine
-      Irp->Tail.Overlay.DriverContext[0] = (PVOID)FileLock;
-      Irp->Tail.Overlay.DriverContext[1] = (PVOID)LockToc;
-      Irp->Tail.Overlay.DriverContext[2] = Context;
+   {	
+      //failed + irp + no fail = make. pending
 
+      Irp->Tail.Overlay.DriverContext[3] = &LockToc->SpinLock;
+      Irp->Tail.Overlay.DriverContext[2] = Context;
+      
       IoSetCancelRoutine(Irp, FsRtlpFileLockCancelRoutine);
-
-      if (Irp->Cancel) 
-      {
-         //irp canceled even before we got to queue it
-         if (IoSetCancelRoutine(Irp, NULL))
-         {  //Cancel routine will NOT be called: cancel it here
-            IoStatus->Status = STATUS_CANCELLED; 
-         }
-         else
-         {  //Cancel routine WILL be called. When we release the lock it will complete the irp
-            //Return pending since we are not completing the irp here
-            Irp->IoStatus.Status = IoStatus->Status = STATUS_PENDING;
-            Irp->IoStatus.Information = 0;
-            InitializeListHead(&Irp->Tail.Overlay.ListEntry);
-         }
+      if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
+      {              
+         //irp was canceled
+         KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
          
+         Irp->IoStatus.Status = STATUS_CANCELLED;
+         Irp->IoStatus.Information = 0;
+         IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+         return TRUE;
       }
-      else 
-      {  //not cancelled: queue irp
-         IoMarkIrpPending(Irp);
+
+      IoMarkIrpPending(Irp);
          Irp->IoStatus.Status = IoStatus->Status = STATUS_PENDING;
          Irp->IoStatus.Information = 0;
-         InsertHeadList(&LockToc->PendingListHead,&Irp->Tail.Overlay.ListEntry);
-      }
+      InsertHeadList(&LockToc->PendingListHead,&Irp->Tail.Overlay.ListEntry);
 
    }
    else 
@@ -1034,11 +1063,9 @@
       {
          Irp->IoStatus.Status = IoStatus->Status;
          Irp->IoStatus.Information = 0;
-
          if (FileLock->CompleteLockIrpRoutine) 
-         { //complete irp routine
-
-            if (!NT_SUCCESS(FileLock->CompleteLockIrpRoutine(Context,Irp))) 
+         {
+            if (FileLock->CompleteLockIrpRoutine(Context,Irp)!=STATUS_SUCCESS) 
             {
                //CompleteLockIrpRoutine complain: revert changes
                FsRtlpUnlockSingle(  FileLock,
@@ -1047,15 +1074,14 @@
                                     Length,
                                     Process,
                                     Key,
-                                    Context,
-                                    AlreadySynchronized,
-                                    FALSE//CallUnlockRoutine
+                                    NULL, /* context */
+                                    FALSE  /* don't call unlock copletion routine */
                                     );
             }
          }
          else 
-         {//std irp completion
-            IofCompleteRequest(Irp, IO_NO_INCREMENT);
+         {
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
          }
       }
    }
@@ -1115,7 +1141,7 @@
                                           Stack->Parameters.LockControl.Length,
                                           IoGetRequestorProcess(Irp),
                                           Stack->Parameters.LockControl.Key,
-                                          Context,
+                                          Context, 
                                           FALSE);
          break;
 
@@ -1123,7 +1149,7 @@
          Status = FsRtlFastUnlockAll(  FileLock,
                                        Stack->FileObject,
                                        IoGetRequestorProcess(Irp),
-                                       Context);
+                                       Context );
          break;
 
       case IRP_MN_UNLOCK_ALL_BY_KEY:
@@ -1131,26 +1157,21 @@
                                              Stack->FileObject,
                                              IoGetRequestorProcess(Irp),
                                              Stack->Parameters.LockControl.Key,
-                                             Context);
+                                             Context );
 
          break;
 
       default:
          Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST;
-         IofCompleteRequest(Irp, IO_NO_INCREMENT);
+         IoCompleteRequest(Irp, IO_NO_INCREMENT);
          return Status;
    }
 
-   Irp->IoStatus.Status = Status;
 
-   if (FileLock->CompleteLockIrpRoutine )
-   {
-      FileLock->CompleteLockIrpRoutine(Context,Irp);
-   }
-   else
-   {
-      IofCompleteRequest(Irp,IO_NO_INCREMENT);
-   }
+   Irp->IoStatus.Status = Status;
+   Irp->IoStatus.Information = 0;
+   
+   IoCompleteRequest(Irp,IO_NO_INCREMENT);
 
    return Status;
 }
@@ -1202,28 +1223,17 @@
       {  
          //The cancel routine will be called. When we release the lock it will complete the irp.
          InitializeListHead(&Irp->Tail.Overlay.ListEntry);
+         continue;
       }
-      else
-      {
-         /*
-         Cancel routine will NOT be called, even though the irp might have been canceled.
-         Don't care since we'l complete it faster than the cancel routine would have.
-         */
-         KeReleaseSpinLock(&LockToc->SpinLock, oldirql);//fires cancel routine	
 
-         Irp->IoStatus.Status = STATUS_RANGE_NOT_LOCKED;
-   
-         if (FileLock->CompleteLockIrpRoutine)
-         {
-            FileLock->CompleteLockIrpRoutine(Irp->Tail.Overlay.DriverContext[2], Irp);
-         }
-         else
-         {
-            IofCompleteRequest(Irp, IO_NO_INCREMENT);
-         }
+      KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
+
+      Irp->IoStatus.Status = STATUS_RANGE_NOT_LOCKED;
+      Irp->IoStatus.Information = 0;
+      IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+      KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
 
-         KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
-      }
    }
 
    KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
@@ -1311,4 +1321,5 @@
     UNIMPLEMENTED;
 }
 
+
 /* EOF */

reactos/ntoskrnl/include/internal
ifs.h 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- ifs.h	14 Aug 2003 18:30:28 -0000	1.6
+++ ifs.h	30 Dec 2004 02:30:40 -0000	1.7
@@ -1,6 +1,6 @@
 #ifndef __INCLUDE_INTERNAL_IFS_H
 #define __INCLUDE_INTERNAL_IFS_H
-/* $Id: ifs.h,v 1.6 2003/08/14 18:30:28 silverblade Exp $ */
+/* $Id: ifs.h,v 1.7 2004/12/30 02:30:40 gdalsnes Exp $ */
 
 #include <ddk/ntifs.h>
 #include <ntos.h>
@@ -38,7 +38,7 @@
     IN PVOID                Context OPTIONAL
     );
 
-NTSTATUS FASTCALL
+BOOLEAN FASTCALL
 FsRtlpAddLock(
     IN PFILE_LOCK_TOC		LockToc,
     IN PFILE_OBJECT         FileObject,
@@ -46,14 +46,16 @@
     IN PLARGE_INTEGER       Length,
     IN PEPROCESS            Process,
     IN ULONG                Key,
-    IN BOOLEAN              ExclusiveLock
+    IN BOOLEAN              ExclusiveLock,
+    IN PVOID                UnlockContext
 	);
 
 VOID FASTCALL
 FsRtlpCompletePendingLocks(
 	IN		PFILE_LOCK		FileLock,
 	IN		PFILE_LOCK_TOC	LockToc,
-	IN OUT	PKIRQL			oldirql
+	IN OUT	PKIRQL			oldirql,
+   IN    PVOID          Context
 	);
 
 NTSTATUS FASTCALL
@@ -65,7 +67,6 @@
     IN PEPROCESS            Process,
     IN ULONG                Key,
     IN PVOID                Context OPTIONAL,
-    IN BOOLEAN              AlreadySynchronized,
 	IN BOOLEAN				CallUnlockRoutine
 	);
 
CVSspam 0.2.8