Good evening, I trying to get the Volume GUID from the volume enumerated, at 1st I define the volumeContext structure and use it,
my understanding is, 1st call FltGetVolumeGuidName() to get the BufferSizeNeeded() and then use this value to allocate memory pool and then call again FltGetVolumeGuidName() to fetch Guid for each of the Volume present in the system,
I have observed kernel crash while using (volumeContext->GUIDinfo.Buffer = NULL; )
Kindly suggest, if my approach is correct.
FLT_PREOP_CALLBACK_STATUS PreFileOperationCallback(__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID* CompletionContext)
{
DbgPrint("\n-------Inside ---PreFileOperationCallback--------");
NTSTATUS status, ntStatus;
PFLT_VOLUME pVolumeList[MAX_VOLUME_CHARS];
ULONG VolumeListSize = MAX_VOLUME_CHARS;
ULONG index = 0;
PULONG NumberVolumesReturned = NULL;
WCHAR wszNameBuffer[MAX_VOLUME_LENGTH] = { 0 };
FILTER_VOLUME_INFORMATION_CLASS FilterVolumeStandardInformation;
FILTER_VOLUME_STANDARD_INFORMATION FltVolumeStdInfo;
PULONG BufferSizeNeeded;
SIZE_T bytesRequired;
ULONG MEMTAG_VOL_GUID = 0;
PVOLUME_CONTEXT volumeContext = NULL;
UNICODE_STRING volumeGuidName, VolumeNameString;
PVOID VolumeNameBuffer = NULL;
UNICODE_STRING volumebuf[MAX_VOLUME_LENGTH];
DbgPrint("\n--------Before FltEnumerateVolumes--------");
ntStatus = FltEnumerateVolumes(fileHandler, pVolumeList, VolumeListSize, &NumberVolumesReturned); //Get volume information
if (!NT_SUCCESS(ntStatus)) {
return ntStatus;
}
DbgPrint("\n-----After FltEnumerateVolumes---------");
DbgPrint("\nNumberVolumesReturned-%d",NumberVolumesReturned);
DbgPrint("\n------------------------------------------");
for (index = 1; index <= NumberVolumesReturned; index++)
{
if (index == NumberVolumesReturned) {
goto Dereference; //jump the forLoop
}
volumeContext->GUIDinfo.Buffer = NULL; //kernel crash here <<<<======
volumeContext->GUIDinfo.Length = 0;
volumeContext->GUIDinfo.MaximumLength = 0;
//fetching correct size
(void) FltGetVolumeGuidName(pVolumeList[index], &volumeContext->GUIDinfo, &BufferSizeNeeded);
//Allocating space
if (NULL == volumeContext->GUIDinfo.Buffer) {
status = STATUS_INSUFFICIENT_RESOURCES;
DbgPrint("\n STATUS_INSUFFICIENT_RESOURCES");
break;
}
//Memory allocation
volumeContext->GUIDinfo.Buffer = (PWCHAR)ExAllocatePoolWithTag(PagedPool, BufferSizeNeeded, MEMTAG_VOL_GUID);
volumeContext->GUIDinfo.Length = 0;
ASSERT(BufferSizeNeeded <= UNICODE_STRING_MAX_BYTES);
volumeContext->GUIDinfo.MaximumLength = (ULONG)BufferSizeNeeded;
ntStatus = FltGetVolumeGuidName(pVolumeList[index], &volumeContext->GUIDinfo, &BufferSizeNeeded);
if (ntStatus == STATUS_BUFFER_TOO_SMALL) {
DbgPrint("\n STATUS_BUFFER_TOO_SMALL");
break;
}else if(ntStatus == STATUS_INSUFFICIENT_RESOURCES) {
DbgPrint("\n STATUS_INSUFFICIENT_RESOURCES");
break;
}
else if (ntStatus == STATUS_INVALID_DEVICE_REQUEST) {
DbgPrint("\n STATUS_INVALID_DEVICE_REQUEST");
}else if (ntStatus == STATUS_FLT_VOLUME_NOT_FOUND) {
DbgPrint("\n STATUS_FLT_VOLUME_NOT_FOUND");
break; //break from forLoop
}
continue;
// The format is \??\Volume{GUID}
for (index = 0; (L'{' != volumeContext->GUIDinfo.Buffer[index] && index < (volumeContext->GUIDinfo.Length / sizeof(WCHAR))); index++)
/* nothing */;
volumeGuidName.Buffer = &volumeContext->GUIDinfo.Buffer[index];
volumeGuidName.Length = (USHORT)DbgPrint("\nVolumeGuidName Length - %ld",volumeGuidName.Length);
DbgPrint("\n-------- GUID Info ---------");
DbgPrint("\nVolumeGuidName - %wZ", &volumeContext->GUIDinfo);
DbgPrint("\nVolumeGuidName Name - %ld",volumeGuidName.Buffer);
DbgPrint("\nVolumeGuidName Length - %ld",volumeGuidName.Length);
DbgPrint("\nVolumeGuidName Buffer - { %s }",(PWCHAR)volumeGuidName.Buffer);
DbgPrint("\n----------------------------");
status = RtlGUIDFromString(&volumeGuidName, &volumeContext->GUIDinfo);
if (!NT_SUCCESS(status)) {
break;
}
}//End of forLoop
Dereference:
for (index = 0; index < NumberVolumesReturned; index++)
{
FltObjectDereference(pVolumeList[index]);
}
//return pInstance;
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}