2018-04-28 07:34:10 +00:00
|
|
|
/*
|
2022-09-24 13:24:08 +00:00
|
|
|
* PROJECT: VFAT Filesystem
|
|
|
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
|
|
|
* PURPOSE: KDBG extension
|
|
|
|
* COPYRIGHT: Copyright 2018 Pierre Schweitzer <pierre@reactos.org>
|
|
|
|
*/
|
2018-04-28 07:34:10 +00:00
|
|
|
|
|
|
|
/* ------------------------------------------------------- INCLUDES */
|
|
|
|
|
|
|
|
#include "vfat.h"
|
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
/* -------------------------------------------------------- DEFINES */
|
|
|
|
|
|
|
|
#ifdef KDBG
|
|
|
|
UNICODE_STRING DebugFile = {0, 0, NULL};
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
vfatKdbgHandler(
|
|
|
|
IN PCHAR Command,
|
|
|
|
IN ULONG Argc,
|
|
|
|
IN PCH Argv[])
|
|
|
|
{
|
|
|
|
ULONG Len;
|
|
|
|
|
|
|
|
Len = strlen(Command);
|
|
|
|
if (Len < sizeof("?fat."))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Command[0] != '?' || Command[1] != 'f' ||
|
|
|
|
Command[2] != 'a' || Command[3] != 't' ||
|
|
|
|
Command[4] != '.')
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Command += (sizeof("?fat.") - sizeof(ANSI_NULL));
|
|
|
|
if (strcmp(Command, "vols") == 0)
|
|
|
|
{
|
|
|
|
ULONG Count = 0;
|
|
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
PDEVICE_EXTENSION DeviceExt;
|
|
|
|
|
|
|
|
for (ListEntry = VfatGlobalData->VolumeListHead.Flink;
|
|
|
|
ListEntry != &VfatGlobalData->VolumeListHead;
|
|
|
|
ListEntry = ListEntry->Flink)
|
|
|
|
{
|
|
|
|
DeviceExt = CONTAINING_RECORD(ListEntry, DEVICE_EXTENSION, VolumeListEntry);
|
|
|
|
DPRINT1("Volume: %p with VCB: %p\n", DeviceExt->VolumeDevice, DeviceExt);
|
|
|
|
++Count;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Count == 0)
|
|
|
|
{
|
|
|
|
DPRINT1("No volume found\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strcmp(Command, "files") == 0)
|
|
|
|
{
|
|
|
|
if (Argc != 2)
|
|
|
|
{
|
|
|
|
DPRINT1("Please provide a volume or a VCB!\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
PDEVICE_EXTENSION DeviceExt;
|
|
|
|
|
|
|
|
for (ListEntry = VfatGlobalData->VolumeListHead.Flink;
|
|
|
|
ListEntry != &VfatGlobalData->VolumeListHead;
|
|
|
|
ListEntry = ListEntry->Flink)
|
|
|
|
{
|
|
|
|
CHAR Volume[17];
|
|
|
|
|
|
|
|
DeviceExt = CONTAINING_RECORD(ListEntry, DEVICE_EXTENSION, VolumeListEntry);
|
|
|
|
sprintf(Volume, "%p", DeviceExt);
|
|
|
|
if (strcmp(Volume, Argv[1]) == 0)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(Volume, "%p", DeviceExt->VolumeDevice);
|
|
|
|
if (strcmp(Volume, Argv[1]) == 0)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
DeviceExt = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DeviceExt == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("No volume %s found!\n", Argv[1]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PVFATFCB Fcb;
|
|
|
|
|
|
|
|
for (ListEntry = DeviceExt->FcbListHead.Flink;
|
|
|
|
ListEntry != &DeviceExt->FcbListHead;
|
|
|
|
ListEntry = ListEntry->Flink)
|
|
|
|
{
|
|
|
|
Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
|
[FASTFAT] Implement delayed close
When we're about to close a file (ie, forget everything about it
and release any associated structure), actually delay it.
This allows keep data fresh in memory for faster reuse in case
it would be required. The effective closing will only happen after some time.
For specific operations, this will produce a real speed up in ReactOS.
For instance, with that patch, Winamp starts within seconds, instead of dozen
of minutes.
In most cases, it will bring ReactOS to performances it had before fixing
the huge leak in FastFAT (commit 94ead99) without leaking the whole FS.
For now, due to regressions, this is only activated for files and not
for directories. Once it gets fixed, it will be enabled for both.
CORE-14826
CORE-14917
2018-08-18 15:04:02 +00:00
|
|
|
DPRINT1("FCB %p (ref: %d, oc: %d %s %s %s) for FO %p with path: %.*S\n",
|
2018-04-28 07:34:10 +00:00
|
|
|
Fcb, Fcb->RefCount, Fcb->OpenHandleCount,
|
|
|
|
((Fcb->Flags & FCB_CLEANED_UP) ? "U" : "NU"),
|
|
|
|
((Fcb->Flags & FCB_CLOSED) ? "C" : "NC"),
|
[FASTFAT] Implement delayed close
When we're about to close a file (ie, forget everything about it
and release any associated structure), actually delay it.
This allows keep data fresh in memory for faster reuse in case
it would be required. The effective closing will only happen after some time.
For specific operations, this will produce a real speed up in ReactOS.
For instance, with that patch, Winamp starts within seconds, instead of dozen
of minutes.
In most cases, it will bring ReactOS to performances it had before fixing
the huge leak in FastFAT (commit 94ead99) without leaking the whole FS.
For now, due to regressions, this is only activated for files and not
for directories. Once it gets fixed, it will be enabled for both.
CORE-14826
CORE-14917
2018-08-18 15:04:02 +00:00
|
|
|
((Fcb->Flags & FCB_DELAYED_CLOSE) ? "D" : "ND"),
|
2018-04-28 07:34:10 +00:00
|
|
|
Fcb->FileObject, Fcb->PathNameU.Length, Fcb->PathNameU.Buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (strcmp(Command, "setdbgfile") == 0)
|
|
|
|
{
|
|
|
|
if (Argc < 2)
|
|
|
|
{
|
|
|
|
if (DebugFile.Buffer != NULL)
|
|
|
|
{
|
|
|
|
ExFreePool(DebugFile.Buffer);
|
|
|
|
DebugFile.Length = 0;
|
|
|
|
DebugFile.MaximumLength = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT1("Debug file reset\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ANSI_STRING Source;
|
|
|
|
|
|
|
|
if (DebugFile.Buffer != NULL)
|
|
|
|
{
|
|
|
|
ExFreePool(DebugFile.Buffer);
|
|
|
|
DebugFile.Length = 0;
|
|
|
|
DebugFile.MaximumLength = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlInitAnsiString(&Source, Argv[1]);
|
|
|
|
Status = RtlAnsiStringToUnicodeString(&DebugFile, &Source, TRUE);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Debug file set to: %.*S\n", DebugFile.Length, DebugFile.Buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT1("Unknown command: %s\n", Command);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
#endif
|