Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

570 lines
12 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: w95hack.c
  6. * Content: Win95 hack-o-rama code
  7. * This is a HACK to handle the fact that Win95 doesn't notify
  8. * a DLL when a process is destroyed.
  9. * History:
  10. * Date By Reason
  11. * ==== == ======
  12. * 28-mar-95 craige initial implementation
  13. * 01-apr-95 craige happy fun joy updated header file
  14. * 06-apr-95 craige reworked for new ddhelp
  15. * 09-may-95 craige loading any DLL
  16. * 16-sep-95 craige bug 1117: must UnmapViewOfFile before closing handle
  17. * 29-nov-95 angusm added HelperCreateDSFocusThread
  18. * 18-jul-96 andyco added Helper(Add/)DeleteDPlayServer
  19. * 12-oct-96 colinmc added new service to get DDHELP to get its own handle
  20. * for communicating with the DirectSound VXD
  21. *
  22. ***************************************************************************/
  23. #undef WIN32_LEAN_AND_MEAN
  24. #define WIN32_LEAN_AND_MEAN
  25. #include <windows.h>
  26. #include <mmsystem.h>
  27. #include <mmreg.h>
  28. #include "w95help.h"
  29. #include "dpf.h"
  30. //extern DWORD * pdwHelperPid;
  31. //extern HANDLE * phModule; // must be defined
  32. extern DWORD dwHelperPid;
  33. extern HANDLE hModule; // must be defined
  34. /*
  35. * sendRequest
  36. *
  37. * communicate a request to DDHELP
  38. */
  39. static BOOL sendRequest( LPDDHELPDATA req_phd )
  40. {
  41. LPDDHELPDATA phd;
  42. HANDLE hmem;
  43. HANDLE hmutex;
  44. HANDLE hackevent;
  45. HANDLE hstartevent;
  46. BOOL rc;
  47. /*
  48. * get events start/ack events
  49. */
  50. hstartevent = CreateEvent( NULL, FALSE, FALSE, DDHELP_EVENT_NAME );
  51. if( hstartevent == NULL )
  52. {
  53. return FALSE;
  54. }
  55. hackevent = CreateEvent( NULL, FALSE, FALSE, DDHELP_ACK_EVENT_NAME );
  56. if( hackevent == NULL )
  57. {
  58. CloseHandle( hstartevent );
  59. return FALSE;
  60. }
  61. /*
  62. * create shared memory area
  63. */
  64. hmem = CreateFileMapping( INVALID_HANDLE_VALUE, NULL,
  65. PAGE_READWRITE, 0, sizeof( DDHELPDATA ),
  66. DDHELP_SHARED_NAME );
  67. if( hmem == NULL )
  68. {
  69. DPF( 1, "Could not create file mapping!" );
  70. CloseHandle( hstartevent );
  71. CloseHandle( hackevent );
  72. return FALSE;
  73. }
  74. phd = (LPDDHELPDATA) MapViewOfFile( hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
  75. if( phd == NULL )
  76. {
  77. DPF( 1, "Could not create view of file!" );
  78. CloseHandle( hmem );
  79. CloseHandle( hstartevent );
  80. CloseHandle( hackevent );
  81. return FALSE;
  82. }
  83. /*
  84. * wait for access to the shared memory
  85. */
  86. hmutex = OpenMutex( SYNCHRONIZE, FALSE, DDHELP_MUTEX_NAME );
  87. if( hmutex == NULL )
  88. {
  89. DPF( 1, "Could not create mutex!" );
  90. UnmapViewOfFile( phd );
  91. CloseHandle( hmem );
  92. CloseHandle( hstartevent );
  93. CloseHandle( hackevent );
  94. return FALSE;
  95. }
  96. WaitForSingleObject( hmutex, INFINITE );
  97. /*
  98. * wake up DDHELP with our request
  99. */
  100. memcpy( phd, req_phd, sizeof( DDHELPDATA ) );
  101. phd->req_id = hModule;
  102. if( SetEvent( hstartevent ) )
  103. {
  104. WaitForSingleObject( hackevent, INFINITE );
  105. memcpy( req_phd, phd, sizeof( DDHELPDATA ) );
  106. rc = TRUE;
  107. }
  108. else
  109. {
  110. DPF( 1, "Could not signal event to notify DDHELP" );
  111. rc = FALSE;
  112. }
  113. /*
  114. * done with things
  115. */
  116. ReleaseMutex( hmutex );
  117. CloseHandle( hmutex );
  118. CloseHandle( hstartevent );
  119. CloseHandle( hackevent );
  120. UnmapViewOfFile( phd );
  121. CloseHandle( hmem );
  122. return rc;
  123. } /* sendRequest */
  124. /*
  125. * DoneWithHelperProcess
  126. */
  127. void DoneWithHelperProcess( void )
  128. {
  129. DDHELPDATA hd;
  130. if( dwHelperPid == 0 )
  131. {
  132. return;
  133. }
  134. hd.req = DDHELPREQ_FREEDCLIST;
  135. sendRequest( &hd );
  136. } /* DoneWithHelperProcess */
  137. /*
  138. * WaitForHelperStartup
  139. */
  140. BOOL WaitForHelperStartup( void )
  141. {
  142. HANDLE hevent;
  143. DWORD rc;
  144. hevent = CreateEvent( NULL, TRUE, FALSE, DDHELP_STARTUP_EVENT_NAME );
  145. if( hevent == NULL )
  146. {
  147. return FALSE;
  148. }
  149. DPF( 3, "Wait DDHELP startup event to be triggered" );
  150. rc = WaitForSingleObject( hevent, INFINITE );
  151. CloseHandle( hevent );
  152. return TRUE;
  153. } /* WaitForHelperStartup */
  154. /*
  155. * HelperLoadDLL
  156. *
  157. * get the helper to load a DLL for us.
  158. */
  159. DWORD HelperLoadDLL( LPSTR dllname, LPSTR fnname, DWORD context )
  160. {
  161. DDHELPDATA hd;
  162. DWORD rc = 0;
  163. if( dllname != NULL )
  164. {
  165. hd.req = DDHELPREQ_LOADDLL;
  166. lstrcpy( hd.fname, dllname );
  167. if( fnname != NULL )
  168. {
  169. strcpy( hd.func, fnname );
  170. hd.context = context;
  171. DPF( 3, "Context=%08lx", context );
  172. }
  173. else
  174. {
  175. hd.func[0] = 0;
  176. }
  177. DPF( 3, "Asking DDHELP to load DLL %s", dllname );
  178. sendRequest( &hd );
  179. rc = hd.dwReturn;
  180. }
  181. return rc;
  182. } /* HelperLoadDLL */
  183. /*
  184. * HelperCreateThread
  185. */
  186. void HelperCreateThread( void )
  187. {
  188. DDHELPDATA hd;
  189. hd.req = DDHELPREQ_CREATEHELPERTHREAD;
  190. sendRequest( &hd );
  191. } /* HelperCreateThread */
  192. /*
  193. * SignalNewProcess
  194. *
  195. * Signal DDHELP that a new process has arrived. This is called with the
  196. * DLL lock taken, so global vars are safe
  197. */
  198. void SignalNewProcess( DWORD pid, LPHELPNOTIFYPROC proc )
  199. {
  200. DDHELPDATA hd;
  201. if( pid == dwHelperPid )
  202. {
  203. DPF( 3, "Helper connected to DLL - no signal required" );
  204. return;
  205. }
  206. DPF( 3, "Signalling DDHELP that a new process has connected" );
  207. hd.req = DDHELPREQ_NEWPID;
  208. hd.pid = pid;
  209. hd.lpNotify = proc;
  210. sendRequest( &hd );
  211. } /* SignalNewProcess */
  212. /*
  213. * SignalNewDriver
  214. *
  215. * Signal DDHELP that a new driver has been loaded. This is called with the
  216. * DLL lock taken, so global vars are safe
  217. */
  218. void SignalNewDriver( LPSTR fname, BOOL isdisp )
  219. {
  220. DDHELPDATA hd;
  221. DPF( 3, "Signalling DDHELP to create a new DC" );
  222. hd.req = DDHELPREQ_NEWDC;
  223. hd.isdisp = isdisp;
  224. lstrcpy( hd.fname, fname );
  225. sendRequest( &hd );
  226. } /* SignalNewDriver */
  227. /*
  228. * CreateHelperProcess
  229. */
  230. BOOL CreateHelperProcess( LPDWORD ppid )
  231. {
  232. if( dwHelperPid == 0 )
  233. {
  234. STARTUPINFO si;
  235. PROCESS_INFORMATION pi;
  236. HANDLE h;
  237. h = OpenEvent( SYNCHRONIZE, FALSE, DDHELP_STARTUP_EVENT_NAME );
  238. if( h == NULL )
  239. {
  240. si.cb = sizeof(STARTUPINFO);
  241. si.lpReserved = NULL;
  242. si.lpDesktop = NULL;
  243. si.lpTitle = NULL;
  244. si.dwFlags = 0;
  245. si.cbReserved2 = 0;
  246. si.lpReserved2 = NULL;
  247. DPF( 3, "Creating helper process now" );
  248. if( !CreateProcess(NULL, "ddhelp.exe", NULL, NULL, FALSE,
  249. NORMAL_PRIORITY_CLASS,
  250. NULL, NULL, &si, &pi) )
  251. {
  252. DPF( 2, "Could not create DDHELP.EXE" );
  253. return FALSE;
  254. }
  255. dwHelperPid = pi.dwProcessId;
  256. DPF( 3, "Helper rocess created" );
  257. }
  258. else
  259. {
  260. DDHELPDATA hd;
  261. DPF( 3, "DDHELP already exists, waiting for DDHELP event" );
  262. WaitForSingleObject( h, INFINITE );
  263. CloseHandle( h );
  264. DPF( 3, "Asking for DDHELP pid" );
  265. hd.req = DDHELPREQ_RETURNHELPERPID;
  266. sendRequest( &hd );
  267. dwHelperPid = hd.pid;
  268. DPF( 3, "DDHELP pid = %08lx", dwHelperPid );
  269. }
  270. *ppid = dwHelperPid;
  271. return TRUE;
  272. }
  273. *ppid = dwHelperPid;
  274. return FALSE;
  275. } /* CreateHelperProcess */
  276. #ifndef WINNT //this is Just For Now... dsound will get the help it needs..jeffno 951206
  277. /*
  278. * HelperWaveOpen
  279. *
  280. * get the helper to load a DLL for us.
  281. */
  282. DWORD HelperWaveOpen( LPVOID lphwo, DWORD dwDeviceID, LPVOID pwfx )
  283. {
  284. DDHELPDATA hd;
  285. if( (lphwo != NULL) && (pwfx != NULL) )
  286. {
  287. hd.req = DDHELPREQ_WAVEOPEN;
  288. hd.pData1 = lphwo;
  289. hd.dwData1 = dwDeviceID;
  290. hd.dwData2 = (DWORD)pwfx;
  291. DPF( 3, "Asking DDHELP to Open Wave Device %d", dwDeviceID );
  292. sendRequest( &hd );
  293. return hd.dwReturn;
  294. }
  295. else
  296. {
  297. DPF( 3, "Helper Wave Open param error");
  298. return MMSYSERR_ERROR;
  299. }
  300. } /* HelperWaveOpen */
  301. /*
  302. * HelperWaveClose
  303. *
  304. * get the helper to load a DLL for us.
  305. */
  306. DWORD HelperWaveClose( DWORD hwo )
  307. {
  308. DDHELPDATA hd;
  309. if( (hwo != 0) )
  310. {
  311. hd.req = DDHELPREQ_WAVECLOSE;
  312. hd.dwData1 = hwo;
  313. DPF( 3, "Asking DDHELP to Close Wave Device ");
  314. sendRequest( &hd );
  315. return hd.dwReturn;
  316. }
  317. else
  318. {
  319. DPF( 3, "Helper Wave Close param error");
  320. return MMSYSERR_ERROR;
  321. }
  322. } /* HelperWaveClose */
  323. /*
  324. * HelperCreateTimer
  325. *
  326. * get the helper to load a DLL for us.
  327. */
  328. DWORD HelperCreateTimer( DWORD dwResolution,
  329. LPVOID pTimerProc,
  330. DWORD dwInstanceData )
  331. {
  332. DDHELPDATA hd;
  333. if( (dwResolution != 0) && (pTimerProc != NULL) )
  334. {
  335. hd.req = DDHELPREQ_CREATETIMER;
  336. hd.pData1 = pTimerProc;
  337. hd.dwData1 = dwResolution;
  338. hd.dwData2 = dwInstanceData;
  339. DPF( 3, "Asking DDHELP to Create Timer" );
  340. sendRequest( &hd );
  341. return hd.dwReturn;
  342. }
  343. else
  344. {
  345. DPF( 3, "Helper Wave Close param error");
  346. return MMSYSERR_ERROR;
  347. }
  348. } /* HelperCreateTimer */
  349. /*
  350. * HelperKillTimer
  351. *
  352. * get the helper to load a DLL for us.
  353. */
  354. DWORD HelperKillTimer( DWORD dwTimerID )
  355. {
  356. DDHELPDATA hd;
  357. if( (dwTimerID != 0) )
  358. {
  359. hd.req = DDHELPREQ_KILLTIMER;
  360. hd.dwData1 = dwTimerID;
  361. DPF( 3, "Asking DDHELP to KILL Timer %X", dwTimerID );
  362. sendRequest( &hd );
  363. return hd.dwReturn;
  364. }
  365. else
  366. {
  367. DPF( 3, "Helper Wave Close param error");
  368. return MMSYSERR_ERROR;
  369. }
  370. } /* HelperKillTimer */
  371. /*
  372. * HelperCreateDSMixerThread
  373. *
  374. * get the helper to create a mixer thread.
  375. */
  376. HANDLE HelperCreateDSMixerThread( LPTHREAD_START_ROUTINE pfnThreadFunc,
  377. LPDWORD pdwThreadParam,
  378. DWORD dwFlags,
  379. LPDWORD pThreadId )
  380. {
  381. DDHELPDATA hd;
  382. hd.req = DDHELPREQ_CREATEDSMIXERTHREAD;
  383. hd.pData1 = pfnThreadFunc;
  384. hd.dwData1 = (DWORD)pdwThreadParam;
  385. hd.dwData2 = dwFlags;
  386. hd.pData2 = pThreadId;
  387. sendRequest( &hd );
  388. return (HANDLE)hd.dwReturn;
  389. } /* HelperCreateDSMixerThread
  390. /*
  391. * HelperCreateDSFocusThread
  392. *
  393. * get the helper to create a sound focus thread.
  394. */
  395. HANDLE HelperCreateDSFocusThread( LPTHREAD_START_ROUTINE pfnThreadFunc,
  396. LPDWORD pdwThreadParam,
  397. DWORD dwFlags,
  398. LPDWORD pThreadId )
  399. {
  400. DDHELPDATA hd;
  401. hd.req = DDHELPREQ_CREATEDSFOCUSTHREAD;
  402. hd.pData1 = pfnThreadFunc;
  403. hd.dwData1 = (DWORD)pdwThreadParam;
  404. hd.dwData2 = dwFlags;
  405. hd.pData2 = pThreadId;
  406. sendRequest( &hd );
  407. return (HANDLE)hd.dwReturn;
  408. } /* HelperCreateDSFocusThread
  409. /*
  410. * HelperCallDSEmulatorCleanup
  411. *
  412. * Call the DirectSound function which cleans up MMSYSTEM handles
  413. */
  414. void HelperCallDSEmulatorCleanup( LPVOID callback,
  415. LPVOID pDirectSound )
  416. {
  417. DDHELPDATA hd;
  418. hd.req = DDHELPREQ_CALLDSCLEANUP;
  419. hd.pData1 = callback;
  420. hd.pData2 = pDirectSound;
  421. sendRequest( &hd );
  422. }
  423. #endif //not winnt -just for now-jeffno
  424. /*
  425. * HelperCreateModeSetThread
  426. *
  427. * get the helper to load a DLL for us.
  428. */
  429. BOOL HelperCreateModeSetThread(
  430. LPVOID callback,
  431. HANDLE *ph,
  432. LPVOID lpdd,
  433. DWORD hInstance )
  434. {
  435. DDHELPDATA hd;
  436. HANDLE h;
  437. char str[64];
  438. hd.req = DDHELPREQ_CREATEMODESETTHREAD;
  439. hd.lpModeSetNotify = callback;
  440. hd.pData1 = lpdd;
  441. hd.dwData1 = hInstance;
  442. sendRequest( &hd );
  443. wsprintf( str, DDHELP_MODESET_EVENT_NAME, hInstance );
  444. DPF( 3, "Trying to open event \"%s\"", str );
  445. h = OpenEvent( SYNCHRONIZE, FALSE, str );
  446. if( h == NULL )
  447. {
  448. DPF( 3, "Could not open modeset event!" );
  449. *ph = NULL;
  450. return FALSE;
  451. }
  452. *ph = h;
  453. DPF( 1, "HelperCreateModeSetThread GotEvent: %08lx", h );
  454. return TRUE;
  455. } /* HelperCreateModeSetThread */
  456. /*
  457. * HelperKillModeSetThread
  458. *
  459. * get the helper to load a DLL for us.
  460. */
  461. void HelperKillModeSetThread( DWORD hInstance )
  462. {
  463. DDHELPDATA hd;
  464. hd.req = DDHELPREQ_KILLMODESETTHREAD;
  465. hd.dwData1 = hInstance;
  466. sendRequest( &hd );
  467. } /* HelperKillModeSetThread */
  468. // notify dphelp.c that we have a new server on this system
  469. BOOL HelperAddDPlayServer(DWORD port)
  470. {
  471. DDHELPDATA hd;
  472. DWORD pid = GetCurrentProcessId();
  473. hd.req = DDHELPREQ_DPLAYADDSERVER;
  474. hd.pid = pid;
  475. hd. dwData1 = port;
  476. return sendRequest(&hd);
  477. } // HelperAddDPlayServer
  478. // server is going away
  479. BOOL HelperDeleteDPlayServer(void)
  480. {
  481. DDHELPDATA hd;
  482. DWORD pid = GetCurrentProcessId();
  483. hd.req = DDHELPREQ_DPLAYDELETESERVER;
  484. hd.pid = pid;
  485. return sendRequest(&hd);
  486. } // HelperDeleteDPlayServer
  487. #ifdef USE_ALIAS
  488. /*
  489. * Get DDHELP to load the DirectSound VXD (if it has not
  490. * already done so) and return a handle to the VXD)
  491. */
  492. HANDLE HelperGetDSVxd( void )
  493. {
  494. DDHELPDATA hd;
  495. hd.req = DDHELPREQ_GETDSVXDHANDLE;
  496. sendRequest( &hd );
  497. return (HANDLE) hd.dwReturn;
  498. } /* HelperGetDSVxd */
  499. #endif /* USE_ALIAS */