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.

1039 lines
26 KiB

  1. page ,132
  2. if 0
  3. /*++
  4. Copyright (c) 1993-4 Microsoft Corporation
  5. Module Name:
  6. resident.asm
  7. Abstract:
  8. This module contains the resident code part of the stub redir TSR for NT
  9. VDM NetWare support.
  10. Author:
  11. Colin Watson (colinw) 08-Jul-1993
  12. Environment:
  13. Dos mode only
  14. Revision History:
  15. 08-Jul-1993 colinw
  16. Created
  17. --*/
  18. endif
  19. .xlist ; don't list these include files
  20. .xcref ; turn off cross-reference listing
  21. include ..\..\..\..\public\sdk\inc\isvbop.inc ; NTVDM BOP mechanism
  22. include dosmac.inc ; Break macro etc (for following include files only)
  23. include dossym.inc ; User_<Reg> defines
  24. include segorder.inc ; segments
  25. include mult.inc ; MultNET
  26. include sf.inc ; SFT definitions/structure
  27. include pdb.inc ; program header/process data block structure
  28. include debugmac.inc ; DbgPrint macro
  29. include asmmacro.inc ; language extensions
  30. include nwdos.inc ; NetWare structures and nwapi32 interface
  31. .cref ; switch cross-reference back on
  32. .list ; switch listing back on
  33. subttl ; kill subtitling started in include file
  34. .286 ; all code in this module 286 compatible
  35. far_segment segment
  36. far_label label far
  37. far_segment ends
  38. ResidentCodeStart
  39. assume cs:ResidentCode
  40. assume ds:nothing
  41. assume es:nothing
  42. assume ss:nothing
  43. public Old21Handler
  44. Old21Handler dd ?
  45. ;
  46. ; IMPORTANT: the following up to the comment <END NWDOSTABLE> must
  47. ; be kept in the same order as for the NWDOSTABLE structure in NWDOS.H/.INC.
  48. ; Align on 32 bits to make it convenient for nwapi32.dll
  49. ;
  50. align 4
  51. public ConnectionIdTable
  52. ConnectionIdTable CID MC dup (<>)
  53. public ServerNameTable
  54. ServerNameTable db MC * SERVERNAME_LENGTH dup (0)
  55. public DriveIdTable
  56. DriveIdTable db MD dup (0)
  57. public DriveFlagTable
  58. DriveFlagTable db MD dup (0)
  59. public DriveHandleTable
  60. DriveHandleTable db MD dup (0)
  61. public PreferredServer
  62. PreferredServer db 0
  63. public PrimaryServer
  64. PrimaryServer db 0
  65. public TaskModeByte
  66. TaskModeByte db 0
  67. CurrentDrive db 0
  68. public SavedAx;
  69. SavedAx dw 0
  70. public NtHandleHi;
  71. NtHandleHi dw 0
  72. public NtHandleLow;
  73. NtHandleLow dw 0
  74. public NtHandleSrcHi; // Used in FileServerCopy
  75. NtHandleSrcHi dw 0
  76. public NtHandleSrcLow;
  77. NtHandleSrcLow dw 0
  78. public hVDD
  79. hVDD dw -1
  80. public PmSelector
  81. PmSelector dw 0
  82. public CreatedJob
  83. CreatedJob db 0
  84. public JobHandle
  85. JobHandle db 0
  86. NOV_BUFFER_LENGTH equ 256
  87. public DenovellBuffer
  88. DenovellBuffer db NOV_BUFFER_LENGTH dup (?)
  89. public DenovellBuffer2
  90. DenovellBuffer2 db NOV_BUFFER_LENGTH dup (?)
  91. .errnz (size DeNovellBuffer2 - size DenovellBuffer)
  92. Comspec db "COMSPEC="
  93. COMSPEC_LENGTH equ ($ - Comspec)
  94. ;
  95. ; this is the <END NWDOSTABLE> structure.
  96. ;
  97. ;
  98. ; data passed from nw16.asm
  99. ;
  100. public not_exclusive
  101. not_exclusive db 0
  102. page
  103. public NwInt21
  104. NwInt21 proc far
  105. assume cs:ResidentCode
  106. assume ds:nothing
  107. assume es:nothing
  108. assume ss:nothing
  109. sti ; make sure ints are still enabled
  110. ;
  111. ; check whether we filter this vector; if not, pass it through to previous INT 21
  112. ; handler (DOS or some other TSR)
  113. ;
  114. ; If this is a name based operation, and the caller is passing through a novell
  115. ; format name - SYS:FOO or SERVER\SYS:FOO - then munge the name to be a UNC name
  116. ;
  117. cmp ah,0eh
  118. jne @f
  119. jmp select_default_drive
  120. @@: cmp ah,39h ; create directory
  121. je check_name
  122. ja @f
  123. ;
  124. ; ah less than 39h (mkdir) is definitely for DOS
  125. ;
  126. public quick_jump_to_dos
  127. quick_jump_to_dos:
  128. jmp far_label
  129. ;
  130. ; run any of the following name-based calls through the name check:
  131. ;
  132. ; 3ah remove directory
  133. ; 3bh change directory
  134. ; 3ch create file
  135. ; 3dh open file
  136. ; 41h delete file
  137. ; 43h get/set attributes
  138. ; 4bh exec program
  139. ; 4eh find first file
  140. ; 56h rename
  141. ;
  142. @@: cmp ah,3dh
  143. jbe check_name
  144. cmp ah,41h ; delete file
  145. je check_name
  146. cmp ah,43h ; get/set attributes
  147. je check_name
  148. cmp ah,4bh ; exec program
  149. je check_name
  150. cmp ah,4eh ; find first file
  151. je check_name
  152. cmp ah,56h ; rename
  153. je rename
  154. jmp dispatch_check
  155. ;
  156. ; Rename function. This has 2 path names: source in ds:dx and
  157. ; destination in es:di. Check the destination first then fall through
  158. ; and check the source.
  159. ;
  160. rename:
  161. push ds
  162. push dx
  163. push es
  164. push di ; user registers saved for after Int21
  165. push ds ; save ds:dx 'cause we will corrupt them
  166. push dx
  167. mov dx,es
  168. mov ds,dx
  169. mov dx,di ; ds:dx = destination buffer
  170. call IsDosPath
  171. je @f ; DOS path, no modification
  172. cld
  173. push di
  174. call DenovellizeName
  175. pop di
  176. cmp dx,offset DenovellBuffer
  177. je swap_buffers
  178. @@:
  179. pop dx ; ds:dx points at source again
  180. pop ds
  181. pop di
  182. pop es
  183. pop dx
  184. pop ds
  185. jmp check_name
  186. ;
  187. ; Destination name was normalized and stored in DeNovellBuffer. put the data
  188. ; in Denovellbuffer2 in-case we need to put the Source name in Denovellbuffer
  189. ;
  190. swap_buffers:
  191. push cx
  192. push si
  193. push ds ; will become es during Dos call
  194. mov si,dx
  195. mov di,cs
  196. mov es,di
  197. mov di,offset DenovellBuffer2
  198. mov cx,NOV_BUFFER_LENGTH / 2
  199. .errnz (NOV_BUFFER_LENGTH and 1)
  200. rep movsw
  201. mov di,offset DenovellBuffer2
  202. pop es ; es:di is now Denovellbuffer2
  203. pop si
  204. pop cx
  205. pop dx ; make ds:dx source again
  206. pop ds
  207. ; stack has users di,es,dx,ds pushed
  208. ; parameters are same as callers except for es:di
  209. jmp check_src
  210. check_name: ; ds:dx points at name to examine
  211. push ds
  212. push dx
  213. push es
  214. push di
  215. ; fall through
  216. check_src: ; only jumped to in rename
  217. cld
  218. call IsDosPath
  219. je for_dos_properR ; x: or UNC filename. No more processing
  220. cmp ah,3dh
  221. jne notNETQ ; special NETQ open only applies for create
  222. cmp CreatedJob,0
  223. jz notNETQ ; don't look at name if no job handle available
  224. push ax
  225. push si
  226. mov si,dx
  227. cld
  228. lodsw
  229. cmp ax,"EN"
  230. jne @f
  231. lodsw
  232. cmp ax,"QT"
  233. jne @f
  234. lodsb
  235. or al,al
  236. jnz @f
  237. pop si ; Opening NETQ. Return Dos handle from CreateJob and File
  238. pop ax
  239. mov CreatedJob,0 ; Only return handle once
  240. mov al, JobHandle
  241. xor ah, ah
  242. pop di
  243. pop es
  244. pop dx
  245. pop ds
  246. clc
  247. retf 2
  248. @@: pop si
  249. pop ax
  250. jmp for_dos_properR
  251. notNETQ:push di
  252. call DenovellizeName ; munge the name if required
  253. pop di ; restore caller DI
  254. ;
  255. ; Look for compatibility mode opens that need to change to exlusive mode
  256. ; opens so that they get properly cached. Criteria for opening exclusive
  257. ; is that the application did not specify any sharing modes and the drive
  258. ; being opened is on a netware drive.
  259. ;
  260. cmp ah, 3ch
  261. je @f
  262. cmp ah, 3dh
  263. jne not_compat
  264. @@: test al,OF_SHARE_MASK
  265. jne not_compat
  266. cmp not_exclusive, 1 ; open shared mode anyway
  267. je not_compat
  268. mov SavedAx,ax
  269. mov ax,hVdd
  270. DispatchCall ; 32 bit code decides if compat mode
  271. not_compat:
  272. pushf
  273. call Old21Handler ; fake int 21 to get to DOS
  274. pop di
  275. pop es
  276. pop dx
  277. pop ds
  278. retf 2 ; return to app (with flags from DOS)
  279. for_dos_properR: ; restore regs and call dos
  280. pop di
  281. pop es
  282. pop dx
  283. pop ds
  284. cmp ah, 3ch
  285. je @f
  286. cmp ah, 3dh
  287. jne for_dos_proper
  288. @@: test al,OF_SHARE_MASK
  289. jne for_dos_proper
  290. cmp not_exclusive, 1 ; open shared mode anyway
  291. je for_dos_proper
  292. mov SavedAx,ax
  293. mov ax,hVdd
  294. @@: DispatchCall ; 32 bit code decides if compat mode
  295. public for_dos_proper
  296. for_dos_proper:
  297. jmp far_label
  298. dispatch_check:
  299. cmp ah,04ch
  300. jne check_9f
  301. jmp process_exit
  302. ;
  303. ; 'special' entry point to return the data segment info to the protect-mode code
  304. ; so it can generate an LDT descriptor which refers to this memory.
  305. ;
  306. check_9f:
  307. cmp ah,9fh
  308. jne check_nw_ep ; is it a Netware call?
  309. or al,al
  310. jnz check_handle_mapper
  311. mov bx,seg ConnectionIdTable; 9f00: return segment info
  312. mov dx,offset ConnectionIdTable
  313. clc ; if we loaded then it can't fail
  314. retf 2
  315. ;
  316. ; if the call is 9f01 then we call MapNtHandle for the value in BX. This will
  317. ; update NtHandleHi and NtHandleLow, which we assume will be accessed from the
  318. ; code segment register
  319. ;
  320. check_handle_mapper:
  321. cmp al,1
  322. jne check_nw_ep ; still not one of ours?
  323. call MapNtHandle ; 9f01: call MapNtHandle
  324. retf 2
  325. check_nw_ep:
  326. cmp ah,0b4h
  327. jb for_dos_proper
  328. cmp ah,0f3h
  329. ja for_dos_proper
  330. jne @f
  331. jmp file_server_copy
  332. @@: cmp ah,0BAh
  333. jne check_f0
  334. push bx ; get environment. used by map.exe
  335. push ax
  336. mov ah,051h ; load current apps PDB into ax
  337. int 021h
  338. @@: mov es, bx
  339. cmp bx, es:PDB_Parent_PID
  340. je @f
  341. mov bx, es:PDB_Parent_PID
  342. jmp @b
  343. @@:
  344. mov dx, es:PDB_environ ; set DX to environment segment
  345. mov es, dx ; set es:di to value of COMSPEC
  346. push si
  347. push ds
  348. mov ds, dx
  349. xor si, si
  350. ; future code to save space
  351. ; es <- env seg
  352. ; di <- env off
  353. ; ds <- cs
  354. ; si <- offset Comspec
  355. ; cx <- .size Comspec / 2
  356. ; cld
  357. ; repz cmpsw
  358. ; jnz no match
  359. ; al <- 0
  360. ; cx <- remaining size of env seg
  361. ; rep scasb
  362. cld
  363. next_var:
  364. lodsb
  365. cmp al, "C"
  366. jne @f
  367. lodsb
  368. cmp al, "O"
  369. jne @f
  370. lodsb
  371. cmp al, "M"
  372. jne @f
  373. lodsb
  374. cmp al, "S"
  375. lodsb
  376. jne @f
  377. cmp al, "P"
  378. jne @f
  379. lodsb
  380. cmp al, "E"
  381. jne @f
  382. lodsb
  383. cmp al, "C"
  384. jne @f
  385. lodsb
  386. cmp al, "="
  387. je got_comspec
  388. @@: ; Search for null terminating environment
  389. or al,al
  390. je next_var
  391. lodsb
  392. jmp @b
  393. got_comspec:
  394. pop ds
  395. mov di,si
  396. pop si
  397. pop ax
  398. pop bx
  399. iret
  400. check_f0:
  401. cmp ah,0f0h
  402. jne for_me
  403. ;
  404. ; if we're here then we're doing simple stuff that we don't need to bop fer
  405. ; currently stuff here is ah=f0, al = 00, 01, 04, 05
  406. ;
  407. ; caveat emptor dept #312: However, it came to pass that we needed to bop when
  408. ; the f00x calls were made without any preceding calls that would cause nwapi32
  409. ; to be loaded
  410. ;
  411. dispatch_f0:
  412. .errnz ((offset PrimaryServer - offset PreferredServer) - 1)
  413. or al,al ; f000 = set preferred server
  414. jnz try_01
  415. cmp dl,8
  416. ja zap_preferred
  417. mov PreferredServer,dl
  418. iret
  419. zap_preferred:
  420. mov PreferredServer,al ; al contains 0 remember
  421. iret
  422. try_01: cmp al,1 ; f001 = get preferred server
  423. jnz try_02
  424. mov al,PreferredServer
  425. iret
  426. try_02: cmp al,2 ; f002 = get default server
  427. jnz try_04
  428. mov al,PreferredServer
  429. or al,al
  430. jnz @f
  431. mov al,PrimaryServer
  432. @@: iret
  433. try_04: cmp al,4 ; f004 = set primary server
  434. jne try_05
  435. cmp dl,8
  436. ja zap_primary
  437. mov PrimaryServer,dl
  438. iret
  439. zap_primary:
  440. mov PrimaryServer,0
  441. iret
  442. try_05: cmp al,5 ; f005 = get primary server
  443. jne for_me
  444. mov al,PrimaryServer
  445. iret
  446. file_server_copy:
  447. call FileServerCopy ; f3 - Used by ncopy.exe
  448. ;jmp for_me
  449. ;
  450. ; if the process exits and the dll is loaded then call the 32 bit code to
  451. ; close any cached handles.
  452. ;
  453. process_exit:
  454. ;jmp for_me
  455. ;
  456. ; if we're here then the dispatch code is for a NetWare client API. First we
  457. ; check if we have already loaded the 32-bit code. If not, then load it. If we
  458. ; get an error, we will fall through to DOS
  459. ;
  460. for_me:
  461. cmp ah,0BCh ; bc,bd,be need handle mapping
  462. jb no_mapping
  463. cmp ah,0BEh
  464. ja no_mapping
  465. ;do_mapping_call:
  466. call MapNtHandle ; take bx and find the Nt handle
  467. no_mapping:
  468. mov SavedAx,ax
  469. cmp ah,0e3h ; Look for CreateJob NCP
  470. jne @f ; try f2 alternative
  471. mov al,[si+2] ; si is NCP subfunction
  472. jmp lookupcode
  473. @@: cmp ax,0f217h
  474. jne do_dispatch ; Not CreateJob
  475. mov al,[si+2] ; si is NCP subfunction
  476. lookupcode:
  477. cmp al,68h
  478. je createjob
  479. cmp al,79h
  480. jne do_dispatch
  481. createjob: ; It is a CreateJob and File
  482. ; Always return the errorcode from the NCP exchange
  483. ; regardless of any earlier failures in the NT plumbing.
  484. mov ax, SavedAx
  485. push ax ; Open \\Server\queue for NCP
  486. push ds
  487. push dx
  488. mov ax, 9f02h
  489. mov SavedAx,ax
  490. mov ax,hVdd
  491. DispatchCall ; Set DeNovellBuffer to \\Server\queue
  492. ; and registers ready for DOS OpenFile
  493. pushf
  494. call Old21Handler ; Open \\server\queue
  495. jc @f
  496. mov JobHandle, al
  497. mov CreatedJob, 1 ; Flag JobHandle is valid
  498. push bx
  499. xor ah, ah
  500. mov bx, ax ; JobHandle
  501. call MapNtHandle ; take bx and find the Nt handle
  502. pop bx
  503. @@:
  504. pop dx
  505. pop ds ; Proceed and send the NCP
  506. pop ax
  507. mov SavedAx, ax
  508. do_dispatch:
  509. mov ax,hVdd
  510. DispatchCall
  511. retf 2 ; return to the application
  512. public chain_previous_int21
  513. chain_previous_int21:
  514. jmp far_label
  515. ;
  516. ; Save new drive so we can conveniently handle compatibility mode opens.
  517. ; also need to return 32 as the number of available drives.
  518. ;
  519. select_default_drive:
  520. pushf
  521. call Old21Handler ; fake int 21 to get to DOS
  522. mov ah,19h ; get current drive
  523. pushf
  524. call Old21Handler ; fake int 21 to get to DOS
  525. mov CurrentDrive,al ; current drive
  526. mov al,32 ; # of drives supported by NetWare
  527. retf 2 ; return to app (with flags from DOS)
  528. NwInt21 endp
  529. ;*******************************************************************************
  530. ;*
  531. ;* FileServerCopy
  532. ;*
  533. ;* Implement preperation for calling
  534. ;* \\...)
  535. ;*
  536. ;* ENTRY applications registers
  537. ;*
  538. ;* EXIT nothing
  539. ;*
  540. ;* RETURNS nothing
  541. ;*
  542. ;* ASSUMES no registers (except flags) can be destroyed
  543. ;*
  544. ;******************************************************************************/
  545. FileServerCopy proc near
  546. push ax
  547. push bx
  548. mov bx,word ptr es:[di] ; Map Source Handle
  549. call MapNtHandle
  550. mov bx,NtHandleHi
  551. mov NtHandleSrcHi,bx
  552. mov bx,NtHandleLow
  553. mov NtHandleSrcLow,bx
  554. mov bx,word ptr es:[di+2] ; Map Destination Handle
  555. call MapNtHandle
  556. @@: pop bx
  557. pop ax
  558. ret
  559. FileServerCopy endp
  560. ;*******************************************************************************
  561. ;*
  562. ;* IsDosPath
  563. ;*
  564. ;* Checks to see if a path name looks like a Microsoft path (<drive>:... or
  565. ;* \\...)
  566. ;*
  567. ;* ENTRY ds:dx = path name
  568. ;*
  569. ;* EXIT nothing
  570. ;*
  571. ;* RETURNS ZF = 1: path is for MS-DOS
  572. ;*
  573. ;* ASSUMES no registers (except flags) can be destroyed
  574. ;*
  575. ;******************************************************************************/
  576. IsDosPath proc near
  577. push ax
  578. xchg si,dx ; si = offset of filename; dx = ????
  579. mov al,[si+1] ; al = second character of filename
  580. cmp al,':'
  581. je @f ; looks like a DOS filename
  582. cmp al,'\' ; (X\... or \\...)
  583. jne tryFirstbyte
  584. cmp al,'/' ; (X/... or //...)
  585. jne @f ; second char is not "\" or "/"
  586. tryFirstbyte:
  587. mov al,[si] ; al = first character of filename
  588. cmp al,'\' ; (\\... or \/...)
  589. je @f
  590. cmp al,'/' ; (\/... or //...)
  591. @@: xchg si,dx ; dx = offset of filename; si = ????
  592. pop ax
  593. ret
  594. IsDosPath endp
  595. ;*******************************************************************************
  596. ;*
  597. ;* DenovellizeName
  598. ;*
  599. ;* Converts a name from Novell format (SERVER\SHARE:filename or
  600. ;* SHARE:filename) to DOS UNC name. Server name is found by:
  601. ;*
  602. ;* if PreferredServer != 0 then Index = PreferredServer
  603. ;* else if PrimaryServer != 0 then Index = PrimaryServer
  604. ;* else Index = 0
  605. ;* servername = ServerNameTable[Index * sizeof(SERVER_NAME)]
  606. ;*
  607. ;* ENTRY ds:dx = name
  608. ;*
  609. ;* EXIT ds:dx = offset of DenovellBuffer
  610. ;*
  611. ;* RETURNS if success, DI points to last byte+1 in DenovellBuffer, else
  612. ;* DI is garbage
  613. ;*
  614. ;* ASSUMES 1. filename does not wrap in buffer segment
  615. ;* 2. DI register can be trashed
  616. ;* 3. DF = 0
  617. ;*
  618. ;******************************************************************************/
  619. DenovellizeName proc near
  620. assume ds:nothing
  621. assume es:nothing
  622. push ax
  623. push bx
  624. push cx
  625. push bp
  626. push si
  627. push es
  628. mov bp,ds
  629. ;
  630. ; get the length of the input filename
  631. ;
  632. mov cx,ds
  633. mov es,cx
  634. mov di,dx ; es:di = filename
  635. xor cx,cx
  636. dec cx ; cx = ffff
  637. xor al,al
  638. repnz scasb
  639. not cx
  640. dec cx ; cx = strlen(filename)
  641. cmp cx,length DenovellBuffer
  642. jb @f
  643. jmp dnn_ret ; filename too long: give it to DOS
  644. ;
  645. ; find the offset of ':' in the filename
  646. ;
  647. @@: mov bx,cx ; remember length
  648. mov di,dx ; es:di = filename
  649. mov al,':'
  650. repnz scasb ; di = strchr(filename, ':')+1
  651. jz @f
  652. go_home:jmp dnn_ret ; no ':' - not novell format name?
  653. @@: cmp byte ptr [di],0
  654. je go_home ; device name? (eg "LPT1:") - to DOS
  655. mov si,di ; si = offset of ':' in name, +1
  656. ;
  657. ; find the offset of the first '/' or '\'
  658. ;
  659. mov cx,bx ; cx = length of filename
  660. mov di,dx ; di = offset of filename
  661. mov al,'\'
  662. repnz scasb
  663. sub bx,cx
  664. mov cx,bx
  665. mov bx,di
  666. mov di,dx
  667. mov al,'/'
  668. repnz scasb
  669. jnz @f
  670. mov bx,di
  671. ;
  672. ; if ':' before '\' or '/' then name is SYS:FOO... else SERVER\SYS:FOO...
  673. ;
  674. @@: mov di,cs
  675. mov es,di
  676. mov di,offset DenovellBuffer
  677. mov ax,('\' shl 8) + '\'
  678. stosw
  679. cmp bx,si
  680. jb copy_share_name
  681. xor bx,bx
  682. mov cl,PreferredServer
  683. or cl,cl
  684. jnz got_index
  685. mov cl,PrimaryServer
  686. jcxz get_server_name
  687. got_index:
  688. dec cl
  689. jz get_server_name
  690. mov bx,cx
  691. .errnz SERVERNAME_LENGTH - 48
  692. shl cx,5
  693. shl bx,4
  694. get_server_name:
  695. add bx,cx
  696. mov cx,ds
  697. mov si,es
  698. mov ds,si
  699. lea si,ServerNameTable[bx]
  700. cmp byte ptr [si],0
  701. je dnn_ret
  702. mov ah,SERVERNAME_LENGTH
  703. copy_server_name:
  704. lodsb
  705. or al,al
  706. jz done_server_name
  707. stosb
  708. dec ah
  709. jnz copy_server_name
  710. done_server_name:
  711. mov al,'\'
  712. stosb
  713. mov ds,cx
  714. copy_share_name:
  715. mov si,dx
  716. next_char:
  717. lodsb
  718. cmp al,':'
  719. je @f
  720. stosb
  721. jmp short next_char
  722. @@: mov al,'\'
  723. stosb
  724. copy_rest:
  725. lodsb
  726. stosb
  727. or al,al
  728. jnz copy_rest
  729. cmp byte ptr [si-2],':'
  730. jne @f
  731. mov byte ptr [si-2],0
  732. @@: mov dx,offset DenovellBuffer
  733. mov bp,es
  734. dnn_ret:mov ds,bp
  735. pop es
  736. pop si
  737. pop bp
  738. pop cx
  739. pop bx
  740. pop ax
  741. ret
  742. DenovellizeName endp
  743. ;*** DosCallBack
  744. ;*
  745. ;* Call back into DOS via the int 2f/ah=12 back door. If CALL_DOS defined,
  746. ;* use a call, else s/w interrupt. Using a call means no other TSRs etc.
  747. ;* which load AFTER the redir can hook it, but we DON'T HAVE TO MAKE A
  748. ;* PRIVILEGE TRANSITION ON x86 which speeds things up. This should be safe,
  749. ;* because no other s/w should really be hooking INT 2F/AH=12
  750. ;*
  751. ;* ENTRY FunctionNumber - dispatch code goes in al
  752. ;* DosAddr - if present, variable containing address of
  753. ;* DOS int 2f entry point
  754. ;* OldMultHandler - this variable contains the address of DOSs
  755. ;* int 2f back door. Specific to redir code
  756. ;*
  757. ;* EXIT nothing
  758. ;*
  759. ;* USES ax, OldMultHandler
  760. ;*
  761. ;* ASSUMES nothing
  762. ;*
  763. ;***
  764. DosCallBack macro FunctionNumber, DosAddr
  765. mov ax,(MultDOS shl 8) + FunctionNumber
  766. ifdef CALL_DOS
  767. pushf
  768. ifb <DosAddr>
  769. if (((.type OldMultHandler) and 32) eq 0) ;; OldMultHandler not defined
  770. extrn OldMultHandler:dword
  771. endif
  772. call OldMultHandler
  773. else
  774. call DosAddr
  775. endif
  776. else
  777. int 2fh
  778. endif
  779. endm
  780. ;
  781. ; defines for DosCallBack FunctionNumbers
  782. ;
  783. SF_FROM_SFN = 22
  784. PJFN_FROM_HANDLE= 32
  785. ; *** MapNtHandle
  786. ; *
  787. ; * Given a handle in BX, map it to a 32-bit Nt handle store result
  788. ; * in NtHandle[Hi|Low]
  789. ; *
  790. ; *
  791. ; * ENTRY bx = handle to map
  792. ; *
  793. ; * EXIT Success - NtHandle set to 32-bit Nt handle from SFT
  794. ; *
  795. ; * RETURNS Success - CF = 0
  796. ; * Failure - CF = 1, ax = ERROR_INVALID_HANDLE
  797. ; *
  798. ; * USES ax, bx, flags
  799. ; *
  800. ; * ASSUMES nothing
  801. ; *
  802. ; ***
  803. MapNtHandle proc near
  804. pusha ; save regs used by Dos call back
  805. push ds
  806. push es
  807. ;
  808. ; call back to Dos to get the pointer to the JFN in our caller's JFT. Remember
  809. ; the handle (BX) is an index into the JFT. The byte at this offset in the JFT
  810. ; contains the index of the SFT structure we want in the system file table
  811. ;
  812. DosCallBack PJFN_FROM_HANDLE ; pJfnFromHamdle
  813. jc @f ; bad handle
  814. ;
  815. ; we retrieved a pointer to the required byte in the JFT. The byte at this
  816. ; pointer is the SFT index which describes our 'file' (file to (un)lock in
  817. ; this case). We use this as an argument to the next call back function -
  818. ; get Sft from System File Number.
  819. ;
  820. mov bl,es:[di]
  821. xor bh,bh
  822. DosCallBack SF_FROM_SFN ; SfFromSfn
  823. jc @f ; oops - bad handle
  824. ;
  825. ; Ok. We have a pointer to the SFT which describes this named pipe. Get the
  826. ; 32-bit Nt handle and store it in the shared datastructure.
  827. ;
  828. mov bx,word ptr es:[di].sf_NtHandle[2]
  829. mov NtHandleHi,bx
  830. mov bx,word ptr es:[di].sf_NtHandle
  831. mov NtHandleLow,bx
  832. ;
  833. ; restore all registers used by Dos call back.
  834. ; Carry flag is set appropriately
  835. ;
  836. @@: pop es
  837. pop ds
  838. popa
  839. jnc @f
  840. ;
  841. ; finally, if there was an error then return a bad handle indication in ax
  842. ;
  843. mov ax,ERROR_INVALID_HANDLE
  844. @@: ret
  845. MapNtHandle endp
  846. ResidentCodeEnd
  847. end