This tip was prompted by a question Jon Lau posted to the CW-Talk mailing list. Jon wanted to know how he could get the Novell network user name using a NetWare DLL. This tip looks at what is required to get the user name from NetWare using NWCALLS.DLL.
All of the functions needed are in the NWCalls DLL. This DLL ships with Windows 95 and is installed when the Windows 95 NetWare network drivers are installed. The DLL is also available from Novell in the NetWare SDK and can be downloaded from Novell's FTP site. NWCalls is a 16-bit DLL, so this example works on both Windows 3.1 and Windows 95 in 16-bit programs. It will not work as part of a 32-bit program.
All of the functions in NWCalls return a result code telling whether or not the function was successful. If the function was successful, the function result is zero and the requested information is returned in variables passed by address to the function.
NWGetPrimaryConnectionID returns what is essentially a handle to a server. When a connection is made to a NetWare server, the workstation assigns the server a connection ID number. These connection IDs are used by NWCalls to determine which server the request should go to. This function gets the primary connection ID, which is the ID for the server from which the login script was read.
The CW prototype for this function is
NWGetPrimaryConnectionID(*USHORT ConnID),USHORT,PASCAL, | NAME('NWGetPrimaryConnectionID')
The function accepts a single parameter that is an unsigned short. When the function completes, this variable will contain the connection ID of the primary server.
NWGetConnectionNumber uses the connection ID to obtain the connection number the workstation uses for that server. This is the familiar NetWare connection number displayed by NetWare utilities including USERLIST.
The CW prototype for this function is
NWGetConnectionNumber(USHORT ConnID,*USHORT ConnNum),USHORT, | PASCAL,NAME('NWGetConnectionNumber')
This function accepts two parameters. The first parameter is the connection ID obtained from NWGetPrimaryConnectionID and the second is an unsigned short that will be filled with the connection number the workstation uses on the primary server.
With the connection ID and connection number in hand, we are ready to request the connection information from the server. This is accomplished by NWGetConnectionInformation. This function returns information about a specific connection number (from NWGetConnectionNumber) on a specific server (from NWGetPrimaryConnectionID). Note that this does not have to be the connection number of the requesting workstation. This function could be used to generate a user list by calling it in a loop using connection numbers from 1 to the maximum number of connections on the server.
This function retrieves the following information:
You only need to provide return variables for the information you need returned. Since we are only interested in the user name, we could omit the parameters for the other information without causing any problems.
The CW prototype for this function is:
NWGetConnectionInformation(USHORT ConnID,USHORT ConnNum, | <*CSTRING UserName>,<*ULONG ObjectType>,<*ULONG ObjectID>, | <*BYTE LoginTime>),USHORT,RAW,PASCAL, | NAME('NWGetConnectionInformation')
The variable used for the user name should be a CSTRING(49). The returned value is a 48-character null-terminated string. Clarion needs a 49-character declaration so that space is allocated for the trailing null if all 48 characters are used.
The object type tells what type of object (user, print server, gateway, etc.) is attached to the connection specified. The object type for a user is 0200h.
The object ID is the object's unique ID in the NetWare bindery.
The login time is stored as a seven byte value (BYTE,DIM(7)) and contains the following values:
To get the user name, we only need to call these three functions. I am going to omit all of the error checking and initialization and just show the code that gets the job done. I am also going to treat the functions as procedures, which requires that the PROC attribute be added to the prototypes:
[Map] NWGetPrimaryConnectionID(*USHORT),USHORT,RAW,PASCAL, | PROC,NAME('NWGetPrimaryConnectionID') NWGetConnectionNumber(USHORT,*USHORT),USHORT,RAW,PASCAL, | PROC,NAME('NWGetConnectionNumber') NWGetConnectionInformation(USHORT,USHORT,<*CSTRING>,<*ULONG>,| <*ULONG>,<*BYTE>),USHORT,RAW,PASCAL,PROC, | NAME('NWGetConnectionInformation') [Data Section] ConnID USHORT ConnNum USHORT UserName CSTRING(49) [Code Section] NWGetPrimaryConnectionID(ConnID) NWGetConnectionNumber(ConnID,ConnNum) NWGetConnectionInformation(ConnID,ConnNum,UserName,,,)
That's all there is to it. Of course, if there are errors there is no guarantee what would come back in the end. But as long as the return value of the three function calls is zero, everything should be OK. For documentation on the other functions available in NWCALLS.DLL, you can download the NetWare C API Reference from Novell's Developer Support web site.
Note: The original NetWare C API Reference used in this article is no longer available from Novell.