Newsgroups: bit.listserv.novell
Date:         Fri, 21 Aug 1992 12:30:30 EDT
Reply-To:     Novell LAN Interest Group <NOVELL@SUVM.BITNET>
From:         Brett Warthen <Brett@INFINITE.MHS.COMPUSERVE.COM>
Subject:      RE: Question about GetConnectionsOpenFiles
X-To:         novell%suvm.bitnet@pucc.Princeton.edu

Anne,

I'm responding to the list, because I think this information might of general
interest to other programmers out there.

Are you trying to use GetConnectionsOpenFiles() on NetWare 3.11 by any chance?

If so, then I would expect a return code of 251 instead of 252, which means
"invalid request".  Basically, the GetConnectionsOpenFiles() API was dropped
for NetWare 3.x.

However...just last week, Novell acknowledged that there is in fact a similar
API that exists in NetWare 3.11!

Here is the source code for a program that lists the open files for a
connection under NetWare 3.11...have fun...

- Brett (Infinite Technologies)

//   **********************************************************************
//   *                                                                    *
//   * module:      3xsc.c                                                *
//   * abstract:    This module shows how to make 3.x system calls using  *
//   *              the F2 Shell Interface.  Obviously, it requires the   *
//   *              NetWare Shell.                                        *
//   *                                                                    *
//   * environment: NetWare 3.x v3.11                                     *
//   *              Borland C 3.0                                         *
//   *                                                                    *
//   *  This software is provided as is and carries no warranty           *
//   *  whatsoever.  Novell disclaims and excludes any and all implied    *
//   *  warranties of merchantability, title and fitness for a particular *
//   *  purpose.  Novell does not warrant that the software will satisfy  *
//   *  your requirements or that the software is without defect or error *
//   *  or that operation of the software will be uninterrupted.  You are *
//   *  using the software at your risk.  The software is not a product   *
//   *  of Novell, Inc. or any of subsidiaries.                           *
//   *                                                                    *
//   **********************************************************************
//   * maintenance history:                                               *
//   * level    date      pi   description                                *
//   **********************************************************************
//   *  001   07/21/92    kl   initial release.                           *
//   *  002   07/21/92    cm   Modified for GetConnectionsOpenFiles       *
//   **********************************************************************

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
#include <fcntl.h>
#include <sys/stat.h>
//
//  If you already have these defined, just remove them.
//

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned long LONG;

//
//  First of all, we define the request and reply structures which are
//  needed for the GetBinderyObjectID API call.  These structures are
//  layed out according to the System Call documentation.
//

struct  {
    WORD    sflen;          // length of the structure.  This is 6 + 'onlen'
    BYTE    sfcode;         // the subfunction code, in our case 53.
	 WORD    connNumber;     // object type (hi-lo)
    WORD    lastRecordSeen; // length of name (below)
}Request;

struct fileStruct{
    WORD    taskNumber;     // task number within ws holding file open
    BYTE    lockType;       // lock type  ie sharable, logged, locked, TTS
    BYTE    accessControl;  // connectiosn access rights to file
    BYTE    lockFlag;       // lock flag
    BYTE    volumeNumber;   // volume number file resides upon
    BYTE    reserved[9];
    BYTE    nameSpace;      // name space identifier
    BYTE    fileName[14];   // name of file (null terminated)
} ;

struct  fileStruct *fs[29];
int     numOpenFiles;
WORD    connectionNumber;

struct  {
    WORD    nextRequestRec; // next record to be requested.
    WORD    numberReturned; // numober of records returned
    BYTE    buffer[512];
}Reply;

void ProcessEntries(void);

//
//  These are some helper routines we need to make system calls.  These
//  are probably better off written in assembly, but I didn't want to tie
//  this to a specific compiler.  Call Developer Support if you want the
//  assembly version...
//

DWORD   DWordSwap( DWORD input )
{
	struct _hilo{
		WORD    lwlb:8;     // low word, low byte
		WORD    lwhb:8;     // low word, hi  byte
		WORD    hwlb:8;     // hi  word, low byte
		WORD    hwhb:8;     // hi  word, hi  byte
	}data;

	data = *(struct _hilo *)&input; // assign it to data

	return ((long)data.lwlb << 24) | ((long)data.lwhb << 16) |
	       ((long)data.hwlb << 8)  |  (long)data.hwhb;
}

WORD    WordSwap( WORD input )
{
	struct _hilo{
		WORD    lwlb:8;     // low byte
		WORD    lwhb:8;     // hi  byte
	}data;

	data = *(struct _hilo *)&input; // assign it to data

	return data.lwlb << 8 | data.lwhb;
}

WORD    NWSystemCall(BYTE func,             // function code
		     void far * req,        // request buffer
		     WORD reqLen,           // request length
		     void far *rep,         // reply buffer
			  WORD repLen)           // reply length
{
	union   REGS    regs;
	struct  SREGS   sregs;

	segread(&sregs);

	regs.x.ax = 0xf200 | func;      // AX = F2nn 'nn' is function code
	regs.x.cx = reqLen;             // CX = request buffer length
	regs.x.dx = repLen;             // DX = reply buffer length
	regs.x.si = FP_OFF(req);        // SI = request buffer offset
	regs.x.di = FP_OFF(rep);        // DI = reply buffer offset

	sregs.ds = FP_SEG(req);         // DS = request buffer segment
	sregs.es = FP_SEG(rep);         // ES = reply buffer segment

	intdos(&regs,&regs);            // do the Int 21

	return (WORD)regs.h.al;         // return code is in AL
}

//
//  This routine allocates memory for the data returned for each file.
//  It also makes the GetConnectionOpenFiles call and parses the data
//  for each file.
//
void ProcessEntries(void)
{
	char *lookup;
	int i,j;

	lookup=(char *)&Reply.buffer;
	numOpenFiles=Reply.numberReturned;
	for(i=0;i < numOpenFiles; i++) {
		fs[i]=malloc(sizeof (struct fileStruct));
		memmove((char *)&fs[i]->taskNumber,(lookup),2);
		fs[i]->lockType=*(lookup+2);
		fs[i]->accessControl=*(lookup+3);
		fs[i]->lockFlag=*(lookup+4);
		fs[i]->volumeNumber=*(lookup+5);
		memmove(fs[i]->reserved,(lookup+6),9);
		fs[i]->nameSpace=*(lookup+15);
		for(j=0;j<*(lookup+16);j++)
			fs[i]->fileName[j]=*(lookup+17+j);
		fs[i]->fileName[j]='\0';
		lookup=(lookup+17+j);
	}
}

//
//  This routine frees memory allocated by ProcessEntries.
//
void FreeEntries( void )
{
	int i;

	for(i=0;i<numOpenFiles;i++)
		free(fs[i]);
}

//
//  Display the list of open files for the connection.
//
void DisplayData( void )
{
	int i;

	clrscr();
	printf("\n\nList Of %d Open Files For Connection %d\n\n",
				numOpenFiles,
				connectionNumber);
	for(i=0;i<numOpenFiles;i++)
		printf("%s\n",&fs[i]->fileName);
}
//
//  This is the main program.  The purpose is to make the GetBinderyObjectID
//  API call to illustrate making system calls using the F2 interface.
//

main(int argc, char *argv[])
{
	int     cc;
	if(argc!=2){printf("usage: 3xsc connectionNumber\n");exit(1);}
	connectionNumber=atoi(argv[1]);
	//
	//  Build the request buffer
	//
	Request.sflen = (sizeof Request) ;
	Request.sfcode = 235;                       // subfunction code
	Request.connNumber = connectionNumber;
	Request.lastRecordSeen = 0;
	cc = NWSystemCall(23,&Request,sizeof Request,&Reply,sizeof Reply);
	printf("Function returned:    %03d--%#02x\n",cc,cc);
	if( cc == 0 ) {
		ProcessEntries();
		DisplayData();
		FreeEntries();
	}
	return 0;
}
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU