Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

430 lines
11 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*************************************************************************
  3. *
  4. * NWLAN.C
  5. *
  6. * Name Enumerator for Novell Netware
  7. *
  8. *
  9. *************************************************************************/
  10. /*
  11. * Includes
  12. */
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <icaipx.h>
  21. #include <nwapi32.h>
  22. #include "qappsrv.h"
  23. /*=============================================================================
  24. == External Functions Defined
  25. =============================================================================*/
  26. int NwEnumerate( void );
  27. /*=============================================================================
  28. == LoadLibrary/GetProcAddress stuff for NWAPI32.DLL
  29. =============================================================================*/
  30. /*
  31. * NWAPI32.DLL stuff
  32. */
  33. #define PSZ_NWAPI32 TEXT("NWAPI32.DLL")
  34. #define PSZ_NWATTACHTOFILESERVER "NWAttachToFileServer"
  35. #define PSZ_NWDETACHFROMFILESERVER "NWDetachFromFileServer"
  36. #define PSZ_NWREADPROPERTYVALUE "NWReadPropertyValue"
  37. #define PSZ_NWSCANOBJECT "NWScanObject"
  38. typedef NWCCODE (NWAPI DLLEXPORT *PNWATTACHTOFILESERVER)
  39. (const char NWFAR *,
  40. NWLOCAL_SCOPE,
  41. NWCONN_HANDLE NWFAR *);
  42. typedef NWCCODE (NWAPI DLLEXPORT *PNWDETACHFROMFILESERVER)
  43. (NWCONN_HANDLE);
  44. typedef NWCCODE (NWAPI DLLEXPORT *PNWREADPROPERTYVALUE)
  45. (NWCONN_HANDLE,
  46. const char NWFAR *,
  47. NWOBJ_TYPE,
  48. char NWFAR *,
  49. unsigned char,
  50. char NWFAR *,
  51. NWFLAGS NWFAR *,
  52. NWFLAGS NWFAR *);
  53. typedef NWCCODE (NWAPI DLLEXPORT *PNWSCANOBJECT)
  54. (NWCONN_HANDLE,
  55. const char NWFAR *,
  56. NWOBJ_TYPE,
  57. NWOBJ_ID NWFAR *,
  58. char NWFAR *,
  59. NWOBJ_TYPE NWFAR *,
  60. NWFLAGS NWFAR *,
  61. NWFLAGS NWFAR *,
  62. NWFLAGS NWFAR *);
  63. /*=============================================================================
  64. == Private Functions
  65. =============================================================================*/
  66. int AppServerFindFirstNW( NWCONN_HANDLE, LPTSTR, ULONG, LPTSTR, ULONG );
  67. int AppServerFindNextNW( NWCONN_HANDLE, LPTSTR, ULONG, LPTSTR, ULONG );
  68. int GetNetwareAddress( NWCONN_HANDLE, LPBYTE, LPBYTE );
  69. int w_appsrv_ff_fn( NWCONN_HANDLE, LPTSTR, ULONG, LPTSTR, ULONG );
  70. void FormatAddress( PBYTE, PBYTE );
  71. /*=============================================================================
  72. == Functions used
  73. =============================================================================*/
  74. int TreeAdd( LPTSTR, LPTSTR );
  75. /*=============================================================================
  76. == Local Data
  77. =============================================================================*/
  78. static long objectID = -1;
  79. static PNWATTACHTOFILESERVER pNWAttachToFileServer = NULL;
  80. static PNWDETACHFROMFILESERVER pNWDetachFromFileServer = NULL;
  81. static PNWREADPROPERTYVALUE pNWReadPropertyValue = NULL;
  82. static PNWSCANOBJECT pNWScanObject = NULL;
  83. /*=============================================================================
  84. == Global Data
  85. =============================================================================*/
  86. extern USHORT fAddress;
  87. /*******************************************************************************
  88. *
  89. * NwEnumerate
  90. *
  91. * NwEnumerate adds all the hydra application servers on a netware network
  92. * to a binary tree
  93. *
  94. * ENTRY:
  95. * nothing
  96. *
  97. * EXIT:
  98. * ERROR_SUCCESS - no error
  99. *
  100. ******************************************************************************/
  101. int
  102. NwEnumerate()
  103. {
  104. NWCONN_HANDLE hConn;
  105. WCHAR abName[MAXNAME];
  106. WCHAR Address[MAXADDRESS];
  107. int rc;
  108. HINSTANCE hinst;
  109. /*
  110. * Load NWAPI32.DLL
  111. */
  112. if ( (hinst = LoadLibrary( PSZ_NWAPI32 )) == NULL ) {
  113. return( ERROR_DLL_NOT_FOUND );
  114. }
  115. /*
  116. * Load pointers to the NWAPI32 APIs that we'll need.
  117. */
  118. if ( (((FARPROC)pNWAttachToFileServer = GetProcAddress( hinst, PSZ_NWATTACHTOFILESERVER )) == NULL) ||
  119. (((FARPROC)pNWDetachFromFileServer = GetProcAddress( hinst, PSZ_NWDETACHFROMFILESERVER )) == NULL) ||
  120. (((FARPROC)pNWReadPropertyValue = GetProcAddress( hinst, PSZ_NWREADPROPERTYVALUE )) == NULL) ||
  121. (((FARPROC) pNWScanObject = GetProcAddress( hinst, PSZ_NWSCANOBJECT )) == NULL) ) {
  122. FreeLibrary( hinst );
  123. return( ERROR_PROC_NOT_FOUND );
  124. }
  125. /*
  126. * Attach to novell file server
  127. */
  128. if ( rc = (*pNWAttachToFileServer)( "*", 0, &hConn ) )
  129. goto badattach;
  130. /*
  131. * Get first appserver
  132. */
  133. if ( rc = AppServerFindFirstNW( hConn, abName, sizeof(abName), Address, sizeof(Address) ) )
  134. goto badfirst;
  135. /*
  136. * Get remaining appservers
  137. */
  138. while ( rc == ERROR_SUCCESS ) {
  139. /*
  140. * Add appserver name to binary tree
  141. */
  142. if ( rc = TreeAdd( abName, Address ) )
  143. goto badadd;
  144. /*
  145. * Get next appserver name
  146. */
  147. rc = AppServerFindNextNW( hConn, abName, sizeof(abName), Address, sizeof(Address) );
  148. }
  149. /*
  150. * Detach from file server
  151. */
  152. (void) (*pNWDetachFromFileServer)( hConn );
  153. FreeLibrary( hinst );
  154. return( ERROR_SUCCESS );
  155. /*=============================================================================
  156. == Error returns
  157. =============================================================================*/
  158. /*
  159. * binary tree name add failed
  160. * error getting first appserver name
  161. */
  162. badadd:
  163. badfirst:
  164. (void) (*pNWDetachFromFileServer)( hConn );
  165. /*
  166. * Attach failed
  167. */
  168. badattach:
  169. return( rc );
  170. }
  171. /*******************************************************************************
  172. *
  173. * GetNetwareAddress
  174. *
  175. *
  176. * ENTRY:
  177. *
  178. * EXIT:
  179. * nothing
  180. *
  181. *
  182. ******************************************************************************/
  183. int
  184. GetNetwareAddress( NWCONN_HANDLE hConn, LPBYTE pAppServer, LPBYTE pAddress )
  185. {
  186. int rc;
  187. unsigned char more;
  188. unsigned char PropFlags;
  189. /* Get property value */
  190. rc = (*pNWReadPropertyValue)( hConn,
  191. pAppServer, // IN: object name
  192. CITRIX_APPLICATION_SERVER_SWAP, // IN: objectType
  193. "NET_ADDRESS", // IN:
  194. 1, // IN: 1st buffer
  195. pAddress, // OUT: Buffer to put Address
  196. &more, // OUT: 0 == no more 128 segment
  197. // ff == more 128 segments
  198. &PropFlags ); // OUT: optional
  199. return( rc );
  200. }
  201. /*******************************************************************************
  202. *
  203. * AppServerFindFirstNW
  204. *
  205. *
  206. * ENTRY:
  207. *
  208. * EXIT:
  209. * nothing
  210. *
  211. *
  212. ******************************************************************************/
  213. int
  214. AppServerFindFirstNW( NWCONN_HANDLE hConn,
  215. LPTSTR pAppServer, ULONG NameLength,
  216. LPTSTR pAddress, ULONG AddrLength )
  217. {
  218. objectID = -1;
  219. return( w_appsrv_ff_fn( hConn, pAppServer, NameLength, pAddress, AddrLength ) );
  220. }
  221. /*******************************************************************************
  222. *
  223. * AppServerFindNextNW
  224. *
  225. *
  226. * ENTRY:
  227. *
  228. * EXIT:
  229. * nothing
  230. *
  231. *
  232. ******************************************************************************/
  233. int
  234. AppServerFindNextNW( NWCONN_HANDLE hConn,
  235. LPTSTR pAppServer, ULONG NameLength,
  236. LPTSTR pAddress, ULONG AddrLength )
  237. {
  238. return( w_appsrv_ff_fn( hConn, pAppServer, NameLength, pAddress, AddrLength ) );
  239. }
  240. /*******************************************************************************
  241. *
  242. * Worker routines
  243. *
  244. *
  245. * ENTRY:
  246. *
  247. * EXIT:
  248. * nothing
  249. *
  250. *
  251. ******************************************************************************/
  252. int
  253. w_appsrv_ff_fn( NWCONN_HANDLE hConn,
  254. LPTSTR pAppServer, ULONG NameLength,
  255. LPTSTR pAddress, ULONG AddrLength )
  256. {
  257. int rc;
  258. WORD objectType;
  259. unsigned char hasPropertiesFlag = 0;
  260. unsigned char objectFlags;
  261. unsigned char objectSecurity;
  262. BYTE abName[49];
  263. BYTE Address[128];
  264. BYTE FormatedAddress[MAXADDRESS];
  265. ULONG ByteCount;
  266. /* while there are still properties */
  267. while ( hasPropertiesFlag == 0 ) {
  268. /* scan bindery object */
  269. if ( rc = (*pNWScanObject)( hConn,
  270. "*",
  271. CITRIX_APPLICATION_SERVER_SWAP,
  272. &objectID,
  273. abName,
  274. &objectType,
  275. &hasPropertiesFlag,
  276. &objectFlags,
  277. &objectSecurity )) {
  278. break;
  279. }
  280. }
  281. RtlMultiByteToUnicodeN( pAppServer, NameLength, &ByteCount,
  282. abName, (strlen(abName) + 1) );
  283. /* get netware address */
  284. if ( fAddress && GetNetwareAddress( hConn, abName, Address ) == ERROR_SUCCESS ) {
  285. FormatAddress( Address, FormatedAddress );
  286. RtlMultiByteToUnicodeN( pAddress, AddrLength, &ByteCount,
  287. FormatedAddress, (strlen(FormatedAddress) + 1) );
  288. } else {
  289. pAddress[0] = '\0';
  290. }
  291. return( rc );
  292. }
  293. /*******************************************************************************
  294. *
  295. * FormatAddress
  296. *
  297. *
  298. * ENTRY:
  299. *
  300. * EXIT:
  301. * nothing
  302. *
  303. *
  304. ******************************************************************************/
  305. void
  306. FormatAddress( PBYTE pInternetAddress, PBYTE pszAddress )
  307. {
  308. USHORT i;
  309. USHORT j;
  310. USHORT firstPass;
  311. BYTE buf2[5];
  312. /* squish leading 0s on network address 1st */
  313. firstPass = TRUE;
  314. pszAddress[0] = '[';
  315. pszAddress[1] = '\0';
  316. for ( i=0; i<3; i++ ) {
  317. j=i;
  318. if ( pInternetAddress[i] ) {
  319. sprintf( buf2, "%2X", pInternetAddress[i] );
  320. strcat( pszAddress, buf2 );
  321. firstPass = FALSE;
  322. break;
  323. }
  324. else {
  325. strcat( pszAddress, " " );
  326. }
  327. }
  328. /* remaining bytes */
  329. for ( i=++j; i<4; i++ ) {
  330. if ( firstPass )
  331. sprintf( buf2, "%2X", pInternetAddress[i] );
  332. else
  333. sprintf( buf2, "%02X", pInternetAddress[i] );
  334. strcat( pszAddress, buf2 );
  335. firstPass = FALSE;
  336. }
  337. strcat( pszAddress, "][" );
  338. /* squish leading 0s on network address 2nd */
  339. firstPass = TRUE;
  340. for ( i=4; i<10; i++ ) {
  341. j=i;
  342. if ( pInternetAddress[i] ) {
  343. sprintf( buf2, "%2X", pInternetAddress[i] );
  344. strcat( pszAddress, buf2 );
  345. firstPass = FALSE;
  346. break;
  347. }
  348. else {
  349. strcat( pszAddress, " " );
  350. }
  351. }
  352. /* remaining bytes */
  353. for ( i=++j; i<10; i++ ) {
  354. if ( firstPass )
  355. sprintf( buf2, "%2X", pInternetAddress[i] );
  356. else
  357. sprintf( buf2, "%02X", pInternetAddress[i] );
  358. strcat( pszAddress, buf2 );
  359. firstPass = FALSE;
  360. }
  361. strcat( pszAddress, "]" );
  362. }