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.

377 lines
9.9 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. uses_lm.c
  5. Abstract:
  6. This file contains the routines which actually call Lan Manager and
  7. retrieve the contents of the workstation uses 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 "uses_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 uses_entry_cmp(
  40. IN const WKSTA_USES_ENTRY *A,
  41. IN const WKSTA_USES_ENTRY *B
  42. ) ;
  43. void build_uses_entry_oids( );
  44. //--------------------------- PUBLIC PROCEDURES -----------------------------
  45. //
  46. // MIB_wsuses_lmget
  47. // Retrieve workstation uses 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_wsuses_lmget(
  61. )
  62. {
  63. DWORD entriesread;
  64. DWORD totalentries;
  65. LPBYTE bufptr;
  66. unsigned lmCode;
  67. unsigned i;
  68. USE_INFO_1 *DataTable;
  69. WKSTA_USES_ENTRY *MIB_WkstaUsesTableElement ;
  70. int First_of_this_block;
  71. time_t curr_time ;
  72. SNMPAPI nResult = SNMPAPI_NOERROR;
  73. DWORD resumehandle=0;
  74. time(&curr_time); // get the time
  75. //
  76. //
  77. // If cached, return piece of info.
  78. //
  79. //
  80. if((NULL != cache_table[C_USES_TABLE].bufptr) &&
  81. (curr_time <
  82. (cache_table[C_USES_TABLE].acquisition_time
  83. + cache_expire[C_USES_TABLE] ) ) )
  84. { // it has NOT expired!
  85. goto Exit ; // the global table is valid
  86. }
  87. //
  88. //
  89. // Do network call to gather information and put it in a nice array
  90. //
  91. //
  92. // free the old table LOOK OUT!!
  93. MIB_WkstaUsesTableElement = MIB_WkstaUsesTable.Table ;
  94. // iterate over the whole table
  95. for(i=0; i<MIB_WkstaUsesTable.Len ;i++)
  96. {
  97. // free any alloc'ed elements of the structure
  98. SnmpUtilOidFree(&(MIB_WkstaUsesTableElement->Oid));
  99. SafeFree(MIB_WkstaUsesTableElement->useLocalName.stream);
  100. SafeFree(MIB_WkstaUsesTableElement->useRemote.stream);
  101. MIB_WkstaUsesTableElement ++ ; // increment table entry
  102. }
  103. SafeFree(MIB_WkstaUsesTable.Table) ; // free the base Table
  104. MIB_WkstaUsesTable.Table = NULL ; // just for safety
  105. MIB_WkstaUsesTable.Len = 0 ; // just for safety
  106. #if 0 // done above
  107. // init the length
  108. MIB_WkstaUsesTable.Len = 0;
  109. #endif
  110. First_of_this_block = 0;
  111. do { // as long as there is more data to process
  112. lmCode =
  113. NetUseEnum( NULL, // local server
  114. 1, // level 1, no admin priv.
  115. &bufptr, // data structure to return
  116. MAX_PREFERRED_LENGTH,
  117. &entriesread,
  118. &totalentries,
  119. &resumehandle // resume handle
  120. );
  121. DataTable = (USE_INFO_1 *) bufptr ;
  122. if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode))
  123. { // valid so process it, otherwise error
  124. if(0 == MIB_WkstaUsesTable.Len) { // 1st time, alloc the whole table
  125. // alloc the table space
  126. MIB_WkstaUsesTable.Table = SnmpUtilMemAlloc(totalentries *
  127. sizeof(WKSTA_USES_ENTRY) );
  128. // prefix bugs 445182
  129. if (MIB_WkstaUsesTable.Table == NULL) {
  130. // free all of the lan man data
  131. SafeBufferFree( bufptr ) ;
  132. // Signal error
  133. nResult = SNMPAPI_ERROR;
  134. goto Exit;
  135. }
  136. }
  137. MIB_WkstaUsesTableElement = MIB_WkstaUsesTable.Table + First_of_this_block ;
  138. for(i=0; i<entriesread; i++) { // once for each entry in the buffer
  139. // increment the entry number
  140. MIB_WkstaUsesTable.Len ++;
  141. // Stuff the data into each item in the table
  142. // client name
  143. MIB_WkstaUsesTableElement->useLocalName.dynamic = TRUE;
  144. #ifdef UNICODE
  145. if (SnmpUtilUnicodeToUTF8(
  146. &MIB_WkstaUsesTableElement->useLocalName.stream,
  147. DataTable->ui1_local,
  148. TRUE))
  149. {
  150. MIB_WkstaUsesTableElement->useLocalName.length = 0;
  151. MIB_WkstaUsesTableElement->useLocalName.stream = NULL;
  152. }
  153. else
  154. {
  155. MIB_WkstaUsesTableElement->useLocalName.length =
  156. strlen(MIB_WkstaUsesTableElement->useLocalName.stream);
  157. }
  158. #else
  159. MIB_WkstaUsesTableElement->useLocalName.stream = SnmpUtilMemAlloc (
  160. strlen( DataTable->ui1_local ) + 1 ) ;
  161. MIB_WkstaUsesTableElement->useLocalName.length =
  162. strlen( DataTable->ui1_local ) ;
  163. memcpy( MIB_WkstaUsesTableElement->useLocalName.stream,
  164. DataTable->ui1_local,
  165. strlen( DataTable->ui1_local ) ) ;
  166. #endif
  167. // remote name
  168. MIB_WkstaUsesTableElement->useRemote.dynamic = TRUE;
  169. #ifdef UNICODE
  170. if (SnmpUtilUnicodeToUTF8(
  171. &MIB_WkstaUsesTableElement->useRemote.stream,
  172. DataTable->ui1_remote,
  173. TRUE))
  174. {
  175. MIB_WkstaUsesTableElement->useRemote.length = 0;
  176. MIB_WkstaUsesTableElement->useRemote.stream = NULL;
  177. }
  178. else
  179. {
  180. MIB_WkstaUsesTableElement->useRemote.length =
  181. strlen(MIB_WkstaUsesTableElement->useRemote.stream);
  182. }
  183. #else
  184. MIB_WkstaUsesTableElement->useRemote.stream = SnmpUtilMemAlloc (
  185. strlen( DataTable->ui1_remote ) + 1 ) ;
  186. MIB_WkstaUsesTableElement->useRemote.length =
  187. strlen( DataTable->ui1_remote ) ;
  188. memcpy( MIB_WkstaUsesTableElement->useRemote.stream,
  189. DataTable->ui1_remote,
  190. strlen( DataTable->ui1_remote ) ) ;
  191. #endif
  192. // status
  193. MIB_WkstaUsesTableElement->useStatus =
  194. DataTable->ui1_status ;
  195. MIB_WkstaUsesTableElement ++ ; // and table entry
  196. DataTable ++ ; // advance pointer to next sess entry in buffer
  197. } // for each entry in the data table
  198. // free all of the lan man data
  199. SafeBufferFree( bufptr ) ;
  200. // indicate where to start adding on next pass, if any
  201. First_of_this_block = i ;
  202. } // if data is valid to process
  203. else
  204. {
  205. // Signal error
  206. nResult = SNMPAPI_ERROR;
  207. goto Exit;
  208. }
  209. } while (ERROR_MORE_DATA == lmCode) ;
  210. // iterate over the table populating the Oid field
  211. build_uses_entry_oids();
  212. // Sort the table information using MSC QuickSort routine
  213. qsort( &MIB_WkstaUsesTable.Table[0], MIB_WkstaUsesTable.Len,
  214. sizeof(WKSTA_USES_ENTRY), uses_entry_cmp );
  215. //
  216. //
  217. // Cache table
  218. //
  219. //
  220. if(0 != MIB_WkstaUsesTable.Len) {
  221. cache_table[C_USES_TABLE].acquisition_time = curr_time ;
  222. cache_table[C_USES_TABLE].bufptr = bufptr ;
  223. }
  224. //
  225. //
  226. // Return piece of information requested
  227. //
  228. //
  229. Exit:
  230. return nResult;
  231. } // MIB_uses_get
  232. //
  233. // MIB_uses_cmp
  234. // Routine for sorting the session table.
  235. //
  236. // Notes:
  237. //
  238. // Return Codes:
  239. // SNMPAPI_NOERROR
  240. // SNMPAPI_ERROR
  241. //
  242. // Error Codes:
  243. // None.
  244. //
  245. int __cdecl uses_entry_cmp(
  246. IN const WKSTA_USES_ENTRY *A,
  247. IN const WKSTA_USES_ENTRY *B
  248. )
  249. {
  250. // Compare the OID's
  251. return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
  252. (AsnObjectIdentifier *)&B->Oid );
  253. } // MIB_uses_cmp
  254. //
  255. // None.
  256. //
  257. void build_uses_entry_oids(
  258. )
  259. {
  260. AsnOctetString OSA ;
  261. AsnObjectIdentifier RemoteOid ;
  262. WKSTA_USES_ENTRY *WkstaUsesEntry ;
  263. unsigned i;
  264. // start pointer at 1st guy in the table
  265. WkstaUsesEntry = MIB_WkstaUsesTable.Table ;
  266. // now iterate over the table, creating an oid for each entry
  267. for( i=0; i<MIB_WkstaUsesTable.Len ; i++) {
  268. // for each entry in the session table
  269. // copy the local name into the oid buffer first
  270. MakeOidFromStr( &WkstaUsesEntry->useLocalName, &WkstaUsesEntry->Oid );
  271. // copy the remote name into a temporary oid buffer
  272. MakeOidFromStr( &WkstaUsesEntry->useRemote, &RemoteOid );
  273. // append the two entries forming the index
  274. SnmpUtilOidAppend( &WkstaUsesEntry->Oid, &RemoteOid );
  275. // free the temporary buffer
  276. SnmpUtilOidFree( &RemoteOid );
  277. WkstaUsesEntry++; // point to the next guy in the table
  278. } // for
  279. } // build_uses_entry_oids
  280. //-------------------------------- END --------------------------------------