.686P .MODEL Flat,StdCall OPTION CASEMAP:NONE INCLUDE \MASM32\INCLUDE\WINDOWS.INC INCLUDE \MASM32\INCLUDE\KERNEL32.INC INCLUDE \MASM32\INCLUDE\OLE32.INC INCLUDE \MASM32\INCLUDE\MSVCRT.INC INCLUDELIB \MASM32\LIB\KERNEL32.LIB INCLUDELIB \MASM32\LIB\OLE32.LIB INCLUDELIB \MASM32\LIB\MSVCRT.LIB DEBUG = 1 ; 0 - режим релиза, 1 - режим отладки ;-- ПСЕВДОНИМЫ, МАКРОСЫ, СТРУКТУРЫ, ИНТЕРФЕЙСЫ ------------------------------------------------------------------------- ; Псевдонимы функций printf EQU crt_printf wprintf EQU crt_wprintf ; Константы eRender = 0 eCapture = 1 eConsole = 0 eMultimedia = 1 eCommunications = 2 STGM_READ = 0 STGM_WRITE = 1 STGM_READWRITE = 2 WAVE_FORMAT_EXTENSIBLE = 0FFFEh ; Определить константу N1&N2&N3 со значением Value Def_CatStr MACRO Value, N1, N2, N3 N1&N2&N3 = Value ENDM ; Вызов функции (по смещению) Ofs объекта Obj с параметрами params cominvk MACRO Obj, Ofs, Params:VARARG LOCAL param, reversed reversed TEXTEQU <> % FOR param, reversed CATSTR ,,reversed ENDM % FOR param, push param ENDM mov eax,Obj push eax mov eax,[eax] call DWORD PTR [eax+Ofs] ENDM ; Определить интерфейс с именем ComName и функциями из списка FuncList Interface MACRO ComName, FuncList:VARARG LOCAL N, func ComName&_QueryInterface = 0*4 ComName&_AddRef = 1*4 ComName&_Release = 2*4 N = 3 FOR func, Def_CatStr N*4, ComName,_,func N = N + 1 ENDM ENDM ; Выполнить Inst, если имя DEBUG определено и не равно 0 DEBUG_ MACRO Inst:VARARG ifdef DEBUG if DEBUG Inst endif endif ENDM ; Определение функций интерфейсов Interface IMMDeviceEnumerator, EnumAudioEndpoints, GetDefaultAudioEndpoint, GetDevice, RegisterEndpointNotificationCallback, UnregisterEndpointNotificationCallback Interface IMMDevice, Activate, OpenPropertyStore, GetId, GetState Interface IPropertyStore, GetCount, GetAt, GetValue, SetValue, Commit BLOB STRUCT cbSize DD ? pBlobData DD ? BLOB ENDS PropVariant STRUCT vt DW ? wRes1 DB ? wRes2 DB ? wRes3 DD ? blob BLOB <> PropVariant ENDS ;-- ДАННЫЕ ------------------------------------------------------------------------------------------------------------- .DATA fmtInfo DB 'Default Wave Format:',13,10 DB ' FormatTag = %i%s',13,10 DB ' SamplesPerSec = %i',13,10 DB ' BitsPerSample = %i',13,10 DB ' Channels = %i',13,10 DB ' AvgBytesPerSec = %i',13,10 DB ' BlockAlign = %i',13,10,0 fmtExtraInfo DB 10,'Extra Info:',13,10 DB ' ValidBitsPerSample = %i',13,10 DB ' ChannelMask = %08X (hex)',13,10 DB ' SubFormat GUID = ',0 strWaveFmtExt DB ' (WAVE_FORMAT_EXTENSIBLE)' strZero DB 0 strError DB 'Interface error :(' strNewLine DB 13,10,0 DEBUG_ fmtDebug DB '%s = %i',13,10,0 DEBUG_ strCoCreateInstance DB 'DEBUG: CoCreateInstance(IMMDeviceEnumerator)',0 DEBUG_ strIMMDeviceEnumerator DB 'DEBUG: IMMDeviceEnumerator.GetDefaultAudioEndpoint',0 DEBUG_ strIMMDevice DB 'DEBUG: IMMDevice.OpenPropertyStore',0 DEBUG_ strIPropertyStore DB 'DEBUG: IPropertyStore.GetValue(PKEY_AudioEngine_DeviceFormat)',0 DEBUG_ strIMMDeviceEnumeratorRelease DB 'DEBUG: IMMDeviceEnumerator.Release',0 DEBUG_ strIMMDeviceRelease DB 'DEBUG: IMMDevice.Release',0 DEBUG_ strIPropertyStoreRelease DB 'DEBUG: IPropertyStore.Release',0 CLASS_MMDeviceEnumerator GUID {0BCDE0395h,0E52Fh,0467Ch,{08Eh,03Dh,0C4h,057h,092h,091h,069h,02Eh}} IID_IMMDeviceEnumerator GUID {0A95664D2h,09614h,04F35h,{0A7h,046h,0DEh,08Dh,0B6h,036h,017h,0E6h}} PKEY_AudioEngine_DeviceFormat GUID {0F19F064Dh,0082Ch,04E27h,{0BCh,073h,068h,082h,0A1h,0BBh,08Eh,04Ch}} DD 0 ; часть PKEY_AudioEngine_DeviceFormat MMDevEnum DD 0 MMDev DD 0 PropStore DD 0 .DATA? Prop PropVariant <> GUIDString DW 40 dup (?) InputRec INPUT_RECORD <> ReallyRead DD ? ;-- ОСНОВНОЙ КОД ------------------------------------------------------------------------------------------------------- .CODE Start: invoke CoInitialize, NULL ; CoCreateInstance(CLASS_MMDeviceEnumerator, nil, CLSCTX_ALL, IID_IMMDeviceEnumerator, MMDevEnum) invoke CoCreateInstance, ADDR CLASS_MMDeviceEnumerator, NULL, CLSCTX_ALL, ADDR IID_IMMDeviceEnumerator, ADDR MMDevEnum DEBUG_ push eax DEBUG_ invoke printf, ADDR fmtDebug, ADDR strCoCreateInstance, eax DEBUG_ pop eax test eax,eax jnz Error ; MMDevEnum.GetDefaultAudioEndpoint(eRender, eMultimedia, MMDev) cominvk MMDevEnum, IMMDeviceEnumerator_GetDefaultAudioEndpoint, eRender, eMultimedia, OFFSET MMDev DEBUG_ push eax DEBUG_ invoke printf, ADDR fmtDebug, ADDR strIMMDeviceEnumerator, eax DEBUG_ pop eax test eax,eax jnz Error ; MMDev.OpenPropertyStore(STGM_READ, PropStore) cominvk MMDev, IMMDevice_OpenPropertyStore, STGM_READ, OFFSET PropStore DEBUG_ push eax DEBUG_ invoke printf, ADDR fmtDebug, ADDR strIMMDevice, eax DEBUG_ pop eax test eax,eax jnz Error ; PropStore.GetValue(Key, Prop) cominvk PropStore, IPropertyStore_GetValue, OFFSET PKEY_AudioEngine_DeviceFormat, OFFSET Prop DEBUG_ push eax DEBUG_ invoke printf, ADDR fmtDebug, ADDR strIPropertyStore, eax DEBUG_ pop eax test eax,eax jnz Error DEBUG_ invoke printf, ADDR strNewLine ; Выводим результаты mov ebx,Prop.blob.pBlobData movzx esi,[ebx+WAVEFORMATEX.wFormatTag] movzx eax,[ebx+WAVEFORMATEX.wBitsPerSample] movzx ecx,[ebx+WAVEFORMATEX.nChannels] movzx edx,[ebx+WAVEFORMATEX.nBlockAlign] mov edi,OFFSET strZero cmp esi,WAVE_FORMAT_EXTENSIBLE jne NotExt mov edi,OFFSET strWaveFmtExt NotExt: invoke printf, ADDR fmtInfo, esi, edi, [ebx+WAVEFORMATEX.nSamplesPerSec], eax, ecx, [ebx+WAVEFORMATEX.nAvgBytesPerSec], edx ; Дополнительные данные cmp esi,WAVE_FORMAT_EXTENSIBLE jne Finish movzx eax,WORD PTR [ebx+18] invoke printf, ADDR fmtExtraInfo, eax, DWORD PTR [ebx+20] lea eax,[ebx+24] invoke StringFromGUID2, eax, ADDR GUIDString, LENGTHOF GUIDString ; переводим GUID в Unicode-строку invoke wprintf, ADDR GUIDString invoke printf, ADDR strNewLine Finish: ; Освобождаем все интерфейсы DEBUG_ invoke printf, ADDR strNewLine cmp MMDevEnum,0 je @@NoMMDevEnum @@: cominvk MMDevEnum, IMMDeviceEnumerator_Release ;DEBUG_ push eax DEBUG_ invoke printf, ADDR fmtDebug, ADDR strIMMDeviceEnumeratorRelease, eax ;DEBUG_ pop eax ; test eax,eax ; jnz @B @@NoMMDevEnum: cmp MMDev,0 je @@NoMMDev @@: cominvk MMDev, IMMDevice_Release ;DEBUG_ push eax DEBUG_ invoke printf, ADDR fmtDebug, ADDR strIMMDeviceRelease, eax ;DEBUG_ pop eax ; test eax,eax ; jnz @B @@NoMMDev: cmp PropStore,0 je @@NoPropStore @@: cominvk PropStore, IPropertyStore_Release ;DEBUG_ push eax DEBUG_ invoke printf, ADDR fmtDebug, ADDR strIPropertyStoreRelease, eax ;DEBUG_ pop eax ; test eax,eax ; jnz @B @@NoPropStore: ; Ожидаем нажатия любой клавиши invoke GetStdHandle, STD_INPUT_HANDLE mov ebx,eax @@LoopInput: invoke ReadConsoleInput, ebx, offset InputRec, 1, offset ReallyRead test eax,eax jz @@Error cmp InputRec.EventType, KEY_EVENT jne @@LoopInput cmp InputRec.KeyEvent.bKeyDown, 0 je @@LoopInput @@Error: invoke ExitProcess, NULL Error: invoke printf, ADDR strError ; сообщение об ошибке jmp Finish END Start