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.

327 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. user_lm.c
  5. Abstract:
  6. This file contains the routines which actually call Lan Manager and
  7. retrieve the contents of the user 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 <string.h>
  21. #include <search.h>
  22. #include <stdlib.h>
  23. #include <time.h>
  24. //--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
  25. #include "mib.h"
  26. #include "mibfuncs.h"
  27. #include "user_tbl.h"
  28. #include "lmcache.h"
  29. //--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
  30. //--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
  31. //--------------------------- PRIVATE CONSTANTS -----------------------------
  32. #define SafeBufferFree(x) if(NULL != x) NetApiBufferFree( x )
  33. #define SafeFree(x) if(NULL != x) SnmpUtilMemFree( x )
  34. //--------------------------- PRIVATE STRUCTS -------------------------------
  35. //--------------------------- PRIVATE VARIABLES -----------------------------
  36. //--------------------------- PRIVATE PROTOTYPES ----------------------------
  37. //--------------------------- PRIVATE PROCEDURES ----------------------------
  38. int __cdecl user_entry_cmp(
  39. IN const USER_ENTRY *A,
  40. IN const USER_ENTRY *B
  41. ) ;
  42. void build_user_entry_oids( );
  43. //--------------------------- PUBLIC PROCEDURES -----------------------------
  44. //
  45. // MIB_user_lmget
  46. // Retrieve print queue table information from Lan Manager.
  47. // If not cached, sort it and then
  48. // cache it.
  49. //
  50. // Notes:
  51. //
  52. // Return Codes:
  53. // SNMPAPI_NOERROR
  54. // SNMPAPI_ERROR
  55. //
  56. // Error Codes:
  57. // None.
  58. //
  59. SNMPAPI MIB_users_lmget(
  60. )
  61. {
  62. DWORD entriesread;
  63. DWORD totalentries;
  64. LPBYTE bufptr;
  65. unsigned lmCode;
  66. unsigned i;
  67. USER_INFO_0 *DataTable;
  68. USER_ENTRY *MIB_UserTableElement ;
  69. int First_of_this_block;
  70. LPSTR ansi_string;
  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_USER_TABLE].bufptr) &&
  81. (curr_time <
  82. (cache_table[C_USER_TABLE].acquisition_time
  83. + cache_expire[C_USER_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. //
  93. // remember to free the existing data
  94. //
  95. MIB_UserTableElement = MIB_UserTable.Table ;
  96. // iterate over the whole table
  97. for(i=0; i<MIB_UserTable.Len ;i++)
  98. {
  99. // free any alloc'ed elements of the structure
  100. SnmpUtilOidFree(&(MIB_UserTableElement->Oid));
  101. SafeFree(MIB_UserTableElement->svUserName.stream);
  102. MIB_UserTableElement ++ ; // increment table entry
  103. }
  104. SafeFree(MIB_UserTable.Table) ; // free the base Table
  105. MIB_UserTable.Table = NULL ; // just for safety
  106. MIB_UserTable.Len = 0 ; // just for safety
  107. #if 0 // done above
  108. // init the length
  109. MIB_UserTable.Len = 0;
  110. #endif
  111. First_of_this_block = 0;
  112. do { // as long as there is more data to process
  113. lmCode =
  114. NetUserEnum( NULL, // local server
  115. 0, // level 0, no admin priv.
  116. FILTER_NORMAL_ACCOUNT,
  117. &bufptr, // data structure to return
  118. MAX_PREFERRED_LENGTH,
  119. &entriesread,
  120. &totalentries,
  121. &resumehandle // resume handle
  122. );
  123. DataTable = (USER_INFO_0 *) bufptr ;
  124. if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode))
  125. { // valid so process it, otherwise error
  126. if(0 == MIB_UserTable.Len) { // 1st time, alloc the whole table
  127. // alloc the table space
  128. MIB_UserTable.Table = SnmpUtilMemAlloc(totalentries *
  129. sizeof(USER_ENTRY) );
  130. // prefix bugs 445183 and 445184
  131. if (MIB_UserTable.Table == NULL) {
  132. // free all of the lan man data
  133. SafeBufferFree( bufptr ) ;
  134. // Signal error
  135. nResult = SNMPAPI_ERROR;
  136. goto Exit;
  137. }
  138. }
  139. MIB_UserTableElement = MIB_UserTable.Table + First_of_this_block ;
  140. for(i=0; i<entriesread; i++) { // once for each entry in the buffer
  141. // increment the entry number
  142. MIB_UserTable.Len ++;
  143. // Stuff the data into each item in the table
  144. // convert the undocumented unicode to something readable
  145. SnmpUtilUnicodeToUTF8(
  146. &ansi_string,
  147. DataTable->usri0_name,
  148. TRUE ); // auto alloc the space for ansi
  149. // client name
  150. MIB_UserTableElement->svUserName.stream = ansi_string;
  151. MIB_UserTableElement->svUserName.length =
  152. strlen( ansi_string ) ;
  153. MIB_UserTableElement->svUserName.dynamic = TRUE;
  154. ansi_string = NULL;
  155. MIB_UserTableElement ++ ; // and table entry
  156. DataTable ++ ; // advance pointer to next sess entry in buffer
  157. } // for each entry in the data table
  158. // free all of the lan man data
  159. SafeBufferFree( bufptr ) ;
  160. // indicate where to start adding on next pass, if any
  161. First_of_this_block = i ;
  162. } // if data is valid to process
  163. else
  164. {
  165. // Signal error
  166. nResult = SNMPAPI_ERROR;
  167. goto Exit;
  168. }
  169. } while (ERROR_MORE_DATA == lmCode) ;
  170. // iterate over the table populating the Oid field
  171. build_user_entry_oids();
  172. // Sort the table information using MSC QuickSort routine
  173. qsort( &MIB_UserTable.Table[0], MIB_UserTable.Len,
  174. sizeof(USER_ENTRY), user_entry_cmp );
  175. //
  176. //
  177. // Cache table
  178. //
  179. //
  180. if(0 != MIB_UserTable.Len) {
  181. cache_table[C_USER_TABLE].acquisition_time = curr_time ;
  182. cache_table[C_USER_TABLE].bufptr = bufptr ;
  183. }
  184. //
  185. //
  186. // Return piece of information requested
  187. //
  188. //
  189. Exit:
  190. return nResult;
  191. } // MIB_user_get
  192. //
  193. // MIB_user_cmp
  194. // Routine for sorting the session table.
  195. //
  196. // Notes:
  197. //
  198. // Return Codes:
  199. // SNMPAPI_NOERROR
  200. // SNMPAPI_ERROR
  201. //
  202. // Error Codes:
  203. // None.
  204. //
  205. int __cdecl user_entry_cmp(
  206. IN const USER_ENTRY *A,
  207. IN const USER_ENTRY *B
  208. )
  209. {
  210. // Compare the OID's
  211. return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
  212. (AsnObjectIdentifier *)&B->Oid );
  213. } // MIB_user_cmp
  214. //
  215. // None.
  216. //
  217. void build_user_entry_oids(
  218. )
  219. {
  220. AsnOctetString OSA ;
  221. USER_ENTRY *UserEntry ;
  222. unsigned i;
  223. // start pointer at 1st guy in the table
  224. UserEntry = MIB_UserTable.Table ;
  225. // now iterate over the table, creating an oid for each entry
  226. for( i=0; i<MIB_UserTable.Len ; i++) {
  227. // for each entry in the session table
  228. OSA.stream = UserEntry->svUserName.stream ;
  229. OSA.length = UserEntry->svUserName.length ;
  230. OSA.dynamic = FALSE;
  231. // Make the entry's OID from string index
  232. MakeOidFromStr( &OSA, &UserEntry->Oid );
  233. UserEntry++; // point to the next guy in the table
  234. } // for
  235. } // build_user_entry_oids
  236. //-------------------------------- END --------------------------------------