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.

344 lines
8.2 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. void build_srvc_entry_oids( );
  44. //--------------------------- PRIVATE PROCEDURES ----------------------------
  45. //--------------------------- PUBLIC PROCEDURES -----------------------------
  46. //
  47. // MIB_srvc_lmget
  48. // Retrieve srvcion table information from Lan Manager.
  49. // If not cached, sort it and then
  50. // cache it.
  51. //
  52. // Notes:
  53. //
  54. // Return Codes:
  55. // SNMPAPI_NOERROR
  56. // SNMPAPI_ERROR
  57. //
  58. // Error Codes:
  59. // None.
  60. //
  61. SNMPAPI MIB_srvcs_lmget(
  62. )
  63. {
  64. DWORD entriesread;
  65. DWORD totalentries;
  66. LPBYTE bufptr;
  67. unsigned lmCode;
  68. unsigned i;
  69. SERVICE_INFO_2 *DataTable;
  70. SRVC_ENTRY *MIB_SrvcTableElement ;
  71. int First_of_this_block;
  72. time_t curr_time ;
  73. SNMPAPI nResult = SNMPAPI_NOERROR;
  74. DWORD resumehandle=0;
  75. #ifdef UNICODE
  76. LPSTR stream;
  77. #endif
  78. time(&curr_time); // get the time
  79. //
  80. //
  81. // If cached, return piece of info.
  82. //
  83. //
  84. if((NULL != cache_table[C_SRVC_TABLE].bufptr) &&
  85. (curr_time <
  86. (cache_table[C_SRVC_TABLE].acquisition_time
  87. + cache_expire[C_SRVC_TABLE] ) ) )
  88. { // it has NOT expired!
  89. goto Exit ; // the global table is valid
  90. }
  91. //
  92. //
  93. // Do network call to gather information and put it in a nice array
  94. //
  95. //
  96. //
  97. // remember to free the existing data
  98. //
  99. MIB_SrvcTableElement = MIB_SrvcTable.Table ;
  100. // iterate over the whole table
  101. for(i=0; i<MIB_SrvcTable.Len ;i++)
  102. {
  103. // free any alloc'ed elements of the structure
  104. SnmpUtilOidFree(&(MIB_SrvcTableElement->Oid));
  105. SafeFree(MIB_SrvcTableElement->svSvcName.stream);
  106. MIB_SrvcTableElement ++ ; // increment table entry
  107. }
  108. SafeFree(MIB_SrvcTable.Table) ; // free the base Table
  109. MIB_SrvcTable.Table = NULL ; // just for safety
  110. MIB_SrvcTable.Len = 0 ; // just for safety
  111. First_of_this_block = 0;
  112. do { // as long as there is more data to process
  113. lmCode =
  114. NetServiceEnum( NULL, // local server
  115. 2, // level 2
  116. &bufptr, // data structure to return
  117. MAX_PREFERRED_LENGTH,
  118. &entriesread,
  119. &totalentries,
  120. &resumehandle // resume handle
  121. );
  122. DataTable = (SERVICE_INFO_2 *) bufptr ;
  123. if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode))
  124. { // valid so process it, otherwise error
  125. if(0 == MIB_SrvcTable.Len) { // 1st time, alloc the whole table
  126. // alloc the table space
  127. MIB_SrvcTable.Table = SnmpUtilMemAlloc(totalentries *
  128. sizeof(SRVC_ENTRY) );
  129. // prefix bugs 445185 and 445186
  130. if (MIB_SrvcTable.Table == NULL) {
  131. // free all of the lan man data
  132. SafeBufferFree( bufptr ) ;
  133. // Signal error
  134. nResult = SNMPAPI_ERROR;
  135. goto Exit;
  136. }
  137. }
  138. MIB_SrvcTableElement = MIB_SrvcTable.Table + First_of_this_block ;
  139. for(i=0; i<entriesread; i++) { // once for each entry in the buffer
  140. // increment the entry number
  141. MIB_SrvcTable.Len ++;
  142. // Stuff the data into each item in the table
  143. MIB_SrvcTableElement->svSvcName.dynamic = TRUE;
  144. #ifdef UNICODE
  145. if (SnmpUtilUnicodeToUTF8(
  146. &MIB_SrvcTableElement->svSvcName.stream,
  147. DataTable->svci2_display_name,
  148. TRUE))
  149. {
  150. MIB_SrvcTableElement->svSvcName.length = 0;
  151. MIB_SrvcTableElement->svSvcName.stream = NULL;
  152. }
  153. else
  154. {
  155. MIB_SrvcTableElement->svSvcName.length =
  156. strlen(MIB_SrvcTableElement->svSvcName.stream);
  157. }
  158. #else
  159. // service name
  160. MIB_SrvcTableElement->svSvcName.stream = SnmpUtilMemAlloc (
  161. strlen( DataTable->svci2_display_name ) + 1) ;
  162. memcpy( MIB_SrvcTableElement->svSvcName.stream,
  163. DataTable->svci2_display_name,
  164. strlen( DataTable->svci2_display_name ) + 1) ;
  165. MIB_SrvcTableElement->svSvcName.length =
  166. strlen( MIB_SrvcTableElement->svSvcName.stream )) ;
  167. #endif
  168. MIB_SrvcTableElement->svSvcInstalledState =
  169. (DataTable->svci2_status & 0x03) + 1;
  170. MIB_SrvcTableElement->svSvcOperatingState =
  171. ((DataTable->svci2_status>>2) & 0x03) + 1;
  172. MIB_SrvcTableElement->svSvcCanBeUninstalled =
  173. ((DataTable->svci2_status>>4) & 0x01) + 1;
  174. MIB_SrvcTableElement->svSvcCanBePaused =
  175. ((DataTable->svci2_status>>5) & 0x01) + 1;
  176. DataTable ++ ; // advance pointer to next srvc entry in buffer
  177. MIB_SrvcTableElement ++ ; // and table entry
  178. } // for each entry in the data table
  179. // free all of the lan man data
  180. SafeBufferFree( bufptr ) ;
  181. // indicate where to start adding on next pass, if any
  182. First_of_this_block = i ;
  183. } // if data is valid to process
  184. else
  185. {
  186. // Signal error
  187. nResult = SNMPAPI_ERROR;
  188. goto Exit;
  189. }
  190. } while (ERROR_MORE_DATA == lmCode) ;
  191. // iterate over the table populating the Oid field
  192. build_srvc_entry_oids();
  193. // Sort the table information using MSC QuickSort routine
  194. qsort( &MIB_SrvcTable.Table[0], MIB_SrvcTable.Len,
  195. sizeof(SRVC_ENTRY), srvc_entry_cmp );
  196. //
  197. //
  198. // Cache table
  199. //
  200. //
  201. if(0 != MIB_SrvcTable.Len) {
  202. cache_table[C_SRVC_TABLE].acquisition_time = curr_time ;
  203. cache_table[C_SRVC_TABLE].bufptr = bufptr ;
  204. }
  205. //
  206. //
  207. // Return piece of information requested
  208. //
  209. //
  210. Exit:
  211. return nResult;
  212. } // MIB_srvc_get
  213. //
  214. // MIB_srvc_cmp
  215. // Routine for sorting the srvcion table.
  216. //
  217. // Notes:
  218. //
  219. // Return Codes:
  220. // SNMPAPI_NOERROR
  221. // SNMPAPI_ERROR
  222. //
  223. // Error Codes:
  224. // None.
  225. //
  226. int __cdecl srvc_entry_cmp(
  227. IN const SRVC_ENTRY *A,
  228. IN const SRVC_ENTRY *B
  229. )
  230. {
  231. // Compare the OID's
  232. return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
  233. (AsnObjectIdentifier *)&B->Oid );
  234. } // MIB_srvc_cmp
  235. //
  236. // None.
  237. //
  238. void build_srvc_entry_oids(
  239. )
  240. {
  241. AsnOctetString OSA ;
  242. SRVC_ENTRY *SrvcEntry ;
  243. unsigned i;
  244. // start pointer at 1st guy in the table
  245. SrvcEntry = MIB_SrvcTable.Table ;
  246. // now iterate over the table, creating an oid for each entry
  247. for( i=0; i<MIB_SrvcTable.Len ; i++) {
  248. // for each entry in the srvc table
  249. OSA.stream = SrvcEntry->svSvcName.stream;
  250. OSA.length = SrvcEntry->svSvcName.length;
  251. OSA.dynamic = FALSE;
  252. // Make the entry's OID from string index
  253. MakeOidFromStr( &OSA, &SrvcEntry->Oid );
  254. SrvcEntry++; // point to the next guy in the table
  255. } // for
  256. } // build_srvc_entry_oids
  257. //-------------------------------- END --------------------------------------