Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

kernel crash while calling FltGetVolumeGuidName() in windows2016

AntoHeraldAntoHerald Member Posts: 11
edited December 2019 in NTFSD

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;
}
Post edited by AntoHerald on

Comments

  • AntoHeraldAntoHerald Member Posts: 11
    edited December 2019

    need some help to fix it.

  • AntoHeraldAntoHerald Member Posts: 11

    Agreed that each of the PFLT_VOLUME I get a valid pointer. Now when I call FltGetVolumeGuidName(PFLT_VOLUME (pVolumeList) &volumeContext->GUIDinfo, BufferSizeNeeded) as mentioned above and print the values in the &volumeContext->GUIDinfo = (Null) and BufferSizeNeeded = 96. With the literature around on FltGetVolumeGuidName, I understand 1st call FltGetVolumeGuidName to get the BufferSizeNeeded and use this size and allocate memory and call again FltGetVolumeGuidName to fetch Guid.

    I have a problem (kernel panic) when I initialize as below

    volumeContext->GUIDinfo.Buffer = NULL;   //kernel crash here  <<<<======
    volumeContext->GUIDinfo.Length = 0;
    volumeContext->GUIDinfo.MaximumLength = 0;
    
  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,220

    You're setting volumeContext to NULL and dereferencing it

    -scott
    OSR

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
Writing WDF Drivers 21 Oct 2019 OSR Seminar Space & ONLINE
Internals & Software Drivers 18 Nov 2019 Dulles, VA
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 27 Apr 2020 OSR Seminar Space & ONLINE