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.

517 lines
12 KiB

  1. page ,132
  2. if 0
  3. /*++
  4. Copyright (c) 1991 Microsoft Corporation
  5. Module Name:
  6. nw16.asm
  7. Abstract:
  8. This module contains the stub redir TSR code for NT VDM net support
  9. Author:
  10. Richard L Firth (rfirth) 05-Sep-1991
  11. Colin Watson (colinw) 30-Jun-1993
  12. Environment:
  13. Dos mode only
  14. Revision History:
  15. 05-Sep-1991 rfirth
  16. Created
  17. 30-Jun-1993 colinw
  18. ported to NetWare
  19. --*/
  20. endif
  21. ;
  22. ; DOS include files
  23. ;
  24. .xlist
  25. .xcref
  26. include ..\..\..\..\public\sdk\inc\isvbop.inc ; NTVDM BOP mechanism
  27. include dossym.inc ; includes MS-DOS version etc
  28. include pdb.inc ; PSP defines
  29. include syscall.inc ; AssignOper
  30. include segorder.inc ; load order of 'redir' segments
  31. include debugmac.inc ; debug display macros
  32. include asmmacro.inc ; jumps which may be short or near
  33. include messages.inc
  34. include nwdos.inc ; NetWare structures and nwapi32 interface
  35. .cref
  36. .list
  37. ;
  38. ; Define externals in resident code and data
  39. ;
  40. ResidentCodeStart
  41. extrn Old21Handler:dword
  42. extrn NwInt21:near
  43. extrn hVDD:dword
  44. extrn quick_jump_to_dos:byte
  45. extrn for_dos_proper:byte
  46. extrn chain_previous_int21:byte
  47. extrn ConnectionIdTable:byte
  48. extrn not_exclusive:byte
  49. ResidentCodeEnd
  50. InitStack segment stack para 'stack'
  51. dw 256 dup (?)
  52. InitStack ends
  53. InitDataStart
  54. bad_ver_msg db NLS_MSG_001,c_CR,c_LF
  55. BAD_VER_MSG_LEN equ $-bad_ver_msg
  56. db '$' ; for INT 21/09 display string
  57. already_loaded_msg db NLS_MSG_004,c_CR,c_LF
  58. ALREADY_LOADED_MSG_LEN equ $-already_loaded_msg
  59. cannot_load_msg db NLS_MSG_005,c_CR, c_LF
  60. CANNOT_LOAD_MSG_LEN equ $-cannot_load_msg
  61. InitDataEnd
  62. InitCodeStart
  63. assume cs:InitCode
  64. assume ds:nothing
  65. assume es:nothing
  66. assume ss:nothing
  67. public DllName
  68. DllName db "NWAPI16.DLL",0
  69. public InitFunc
  70. InitFunc db "Nw16Register",0
  71. public DispFunc
  72. DispFunc db "Nw16Handler",0
  73. public start
  74. start proc near
  75. ;
  76. ; when we start up we could be on any old PC - even an original, so don't
  77. ; assume anything other than a model-T processor
  78. ;
  79. .8086
  80. ;
  81. ; Set the data segment while we're at it - all paths set it sooner
  82. ; or later. NOTE: es will point to the PSP until we change it!
  83. ;
  84. mov dx,InitData
  85. mov ds,dx
  86. assume ds:InitData
  87. ;
  88. ; first off, get the DOS version. If we're not running on NT (VDM) then this
  89. ; TSR's not going to do much, so exit. Exit using various methods, depending
  90. ; on the DOS version (don't you hate compatibility?)
  91. ;
  92. mov ah,30h
  93. int 21h
  94. jc ancient_version ; version not even supported
  95. ;
  96. ; version is 2.0 or higher. Check it out. al = major#, ah = minor#
  97. ;
  98. cmp al,major_version
  99. jne invalid_version
  100. ;
  101. ; what do you know? We're actually running on NT (unless some evil programmer
  102. ; has pinched int 21h/30h and broken it!). Enable minimum instruction set
  103. ; for NTVDM (286 on RISC).
  104. ;
  105. .286c
  106. ;
  107. ; perform an installation check by calling one of our entry points
  108. ; (GetFileServerNameTable). If this returns a table pointer in ES:DI then we
  109. ; know this TSR is already active, in which case we bail out now
  110. ;
  111. push es
  112. push di
  113. xor di,di
  114. mov es,di
  115. mov ax,0ef03h
  116. int 21h
  117. mov ax,es
  118. or ax,di
  119. pop di
  120. pop es
  121. jnz already_here
  122. ;
  123. ; OK, the NetWare redir is not already loaded - we're in business.
  124. ; Find entrypoints to nwapi16.dll Get and set the various interrupt
  125. ; vectors, Calculate the amount of space we want to keep,
  126. ; free up any unused space (like the environment segment), display a message
  127. ; in the DEBUG version, then terminate and stay resident. Remember: at this
  128. ; point we expect ES to point at the PSP
  129. ;
  130. call PullInDll
  131. jc already_here ; failed to load
  132. call InstallInterruptHandlers
  133. assume es:nothing
  134. push es
  135. pop ds
  136. call is_c_on_command_line
  137. jz @f
  138. mov dx,ResidentCode
  139. mov ds,dx
  140. assume ds:ResidentCode
  141. mov not_exclusive, 1
  142. assume ds:nothing
  143. @@:
  144. ;
  145. ; free the environment segment
  146. ;
  147. mov es,es:[PDB_environ]
  148. mov ah,49h
  149. int 21h ; free environment segment
  150. ;if DEBUG
  151. ;ifdef VERBOSE
  152. ; DbgPrintString <"NetWare Redir successfully loaded",13,10>
  153. ;endif
  154. ;endif
  155. ;
  156. ; finally terminate and stay resident
  157. ;
  158. mov dx,ResidentEnd
  159. sub dx,ResidentStart ; number of paragraphs in resident code
  160. add dx,10h ; additional for PSP (PDB)
  161. ;if DEBUG
  162. ;ifdef VERBOSE
  163. ; DbgPrintString "Staying resident with "
  164. ; DbgPrintHexWord dx
  165. ; DbgPrintString " paragraphs. Load seg is ",NOBANNER
  166. ; mov ah,62h
  167. ; int 21h
  168. ; DbgPrintHexWord bx
  169. ; DbgPrintString " current seg is ",NOBANNER
  170. ; DbgPrintHexWord cs
  171. ; DbgCrLf
  172. ;endif
  173. ;endif
  174. mov ax,3100h
  175. int 21h ; terminate and stay resident
  176. ;
  177. ; here if the MS-DOS version check (Ah=30h) call is not supported
  178. ;
  179. ancient_version:
  180. mov dx,InitData
  181. mov ds,dx
  182. assume ds:InitData
  183. mov dx,offset bad_ver_msg
  184. mov ah,9 ; cp/m-style write to output
  185. int 21h
  186. ;
  187. ; safe exit: what we really want to do here is INT 20H, but when you do this,
  188. ; CS must be the segment of the PSP of this program. Knowing that CD 20 is
  189. ; embedded at the start of the PSP, the most foolproof way of doing this is
  190. ; to jump (using far return) to the start of the PSP
  191. ;
  192. push es
  193. xor ax,ax
  194. push ax
  195. retf ; terminate
  196. ;
  197. ; we are running on a version of DOS >= 2.00, but its not NT, so we still can't
  198. ; help. Display the familiar message and exit, but using a less programmer-
  199. ; hostile mechanism
  200. ;
  201. invalid_version:
  202. mov dx,offset bad_ver_msg
  203. mov cx,BAD_VER_MSG_LEN
  204. jmps print_error_message_and_exit
  205. ;
  206. ; if we cannot initialize 32-bit support (because we can't find/load the DLL)
  207. ; then put back the hooked interrupt vectors as they were when this TSR started,
  208. ; display a message and fail to load the redir TSR
  209. ;
  210. initialization_error:
  211. call RestoreInterruptHandlers
  212. mov dx,offset cannot_load_msg
  213. mov cx,CANNOT_LOAD_MSG_LEN
  214. jmps print_error_message_and_exit
  215. ;
  216. ; The DOS version's OK, but this TSR is already loaded
  217. ;
  218. already_here:
  219. mov dx,offset already_loaded_msg
  220. mov cx,ALREADY_LOADED_MSG_LEN
  221. print_error_message_and_exit:
  222. mov bx,1 ; bx = stdout handle
  223. mov ah,40h ; write to handle
  224. int 21h ; write (cx) bytes @ (ds:dx) to stdout
  225. mov ax,4c01h ; terminate program
  226. int 21h ; au revoir, cruel environment
  227. start endp
  228. ;*******************************************************************************
  229. ;*
  230. ;* InstallInterruptHandlers
  231. ;*
  232. ;* Sets the interrupt handlers for all the ints we use - 21
  233. ;*
  234. ;* ENTRY es = PSP segment
  235. ;* ds =
  236. ;*
  237. ;* EXIT Old21Handler contains the original interrupt 21 vector
  238. ;*
  239. ;* RETURNS nothing
  240. ;*
  241. ;* ASSUMES
  242. ;*
  243. ;*******************************************************************************
  244. InstallInterruptHandlers proc
  245. push es ; PSP segment - destroyed by INT 21/35h
  246. push ds
  247. ;
  248. ; note: if we use ResidentCode here, explicitly, instead of seg OldMultHandler,
  249. ; then we can leave out an extraneous load of ds for the ISR address
  250. ;
  251. mov dx,ResidentCode
  252. mov ds,dx
  253. assume ds:ResidentCode
  254. ;
  255. ; Add ourselves to the int 21 chain
  256. ;
  257. mov ax,3521h
  258. int 21h
  259. mov word ptr Old21Handler,bx
  260. mov word ptr Old21Handler+2,es
  261. mov word ptr quick_jump_to_dos+1,bx
  262. mov word ptr quick_jump_to_dos+3,es
  263. mov word ptr for_dos_proper+1,bx
  264. mov word ptr for_dos_proper+3,es
  265. mov word ptr chain_previous_int21+1,bx
  266. mov word ptr chain_previous_int21+3,es
  267. mov dx,offset ResidentCode:NwInt21
  268. mov ax,2521h
  269. int 21h
  270. pop ds ; restore segment registers
  271. pop es
  272. ret
  273. InstallInterruptHandlers endp
  274. ;*******************************************************************************
  275. ;*
  276. ;* RestoreInterruptHandlers
  277. ;*
  278. ;* Resets the interrupt handlers for all the ints we use - 21
  279. ;*
  280. ;* ENTRY Old21Handler
  281. ;* contain the interrupt vectors from before nw16.sys was loaded
  282. ;*
  283. ;* EXIT Original interrupt vectors are restored
  284. ;*
  285. ;* RETURNS nothing
  286. ;*
  287. ;* ASSUMES
  288. ;*
  289. ;*******************************************************************************
  290. RestoreInterruptHandlers proc
  291. push ds
  292. assume ds:nothing
  293. push es
  294. mov dx,ResidentCode
  295. mov es,dx
  296. assume es:ResidentCode
  297. lds dx,Old21Handler
  298. mov ax,2521h
  299. int 21h
  300. pop es
  301. pop ds
  302. ret
  303. RestoreInterruptHandlers endp
  304. ;*******************************************************************************
  305. ;*
  306. ;* PullInDll
  307. ;*
  308. ;* Does a RegisterModule to load NWAPI32.DLL into our NTVDM.EXE
  309. ;*
  310. ;* ENTRY nothing
  311. ;*
  312. ;* EXIT nothing
  313. ;*
  314. ;* RETURNS cf if fails.
  315. ;*
  316. ;* ASSUMES Earth moves round Sun
  317. ;*
  318. ;******************************************************************************/
  319. PullInDll proc near
  320. pusha ; dispatch code
  321. push dx ; save callers dx,ds,es,ax
  322. push ds
  323. push es
  324. push ax
  325. mov dx,InitCode
  326. mov ds,dx
  327. assume ds:InitCode
  328. push ds
  329. pop es
  330. assume es:InitCode
  331. mov si,offset DllName ; ds:si = nwapi32.dll
  332. mov di,offset InitFunc ; es:di = init routine
  333. mov bx,offset DispFunc ; ds:bx = dispatch routine
  334. mov ax,ResidentCode
  335. mov dx,offset ConnectionIdTable
  336. ; ax:dx = shared datastructure
  337. RegisterModule
  338. jc @f
  339. mov dx,ResidentCode
  340. mov ds,dx
  341. assume ds:ResidentCode
  342. mov word ptr hVDD,ax
  343. @@: pop ax ; callers ax
  344. pop es ; callers es
  345. pop ds ; callers ds
  346. pop dx ; callers dx
  347. assume ds:nothing
  348. assume es:nothing
  349. popa ; dispatch code
  350. ret
  351. PullInDll endp
  352. ;*******************************************************************************
  353. ;*
  354. ;* is_c_on_command_line
  355. ;*
  356. ;* -C or /C means we should open compatiblity mode createfiles as shared
  357. ;* instead of exclusive
  358. ;*
  359. ;* ENTRY ds points to PDB
  360. ;*
  361. ;* EXIT nothing
  362. ;*
  363. ;* RETURNS zero if not found.
  364. ;*
  365. ;* ASSUMES ds points at PSP
  366. ;*
  367. ;******************************************************************************/
  368. is_c_on_command_line proc near
  369. mov si,80h
  370. lodsb
  371. cbw
  372. mov cx,ax
  373. next: jcxz quit
  374. dec cx
  375. lodsb
  376. check_next:
  377. cmp al,'-'
  378. je check_c
  379. cmp al,'/'
  380. je check_c
  381. cmp al,' '
  382. je next
  383. cmp al,9
  384. je next
  385. find_ws:jcxz quit
  386. dec cx
  387. lodsb
  388. cmp al,' '
  389. je next
  390. cmp al,9
  391. je next
  392. jmp short find_ws
  393. check_c:jcxz quit
  394. dec cx
  395. lodsb
  396. or al,20h
  397. cmp al,'c'
  398. jne find_ws
  399. or cx,ax
  400. quit: or cx,cx
  401. ret
  402. is_c_on_command_line endp
  403. InitCodeEnd
  404. end start