431 lines
11 KiB
C
431 lines
11 KiB
C
//Copyright (c) 1998 - 1999 Microsoft Corporation
|
|
|
|
/*************************************************************************
|
|
*
|
|
* NWLAN.C
|
|
*
|
|
* Name Enumerator for Novell Netware
|
|
*
|
|
*
|
|
*************************************************************************/
|
|
|
|
/*
|
|
* Includes
|
|
*/
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <icaipx.h>
|
|
#include <nwapi32.h>
|
|
#include "qappsrv.h"
|
|
|
|
|
|
/*=============================================================================
|
|
== External Functions Defined
|
|
=============================================================================*/
|
|
|
|
int NwEnumerate( void );
|
|
|
|
|
|
/*=============================================================================
|
|
== LoadLibrary/GetProcAddress stuff for NWAPI32.DLL
|
|
=============================================================================*/
|
|
|
|
/*
|
|
* NWAPI32.DLL stuff
|
|
*/
|
|
|
|
#define PSZ_NWAPI32 TEXT("NWAPI32.DLL")
|
|
|
|
#define PSZ_NWATTACHTOFILESERVER "NWAttachToFileServer"
|
|
#define PSZ_NWDETACHFROMFILESERVER "NWDetachFromFileServer"
|
|
#define PSZ_NWREADPROPERTYVALUE "NWReadPropertyValue"
|
|
#define PSZ_NWSCANOBJECT "NWScanObject"
|
|
|
|
typedef NWCCODE (NWAPI DLLEXPORT *PNWATTACHTOFILESERVER)
|
|
(const char NWFAR *,
|
|
NWLOCAL_SCOPE,
|
|
NWCONN_HANDLE NWFAR *);
|
|
typedef NWCCODE (NWAPI DLLEXPORT *PNWDETACHFROMFILESERVER)
|
|
(NWCONN_HANDLE);
|
|
typedef NWCCODE (NWAPI DLLEXPORT *PNWREADPROPERTYVALUE)
|
|
(NWCONN_HANDLE,
|
|
const char NWFAR *,
|
|
NWOBJ_TYPE,
|
|
char NWFAR *,
|
|
unsigned char,
|
|
char NWFAR *,
|
|
NWFLAGS NWFAR *,
|
|
NWFLAGS NWFAR *);
|
|
typedef NWCCODE (NWAPI DLLEXPORT *PNWSCANOBJECT)
|
|
(NWCONN_HANDLE,
|
|
const char NWFAR *,
|
|
NWOBJ_TYPE,
|
|
NWOBJ_ID NWFAR *,
|
|
char NWFAR *,
|
|
NWOBJ_TYPE NWFAR *,
|
|
NWFLAGS NWFAR *,
|
|
NWFLAGS NWFAR *,
|
|
NWFLAGS NWFAR *);
|
|
|
|
|
|
/*=============================================================================
|
|
== Private Functions
|
|
=============================================================================*/
|
|
|
|
int AppServerFindFirstNW( NWCONN_HANDLE, LPTSTR, ULONG, LPTSTR, ULONG );
|
|
int AppServerFindNextNW( NWCONN_HANDLE, LPTSTR, ULONG, LPTSTR, ULONG );
|
|
int GetNetwareAddress( NWCONN_HANDLE, LPBYTE, LPBYTE );
|
|
int w_appsrv_ff_fn( NWCONN_HANDLE, LPTSTR, ULONG, LPTSTR, ULONG );
|
|
void FormatAddress( PBYTE, PBYTE );
|
|
|
|
|
|
/*=============================================================================
|
|
== Functions used
|
|
=============================================================================*/
|
|
|
|
int TreeAdd( LPTSTR, LPTSTR );
|
|
|
|
|
|
/*=============================================================================
|
|
== Local Data
|
|
=============================================================================*/
|
|
|
|
static long objectID = -1;
|
|
static PNWATTACHTOFILESERVER pNWAttachToFileServer = NULL;
|
|
static PNWDETACHFROMFILESERVER pNWDetachFromFileServer = NULL;
|
|
static PNWREADPROPERTYVALUE pNWReadPropertyValue = NULL;
|
|
static PNWSCANOBJECT pNWScanObject = NULL;
|
|
|
|
/*=============================================================================
|
|
== Global Data
|
|
=============================================================================*/
|
|
|
|
extern USHORT fAddress;
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* NwEnumerate
|
|
*
|
|
* NwEnumerate adds all the hydra application servers on a netware network
|
|
* to a binary tree
|
|
*
|
|
* ENTRY:
|
|
* nothing
|
|
*
|
|
* EXIT:
|
|
* ERROR_SUCCESS - no error
|
|
*
|
|
******************************************************************************/
|
|
|
|
int
|
|
NwEnumerate()
|
|
{
|
|
NWCONN_HANDLE hConn;
|
|
WCHAR abName[MAXNAME];
|
|
WCHAR Address[MAXADDRESS];
|
|
int rc;
|
|
HINSTANCE hinst;
|
|
|
|
/*
|
|
* Load NWAPI32.DLL
|
|
*/
|
|
if ( (hinst = LoadLibrary( PSZ_NWAPI32 )) == NULL ) {
|
|
return( ERROR_DLL_NOT_FOUND );
|
|
}
|
|
|
|
/*
|
|
* Load pointers to the NWAPI32 APIs that we'll need.
|
|
*/
|
|
if ( (((FARPROC)pNWAttachToFileServer = GetProcAddress( hinst, PSZ_NWATTACHTOFILESERVER )) == NULL) ||
|
|
(((FARPROC)pNWDetachFromFileServer = GetProcAddress( hinst, PSZ_NWDETACHFROMFILESERVER )) == NULL) ||
|
|
(((FARPROC)pNWReadPropertyValue = GetProcAddress( hinst, PSZ_NWREADPROPERTYVALUE )) == NULL) ||
|
|
(((FARPROC) pNWScanObject = GetProcAddress( hinst, PSZ_NWSCANOBJECT )) == NULL) ) {
|
|
|
|
FreeLibrary( hinst );
|
|
return( ERROR_PROC_NOT_FOUND );
|
|
}
|
|
|
|
/*
|
|
* Attach to novell file server
|
|
*/
|
|
if ( rc = (*pNWAttachToFileServer)( "*", 0, &hConn ) )
|
|
goto badattach;
|
|
|
|
/*
|
|
* Get first appserver
|
|
*/
|
|
if ( rc = AppServerFindFirstNW( hConn, abName, sizeof(abName), Address, sizeof(Address) ) )
|
|
goto badfirst;
|
|
|
|
/*
|
|
* Get remaining appservers
|
|
*/
|
|
while ( rc == ERROR_SUCCESS ) {
|
|
|
|
/*
|
|
* Add appserver name to binary tree
|
|
*/
|
|
if ( rc = TreeAdd( abName, Address ) )
|
|
goto badadd;
|
|
|
|
/*
|
|
* Get next appserver name
|
|
*/
|
|
rc = AppServerFindNextNW( hConn, abName, sizeof(abName), Address, sizeof(Address) );
|
|
}
|
|
|
|
/*
|
|
* Detach from file server
|
|
*/
|
|
(void) (*pNWDetachFromFileServer)( hConn );
|
|
|
|
FreeLibrary( hinst );
|
|
return( ERROR_SUCCESS );
|
|
|
|
|
|
/*=============================================================================
|
|
== Error returns
|
|
=============================================================================*/
|
|
|
|
/*
|
|
* binary tree name add failed
|
|
* error getting first appserver name
|
|
*/
|
|
badadd:
|
|
badfirst:
|
|
(void) (*pNWDetachFromFileServer)( hConn );
|
|
|
|
/*
|
|
* Attach failed
|
|
*/
|
|
badattach:
|
|
return( rc );
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* GetNetwareAddress
|
|
*
|
|
*
|
|
* ENTRY:
|
|
*
|
|
* EXIT:
|
|
* nothing
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
|
|
int
|
|
GetNetwareAddress( NWCONN_HANDLE hConn, LPBYTE pAppServer, LPBYTE pAddress )
|
|
{
|
|
int rc;
|
|
unsigned char more;
|
|
unsigned char PropFlags;
|
|
|
|
/* Get property value */
|
|
rc = (*pNWReadPropertyValue)( hConn,
|
|
pAppServer, // IN: object name
|
|
CITRIX_APPLICATION_SERVER_SWAP, // IN: objectType
|
|
"NET_ADDRESS", // IN:
|
|
1, // IN: 1st buffer
|
|
pAddress, // OUT: Buffer to put Address
|
|
&more, // OUT: 0 == no more 128 segment
|
|
// ff == more 128 segments
|
|
&PropFlags ); // OUT: optional
|
|
|
|
return( rc );
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* AppServerFindFirstNW
|
|
*
|
|
*
|
|
* ENTRY:
|
|
*
|
|
* EXIT:
|
|
* nothing
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
|
|
int
|
|
AppServerFindFirstNW( NWCONN_HANDLE hConn,
|
|
LPTSTR pAppServer, ULONG NameLength,
|
|
LPTSTR pAddress, ULONG AddrLength )
|
|
{
|
|
objectID = -1;
|
|
return( w_appsrv_ff_fn( hConn, pAppServer, NameLength, pAddress, AddrLength ) );
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* AppServerFindNextNW
|
|
*
|
|
*
|
|
* ENTRY:
|
|
*
|
|
* EXIT:
|
|
* nothing
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
|
|
int
|
|
AppServerFindNextNW( NWCONN_HANDLE hConn,
|
|
LPTSTR pAppServer, ULONG NameLength,
|
|
LPTSTR pAddress, ULONG AddrLength )
|
|
{
|
|
return( w_appsrv_ff_fn( hConn, pAppServer, NameLength, pAddress, AddrLength ) );
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Worker routines
|
|
*
|
|
*
|
|
* ENTRY:
|
|
*
|
|
* EXIT:
|
|
* nothing
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
|
|
int
|
|
w_appsrv_ff_fn( NWCONN_HANDLE hConn,
|
|
LPTSTR pAppServer, ULONG NameLength,
|
|
LPTSTR pAddress, ULONG AddrLength )
|
|
{
|
|
int rc;
|
|
WORD objectType;
|
|
unsigned char hasPropertiesFlag = 0;
|
|
unsigned char objectFlags;
|
|
unsigned char objectSecurity;
|
|
BYTE abName[49];
|
|
BYTE Address[128];
|
|
BYTE FormatedAddress[MAXADDRESS];
|
|
ULONG ByteCount;
|
|
|
|
|
|
/* while there are still properties */
|
|
while ( hasPropertiesFlag == 0 ) {
|
|
/* scan bindery object */
|
|
if ( rc = (*pNWScanObject)( hConn,
|
|
"*",
|
|
CITRIX_APPLICATION_SERVER_SWAP,
|
|
&objectID,
|
|
abName,
|
|
&objectType,
|
|
&hasPropertiesFlag,
|
|
&objectFlags,
|
|
&objectSecurity )) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
RtlMultiByteToUnicodeN( pAppServer, NameLength, &ByteCount,
|
|
abName, (strlen(abName) + 1) );
|
|
|
|
/* get netware address */
|
|
if ( fAddress && GetNetwareAddress( hConn, abName, Address ) == ERROR_SUCCESS ) {
|
|
FormatAddress( Address, FormatedAddress );
|
|
RtlMultiByteToUnicodeN( pAddress, AddrLength, &ByteCount,
|
|
FormatedAddress, (strlen(FormatedAddress) + 1) );
|
|
} else {
|
|
pAddress[0] = '\0';
|
|
}
|
|
|
|
return( rc );
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FormatAddress
|
|
*
|
|
*
|
|
* ENTRY:
|
|
*
|
|
* EXIT:
|
|
* nothing
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
void
|
|
FormatAddress( PBYTE pInternetAddress, PBYTE pszAddress )
|
|
{
|
|
USHORT i;
|
|
USHORT j;
|
|
USHORT firstPass;
|
|
BYTE buf2[5];
|
|
|
|
/* squish leading 0s on network address 1st */
|
|
firstPass = TRUE;
|
|
pszAddress[0] = '[';
|
|
pszAddress[1] = '\0';
|
|
for ( i=0; i<3; i++ ) {
|
|
j=i;
|
|
if ( pInternetAddress[i] ) {
|
|
sprintf( buf2, "%2X", pInternetAddress[i] );
|
|
strcat( pszAddress, buf2 );
|
|
firstPass = FALSE;
|
|
break;
|
|
}
|
|
else {
|
|
strcat( pszAddress, " " );
|
|
}
|
|
}
|
|
|
|
/* remaining bytes */
|
|
for ( i=++j; i<4; i++ ) {
|
|
if ( firstPass )
|
|
sprintf( buf2, "%2X", pInternetAddress[i] );
|
|
else
|
|
sprintf( buf2, "%02X", pInternetAddress[i] );
|
|
strcat( pszAddress, buf2 );
|
|
firstPass = FALSE;
|
|
}
|
|
strcat( pszAddress, "][" );
|
|
|
|
/* squish leading 0s on network address 2nd */
|
|
firstPass = TRUE;
|
|
for ( i=4; i<10; i++ ) {
|
|
j=i;
|
|
if ( pInternetAddress[i] ) {
|
|
sprintf( buf2, "%2X", pInternetAddress[i] );
|
|
strcat( pszAddress, buf2 );
|
|
firstPass = FALSE;
|
|
break;
|
|
}
|
|
else {
|
|
strcat( pszAddress, " " );
|
|
}
|
|
}
|
|
|
|
/* remaining bytes */
|
|
for ( i=++j; i<10; i++ ) {
|
|
if ( firstPass )
|
|
sprintf( buf2, "%2X", pInternetAddress[i] );
|
|
else
|
|
sprintf( buf2, "%02X", pInternetAddress[i] );
|
|
strcat( pszAddress, buf2 );
|
|
firstPass = FALSE;
|
|
}
|
|
strcat( pszAddress, "]" );
|
|
}
|
|
|