114c39362SHervé Poussineau /*
2*542e9f2bSStanislav Motylkov * PROJECT: VFAT Filesystem
3*542e9f2bSStanislav Motylkov * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4*542e9f2bSStanislav Motylkov * PURPOSE: KDBG extension
5*542e9f2bSStanislav Motylkov * COPYRIGHT: Copyright 2018 Pierre Schweitzer <pierre@reactos.org>
614c39362SHervé Poussineau */
714c39362SHervé Poussineau
814c39362SHervé Poussineau /* ------------------------------------------------------- INCLUDES */
914c39362SHervé Poussineau
1014c39362SHervé Poussineau #include "vfat.h"
1114c39362SHervé Poussineau
1214c39362SHervé Poussineau #define NDEBUG
1314c39362SHervé Poussineau #include <debug.h>
1414c39362SHervé Poussineau
1514c39362SHervé Poussineau #include <stdio.h>
1614c39362SHervé Poussineau
1714c39362SHervé Poussineau /* -------------------------------------------------------- DEFINES */
1814c39362SHervé Poussineau
1914c39362SHervé Poussineau #ifdef KDBG
2014c39362SHervé Poussineau UNICODE_STRING DebugFile = {0, 0, NULL};
2114c39362SHervé Poussineau
2214c39362SHervé Poussineau BOOLEAN
2314c39362SHervé Poussineau NTAPI
vfatKdbgHandler(IN PCHAR Command,IN ULONG Argc,IN PCH Argv[])2414c39362SHervé Poussineau vfatKdbgHandler(
2514c39362SHervé Poussineau IN PCHAR Command,
2614c39362SHervé Poussineau IN ULONG Argc,
2714c39362SHervé Poussineau IN PCH Argv[])
2814c39362SHervé Poussineau {
2914c39362SHervé Poussineau ULONG Len;
3014c39362SHervé Poussineau
3114c39362SHervé Poussineau Len = strlen(Command);
3214c39362SHervé Poussineau if (Len < sizeof("?fat."))
3314c39362SHervé Poussineau {
3414c39362SHervé Poussineau return FALSE;
3514c39362SHervé Poussineau }
3614c39362SHervé Poussineau
3714c39362SHervé Poussineau if (Command[0] != '?' || Command[1] != 'f' ||
3814c39362SHervé Poussineau Command[2] != 'a' || Command[3] != 't' ||
3914c39362SHervé Poussineau Command[4] != '.')
4014c39362SHervé Poussineau {
4114c39362SHervé Poussineau return FALSE;
4214c39362SHervé Poussineau }
4314c39362SHervé Poussineau
4414c39362SHervé Poussineau Command += (sizeof("?fat.") - sizeof(ANSI_NULL));
4514c39362SHervé Poussineau if (strcmp(Command, "vols") == 0)
4614c39362SHervé Poussineau {
4714c39362SHervé Poussineau ULONG Count = 0;
4814c39362SHervé Poussineau PLIST_ENTRY ListEntry;
4914c39362SHervé Poussineau PDEVICE_EXTENSION DeviceExt;
5014c39362SHervé Poussineau
5114c39362SHervé Poussineau for (ListEntry = VfatGlobalData->VolumeListHead.Flink;
5214c39362SHervé Poussineau ListEntry != &VfatGlobalData->VolumeListHead;
5314c39362SHervé Poussineau ListEntry = ListEntry->Flink)
5414c39362SHervé Poussineau {
5514c39362SHervé Poussineau DeviceExt = CONTAINING_RECORD(ListEntry, DEVICE_EXTENSION, VolumeListEntry);
5614c39362SHervé Poussineau DPRINT1("Volume: %p with VCB: %p\n", DeviceExt->VolumeDevice, DeviceExt);
5714c39362SHervé Poussineau ++Count;
5814c39362SHervé Poussineau }
5914c39362SHervé Poussineau
6014c39362SHervé Poussineau if (Count == 0)
6114c39362SHervé Poussineau {
6214c39362SHervé Poussineau DPRINT1("No volume found\n");
6314c39362SHervé Poussineau }
6414c39362SHervé Poussineau }
6514c39362SHervé Poussineau else if (strcmp(Command, "files") == 0)
6614c39362SHervé Poussineau {
6714c39362SHervé Poussineau if (Argc != 2)
6814c39362SHervé Poussineau {
6914c39362SHervé Poussineau DPRINT1("Please provide a volume or a VCB!\n");
7014c39362SHervé Poussineau }
7114c39362SHervé Poussineau else
7214c39362SHervé Poussineau {
7314c39362SHervé Poussineau PLIST_ENTRY ListEntry;
7414c39362SHervé Poussineau PDEVICE_EXTENSION DeviceExt;
7514c39362SHervé Poussineau
7614c39362SHervé Poussineau for (ListEntry = VfatGlobalData->VolumeListHead.Flink;
7714c39362SHervé Poussineau ListEntry != &VfatGlobalData->VolumeListHead;
7814c39362SHervé Poussineau ListEntry = ListEntry->Flink)
7914c39362SHervé Poussineau {
8014c39362SHervé Poussineau CHAR Volume[17];
8114c39362SHervé Poussineau
8214c39362SHervé Poussineau DeviceExt = CONTAINING_RECORD(ListEntry, DEVICE_EXTENSION, VolumeListEntry);
8314c39362SHervé Poussineau sprintf(Volume, "%p", DeviceExt);
8414c39362SHervé Poussineau if (strcmp(Volume, Argv[1]) == 0)
8514c39362SHervé Poussineau {
8614c39362SHervé Poussineau break;
8714c39362SHervé Poussineau }
8814c39362SHervé Poussineau
8914c39362SHervé Poussineau sprintf(Volume, "%p", DeviceExt->VolumeDevice);
9014c39362SHervé Poussineau if (strcmp(Volume, Argv[1]) == 0)
9114c39362SHervé Poussineau {
9214c39362SHervé Poussineau break;
9314c39362SHervé Poussineau }
9414c39362SHervé Poussineau
9514c39362SHervé Poussineau DeviceExt = NULL;
9614c39362SHervé Poussineau }
9714c39362SHervé Poussineau
9814c39362SHervé Poussineau if (DeviceExt == NULL)
9914c39362SHervé Poussineau {
10014c39362SHervé Poussineau DPRINT1("No volume %s found!\n", Argv[1]);
10114c39362SHervé Poussineau }
10214c39362SHervé Poussineau else
10314c39362SHervé Poussineau {
10414c39362SHervé Poussineau PVFATFCB Fcb;
10514c39362SHervé Poussineau
10614c39362SHervé Poussineau for (ListEntry = DeviceExt->FcbListHead.Flink;
10714c39362SHervé Poussineau ListEntry != &DeviceExt->FcbListHead;
10814c39362SHervé Poussineau ListEntry = ListEntry->Flink)
10914c39362SHervé Poussineau {
11014c39362SHervé Poussineau Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
11114c39362SHervé Poussineau DPRINT1("FCB %p (ref: %d, oc: %d %s %s %s) for FO %p with path: %.*S\n",
11214c39362SHervé Poussineau Fcb, Fcb->RefCount, Fcb->OpenHandleCount,
11314c39362SHervé Poussineau ((Fcb->Flags & FCB_CLEANED_UP) ? "U" : "NU"),
11414c39362SHervé Poussineau ((Fcb->Flags & FCB_CLOSED) ? "C" : "NC"),
11514c39362SHervé Poussineau ((Fcb->Flags & FCB_DELAYED_CLOSE) ? "D" : "ND"),
11614c39362SHervé Poussineau Fcb->FileObject, Fcb->PathNameU.Length, Fcb->PathNameU.Buffer);
11714c39362SHervé Poussineau }
11814c39362SHervé Poussineau }
11914c39362SHervé Poussineau }
12014c39362SHervé Poussineau }
12114c39362SHervé Poussineau else if (strcmp(Command, "setdbgfile") == 0)
12214c39362SHervé Poussineau {
12314c39362SHervé Poussineau if (Argc < 2)
12414c39362SHervé Poussineau {
12514c39362SHervé Poussineau if (DebugFile.Buffer != NULL)
12614c39362SHervé Poussineau {
12714c39362SHervé Poussineau ExFreePool(DebugFile.Buffer);
12814c39362SHervé Poussineau DebugFile.Length = 0;
12914c39362SHervé Poussineau DebugFile.MaximumLength = 0;
13014c39362SHervé Poussineau }
13114c39362SHervé Poussineau
13214c39362SHervé Poussineau DPRINT1("Debug file reset\n");
13314c39362SHervé Poussineau }
13414c39362SHervé Poussineau else
13514c39362SHervé Poussineau {
13614c39362SHervé Poussineau NTSTATUS Status;
13714c39362SHervé Poussineau ANSI_STRING Source;
13814c39362SHervé Poussineau
13914c39362SHervé Poussineau if (DebugFile.Buffer != NULL)
14014c39362SHervé Poussineau {
14114c39362SHervé Poussineau ExFreePool(DebugFile.Buffer);
14214c39362SHervé Poussineau DebugFile.Length = 0;
14314c39362SHervé Poussineau DebugFile.MaximumLength = 0;
14414c39362SHervé Poussineau }
14514c39362SHervé Poussineau
14614c39362SHervé Poussineau RtlInitAnsiString(&Source, Argv[1]);
14714c39362SHervé Poussineau Status = RtlAnsiStringToUnicodeString(&DebugFile, &Source, TRUE);
14814c39362SHervé Poussineau if (NT_SUCCESS(Status))
14914c39362SHervé Poussineau {
15014c39362SHervé Poussineau DPRINT1("Debug file set to: %.*S\n", DebugFile.Length, DebugFile.Buffer);
15114c39362SHervé Poussineau }
15214c39362SHervé Poussineau }
15314c39362SHervé Poussineau }
15414c39362SHervé Poussineau else
15514c39362SHervé Poussineau {
15614c39362SHervé Poussineau DPRINT1("Unknown command: %s\n", Command);
15714c39362SHervé Poussineau }
15814c39362SHervé Poussineau
15914c39362SHervé Poussineau return TRUE;
16014c39362SHervé Poussineau }
16114c39362SHervé Poussineau #endif
162