Драйвер виртуального аудиоустройства
Суть задачи: реализовать драйвер виртуального аудиоустройства, в качестве источника данных выступает приложение пользовательского пространства. Аудиоустройство представляет собой микрофон, которой можно использовать в приложениях вроде Skype, Zoom и им подобных.
Начал с драйвера MSVAD (конкретнее, проект micarray). Добавил обработчики для открытия\закрытия файла и для записи данных, вроде:
DriverObject->MajorFunction[IRP_MJ_WRITE] = [](_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) -> NTSTATUS { ... };
// other handlers
Далее, используя Microsoft Media Foundation, попытался перечислить все audio-capture устройства в системе, и получить их символьные ссылки (для того, чтобы в дальнейшем можно было работать с устройством как с файлом - CreateFile/WriteFile):
IMFAttributes* pAttributes = nullptr;
if (const auto err = MFCreateAttributes(&pAttributes, 1); err != S_OK)
{
return EXIT_FAILURE;
}
pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID);
IMFActivate** pActivationObjects;
UINT32 uActivationObjectsCount;
if (const auto err = MFEnumDeviceSources(pAttributes, &pActivationObjects, &uActivationObjectsCount); err != S_OK)
{
return EXIT_FAILURE;
}
for (auto ptr = pActivationObjects; ptr != pActivationObjects + uActivationObjectsCount; ++ptr)
{
const auto symlink = GetSymbolicLink(*ptr);
}
// release
Получение симлинка:
std::wstring GetSymbolicLink(IMFAttributes* _attributes)
{
std::wstring str;
if (_attributes)
{
LPWSTR symbolicLink = nullptr;
UINT32 symbolicLinkLength = 0;
HRESULT hr = _attributes->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &symbolicLink, &symbolicLinkLength);
if (SUCCEEDED(hr))
{
str.assign(symbolicLink, symbolicLinkLength);
CoTaskMemFree(symbolicLink);
}
}
return str;
}
Результат: строка, содержащая симлинк, оказалась пустой.
Вопрос: каким образом можно взаимодействовать с драйвером из user-space приложения? Важен именно данный драйвер - micarray (из MSVAD).
P.S. Я не уверен в правильности своего выбора (нужно ли было брать за основу именно micarray). Нашел проприетарный драйвер, предоставляющий аналогичный функционал, установил его и посмотрел пины устройств с помощью KsStudio. Их количество, тип и наличие соединений полностью соответствует тому, что я вижу в KsStudio для micarray драйвера:
+------+ +------+
| Topo | | Wave |
| | | |
Jack --->|0 1|===>|0 1|---> Capture Host Pin
| | | |
+------+ +------+
Если кто-то считает, что я все делаю неправильно - прошу поделится опытом, линками на соответствующие статьи, буду только рад, потому что у меня это первый опыт в разработке аудиодрайверов.