Leaked source code of windows server 2003
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.

372 lines
10 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. srvc_lm.c
  5. Abstract:
  6. This file contains MIB_srvc_lmget, which actually call lan manager
  7. for the srvce table, copies it into structures, and sorts it to
  8. return ready to use by the higher level functions.
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. 10-May-1996 DonRyan
  13. Removed banner from Technology Dynamics, Inc.
  14. --*/
  15. //--------------------------- WINDOWS DEPENDENCIES --------------------------
  16. //--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
  17. #ifdef WIN32
  18. #include <windows.h>
  19. #include <lm.h>
  20. #endif
  21. #include <tchar.h>
  22. #include <string.h>
  23. #include <search.h>
  24. #include <stdlib.h>
  25. #include <time.h>
  26. //--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
  27. #include "mib.h"
  28. #include "mibfuncs.h"
  29. #include "srvc_tbl.h"
  30. #include "lmcache.h"
  31. //--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
  32. //--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
  33. //--------------------------- PRIVATE CONSTANTS -----------------------------
  34. #define SafeBufferFree(x) if(NULL != x) NetApiBufferFree( x )
  35. #define SafeFree(x) if(NULL != x) SnmpUtilMemFree( x )
  36. //--------------------------- PRIVATE STRUCTS -------------------------------
  37. //--------------------------- PRIVATE VARIABLES -----------------------------
  38. //--------------------------- PRIVATE PROTOTYPES ----------------------------
  39. int __cdecl srvc_entry_cmp(
  40. IN const SRVC_ENTRY *A,
  41. IN const SRVC_ENTRY *B
  42. ) ;
  43. BOOL build_srvc_entry_oids( );
  44. void FreeSrvcTable();
  45. //--------------------------- PRIVATE PROCEDURES ----------------------------
  46. //--------------------------- PUBLIC PROCEDURES -----------------------------
  47. //
  48. // MIB_srvc_lmget
  49. // Retrieve srvcion table information from Lan Manager.
  50. // If not cached, sort it and then
  51. // cache it.
  52. //
  53. // Notes:
  54. //
  55. // Return Codes:
  56. // SNMPAPI_NOERROR
  57. // SNMPAPI_ERROR
  58. //
  59. // Error Codes:
  60. // None.
  61. //
  62. SNMPAPI MIB_srvcs_lmget(
  63. )
  64. {
  65. DWORD entriesread;
  66. DWORD totalentries;
  67. LPBYTE bufptr;
  68. unsigned lmCode;
  69. unsigned i;
  70. SERVICE_INFO_2 *DataTable;
  71. SRVC_ENTRY *MIB_SrvcTableElement ;
  72. int First_of_this_block;
  73. time_t curr_time ;
  74. SNMPAPI nResult = SNMPAPI_NOERROR;
  75. DWORD resumehandle=0;
  76. #ifdef UNICODE
  77. LPSTR stream;
  78. #endif
  79. DWORD dwAllocatedEntries=0;
  80. time(&curr_time); // get the time
  81. //
  82. //
  83. // If cached, return piece of info.
  84. //
  85. //
  86. if((NULL != cache_table[C_SRVC_TABLE].bufptr) &&
  87. (curr_time <
  88. (cache_table[C_SRVC_TABLE].acquisition_time
  89. + cache_expire[C_SRVC_TABLE] ) ) )
  90. { // it has NOT expired!
  91. goto Exit ; // the global table is valid
  92. }
  93. //
  94. //
  95. // Do network call to gather information and put it in a nice array
  96. //
  97. //
  98. //
  99. // remember to free the existing data
  100. //
  101. FreeSrvcTable();
  102. First_of_this_block = 0;
  103. do { // as long as there is more data to process
  104. lmCode =
  105. NetServiceEnum( NULL, // local server
  106. 2, // level 2
  107. &bufptr, // data structure to return
  108. MAX_PREFERRED_LENGTH,
  109. &entriesread,
  110. &totalentries,
  111. &resumehandle // resume handle
  112. );
  113. DataTable = (SERVICE_INFO_2 *) bufptr ;
  114. if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode))
  115. { // valid so process it, otherwise error
  116. if(0 == MIB_SrvcTable.Len) { // 1st time, alloc the whole table
  117. // alloc the table space
  118. MIB_SrvcTable.Table = SnmpUtilMemAlloc(totalentries *
  119. sizeof(SRVC_ENTRY) );
  120. // prefix bugs 445185 and 445186
  121. if (MIB_SrvcTable.Table == NULL) {
  122. // free all of the lan man data
  123. SafeBufferFree( bufptr ) ;
  124. // Signal error
  125. nResult = SNMPAPI_ERROR;
  126. goto Exit;
  127. }
  128. dwAllocatedEntries = totalentries;
  129. }
  130. MIB_SrvcTableElement = MIB_SrvcTable.Table + First_of_this_block ;
  131. for(i=0; (i<entriesread) && ((i+First_of_this_block) < dwAllocatedEntries); i++) { // once for each entry in the buffer
  132. // increment the entry number
  133. MIB_SrvcTable.Len ++;
  134. // Stuff the data into each item in the table
  135. MIB_SrvcTableElement->svSvcName.dynamic = TRUE;
  136. #ifdef UNICODE
  137. if (SnmpUtilUnicodeToUTF8(
  138. &MIB_SrvcTableElement->svSvcName.stream,
  139. DataTable->svci2_display_name,
  140. TRUE))
  141. {
  142. MIB_SrvcTableElement->svSvcName.length = 0;
  143. MIB_SrvcTableElement->svSvcName.stream = NULL;
  144. MIB_SrvcTableElement->svSvcName.dynamic = FALSE;
  145. }
  146. else
  147. {
  148. MIB_SrvcTableElement->svSvcName.length =
  149. strlen(MIB_SrvcTableElement->svSvcName.stream);
  150. }
  151. #else
  152. // service name
  153. MIB_SrvcTableElement->svSvcName.stream = SnmpUtilMemAlloc (
  154. strlen( DataTable->svci2_display_name ) + 1) ;
  155. memcpy( MIB_SrvcTableElement->svSvcName.stream,
  156. DataTable->svci2_display_name,
  157. strlen( DataTable->svci2_display_name ) + 1) ;
  158. MIB_SrvcTableElement->svSvcName.length =
  159. strlen( MIB_SrvcTableElement->svSvcName.stream )) ;
  160. #endif
  161. MIB_SrvcTableElement->svSvcInstalledState =
  162. (DataTable->svci2_status & 0x03) + 1;
  163. MIB_SrvcTableElement->svSvcOperatingState =
  164. ((DataTable->svci2_status>>2) & 0x03) + 1;
  165. MIB_SrvcTableElement->svSvcCanBeUninstalled =
  166. ((DataTable->svci2_status>>4) & 0x01) + 1;
  167. MIB_SrvcTableElement->svSvcCanBePaused =
  168. ((DataTable->svci2_status>>5) & 0x01) + 1;
  169. DataTable ++ ; // advance pointer to next srvc entry in buffer
  170. MIB_SrvcTableElement ++ ; // and table entry
  171. } // for each entry in the data table
  172. // free all of the lan man data
  173. SafeBufferFree( bufptr ) ;
  174. // indicate where to start adding on next pass, if any
  175. First_of_this_block += i ;
  176. } // if data is valid to process
  177. else
  178. {
  179. // Signal error
  180. nResult = SNMPAPI_ERROR;
  181. goto Exit;
  182. }
  183. } while (ERROR_MORE_DATA == lmCode) ;
  184. // iterate over the table populating the Oid field
  185. if (! build_srvc_entry_oids())
  186. {
  187. SNMPDBG((
  188. SNMP_LOG_TRACE,
  189. "SNMP: LMMIB2: build_srvc_entry_oids failed\n."));
  190. FreeSrvcTable();
  191. cache_table[C_SRVC_TABLE].bufptr = NULL;
  192. nResult = SNMPAPI_ERROR;
  193. goto Exit;
  194. }
  195. // Sort the table information using MSC QuickSort routine
  196. qsort( &MIB_SrvcTable.Table[0], MIB_SrvcTable.Len,
  197. sizeof(SRVC_ENTRY), srvc_entry_cmp );
  198. //
  199. //
  200. // Cache table
  201. //
  202. //
  203. if(0 != MIB_SrvcTable.Len) {
  204. cache_table[C_SRVC_TABLE].acquisition_time = curr_time ;
  205. cache_table[C_SRVC_TABLE].bufptr = bufptr ;
  206. }
  207. //
  208. //
  209. // Return piece of information requested
  210. //
  211. //
  212. Exit:
  213. return nResult;
  214. } // MIB_srvc_get
  215. //
  216. // MIB_srvc_cmp
  217. // Routine for sorting the srvcion table.
  218. //
  219. // Notes:
  220. //
  221. // Return Codes:
  222. // SNMPAPI_NOERROR
  223. // SNMPAPI_ERROR
  224. //
  225. // Error Codes:
  226. // None.
  227. //
  228. int __cdecl srvc_entry_cmp(
  229. IN const SRVC_ENTRY *A,
  230. IN const SRVC_ENTRY *B
  231. )
  232. {
  233. // Compare the OID's
  234. return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
  235. (AsnObjectIdentifier *)&B->Oid );
  236. } // MIB_srvc_cmp
  237. //
  238. // None.
  239. //
  240. BOOL build_srvc_entry_oids(
  241. )
  242. {
  243. AsnOctetString OSA ;
  244. SRVC_ENTRY *SrvcEntry ;
  245. unsigned i;
  246. // start pointer at 1st guy in the table
  247. SrvcEntry = MIB_SrvcTable.Table ;
  248. // now iterate over the table, creating an oid for each entry
  249. for( i=0; i<MIB_SrvcTable.Len ; i++) {
  250. // for each entry in the srvc table
  251. OSA.stream = SrvcEntry->svSvcName.stream;
  252. OSA.length = SrvcEntry->svSvcName.length;
  253. OSA.dynamic = FALSE;
  254. // Make the entry's OID from string index
  255. if (! MakeOidFromStr( &OSA, &SrvcEntry->Oid ))
  256. {
  257. return FALSE;
  258. }
  259. SrvcEntry++; // point to the next guy in the table
  260. } // for
  261. return TRUE;
  262. } // build_srvc_entry_oids
  263. void FreeSrvcTable()
  264. {
  265. UINT i;
  266. SRVC_ENTRY *MIB_SrvcTableElement ;
  267. MIB_SrvcTableElement = MIB_SrvcTable.Table ;
  268. if (MIB_SrvcTableElement)
  269. {
  270. // iterate over the whole table
  271. for(i=0; i<MIB_SrvcTable.Len ;i++)
  272. {
  273. // free any alloc'ed elements of the structure
  274. SnmpUtilOidFree(&(MIB_SrvcTableElement->Oid));
  275. SnmpUtilMemFree(MIB_SrvcTableElement->svSvcName.stream);
  276. MIB_SrvcTableElement ++ ; // increment table entry
  277. }
  278. SnmpUtilMemFree(MIB_SrvcTable.Table) ; // free the base Table
  279. }
  280. MIB_SrvcTable.Table = NULL ; // just for safety
  281. MIB_SrvcTable.Len = 0 ; // just for safety
  282. }
  283. //-------------------------------- END --------------------------------------