;**************************************************************************** ;** ** ;** ** ;** ** ;** ** ;** ** ;** ** ;** ** ;** ** ;**************************************************************************** .386 .xlist include vmm.inc include vtd.inc include debug.inc ; include mmdevldr.inc include vwin32.inc include pagefile.inc include vmcpd.inc ; include shell.inc ; include debugsys.inc .list Create_DSOUND_Service_Table equ 1 include dsdriver.inc OPTION SCOPED ;**************************************************************************** ;** ** ;** VxD declaration ** ;** ** ;**************************************************************************** DSOUND_VERSION_MAJOR equ 4 ; Version 4.02 DSOUND_VERSION_MINOR equ 2 ; Declare_Virtual_Device DSOUND, \ DSOUND_VERSION_MAJOR, DSOUND_VERSION_MINOR, \ DSOUND_Control, \ DSOUND_Device_ID, \ UNDEFINED_INIT_ORDER, \ DSOUND_API_Handler, \ DSOUND_API_Handler ;**************************************************************************** ;** ** ;** Macro, equate, and type declarations ** ;** ** ;**************************************************************************** LONG_MAX equ 7fffffffh ;Maximum 32-bit signed value RESAMPLING_TOLERANCE equ 0 ;E.g., 655=1% resampling tolerance ;**************************************************************************** ;** ** ;** Locked data ** ;** ** ;**************************************************************************** VxD_LOCKED_DATA_SEG ;**************************************************************************** ;** ** ;** Primitive vectors generated at beginning of data segment ** ;** ** ;** 1st 32 entries: MAKE_DC procedures for AILSSA_DMA_copy() ** ;** 2nd 128 entries: MAKE_MERGE procedures for AILSSA_merge() ** ;** ** ;**************************************************************************** ; ;First device code is duplicated since IOCTL calls with ;function 0 always fail in Win95 for some reason ; ;--- ; ; Read the documentation, silly. Function 0 is DIOC_OPEN. ; It is the VxD version of PROCESS_ATTACH. DSVXD_IOCTL_Table LABEL DWORD dd OFFSET32 _ioctlDsvxdGetVersion dd OFFSET32 _ioctlDsvxdInitialize dd OFFSET32 _ioctlDsvxdShutdown dd OFFSET32 _ioctlDrvGetNextDescFromGuid dd OFFSET32 _ioctlDrvGetDescFromGuid dd OFFSET32 _ioctlIDsDriver_QueryInterface dd OFFSET32 _ioctlDrvOpenFromGuid dd OFFSET32 _ioctlIDsDriver_Close dd OFFSET32 _ioctlIDsDriver_GetCaps dd OFFSET32 _ioctlIDsDriver_CreateSoundBuffer dd OFFSET32 _ioctlIDsDriver_DuplicateSoundBuffer dd OFFSET32 _ioctlBufferRelease dd OFFSET32 _ioctlBufferLock dd OFFSET32 _ioctlBufferUnlock dd OFFSET32 _ioctlBufferSetFormat dd OFFSET32 _ioctlBufferSetFrequency dd OFFSET32 _ioctlBufferSetVolumePan dd OFFSET32 _ioctlBufferSetPosition dd OFFSET32 _ioctlBufferGetPosition dd OFFSET32 _ioctlBufferPlay dd OFFSET32 _ioctlBufferStop dd OFFSET32 _ioctlEventScheduleWin32Event dd OFFSET32 _ioctlEventCloseVxDHandle dd OFFSET32 _ioctlMemReserveAlias dd OFFSET32 _ioctlMemCommitAlias dd OFFSET32 _ioctlMemRedirectAlias dd OFFSET32 _ioctlMemDecommitAlias dd OFFSET32 _ioctlMemFreeAlias dd OFFSET32 _ioctlMemPageLock dd OFFSET32 _ioctlMemPageUnlock dd OFFSET32 _ioctlDsvxd_PageFile_Get_Version dd OFFSET32 _ioctlDsvxd_VMM_Test_Debug_Installed dd OFFSET32 _ioctlDsvxd_VMCPD_Get_Version dd OFFSET32 _ioctlDsvxd_GetMixerMutexPtr dd OFFSET32 _ioctlMixer_Run dd OFFSET32 _ioctlMixer_Stop dd OFFSET32 _ioctlMixer_PlayWhenIdle dd OFFSET32 _ioctlMixer_StopWhenIdle dd OFFSET32 _ioctlMixer_MixListAdd dd OFFSET32 _ioctlMixer_MixListRemove dd OFFSET32 _ioctlMixer_FilterOn dd OFFSET32 _ioctlMixer_FilterOff dd OFFSET32 _ioctlMixer_GetBytePosition dd OFFSET32 _ioctlMixer_SignalRemix dd OFFSET32 _ioctlKeDest_New dd OFFSET32 _ioctlMixDest_Delete dd OFFSET32 _ioctlMixDest_Initialize dd OFFSET32 _ioctlMixDest_Terminate dd OFFSET32 _ioctlMixDest_SetFormat dd OFFSET32 _ioctlMixDest_SetFormatInfo dd OFFSET32 _ioctlMixDest_AllocMixer dd OFFSET32 _ioctlMixDest_FreeMixer dd OFFSET32 _ioctlMixDest_Play dd OFFSET32 _ioctlMixDest_Stop dd OFFSET32 _ioctlMixDest_GetFrequency dd OFFSET32 _ioctlMemCommitPhysAlias dd OFFSET32 _ioctlMemRedirectPhysAlias dd OFFSET32 _ioctlIUnknown_QueryInterface dd OFFSET32 _ioctlIUnknown_AddRef dd OFFSET32 _ioctlIUnknown_Release dd OFFSET32 _ioctlIDirectSoundPropertySet_GetProperty dd OFFSET32 _ioctlIDirectSoundPropertySet_SetProperty dd OFFSET32 _ioctlIDirectSoundPropertySet_QuerySupport dd OFFSET32 _ioctlGetInternalVersionNumber DSOUND_N_IOCTLS EQU ($-DSVXD_IOCTL_Table) / SIZE DWORD ; ;Pointer to input/output parms ; IOCTL_parms dd ? VxD_LOCKED_DATA_ENDS ;**************************************************************************** ;** ** ;** Locked code ** ;** ** ;**************************************************************************** VxD_LOCKED_CODE_SEG extrn _ioctlDsvxdInitialize:NEAR extrn _ioctlDsvxdShutdown:NEAR extrn _ioctlDrvGetNextDescFromGuid:NEAR extrn _ioctlDrvGetDescFromGuid:NEAR extrn _ioctlDrvOpenFromGuid:NEAR extrn _ioctlIDsDriver_QueryInterface:NEAR extrn _ioctlIDsDriver_Close:NEAR extrn _ioctlIDsDriver_GetCaps:NEAR extrn _ioctlIDsDriver_CreateSoundBuffer:NEAR extrn _ioctlIDsDriver_DuplicateSoundBuffer:NEAR extrn _ioctlBufferRelease:NEAR extrn _ioctlBufferLock:NEAR extrn _ioctlBufferUnlock:NEAR extrn _ioctlBufferSetFormat:NEAR extrn _ioctlBufferSetFrequency:NEAR extrn _ioctlBufferSetVolumePan:NEAR extrn _ioctlBufferSetPosition:NEAR extrn _ioctlBufferGetPosition:NEAR extrn _ioctlBufferPlay:NEAR extrn _ioctlBufferStop:NEAR extrn _ioctlEventScheduleWin32Event:NEAR extrn _ioctlEventCloseVxDHandle:NEAR extrn _ioctlMemReserveAlias:NEAR extrn _ioctlMemCommitAlias:NEAR extrn _ioctlMemRedirectAlias:NEAR extrn _ioctlMemDecommitAlias:NEAR extrn _ioctlMemFreeAlias:NEAR extrn _ioctlMemPageLock:NEAR extrn _ioctlMemPageUnlock:NEAR extrn _ioctlDsvxd_PageFile_Get_Version:NEAR extrn _ioctlDsvxd_VMM_Test_Debug_Installed:NEAR extrn _ioctlDsvxd_VMCPD_Get_Version:NEAR extrn _ioctlDsvxd_GetMixerMutexPtr:NEAR extrn _ioctlMixer_Run:NEAR extrn _ioctlMixer_Stop:NEAR extrn _ioctlMixer_PlayWhenIdle:NEAR extrn _ioctlMixer_StopWhenIdle:NEAR extrn _ioctlMixer_MixListAdd:NEAR extrn _ioctlMixer_MixListRemove:NEAR extrn _ioctlMixer_FilterOn:NEAR extrn _ioctlMixer_FilterOff:NEAR extrn _ioctlMixer_GetBytePosition:NEAR extrn _ioctlMixer_SignalRemix:NEAR extrn _ioctlKeDest_New:NEAR extrn _ioctlMixDest_Delete:NEAR extrn _ioctlMixDest_Initialize:NEAR extrn _ioctlMixDest_Terminate:NEAR extrn _ioctlMixDest_SetFormat:NEAR extrn _ioctlMixDest_SetFormatInfo:NEAR extrn _ioctlMixDest_AllocMixer:NEAR extrn _ioctlMixDest_FreeMixer:NEAR extrn _ioctlMixDest_Play:NEAR extrn _ioctlMixDest_Stop:NEAR extrn _ioctlMixDest_GetFrequency:NEAR extrn _ioctlMemCommitPhysAlias:NEAR extrn _ioctlMemRedirectPhysAlias:NEAR extrn _ioctlIUnknown_QueryInterface:NEAR extrn _ioctlIUnknown_AddRef:NEAR extrn _ioctlIUnknown_Release:NEAR extrn _ioctlIDirectSoundPropertySet_QuerySupport:NEAR extrn _ioctlIDirectSoundPropertySet_SetProperty:NEAR extrn _ioctlIDirectSoundPropertySet_GetProperty:NEAR extrn _ioctlGetInternalVersionNumber:NEAR ;**************************************************************************** ;** ** ;** IOCTL dispatcher for VxD ** ;** ** ;** Dispatch control messages to the correct handlers. Must be in ** ;** locked code segment. (All VxD segments are locked in 3.0/3.1) ** ;** ** ;** ENTRY: ** ;** ** ;** EXIT: ** ;** Carry clear success; Carry Set if fail. ** ;** ** ;**************************************************************************** BeginProc DSOUND_Control Control_Dispatch Sys_Dynamic_Device_Init, ctrlDynamicDeviceInitA Control_Dispatch Sys_Dynamic_Device_Exit, ctrlDynamicDeviceExitA Control_Dispatch W32_DEVICEIOCONTROL, ctrlDeviceIOControl ; Trace_Out "DSOUND_Control " clc ret EndProc DSOUND_Control ;**************************************************************************** ;** ** ;** API dispatcher for VxD ** ;** ** ;** Dispatch control messages to the correct handlers. ** ;** ** ;** ENTRY: ** ;** ** ;** EXIT: ** ;** Carry clear success; Carry Set if fail. ** ;** ** ;**************************************************************************** BeginProc DSOUND_API_Handler Trace_Out "DSOUND_API_Handler " clc ret EndProc DSOUND_API_Handler ;---------------------------------------------------------------------------; ; ; ctrlDynamicDeviceInit and Exit ; ;---------------------------------------------------------------------------; BeginProc ctrlDynamicDeviceInitA Ccall _ctrlDynamicDeviceInit sub eax, 1 ret EndProc ctrlDynamicDeviceInitA BeginProc ctrlDynamicDeviceExitA Ccall _ctrlDynamicDeviceExit sub eax, 1 ret EndProc ctrlDynamicDeviceExitA ;------------------------------------------------------------------------------ ; FUNC DSOUND_GetVersion - Locked Code ; ; ENTRY ; None ; ; EXIT ; AH = Major version number ; AL = Minor version number ; Carry flag clear ; ; USES ; EAX, Flags ; ;------------------------------------------------------------------------------ BeginProc _DSOUND_GetVersion, SERVICE mov eax, DSOUND_VERSION_MAJOR * 100h + DSOUND_VERSION_MINOR clc ret EndProc _DSOUND_GetVersion ;**************************************************************************** ;** ** ;** ctrlDeviceIOControl ** ;** ** ;** DESCRIPTION: This function is called to perform Device IO ** ;** for a 32 bit process which has opened this device with ** ;** , and is performing IO using ** ;** . Preserves the C32 calling registers ** ;** ESI, EDI, and EBX. ** ;** ** ;** ENTRY: EBX DDB ** ;** ECX dwIoControlCode ** ;** ESI ptr to DIOCParams ** ;** ** ;** EXIT: As determined by function, or 1 if invalid IOCTL ** ;** ** ;** ----- ** ;** ** ;** Note: Function 0 is documented in vmm.h ** ;** as DIOC_OPEN. It is your VxD's PROCESS_ATTACH call. ** ;** ** ;**************************************************************************** BeginProc ctrlDeviceIOControl cmp ecx, DSOUND_N_IOCTLS jae cDIOC_InvalidCode push edi push esi push ebx mov IOCTL_parms,esi push esi call DSVXD_IOCTL_Table[ecx*4] add esp, 4 pop ebx pop esi pop edi ret cDIOC_InvalidCode: IFDEF DEBUG cmp ecx, DIOC_CLOSEHANDLE Debug_OutNZ "DSVXD: Invalid dwIoControlCode #ECX" ENDIF mov eax, 1 ; ERROR_INVALID_FUNCTION ret EndProc ctrlDeviceIOControl ;**************************************************************************** ;** ** ;** _ioctlDsvxdGetVersion ** ;** ** ;** DESCRIPTION: Get the version of DSVXD ** ;** ** ;** ENTRY: ** ;** ** ;** EXIT: ** ;** ** ;**************************************************************************** BeginProc _ioctlDsvxdGetVersion Trace_Out "DSVXD: ioctlDsvxdGetVersion" xor eax, eax mov ecx, DSOUND_VERSION_MAJOR * 100h + DSOUND_VERSION_MINOR ret EndProc _ioctlDsvxdGetVersion ;**************************************************************************** ;** ** ;** ** ;** ** ;**************************************************************************** ;--------------------------------------------------------------------------; ; ; _Dsvxd_VMM_Test_Debug_Installed ; ; Out: ; ; Notes: ; ;--------------------------------------------------------------------------; BeginProc _Dsvxd_VMM_Test_Debug_Installed EnterProc VMMcall Test_Debug_Installed mov eax, 0 jz @F inc eax @@: LeaveProc Return EndProc _Dsvxd_VMM_Test_Debug_Installed ;--------------------------------------------------------------------------; ; ; _Dsvxd_PageFile_Get_Version ; ; Out: ; ; Notes: ; ;--------------------------------------------------------------------------; BeginProc _Dsvxd_PageFile_Get_Version ArgVar p_version, DWORD ArgVar p_maxsize, DWORD ArgVar p_pager_type, DWORD EnterProc pushad VxDcall PageFile_Get_Version mov edi, p_version mov [edi], eax mov edi, p_maxsize mov [edi], ecx xor eax, eax mov al, bl mov edi, p_pager_type mov [edi], eax popad LeaveProc Return EndProc _Dsvxd_PageFile_Get_Version ;--------------------------------------------------------------------------; ; ; _Dsvxd_VMCPD_Get_Version ; ; Out: ; ; Notes: ; ;--------------------------------------------------------------------------; BeginProc _Dsvxd_VMCPD_Get_Version ArgVar pMajorVersion, DWORD ArgVar pMinorVersion, DWORD ArgVar pLevel, DWORD EnterProc pushad VxDcall VMCPD_Get_Version xor ebx, ebx mov edi, pMajorVersion mov bl, ah mov [edi], ebx mov bl, al mov edi, pMinorVersion mov [edi], ebx mov edi, pLevel mov [edi], ecx popad LeaveProc Return EndProc _Dsvxd_VMCPD_Get_Version ;--------------------------------------------------------------------------; ; ; _KeGrace_GlobalTimeOutProcAsm ; ; This is the entry point for the global time out set by the ; KeGrace object. This is just an ASM thunk to KeGrace_GlobalTimeOutProc ; "C" function. ; ; This function is called from the VMM as follows: ; ; mov ebx, VMHandle ; current VM handle ; mov ecx, Tardiness ; number of milliseconds since time-out ; mov edx, RefData ; reference data ; mov ebp, OFFSET32 crs ; points to Client_Reg_Struc ; call [TimeOutCallback] ; ; Out: ; ; Notes: ; ;--------------------------------------------------------------------------; extrn _KeGrace_GlobalTimeOutProc:NEAR BeginProc _KeGrace_GlobalTimeOutProcAsm ; The reference data is a pointer to and EVENTPARAMS structure whose ; first member is the event handle and second member is the "this" pointer ; to the KeGrace object xor eax, eax xchg [edx], eax ; Clear the event handle Debug_OutEAXz "DSVXD: executing KeGrace_GlobalTimeOutProcAsm after cancelled!" or eax, eax jz @F pushad push ecx ; Pass tardiness push [edx + 4] ; Pass "this" to the "C" function Ccall _KeGrace_GlobalTimeOutProc add esp, 8 popad @@: ret EndProc _KeGrace_GlobalTimeOutProcAsm ;--------------------------------------------------------------------------; ; ; _VMEvent_SetWin32Event ; ; This is a VM EventCallback scheduled by _AsyncTimeOut_SetWin32Event. ; This calls VWin32 to set a Win32 event. ; ; In: ; ebx = vm handle ; edi = thread handle ; edx = refdata = vxd handle to win32 event ; ebp = offset32 client reg struc ; ; Out: ; ; Notes: ; See _eventScheduleWin32Event ; ;--------------------------------------------------------------------------; BeginProc _VMEvent_SetWin32Event mov eax, edx VxDcall _VWIN32_SetWin32Event ret EndProc _VMEvent_SetWin32Event ;--------------------------------------------------------------------------; ; ; _AsyncTimeOut_SetWin32Event ; ; This is an async timeout callback set by _Set_SetWin32Event_TimeOut. ; This schedules _VMEvent_SetWin32Event as a sys vm event callback. ; ; In: ; ecx = tardiness ; edx = reference data = vxd handle to win32 event ; ; Out: ; ; Notes: ; See _eventScheduleWin32Event ; ;--------------------------------------------------------------------------; BeginProc _AsyncTimeOut_SetWin32Event push ebx push esi VMMcall Get_Sys_VM_Handle mov esi, _VMEvent_SetWin32Event VMMcall Schedule_VM_Event pop esi pop ebx ret EndProc _AsyncTimeOut_SetWin32Event ;--------------------------------------------------------------------------; ; ; _EventScheduleWin32Event ; ; This signals a win32 event after a specified delay. ; ; In: ; vxdhEvent - vxd handle to win32 event ; dwDelay - milliseconds delay ; ; Out(int): ; 0 if failure, non-0 otherwise ; ; Notes: ; Use 'C' calling convention. Sets an async timeout which in ; turn schedules a vm event to actually signal the win32 event. ; ;--------------------------------------------------------------------------; BeginProc _eventScheduleWin32Event ArgVar vxdhEvent,DWORD ArgVar dwDelay,DWORD EnterProc push ebx push esi mov eax, dwDelay test eax, eax jnz _ESW32E_delayed VMMcall Get_Sys_VM_Handle mov esi, _VMEvent_SetWin32Event mov edx, vxdhEvent Vmmcall Call_VM_Event mov eax, -1 jmp _ESW32E_exit _ESW32E_delayed: Debug_Out "DSVXD: Tried to set a defered win32 event???" mov edx, vxdhEvent mov esi, _AsyncTimeOut_SetWin32Event VMMcall Set_Async_Time_Out mov eax, esi _ESW32E_exit: pop esi pop ebx LeaveProc Return EndProc _eventScheduleWin32Event VXD_LOCKED_CODE_ENDS END