waveInOpen の dwCallback に CALLBACK_FUNCTION を指定した時に waveInProc コールバック内で waveInAddBuffer をコールすると、スレッドがフリーズして処理が返ってこなくなる問題に少しはまりました。
コールバックの外から呼ぶとフリーズしないので、メインスレッドの処理では何もしないようにしても直らない...と思ったら、MSDN の waveInProc のページにコールバックでシステム定義関数呼ぶなと書いてありました。
EnterCriticalSection、LeaveCriticalSection、midiOutLongMsg、midiOutShortMsg、OutputDebugString、PostMessage、PostThreadMessage、SetEvent、timeGetSystemTime、timeGetTime、timeKillEvent および timeSetEvent を除き、アプリケーションでコールバック関数内からシステム定義関数を呼び出さないようにしてください。ほかのウェーブ関数を呼び出すと、デッドロックの原因となります。
悩む前にドキュメントちゃんと読めってやつですね...