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.

690 lines
17 KiB

  1. ;****************************************************************************
  2. ;** **
  3. ;** **
  4. ;** **
  5. ;** **
  6. ;** **
  7. ;** **
  8. ;** **
  9. ;** **
  10. ;****************************************************************************
  11. .386
  12. .xlist
  13. include vmm.inc
  14. include vtd.inc
  15. include debug.inc
  16. ; include mmdevldr.inc
  17. include vwin32.inc
  18. include pagefile.inc
  19. include vmcpd.inc
  20. ; include shell.inc
  21. ; include debugsys.inc
  22. .list
  23. Create_DSOUND_Service_Table equ 1
  24. include dsdriver.inc
  25. OPTION SCOPED
  26. ;****************************************************************************
  27. ;** **
  28. ;** VxD declaration **
  29. ;** **
  30. ;****************************************************************************
  31. DSOUND_VERSION_MAJOR equ 4 ; Version 4.02
  32. DSOUND_VERSION_MINOR equ 2 ;
  33. Declare_Virtual_Device DSOUND, \
  34. DSOUND_VERSION_MAJOR, DSOUND_VERSION_MINOR, \
  35. DSOUND_Control, \
  36. DSOUND_Device_ID, \
  37. UNDEFINED_INIT_ORDER, \
  38. DSOUND_API_Handler, \
  39. DSOUND_API_Handler
  40. ;****************************************************************************
  41. ;** **
  42. ;** Macro, equate, and type declarations **
  43. ;** **
  44. ;****************************************************************************
  45. LONG_MAX equ 7fffffffh ;Maximum 32-bit signed value
  46. RESAMPLING_TOLERANCE equ 0 ;E.g., 655=1% resampling tolerance
  47. ;****************************************************************************
  48. ;** **
  49. ;** Locked data **
  50. ;** **
  51. ;****************************************************************************
  52. VxD_LOCKED_DATA_SEG
  53. ;****************************************************************************
  54. ;** **
  55. ;** Primitive vectors generated at beginning of data segment **
  56. ;** **
  57. ;** 1st 32 entries: MAKE_DC procedures for AILSSA_DMA_copy() **
  58. ;** 2nd 128 entries: MAKE_MERGE procedures for AILSSA_merge() **
  59. ;** **
  60. ;****************************************************************************
  61. ;
  62. ;First device code is duplicated since IOCTL calls with
  63. ;function 0 always fail in Win95 for some reason
  64. ;
  65. ;---
  66. ;
  67. ; Read the documentation, silly. Function 0 is DIOC_OPEN.
  68. ; It is the VxD version of PROCESS_ATTACH.
  69. DSVXD_IOCTL_Table LABEL DWORD
  70. dd OFFSET32 _ioctlDsvxdGetVersion
  71. dd OFFSET32 _ioctlDsvxdInitialize
  72. dd OFFSET32 _ioctlDsvxdShutdown
  73. dd OFFSET32 _ioctlDrvGetNextDescFromGuid
  74. dd OFFSET32 _ioctlDrvGetDescFromGuid
  75. dd OFFSET32 _ioctlIDsDriver_QueryInterface
  76. dd OFFSET32 _ioctlDrvOpenFromGuid
  77. dd OFFSET32 _ioctlIDsDriver_Close
  78. dd OFFSET32 _ioctlIDsDriver_GetCaps
  79. dd OFFSET32 _ioctlIDsDriver_CreateSoundBuffer
  80. dd OFFSET32 _ioctlIDsDriver_DuplicateSoundBuffer
  81. dd OFFSET32 _ioctlBufferRelease
  82. dd OFFSET32 _ioctlBufferLock
  83. dd OFFSET32 _ioctlBufferUnlock
  84. dd OFFSET32 _ioctlBufferSetFormat
  85. dd OFFSET32 _ioctlBufferSetFrequency
  86. dd OFFSET32 _ioctlBufferSetVolumePan
  87. dd OFFSET32 _ioctlBufferSetPosition
  88. dd OFFSET32 _ioctlBufferGetPosition
  89. dd OFFSET32 _ioctlBufferPlay
  90. dd OFFSET32 _ioctlBufferStop
  91. dd OFFSET32 _ioctlEventScheduleWin32Event
  92. dd OFFSET32 _ioctlEventCloseVxDHandle
  93. dd OFFSET32 _ioctlMemReserveAlias
  94. dd OFFSET32 _ioctlMemCommitAlias
  95. dd OFFSET32 _ioctlMemRedirectAlias
  96. dd OFFSET32 _ioctlMemDecommitAlias
  97. dd OFFSET32 _ioctlMemFreeAlias
  98. dd OFFSET32 _ioctlMemPageLock
  99. dd OFFSET32 _ioctlMemPageUnlock
  100. dd OFFSET32 _ioctlDsvxd_PageFile_Get_Version
  101. dd OFFSET32 _ioctlDsvxd_VMM_Test_Debug_Installed
  102. dd OFFSET32 _ioctlDsvxd_VMCPD_Get_Version
  103. dd OFFSET32 _ioctlDsvxd_GetMixerMutexPtr
  104. dd OFFSET32 _ioctlMixer_Run
  105. dd OFFSET32 _ioctlMixer_Stop
  106. dd OFFSET32 _ioctlMixer_PlayWhenIdle
  107. dd OFFSET32 _ioctlMixer_StopWhenIdle
  108. dd OFFSET32 _ioctlMixer_MixListAdd
  109. dd OFFSET32 _ioctlMixer_MixListRemove
  110. dd OFFSET32 _ioctlMixer_FilterOn
  111. dd OFFSET32 _ioctlMixer_FilterOff
  112. dd OFFSET32 _ioctlMixer_GetBytePosition
  113. dd OFFSET32 _ioctlMixer_SignalRemix
  114. dd OFFSET32 _ioctlKeDest_New
  115. dd OFFSET32 _ioctlMixDest_Delete
  116. dd OFFSET32 _ioctlMixDest_Initialize
  117. dd OFFSET32 _ioctlMixDest_Terminate
  118. dd OFFSET32 _ioctlMixDest_SetFormat
  119. dd OFFSET32 _ioctlMixDest_SetFormatInfo
  120. dd OFFSET32 _ioctlMixDest_AllocMixer
  121. dd OFFSET32 _ioctlMixDest_FreeMixer
  122. dd OFFSET32 _ioctlMixDest_Play
  123. dd OFFSET32 _ioctlMixDest_Stop
  124. dd OFFSET32 _ioctlMixDest_GetFrequency
  125. dd OFFSET32 _ioctlMemCommitPhysAlias
  126. dd OFFSET32 _ioctlMemRedirectPhysAlias
  127. dd OFFSET32 _ioctlIUnknown_QueryInterface
  128. dd OFFSET32 _ioctlIUnknown_AddRef
  129. dd OFFSET32 _ioctlIUnknown_Release
  130. dd OFFSET32 _ioctlIDirectSoundPropertySet_GetProperty
  131. dd OFFSET32 _ioctlIDirectSoundPropertySet_SetProperty
  132. dd OFFSET32 _ioctlIDirectSoundPropertySet_QuerySupport
  133. dd OFFSET32 _ioctlGetInternalVersionNumber
  134. DSOUND_N_IOCTLS EQU ($-DSVXD_IOCTL_Table) / SIZE DWORD
  135. ;
  136. ;Pointer to input/output parms
  137. ;
  138. IOCTL_parms dd ?
  139. VxD_LOCKED_DATA_ENDS
  140. ;****************************************************************************
  141. ;** **
  142. ;** Locked code **
  143. ;** **
  144. ;****************************************************************************
  145. VxD_LOCKED_CODE_SEG
  146. extrn _ioctlDsvxdInitialize:NEAR
  147. extrn _ioctlDsvxdShutdown:NEAR
  148. extrn _ioctlDrvGetNextDescFromGuid:NEAR
  149. extrn _ioctlDrvGetDescFromGuid:NEAR
  150. extrn _ioctlDrvOpenFromGuid:NEAR
  151. extrn _ioctlIDsDriver_QueryInterface:NEAR
  152. extrn _ioctlIDsDriver_Close:NEAR
  153. extrn _ioctlIDsDriver_GetCaps:NEAR
  154. extrn _ioctlIDsDriver_CreateSoundBuffer:NEAR
  155. extrn _ioctlIDsDriver_DuplicateSoundBuffer:NEAR
  156. extrn _ioctlBufferRelease:NEAR
  157. extrn _ioctlBufferLock:NEAR
  158. extrn _ioctlBufferUnlock:NEAR
  159. extrn _ioctlBufferSetFormat:NEAR
  160. extrn _ioctlBufferSetFrequency:NEAR
  161. extrn _ioctlBufferSetVolumePan:NEAR
  162. extrn _ioctlBufferSetPosition:NEAR
  163. extrn _ioctlBufferGetPosition:NEAR
  164. extrn _ioctlBufferPlay:NEAR
  165. extrn _ioctlBufferStop:NEAR
  166. extrn _ioctlEventScheduleWin32Event:NEAR
  167. extrn _ioctlEventCloseVxDHandle:NEAR
  168. extrn _ioctlMemReserveAlias:NEAR
  169. extrn _ioctlMemCommitAlias:NEAR
  170. extrn _ioctlMemRedirectAlias:NEAR
  171. extrn _ioctlMemDecommitAlias:NEAR
  172. extrn _ioctlMemFreeAlias:NEAR
  173. extrn _ioctlMemPageLock:NEAR
  174. extrn _ioctlMemPageUnlock:NEAR
  175. extrn _ioctlDsvxd_PageFile_Get_Version:NEAR
  176. extrn _ioctlDsvxd_VMM_Test_Debug_Installed:NEAR
  177. extrn _ioctlDsvxd_VMCPD_Get_Version:NEAR
  178. extrn _ioctlDsvxd_GetMixerMutexPtr:NEAR
  179. extrn _ioctlMixer_Run:NEAR
  180. extrn _ioctlMixer_Stop:NEAR
  181. extrn _ioctlMixer_PlayWhenIdle:NEAR
  182. extrn _ioctlMixer_StopWhenIdle:NEAR
  183. extrn _ioctlMixer_MixListAdd:NEAR
  184. extrn _ioctlMixer_MixListRemove:NEAR
  185. extrn _ioctlMixer_FilterOn:NEAR
  186. extrn _ioctlMixer_FilterOff:NEAR
  187. extrn _ioctlMixer_GetBytePosition:NEAR
  188. extrn _ioctlMixer_SignalRemix:NEAR
  189. extrn _ioctlKeDest_New:NEAR
  190. extrn _ioctlMixDest_Delete:NEAR
  191. extrn _ioctlMixDest_Initialize:NEAR
  192. extrn _ioctlMixDest_Terminate:NEAR
  193. extrn _ioctlMixDest_SetFormat:NEAR
  194. extrn _ioctlMixDest_SetFormatInfo:NEAR
  195. extrn _ioctlMixDest_AllocMixer:NEAR
  196. extrn _ioctlMixDest_FreeMixer:NEAR
  197. extrn _ioctlMixDest_Play:NEAR
  198. extrn _ioctlMixDest_Stop:NEAR
  199. extrn _ioctlMixDest_GetFrequency:NEAR
  200. extrn _ioctlMemCommitPhysAlias:NEAR
  201. extrn _ioctlMemRedirectPhysAlias:NEAR
  202. extrn _ioctlIUnknown_QueryInterface:NEAR
  203. extrn _ioctlIUnknown_AddRef:NEAR
  204. extrn _ioctlIUnknown_Release:NEAR
  205. extrn _ioctlIDirectSoundPropertySet_QuerySupport:NEAR
  206. extrn _ioctlIDirectSoundPropertySet_SetProperty:NEAR
  207. extrn _ioctlIDirectSoundPropertySet_GetProperty:NEAR
  208. extrn _ioctlGetInternalVersionNumber:NEAR
  209. ;****************************************************************************
  210. ;** **
  211. ;** IOCTL dispatcher for VxD **
  212. ;** **
  213. ;** Dispatch control messages to the correct handlers. Must be in **
  214. ;** locked code segment. (All VxD segments are locked in 3.0/3.1) **
  215. ;** **
  216. ;** ENTRY: **
  217. ;** **
  218. ;** EXIT: **
  219. ;** Carry clear success; Carry Set if fail. **
  220. ;** **
  221. ;****************************************************************************
  222. BeginProc DSOUND_Control
  223. Control_Dispatch Sys_Dynamic_Device_Init, ctrlDynamicDeviceInitA
  224. Control_Dispatch Sys_Dynamic_Device_Exit, ctrlDynamicDeviceExitA
  225. Control_Dispatch W32_DEVICEIOCONTROL, ctrlDeviceIOControl
  226. ; Trace_Out "DSOUND_Control "
  227. clc
  228. ret
  229. EndProc DSOUND_Control
  230. ;****************************************************************************
  231. ;** **
  232. ;** API dispatcher for VxD **
  233. ;** **
  234. ;** Dispatch control messages to the correct handlers. **
  235. ;** **
  236. ;** ENTRY: **
  237. ;** **
  238. ;** EXIT: **
  239. ;** Carry clear success; Carry Set if fail. **
  240. ;** **
  241. ;****************************************************************************
  242. BeginProc DSOUND_API_Handler
  243. Trace_Out "DSOUND_API_Handler "
  244. clc
  245. ret
  246. EndProc DSOUND_API_Handler
  247. ;---------------------------------------------------------------------------;
  248. ;
  249. ; ctrlDynamicDeviceInit and Exit
  250. ;
  251. ;---------------------------------------------------------------------------;
  252. BeginProc ctrlDynamicDeviceInitA
  253. Ccall _ctrlDynamicDeviceInit
  254. sub eax, 1
  255. ret
  256. EndProc ctrlDynamicDeviceInitA
  257. BeginProc ctrlDynamicDeviceExitA
  258. Ccall _ctrlDynamicDeviceExit
  259. sub eax, 1
  260. ret
  261. EndProc ctrlDynamicDeviceExitA
  262. ;------------------------------------------------------------------------------
  263. ; FUNC DSOUND_GetVersion - Locked Code
  264. ;
  265. ; ENTRY
  266. ; None
  267. ;
  268. ; EXIT
  269. ; AH = Major version number
  270. ; AL = Minor version number
  271. ; Carry flag clear
  272. ;
  273. ; USES
  274. ; EAX, Flags
  275. ;
  276. ;------------------------------------------------------------------------------
  277. BeginProc _DSOUND_GetVersion, SERVICE
  278. mov eax, DSOUND_VERSION_MAJOR * 100h + DSOUND_VERSION_MINOR
  279. clc
  280. ret
  281. EndProc _DSOUND_GetVersion
  282. ;****************************************************************************
  283. ;** **
  284. ;** ctrlDeviceIOControl **
  285. ;** **
  286. ;** DESCRIPTION: This function is called to perform Device IO **
  287. ;** for a 32 bit process which has opened this device with **
  288. ;** <f CreateFile>, and is performing IO using **
  289. ;** <f DeviceIOControl>. Preserves the C32 calling registers **
  290. ;** ESI, EDI, and EBX. **
  291. ;** **
  292. ;** ENTRY: EBX DDB **
  293. ;** ECX dwIoControlCode **
  294. ;** ESI ptr to DIOCParams **
  295. ;** **
  296. ;** EXIT: As determined by function, or 1 if invalid IOCTL **
  297. ;** **
  298. ;** ----- **
  299. ;** **
  300. ;** Note: Function 0 is documented in vmm.h **
  301. ;** as DIOC_OPEN. It is your VxD's PROCESS_ATTACH call. **
  302. ;** **
  303. ;****************************************************************************
  304. BeginProc ctrlDeviceIOControl
  305. cmp ecx, DSOUND_N_IOCTLS
  306. jae cDIOC_InvalidCode
  307. push edi
  308. push esi
  309. push ebx
  310. mov IOCTL_parms,esi
  311. push esi
  312. call DSVXD_IOCTL_Table[ecx*4]
  313. add esp, 4
  314. pop ebx
  315. pop esi
  316. pop edi
  317. ret
  318. cDIOC_InvalidCode:
  319. IFDEF DEBUG
  320. cmp ecx, DIOC_CLOSEHANDLE
  321. Debug_OutNZ "DSVXD: Invalid dwIoControlCode #ECX"
  322. ENDIF
  323. mov eax, 1 ; ERROR_INVALID_FUNCTION
  324. ret
  325. EndProc ctrlDeviceIOControl
  326. ;****************************************************************************
  327. ;** **
  328. ;** _ioctlDsvxdGetVersion **
  329. ;** **
  330. ;** DESCRIPTION: Get the version of DSVXD **
  331. ;** **
  332. ;** ENTRY: **
  333. ;** **
  334. ;** EXIT: **
  335. ;** **
  336. ;****************************************************************************
  337. BeginProc _ioctlDsvxdGetVersion
  338. Trace_Out "DSVXD: ioctlDsvxdGetVersion"
  339. xor eax, eax
  340. mov ecx, DSOUND_VERSION_MAJOR * 100h + DSOUND_VERSION_MINOR
  341. ret
  342. EndProc _ioctlDsvxdGetVersion
  343. ;****************************************************************************
  344. ;** **
  345. ;** **
  346. ;** **
  347. ;****************************************************************************
  348. ;--------------------------------------------------------------------------;
  349. ;
  350. ; _Dsvxd_VMM_Test_Debug_Installed
  351. ;
  352. ; Out:
  353. ;
  354. ; Notes:
  355. ;
  356. ;--------------------------------------------------------------------------;
  357. BeginProc _Dsvxd_VMM_Test_Debug_Installed
  358. EnterProc
  359. VMMcall Test_Debug_Installed
  360. mov eax, 0
  361. jz @F
  362. inc eax
  363. @@:
  364. LeaveProc
  365. Return
  366. EndProc _Dsvxd_VMM_Test_Debug_Installed
  367. ;--------------------------------------------------------------------------;
  368. ;
  369. ; _Dsvxd_PageFile_Get_Version
  370. ;
  371. ; Out:
  372. ;
  373. ; Notes:
  374. ;
  375. ;--------------------------------------------------------------------------;
  376. BeginProc _Dsvxd_PageFile_Get_Version
  377. ArgVar p_version, DWORD
  378. ArgVar p_maxsize, DWORD
  379. ArgVar p_pager_type, DWORD
  380. EnterProc
  381. pushad
  382. VxDcall PageFile_Get_Version
  383. mov edi, p_version
  384. mov [edi], eax
  385. mov edi, p_maxsize
  386. mov [edi], ecx
  387. xor eax, eax
  388. mov al, bl
  389. mov edi, p_pager_type
  390. mov [edi], eax
  391. popad
  392. LeaveProc
  393. Return
  394. EndProc _Dsvxd_PageFile_Get_Version
  395. ;--------------------------------------------------------------------------;
  396. ;
  397. ; _Dsvxd_VMCPD_Get_Version
  398. ;
  399. ; Out:
  400. ;
  401. ; Notes:
  402. ;
  403. ;--------------------------------------------------------------------------;
  404. BeginProc _Dsvxd_VMCPD_Get_Version
  405. ArgVar pMajorVersion, DWORD
  406. ArgVar pMinorVersion, DWORD
  407. ArgVar pLevel, DWORD
  408. EnterProc
  409. pushad
  410. VxDcall VMCPD_Get_Version
  411. xor ebx, ebx
  412. mov edi, pMajorVersion
  413. mov bl, ah
  414. mov [edi], ebx
  415. mov bl, al
  416. mov edi, pMinorVersion
  417. mov [edi], ebx
  418. mov edi, pLevel
  419. mov [edi], ecx
  420. popad
  421. LeaveProc
  422. Return
  423. EndProc _Dsvxd_VMCPD_Get_Version
  424. ;--------------------------------------------------------------------------;
  425. ;
  426. ; _KeGrace_GlobalTimeOutProcAsm
  427. ;
  428. ; This is the entry point for the global time out set by the
  429. ; KeGrace object. This is just an ASM thunk to KeGrace_GlobalTimeOutProc
  430. ; "C" function.
  431. ;
  432. ; This function is called from the VMM as follows:
  433. ;
  434. ; mov ebx, VMHandle ; current VM handle
  435. ; mov ecx, Tardiness ; number of milliseconds since time-out
  436. ; mov edx, RefData ; reference data
  437. ; mov ebp, OFFSET32 crs ; points to Client_Reg_Struc
  438. ; call [TimeOutCallback]
  439. ;
  440. ; Out:
  441. ;
  442. ; Notes:
  443. ;
  444. ;--------------------------------------------------------------------------;
  445. extrn _KeGrace_GlobalTimeOutProc:NEAR
  446. BeginProc _KeGrace_GlobalTimeOutProcAsm
  447. ; The reference data is a pointer to and EVENTPARAMS structure whose
  448. ; first member is the event handle and second member is the "this" pointer
  449. ; to the KeGrace object
  450. xor eax, eax
  451. xchg [edx], eax ; Clear the event handle
  452. Debug_OutEAXz "DSVXD: executing KeGrace_GlobalTimeOutProcAsm after cancelled!"
  453. or eax, eax
  454. jz @F
  455. pushad
  456. push ecx ; Pass tardiness
  457. push [edx + 4] ; Pass "this" to the "C" function
  458. Ccall _KeGrace_GlobalTimeOutProc
  459. add esp, 8
  460. popad
  461. @@:
  462. ret
  463. EndProc _KeGrace_GlobalTimeOutProcAsm
  464. ;--------------------------------------------------------------------------;
  465. ;
  466. ; _VMEvent_SetWin32Event
  467. ;
  468. ; This is a VM EventCallback scheduled by _AsyncTimeOut_SetWin32Event.
  469. ; This calls VWin32 to set a Win32 event.
  470. ;
  471. ; In:
  472. ; ebx = vm handle
  473. ; edi = thread handle
  474. ; edx = refdata = vxd handle to win32 event
  475. ; ebp = offset32 client reg struc
  476. ;
  477. ; Out:
  478. ;
  479. ; Notes:
  480. ; See _eventScheduleWin32Event
  481. ;
  482. ;--------------------------------------------------------------------------;
  483. BeginProc _VMEvent_SetWin32Event
  484. mov eax, edx
  485. VxDcall _VWIN32_SetWin32Event
  486. ret
  487. EndProc _VMEvent_SetWin32Event
  488. ;--------------------------------------------------------------------------;
  489. ;
  490. ; _AsyncTimeOut_SetWin32Event
  491. ;
  492. ; This is an async timeout callback set by _Set_SetWin32Event_TimeOut.
  493. ; This schedules _VMEvent_SetWin32Event as a sys vm event callback.
  494. ;
  495. ; In:
  496. ; ecx = tardiness
  497. ; edx = reference data = vxd handle to win32 event
  498. ;
  499. ; Out:
  500. ;
  501. ; Notes:
  502. ; See _eventScheduleWin32Event
  503. ;
  504. ;--------------------------------------------------------------------------;
  505. BeginProc _AsyncTimeOut_SetWin32Event
  506. push ebx
  507. push esi
  508. VMMcall Get_Sys_VM_Handle
  509. mov esi, _VMEvent_SetWin32Event
  510. VMMcall Schedule_VM_Event
  511. pop esi
  512. pop ebx
  513. ret
  514. EndProc _AsyncTimeOut_SetWin32Event
  515. ;--------------------------------------------------------------------------;
  516. ;
  517. ; _EventScheduleWin32Event
  518. ;
  519. ; This signals a win32 event after a specified delay.
  520. ;
  521. ; In:
  522. ; vxdhEvent - vxd handle to win32 event
  523. ; dwDelay - milliseconds delay
  524. ;
  525. ; Out(int):
  526. ; 0 if failure, non-0 otherwise
  527. ;
  528. ; Notes:
  529. ; Use 'C' calling convention. Sets an async timeout which in
  530. ; turn schedules a vm event to actually signal the win32 event.
  531. ;
  532. ;--------------------------------------------------------------------------;
  533. BeginProc _eventScheduleWin32Event
  534. ArgVar vxdhEvent,DWORD
  535. ArgVar dwDelay,DWORD
  536. EnterProc
  537. push ebx
  538. push esi
  539. mov eax, dwDelay
  540. test eax, eax
  541. jnz _ESW32E_delayed
  542. VMMcall Get_Sys_VM_Handle
  543. mov esi, _VMEvent_SetWin32Event
  544. mov edx, vxdhEvent
  545. Vmmcall Call_VM_Event
  546. mov eax, -1
  547. jmp _ESW32E_exit
  548. _ESW32E_delayed:
  549. Debug_Out "DSVXD: Tried to set a defered win32 event???"
  550. mov edx, vxdhEvent
  551. mov esi, _AsyncTimeOut_SetWin32Event
  552. VMMcall Set_Async_Time_Out
  553. mov eax, esi
  554. _ESW32E_exit:
  555. pop esi
  556. pop ebx
  557. LeaveProc
  558. Return
  559. EndProc _eventScheduleWin32Event
  560. VXD_LOCKED_CODE_ENDS
  561. END