Getting calling module when hooking WINMM.waveOutOpen

c++ / delphi package - dll injection and api hooking
Post Reply
spoox
Posts: 2
Joined: Thu Dec 30, 2004 5:32 am

Getting calling module when hooking WINMM.waveOutOpen

Post by spoox »

I'm having some problems getting the correct calling module when hooking WINMM.waveOutOpen() .. Even though I've checked that the .dll and .ocx'es I'm trying to modify the behaviour of uses this API, I still end up getting 'c:\winnt\system32\msacm32.drv' as the active module instead of the actual calling .dll/.ocx'es..

My .dll code is as follows:

Code: Select all

library dllhook;

uses
  Windows, madRemote, madCodeHook, mmsystem, madStrings, sysutils;

var
  waveOutOpenNext : function (lphWaveOut: PHWaveOut; uDeviceID: UINT; lpFormat: PWaveFormatEx; dwCallback, dwInstance, dwFlags: DWORD): MMRESULT; stdcall;

{
  winmm.dll:

  MMRESULT waveOutOpen(
    LPHWAVEOUT     phwo,
    UINT_PTR       uDeviceID,
    LPWAVEFORMATEX pwfx,
    DWORD_PTR      dwCallback,
    DWORD_PTR      dwCallbackInstance,
    DWORD          fdwOpen
  );

}

function waveOutOpenCallback(lphWaveOut: PHWaveOut; uDeviceID: UINT; lpFormat: PWaveFormatEx; dwCallback, dwInstance, dwFlags: DWORD): MMRESULT; stdcall;
var
  pid: dword;
  module: cardinal;
  arrCh: array[0..MAX_PATH] of Char;
  h: HWnd;
begin
  { basically what is to be done here is the following:

      if whoever called waveOutOpen(..) is 'npswf32.dll' or 'flash.ocx' then
      return some fake error state to prevent sound

      if something else, pass on the request
  }

  { get calling process }
  { PROBLEM: this can't be used, will be i.e. 'firefox.exe' or
     'SAFlashPlayer.e' or 'iexplore.exe' }
  pid := ProcessHandleToId(GetCurrentProcess());

  { get calling module }
  { PROBLEM: this will be 'winnt\system32\msacm32.drv' }
  module := GetCallingModule();

  { just some quick hack to see calling process and module }
  h := FindWindow(nil, 'Untitled - Notepad');
  if h<>0 then
  begin
    ProcessIdToFileName(pid, arrCh);
    SetWindowText(h, PChar('pid='+IntToStr(pid)+': '+StrPas(arrCh)+', mod='+IntToStr(module)+': '+GetModuleName(module)));
  end;

  { if flash .dll/.ocx then }
  result := MMSYSERR_NODRIVER;
  { else }
//  result := waveOutOpenNext(lphWaveOut, uDeviceID, lpFormat, dwCallback, dwInstance, dwFlags);
end;

begin
  HookAPI('winmm.dll', 'waveOutOpen', @waveOutOpenCallback, @waveOutOpenNext);
end.

What I'm really trying to do is just make it impossible for Flash plugins to play any sounds. Flash is implemented as an ActiveX control as 'flash.ocx' and as a Netscape-compatible plugin as 'npswf32.dll'...

Killing sound works quite well, but I am only interested in doing it if those 2 files are calling the WINMM.waveOutOpen() API... But, as illustrated, the calling module is reported to be msacm32.drv, which is the Windows Sound Mapper...

Any clues what I should do here? Neither of the .dll/.ocx'es import msacm32.drv so there's problaby some voodoo being done by Windows..

(Yes, this functionality has been done a few times before, but all of the implementations I've seen are just hacks of the .dll's, something which is a PITA each time a new version of Flash is released since the .dll's need patching again then)
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

I'd suggest writing a little demo program which itself calls waveOutOpen. Does GetCallingModule work correctly then? The first question we have to solve is to find out whether GetCallingModule works alright or not.
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

P.S: I'm seeing this line quite often:

pid := ProcessHandleToId(GetCurrentProcess());

Please don't use it. It works, but it's a really bad way to get the process ID of the current process. Instead please simple use:

pid := GetCurrentProcessId();

Much faster, simpler and cleaner.
Post Reply