PlaySound only working in DllMain

Pages: 12
Hello,

im just working on my first dll and have problems with PlaySound.
For some reason, it only works in the DllMain.
Im playing the sounds from the resources like this(hDLLInst declared as global var):

PlaySound(MAKEINTRESOURCE(IDR_WAVE1), hDLLInst, SND_RESOURCE);

The code for the DllMain is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
BOOL WINAPI DllMain(HINSTANCE hinstModule, DWORD dwReason, LPVOID lpvReserved)
{
  if(dwReason == DLL_PROCESS_ATTACH)
  {
	AllocConsole();
	system("Color 0A");
	AttachConsole(GetCurrentProcessId());
	freopen("CONOUT$", "w", stdout);
	SetConsoleTitle("My first dll");
	hDLLInst = hinstModule; 
	printf("Creating thread...\n");
	CreateThread(0, 0, MainThread, 0, 0, 0); 
        printf("Thread created!\n");
        PlaySound(MAKEINTRESOURCE(IDR_WAVE1), hDLLInst, SND_RESOURCE);
	printf("Successfully loaded!\n");
    return TRUE;
  }

  return FALSE;
}


The PlaySound here works flawless after the dll injection but for all other PlaySounds in the thread MainThread theres no sound getting played.

The MainThread:
1
2
3
4
5
6
7
8
9
10
11
12
13
DWORD WINAPI MainThread(LPVOID)
{
	Sleep(2000);

	while (1)
	{
	      if (GetAsyncKeyState (VK_UP) &1) 
              {
              PlaySound(MAKEINTRESOURCE(IDR_WAVE2), hDLLInst, SND_RESOURCE);
	      }
	      Sleep(1);
	}
}


This PlaySound does not work as it should.
Can someone help me with this?
Last edited on
GetAsyncKeyState returns key status in bit 15, not bit 0:

1
2
3
if (GetAsyncKeyState (VK_UP) &1)   // <- wrong

if( GetAsyncKeyState (VK_UP) & 0x8000)   // <- right 


EDIT:

Actually... I just checked the docs and it looks like bit 0 returns "just pressed" status... but is unreliable.

From msdn:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646293%28v=vs.85%29.aspx

msdn wrote:

If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior; for more information, see the Remarks.

...

Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon.
Last edited on
You must be completely wrong, i didn't post my whole code and i also have 4 other functions i use hotkeys for, they all work as they should. There is also other code inside these ifs and it all works fine only the PlaySound does nothing.
Please only look for the reason why PlaySound is not working, everything else in the code does what it should and is tested.
Last edited on
You must be completely wrong,


Pfft. Well screw you too then. =P

FYI, what I posted might explain why PlaySound wasn't working. Maybe instead of being so dismissive of someone who actually knows a bit about what he's talking about you should actually try it out first.

Being an asshole doesn't help your case either.
Last edited on
Why being an asshole? I just said that GetAsyncKeyState works as it should and the problem is PlaySound itself. I never tried to be an asshole i just said where the problem is. If you interpret this wrong then im sorry.
Why being an asshole?


Maybe I over stated it when I called you an asshole. I'm sorry for that.

But I still don't appreciate my responses being callously dismissed.

I'm probably overreacting. Maybe someone else can help you, but I'm all butthurt now and don't want to spend any more of my time on this.
Last edited on
Nobody with ideas anymore? :(
Sorry for getting all butthurt, ccman. I don't know what came over me. For some reason I was in some weird funky mood and your post just rubbed me the wrong way. My reaction was unjustified.

As for your problem... The only thing I can see that might be an issue is that you're running from a separate thread (I would ask why you're doing that.. but you made it clear you're uninteresting in advice). Although I did a small test locally and PlaySound works just fine for me when run from multiple threads. I also didn't see anything on the doc page to suggest you couldn't call it from multiple threads.


So that leaves the more obvious culprit of it not finding or failing to load the file. Have you ruled that out?

If so... the next thing I would recommend is check the return value of PlaySound. If there was a problem it will return FALSE... and if it does you can check GetLastError to see what the problem was.
Ok im first gonna put it in a new void and test what happens when i call the void instead. If that doesn't work i will check for errors after calling PlaySound.
Ok, GetLastError gives me code 1812 = ERROR_RESOURCE_DATA_NOT_FOUND

I can play all sounds i have in the resources from within the DLLMain or a void getting called from withing the DLLMain but somehow i cannot use them in other threads. What am i supposed to do now?
Double check your hDLLInst variable and make sure it's the same for both working and non-working calls.
It IS the same but still not working.
http://i.imgur.com/dvpQv34.png
Last edited on
Okay I did some testing and it's starting to make sense.


Looks like PlaySound can only play 1 sound at a time. If you call PlaySound when a sound is already playing, the playing sound will stop.

In my tests, I had two threads repeatedly calling PlaySound in a loop, and I never heard 2 sounds played simultaneously. Furthermore, when I added the SND_ASYNC option PlaySound calls started failing (I didn't check the error code).


Looks like PlaySound is simply not meant to be used this way.
How can i use it then? Other people have no problems with using it.
PlaySound is meant for quick/easy audio blurbs. It's not meant to be used for high performance situations. "Other people" that are not having problems are probably not using PlaySound or are putting a much lighter load on it.

Considering what you seem to be doing, you probably need to use a more serious sound lib.


So the question now is... what are you doing? Why does it require PlaySound and multiple threads?
Im creating a little dll hack for a game called AVA. Im using multiple threads, one for each function of it but the PlaySound gets called only in the thread i use to detect if one of the hotkeys for enabling/disabling a function got pressed. The sounds are "Enabled"/"Disabled" sounds i wanna play when one of the hotkeys gets pressed to know the function got enabled/disabled.
There were already some dlls existing for this game in the past by other coders and they all had a feature like this with custom sounds added. I already talked with one of the older coders and he told me that he uses PlaySound for his sounds. So my question is still, why can he use it and i can't? Are there any better ways to handle the functions than using a own thread for each function which would also give me the possibility to use PlaySound? My problem is that i cannot use only one thread for them because they all have to run in different time intervals to work.
Last edited on
So my question is still, why can he use it and i can't?


Without seeing both of your code I really couldn't say. My best guess is that he's putting a lighter load on PlaySound (ie: not triggering multiple simultaneous sound effects from multiple threads). But again that's a total guess.

My problem is that i cannot use only one thread for them because they all have to run in different time intervals to work.


You can do any amount of work from 1 thread. You do not need a thread for each function... in fact using multiple threads that way is kind of crazy.

If your DLL gets constant CPU attention from the main process (in the form of an "update" function or something similar) then you don't need to [and shouldn't] create any threads. Especially not for something this simple.

All you have to do to drive things is keep a timer and update them as time passes. It doesn't matter if the things need to be updated at different intervals... all that means is that you just need to keep multiple timers.

Simplistic example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
void func1()
{
  // to be called every 1000 ms
}

void func2()
{
  // to be called every 500 ms
}

// timers
unsigned timer1;
unsigned timer2;

// on initialzation
void init()
{
  unsigned now = GetTickCount();  // or whatever other timing mechanism you want
  timer1 = now + 1000;
  timer2 = now + 500;
}

// This is your "update" function which is called repeatedly by the main program
void main_logic()
{
  unsigned now = GetTickCount();

  int dif = static_cast<int>( timer1 - now );
  if(dif <= 0)
  {
    timer1 += 1000;  // it's been 1000 ms since the last call.  Call it again
    func1();
  }

  dif = static_cast<int>( timer2 - now );
  if(dif <= 0)
  {
    timer2 += 500;  // it's been 500 ms since the last call.  Call it again
    func2();
  }
}


If there is no "update" function you'll have to create a single thread which basically does that.

Also in this case you would not want PlaySound to be blocking, so you'd want to give it the SND_ASYNC option.
Thanks very much, im gonna try this instead now. Some minutes ago i asked this question also in a game hacking specific forum now with a little bit more source code. Look here->http://www.mpgh.net/forum/31-c-c-programming/647451-playsound-not-finding-sound-resource.html#post7939573
The source code there shows the way i use to organize my functions a bit better than the piece of code here. I always used timers back when i coded with VB.NET xD
Last edited on
So, since VS 2012 has way too many bugs like IntelliSense giving like 150 Errors while the source code is flawless and working after compiling and many other bugs which makes it almost impossible for me to continue working with that piece of shit IDE (Random errors while i just recompiled the SAME(!) project without any changes or just a added printf resulting in ~50 other errors) i decided to uninstall it and switch to the older VS 2010. Now it's installed, started and already giving me around 30 errors from missing header files. I navigate to the folder with the headers and what do i see? Nothing, it's empty, header files not in the installation, THANK YOU VERY MUCH MICROSOFT FOR STEALING MY TIME.
Last edited on
From my experience VS2012 doesn't play nice if VS2010 is installed. VS2012 will use 2010's project settings, in particular the PATH, which wont work. I had to completely uninstall 2010 and reinstall 2012, a total PITA but worth it in the end 2012 is pretty sweet.
Pages: 12