WindowsXP-SP1/termsrv/admtools/qappsrv/nwlan.c
2020-09-30 16:53:49 +02:00

431 lines
12 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, "]" );
}