}
LOCK_SHARED_RANGE, *PLOCK_SHARED_RANGE;
+#define TAG_TABLE 'LTAB'
+#define TAG_RANGE 'FSRA'
+#define TAG_FLOCK 'FLCK'
+
/* PRIVATE FUNCTIONS *********************************************************/
VOID
static PVOID NTAPI LockAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes)
{
PVOID Result;
- Result = ExAllocatePoolWithTag(NonPagedPool, Bytes, 'LTAB');
- DPRINT("LockAllocate(%d) => %p\n", Bytes, Result);
+ Result = ExAllocatePoolWithTag(NonPagedPool, Bytes, TAG_TABLE);
+ DPRINT("LockAllocate(%lu) => %p\n", Bytes, Result);
return Result;
}
static VOID NTAPI LockFree(PRTL_GENERIC_TABLE Table, PVOID Buffer)
{
DPRINT("LockFree(%p)\n", Buffer);
- ExFreePoolWithTag(Buffer, 'LTAB');
+ ExFreePoolWithTag(Buffer, TAG_TABLE);
}
static RTL_GENERIC_COMPARE_RESULTS NTAPI LockCompare
ULARGE_INTEGER UnsignedStart;
ULARGE_INTEGER UnsignedEnd;
- DPRINT("FsRtlPrivateLock(%wZ, Offset %08x%08x (%d), Length %08x%08x (%d), Key %x, FailImmediately %d, Exclusive %d)\n",
+ DPRINT("FsRtlPrivateLock(%wZ, Offset %08x%08x (%d), Length %08x%08x (%d), Key %x, FailImmediately %u, Exclusive %u)\n",
&FileObject->FileName,
FileOffset->HighPart,
FileOffset->LowPart,
/* Initialize the lock, if necessary */
if (!FileLock->LockInformation)
{
- LockInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(LOCK_INFORMATION), 'FLCK');
+ LockInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(LOCK_INFORMATION), TAG_FLOCK);
if (!LockInfo)
{
IoStatus->Status = STATUS_NO_MEMORY;
{
if (Conflict->Exclusive.FileLock.ExclusiveLock || ExclusiveLock)
{
- DPRINT("Conflict %08x%08x:%08x%08x Exc %d (Want Exc %d)\n",
+ DPRINT("Conflict %08x%08x:%08x%08x Exc %u (Want Exc %u)\n",
Conflict->Exclusive.FileLock.StartingByte.HighPart,
Conflict->Exclusive.FileLock.StartingByte.LowPart,
Conflict->Exclusive.FileLock.EndingByte.HighPart,
}
return FALSE;
}
- else
- {
- DPRINT("Overlapping shared lock %wZ %08x%08x %08x%08x\n",
- &FileObject->FileName,
- Conflict->Exclusive.FileLock.StartingByte.HighPart,
- Conflict->Exclusive.FileLock.StartingByte.LowPart,
- Conflict->Exclusive.FileLock.EndingByte.HighPart,
- Conflict->Exclusive.FileLock.EndingByte.LowPart);
- Conflict = FsRtlpRebuildSharedLockRange(FileLock,
- LockInfo,
- &ToInsert);
- if (!Conflict)
- {
- IoStatus->Status = STATUS_NO_MEMORY;
- if (Irp)
- {
- FsRtlCompleteLockIrpReal
- (FileLock->CompleteLockIrpRoutine,
- Context,
- Irp,
- IoStatus->Status,
- &Status,
- FileObject);
- }
- break;
- }
- }
+ }
+ }
+
+ DPRINT("Overlapping shared lock %wZ %08x%08x %08x%08x\n",
+ &FileObject->FileName,
+ Conflict->Exclusive.FileLock.StartingByte.HighPart,
+ Conflict->Exclusive.FileLock.StartingByte.LowPart,
+ Conflict->Exclusive.FileLock.EndingByte.HighPart,
+ Conflict->Exclusive.FileLock.EndingByte.LowPart);
+ Conflict = FsRtlpRebuildSharedLockRange(FileLock,
+ LockInfo,
+ &ToInsert);
+ if (!Conflict)
+ {
+ IoStatus->Status = STATUS_NO_MEMORY;
+ if (Irp)
+ {
+ FsRtlCompleteLockIrpReal
+ (FileLock->CompleteLockIrpRoutine,
+ Context,
+ Irp,
+ IoStatus->Status,
+ &Status,
+ FileObject);
}
}
DPRINT("Adding shared lock %wZ\n", &FileObject->FileName);
NewSharedRange =
- ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), 'FSRA');
+ ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), TAG_RANGE);
if (!NewSharedRange)
{
IoStatus->Status = STATUS_NO_MEMORY;
return FALSE;
}
DPRINT("Adding shared lock %wZ\n", &FileObject->FileName);
- NewSharedRange->Start = ToInsert.Exclusive.FileLock.StartingByte;
- NewSharedRange->End = ToInsert.Exclusive.FileLock.EndingByte;
+ NewSharedRange->Start = *FileOffset;
+ NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart;
NewSharedRange->Key = Key;
NewSharedRange->ProcessId = ToInsert.Exclusive.FileLock.ProcessId;
InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry);
}
else
{
- DPRINT("Inserted new lock %wZ %08x%08x %08x%08x exclusive %d\n",
+ DPRINT("Inserted new lock %wZ %08x%08x %08x%08x exclusive %u\n",
&FileObject->FileName,
Conflict->Exclusive.FileLock.StartingByte.HighPart,
Conflict->Exclusive.FileLock.StartingByte.LowPart,
if (!ExclusiveLock)
{
NewSharedRange =
- ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), 'FSRA');
+ ExAllocatePoolWithTag(NonPagedPool, sizeof(*NewSharedRange), TAG_RANGE);
if (!NewSharedRange)
{
IoStatus->Status = STATUS_NO_MEMORY;
return FALSE;
}
DPRINT("Adding shared lock %wZ\n", &FileObject->FileName);
- NewSharedRange->Start = ToInsert.Exclusive.FileLock.StartingByte;
- NewSharedRange->End = ToInsert.Exclusive.FileLock.EndingByte;
+ NewSharedRange->Start = *FileOffset;
+ NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart;
NewSharedRange->Key = Key;
- NewSharedRange->ProcessId = ToInsert.Exclusive.FileLock.ProcessId;
+ NewSharedRange->ProcessId = Process->UniqueProcessId;
InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry);
}
Find.Exclusive.FileLock.StartingByte = *FileOffset;
Find.Exclusive.FileLock.EndingByte.QuadPart =
FileOffset->QuadPart + Length->QuadPart;
- ASSERT(InternalInfo);
+ if (!InternalInfo) {
+ DPRINT("File not previously locked (ever)\n");
+ return STATUS_RANGE_NOT_LOCKED;
+ }
Entry = RtlLookupElementGenericTable(&InternalInfo->RangeTable, &Find);
if (!Entry) {
DPRINT("Range not locked %wZ\n", &FileObject->FileName);
return STATUS_RANGE_NOT_LOCKED;
}
- DPRINT("Found lock entry: Exclusive %d %08x%08x:%08x%08x %wZ\n",
+ DPRINT("Found lock entry: Exclusive %u %08x%08x:%08x%08x %wZ\n",
Entry->Exclusive.FileLock.ExclusiveLock,
Entry->Exclusive.FileLock.StartingByte.HighPart,
Entry->Exclusive.FileLock.StartingByte.LowPart,
}
if (FoundShared)
{
- PLIST_ENTRY SharedRangeEntry;
- PLOCK_SHARED_RANGE WatchSharedRange;
- COMBINED_LOCK_ELEMENT RemadeElement;
- Find.Exclusive.FileLock.StartingByte = SharedRange->Start;
- Find.Exclusive.FileLock.EndingByte = SharedRange->End;
- SharedEntry = SharedRange->Entry.Flink;
+ /* Remove the found range from the shared range lists */
RemoveEntryList(&SharedRange->Entry);
- ExFreePool(SharedRange);
+ ExFreePoolWithTag(SharedRange, TAG_RANGE);
/* We need to rebuild the list of shared ranges. */
DPRINT("Removing the lock entry %wZ (%08x%08x:%08x%08x)\n",
&FileObject->FileName,
Entry->Exclusive.FileLock.StartingByte.LowPart,
Entry->Exclusive.FileLock.EndingByte.HighPart,
Entry->Exclusive.FileLock.EndingByte.LowPart);
- /* Copy */
- RemadeElement = *Entry;
- RtlDeleteElementGenericTable(&InternalInfo->RangeTable, Entry);
+
+ /* Remember what was in there and remove it from the table */
+ Find = *Entry;
+ RtlDeleteElementGenericTable(&InternalInfo->RangeTable, &Find);
/* Put shared locks back in place */
- for (SharedRangeEntry = InternalInfo->SharedLocks.Flink;
- SharedRangeEntry != &InternalInfo->SharedLocks;
- SharedRangeEntry = SharedRangeEntry->Flink)
+ for (SharedEntry = InternalInfo->SharedLocks.Flink;
+ SharedEntry != &InternalInfo->SharedLocks;
+ SharedEntry = SharedEntry->Flink)
{
COMBINED_LOCK_ELEMENT LockElement;
- WatchSharedRange = CONTAINING_RECORD(SharedRangeEntry, LOCK_SHARED_RANGE, Entry);
- LockElement.Exclusive.FileLock.StartingByte = WatchSharedRange->Start;
- LockElement.Exclusive.FileLock.EndingByte = WatchSharedRange->End;
- if (LockCompare(&InternalInfo->RangeTable, &RemadeElement, &LockElement) != GenericEqual)
+ SharedRange = CONTAINING_RECORD(SharedEntry, LOCK_SHARED_RANGE, Entry);
+ LockElement.Exclusive.FileLock.FileObject = FileObject;
+ LockElement.Exclusive.FileLock.StartingByte = SharedRange->Start;
+ LockElement.Exclusive.FileLock.EndingByte = SharedRange->End;
+ LockElement.Exclusive.FileLock.ProcessId = SharedRange->ProcessId;
+ LockElement.Exclusive.FileLock.Key = SharedRange->Key;
+ LockElement.Exclusive.FileLock.ExclusiveLock = FALSE;
+
+ if (LockCompare(&InternalInfo->RangeTable, &Find, &LockElement) != GenericEqual)
{
DPRINT("Skipping range %08x%08x:%08x%08x\n",
LockElement.Exclusive.FileLock.StartingByte.HighPart,
LockElement.Exclusive.FileLock.StartingByte.LowPart,
LockElement.Exclusive.FileLock.EndingByte.HighPart,
LockElement.Exclusive.FileLock.EndingByte.LowPart);
- RtlZeroMemory(&RemadeElement, sizeof(RemadeElement));
- RemadeElement.Exclusive.FileLock.StartingByte = WatchSharedRange->Start;
- RemadeElement.Exclusive.FileLock.EndingByte = WatchSharedRange->End;
- FsRtlpRebuildSharedLockRange(FileLock, InternalInfo, &RemadeElement);
+ FsRtlpRebuildSharedLockRange(FileLock, InternalInfo, &LockElement);
}
}
else
return STATUS_RANGE_NOT_LOCKED;
}
}
-
+
+#ifndef NDEBUG
DPRINT("Lock still has:\n");
for (SharedEntry = InternalInfo->SharedLocks.Flink;
SharedEntry != &InternalInfo->SharedLocks;
SharedRange->End.LowPart,
SharedRange->Key);
}
+#endif
// this is definitely the thing we want
InternalInfo->Generation++;
{
SharedRange = CONTAINING_RECORD(SharedEntry, LOCK_SHARED_RANGE, Entry);
SharedEntry = SharedEntry->Flink;
- RemoveEntryList(SharedEntry);
- ExFreePool(SharedRange);
+ RemoveEntryList(&SharedRange->Entry);
+ ExFreePoolWithTag(SharedRange, TAG_RANGE);
}
while ((Entry = RtlGetElementGenericTable(&InternalInfo->RangeTable, 0)) != NULL)
{
{
FsRtlProcessFileLock(FileLock, Irp, NULL);
}
- ExFreePoolWithTag(InternalInfo, 'FLCK');
+ ExFreePoolWithTag(InternalInfo, TAG_FLOCK);
FileLock->LockInformation = NULL;
}
}