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.

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