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.

323 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. srvr_lm.c
  5. Abstract:
  6. This file contains the routines which actually call Lan Manager and
  7. retrieve the contents of the domain server table, including cacheing.
  8. Environment:
  9. User Mode - Win32
  10. Revision History:
  11. 10-May-1996 DonRyan
  12. Removed banner from Technology Dynamics, Inc.
  13. --*/
  14. //--------------------------- WINDOWS DEPENDENCIES --------------------------
  15. //--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
  16. #ifdef WIN32
  17. #include <windows.h>
  18. #include <lm.h>
  19. #endif
  20. #include <tchar.h>
  21. #include <string.h>
  22. #include <search.h>
  23. #include <stdlib.h>
  24. #include <time.h>
  25. //--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
  26. #include "mib.h"
  27. #include "mibfuncs.h"
  28. #include "srvr_tbl.h"
  29. #include "lmcache.h"
  30. //--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
  31. //--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
  32. //--------------------------- PRIVATE CONSTANTS -----------------------------
  33. #define SafeBufferFree(x) if(NULL != x) NetApiBufferFree( x )
  34. #define SafeFree(x) if(NULL != x) SnmpUtilMemFree( x )
  35. //--------------------------- PRIVATE STRUCTS -------------------------------
  36. //--------------------------- PRIVATE VARIABLES -----------------------------
  37. //--------------------------- PRIVATE PROTOTYPES ----------------------------
  38. //--------------------------- PRIVATE PROCEDURES ----------------------------
  39. int __cdecl srvr_entry_cmp(
  40. IN const DOM_SERVER_ENTRY *A,
  41. IN const DOM_SERVER_ENTRY *B
  42. ) ;
  43. void build_srvr_entry_oids( );
  44. //--------------------------- PUBLIC PROCEDURES -----------------------------
  45. //
  46. // MIB_srvr_lmget
  47. // Retrieve domain server table information from Lan Manager.
  48. // If not cached, sort it and then
  49. // cache it.
  50. //
  51. // Notes:
  52. //
  53. // Return Codes:
  54. // SNMPAPI_NOERROR
  55. // SNMPAPI_ERROR
  56. //
  57. // Error Codes:
  58. // None.
  59. //
  60. SNMPAPI MIB_svsond_lmget()
  61. {
  62. DWORD entriesread;
  63. DWORD totalentries;
  64. LPBYTE bufptr;
  65. unsigned lmCode;
  66. unsigned i;
  67. SERVER_INFO_100 *DataTable;
  68. DOM_SERVER_ENTRY *MIB_DomServerTableElement ;
  69. int First_of_this_block;
  70. time_t curr_time ;
  71. SNMPAPI nResult = SNMPAPI_NOERROR;
  72. DWORD resumehandle=0;
  73. time(&curr_time); // get the time
  74. //
  75. //
  76. // If cached, return piece of info.
  77. //
  78. //
  79. if((NULL != cache_table[C_SRVR_TABLE].bufptr) &&
  80. (curr_time < (cache_table[C_SRVR_TABLE].acquisition_time + cache_expire[C_SRVR_TABLE]))
  81. )
  82. { // it has NOT expired!
  83. goto Exit ; // the global table is valid
  84. }
  85. // free the old table LOOK OUT!!
  86. MIB_DomServerTableElement = MIB_DomServerTable.Table ;
  87. // iterate over the whole table
  88. for(i=0; i<MIB_DomServerTable.Len ;i++)
  89. {
  90. // free any alloc'ed elements of the structure
  91. SnmpUtilOidFree(&(MIB_DomServerTableElement->Oid));
  92. SafeFree(MIB_DomServerTableElement->domServerName.stream);
  93. MIB_DomServerTableElement ++ ; // increment table entry
  94. }
  95. SafeFree(MIB_DomServerTable.Table) ; // free the base Table
  96. MIB_DomServerTable.Table = NULL ; // just for safety
  97. MIB_DomServerTable.Len = 0 ; // just for safety
  98. First_of_this_block = 0;
  99. do
  100. {
  101. // as long as there is more data to process
  102. //
  103. //
  104. // Do network call to gather information and put it in a nice array
  105. //
  106. //
  107. lmCode = NetServerEnum(
  108. NULL, // local server NT_PROBLEM
  109. 100, // level 100
  110. &bufptr, // data structure to return
  111. MAX_PREFERRED_LENGTH,
  112. &entriesread,
  113. &totalentries,
  114. SV_TYPE_SERVER,
  115. NULL,
  116. &resumehandle // resume handle
  117. );
  118. DataTable = (SERVER_INFO_100 *) bufptr ;
  119. if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode))
  120. {
  121. // valid so process it, otherwise error
  122. if(0 == MIB_DomServerTable.Len)
  123. {
  124. // 1st time, alloc the whole table
  125. // alloc the table space
  126. MIB_DomServerTable.Table = SnmpUtilMemAlloc(totalentries * sizeof(DOM_SERVER_ENTRY) );
  127. if (MIB_DomServerTable.Table == NULL)
  128. {
  129. // free all of the lan man data
  130. SafeBufferFree( bufptr ) ;
  131. // Signal error
  132. nResult = SNMPAPI_ERROR;
  133. goto Exit;
  134. }
  135. }
  136. MIB_DomServerTableElement = MIB_DomServerTable.Table + First_of_this_block ;
  137. for(i=0; i<entriesread; i++)
  138. {
  139. // once for each entry in the buffer
  140. // increment the entry number
  141. MIB_DomServerTable.Len ++;
  142. // Stuff the data into each item in the table
  143. MIB_DomServerTableElement->domServerName.dynamic = TRUE;
  144. #ifdef UNICODE
  145. if (SnmpUtilUnicodeToUTF8(
  146. &MIB_DomServerTableElement->domServerName.stream,
  147. DataTable->sv100_name,
  148. TRUE))
  149. {
  150. MIB_DomServerTableElement->domServerName.stream = NULL;
  151. }
  152. else
  153. {
  154. MIB_DomServerTableElement->domServerName.length =
  155. strlen(MIB_DomServerTableElement->domServerName.stream);
  156. }
  157. #else
  158. MIB_DomServerTableElement->domServerName.stream = SnmpUtilMemAlloc(strlen( DataTable->sv100_name ) + 1 );
  159. MIB_DomServerTableElement->domServerName.length = strlen( DataTable->sv100_name ) ;
  160. // client name
  161. memcpy(
  162. MIB_DomServerTableElement->domServerName.stream,
  163. DataTable->sv100_name,
  164. strlen(DataTable->sv100_name)) ;
  165. #endif
  166. MIB_DomServerTableElement ++ ; // and table entry
  167. DataTable ++ ; // advance pointer to next sess entry in buffer
  168. } // for each entry in the data table
  169. // free all of the lan man data
  170. SafeBufferFree( bufptr ) ;
  171. // indicate where to start adding on next pass, if any
  172. First_of_this_block = i ;
  173. } // if data is valid to process
  174. else
  175. {
  176. // if ERROR_NO_BROWSER_SERVERS_FOUND we are not running in an NetBIOS environment
  177. // in this case we will have an empty table.
  178. nResult = (lmCode == ERROR_NO_BROWSER_SERVERS_FOUND) ? SNMPAPI_NOERROR : SNMPAPI_ERROR;
  179. goto Exit;
  180. }
  181. } while (ERROR_MORE_DATA == lmCode) ;
  182. // iterate over the table populating the Oid field
  183. build_srvr_entry_oids();
  184. // Sort the table information using MSC QuickSort routine
  185. qsort( &MIB_DomServerTable.Table[0], MIB_DomServerTable.Len,
  186. sizeof(DOM_SERVER_ENTRY), srvr_entry_cmp );
  187. //
  188. //
  189. // Cache table
  190. //
  191. //
  192. if(0 != MIB_DomServerTable.Len)
  193. {
  194. cache_table[C_SRVR_TABLE].acquisition_time = curr_time ;
  195. cache_table[C_SRVR_TABLE].bufptr = bufptr ;
  196. }
  197. //
  198. //
  199. // Return piece of information requested
  200. //
  201. //
  202. Exit:
  203. return nResult;
  204. } // MIB_srvr_get
  205. //
  206. // MIB_srvr_cmp
  207. // Routine for sorting the session table.
  208. //
  209. // Notes:
  210. //
  211. // Return Codes:
  212. // SNMPAPI_NOERROR
  213. // SNMPAPI_ERROR
  214. //
  215. // Error Codes:
  216. // None.
  217. //
  218. int __cdecl srvr_entry_cmp(
  219. IN const DOM_SERVER_ENTRY *A,
  220. IN const DOM_SERVER_ENTRY *B
  221. )
  222. {
  223. // Compare the OID's
  224. return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
  225. (AsnObjectIdentifier *)&B->Oid );
  226. } // MIB_srvr_cmp
  227. //
  228. // None.
  229. //
  230. void build_srvr_entry_oids(
  231. )
  232. {
  233. AsnOctetString OSA ;
  234. DOM_SERVER_ENTRY *DomServerEntry ;
  235. unsigned i;
  236. // start pointer at 1st guy in the table
  237. DomServerEntry = MIB_DomServerTable.Table ;
  238. // now iterate over the table, creating an oid for each entry
  239. for( i=0; i<MIB_DomServerTable.Len ; i++) {
  240. // for each entry in the session table
  241. OSA.stream = DomServerEntry->domServerName.stream ;
  242. OSA.length = DomServerEntry->domServerName.length ;
  243. OSA.dynamic = FALSE;
  244. // Make the entry's OID from string index
  245. MakeOidFromStr( &OSA, &DomServerEntry->Oid );
  246. DomServerEntry++; // point to the next guy in the table
  247. } // for
  248. } // build_srvr_entry_oids
  249. //-------------------------------- END --------------------------------------