Jump to content

How Do I Change The System/Master Volume?

- - - - -

  • Please log in to reply
2 replies to this topic

#1
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,252 posts
  • Location:C:\Countries\US
Hello everyone. I am trying to write a program that would be able to mute/turn loud/restore volume of the computer. This is for Windows, using the Win32 API. I tried using waveOutSetVolume(), from winmm.dll, but that didn't work.

I already have the handling procedures for the hotkeys, and everything, it's just this part doesn't work. (By the way, I just found out, from trying it with this project, that you don't even need a window to receive WM_* messages.)

Here's the code, if it's needed:
;; winmm.dll is one of the DLLs that we'll have to import functions from. 


;; Externs. 

extern RegisterHotKey 

extern UnregisterHotKey 

extern GetMessageA 

extern TranslateMessage 

extern ExitProcess 


extern OpenFile 

extern ReadFile 

extern CloseHandle 


extern waveOutSetVolume 

extern waveOutGetVolume 


extern MessageBoxA 


;; Imports. 

import RegisterHotKey user32.dll 

import UnregisterHotKey user32.dll 

import GetMessageA user32.dll 

import TranslateMessage user32.dll 

import ExitProcess kernel32.dll 


import OpenFile kernel32.dll 

import ReadFile kernel32.dll 

import CloseHandle kernel32.dll 


import waveOutSetVolume winmm.dll 

import waveOutGetVolume winmm.dll 


import MessageBoxA user32.dll 


;; Defines. 

%define MOD_ALT                        0x0001 

%define MOD_CONTROL                    0x0002 

%define MOD_NOREPEAT                   0x4000 

%define MOD_SHIFT                      0x0004 

%define MOD_WIN                        0x0008 


%define WM_HOTKEY                      0x0312 


%define IDOK                           0x0001 


;; MY_* defines. 

%define MY_LOUD                        0x0001 

%define MY_MUTE                        0x0002 

%define MY_WAIT                        0x0003 

%define MY_EXIT                        0x0004 

%define MY_TIME                        0x0005 

%define MY_SYNC                        0x0006 

%define MY_PREV                        0x0007 


section .text use32 

..start: 


call main 


push eax 

call [ExitProcess] 


main: 

	enter 28, 0 

	

	call InitVolumeControl 

	

	call ReadConfig 

	

	push dword 1 

	call RegisterKeys 

	

	.MessageLoop: 

		lea ebx, [ebp-28] 

		

		push dword 0 

		push dword 0 

		push dword 0 

		push dword ebx 

		call [GetMessageA] 

		cmp eax, 0 

		jz .ExitMessageLoop 

		

		push dword ebx 

		call [TranslateMessage] 

		

		cmp dword [ebx+4], WM_HOTKEY 

		jnz .MessageLoop 

		

		mov eax, dword [ebx+8] 

		cmp eax, MY_LOUD 

		jz .go_loud 

		cmp eax, MY_MUTE 

		jz .go_mute 

		cmp eax, MY_WAIT 

		jz .go_wait 

		cmp eax, MY_EXIT 

		jz .go_exit 

		cmp eax, MY_SYNC 

		jz .go_sync 

		cmp eax, MY_PREV 

		jz .go_prev 

		

		jmp .MessageLoop 

	.go_loud: 

		call LoudVolume 

		

		push dword 0 

		push dword ApplicationName 

		push dword loud_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .MessageLoop 

	.go_mute: 

		call MuteVolume 

		

		push dword 0 

		push dword ApplicationName 

		push dword mute_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .MessageLoop 

	.go_wait: 

		push dword 0 

		push dword ApplicationName 

		push dword wait_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .MessageLoop 

	.go_exit: 

		push dword 0 

		push dword ApplicationName 

		push dword exit_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .ExitMessageLoop 

		

		jmp .MessageLoop 

	.go_sync: 

		push dword 1 

		push dword ApplicationName 

		push dword sync_msg 

		push dword 0 

		call [MessageBoxA] 

		cmp eax, IDOK 

		jnz .MessageLoop 

		

		call ReadConfig 

		

		push dword 1 

		call RegisterKeys 

		

		jmp .MessageLoop 

	.go_prev: 

		call PrevVolume 

		

		push dword 0 

		push dword ApplicationName 

		push dword prev_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .MessageLoop 

	.ExitMessageLoop: 

	

	;; If the parameter is 0, RegisterKeys() deregisters the hotkeys, and 

	;; does (just about) nothing else. 

	push dword 0 

	call RegisterKeys 

	

	xor eax, eax 

	leave 

ret 0 


ReadConfig: 

	enter 144, 0 

	;; hFile = [ebp-4] 

	;; ofs = [ebp-140] 

	;; brd = [ebp-144] 

	pusha 

	

	push dword dv1 

	push dword vl1 

	call strcpy 

	

	push dword dv2 

	push dword vl2 

	call strcpy 

	

	push dword dv3 

	push dword vl3 

	call strcpy 

	

	push dword dv4 

	push dword vl4 

	call strcpy 

	

	push dword dv5 

	push dword vl5 

	call strcpy 

	

	push dword dv6 

	push dword vl6 

	call strcpy 

	

	push dword dv7 

	push dword vl7 

	call strcpy 

	

	mov dword [ebp-144], 0 

	

	;; Open file. 

	lea eax, [ebp-140] 

	push dword 0 

	push dword eax 

	push dword fn_cnf 

	call [OpenFile] 

	mov dword [ebp-4], eax 

	

	;; Read file to buffer. 

	lea eax, [ebp-144] 

	push dword 0 

	push dword eax 

	push dword buff_len 

	push dword buff_txt 

	push dword [ebp-4] 

	call [ReadFile] 

	

	;; NULL-terminate data. 

	push dword [ebp-144] 

	mov ebx, buff_txt 

	pop ecx 

	mov dword [ebx+ecx], 0 

	

	;; Close file. 

	push dword [ebp-4] 

	call [CloseHandle] 

	

	

	;; Okay, now the scanning. We have to scan the text buffer, that we just read, for the configuration settings. 

	

	mov ebx, buff_txt 

	.lp1: 

		cmp byte [ebx], 0 

		jz .lp1s 

		

		;; Copy whatever we're at to our temporary string. 

		push dword ebx 

		push dword temp_str 

		call strcpy 

		

		;; Chomp the temporary string. 

		push ebx 

			mov ebx, temp_str 

			call to_nl 

			mov byte [ebx], 0 

		pop ebx 

		

		;; The temporary string most supposably contains a string of the format 'name=value' 

		;; Set the element, in our hash, with that name to that value. 

		push dword temp_str 

		push dword config 

		call SetHash 

		

		call to_nl 

		jmp .lp1 

	.lp1s: 

	

	popa 

	leave 

ret 0 


;; RegisterKeys (bool register_keys); 

RegisterKeys: 

	enter 516, 0 

	

	lea eax, [ebp-516] 

	mov dword [ebp-4], eax 

	

	mov eax, MY_LOUD 

	call .undo 

	mov eax, MY_MUTE 

	call .undo 

	mov eax, MY_WAIT 

	call .undo 

	mov eax, MY_EXIT 

	call .undo 

	; mov eax, MY_TIME 

	; call .undo 

	mov eax, MY_SYNC 

	call .undo 

	mov eax, MY_PREV 

	call .undo 

	

	;; If need not to register keys, exit. 

	mov eax, dword [ebp+8] 

	test eax, eax 

	jz .finish 

	

	mov eax, values.j_loud 

	mov ecx, MY_LOUD 

	call .act 

	

	mov eax, values.j_mute 

	mov ecx, MY_MUTE 

	call .act 

	

	mov eax, values.j_wait 

	mov ecx, MY_WAIT 

	call .act 

	

	mov eax, values.j_exit 

	mov ecx, MY_EXIT 

	call .act 

	test eax, eax 

	jnz .over1 

		

		mov eax, MY_LOUD 

		call .undo 

		mov eax, MY_MUTE 

		call .undo 

		mov eax, MY_WAIT 

		call .undo 

		

		push dword 0 

		push dword ApplicationName 

		push dword startup_err_msg 

		push dword 0 

		call [MessageBoxA] 

		

		push dword 1 

		call [ExitProcess] 

		

	.over1: 

	

	; mov eax, values.j_time 

	; mov ecx, MY_TIME 

	; call .act 

	

	mov eax, values.j_sync 

	mov ecx, MY_SYNC 

	call .act 

	

	mov eax, values.j_prev 

	mov ecx, MY_PREV 

	call .act 

	

	call .work_time 

	

	jmp .finish 

	

	.act: 

	push dword eax 

	push dword [ebp-4] 

	call strcpy 

	

	push dword [ebp-4] 

	push dword config 

	call GetHash 

	

	mov al, byte [ebp-516] 

	call ensure_cap_byte 

	push dword eax 

	push dword MOD_CONTROL | MOD_ALT 

	push dword ecx 

	push dword 0 

	call [RegisterHotKey] 

	

	ret 0 

	

	.undo: 

	push dword eax 

	push dword 0 

	call [UnregisterHotKey] 

	

	ret 0 

	

	.work_time: 

	push dword values.j_time 

	push dword [ebp-4] 

	call strcpy 

	

	push dword [ebp-4] 

	push dword config 

	call GetHash 

	

	push dword [ebp-4] 

	call str2i 

	mov dword [myTime], eax 

	

	ret 0 

	

	.finish: 

	

	leave 

ret 4 


ensure_cap_byte: 

	cmp al, 123 

	jnl .finish 

	cmp al, 97 

	jl .finish 

	sub al, 32 

	.finish: 

ret 0 


to_nl: 

	.lp1: 

		mov al, byte [ebx] 

		cmp al, 13 

		jz .lp1s 

		cmp al, 10 

		jz .lp1s 

		cmp al, 0 

		jz .lp1s 

		

		inc ebx 

		jmp .lp1 

	.lp1s: 

	.lp2: 

		mov al, byte [ebx] 

		cmp al, 13 

		jz .lp2c 

		cmp al, 10 

		jz .lp2c 

		

		jmp .lp2s 

	.lp2c: 

		inc ebx 

		jmp .lp2 

	.lp2s: 

ret 0 


eq_nl: 

	push eax 

	push ebx 

	

	mov eax, dword [esp+12] 

	mov ebx, eax 

	

	.lp1: 

		mov al, byte [ebx] 

		cmp al, 61 

		jz .lp1s 

		cmp al, 0 

		jz .lp1s 

		

		inc ebx 

		jmp .lp1 

	.lp1s: 

	mov byte [ebx], 0 

	

	pop ebx 

	pop eax 

ret 4 


InitVolumeControl: 

	enter 512, 0 

	

	push dword prev_vol 

	push dword 0 

	call [waveOutGetVolume] 

	

	leave 

ret 0 


PrevVolume: 

	enter 512, 0 

	

	push dword [prev_vol] 

	push dword 0 

	call [waveOutSetVolume] 

	

	leave 

ret 0 


LoudVolume: 

	enter 512, 0 

	

	push dword [loud_vol] 

	push dword 0 

	call [waveOutSetVolume] 

	

	leave 

ret 0 


MuteVolume: 

	enter 512, 0 

	

	push dword 0 

	push dword 0 

	call [waveOutSetVolume] 

	

	leave 

ret 0 


%include "inc/str.asm" 

%include "inc/istr.asm" 

%include "inc/hash.asm" 


section .data 

myTime                                 dd 30     ;; 30 seconds is the default wait time. 


fn_int                                 db "interval.txt", 0 

fn_cnf                                 db "muteconf.txt", 0 


ApplicationName                        db "SoundCat", 0 


loud_msg                               db "Loud hotkey used. ", 0 

mute_msg                               db "Mute hotkey used. ", 0 

wait_msg                               db "Wait hotkey used. ", 0 

exit_msg                               db "Press OK to exit. ", 0 

sync_msg                               db "Press OK to sync SoundCat configurations. ", 0 

prev_msg                               db "Prev hotkey used. ", 0 


startup_err_msg                        db "Error:  Could not register the exit hotkey. ", 0 


nm1                                    db "loud", 0, 0, 0, 0 

nm2                                    db "mute", 0, 0, 0, 0 

nm3                                    db "wait", 0, 0, 0, 0 

nm4                                    db "exit", 0, 0, 0, 0 

nm5                                    db "time", 0, 0, 0, 0 

nm6                                    db "sync", 0, 0, 0, 0 

nm7                                    db "prev", 0, 0, 0, 0 


dv1                                    db "L", 0 

dv2                                    db "M", 0 

dv3                                    db "W", 0 

dv4                                    db "Q", 0 

dv5                                    db "30", 0 

dv6                                    db "S", 0 

dv7                                    db "P", 0 


config: 

dd nm1 

dd vl1 

dd nm2 

dd vl2 

dd nm3 

dd vl3 

dd nm4 

dd vl4 

dd nm5 

dd vl5 

dd nm6 

dd vl6 

dd nm7 

dd vl7 

dd 0 

dd 0 


values: 

.j_loud: 

db "loud", 0 

.j_mute: 

db "mute", 0 

.j_wait: 

db "wait", 0 

.j_exit: 

db "exit", 0 

.j_time: 

db "time", 0 

.j_sync: 

db "sync", 0 

.j_prev: 

db "prev", 0 


section .bss 

prev_vol                               dd 0 

loud_vol                               dd 0x7FFF7FFF 


buff_txt                               resb 4096 

buff_len                               equ  $ - buff_txt 


temp_str                               resb 4096 


vl1                                    resb 512 

vl2                                    resb 512 

vl3                                    resb 512 

vl4                                    resb 512 

vl5                                    resb 512 

vl6                                    resb 512 

vl7                                    resb 512 



#2
Gunner

Gunner

    Learning Programmer

  • Members
  • PipPipPip
  • 45 posts
Dang, went to look for the API in the SDK, didn't reinstall it after I built this new box. Here is some straight foward c code to look at: mixerSetControlDetails - CodeProject

#3
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,252 posts
  • Location:C:\Countries\US
Thanks for the resource.

Here's now what I have so far:
;; winmm.dll is one of the DLLs that we'll have to import functions from. 


;; Externs. 

extern RegisterHotKey 

extern UnregisterHotKey 

extern GetMessageA 

extern TranslateMessage 

extern ExitProcess 


extern OpenFile 

extern ReadFile 

extern CloseHandle 


extern mixerOpen 

extern mixerClose 

extern mixerGetLineInfoA 

extern mixerGetLineControlsA 

extern mixerSetControlDetails 

extern mixerGetControlDetailsA 


extern MessageBoxA 


;; Imports. 

import RegisterHotKey user32.dll 

import UnregisterHotKey user32.dll 

import GetMessageA user32.dll 

import TranslateMessage user32.dll 

import ExitProcess kernel32.dll 


import OpenFile kernel32.dll 

import ReadFile kernel32.dll 

import CloseHandle kernel32.dll 


import mixerOpen winmm.dll 

import mixerClose winmm.dll 

import mixerGetLineInfoA winmm.dll 

import mixerGetLineControlsA winmm.dll 

import mixerSetControlDetails winmm.dll 

import mixerGetControlDetailsA winmm.dll 


import MessageBoxA user32.dll 


;; Defines. 

%define MOD_ALT                        0x0001 

%define MOD_CONTROL                    0x0002 

%define MOD_NOREPEAT                   0x4000 

%define MOD_SHIFT                      0x0004 

%define MOD_WIN                        0x0008 


%define WM_HOTKEY                      0x0312 


%define IDOK                           0x0001 


%define MIXER_OBJECTF_MIXER            0x0000 

%define MIXER_GETLINEINFOF_COMPONENTTYPE 	0x0003 

%define MIXER_GETLINECONTROLSF_ONEBYTYPE 	0x0002 

%define MIXER_SETCONTROLDETAILSF_VALUE  	0x0000 

%define MIXER_GETCONTROLDETAILSF_VALUE  	0x0000 


%define MIXERLINE_COMPONENTTYPE_DST_FIRST       0x0000 

%define MIXERLINE_COMPONENTTYPE_DST_SPEAKERS 	MIXERLINE_COMPONENTTYPE_DST_FIRST | 4 

%define MIXERLINE_COMPONENTTYPE_DST_HEADPHONES	MIXERLINE_COMPONENTTYPE_DST_FIRST | 5 


%define MIXERCONTROL_CT_CLASS_FADER     	0x50000000 

%define MIXERCONTROL_CT_UNITS_UNSIGNED  	0x00030000 

%define MIXERCONTROL_CONTROLTYPE_FADER  	MIXERCONTROL_CT_CLASS_FADER | MIXERCONTROL_CT_UNITS_UNSIGNED 

%define MIXERCONTROL_CONTROLTYPE_VOLUME 	MIXERCONTROL_CONTROLTYPE_FADER + 1 


%define MIXERCONTROL_CT_CLASS_SWITCH            0x20000000 

%define MIXERCONTROL_CT_SC_SWITCH_BOOLEAN       0x00000000 

%define MIXERCONTROL_CT_UNITS_BOOLEAN           0x00010000 

%define MIXERCONTROL_CONTROLTYPE_BOOLEAN        MIXERCONTROL_CT_CLASS_SWITCH | MIXERCONTROL_CT_SC_SWITCH_BOOLEAN | MIXERCONTROL_CT_UNITS_BOOLEAN 

%define MIXERCONTROL_CONTROLTYPE_MUTE           MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2 


;; MY_* defines. 

%define MY_LOUD                        0x0001 

%define MY_MUTE                        0x0002 

%define MY_WAIT                        0x0003 

%define MY_EXIT                        0x0004 

%define MY_TIME                        0x0005 

%define MY_SYNC                        0x0006 

%define MY_PREV                        0x0007 


section .text use32 

..start: 


call main 


push eax 

call [ExitProcess] 


main: 

	enter 28, 0 

	

	call InitVolumeControl 

	

	call ReadConfig 

	

	push dword 1 

	call RegisterKeys 

	

	.MessageLoop: 

		lea ebx, [ebp-28] 

		

		push dword 0 

		push dword 0 

		push dword 0 

		push dword ebx 

		call [GetMessageA] 

		cmp eax, 0 

		jz .ExitMessageLoop 

		

		push dword ebx 

		call [TranslateMessage] 

		

		cmp dword [ebx+4], WM_HOTKEY 

		jnz .MessageLoop 

		

		mov eax, dword [ebx+8] 

		cmp eax, MY_LOUD 

		jz .go_loud 

		cmp eax, MY_MUTE 

		jz .go_mute 

		cmp eax, MY_WAIT 

		jz .go_wait 

		cmp eax, MY_EXIT 

		jz .go_exit 

		cmp eax, MY_SYNC 

		jz .go_sync 

		cmp eax, MY_PREV 

		jz .go_prev 

		

		jmp .MessageLoop 

	.go_loud: 

		call LoudVolume 

		

		push dword 0 

		push dword ApplicationName 

		push dword loud_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .MessageLoop 

	.go_mute: 

		call MuteVolume 

		

		push dword 0 

		push dword ApplicationName 

		push dword mute_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .MessageLoop 

	.go_wait: 

		push dword 0 

		push dword ApplicationName 

		push dword wait_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .MessageLoop 

	.go_exit: 

		push dword 0 

		push dword ApplicationName 

		push dword exit_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .ExitMessageLoop 

		

		jmp .MessageLoop 

	.go_sync: 

		push dword 1 

		push dword ApplicationName 

		push dword sync_msg 

		push dword 0 

		call [MessageBoxA] 

		cmp eax, IDOK 

		jnz .MessageLoop 

		

		call ReadConfig 

		

		push dword 1 

		call RegisterKeys 

		

		jmp .MessageLoop 

	.go_prev: 

		call PrevVolume 

		

		push dword 0 

		push dword ApplicationName 

		push dword prev_msg 

		push dword 0 

		call [MessageBoxA] 

		

		jmp .MessageLoop 

	.ExitMessageLoop: 

	

	;; If the parameter is 0, RegisterKeys() deregisters the hotkeys, and 

	;; does (just about) nothing else. 

	push dword 0 

	call RegisterKeys 

	

	xor eax, eax 

	leave 

ret 0 


ReadConfig: 

	enter 144, 0 

	;; hFile = [ebp-4] 

	;; ofs = [ebp-140] 

	;; brd = [ebp-144] 

	pusha 

	

	push dword dv1 

	push dword vl1 

	call strcpy 

	

	push dword dv2 

	push dword vl2 

	call strcpy 

	

	push dword dv3 

	push dword vl3 

	call strcpy 

	

	push dword dv4 

	push dword vl4 

	call strcpy 

	

	push dword dv5 

	push dword vl5 

	call strcpy 

	

	push dword dv6 

	push dword vl6 

	call strcpy 

	

	push dword dv7 

	push dword vl7 

	call strcpy 

	

	mov dword [ebp-144], 0 

	

	;; Open file. 

	lea eax, [ebp-140] 

	push dword 0 

	push dword eax 

	push dword fn_cnf 

	call [OpenFile] 

	mov dword [ebp-4], eax 

	

	;; Read file to buffer. 

	lea eax, [ebp-144] 

	push dword 0 

	push dword eax 

	push dword buff_len 

	push dword buff_txt 

	push dword [ebp-4] 

	call [ReadFile] 

	

	;; NULL-terminate data. 

	push dword [ebp-144] 

	mov ebx, buff_txt 

	pop ecx 

	mov dword [ebx+ecx], 0 

	

	;; Close file. 

	push dword [ebp-4] 

	call [CloseHandle] 

	

	

	;; Okay, now the scanning. We have to scan the text buffer, that we just read, for the configuration settings. 

	

	mov ebx, buff_txt 

	.lp1: 

		cmp byte [ebx], 0 

		jz .lp1s 

		

		;; Copy whatever we're at to our temporary string. 

		push dword ebx 

		push dword temp_str 

		call strcpy 

		

		;; Chomp the temporary string. 

		push ebx 

			mov ebx, temp_str 

			call to_nl 

			mov byte [ebx], 0 

		pop ebx 

		

		;; The temporary string most supposably contains a string of the format 'name=value' 

		;; Set the element, in our hash, with that name to that value. 

		push dword temp_str 

		push dword config 

		call SetHash 

		

		call to_nl 

		jmp .lp1 

	.lp1s: 

	

	popa 

	leave 

ret 0 


;; RegisterKeys (bool register_keys); 

RegisterKeys: 

	enter 516, 0 

	

	lea eax, [ebp-516] 

	mov dword [ebp-4], eax 

	

	mov eax, MY_LOUD 

	call .undo 

	mov eax, MY_MUTE 

	call .undo 

	mov eax, MY_WAIT 

	call .undo 

	mov eax, MY_EXIT 

	call .undo 

	; mov eax, MY_TIME 

	; call .undo 

	mov eax, MY_SYNC 

	call .undo 

	mov eax, MY_PREV 

	call .undo 

	

	;; If need not to register keys, exit. 

	mov eax, dword [ebp+8] 

	test eax, eax 

	jz .finish 

	

	mov eax, values.j_loud 

	mov ecx, MY_LOUD 

	call .act 

	

	mov eax, values.j_mute 

	mov ecx, MY_MUTE 

	call .act 

	

	mov eax, values.j_wait 

	mov ecx, MY_WAIT 

	call .act 

	

	mov eax, values.j_exit 

	mov ecx, MY_EXIT 

	call .act 

	test eax, eax 

	jnz .over1 

		

		mov eax, MY_LOUD 

		call .undo 

		mov eax, MY_MUTE 

		call .undo 

		mov eax, MY_WAIT 

		call .undo 

		

		push dword 0 

		push dword ApplicationName 

		push dword startup_err_msg 

		push dword 0 

		call [MessageBoxA] 

		

		push dword 1 

		call [ExitProcess] 

		

	.over1: 

	

	; mov eax, values.j_time 

	; mov ecx, MY_TIME 

	; call .act 

	

	mov eax, values.j_sync 

	mov ecx, MY_SYNC 

	call .act 

	

	mov eax, values.j_prev 

	mov ecx, MY_PREV 

	call .act 

	

	call .work_time 

	

	jmp .finish 

	

	.act: 

	push dword eax 

	push dword [ebp-4] 

	call strcpy 

	

	push dword [ebp-4] 

	push dword config 

	call GetHash 

	

	mov al, byte [ebp-516] 

	call ensure_cap_byte 

	push dword eax 

	push dword MOD_CONTROL | MOD_ALT 

	push dword ecx 

	push dword 0 

	call [RegisterHotKey] 

	

	ret 0 

	

	.undo: 

	push dword eax 

	push dword 0 

	call [UnregisterHotKey] 

	

	ret 0 

	

	.work_time: 

	push dword values.j_time 

	push dword [ebp-4] 

	call strcpy 

	

	push dword [ebp-4] 

	push dword config 

	call GetHash 

	

	push dword [ebp-4] 

	call str2i 

	mov dword [myTime], eax 

	

	ret 0 

	

	.finish: 

	

	leave 

ret 4 


ensure_cap_byte: 

	cmp al, 123 

	jnl .finish 

	cmp al, 97 

	jl .finish 

	sub al, 32 

	.finish: 

ret 0 


to_nl: 

	.lp1: 

		mov al, byte [ebx] 

		cmp al, 13 

		jz .lp1s 

		cmp al, 10 

		jz .lp1s 

		cmp al, 0 

		jz .lp1s 

		

		inc ebx 

		jmp .lp1 

	.lp1s: 

	.lp2: 

		mov al, byte [ebx] 

		cmp al, 13 

		jz .lp2c 

		cmp al, 10 

		jz .lp2c 

		

		jmp .lp2s 

	.lp2c: 

		inc ebx 

		jmp .lp2 

	.lp2s: 

ret 0 


eq_nl: 

	push eax 

	push ebx 

	

	mov eax, dword [esp+12] 

	mov ebx, eax 

	

	.lp1: 

		mov al, byte [ebx] 

		cmp al, 61 

		jz .lp1s 

		cmp al, 0 

		jz .lp1s 

		

		inc ebx 

		jmp .lp1 

	.lp1s: 

	mov byte [ebx], 0 

	

	pop ebx 

	pop eax 

ret 4 


InitVolumeControl: 

	enter 512, 0 

	

	call GetVolume 

	mov dword [prev_vol], eax 

	

	leave 

ret 0 


PrevVolume: 

	enter 512, 0 

	

	push dword [prev_vol] 

	call SetVolume 

	

	leave 

ret 0 


LoudVolume: 

	enter 512, 0 

	

	push dword [loud_vol] 

	call SetVolume 

	

	leave 

ret 0 


MuteVolume: 

	enter 512, 0 

	

	call GetMute 

	

	;; Perform a boolean not. 

	mov ecx, -1 

	imul ecx 

	inc eax 

	

	push dword eax 

	call SetMute 

	

	leave 

ret 0 


RetrieveMixer: 

	;; params:  HMIXER *, MIXERLINE *, COMPONENTTYPE, MIXERLINECONTROLS *, MIXERCONTROL * 

	enter 4, 0 

	

	mov eax, dword [ebp+08] 

	mov ebx, eax 

	;; EBX is the pointer to the mixer handle. 

	push dword 0 

	push dword 0 

	push dword 0 

	push dword MIXER_OBJECTF_MIXER 

	push dword ebx 

	call [mixerOpen] 

	mov dword [ebp-4], eax 

	

	mov esi, ebx              ;; HMIXER * 

	

	mov eax, dword [ebp+12] 

	mov ebx, eax 

	mov dword [ebx+00], 16 + 64 + 32 + (14 * 4) 

	mov eax, dword [ebp+16] 

	mov dword [ebx+24], eax 

	

	push dword MIXER_GETLINEINFOF_COMPONENTTYPE 

	push dword ebx 

		xchg ebx, esi     ;; HMIXER * 

	push dword [ebx] 

	call [mixerGetLineInfoA] 

	mov dword [ebp-4], eax 

	

	;; Save the pointer to the first structure. 

	mov edi, esi 

	

	;; Fill out the MIXERLINECONTROLS structure. 

	;; First clear the structure. 

	mov eax, dword [ebp+20]   ;; MIXERLINECONTROLS * 

	xor esi, esi 

	mov ebx, eax 

	.lp1: 

		cmp esi, 28 

		jnl .lp1s 

		

		mov byte [ebx+esi], 0 

		

		inc esi 

		jmp .lp1 

	.lp1s: 

	;; Now set some values. 

	mov dword [ebx+00], 28 

		xchg ebx, edi 

	mov eax, dword [ebx+12] 

		xchg ebx, edi 

	mov dword [ebx+04], eax 

		mov eax, dword [ebp+28]                ;; Control type. 

	mov dword [ebx+12], eax 

	mov dword [ebx+16], 1 

	

	mov dword [ebx+20], (13 * 4) + 16 + 64 

	mov eax, dword [ebp+24] 

	mov dword [ebx+24], eax 

	

	push dword MIXER_GETLINECONTROLSF_ONEBYTYPE 

	push dword ebx 

		mov eax, dword [ebp+08] 

		mov ebx, eax 

	push dword [ebx] 

	call [mixerGetLineControlsA] 

	mov dword [ebp-4], eax 

	

	leave 

ret 24 


SetVolume: 

	enter 4096, 0 

	

	lea ebx, [ebp-4096] 

	push dword MIXERCONTROL_CONTROLTYPE_VOLUME 

	lea eax, [ebx+000]      ;; MIXERCONTROL * 

	push dword eax 

	lea eax, [ebx+132]      ;; MIXERLINECONTROLS * 

	push dword eax 

	push dword MIXERLINE_COMPONENTTYPE_DST_SPEAKERS 

	lea eax, [ebx+160]      ;; MIXERLINE * 

	push dword eax 

	lea eax, [ebx+328]      ;; HMIXER * 

	push dword eax 

	call RetrieveMixer 

	

	mov eax, dword [ebx+04]      ;; MIXERCONTROL.dwControlID 

	

	;; At this point, 332 bytes of local memory are being used. 

	add ebx, 332 

	

	mov dword [ebx+00], 28 

	mov dword [ebx+04], eax      ;; MIXERCONTROLDETAILS.dwControlID 

	mov dword [ebx+08], 1        ;; MIXERCONTROLDETAILS.cChannels 

	mov dword [ebx+12], 0        ;; MIXERCONTROLDETAILS.hwndOwner 

	mov dword [ebx+16], 0        ;; MIXERCONTROLDETAILS.cMultipleItems 

	mov dword [ebx+20], 4        ;; MIXERCONTROLDETAILS.cbDetails 

	lea eax, [ebx+28]            ;; [EBX+360] is MIXERCONTROLDETAILS_UNSIGNED where EBX = EBP - 4096 

	mov dword [ebx+24], eax      ;; MIXERCONTROLDETAILS.paDetails 

	

	mov eax, dword [ebp+8]       ;; The new volume. 

	mov dword [ebx+28], eax 

	

	push dword MIXER_SETCONTROLDETAILSF_VALUE 

	push dword ebx 

		mov eax, [ebp-4096+328] 

	push dword eax 

	call [mixerSetControlDetails] 

	

	push dword [ebp-4096+328] 

	call [mixerClose] 

	

	leave 

ret 4 


GetVolume: 

	enter 4096, 0 

	

	lea ebx, [ebp-4096] 

	push dword MIXERCONTROL_CONTROLTYPE_VOLUME 

	lea eax, [ebx+000]      ;; MIXERCONTROL * 

	push dword eax 

	lea eax, [ebx+132]      ;; MIXERLINECONTROLS * 

	push dword eax 

	push dword MIXERLINE_COMPONENTTYPE_DST_SPEAKERS 

	lea eax, [ebx+160]      ;; MIXERLINE * 

	push dword eax 

	lea eax, [ebx+328]      ;; HMIXER * 

	push dword eax 

	call RetrieveMixer 

	

	mov eax, dword [ebx+04]      ;; MIXERCONTROL.dwControlID 

	

	;; At this point, 332 bytes of local memory are being used. 

	add ebx, 332 

	

	mov dword [ebx+00], 28 

	mov dword [ebx+04], eax      ;; MIXERCONTROLDETAILS.dwControlID 

	mov dword [ebx+08], 1        ;; MIXERCONTROLDETAILS.cChannels 

	mov dword [ebx+12], 0        ;; MIXERCONTROLDETAILS.hwndOwner 

	mov dword [ebx+16], 0        ;; MIXERCONTROLDETAILS.cMultipleItems 

	mov dword [ebx+20], 4        ;; MIXERCONTROLDETAILS.cbDetails 

	lea eax, [ebx+28]            ;; [EBX+360] is MIXERCONTROLDETAILS_UNSIGNED where EBX = EBP - 4096 

	mov dword [ebx+24], eax      ;; MIXERCONTROLDETAILS.paDetails 

	

	;;mov eax, dword [ebp+8]       ;; The new volume. 

	mov dword [ebx+28], 0 

	

	push dword MIXER_GETCONTROLDETAILSF_VALUE 

	push dword ebx 

		mov eax, [ebp-4096+328] 

	push dword eax 

	call [mixerGetControlDetailsA] 

	

	push dword [ebp-4096+328] 

	call [mixerClose] 

	

	leave 

ret 0 


SetMute: 

	enter 4096, 0 

	

	lea ebx, [ebp-4096] 

	push dword MIXERCONTROL_CONTROLTYPE_MUTE 

	lea eax, [ebx+000]      ;; MIXERCONTROL * 

	push dword eax 

	lea eax, [ebx+132]      ;; MIXERLINECONTROLS * 

	push dword eax 

	push dword MIXERLINE_COMPONENTTYPE_DST_SPEAKERS 

	lea eax, [ebx+160]      ;; MIXERLINE * 

	push dword eax 

	lea eax, [ebx+328]      ;; HMIXER * 

	push dword eax 

	call RetrieveMixer 

	

	mov eax, dword [ebx+04]      ;; MIXERCONTROL.dwControlID 

	

	;; At this point, 332 bytes of local memory are being used. 

	add ebx, 332 

	

	mov dword [ebx+00], 28 

	mov dword [ebx+04], eax      ;; MIXERCONTROLDETAILS.dwControlID 

	mov dword [ebx+08], 1        ;; MIXERCONTROLDETAILS.cChannels 

	mov dword [ebx+12], 0        ;; MIXERCONTROLDETAILS.hwndOwner 

	mov dword [ebx+16], 0        ;; MIXERCONTROLDETAILS.cMultipleItems 

	mov dword [ebx+20], 4        ;; MIXERCONTROLDETAILS.cbDetails 

	lea eax, [ebx+28]            ;; [EBX+360] is MIXERCONTROLDETAILS_UNSIGNED where EBX = EBP - 4096 

	mov dword [ebx+24], eax      ;; MIXERCONTROLDETAILS.paDetails 

	

	mov eax, dword [ebp+8]       ;; The new volume. 

	mov dword [ebx+28], eax 

	

	push dword MIXER_SETCONTROLDETAILSF_VALUE 

	push dword ebx 

		mov eax, [ebp-4096+328] 

	push dword eax 

	call [mixerSetControlDetails] 

	

	push dword [ebp-4096+328] 

	call [mixerClose] 

	

	leave 

ret 4 


GetMute: 

	enter 4096, 0 

	

	lea ebx, [ebp-4096] 

	push dword MIXERCONTROL_CONTROLTYPE_MUTE 

	lea eax, [ebx+000]      ;; MIXERCONTROL * 

	push dword eax 

	lea eax, [ebx+132]      ;; MIXERLINECONTROLS * 

	push dword eax 

	push dword MIXERLINE_COMPONENTTYPE_DST_SPEAKERS 

	lea eax, [ebx+160]      ;; MIXERLINE * 

	push dword eax 

	lea eax, [ebx+328]      ;; HMIXER * 

	push dword eax 

	call RetrieveMixer 

	

	mov eax, dword [ebx+04]      ;; MIXERCONTROL.dwControlID 

	

	;; At this point, 332 bytes of local memory are being used. 

	add ebx, 332 

	

	mov dword [ebx+00], 28 

	mov dword [ebx+04], eax      ;; MIXERCONTROLDETAILS.dwControlID 

	mov dword [ebx+08], 1        ;; MIXERCONTROLDETAILS.cChannels 

	mov dword [ebx+12], 0        ;; MIXERCONTROLDETAILS.hwndOwner 

	mov dword [ebx+16], 0        ;; MIXERCONTROLDETAILS.cMultipleItems 

	mov dword [ebx+20], 4        ;; MIXERCONTROLDETAILS.cbDetails 

	lea eax, [ebx+28]            ;; [EBX+360] is MIXERCONTROLDETAILS_UNSIGNED where EBX = EBP - 4096 

	mov dword [ebx+24], eax      ;; MIXERCONTROLDETAILS.paDetails 

	

	;;mov eax, dword [ebp+8]       ;; The new volume. 

	mov dword [ebx+28], 0 

	

	push dword MIXER_GETCONTROLDETAILSF_VALUE 

	push dword ebx 

		mov eax, [ebp-4096+328] 

	push dword eax 

	call [mixerGetControlDetailsA] 

	

	push dword [ebp-4096+328] 

	call [mixerClose] 

	

	leave 

ret 0 


%include "inc/str.asm" 

%include "inc/istr.asm" 

%include "inc/hash.asm" 


section .data 

myTime                                 dd 30     ;; 30 seconds is the default wait time. 


fn_int                                 db "interval.txt", 0 

fn_cnf                                 db "muteconf.txt", 0 


ApplicationName                        db "SoundCat", 0 


loud_msg                               db "Loud hotkey used. ", 0 

mute_msg                               db "Mute hotkey used. ", 0 

wait_msg                               db "Wait hotkey used. ", 0 

exit_msg                               db "Press OK to exit. ", 0 

sync_msg                               db "Press OK to sync SoundCat configurations. ", 0 

prev_msg                               db "Prev hotkey used. ", 0 


startup_err_msg                        db "Error:  Could not register the exit hotkey. ", 0 


nm1                                    db "loud", 0, 0, 0, 0 

nm2                                    db "mute", 0, 0, 0, 0 

nm3                                    db "wait", 0, 0, 0, 0 

nm4                                    db "exit", 0, 0, 0, 0 

nm5                                    db "time", 0, 0, 0, 0 

nm6                                    db "sync", 0, 0, 0, 0 

nm7                                    db "prev", 0, 0, 0, 0 


dv1                                    db "L", 0 

dv2                                    db "M", 0 

dv3                                    db "W", 0 

dv4                                    db "Q", 0 

dv5                                    db "30", 0 

dv6                                    db "S", 0 

dv7                                    db "P", 0 


config: 

dd nm1 

dd vl1 

dd nm2 

dd vl2 

dd nm3 

dd vl3 

dd nm4 

dd vl4 

dd nm5 

dd vl5 

dd nm6 

dd vl6 

dd nm7 

dd vl7 

dd 0 

dd 0 


values: 

.j_loud: 

db "loud", 0 

.j_mute: 

db "mute", 0 

.j_wait: 

db "wait", 0 

.j_exit: 

db "exit", 0 

.j_time: 

db "time", 0 

.j_sync: 

db "sync", 0 

.j_prev: 

db "prev", 0 


section .bss 

prev_vol                               dd 0 

loud_vol                               dd 0x7FFF7FFF 


buff_txt                               resb 4096 

buff_len                               equ  $ - buff_txt 


temp_str                               resb 4096 


vl1                                    resb 512 

vl2                                    resb 512 

vl3                                    resb 512 

vl4                                    resb 512 

vl5                                    resb 512 

vl6                                    resb 512 

vl7                                    resb 512 



In case anyone wants to assemble that code, I posted the include files on my website at inc - Site5

However, it still doesn't work. I haven't tried it on Windows XP, but on my Windows 7 it doesn't do anything. The correct message boxes appear, and everything, but the volume remains constant the whole time.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users