Search code examples
cwindowsdriverswdk

Passing variable length struct from User Mode to Kernel Mode


I'm writing virtual disk driver, and there I have structure defined like that:

typedef struct _MOUNT_NEW_QUERY {
    PWCHAR imagePath;
    WCHAR letter;
    PCHAR key;
} MOUNT_NEW_QUERY, *PMOUNT_NEW_QUERY;

So I have sort of dynamically sized structure.

How must I pass it from User Mode to my driver?


Solution

  • Allocate a continuous chunk of memory, sufficient to hold both your struct and the data for "key" and "path" - something like this:

    /* we add + 1 for terminating NULLs to make life easy */
    size_t keyLen = (strlen(key) +  1); 
    size_t imgLen = (wcslen(imagePath) + 1) * sizeof(WCHAR);
    
    PMOUNT_NEW_QUERY pMNQ = malloc(sizeof(MOUNT_NEW_QUERY) + keyLen + imgLen);
    
    if(pMNQ != NULL) 
    {       
       /* make imagePath point to the allocated buffer immediately after 
        * the MOUNT_NEW_QUERY portion 
        */
       pMNQ->imagePath = (PWCHAR)((PBYTE)pMNQ + sizeof(MOUNT_NEW_QUERY));
    
       /* make the key point to the allocated buffer immediately after 
        * the imagePath portion (including a NULL WCHAR terminator)
        */
       pMNQ->key = (PCHAR)((PBYTE)pMNQ + sizeof(MOUNT_NEW_QUERY) + imgLen);
    
       /* populate the data here appropriately, typically with strcpy
        * and wcscpy, and then send the IOCTL 
        */
       fun(pMNQ);
    }
    

    When you call the IOCTL for your driver, pass the total size of the buffer, not just the sizeof the MOUNT_NEW_QUERY structure.