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.

527 lines
14 KiB

  1. ;****************************************************************************
  2. ; *
  3. ; THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY *
  4. ; KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
  5. ; IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR *
  6. ; PURPOSE. *
  7. ; *
  8. ; Copyright (C) 1993-95 Microsoft Corporation. All Rights Reserved. *
  9. ; *
  10. ;****************************************************************************
  11. PAGE 58,132
  12. ;******************************************************************************
  13. TITLE GENERIC - Generic VxD
  14. ;******************************************************************************
  15. ;
  16. ; Title: GENERIC.ASM - Generic VxD
  17. ;
  18. ; Version: 1.00
  19. ;
  20. ;==============================================================================
  21. .386p
  22. ;******************************************************************************
  23. ; I N C L U D E S
  24. ;******************************************************************************
  25. DDK_VERSION EQU 400H
  26. .XLIST
  27. INCLUDE VMM.Inc
  28. INCLUDE Debug.Inc
  29. .LIST
  30. ;******************************************************************************
  31. ; V I R T U A L D E V I C E D E C L A R A T I O N
  32. ;------------------------------------------------------------------------------
  33. ; The VxD declaration statement defines the VxD name, version number,
  34. ; control proc entry point, VxD ID, initialization order, and VM API
  35. ; entry points. What follows is a minimal VxD declaration, defining
  36. ; only the name, version, control proc, and an undefined ID. Depending
  37. ; on the requirements of the VxD, the following may be added:
  38. ;
  39. ; - Defined VxD ID: See VXDID.TXT for more information
  40. ; - Init order: If your Vxd MUST load before or after a specific VxD,
  41. ; the init order can be defined. See VMM.INC for the
  42. ; definition of the init order of the standard devices.
  43. ; - V86,PM API: You may wish to allow application or library code running
  44. ; in a virtual machine to communicate with your VxD directly.
  45. ; See the chapter entitled "VxD APIs (Call-Ins)" in the
  46. ; Virtual Device Adaptation Guide.
  47. ;
  48. ;******************************************************************************
  49. Declare_Virtual_Device PCMVXD, 1, 0, VXD_Control, 77h, \
  50. Undefined_Init_Order,GENERIC_PM_API,GENERIC_PM_API
  51. ;******************************************************************************
  52. ; D A T A
  53. ;******************************************************************************
  54. VxD_IDATA_SEG
  55. ; Initialization data here - discarded after Init_Complete
  56. VxD_IDATA_ENDS
  57. VxD_DATA_SEG
  58. ; Normal Data here
  59. PM_API_Table label DWORD
  60. dd OFFSET32 PM_GetVersion
  61. dd OFFSET32 PM_OpenPin
  62. dd OFFSET32 PM_ClosePin
  63. dd OFFSET32 PM_Write
  64. CallbackSeg dw 0
  65. CallbackOff dw 0
  66. CallbackRef dd 0
  67. EXTRN _OpenPin:near
  68. EXTRN _ClosePin:near
  69. EXTRN _WritePin:near
  70. VxD_DATA_ENDS
  71. write_context STRUC
  72. WH_Data DD ?
  73. WH_BufferLength DD ?
  74. WH_BytesRecorded DD ?
  75. WH_User DD ?
  76. WH_Flags DD ?
  77. WH_Loops DD ?
  78. WH_Next DD ?
  79. WH_reserved DD ?
  80. WC_ClientContext DD ?
  81. WC_CallbackOffset DW ?
  82. WC_CallbackSegment DW ?
  83. WC_ClientThread DD ?
  84. WC_Reserved DD ?
  85. write_context ENDS
  86. VxD_LOCKED_DATA_SEG
  87. ; Pagelocked data here - try to keep this to a minimum.
  88. VxD_LOCKED_DATA_ENDS
  89. ;******************************************************************************
  90. ; I N I T I A L I Z A T I O N C O D E
  91. ;------------------------------------------------------------------------------
  92. ; Code in the initialization segment is discarded after Init_Complete
  93. ;******************************************************************************
  94. VxD_ICODE_SEG
  95. ;******************************************************************************
  96. ;
  97. ; VXD_Device_Init
  98. ;
  99. ; DESCRIPTION:
  100. ; This is a shell for a routine that is called at system BOOT.
  101. ; Typically, a VxD would do its initialization in this routine.
  102. ;
  103. ; ENTRY:
  104. ; EBX = System VM handle
  105. ;
  106. ; EXIT:
  107. ; Carry clear to indicate load success
  108. ; Carry set to abort loading this VxD
  109. ;
  110. ; USES:
  111. ; flags
  112. ;
  113. ;==============================================================================
  114. BeginProc VXD_Device_Init
  115. clc ;no error - load VxD
  116. ret
  117. EndProc VXD_Device_Init
  118. VxD_ICODE_ENDS
  119. ;******************************************************************************
  120. ; C O D E
  121. ;------------------------------------------------------------------------------
  122. ; The 'body' of the VxD would typically be in the standard code segment.
  123. ;******************************************************************************
  124. VxD_CODE_SEG
  125. ;******************************************************************************
  126. ;
  127. ; VXD_Create_VM
  128. ;
  129. ; DESCRIPTION:
  130. ; This is a shell for a routine that is called when a virtual
  131. ; machine is created. A typical VxD might perform some action
  132. ; here to prepare for handling the new VM in the system.
  133. ;
  134. ; ENTRY:
  135. ; EBX = VM handle
  136. ;
  137. ; EXIT:
  138. ; Carry clear to continue creating VM
  139. ; Carry set to abort the creation of the VM
  140. ;
  141. ; USES:
  142. ; flags
  143. ;
  144. ;==============================================================================
  145. BeginProc VXD_Create_VM
  146. clc ;no error - continue
  147. ret
  148. EndProc VXD_Create_VM
  149. ;******************************************************************************
  150. ;
  151. ;
  152. ; Description:
  153. ;
  154. ; Entry:
  155. ; Exit:
  156. ; Uses:
  157. ;==============================================================================
  158. BeginProc GENERIC_PM_API,PUBLIC
  159. movzx eax,[ebp.Client_AX] ; get function code
  160. cmp eax,PM_Write
  161. ja VPA_Failed
  162. jmp dword ptr PM_API_Table[eax*4]
  163. VPA_Failed:
  164. mov [ebp.Client_AX],0
  165. ret
  166. EndProc GENERIC_PM_API
  167. ;******************************************************************************
  168. ;
  169. ;
  170. ; Description:
  171. ;
  172. ; Entry:
  173. ;
  174. ; Exit:
  175. ; Uses:
  176. ;==============================================================================
  177. BeginProc PM_GetVersion,PUBLIC
  178. int 3
  179. ret
  180. EndProc PM_GetVersion
  181. ;******************************************************************************
  182. ;
  183. ;
  184. ; Description:
  185. ;
  186. ; Entry:
  187. ;
  188. ; Exit:
  189. ; Uses:
  190. ;==============================================================================
  191. BeginProc PM_OpenPin,CCALL,PUBLIC
  192. cCall _OpenPin
  193. ret
  194. EndProc PM_OpenPin
  195. ;******************************************************************************
  196. ;
  197. ;
  198. ; Description:
  199. ;
  200. ; Entry:
  201. ;
  202. ; Exit:
  203. ; Uses:
  204. ;==============================================================================
  205. BeginProc PM_ClosePin,PUBLIC
  206. cCall _ClosePin
  207. ret
  208. EndProc PM_ClosePin
  209. ;******************************************************************************
  210. ;
  211. ;
  212. ; Description:
  213. ;
  214. ; Entry:
  215. ;
  216. ; Exit:
  217. ; Uses:
  218. ;==============================================================================
  219. BeginProc PM_Write,PUBLIC
  220. ; DS:SI is ptr to WaveHdr
  221. ; ES:DI is callback for completion (do callback with DS:SI as context)
  222. ; Allocate space to store our write context
  223. VMMcall _HeapAllocate, <(SIZE write_context), 0>
  224. or eax, eax ; zero if error
  225. jz error
  226. ; Remember our write context pointer (we pop it three times below)
  227. push eax
  228. push eax
  229. push eax
  230. ; Store a pointer to the callback routine
  231. mov cx, [ebp.Client_ES]
  232. mov [eax.WC_CallbackSegment],cx
  233. mov cx, [ebp.Client_DI]
  234. mov [eax.WC_CallbackOffset],cx
  235. ; Store the client's context (for use during callback)
  236. mov cx, [ebp.Client_DS]
  237. mov WORD PTR [eax.WC_ClientContext + 2],cx
  238. mov cx, [ebp.Client_SI]
  239. mov WORD PTR [eax.WC_ClientContext],cx
  240. VMMCall Get_Cur_Thread_Handle ; returned in edi
  241. mov [eax.WC_ClientThread], edi
  242. ; Convert the WaveHdr pointer to a flat address
  243. Client_Ptr_Flat esi, DS, SI
  244. ; Copy the WaveHdr structure from the client to our WaveHdr
  245. mov ecx, 32
  246. pop edi
  247. cld
  248. rep movsb
  249. ; Get the current VM (returned in EBX)
  250. VMMcall Get_Cur_VM_Handle
  251. ; Map the Wave data selector to its flat base address
  252. pop eax
  253. movzx ecx, WORD PTR [eax + 2]
  254. VMMcall _SelectorMapFlat, <ebx, ecx, 0>
  255. pop ecx ; get back write context ptr
  256. cmp eax, 0FFFFFFFFh ; 0FFFFFFFFh if error
  257. je error
  258. ; Munge the user-mode address of our data
  259. movzx ebx, WORD PTR [ecx.WH_Data]
  260. add eax, ebx
  261. mov [ecx.WH_Data], eax
  262. mov eax, OFFSET32 PM_Callback
  263. cCall _WritePin, <ecx, eax, ecx>
  264. error:
  265. ret
  266. EndProc PM_Write
  267. ;******************************************************************************
  268. ;
  269. ;
  270. ; Description:
  271. ;
  272. ; Entry:
  273. ;
  274. ; Exit:
  275. ; Uses:
  276. ;==============================================================================
  277. BeginProc PM_ScheduledCallback,PUBLIC
  278. ; ebx VMHandle
  279. ; edi ThreadHandle
  280. ; edx RefData
  281. ; ebp OFFSET32 Client_Reg_Struc
  282. push edx
  283. Push_Client_State ; does VMMCall Save_Client_State
  284. VMMCall Begin_Nest_Exec ; or Begin_Nest_V86_Exec
  285. ; edx holds our write context
  286. mov ax, WORD PTR [edx.WC_ClientContext]
  287. mov [ebp.Client_SI], ax
  288. mov ax, WORD PTR [edx.WC_ClientContext + 2]
  289. mov [ebp.Client_DS], ax
  290. mov eax, edx
  291. mov cx, [eax.WC_CallbackSegment]
  292. movzx edx, [eax.WC_CallbackOffset]
  293. VMMCall Simulate_Far_Call ; set up CX:EDX as CS:EIP to call
  294. VMMCall Resume_Exec ; do it!
  295. VMMCall End_Nest_Exec
  296. Pop_Client_State ; does VMMCall Restore_Client_State
  297. pop edx
  298. VMMcall _HeapFree, <edx, 0>
  299. ret
  300. EndProc PM_ScheduledCallback
  301. ;******************************************************************************
  302. ;
  303. ;
  304. ; Description:
  305. ;
  306. ; Entry:
  307. ;
  308. ; Exit:
  309. ; Uses:
  310. ;==============================================================================
  311. BeginProc PM_Callback,CCALL,PUBLIC
  312. ArgVar DevObject,DWORD
  313. ArgVar pIrp,DWORD
  314. ArgVar Context,DWORD
  315. EnterProc
  316. SaveReg <esi, edi>
  317. mov eax, Context
  318. mov ebx, [eax.WC_ClientThread]
  319. mov ecx, (PEF_Thread_Event)
  320. ; OR PEF_Wait_Not_Nested_Exec)
  321. mov edx, Context
  322. mov esi, OFFSET32 PM_ScheduledCallback
  323. mov edi, 0
  324. mov eax, 0 ; no priority boost
  325. VMMcall Call_Restricted_Event
  326. RestoreReg <edi, esi>
  327. LeaveProc
  328. xor eax, eax
  329. ret 12
  330. EndProc PM_Callback
  331. VxD_CODE_ENDS
  332. ;******************************************************************************
  333. ; P A G E L O C K E D C O D E
  334. ;------------------------------------------------------------------------------
  335. ; Memory is a scarce resource. Use this only where necessary.
  336. ;******************************************************************************
  337. VxD_LOCKED_CODE_SEG
  338. ;******************************************************************************
  339. ;
  340. ; VXD_Control
  341. ;
  342. ; DESCRIPTION:
  343. ;
  344. ; This is a call-back routine to handle the messages that are sent
  345. ; to VxD's to control system operation. Every VxD needs this function
  346. ; regardless if messages are processed or not. The control proc must
  347. ; be in the LOCKED code segment.
  348. ;
  349. ; The Control_Dispatch macro used in this procedure simplifies
  350. ; the handling of messages. To handle a particular message, add
  351. ; a Control_Dispatch statement with the message name, followed
  352. ; by the procedure that should handle the message.
  353. ;
  354. ; The two messages handled in this sample control proc, Device_Init
  355. ; and Create_VM, are done only to illustrate how messages are
  356. ; typically handled by a VxD. A VxD is not required to handle any
  357. ; messages.
  358. ;
  359. ; ENTRY:
  360. ; EAX = Message number
  361. ; EBX = VM Handle
  362. ;
  363. ;==============================================================================
  364. BeginProc VXD_Control
  365. Control_Dispatch Device_Init, VXD_Device_Init
  366. Control_Dispatch Create_VM, VXD_Create_VM
  367. clc
  368. ret
  369. EndProc VXD_Control
  370. VxD_LOCKED_CODE_ENDS
  371. ;******************************************************************************
  372. ; R E A L M O D E C O D E
  373. ;******************************************************************************
  374. ;******************************************************************************
  375. ;
  376. ; Real mode initialization code
  377. ;
  378. ; DESCRIPTION:
  379. ; This code is called when the system is still in real mode, and
  380. ; the VxDs are being loaded.
  381. ;
  382. ; This routine as coded shows how a VxD (with a defined VxD ID)
  383. ; could check to see if it was being loaded twice, and abort the
  384. ; second without an error message. Note that this would require
  385. ; that the VxD have an ID other than Undefined_Device_ID. See
  386. ; the file VXDID.TXT more details.
  387. ;
  388. ; ENTRY:
  389. ; AX = VMM Version
  390. ; BX = Flags
  391. ; Bit 0: duplicate device ID already loaded
  392. ; Bit 1: duplicate ID was from the INT 2F device list
  393. ; Bit 2: this device is from the INT 2F device list
  394. ; EDX = Reference data from INT 2F response, or 0
  395. ; SI = Environment segment, passed from MS-DOS
  396. ;
  397. ; EXIT:
  398. ; BX = ptr to list of pages to exclude (0, if none)
  399. ; SI = ptr to list of instance data items (0, if none)
  400. ; EDX = DWORD of reference data to be passed to protect mode init
  401. ;
  402. ;==============================================================================
  403. VxD_REAL_INIT_SEG
  404. BeginProc VxD_Real_Init_Proc
  405. test bx, Duplicate_Device_ID ; check for already loaded
  406. jnz short duplicate ; jump if so
  407. xor bx, bx ; no exclusion table
  408. xor si, si ; no instance data table
  409. xor edx, edx ; no reference data
  410. mov ax, Device_Load_Ok
  411. ret
  412. duplicate:
  413. mov ax, Abort_Device_Load + No_Fail_Message
  414. ret
  415. EndProc VxD_Real_Init_Proc
  416. VxD_REAL_INIT_ENDS
  417. END