[Search for users]
[Overall Top Noters]
[List of all Conferences]
[Download this site]
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.R | Title | User | Personal Name | Date | Lines |
---|
7375.1 | | THOLIN::TBAKER | Hey! Can my code do that? | Wed Mar 26 1997 11:18 | 10 |
| 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.2 | GOOD !! - One step further .... | PRSSOS::GAUTIER | | Thu Mar 27 1997 12:43 | 12 |
| 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.3 | | THOLIN::TBAKER | Hey! Can my code do that? | Thu Mar 27 1997 13:49 | 5 |
| 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.4 | A sample would be so nice | PRSSOS::GAUTIER | | Tue Apr 01 1997 09:07 | 12 |
| 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
|