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

Home NTDEV

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Before Posting...

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

Sysdriver: How to capture Input data and play user audio application data

13

Comments

  • abin_k_rajanabin_k_rajan Member Posts: 2
    edited January 7

    Hi guys, I need help in this project too. Can someone tell me where to implement IOCTL.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,030

    Where to implement WHAT ioctl? How much have you done? What do you have working already?

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • abin_k_rajanabin_k_rajan Member Posts: 2

    I am relatively new to this as well. I want the driver to record and play live audio instead of Sine wave. I am finding it difficult to progress. I read the previous comments and tried following it but I haven't got any further. I need some help on which places to change codes.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,030

    I want the driver to record and play live audio instead of Sine wave.

    That doesn't make sense. The virtual driver has no connection at all to "live audio". You can capture the speaker output from an application, but the microphone data has to be fed in from an external application.

    This is a difficult project, and not a good place for a beginner.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 7

    Hi,

    I have decoded PCM data that I want to feed to virtual microphone, using SYSVAD i have created virtual mic,but I dont understand how to feed the data to virtual mic, may I know which class in sysvad to change for the same ,

    **basically I have captured (using WASAPI) audio data that I want to redirect to virtual microphone, instead of playing using speaker
    **
    need help.....thanks in advance

    Note: is virtual speaker really required to feed the data to virtual mic....plz suggest i am new to this

  • craig_howardcraig_howard Member Posts: 126

    Welcome to the forum! First, this is a "necro-post", which is a term describing bringing a thread back from long ago ... best to create an entirely new thread asking specifically what you're running into ("How do I send audio data to the virtual microphone in SysVAD" or something similar. Next, this topic has been asked and answered a number of times, so use the handy "search" function at the top right for "SysVAD" and you'll run into what others have found. Finally, SysVAD fills a ring buffer from the microphone, in the example using a sine wave function ... you will need to do the same, pushing data from [wherever] into the ring buffer which is then used by the Audio Engine ...

    Do some searching, then see if that helps out a bit ... :)

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 14

    Hi Tim_Roberts ,

    inside AddDevice function i have added

    ntStatus = IoRegisterDeviceInterface(
    PhysicalDeviceObject,
    &RPC_IOCTL_AUDIO,
    NULL,
    &referenceIOCtlString
    );

    if (ntStatus == STATUS_SUCCESS)
    {
        ntStatus = IoSetDeviceInterfaceState(&referenceIOCtlString, TRUE);
    }
    

    after that do I need to create call IoCreateSymbolicLink or not required.

    or: where and how to create symbolic link in sysvad example??? plz help i am stuck with this

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 14

    Hi ,

    my createfile function returns INVALID_HANDLE_VALUE,

    hDev = CreateFile(
    (LPCSTR)DeviceInterfaceList,
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    FILE_SHARE_READ|FILE_SHARE_WRITE,
    NULL
    );

    i have below code in place:

    inside driverentry:
    DriverObject->MajorFunction[IRP_MJ_CREATE] = IoctlCreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = IoctlCreateClose;

    definition:

    NTSTATUS IoctlCreateClose(In DEVICE_OBJECT* DeviceObject,
    _Inout
    IRP* _Irp)
    {
    UNREFERENCED_PARAMETER(_DeviceObject);

    PIO_STACK_LOCATION stackLocation = NULL;
    stackLocation = IoGetCurrentIrpStackLocation(_Irp);
    
    switch (stackLocation->MajorFunction)
    {
    case IRP_MJ_CREATE:
        DbgPrint("Handle to symbolink link %wZ opened", DEVICE_SYMBOLIC_NAME);
        break;
    case IRP_MJ_CLOSE:
        DbgPrint("Handle to symbolink link %wZ closed", DEVICE_SYMBOLIC_NAME);
        break;
    default:
        break;
    }
    
    _Irp->IoStatus.Information = 0;
    _Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(_Irp, IO_NO_INCREMENT);
    PcDispatchIrp(_DeviceObject, _Irp);
    
    return STATUS_SUCCESS;
    

    }

    in output console i am getting

    \?\ROOT#MEDIA#0001#{4d36e96c-e325-11ce-bfc1-08002be10318}/////////DeviceInterfaceList value
    fail to open device (0x2)/////how to resolve this

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 14

    hello All,

    need your help on above post,
    plz i am totally stuck on this, not able to find the reason why my CreateFile api gives ERROR_FILE_NOT_FOUND , while the value of device interface is \?\ROOT#MEDIA#0001#{4d36e96c-e325-11ce-bfc1-08002be10318}

    Please do let me know if u need any more input inorder to understand my issue

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,567

    after that do I need to create call IoCreateSymbolicLink or not required

    Not required.

    IoRegisterDeviceInterface ... RPC_AUDIO_IOCTL

    Is that actually a GUID? That's a very strange name for a Device Interface GUID.

    And WHERE do you want to access the device from? In user mode, you lookup the GUID using CM_Get_Device_Interface_List

    None of the code that you posted makes much sense to me... I don't feel like I've got the full picture of what you're trying to do, where, and how...

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,030

    You don't need to call IoCreateSymbolicLink, but you do need to call IoSetDeviceInterfaceState to turn it on.

    4d36e96c-e325-11ce-bfc1-08002be10318

    That's the Media class GUID. Your driver should already be registered there. How did you define RPC_IOCTL_AUDIO? Where did DEVICE_SYMBOLIC_LINK come from in your driver code?

    Also, you need to remember that you are going to see IRP_MJ_CREATE calls both from your test application AND from the Audio Engine. Audio Engine opens many file handles into an audio device: some for the filter while it's probing, some for the filter while it is operating, and some for each of the pins, where the traffic really flows. You need to check in your "create" handler whether it is a request from your app or not. If it is, you handle it and complete it. If not, you pass it to PcDispatchIrp.

    _Irp->IoStatus.Information = 0;
    _Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(_Irp, IO_NO_INCREMENT);
    PcDispatchIrp(_DeviceObject, _Irp);

    If you were looking for the fastest way to generate a blue screen, this is it. Do you really not understand what's going on here at all? PcDispatchIrp tells the Port Class driver to handle this request using its normal processing. It's going to go through it's own "create" processing, then it will complete the request. Since you have already completed, it, BANG, blue screen. You need to ONE or the OTHER. Never both. If you handle the IRP, then you don't let Port Class see it. If you don't handle it, then you pass it to Port Class.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24

    @Peter_Viscarola_(OSR) said:

    after that do I need to create call IoCreateSymbolicLink or not required

    Not required.

    IoRegisterDeviceInterface ... RPC_AUDIO_IOCTL

    Is that actually a GUID? That's a very strange name for a Device Interface GUID.

    And WHERE do you want to access the device from? In user mode, you lookup the GUID using CM_Get_Device_Interface_List

    None of the code that you posted makes much sense to me... I don't feel like I've got the full picture of what you're trying to do, where, and how...

    Peter

    DEFINE_GUIDSTRUCT("4d36e96c-e325-11ce-bfc1-08002be10318", RPC_IOCTL_AUDIO);

    define RPC_IOCTL_AUDIO DEFINE_GUIDNAMED(RPC_IOCTL_AUDIO)

    in user application:

    GUID guid = { 0x4d36e96c, 0xe325, 0x11ce, 0xbf, 0xc1, 0x8, 0x0, 0x2b, 0xe1, 0x3, 0x18 };

    CONFIGRET cr;
    

    // char* DevicePath = NULL;
    PZZSTR DeviceInterfaceList = NULL;
    ULONG DeviceInterfaceListLength = 0;

    cr = CM_Get_Device_Interface_List_Size(
        &DeviceInterfaceListLength,
        &guid,
        NULL,
        CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES
    );
    
    if (cr != CR_SUCCESS) {
        wprintf(L"fail to get interface list size\n");
        return ;
    }
    

    // WCHAR DeviceInterfaceList[4096];
    //DeviceInterfaceList = (PZZSTR)malloc(DeviceInterfaceListLength);
    DeviceInterfaceList = (PZZSTR)HeapAlloc(
    GetProcessHeap(),
    HEAP_ZERO_MEMORY,
    DeviceInterfaceListLength * sizeof(WCHAR));

    if (DeviceInterfaceList == NULL) {
        wprintf(L"allocate interface list buffer fail\n");
        return ;
    }
    
    cr = CM_Get_Device_Interface_List(
        &guid,
        NULL,
        DeviceInterfaceList,
        DeviceInterfaceListLength,
        CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
    

    _tprintf(_T("%s\n"), (LPCSTR)DeviceInterfaceList);
    HANDLE hDev = INVALID_HANDLE_VALUE;

    hDev = CreateFile(
        (LPCSTR)DeviceInterfaceList,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_SHARE_READ|FILE_SHARE_WRITE,
        NULL
    );
    

    DeviceInterfaceList value is : \?\ROOT#MEDIA#0001#{4d36e96c-e325-11ce-bfc1-08002be10318}

    but Createfile returns ERROR_FILE_NOT_FOUND//////need help on this

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 14

    @Tim_Roberts said:
    You don't need to call IoCreateSymbolicLink, but you do need to call IoSetDeviceInterfaceState to turn it on.

    4d36e96c-e325-11ce-bfc1-08002be10318

    That's the Media class GUID. Your driver should already be registered there. How did you define RPC_IOCTL_AUDIO? Where did DEVICE_SYMBOLIC_LINK come from in your driver code?

    Also, you need to remember that you are going to see IRP_MJ_CREATE calls both from your test application AND from the Audio Engine. Audio Engine opens many file handles into an audio device: some for the filter while it's probing, some for the filter while it is operating, and some for each of the pins, where the traffic really flows. You need to check in your "create" handler whether it is a request from your app or not. If it is, you handle it and complete it. If not, you pass it to PcDispatchIrp.

    _Irp->IoStatus.Information = 0;
    _Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(_Irp, IO_NO_INCREMENT);
    PcDispatchIrp(_DeviceObject, _Irp);

    If you were looking for the fastest way to generate a blue screen, this is it. Do you really not understand what's going on here at all? PcDispatchIrp tells the Port Class driver to handle this request using its normal processing. It's going to go through it's own "create" processing, then it will complete the request. Since you have already completed, it, BANG, blue screen. You need to ONE or the OTHER. Never both. If you handle the IRP, then you don't let Port Class see it. If you don't handle it, then you pass it to Port Class.

    Hi,

    my device is already registered at 4d36e96c-e325-11ce-bfc1-08002be10318 in registry,

    define IOCTL_NT_DEVICE_NAME L"\Device\RemotePCVad"

    UNICODE_STRING referenceIOCtlString;

    DEFINE_GUIDSTRUCT("4d36e96c-e325-11ce-bfc1-08002be10318", RPC_IOCTL_AUDIO);

    define RPC_IOCTL_AUDIO DEFINE_GUIDNAMED(RPC_IOCTL_AUDIO)

    I think since i am using

    RtlInitUnicodeString(&referenceIOCtlString, IOCTL_NT_DEVICE_NAME);

    ntStatus = IoRegisterDeviceInterface(
        PhysicalDeviceObject,
        &RPC_IOCTL_AUDIO,
        NULL,
        &referenceIOCtlString
    );
    
    if (ntStatus == STATUS_SUCCESS)
    {
        ntStatus = IoSetDeviceInterfaceState(&referenceIOCtlString, TRUE);
    }
    

    so Symbolinclink is not required, I will remove DbgPrint("Handle to symbolink link %wZ opened", DEVICE_SYMBOLIC_NAME); code from IoctlCreateClose function

    but why Createfile returns ERROR_FILE_NOT_FOUND;

    my testapp code:

    GUID guid = { 0x4d36e96c, 0xe325, 0x11ce, 0xbf, 0xc1, 0x8, 0x0, 0x2b, 0xe1, 0x3, 0x18 };/

    CONFIGRET cr;
    PZZSTR DeviceInterfaceList = NULL;
    ULONG DeviceInterfaceListLength = 0;
    
    cr = CM_Get_Device_Interface_List_Size(
        &DeviceInterfaceListLength,
        &guid,
        NULL,
        CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES
    );
    
    if (cr != CR_SUCCESS) {
        wprintf(L"fail to get interface list size\n");
        return ;
    }
    
    DeviceInterfaceList = (PZZSTR)HeapAlloc(
        GetProcessHeap(),
        HEAP_ZERO_MEMORY,
        DeviceInterfaceListLength * sizeof(WCHAR));
    
    if (DeviceInterfaceList == NULL) {
        wprintf(L"allocate interface list buffer fail\n");
        return ;
    }
    
    cr = CM_Get_Device_Interface_List(
        &guid,
        NULL,
        DeviceInterfaceList,
        DeviceInterfaceListLength,
        CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
    
    if (cr != CR_SUCCESS) {
        wprintf(L"fail to get interface list\n");
       return ;
    }
    

    // strncpy_s(DevicePath, DeviceInterfaceListLength,DeviceInterfaceList, DeviceInterfaceListLength);
    //StringCchCopy(DevicePath, DeviceInterfaceListLength, DeviceInterfaceList);
    ///printf(L"%s\n", (const char*)DeviceInterfaceList);

    _tprintf(_T("%s\n"), (LPCSTR)DeviceInterfaceList);
    HANDLE hDev = INVALID_HANDLE_VALUE;
    
    hDev = CreateFile(
        (LPCSTR)DeviceInterfaceList,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_SHARE_READ|FILE_SHARE_WRITE,
        NULL
    );
    

    errNum = GetLastError();//////errNum value is 2/////this is issue i am facing

    in registry i can see my device registered under:

    Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses{4d36e96c-e325-11ce-bfc1-08002be10318}##?#ROOT#MEDIA#0001#{4d36e96c-e325-11ce-bfc1-08002be10318}

    How to know who(user app or audio engine) calls IRP_MJ_CREATE

    Post edited by chauhan_sumit001 on
  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,030
    edited July 14

    my device is already registered at 4d36e96c-e325-11ce-bfc1-08002be10318 in registry

    That GUID does not belong to you. That's a Microsoft GUID, and exposing it makes other promises. You need to create your own GUID for your own private interface.

    All of the casts you are doing make me suspicious that you've made a rookie mistake. You shouldn't have to cast any of that. Just for now, you should throw out the _tprintf and use straight puts to make absolutely sure you're getting an ANSI string, and not a Unicode string. Get rid of any casts where you are passing that variable to other APIs. If you get compilation errors, then you are mixing character sets, which is disastrous. That's especially true for CreateFile. If you have to cast the file name to get it into CreateFile, then you have made a mistake.

    How to know who(user app or audio engine) calls IRP_MJ_CREATE

    It's tricky, The most common way is to add a reference string when you create your device interface, and look for that reference string in the file name field when you get the IRP_MJ_CREATE call.

    Is your create handler getting called at all? I'm guessing it isn't, because you would have seen a blue screen. Does your device appear in Device Manager as a sound device?

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 15

    @Tim_Roberts said:

    my device is already registered at 4d36e96c-e325-11ce-bfc1-08002be10318 in registry

    That GUID does not belong to you. That's a Microsoft GUID, and exposing it makes other promises. You need to create your own GUID for your own private interface.

    All of the casts you are doing make me suspicious that you've made a rookie mistake. You shouldn't have to cast any of that. Just for now, you should throw out the _tprintf and use straight puts to make absolutely sure you're getting an ANSI string, and not a Unicode string. Get rid of any casts where you are passing that variable to other APIs. If you get compilation errors, then you are mixing character sets, which is disastrous. That's especially true for CreateFile. If you have to cast the file name to get it into CreateFile, then you have made a mistake.

    How to know who(user app or audio engine) calls IRP_MJ_CREATE

    It's tricky, The most common way is to add a reference string when you create your device interface, and look for that reference string in the file name field when you get the IRP_MJ_CREATE call.

    Is your create handler getting called at all? I'm guessing it isn't, because you would have seen a blue screen. Does your device appear in Device Manager as a sound device?

    Hi Tim,

    You are right, i have seen bluescreen issue, but my device appear in device manager, and also i can see the virtual mic in my sound control panel, the only issue i am facing is blue screen(thats bcz of PCDispatcher as u mentioned in create function) and CreateFile error.

    for CreateFile i removed all the casting:

    GUID guid = {0x4d36e96c, 0xe325, 0x11ce, 0xbf, 0xc1, 0x8, 0x0, 0x2b, 0xe1, 0x3, 0x18 };
    CONFIGRET cr;
    PWSTR DeviceInterfaceList = NULL;
    ULONG DeviceInterfaceListLength = 0;

    cr = CM_Get_Device_Interface_List_Size(
        &DeviceInterfaceListLength,
        &guid,
        NULL,
        CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES
    );
    
    if (cr != CR_SUCCESS) {
        wprintf(L"fail to get interface list size\n");
        return -1;
    }
    
    DeviceInterfaceList = (PWSTR)HeapAlloc(
        GetProcessHeap(),
        HEAP_ZERO_MEMORY,
        DeviceInterfaceListLength * sizeof(WCHAR));
    
    if (DeviceInterfaceList == NULL) {
        wprintf(L"allocate interface list buffer fail\n");
        return -2;
    }
    
    cr = CM_Get_Device_Interface_List(
        &guid,
        NULL,
        DeviceInterfaceList,/////////////////////////////getting error here:    'function': incompatible types - from 'PWSTR' to 'PZZSTR'
        DeviceInterfaceListLength,
        CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES);
    
    if (cr != CR_SUCCESS) {
        wprintf(L"fail to get interface list\n");
        return -3;
    }
    
    wprintf(L"%s\n", DeviceInterfaceList);
    
    HANDLE hDev = INVALID_HANDLE_VALUE;
    
    hDev = CreateFile(
        DeviceInterfaceList,
        FILE_GENERIC_READ,
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL
    );
    
    if (hDev == INVALID_HANDLE_VALUE) {
        wprintf(L"fail to open device (0x%X)\n", GetLastError());
        return -4;
    }
    

    plz help me to resolve 'function': incompatible types - from 'PWSTR' to 'PZZSTR' error in CM_Get_Device_Interface_List function

    Post edited by chauhan_sumit001 on
  • chauhan_sumit001chauhan_sumit001 Member Posts: 24

    @chauhan_sumit001 said:

    @Tim_Roberts said:

    my device is already registered at 4d36e96c-e325-11ce-bfc1-08002be10318 in registry

    That GUID does not belong to you. That's a Microsoft GUID, and exposing it makes other promises. You need to create your own GUID for your own private interface.

    All of the casts you are doing make me suspicious that you've made a rookie mistake. You shouldn't have to cast any of that. Just for now, you should throw out the _tprintf and use straight puts to make absolutely sure you're getting an ANSI string, and not a Unicode string. Get rid of any casts where you are passing that variable to other APIs. If you get compilation errors, then you are mixing character sets, which is disastrous. That's especially true for CreateFile. If you have to cast the file name to get it into CreateFile, then you have made a mistake.

    How to know who(user app or audio engine) calls IRP_MJ_CREATE

    It's tricky, The most common way is to add a reference string when you create your device interface, and look for that reference string in the file name field when you get the IRP_MJ_CREATE call.

    Is your create handler getting called at all? I'm guessing it isn't, because you would have seen a blue screen. Does your device appear in Device Manager as a sound device?

    Hi Tim,

    You are right, i have seen bluescreen issue, but my device appear in device manager, and also i can see the virtual mic in my sound control panel, the only issue i am facing is blue screen(thats bcz of PCDispatcher as u mentioned in create function) and CreateFile error.

    That GUID i have added in INF file .

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,030

    Is it complaining about PZZSTR, or about PZZWSTR? If it is complaining about PZZSTR, then you have somehow mixed up your APIs, because it means you have the ANSI CM_Get_Device_Interface_List and the Unicode CreateFile. If it is complaining about PZZWSTR, then I will allow you to insert a cast to eliminate that warning. ;) Just make sure the wprintf prints something readable.

    That GUID I have added in INF file.

    Why? It doesn't need to be there. And it's STILL not your GUID.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 15

    @Tim_Roberts said:
    Is it complaining about PZZSTR, or about PZZWSTR? If it is complaining about PZZSTR, then you have somehow mixed up your APIs, because it means you have the ANSI CM_Get_Device_Interface_List and the Unicode CreateFile. If it is complaining about PZZWSTR, then I will allow you to insert a cast to eliminate that warning. ;) Just make sure the wprintf prints something readable.

    That GUID I have added in INF file.

    Why? It doesn't need to be there. And it's STILL not your GUID.

    It was complaining about PZZSTR that too inside CM_Get_Device_Interface_List.

    GUID guid = { 0x4d36e96c, 0xe325, 0x11ce, 0xbf, 0xc1, 0x8, 0x0, 0x2b, 0xe1, 0x3, 0x18 };

    CONFIGRET cr;
    LPTSTR  DeviceInterfaceList = NULL;////////////////////////LPTSTR instead of PWSTR
    ULONG DeviceInterfaceListLength = 0;
    
    
    cr = CM_Get_Device_Interface_List_Size(
        &DeviceInterfaceListLength,
        &guid,
        NULL,
        CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES
    );
    
    if (cr != CR_SUCCESS) {
        wprintf(L"fail to get interface list size\n");
        return ;
    }
    DeviceInterfaceList = (LPTSTR)HeapAlloc(//(PZZSTR)HeapAlloc(
        GetProcessHeap(),
        HEAP_ZERO_MEMORY,
        DeviceInterfaceListLength * sizeof(WCHAR));
    
    if (DeviceInterfaceList == NULL) {
        wprintf(L"allocate interface list buffer fail\n");
        return ;
    }
    
    cr = CM_Get_Device_Interface_List(
        &guid,
        NULL,
        DeviceInterfaceList,
        DeviceInterfaceListLength,
        CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
    
    if (cr != CR_SUCCESS) {
        wprintf(L"fail to get interface list\n");
       return ;
    }
    
    printf("%s\n", DeviceInterfaceList);
    
    HANDLE hDev = INVALID_HANDLE_VALUE;
    
    hDev = CreateFile(
        DeviceInterfaceList,//DeviceInterfaceList,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_SHARE_READ|FILE_SHARE_WRITE,
        NULL
    );
    

    if I declare DeviceInterfaceList as LPTSTR instead of PWSTR its compiling and , value of DeviceInterfaceList also gettingprinted as

    \?\ROOT#UNNAMED_DEVICE#0001#{4d36e96c - e325 - 11ce - bfc1 - 08002be10318}

    is it fine???

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24

    @Tim_Roberts said:
    Is it complaining about PZZSTR, or about PZZWSTR? If it is complaining about PZZSTR, then you have somehow mixed up your APIs, because it means you have the ANSI CM_Get_Device_Interface_List and the Unicode CreateFile. If it is complaining about PZZWSTR, then I will allow you to insert a cast to eliminate that warning. ;) Just make sure the wprintf prints something readable.

    That GUID I have added in INF file.

    Why? It doesn't need to be there. And it's STILL not your GUID.

    It was complaining about PZZSTR that too inside CM_Get_Device_Interface_List ,

    then I changed the variable DeviceInterfaceList type from PWSTR to LPTSTR

    GUID guid = { 0x01ee4b4f, 0x6fb0, 0x4763, 0xa8, 0x43, 0x41, 0x55, 0x91, 0xf1, 0xf0, 0x1 };

    CONFIGRET cr;
    LPTSTR  DeviceInterfaceList = NULL;
    ULONG DeviceInterfaceListLength = 0;
    
    cr = CM_Get_Device_Interface_List_Size(
        &DeviceInterfaceListLength,
        &guid,
        NULL,
        CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES
    );
    
    if (cr != CR_SUCCESS) {
        wprintf(L"fail to get interface list size\n");
        return ;
    }
    DeviceInterfaceList = (LPTSTR)HeapAlloc(//(PZZSTR)HeapAlloc(
        GetProcessHeap(),
        HEAP_ZERO_MEMORY,
        DeviceInterfaceListLength * sizeof(WCHAR));
    
    if (DeviceInterfaceList == NULL) {
        wprintf(L"allocate interface list buffer fail\n");
        return ;
    }
    
    cr = CM_Get_Device_Interface_List(
        &guid,
        NULL,
        DeviceInterfaceList,
        DeviceInterfaceListLength,
        CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
    
    if (cr != CR_SUCCESS) {
        wprintf(L"fail to get interface list\n");
       return ;
    }
    
    printf("%s\n", DeviceInterfaceList);
    HANDLE hDev = INVALID_HANDLE_VALUE;
    
    hDev = CreateFile(
        DeviceInterfaceList,//DeviceInterfaceList,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_SHARE_READ|FILE_SHARE_WRITE,
        NULL
    );
    

    got DeviceInterfaceList as \?\ROOT#UNNAMED_DEVICE#0001#{01ee4b4f-6fb0-4763-a843-415591f1f001}

    Is it fine , need your approval

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,030
    edited July 15

    You don't need MY approval, you need WINDOWS' approval. Does your CreateFile call get into the driver now?

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 15

    @Tim_Roberts said:
    You don't need MY approval, you need WINDOWS' approval. Does your CreateFile call get into the driver now?

    that i still need to check.

    but one more help i already asked, need solution

    NTSTATUS IoctlCreateClose(In DEVICE_OBJECT* DeviceObject,
    _Inout
    IRP* _Irp)
    {
    UNREFERENCED_PARAMETER(_DeviceObject);

    PIO_STACK_LOCATION stackLocation = NULL;
    stackLocation = IoGetCurrentIrpStackLocation(_Irp);
    stackLocation->FileObject->FileName == 
    switch (stackLocation->MajorFunction)
    {
    case IRP_MJ_CREATE:
        DbgPrint("Handle to symbolink link  opened");
        break;
    case IRP_MJ_CLOSE:
        DbgPrint("Handle to symbolink link closed");
        break;
    default:
        break;
    }
    _Irp->IoStatus.Information = 0;
    _Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(_Irp, IO_NO_INCREMENT);
    ////PcDispatchIrp(_DeviceObject, _Irp);
    
    return STATUS_SUCCESS;
    

    }

    how to knoe that user application calls this api, so that in that case i can avoid PcDispatchIrp

    without PcDispatchIrp call here, i couldnot see virtual mic in sound control panel, how to proceed for now

    Hi Tim,

    For now i have only added PcDispatchIrp and commented IoCompleteRequest(_Irp, IO_NO_INCREMENT); part in IRP_MJ_CREATE handler function still my CreateFile returns FILE_NOT_FOUND error number 2.

    some bug in my code that you can only identify sir.

    Post edited by chauhan_sumit001 on
  • chauhan_sumit001chauhan_sumit001 Member Posts: 24

    Any help on above post....thanks in advance

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 15

    Hi Tim,

    inside IRP_MJ_CREATE handler function for now i commented PcDispatchIrp(_DeviceObject, _Irp);

    with that Createfile is working, but i am not able to see virtual device sound control panel.
    while it is visible in device manager.

    so plz help me how i can have both PcDispatchIrp(_DeviceObject, _Irp); and IoCompleteRequest(_Irp, IO_NO_INCREMENT); in IRP_MJ_CREATE handler. under condition that when user app call IRP_MJ_CREATE it should skip PcDispatchIrp(_DeviceObject, _Irp);

    NTSTATUS IoctlCreateClose(In DEVICE_OBJECT* DeviceObject,
    _Inout
    IRP* _Irp)
    {
    UNREFERENCED_PARAMETER(_DeviceObject);

    PIO_STACK_LOCATION stackLocation = NULL;
    stackLocation = IoGetCurrentIrpStackLocation(_Irp);
    
    switch (stackLocation->MajorFunction)
    {
    case IRP_MJ_CREATE:
        DbgPrint("Handle to symbolink link  opened");
        break;
    case IRP_MJ_CLOSE:
        DbgPrint("Handle to symbolink link closed");
        break;
    default:
        break;
    }
    
    _Irp->IoStatus.Information = 0;
    _Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(_Irp, IO_NO_INCREMENT);
    //PcDispatchIrp(_DeviceObject, _Irp);////////////////////////how to keep this also
    
    return STATUS_SUCCESS;
    

    }

    Post edited by chauhan_sumit001 on
  • chauhan_sumit001chauhan_sumit001 Member Posts: 24

    @chauhan_sumit001 said:
    Any help on above post....thanks in advance

    my createfile is working now,after commenting pcdispatcher from IRP_MJ_CREATE handler, but i want PCDispatcher also,how to do that

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,030

    I did tell you that earlier in the thread. Port Class uses the file name in the IRP_MJ_CREATE IRP to decide what kind of open it is. You can dump those file names in the debugger to see what they look like. You can add a reference string to your device interface, and that reference string will be passed as the file name. If you use a custom reference string, then you can identify when the open comes from your application.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24

    Hi Tim,

    Plz give some clue on above post.

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 16

    @Tim_Roberts said:
    I did tell you that earlier in the thread. Port Class uses the file name in the IRP_MJ_CREATE IRP to decide what kind of open it is. You can dump those file names in the debugger to see what they look like. You can add a reference string to your device interface, and that reference string will be passed as the file name. If you use a custom reference string, then you can identify when the open comes from your application.

    Hi Tim,

    I have one doubt, you have mentioned about "add a reference string to your device interface"

    Is it the same reference string which we pass inside

    UNICODE_STRING device_sym_link = RTL_CONSTANT_STRING(L"\Device\RemotePCVadDevice");
    UNICODE_STRING device_ref_string = RTL_CONSTANT_STRING(L"RemotePCVadDevice");

    ntStatus = IoRegisterDeviceInterface(
    PhysicalDeviceObject,
    &RPC_IOCTL_AUDIO,
    &device_ref_string,/////////////////are u talking about this??????plz clarify
    &device_sym_link
    );

    if yes then we can use

    const auto IsUserSpaceAppRequest =
    !RtlCompareUnicodeString(&device_ref_string
    , &IrpStack->FileObject->FileName
    , TRUE);

    to identify the call inside IRP_MJ_CREATE

    In CreateFile I am passing "\?\ROOT#MEDIA#0007#{4d36e96c-e325-11ce-bfc1-08002be10318}\RemotePCVadDevice" as file name

    plz clarify.

    Post edited by chauhan_sumit001 on
  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,030

    Yes, that's it. I don't remember whether the driver gets a leading "\" or not; you'll have to do some debug prints to verify that.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    edited July 25

    Hi Tim,

    over the TCP connection I am receiving encoded mic output from source application ,at target app i am decoding the audio data , now
    I have decoded audio data(using AAC) in my target application, that I want to redirect to virtual audio mic(earlier i was playing it using SDL player). do I need to store that decoded data again in ring buffer within the driver code??,

    I can transfer that decode data to driver using IOCTL, but there I will receive inside driver.cpp custom IOCTL handler, from custom IOCTL handler how can I transfer the data to MiniportWaveRTStream::WriteBytes and copy it to m_pDmaBuffer. plz help with some sample code snippet.

    VOID MiniportWaveRTStream::WriteBytes
    (
    In ULONG ByteDisplacement
    )
    /*++

    Routine Description:

    This function writes the audio buffer using a sine wave generator
    Arguments:

    ByteDisplacement - # of bytes to process.

    --*/
    {

    ULONG bufferOffset = m_ullLinearPosition % m_ulDmaBufferSize;
    
    //// Normally this will loop no more than once for a single wrap, but if
    //// many bytes have been displaced then this may loops many times.
    while (ByteDisplacement > 0)
    {
        ULONG runWrite = min(ByteDisplacement, m_ulDmaBufferSize - bufferOffset);
        SIZE_T actuallyWritten;
    
        m_RingBuffer->Take(m_pDmaBuffer + bufferOffset, runWrite, &actuallyWritten);
        if (actuallyWritten < runWrite)
        {
            RtlZeroMemory(m_pDmaBuffer + bufferOffset + actuallyWritten, runWrite - actuallyWritten);
        }
    
        bufferOffset = (bufferOffset + runWrite) % m_ulDmaBufferSize;
        ByteDisplacement -= runWrite;
    }
    

    }

    if i have to feed my audio buffer to m_pDmaBuffer , do i need to write that much code inside WriteBytes(mentioned above), except
    memcpy(m_pDmaBuffer ,my audio buffer received USING IOCTL, length)????

    plz need your help.

  • chauhan_sumit001chauhan_sumit001 Member Posts: 24
    Hi ,

    Any suggestion on above post.
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
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Developing Minifilters 24 May 2021 Live, Online
Writing WDF Drivers 14 June 2021 Live, Online
Internals & Software Drivers 27 September 2021 Live, Online
Kernel Debugging 15 November 2021 Live, Online