[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference noted::pwdoswinv5

Title:PATHWORKS V5 for DOS and Windows
Notice:OS2LAN::OS2:[PUBLIC] is alive again, but not what it used to be
Moderator:RANGER::CURLESS
Created:Fri Feb 11 1994
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:7404
Total number of notes:27276

7375.0. "Lat START_SERVICE API problem" by PRSSOS::GAUTIER () Tue Mar 25 1997 11:53

    Hi,
    
    
    Could anyone post here some documentation on how to create a lat 
    service using the Pathworks for Dos API.
    I have a customer who developed a program creating a LAT service. He
    says it worked fine before (maybe in V4, he couldn't tell me 
    precisely), but mow he gets the error return code 2h when his program 
    calls the START_SERVICE function thru the interrupt int86x.
    
    We reproduced his problem here by using one of the Pathworks SDK 
    example (terml.c) and adding a call to the START_SESSION function.
    
    Tanks in advance for your help,
    Didier GAUTIER - France PCI support group
    
    
    
    Follows the code :
    /*********************************************************************
     *                                                                     
     *
     *                      Copyright (c) 1989, 1990 by                    
     *
     *              Digital Equipment Corporation, Maynard, MA             
     *
     *                      All rights reserved.                           
     *
     *                                                                     
     *
     *   This software is furnished under a license and may be used and    
     *
     *   copied  only  in accordance with the terms of such license and    
     *
     *   with the  inclusion  of  the  above  copyright  notice.   This    
     *
     *   software  or  any  other copies thereof may not be provided or    
     *
     *   otherwise made available to any other person.  No title to and    
     *
     *   ownership of the software is hereby transferred.                  
     *
     *                                                                     
     *
     *   The information in this software is subject to change  without    
     *
     *   notice  and should not be construed as a commitment by Digital    
     *
     *   Equipment Corporation.                                            
     *
     *                                                                     
     *
     *   Digital assumes no responsibility for the use  or  reliability    
     *
     *   of its software on equipment which is not supplied by Digital.    
     *
     *                                                                     
     *
     *********************************************************************/
    
    /*
     *  A simple terminal emulator program using the LAT TSR
     *
     *  Built with:
     *  	Microsoft (R) C Optimizing Compiler Version 5.10
     *  	Microsoft (R) Overlay Linker Version 3.65
     *
     *  To build, using packed structures and a small memory model:
     *  	CL /Zp terml.c
     * 
     *  To build, using packed structures and a large memory model:
     *  	CL /AL /Zp terml.c
     *
     *  To invoke, after LAT is loaded:
     *  	TERML service
     */
    
    #include <dos.h>
    #include <stdio.h>
    #include <signal.h>
    #include <dos.h>
    #include <process.h>
    #include <memory.h>
    #include <string.h>
    #include <dos.h>
    #include <conio.h>
    
    #define byte  		unsigned char
    #define word  		unsigned int
    #define dword 		unsigned long
    
    #define LAT_INT		0x6A	 /* LAT software interrupt       
    */ 	
    #define DOS_INT		0x21	 /* DOS software interrupt       
    */
    #define CONTROL_SLASH	0x1C	 /* key used to exit TERML       
    */
    #define LAT_FLAG        	0xFF00   /* identifies call as a LAT call */
    #define TRANSMIT		0x01     /* transmit a character          */
    #define RECIEVE         	0x02     /* receive a character		 
    */
    #define START_SESSION   	0xD0FF   /* start a LAT session           */
    #define START_SERVICE    	0xDA00 	/* start a LAT service           */
    #define CLOSE_SESSION   	0xD000  /* close a LAT session           */
    #define KBD_INPUT		0x08	/* DOS function number           */
    #define GET_VECTOR		0x35	 /* DOS function number		  */
    
    #define SLOT_LEN 		259	 /* slot length			  */
    #define SRV_LEN		17	 /* max. service name + NULL     
    */
    #define NUM_SLOTS		3	 /* number of slots               */
    #define FATAL_ERROR     	0x8      /* bit 3 or 4 set in first byte  */
                                	     /* of session status word?     */
    #define API_ERROR       	0x80     /* bit 7 in AH set               */
    
    
    /* Port structure */
    static struct port_tag {
      byte  port_enable;
      byte  port_in_use;
      byte  port_type;
    
      byte  port_rating;
      byte  port_srv_len;    
      byte  port_service[16];
      byte  port_desc_len;
      byte  port_desc[48];
      byte  port_pswd_len;
      byte  port_pswd[16];
      byte  port_flow_ctrl;
      byte  port_flags;
      
      byte  port_parity;
      byte  port_data_len;
      dword port_scb;
      byte  port_hdl;
      byte  port_requests;
      byte  port_start;
      word  port_start_counter;
      word  port_vcb;
      byte  port_name_len;
      byte  port_name[16];
      byte  port_reserved[4];
      word  port_tx_speed;
      word  port_rx_speed;
      word  port_queue[16];
    } port; 
    
    
    /*
     * SCB = Session Control Block used for each session
     */
    
    static struct scb_tag {
        byte scb_service[SRV_LEN];	 /* service name                 */
        byte reserved_1;
        word scb_queue_pos;          /* queue position               */
        byte scb_queue_con;          /* is connection queueable?     */
        byte reserved_2[6];
        dword scb_buffer;            /* address of password etc.     */
        byte scb_buffer_len;         /* user buffer length           */
        byte reserved_3[22];
        dword scb_sess_stopped;      /* set to zero or address       */
        byte reserved_4[12];
        word scb_status;		 /* session status               */
        byte reserved_5[270];
        byte scb_num_slots;      	 /* number of slots provided     */
        byte reserved_6[5];
        word scb_slot_tbl[NUM_SLOTS];	/* offsets of provided slots    */
    } scb; 
    
    static byte slot_1[SLOT_LEN];    /* slot buffers                 */
    static byte slot_2[SLOT_LEN];
    static byte slot_3[SLOT_LEN];
    
    word handle;			 /* LAT_FLAG + session handle    */
    word far *pflag;      		 /* Pointer to Lock process flag */
    /*********************************************************************
     *
     *     main
     *
     *  
    *********************************************************************/
    main(argc,argv)
    int argc;
    char *argv[];
    {
    union REGS inregs, outregs;  
    int status;
    byte far *p;
    
        if (argc < 2) {
           	printf("\nUsage: TERML service\n");
           	exit(1);
        }
        else if (!lat_installed()){
           	printf("\nLAT is not installed\n");
           	exit(1);
        }
    /*
     * Initialize the SCB to all zeros. Then copy the service name and  
     * specify how many slot buffers will be provided.
     */
        memset((char *) &scb, '\0', sizeof(struct scb_tag));  
        strcpy(scb.scb_service, argv[1]);		
        scb.scb_num_slots     = NUM_SLOTS;	        
    /*
     * Store the offsets of the slot buffers in scb_slot_tbl[], making  
     * certain that they use the same segment as the SCB. 
     */
        p = (byte far *) slot_1;
        scb.scb_slot_tbl[0] = FP_OFF(p);
        p = (byte far *) slot_2;	
        scb.scb_slot_tbl[1] = FP_OFF(p);
        p = (byte far *) slot_3;
        scb.scb_slot_tbl[2] = FP_OFF(p);
    
        signal(SIGINT,SIG_IGN);		/* trap <CTRL/C> 		*/
    
        status=lat_start_slave_session(); 
    	printf("status of lat_start %d\n",status); 
       exit(0);
    }
    
    /********************************************************************
     * 	start_session
     *
     * 	Starts a LAT session. 
     *********************************************************************/
    start_session(){
    union REGS inregs, outregs;
    struct SREGS segregs;
    char far *p;
    
        p = (char far *) &scb;
        printf("Connecting to %s...\n", strupr(scb.scb_service));
    
        segread(&segregs);
        inregs.x.dx = LAT_FLAG;      
        inregs.x.ax = START_SESSION;
        segregs.es  = FP_SEG(p);
        inregs.x.bx = FP_OFF(p);		/* ES:BX => SCB */
        int86x(LAT_INT, &inregs, &outregs, &segregs);
    
        if (outregs.h.ah != 0){
    	printf("\nConnect failed. Status = %X hex\n", outregs.h.ah);
    	exit(1);
        }
        else {
           	handle = outregs.x.dx;
           	printf("Logout or Press <Ctrl-\\> to exit\n");
        }
    }               
    /********************************************************************
     * 	lat_start_slave_session
     *
     * 	Starts a LAT service
    /********************************************************************/
    int lat_start_slave_session() 
    {
      union REGS inregs, outregs;
      struct SREGS segregs;
      char far *p;
      byte far *q;
                                      
      /* Initialize the SCB */
      memset((char *) &scb, '\0', sizeof(struct scb_tag));  
      strcpy(scb.scb_service, "ICA_PORT"); 
      scb.scb_num_slots     = NUM_SLOTS;          
    
      q = (byte far *) slot_1;
      scb.scb_slot_tbl[0] = FP_OFF(q);
      q = (byte far *) slot_2;  
      scb.scb_slot_tbl[1] = FP_OFF(q);
      q = (byte far *) slot_3;
      scb.scb_slot_tbl[2] = FP_OFF(q);
    
      scb.scb_queue_con=1;
    
      /* Port Initialisation  */
      memset((char *)&port, '\0', sizeof(struct port_tag));  
      port.port_rating = 255;
      memcpy (port.port_service, "ICA_PORT"         ,  8);  
      port.port_srv_len  =  8; 
      memcpy (port.port_name   , "ICA"              ,  3); 
      port.port_name_len =  3; 
      memcpy (port.port_desc   , "ESCALE CLOCK PORT", 17); 
      port.port_desc_len = 17; 
      memcpy (port.port_pswd   , ""                 ,  0); 
      port.port_pswd_len =  0; 
      port.port_flags = 0x01; /* accept incoming requests */
      port.port_scb = (dword)&scb;
    
    /*  p = (char far *)&port;????????????????????*/
      p = (char far *)&scb;
      segread(&segregs);
      inregs.x.dx = LAT_FLAG;
      inregs.x.ax = START_SERVICE;
      segregs.es  = FP_SEG(p); 
      inregs.x.bx = FP_OFF(p); 
    
    
      int86x(LAT_INT, &inregs, &outregs, &segregs);
    
      if (outregs.h.ah != 0){
        printf("Lat err : start %xh\n", outregs.h.ah);
        return(-1);
      }
      else {
        handle = outregs.x.dx;
        pflag = _MK_FP (segregs.es, outregs.x.bx);  
        printf ("Lat lock-process-byte : %lxh, %xh.", pflag, *pflag);
        printf ("Lat handle : %xh.", handle);
      }
      return(0);
    }
    
    /*********************************************************************
     *	stop_session
     *
     *	Stop the LAT session.
    **********************************************************************/
    stop_session(){
    union REGS inregs, outregs;
    
        inregs.x.ax = CLOSE_SESSION;
        inregs.x.dx = handle;
        int86(LAT_INT, &inregs, &outregs);
        if (outregs.x.ax != 0)
    	printf("\nError closing session. Status = %X hex\n", outregs.x.ax);
    }
    
    /*********************************************************************
     *	display_rcv_char
     *
     *	Check if a character has been received. If so display it.
    **********************************************************************/
    display_rcv_char(){
    union REGS inregs, outregs;
    
    /*
     * read a character if its available, and display it
     */
        inregs.h.ah = RECIEVE;
        inregs.x.dx = handle;
        int86(LAT_INT, &inregs, &outregs);
        if (!(outregs.h.ah & API_ERROR))	/* error return in AH      
    */
           	putchar(outregs.h.al);	        /* character returned in AL
    */
    }
    
    /******************************************************************
     *	send_char
     *
     *	Send a character entered at the keyboard
     *********************************************************************/
    send_char(kbd_char)
    byte kbd_char;
    {
    union REGS inregs, outregs;
    
        inregs.h.ah = TRANSMIT;
        inregs.h.al = kbd_char;
        inregs.x.dx = handle;
        int86(LAT_INT, &inregs, &outregs);
    }
    
    /*********************************************************************
     * 	lat_installed
     *
     * Returns TRUE if LAT is installed. It checks if LAT is installed by 
     * getting the vectors address, and then testing for the `LAT' TLA  *
    which should precede it.
     ********************************************************************/
    #ifdef toto 
    lat_installed(){
    byte far *p;
    union REGS inregs, outregs;
    struct SREGS segregs;
    dword es_seg;
    
        inregs.h.ah = GET_VECTOR;
        inregs.h.al = LAT_INT;
        int86(DOS_INT, &inregs, &outregs);
        segread(&segregs);
        es_seg = (segregs.es << 16L);
        p = (char far *) (es_seg + outregs.x.bx);
        p -= 3;                  
        printf("Return code %c %c %c %c %d %d %d
    %d\n",p[0],p[1],p[2],p[3],p[0],p[1],p[2],p[3]);
        if (p[0] != 'L' || p[1] != 'A' || p[2] != 'T')
           	return(0);
        else
    	return(1);
    
    } 
    #endif
    
    lat_installed() 
    {
      byte far *p;
      union REGS inregs, outregs;
      struct SREGS segregs;
      dword es_seg;
    
      inregs.h.ah = GET_VECTOR; 
      inregs.h.al = LAT_INT; 
      int86(DOS_INT, &inregs, &outregs);        /* lecture vecteur (d'IT)
    */
      segread(&segregs); 
      es_seg = ((dword) segregs.es << 16L);
      p = (char far *)(es_seg + outregs.x.bx);  /* calcule adresse pointee
    */
      p -= 3;        
      if ((p[0] != 'L') || (p[1] != 'A') || (p[2] != 'T')) return(0);
      return(1);
    }           
    
    
T.RTitleUserPersonal
Name
DateLines
7375.1THOLIN::TBAKERHey! Can my code do that?Wed Mar 26 1997 11:1810
    Have him get into LATCP and do a

	LATCP> DEFINE MAXIMUM PORTS 

    LAT needs to know that it has to make room for more services.

    As far as documentation, I'm sure your customer has some or
    else he wouldn't have been able to get that far.
    
    Tom
7375.2GOOD !! - One step further ....PRSSOS::GAUTIERThu Mar 27 1997 12:4312
    Hi Tom,  
    
    Thanks very much for your reply.
    You were right. The "Ports" value was set to 0. I set it to 1, then I
    got a return code of "1h". I tried other values (like 6) with the same
    result.
    
    Any ideas ?
    
    Best regards,
    Didier
    
7375.3THOLIN::TBAKERHey! Can my code do that?Thu Mar 27 1997 13:495
    If there are ports left over (you haven't used all of them)
    the only thing to set the return code to 1 (as far as I can
    tell) is if the SCB is somehow incorrect (bad pointer, etc).
    
    Tom
7375.4A sample would be so nice PRSSOS::GAUTIERTue Apr 01 1997 09:0712
    Hi Tom,
    
    Yes, I have free ports when the error occurs.
    I have no way to check if my SCB or my port declaration are correct.
    They come from the TERML.C PWSDK sample, but this example only shows how
    to connect to a LAT service, not how to create one.
    
    What I'd need is a sample code that creates a LAT service properly so I
    could compare it with my code. Has anybody got this precious thing ?
    
    Best regards,
    Didier