;       SCCSID = @(#)demnmp.asm 6.5 92/02/20
;       SCCSID = @(#)demnmp.asm 6.5 92/02/20
;       SCCSID = @(#)demnmp.asm 6.5 92/02/20
        PAGE    ,132
TITLE   NETWORK PIPE API ROUTINES - Routines for pipe API
NAME    NETPIAPI
;
; $AssignOper
; DosQNmpHandState      => QNmpHandState
; DosSetNmpHandState    => SetNmpHandState
; DosPeekNmPipe         => PeekNmPipe
; DosTransactNmPipe     => TransactNmPipe
; DosRawReadNmPipe      => RawReadNmPipe
; DosRawWriteNmPipe     => RawWriteNmPipe
; DosQNmPipeInfo        => QNmPipeInfo
; DosCallNmPipe         => CallNmPipe
; DosWaitNmPipe         => WaitNmPipe
;
;
;   Modification history:
;       05-Sep-1990  sudeepb    Created
;
; B001  2/12/92  CP20 B731511  Mark Rogalski
;       Add named pipe support to FSFILTER.
;
; B002  8/04/92  defect 52976  Mark Rogalski
;       Allow both function ranges of named pipe support.
;
; B005 - 5/13/92  defect 24729  Mark Rogalski                           ;BN005;
;         Also remove unneeded code for handling RM devices.            ;BN005;
;
; B006 - 1/5/93   defect 76223  Catherine E. Bundy
;        Pass CallNMPipe off to dos if Named Pipe is a UNC and network
;        is loaded.

.xlist
include v86seg.inc

.xcref
include basemaca.inc
include osmaca.inc
include oldmaca.inc
include demmac.inc
include dossymc.inc
include filemode.inc
include opncreat.inc
include error.inc
include mi.inc
include demsvc.inc
include mvdmexp.inc
include dirent.inc
include pdb.inc
include demdbcs.inc
include devhdr.inc
include syscalls.inc
include argframe.inc   ;ceb 76223

.cref
.list
        CpuMode 386

        ReferV86    TempBX,WORD
        ReferV86    os2_handled,BYTE         ;BN001

V86CODE SEGMENT
        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING

        EXTRN   VSFNFromHandle:NEAR
;BD005        EXTRN   RMDevCheck:NEAR
        EXTRN   Sys_Ret_OK:NEAR
        EXTRN   Sys_Ret_Err:NEAR
        EXTRN   get_user_stack:NEAR
        EXTRN   VMcheck_handle:NEAR         ;BN001

BREAK <$AssignOper - Int 21 Fun 5f dispatcher>
; Input:
;       ah = 5f
;       al = Name Pipe Subfunction
;       other registers depending on al
;
; Output:
;       Carry Clear - Success; Resulting registers depend on al
;       Carry Set   - Failure;
;
; Uses

        PUBLIC  apNPipeFunc
BeginNPipeFunc  equ     032h                         ;BC002
BeginNPipeFunc2 equ     0f2h                         ;BC002
apNPipeFunc     label   word
        dw      OFFSET V86GROUP:QnmPipeInfo          ; 5ff2
        dw      OFFSET V86GROUP:QNmpHandState        ; 5ff3
        dw      OFFSET V86GROUP:SetNmpHandState      ; 5ff4
        dw      OFFSET V86GROUP:PeekNmPipe           ; 5ff5
        dw      OFFSET V86GROUP:TransactNmPipe       ; 5ff6
        dw      OFFSET V86GROUP:CallNmPipe           ; 5ff7
        dw      OFFSET V86GROUP:WaitNmPipe           ; 5ff8
        dw      OFFSET V86GROUP:RawReadNmPipe        ; 5ff9
        dw      OFFSET V86GROUP:RawWriteNmPipe       ; 5ffa
cNPipeFunc  equ ($-apNPipeFunc) / 2

procedure $AssignOper,NEAR
        cmp     al,BeginNPipeFunc2                   ;BN002
        jae     high_range                           ;BN002
        sub     al,BeginNPipeFunc      ; too low?
        jmp     short over                           ;BN002
high_range:                                          ;BN002
        sub     al,BeginNPipeFunc2     ; too low?    ;BN002
over:                                                ;BN002
        jc      short aoerr
        cmp     al,cNPipeFunc          ; too high?
        jae     short aoerr
        xor     ah,ah
        mov     [TempBX],bx
        mov     bx,ax
        shl     bx,1
        push    apNPipeFunc[bx]
        mov     bx,[TempBX]
        ret                            ; this jumps us to appropriate func

aoerr:  stc                            ;BN002
        mov     cs:[os2_handled],0     ;BN001 DOS function
        ret                            ;BN001
EndProc $AssignOper

BREAK <NmpHandleCheck - Check file handle for named pipe calls>
; Input
;       BX is handle
; Output
;       CY clear if valid handle
;       CY set if invalid
;
; Uses  AX= error code if cy set
;       BX= VSFN if no cy
;BD001procedure NmpHandleCheck,NEAR
;BD001        call    VSFNFromHandle          ; get the VSFN
;BD001        jc      short nhc5              ; exit if bad handle
;BD001        call    RMDevCheck
;BD001        jnz     short nhc5              ; error if an RM device
;BD001        clc
;BD001        ret
;BD001nhc5:
;BD001        stc
;BD001        ret
;BD001EndProc NmpHandleCheck

BREAK <QNmPipeInfo - Get info on a named pipe>
; Inputs:
;       BX is handle of pipe (must be checked)
;       CX is size of buffer for info
;       DX is Level of info to get
;       DS:SI is address of buffer
; Function:
;       Get pipe info
; Returns:
;       Carry set
;           AX = error
;       Carry Clear
;           OK
; Uses all

        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
procedure   QnmPipeInfo,NEAR
        call    VMcheck_handle          ;BN001 convert handle or return
;BD001        call    NmpHandleCheck          ; Handle sanity check
;BD001        jc      short qp5
        SVC     SVC_DEMQNMPINFO         ; let OS/2 do the work
        jc      short qp5               ; skip if error
        jmp     Sys_Ret_OK              ; return OK

qp5:    jmp     Sys_Ret_Err             ; return error
EndProc QnmPipeInfo

BREAK <QNmpHandState - Get pipe mode information>
; Inputs:
;       BX is handle of pipe (must be checked)
; Function:
;       Return mode of pipe
; Returns:
;       Carry clear
;           AX = Pipe mode word
;       Carry set
;           AX = error
; Uses all

        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
procedure   QNmpHandState,NEAR
        call    VMcheck_handle          ;BN001 convert handle or return
;BD001        call    NmpHandleCheck          ; Handle sanity check
;BD001        jc      short qn5
        SVC     SVC_DEMQNMPHANDSTATE    ; let OS/2 do the work
        jc      short qn5               ; skip if error
        invoke  get_user_stack
        ASSUME DS:NOTHING
        mov     [SI.user_AX],ax         ; Save Pipe Mode
        jmp     Sys_Ret_OK              ; return OK

qn5:    jmp     Sys_Ret_Err             ; return error

EndProc QNmpHandState

BREAK <SetNmpHandState - Set pipe mode>
; Inputs:
;       BX is handle of pipe (must be checked)
;       CX is pipe mode word to set
; Function:
;       Set mode of pipe
; Returns:
;       Carry Clear
;           Indicated mode set
;       Carry set
;           AX = error
; Uses all

        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
procedure   SetNmpHandState,NEAR
        call    VMcheck_handle          ;BN001 convert handle or return
;BD001        call    NmpHandleCheck          ; Handle sanity check
;BD001        jc      short sh5
        SVC     SVC_DEMSETNMPHANDSTATE  ; let OS/2 do the work
        jc      short sh5               ; skip if error
        jmp     Sys_Ret_OK              ; return OK

sh5:    jmp     Sys_Ret_Err             ; return error
EndProc SetNmpHandState


BREAK <PeekNmPipe - Peek on a named pipe>
;***    PeekNmPipe - Peek on a named pipe
;
; Inputs:
;       BX is handle of pipe (must be checked)
;       CX is size of buffer for peek
;       DS:SI is address of peek buffer
; Function:
;       Peek from pipe
; Returns:
;       Carry set
;           AX = error code. IF ERROR IS ERROR_MORE_DATA Carry
;                clear returns are also set.
;       Carry Clear
;           CX = bytes peeked from pipe
;           User DX:SI is available data
;           AX is pipe status
; Uses all
;
        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
procedure   PeekNmPipe,NEAR
        call    VMcheck_handle          ;BN001 convert handle or return
;BD001        call    NmpHandleCheck          ; Handle sanity check
;BD001        jc      short pp5
        SVC     SVC_DEMPEEKNMP          ; let OS/2 do the work
        mov     bx,si
        invoke  get_user_stack
        jc      short pp5               ; skip if error
ASSUME  DS:NOTHING
        mov     [si.user_ax],ax
        mov     [si.user_cx],cx
        mov     [si.user_dx],dx
        mov     [si.user_si],bx
        jmp     Sys_Ret_OK              ; return OK

pp5:
        cmp     ax,ERROR_MORE_DATA
        jne     short pp10
        mov     [si.user_cx],cx
        mov     [si.user_dx],dx
        mov     [si.user_si],bx
pp10:
        jmp     Sys_Ret_Err             ; return error
EndProc PeekNmPipe

BREAK <TransactNmPipe - Do a transact named pipe>
; Inputs:
;       BX is handle of pipe (must be checked)
;       CX is source (write) buffer length
;       DX is destination (read) buffer length
;       DS:SI is address of source (write) buffer
;       ES:DI is address of destination (read) buffer
; Function:
;       Write the data part of the transaction
;       NOTE: IT IS ASSUMED THE RESPONSE SMB HAS ONE PARAMETER WHICH IS THE
;             AMOUNT WRITTEN.
; Returns:
;       Carry set
;           AX = error code. IF ERROR IS ERROR_MORE_DATA Carry
;                clear returns are also set.
;       Carry Clear
;           CX = bytes read into destination (read) buffer address
; Uses all
        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
procedure   TransactNmPipe,NEAR
        call    VMcheck_handle          ;BN001 convert handle or return
;BD001        call    NmpHandleCheck          ; Handle sanity check
;BD001        jc      short tnp5
        SVC     SVC_DEMTRANSACTNMP      ; let OS/2 do the work
        invoke  get_user_stack
        jc      short tnp5              ; skip if error
ASSUME  DS:NOTHING
        mov     [si.user_cx],cx
        jmp     Sys_Ret_OK              ; return OK
tnp5:
        cmp     ax,ERROR_MORE_DATA
        jne     short tnp10
        mov     [si.user_cx],cx
tnp10:
        jmp     Sys_Ret_Err             ; return error
EndProc TransactNmPipe

BREAK <CallNmPipe - Do a call named pipe>
; Inputs:
;       DS:SI -> Call named pipe parameter structure
; Function:
;       Do a call named pipe
; Returns:
;       Carry set
;           AX = error code. IF ERROR IS ERROR_MORE_DATA Carry
;                clear returns are also set.
;       Carry Clear
;           CX = Bytes read
; Uses all

        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
procedure   CallNmPipe,NEAR

        push    di                      ; ceb 76223
        mov     di,word ptr ds:[si].cnmp_FileName  ; see if UNC name ceb 76223
        cmp     ds:[di],5c5ch           ; see if UNC name ceb
        pop     di                      ; ceb 76223
        jne     cnp3                    ; no? skip over net check    ;ceb 76223
        push    ax                      ; ceb 76223
        mov     ax,0B800h               ; see if DOS LAN installed   ;ceb 76223
        int     2fh                     ; AL non zero if installed   ;ceb 76223
        cmp     al,0                    ; ceb 76223                               ;ceb 76223
        pop     ax                      ; ceb 76223
        jz      cnp3                    ; yes? send request to OS/2  ;ceb 76223
        stc                             ; ceb 76223
        mov     cs:[os2_handled],0      ; ceb 76223
        ret                             ; ceb 76223

cnp3:                                   ; ceb 76223
        SVC     SVC_DEMCALLNMP          ; let OS/2 do the work
        invoke  get_user_stack
        jc      short cnp5              ; skip if error
ASSUME  DS:NOTHING
        mov     [si.user_cx],cx
        jmp     Sys_Ret_OK              ; return OK

cnp5:
        cmp     ax,ERROR_MORE_DATA
        jne     short cnp10
        mov     [si.user_cx],cx
cnp10:
        jmp     Sys_Ret_Err             ; return error
EndProc CallNmPipe

BREAK <WaitNmPipe - Do a wait named pipe>
; Inputs:
;       DS:DX -> Pipe name
;       BX:CX = Timeout value
; Function:
;       Do a wait named pipe
; Returns:
;       Carry set
;           AX = error
;       Carry Clear
;
; Uses all
procedure   WaitNmPipe,NEAR
        SVC     SVC_DEMWAITNMP          ; let OS/2 do the work
        jc      short wnp5              ; skip if error
        jmp     Sys_Ret_OK              ; return OK

wnp5:   jmp     Sys_Ret_Err             ; return error
EndProc WaitNmPipe


BREAK <RawReadNmPipe/WriteNmPipe - Do raw I/O on a pipe>
;
; Notes about RAW read write.
;
;       Since we only buffer on pipes that are BYTE mode at both ends,
;           the RA and WB buffer data is the same as the RAW data. Thus the
;           "buffered" case is the same as normal read and write.
;
;       These calls are not high volume, they aren't even supposed to be
;           documented. Thus we will sort of PUNT on the efficiency issue as
;           far as "buffering" is concerned.
;
;           Both Read and Write simply FLUSH the WB buffer first. On read if
;               there is a RA buffer, we will satisfy the first part of the read
;               from the buffer, flush the buffer (if we suck up all of it) and
;               then complete the read from the server WITHOUT doing any
;               buffering.
;
;           In both of the unbuffered cases we simply send the RW to the server
;               with NO check on its size. This will be gag me slow if the user
;               is stupid enough to do it in repeated small pieces.
;
; Inputs:
;       BX is handle of pipe (must be checked)
;       CX is size to read
;       DS:DX is address of buffer
; Function:
;       Do a Raw read transaction on the pipe
; Returns:
;       Carry set
;           AX = error code. IF ERROR IS ERROR_MORE_DATA Carry
;                clear returns are also set.
;       Carry Clear
;           CX = bytes read into transfer address
; Uses all

        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
procedure   RawReadNmPipe,NEAR
        call    VMcheck_handle          ;BN001 convert handle or return
;BD001        call    NmpHandleCheck          ; Handle sanity check
;BD001        jc      short rrp5
        SVC     SVC_DEMRAWREADNMP       ; let OS/2 do the work
        invoke  get_user_stack
        jc      short rrp5              ; skip if error
ASSUME  DS:NOTHING
        mov     [si.user_cx],cx
        jmp     Sys_Ret_OK              ; return OK

rrp5:
        cmp     ax,ERROR_MORE_DATA
        jne     short rrp10
        mov     [si.user_cx],cx
rrp10:
        jmp     Sys_Ret_Err             ; return error
EndProc RawReadNmPipe


; Inputs:
;       BX is handle of pipe (must be checked)
;       CX is size to write
;       DS:DX is address of buffer
; Function:
;       Do a Raw write transaction on the pipe
; Returns:
;       Carry set
;           AX = error
;       Carry Clear
;           CX = bytes written from transfer address
; Uses all

        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
procedure   RawWriteNmPipe,NEAR
        call    VMcheck_handle          ;BN001 convert handle or return
;BD001        call    NmpHandleCheck          ; Handle sanity check
;BD001        jc      short rwp5
        SVC     SVC_DEMRAWWRITENMP      ; let OS/2 do the work
        jc      short rwp5              ; skip if error
        jmp     Sys_Ret_OK              ; return OK

rwp5:   jmp     Sys_Ret_Err             ; return error
EndProc RawWriteNmPipe

V86CODE ENDS
    END
