&ByteOffset,
NULL);
/* If it fails or returns inconsistent data, drop it (= truncate) */
- if (!NT_SUCCESS(Status) || IoStatusBlock.Information != EntrySize || EntrySize < sizeof(DATABASE_ENTRY))
+ if (!NT_SUCCESS(Status) ||
+ (IoStatusBlock.Information != EntrySize) ||
+ (EntrySize < sizeof(DATABASE_ENTRY)) )
{
TruncateRemoteDatabase(Database, StartingOffset);
FreePool(Entry);
/* Validate entry */
if (MAX(Entry->SymbolicNameOffset + Entry->SymbolicNameLength,
- Entry->UniqueIdOffset + Entry->UniqueIdLength) > EntrySize)
+ Entry->UniqueIdOffset + Entry->UniqueIdLength) > (LONG)EntrySize)
{
TruncateRemoteDatabase(Database, StartingOffset);
FreePool(Entry);
return Entry;
}
+/*
+ * @implemented
+ */
NTSTATUS
DeleteRemoteDatabaseEntry(IN HANDLE Database,
IN LONG StartingOffset)
{
- return STATUS_NOT_IMPLEMENTED;
+ ULONG EndSize;
+ PVOID TmpBuffer;
+ NTSTATUS Status;
+ ULONG DatabaseSize;
+ PDATABASE_ENTRY Entry;
+ IO_STATUS_BLOCK IoStatusBlock;
+ LARGE_INTEGER EndEntriesOffset;
+
+ /* First, get database size */
+ DatabaseSize = GetRemoteDatabaseSize(Database);
+ if (!DatabaseSize)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Then, get the entry to remove */
+ Entry = GetRemoteDatabaseEntry(Database, StartingOffset);
+ if (!Entry)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Validate parameters: ensure we won't get negative size */
+ if (Entry->EntrySize + StartingOffset > DatabaseSize)
+ {
+ /* If we get invalid parameters, truncate the whole database
+ * starting the wrong entry. We can't rely on the rest
+ */
+ FreePool(Entry);
+ return TruncateRemoteDatabase(Database, StartingOffset);
+ }
+
+ /* Now, get the size of the remaining entries (those after the one to remove) */
+ EndSize = DatabaseSize - Entry->EntrySize - StartingOffset;
+ /* Allocate a buffer big enough to hold them */
+ TmpBuffer = AllocatePool(EndSize);
+ if (!TmpBuffer)
+ {
+ FreePool(Entry);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Get the offset of the entry right after the one to delete */
+ EndEntriesOffset.QuadPart = Entry->EntrySize + StartingOffset;
+ /* We don't need the entry any more */
+ FreePool(Entry);
+
+ /* Read the ending entries */
+ Status = ZwReadFile(Database, NULL, NULL, NULL, &IoStatusBlock,
+ TmpBuffer, EndSize, &EndEntriesOffset, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ FreePool(TmpBuffer);
+ return Status;
+ }
+
+ /* Ensure nothing went wrong - we don't want to corrupt the DB */
+ if (IoStatusBlock.Information != EndSize)
+ {
+ FreePool(TmpBuffer);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Remove the entry */
+ Status = TruncateRemoteDatabase(Database, StartingOffset + EndSize);
+ if (!NT_SUCCESS(Status))
+ {
+ FreePool(TmpBuffer);
+ return Status;
+ }
+
+ /* Now, shift the ending entries to erase the entry */
+ EndEntriesOffset.QuadPart = StartingOffset;
+ Status = ZwWriteFile(Database, NULL, NULL, NULL, &IoStatusBlock,
+ TmpBuffer, EndSize, &EndEntriesOffset, NULL);
+
+ FreePool(TmpBuffer);
+
+ return Status;
}
/*
/* Acquire workers lock */
KeWaitForSingleObject(&(DeviceExtension->WorkerSemaphore), Executive, KernelMode, FALSE, NULL);
- OldIrql = KfAcquireSpinLock(&(DeviceExtension->WorkerLock));
+ KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
+
/* Ensure there are workers */
while (!IsListEmpty(&(DeviceExtension->WorkerQueueListHead)))
{
RECONCILE_WORK_ITEM,
WorkerQueueListEntry);
- KfReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
+ KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
/* Call it */
WorkItem->WorkerRoutine(WorkItem->Context);
}
KeWaitForSingleObject(&(DeviceExtension->WorkerSemaphore), Executive, KernelMode, FALSE, NULL);
- OldIrql = KfAcquireSpinLock(&(DeviceExtension->WorkerLock));
+ KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
}
- KfReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
+ KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
InterlockedDecrement(&(DeviceExtension->WorkerReferences));
}
/* Otherwise queue worker for delayed execution */
- OldIrql = KfAcquireSpinLock(&(DeviceExtension->WorkerLock));
+ KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
InsertTailList(&(DeviceExtension->WorkerQueueListHead),
&(WorkItem->WorkerQueueListEntry));
- KfReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
+ KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
KeReleaseSemaphore(&(DeviceExtension->WorkerSemaphore), IO_NO_INCREMENT, 1, FALSE);
}
/* Return the volume name */
- VolumeName->Length = FileNameInfo->FileNameLength;
- VolumeName->MaximumLength = FileNameInfo->FileNameLength + sizeof(WCHAR);
+ VolumeName->Length = (USHORT)FileNameInfo->FileNameLength;
+ VolumeName->MaximumLength = (USHORT)FileNameInfo->FileNameLength + sizeof(WCHAR);
VolumeName->Buffer = AllocatePool(VolumeName->MaximumLength);
if (!VolumeName->Buffer)
{
}
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
- Status == STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
Complete = TRUE;
}
if (!NT_SUCCESS(Status) || Complete)
}
/* And write them into new database */
- Length = IoStatusBlock.Information;
+ Length = (ULONG)IoStatusBlock.Information;
Status = ZwWriteFile(Database,
NULL,
NULL,
if (IntUniqueId)
{
/* Copy data & return */
- IntUniqueId->UniqueIdLength = ValueLength;
+ IntUniqueId->UniqueIdLength = (USHORT)ValueLength;
RtlCopyMemory(&(IntUniqueId->UniqueId), ValueData, ValueLength);
UniqueId = Context;