|
|
/*==========================================================================
* * Copyright (C) 1994-1997 Microsoft Corporation. All Rights Reserved. * * File: w95hack.c * Content: Win95 hack-o-rama code * This is a HACK to handle the fact that Win95 doesn't notify * a DLL when a process is destroyed. * History: * Date By Reason * ==== == ====== * 28-mar-95 craige initial implementation * 01-apr-95 craige happy fun joy updated header file * 06-apr-95 craige reworked for new ddhelp * 09-may-95 craige loading any DLL * 16-sep-95 craige bug 1117: must UnmapViewOfFile before closing handle * 29-nov-95 angusm added HelperCreateDSFocusThread * 18-jul-96 andyco added Helper(Add/)DeleteDPlayServer * 12-oct-96 colinmc added new service to get DDHELP to get its own handle * for communicating with the DirectSound VXD * 22-jan-97 kipo return an HRESULT from HelperAddDPlayServer() * 29-jan-97 colinmc vxd handling stuff is no longer win16 lock specific * ***************************************************************************/ #undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#include <mmreg.h>
#include "w95help.h"
#include "dpf.h"
#undef E_FAIL
#define E_FAIL 0x80004005L
//extern DWORD * pdwHelperPid;
//extern HANDLE * phModule; // must be defined
extern DWORD dwHelperPid; extern HINSTANCE hModule; // must be defined
/*
* sendRequest * * communicate a request to DDHELP */ static BOOL sendRequest( LPDDHELPDATA req_phd ) { LPDDHELPDATA phd; HANDLE hmem; HANDLE hmutex; HANDLE hackevent; HANDLE hstartevent; BOOL rc;
/*
* get events start/ack events */ hstartevent = CreateEvent( NULL, FALSE, FALSE, DDHELP_EVENT_NAME ); if( hstartevent == NULL ) { return FALSE; } hackevent = CreateEvent( NULL, FALSE, FALSE, DDHELP_ACK_EVENT_NAME ); if( hackevent == NULL ) { CloseHandle( hstartevent ); return FALSE; }
/*
* create shared memory area */ hmem = CreateFileMapping( (HANDLE) 0xffffffff, NULL, PAGE_READWRITE, 0, sizeof( DDHELPDATA ), DDHELP_SHARED_NAME ); if( hmem == NULL ) { DPF( 1, "Could not create file mapping!" ); CloseHandle( hstartevent ); CloseHandle( hackevent ); return FALSE; } phd = (LPDDHELPDATA) MapViewOfFile( hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0 ); if( phd == NULL ) { DPF( 1, "Could not create view of file!" ); CloseHandle( hmem ); CloseHandle( hstartevent ); CloseHandle( hackevent ); return FALSE; }
/*
* wait for access to the shared memory */ hmutex = OpenMutex( SYNCHRONIZE, FALSE, DDHELP_MUTEX_NAME ); if( hmutex == NULL ) { DPF( 1, "Could not create mutex!" ); UnmapViewOfFile( phd ); CloseHandle( hmem ); CloseHandle( hstartevent ); CloseHandle( hackevent ); return FALSE; } WaitForSingleObject( hmutex, INFINITE );
/*
* wake up DDHELP with our request */ memcpy( phd, req_phd, sizeof( DDHELPDATA ) ); phd->req_id = hModule; if( SetEvent( hstartevent ) ) { WaitForSingleObject( hackevent, INFINITE ); memcpy( req_phd, phd, sizeof( DDHELPDATA ) ); rc = TRUE; } else { DPF( 1, "Could not signal event to notify DDHELP" ); rc = FALSE; }
/*
* done with things */ ReleaseMutex( hmutex ); CloseHandle( hmutex ); CloseHandle( hstartevent ); CloseHandle( hackevent ); UnmapViewOfFile( phd ); CloseHandle( hmem ); return rc;
} /* sendRequest */
/*
* DoneWithHelperProcess */ void DoneWithHelperProcess( void ) { DDHELPDATA hd;
if( dwHelperPid == 0 ) { return; }
hd.req = DDHELPREQ_FREEDCLIST; sendRequest( &hd );
} /* DoneWithHelperProcess */
/*
* WaitForHelperStartup */ BOOL WaitForHelperStartup( void ) { HANDLE hevent; DWORD rc;
hevent = CreateEvent( NULL, TRUE, FALSE, DDHELP_STARTUP_EVENT_NAME ); if( hevent == NULL ) { return FALSE; } DPF( 3, "Wait DDHELP startup event to be triggered" ); rc = WaitForSingleObject( hevent, 100000 ); // fail if this doesn't work within 100 seconds
CloseHandle( hevent ); if( rc == WAIT_TIMEOUT ) { return FALSE; } return TRUE;
} /* WaitForHelperStartup */
/*
* HelperLoadDLL * * get the helper to load a DLL for us. */ DWORD HelperLoadDLL( LPSTR dllname, LPSTR fnname, DWORD context ) { DDHELPDATA hd; DWORD rc = 0;
if( dllname != NULL ) { hd.req = DDHELPREQ_LOADDLL; lstrcpy( hd.fname, dllname ); if( fnname != NULL ) { strcpy( hd.func, fnname ); hd.context = context; DPF( 3, "Context=%08lx", context ); } else { hd.func[0] = 0; } DPF( 3, "Asking DDHELP to load DLL %s", dllname ); sendRequest( &hd ); rc = (DWORD)hd.dwReturn; }
return rc;
} /* HelperLoadDLL */
/*
* HelperCreateThread */ void HelperCreateThread( void ) { DDHELPDATA hd;
hd.req = DDHELPREQ_CREATEHELPERTHREAD; sendRequest( &hd );
} /* HelperCreateThread */
/*
* SignalNewProcess * * Signal DDHELP that a new process has arrived. This is called with the * DLL lock taken, so global vars are safe */ void SignalNewProcess( DWORD pid, LPHELPNOTIFYPROC proc ) { DDHELPDATA hd;
if( pid == dwHelperPid ) { DPF( 3, "Helper connected to DLL - no signal required" ); return; }
DPF( 3, "Signalling DDHELP that a new process has connected" ); hd.req = DDHELPREQ_NEWPID; hd.pid = pid; hd.lpNotify = proc; sendRequest( &hd );
} /* SignalNewProcess */
/*
* StopWatchProcess * * Signal DDHELP to stop watching a process. This is called with the * DLL lock taken, so global vars are safe */ void StopWatchProcess( DWORD pid, LPHELPNOTIFYPROC proc ) { DDHELPDATA hd;
if( pid == dwHelperPid ) { DPF( 3, "Helper connected to DLL - no signal required" ); return; }
DPF( 3, "Signalling DDHELP to stop watching a process" ); hd.req = DDHELPREQ_STOPWATCHPID; hd.pid = pid; hd.lpNotify = proc; sendRequest( &hd );
} /* SignalNewProcess */
/*
* SignalNewDriver * * Signal DDHELP that a new driver has been loaded. This is called with the * DLL lock taken, so global vars are safe */ void SignalNewDriver( LPSTR fname, BOOL isdisp ) { DDHELPDATA hd;
DPF( 3, "Signalling DDHELP to create a new DC" ); hd.req = DDHELPREQ_NEWDC; hd.isdisp = isdisp; lstrcpy( hd.fname, fname ); sendRequest( &hd );
} /* SignalNewDriver */
/*
* CreateHelperProcess */ BOOL CreateHelperProcess( LPDWORD ppid ) { if( dwHelperPid == 0 ) { STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE h;
h = OpenEvent( SYNCHRONIZE, FALSE, DDHELP_STARTUP_EVENT_NAME ); if( h == NULL ) { si.cb = sizeof(STARTUPINFO); si.lpReserved = NULL; si.lpDesktop = NULL; si.lpTitle = NULL; si.dwFlags = 0; si.cbReserved2 = 0; si.lpReserved2 = NULL;
DPF( 3, "Creating helper process now" ); if( !CreateProcess(NULL, "ddhelp.exe", NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi) ) { DPF( 2, "Could not create DDHELP.EXE" ); return FALSE; } dwHelperPid = pi.dwProcessId; DPF( 3, "Helper rocess created" ); } else { DDHELPDATA hd; DPF( 3, "DDHELP already exists, waiting for DDHELP event" ); WaitForSingleObject( h, INFINITE ); CloseHandle( h ); DPF( 3, "Asking for DDHELP pid" ); hd.req = DDHELPREQ_RETURNHELPERPID; sendRequest( &hd ); dwHelperPid = hd.pid; DPF( 3, "DDHELP pid = %08lx", dwHelperPid ); } *ppid = dwHelperPid; return TRUE; } *ppid = dwHelperPid; return FALSE;
} /* CreateHelperProcess */
#ifdef WIN95 //this is Just For Now... dsound will get the help it needs..jeffno 951206
/*
* HelperWaveOpen * * get the helper to load a DLL for us. */ DWORD HelperWaveOpen( LPVOID lphwo, DWORD dwDeviceID, LPVOID pwfx ) { DDHELPDATA hd;
if( (lphwo != NULL) && (pwfx != NULL) ) { hd.req = DDHELPREQ_WAVEOPEN; hd.pData1 = lphwo; hd.dwData1 = dwDeviceID; hd.dwData2 = (DWORD)pwfx; DPF( 3, "Asking DDHELP to Open Wave Device %d", dwDeviceID ); sendRequest( &hd ); return hd.dwReturn; } else { DPF( 3, "Helper Wave Open param error"); return MMSYSERR_ERROR; }
} /* HelperWaveOpen */
/*
* HelperWaveClose * * get the helper to load a DLL for us. */ DWORD HelperWaveClose( DWORD hwo ) { DDHELPDATA hd;
if( (hwo != 0) ) { hd.req = DDHELPREQ_WAVECLOSE; hd.dwData1 = hwo; DPF( 3, "Asking DDHELP to Close Wave Device "); sendRequest( &hd ); return hd.dwReturn; } else { DPF( 3, "Helper Wave Close param error"); return MMSYSERR_ERROR; }
} /* HelperWaveClose */
/*
* HelperCreateTimer * * get the helper to load a DLL for us. */ DWORD HelperCreateTimer( DWORD dwResolution, LPVOID pTimerProc, DWORD dwInstanceData ) { DDHELPDATA hd;
if( (dwResolution != 0) && (pTimerProc != NULL) ) { hd.req = DDHELPREQ_CREATETIMER; hd.pData1 = pTimerProc; hd.dwData1 = dwResolution; hd.dwData2 = dwInstanceData; DPF( 3, "Asking DDHELP to Create Timer" ); sendRequest( &hd ); return hd.dwReturn; } else { DPF( 3, "Helper Wave Close param error"); return MMSYSERR_ERROR; }
} /* HelperCreateTimer */
/*
* HelperKillTimer * * get the helper to load a DLL for us. */ DWORD HelperKillTimer( DWORD dwTimerID ) { DDHELPDATA hd;
if( (dwTimerID != 0) ) { hd.req = DDHELPREQ_KILLTIMER; hd.dwData1 = dwTimerID; DPF( 3, "Asking DDHELP to KILL Timer %X", dwTimerID ); sendRequest( &hd ); return hd.dwReturn; } else { DPF( 3, "Helper Wave Close param error"); return MMSYSERR_ERROR; }
} /* HelperKillTimer */
/*
* HelperCreateDSMixerThread * * get the helper to create a mixer thread. */ HANDLE HelperCreateDSMixerThread( LPTHREAD_START_ROUTINE pfnThreadFunc, LPDWORD pdwThreadParam, DWORD dwFlags, LPDWORD pThreadId ) { DDHELPDATA hd;
hd.req = DDHELPREQ_CREATEDSMIXERTHREAD; hd.pData1 = pfnThreadFunc; hd.dwData1 = (DWORD)pdwThreadParam; hd.dwData2 = dwFlags; hd.pData2 = pThreadId;
sendRequest( &hd ); return (HANDLE)hd.dwReturn; } /* HelperCreateDSMixerThread
/*
* HelperCreateDSFocusThread * * get the helper to create a sound focus thread. */ HANDLE HelperCreateDSFocusThread( LPTHREAD_START_ROUTINE pfnThreadFunc, LPDWORD pdwThreadParam, DWORD dwFlags, LPDWORD pThreadId ) { DDHELPDATA hd;
hd.req = DDHELPREQ_CREATEDSFOCUSTHREAD; hd.pData1 = pfnThreadFunc; hd.dwData1 = (DWORD)pdwThreadParam; hd.dwData2 = dwFlags; hd.pData2 = pThreadId;
sendRequest( &hd ); return (HANDLE)hd.dwReturn; } /* HelperCreateDSFocusThread
/*
* HelperCallDSEmulatorCleanup * * Call the DirectSound function which cleans up MMSYSTEM handles */ void HelperCallDSEmulatorCleanup( LPVOID callback, LPVOID pDirectSound ) { DDHELPDATA hd;
hd.req = DDHELPREQ_CALLDSCLEANUP; hd.pData1 = callback; hd.pData2 = pDirectSound;
sendRequest( &hd ); }
#endif //not winnt -just for now-jeffno
/*
* HelperCreateModeSetThread * * get the helper to load a DLL for us. */ BOOL HelperCreateModeSetThread( LPVOID callback, HANDLE *ph, LPVOID lpdd, DWORD hInstance ) { DDHELPDATA hd; HANDLE h; char str[64];
hd.req = DDHELPREQ_CREATEMODESETTHREAD; hd.lpModeSetNotify = callback; hd.pData1 = lpdd; hd.dwData1 = hInstance; sendRequest( &hd ); wsprintf( str, DDHELP_MODESET_EVENT_NAME, hInstance ); DPF( 3, "Trying to open event \"%s\"", str ); h = OpenEvent( SYNCHRONIZE, FALSE, str ); if( h == NULL ) { DPF( 3, "Could not open modeset event!" ); *ph = NULL; return FALSE; } *ph = h; DPF( 1, "HelperCreateModeSetThread GotEvent: %08lx", h ); return TRUE;
} /* HelperCreateModeSetThread */
/*
* HelperKillModeSetThread * * get the helper to load a DLL for us. */ void HelperKillModeSetThread( DWORD hInstance ) { DDHELPDATA hd;
hd.req = DDHELPREQ_KILLMODESETTHREAD; hd.dwData1 = hInstance; sendRequest( &hd );
} /* HelperKillModeSetThread */
#ifdef WIN95
/*
* HelperCreateDOSBoxThread * * get the helper to create a thread so kernel mode can notify us of DOS box * changes. */ BOOL HelperCreateDOSBoxThread( LPVOID callback, HANDLE *ph, LPVOID lpdd, DWORD hInstance ) { DDHELPDATA hd; HANDLE h; char str[64];
hd.req = DDHELPREQ_CREATEDOSBOXTHREAD; hd.lpModeSetNotify = callback; hd.pData1 = lpdd; hd.dwData1 = hInstance; sendRequest( &hd ); wsprintf( str, DDHELP_DOSBOX_EVENT_NAME, hInstance ); DPF( 3, "Trying to open event \"%s\"", str ); h = OpenEvent( SYNCHRONIZE, FALSE, str ); if( h == NULL ) { DPF( 3, "Could not open DOS box event!" ); *ph = NULL; return FALSE; } *ph = h; DPF( 1, "HelperCreateDOSBoxThread GotEvent: %08lx", h ); return TRUE;
} /* HelperCreateDOSBoxThread */
/*
* HelperKillDOSBoxThread * * get the helper to load a DLL for us. */ void HelperKillDOSBoxThread( DWORD hInstance ) { DDHELPDATA hd;
hd.req = DDHELPREQ_KILLDOSBOXTHREAD; hd.dwData1 = hInstance; sendRequest( &hd );
} /* HelperKillDOSBoxThread */
#endif //!winnt
// notify dphelp.c that we have a new server on this system
DWORD HelperAddDPlayServer(DWORD port) { DDHELPDATA hd; DWORD pid = GetCurrentProcessId();
memset(&hd, 0, sizeof(DDHELPDATA)); hd.req = DDHELPREQ_DPLAYADDSERVER; hd.pid = pid; hd. dwData1 = port; if (sendRequest(&hd)) return (DWORD)hd.dwReturn; else return ((DWORD) E_FAIL); } // HelperAddDPlayServer
// server is going away
BOOL HelperDeleteDPlayServer(void) { DDHELPDATA hd; DWORD pid = GetCurrentProcessId();
hd.req = DDHELPREQ_DPLAYDELETESERVER; hd.pid = pid; return sendRequest(&hd);
} // HelperDeleteDPlayServer
#ifdef WIN95
/*
* Get DDHELP to load the DirectSound VXD (if it has not * already done so) and return a handle to the VXD) */ HANDLE HelperGetDSVxd( void ) { DDHELPDATA hd; hd.req = DDHELPREQ_GETDSVXDHANDLE; sendRequest( &hd ); return (HANDLE) hd.dwReturn; } /* HelperGetDSVxd */
/*
* Get DDHELP to load the DirectDraw VXD (if it has not * already done so) and return a handle to the VXD) */ HANDLE HelperGetDDVxd( void ) { DDHELPDATA hd; hd.req = DDHELPREQ_GETDDVXDHANDLE; sendRequest( &hd ); return (HANDLE) hd.dwReturn; } /* HelperGetDDVxd */
#endif /* WIN95 */
/*
* HelperSetOnDisplayChangeNotify * * get the helper to call us back if there is DisplayChange * message. (This is for multi-mon topology changes.) */ void HelperSetOnDisplayChangeNotify( void *pfn ) { DDHELPDATA hd; hd.req = DDHELPREQ_NOTIFYONDISPLAYCHANGE; hd.dwData1 = (DWORD_PTR)pfn; sendRequest( &hd ); return; }
HINSTANCE HelperLoadLibrary(LPCSTR pszLibraryName) { DDHELPDATA hd; hd.req = DDHELPREQ_LOADLIBRARY; hd.dwData1 = (DWORD_PTR)pszLibraryName; sendRequest(&hd); return (HINSTANCE)hd.dwReturn; }
BOOL HelperFreeLibrary(HINSTANCE hInst) { DDHELPDATA hd; hd.req = DDHELPREQ_FREELIBRARY; hd.dwData1 = (DWORD_PTR)hInst; sendRequest(&hd); return (BOOL)hd.dwReturn; }
void HelperAddDeviceChangeNotify(LPDEVICECHANGENOTIFYPROC lpNotify) { DDHELPDATA hd; hd.req = DDHELPREQ_ADDDEVICECHANGENOTIFY; hd.pData1 = lpNotify; sendRequest(&hd); }
void HelperDelDeviceChangeNotify(LPDEVICECHANGENOTIFYPROC lpNotify) { DDHELPDATA hd; hd.req = DDHELPREQ_DELDEVICECHANGENOTIFY; hd.pData1 = lpNotify; sendRequest(&hd); }
|