page ,132 if 0 /*++ Copyright (c) 1991 Microsoft Corporation Module Name: namepipe.asm Abstract: This module contains the resident code part of the stub redir TSR for NT VDM net support. The routines contained herein are the named pipe API stubs: DosQNmPipeInfo DosQNmpHandState DosSetNmpHandState DosPeekNmPipe DosTransactNmPipe DosCallNmPipe DosWaitNmPipe NetHandleGetInfo NetHandleSetInfo DosReadAsyncNmPipe DosWriteAsyncNmPipe DosReadAsyncNmPipe2 DosWriteAsyncNmPipe2 (MapNtHandle) Author: Richard L Firth (rfirth) 05-Sep-1991 Environment: Dos mode only Revision History: 05-Sep-1991 rfirth Created --*/ endif .xlist ; don't list these include files .xcref ; turn off cross-reference listing include dosmac.inc ; Break macro etc (for following include files only) include dossym.inc ; User_ defines include mult.inc ; MultNET include error.inc ; DOS errors - ERROR_INVALID_FUNCTION include syscall.inc ; DOS system call numbers include rdrint2f.inc ; redirector Int 2f numbers include segorder.inc ; segments include enumapis.inc ; dispatch codes include debugmac.inc ; DosCallBack macro include localmac.inc ; DbgPrint macro include rdrsvc.inc ; BOP and SVC macros/dispatch codes include sf.inc ; SFT definitions/structure .cref ; switch cross-reference back on .list ; switch listing back on subttl ; kill subtitling started in include file .286 ; all code in this module 286 compatible ResidentCodeStart assume cs:ResidentCode assume ds:nothing ; *** DosQNmPipeInfo ; * ; * Implements the DosQNmPipeInfo call by vectoring into the VdmRedir ; * dispatcher which calls a 32-bit function to do the work ; * ; * Function = 5F32h ; * ; * ENTRY BX = Pipe handle ; * CX = Buffer size ; * DX = Info level ; * DS:SI = Buffer ; * ; * EXIT CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * no error ; * AX = undefined ; * ; * USES ax, flags ; * ; * ASSUMES nothing ; * ; *** public DosQNmPipeInfo DosQNmPipeInfo proc near call MapNtHandle jc @f ; bad handle: ax = error code, cf = 1 SVC SVC_RDRQNMPIPEINFO ; BP:BX is 32-bit handle @@: ret DosQNmPipeInfo endp ; *** DosQNmpHandState ; * ; * Implements the DosQNmpHandState call by vectoring into the VdmRedir ; * dispatcher which calls a 32-bit function to do the work ; * ; * Function = 5F33h ; * ; * ENTRY BX = Pipe handle ; * ; * EXIT CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * AX = Pipe mode: ; * BSxxxWxRIIIIIIII ; * ; * where: ; * B = Blocking mode. If B=1 the pipe is non blocking ; * S = Server end of pipe if 1 ; * W = Pipe is written in message mode if 1 (else byte mode) ; * R = Pipe is read in message mode if 1 (else byte mode) ; * I = Pipe instances. Unlimited if 0xFF ; * ; * USES ax, flags ; * ; * ASSUMES nothing ; * ; *** public DosQNmpHandState DosQNmpHandState proc near call MapNtHandle jc @f ; bad handle: ax = error code, cf = 1 SVC SVC_RDRQNMPHANDSTATE @@: ret DosQNmpHandState endp ; *** DosSetNmpHandState ; * ; * Implements the DosSetNmpHandState call by vectoring into the VdmRedir ; * dispatcher which calls a 32-bit function to do the work ; * ; * Function = 5F34h ; * ; * ENTRY BX = Pipe handle ; * CX = Pipe mode to set ; * ; * EXIT CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * AX = Pipe mode set ; * ; * USES ax, flags ; * ; * ASSUMES nothing ; * ; *** public DosSetNmpHandState DosSetNmpHandState proc near call MapNtHandle jc @f ; bad handle: ax = error code, cf = 1 SVC SVC_RDRSETNMPHANDSTATE @@: ret DosSetNmpHandState endp ; *** DosPeekNmPipe ; * ; * Implements the DosPeekNmPipe call by vectoring into the VdmRedir ; * dispatcher which calls a 32-bit function to do the work ; * ; * Function = 5F35h ; * ; * ENTRY BX = Pipe handle ; * CX = Size of buffer for peek ; * DS:SI = Buffer address ; * ; * EXIT CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * AX = Pipe status ; * BX = Number of bytes peeked into buffer ; * CX = Number of bytes in pipe ; * DX = Number of bytes in message ; * DI = Pipe status ; * DS:SI = Data peeked ; * ; * USES ax, bx, cx, dx, si, di, ds, flags ; * ; * ASSUMES nothing ; * ; *** public DosPeekNmPipe DosPeekNmPipe proc near call MapNtHandle jc @f ; bad handle: ax = error code, cf = 1 SVC SVC_RDRPEEKNMPIPE ; do the 'bop' (makes the lambada look tame) jc @f ; error returned from protect mode ; ; success - set the user's registers to values returned ; push ax ; pipe status DosCallBack GET_USER_STACK ; Get_User_Stack pop [si].User_Ax ; copy saved return code into user's copy mov [si].User_Bx,bx mov [si].User_Cx,cx mov [si].User_Dx,dx mov [si].User_Di,di clc ; reset cf, just in case @@: ret DosPeekNmPipe endp ; *** DosTransactNmPipe ; * ; * Implements the DosTransactNmPipe call by vectoring into the VdmRedir ; * dispatcher which calls a 32-bit function to do the work ; * ; * Function = 5F36h ; * ; * ENTRY BX = Pipe handle ; * CX = Transmit buffer length ; * DX = Receive buffer length ; * DS:SI = Transmit buffer ; * ES:DI = Receive buffer ; * ; * EXIT CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * CX = Number of bytes in Receive buffer ; * ; * USES ax, flags ; * ; * ASSUMES nothing ; * ; *** public DosTransactNmPipe DosTransactNmPipe proc near call MapNtHandle jc @f ; bad handle: ax = error code, cf = 1 SVC SVC_RDRTRANSACTNMPIPE jc @f ; error from protect-mode side ; ; success - copy returned cx value to user's registers in Dos stack seg ; DosCallBack GET_USER_STACK mov [si].User_Cx,cx clc ; reset carry flag, just in case @@: ret DosTransactNmPipe endp ; *** DosCallNmPipe ; * ; * Implements the DosCallNmPipe call by vectoring into the VdmRedir ; * dispatcher which calls a 32-bit function to do the work ; * ; * Function = 5F37h ; * ; * ENTRY DS:SI = Pointer to CallNmPipe structure: ; * DWORD Timeout; +0 ; * LPWORD lpBytesRead; +4 ; * WORD OutputBufferLen; +8 ; * LPBYTE OutputBuffer; +10 ; * WORD InputBufferLength; +14 ; * LPBYTE InputBuffer; +16 ; * LPSTR PipeName; +20 ; * ; * EXIT CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * CX = Bytes received ; * ; * USES ax, flags ; * ; * ASSUMES nothing ; * ; *** public DosCallNmPipe DosCallNmPipe proc near SVC SVC_RDRCALLNMPIPE jc @f ; oops - error ; ; success - copy returned ByteRead count in cx to user's cx in Dos stack seg ; DosCallBack GET_USER_STACK mov [si].User_Cx,cx clc ; reset carry flag, just in case @@: ret DosCallNmPipe endp ; *** DosWaitNmPipe ; * ; * Implements the DosWaitNmPipe call by vectoring into the VdmRedir ; * dispatcher which calls a 32-bit function to do the work ; * ; * Function = 5F38h ; * ; * ENTRY BX:CX = Timeout ; * DS:DX = Pipe name ; * ; * EXIT CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * No error ; * ; * USES ax, flags ; * ; * ASSUMES nothing ; * ; *** public DosWaitNmPipe DosWaitNmPipe proc near SVC SVC_RDRWAITNMPIPE ret DosWaitNmPipe endp ; *** NetHandleSetInfo ; * ; * Function = 5F3Bh ; * ; * ENTRY BX = Pipe handle ; * CX = Buffer length ; * SI = Level (1) ; * DI = Parmnum ; * DS:DX = Buffer ; * ; * EXIT CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * Stuff from buffer set ; * ; * USES ax, flags ; * ; * ASSUMES nothing ; * ; *** public NetHandleSetInfo NetHandleSetInfo proc call MapNtHandle jc @f SVC SVC_RDRHANDLESETINFO @@: ret NetHandleSetInfo endp ; *** NetHandleGetInfo ; * ; * Function = 5F3Ch ; * ; * ENTRY BX = Pipe handle ; * CX = Buffer length ; * SI = Level (1) ; * DS:DX = Buffer ; * ; * EXIT CX = size of required buffer (whether we got it or not) ; * CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * indicated stuff put in buffer ; * ; * USES ax, flags ; * ; * ASSUMES nothing ; * ; *** public NetHandleGetInfo NetHandleGetInfo proc call MapNtHandle jc @f SVC SVC_RDRHANDLEGETINFO jc @f DosCallBack GET_USER_STACK mov [si].User_Cx,cx clc @@: ret NetHandleGetInfo endp ; *** DosReadAsyncNmPipe/DosReadAsyncNmPipe2 ; * DosWriteAsyncNmPipe/DosWriteAsyncNmPipe2 ; * ; * Implements the AsyncNmPipe calls. 32-bit DLL does all the work ; * ; * Function = int 2fh/ax=1186h (DosReadAsyncNmPipe) ; * Function = int 2fh/ax=1190h (DosReadAsyncNmPipe2) ; * Function = int 2fh/ax=118fh (DosWriteAsyncNmPipe) ; * Function = int 2fh/ax=1191h (DosWriteAsyncNmPipe2) ; * ; * ENTRY DS:SI = DosAsyncNmPipeStruct: ; * DD pBytesRead +0 ; * DW buflen +4 ; * DD pBuffer +6 ; * DD pError +10 ; * DD pAnr +14 ; * DW hPipe +18 ; * ; * + For DosReadAsyncNmPipe2/DosWriteAsyncNmPipe2 ; * DD pSemaphore +20 ; * ; * EXIT CF = 1 ; * AX = Error code ; * ; * CF = 0 ; * No error ; * ; * USES ax, flags ; * ; * ASSUMES nothing ; * ; *** public DosReadAsyncNmPipe DosReadAsyncNmPipe proc near Int2fNumber DosReadAsyncNmPipe async_read_write_common: ; ; since the async named pipe calls arrive via int 2f, we don't have the safety ; blanket of DOS saving our registers ; push bp push bx mov bx,word ptr [si+18] ; pipe handle call MapNtHandle jc @f SVC SVC_RDRREADASYNCNMPIPE ; same for Read & Write @@: pop bx pop bp ret public DosReadAsyncNmPipe2 DosReadAsyncNmPipe2: Int2fNumber DosReadAsyncNmPipe2 jmp short async_read_write_common public DosWriteAsyncNmPipe DosWriteAsyncNmPipe: Int2fNumber DosWriteAsyncNmPipe jmp short async_read_write_common public DosWriteAsyncNmPipe2 DosWriteAsyncNmPipe2: Int2fNumber DosWriteAsyncNmPipe2 jmp short async_read_write_common DosReadAsyncNmPipe endp ; *** MapNtHandle ; * ; * Given a handle in BX, map it to a 32-bit Nt handle from the SFT in ; * BP:BX ; * ; * ENTRY bx = handle to map ; * ; * EXIT Success - BP:BX = 32-bit Nt handle from SFT ; * ; * RETURNS Success - CF = 0 ; * Failure - CF = 1, ax = ERROR_INVALID_HANDLE ; * ; * USES ax, bp, bx, flags ; * ; * ASSUMES nothing ; * ; *** MapNtHandle proc near push ax ; save regs used by Dos call back push cx push dx push ds push si push es push di ; ; call back to Dos to get the pointer to the JFN in our caller's JFT. Remember ; the handle (BX) is an index into the JFT. The byte at this offset in the JFT ; contains the index of the SFT structure we want in the system file table ; DosCallBack PJFN_FROM_HANDLE ; pJfnFromHamdle jc @f ; bad handle ; ; we retrieved a pointer to the required byte in the JFT. The byte at this ; pointer is the SFT index which describes our 'file' (named pipe in this ; case). We use this as an argument to the next call back function - get ; Sft from System File Number ; mov bl,es:[di] xor bh,bh DosCallBack SF_FROM_SFN ; SfFromSfn jc @f ; oops - bad handle ; ; Ok. We have a pointer to the SFT which describes this named pipe. Get the ; 32-bit Nt handle ; mov bx,word ptr es:[di].sf_NtHandle mov bp,word ptr es:[di].sf_NtHandle[2] ; ; restore all registers used by Dos call back. BX at this point is either ; the low 16-bits of the 32-bit Nt handle or junk. Carry flag is set ; appropriately ; @@: pop di pop es pop si pop ds pop dx pop cx pop ax jnc @f ; ; finally, if there was an error then return a bad handle indication in ax ; mov ax,ERROR_INVALID_HANDLE @@: ret MapNtHandle endp ResidentCodeEnd end