This is my very simple version of audio installable driver (mydrv.drv): #include <windows.h> #include <mmsystem.h> #define _MY_EXPORT __declspec(dllexport)__stdcall extern "C" LRESULT _MY_EXPORT DriverProc(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, LONG lParam1, LONG lParam2) { DWORD dwRes = 0L; OutputDebugString(L"ZV_DRV.DRV: input\n"); switch (msg) { case DRV_LOAD: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_LOAD\n"); dwRes = 1L; // returns 0L to fail break; case DRV_FREE: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_FREE\n"); dwRes = 1L; // return value ignored break; case DRV_OPEN: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_OPEN\n"); dwRes = 1L; // returns 0L to fail break; // value subsequently used // for dwDriverId. case DRV_CLOSE: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_CLOSE\n"); dwRes = 1L; // returns 0L to fail break; case DRV_ENABLE: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_ENABLE\n"); dwRes = 1L; // return value ignored break; case DRV_DISABLE: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_DISABLE\n"); dwRes = 1L; // return value ignored break; case DRV_INSTALL: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_INSTALL\n"); dwRes = DRVCNF_OK; // Can also return break; // DRVCNF_CANCEL and DRV_RESTART case DRV_REMOVE: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_REMOVE\n"); dwRes = 1L; // return value ignored break; case DRV_QUERYCONFIGURE: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_QUERYCONFIGURE\n"); dwRes = 0L; // Zero indicates configuration break; // NOT supported case DRV_CONFIGURE: OutputDebugString(L"ZV_DRV.DRV: msg = DRV_CONFIGURE\n"); dwRes = DRVCNF_OK; // Can also return break; // DRVCNF_CANCEL and DRVCNF_RESTART default: OutputDebugString(L"ZV_DRV.DRV: msg = ? (default)\n"); dwRes = DefDriverProc((DWORD_PTR)&dwDriverId, hdrvr, msg, lParam1, lParam2); } return dwRes; } extern "C" DWORD _MY_EXPORT wodMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2) { OutputDebugString(L"ZV_DRV.DRV: [wodMessage]\n"); return MMSYSERR_NOTSUPPORTED; } extern "C" DWORD _MY_EXPORT widMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2) { OutputDebugString(L"ZV_DRV.DRV: [widMessage]\n"); return MMSYSERR_NOTSUPPORTED; } extern "C" DWORD _MY_EXPORT mxdMessage(UINT uDeviceID, UINT uMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2) { OutputDebugString(L"ZV_DRV.DRV: [mxdMessage]\n"); return MMSYSERR_NOTSUPPORTED; } BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID lpReserved) { // Perform actions based on the reason for calling. OutputDebugString(L"ZV_DRV.DRV - DllMain\n"); switch ( fdwReason ) { case DLL_PROCESS_ATTACH : OutputDebugString(L"ZV_DRV.DRV - Process attached\n"); break; case DLL_PROCESS_DETACH : OutputDebugString(L"ZV_DRV.DRV - Process detached\n"); break; case DLL_THREAD_ATTACH : OutputDebugString(L"ZV_DRV.DRV - Thread attached\n"); break; case DLL_THREAD_DETACH : OutputDebugString(L"ZV_DRV.DRV - Thread detached\n"); break; } return TRUE; } I use MS Visual Studio 2005 Pro and Platform SDK (3790.1830)! This is usual DLL project. I set "Calling Convention" to "__cdecl" in "C/C++" property of this project and "Entry Point" to "DllMain" in "Linker" property (section "Advanced" in both properties). There can be I have written something incorrectly? -- Igor Galchuk <ingvio@xxxxxxxxxxx> ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/