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.

495 lines
12 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. odom_lm.c
  5. Abstract:
  6. This file contains the routines which actually call Lan Manager and
  7. retrieve the contents of the other domains 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 "odom_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 odom_entry_cmp(
  39. IN const DOM_OTHER_ENTRY *A,
  40. IN const DOM_OTHER_ENTRY *B
  41. ) ;
  42. void build_odom_entry_oids( );
  43. int chrcount(char *s)
  44. {
  45. char *temp;
  46. int i;
  47. temp = s;
  48. i = 1; // assume one since no terminating space, other code counts tokens
  49. while( NULL != (temp = strchr(temp,' ')) ) {
  50. i++;
  51. }
  52. return i;
  53. }
  54. //--------------------------- PUBLIC PROCEDURES -----------------------------
  55. //
  56. // MIB_odoms_lmset
  57. // Perform the necessary actions to set an entry in the Other Domain Table.
  58. //
  59. // Notes:
  60. //
  61. // Return Codes:
  62. //
  63. // Error Codes:
  64. // None.
  65. //
  66. UINT MIB_odoms_lmset(
  67. IN AsnObjectIdentifier *Index,
  68. IN UINT Field,
  69. IN AsnAny *Value
  70. )
  71. {
  72. LPBYTE bufptr = NULL;
  73. WKSTA_USER_INFO_1101 ODom;
  74. LPBYTE Temp;
  75. UINT Entry;
  76. UINT I;
  77. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  78. #ifdef UNICODE
  79. LPWSTR unitemp ;
  80. #endif
  81. // Must make sure the table is in memory
  82. if ( SNMPAPI_ERROR == MIB_odoms_lmget() )
  83. {
  84. ErrStat = SNMP_ERRORSTATUS_GENERR;
  85. goto Exit;
  86. }
  87. // See if match in table
  88. if ( MIB_TBL_POS_FOUND == MIB_odoms_match(Index, &Entry) )
  89. {
  90. // If empty string then delete entry
  91. if ( Value->asnValue.string.length == 0 )
  92. {
  93. // Alloc memory for buffer
  94. bufptr = SnmpUtilMemAlloc( DNLEN * sizeof(char) *
  95. (MIB_DomOtherDomainTable.Len-1) +
  96. MIB_DomOtherDomainTable.Len-1 );
  97. // prefix #57351
  98. if (bufptr == NULL)
  99. return SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  100. // Create the other domain string
  101. Temp = bufptr;
  102. for ( I=0;I < MIB_DomOtherDomainTable.Len;I++ )
  103. {
  104. if ( I+1 != Entry )
  105. {
  106. memcpy( Temp,
  107. MIB_DomOtherDomainTable.Table[I].domOtherName.stream,
  108. MIB_DomOtherDomainTable.Table[I].domOtherName.length );
  109. Temp[MIB_DomOtherDomainTable.Table[I].domOtherName.length] = ' ';
  110. Temp += MIB_DomOtherDomainTable.Table[I].domOtherName.length + 1;
  111. }
  112. }
  113. *(Temp-1) = '\0';
  114. }
  115. else
  116. {
  117. // Cannot modify the domain entries, so bad value
  118. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  119. goto Exit;
  120. }
  121. }
  122. else
  123. {
  124. // Check for addition of NULL string, bad value
  125. if ( Value->asnValue.string.length == 0 )
  126. {
  127. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  128. goto Exit;
  129. }
  130. //
  131. // Entry doesn't exist so add it to the list
  132. //
  133. // Alloc memory for buffer
  134. bufptr = SnmpUtilMemAlloc( DNLEN * sizeof(char) *
  135. (MIB_DomOtherDomainTable.Len+1) +
  136. MIB_DomOtherDomainTable.Len+1 );
  137. // prefix #57352
  138. if (bufptr == NULL)
  139. return SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  140. // Create the other domain string
  141. Temp = bufptr;
  142. for ( I=0;I < MIB_DomOtherDomainTable.Len;I++ )
  143. {
  144. memcpy( Temp, MIB_DomOtherDomainTable.Table[I].domOtherName.stream,
  145. MIB_DomOtherDomainTable.Table[I].domOtherName.length );
  146. Temp[MIB_DomOtherDomainTable.Table[I].domOtherName.length] = ' ';
  147. Temp += MIB_DomOtherDomainTable.Table[I].domOtherName.length + 1;
  148. }
  149. // Add new entry
  150. memcpy( Temp, Value->asnValue.string.stream,
  151. Value->asnValue.string.length );
  152. // Add NULL terminator
  153. Temp[Value->asnValue.string.length] = '\0';
  154. }
  155. // Set table and check return codes
  156. #ifdef UNICODE
  157. SnmpUtilUTF8ToUnicode( &unitemp,
  158. bufptr,
  159. TRUE );
  160. ODom.wkui1101_oth_domains = unitemp;
  161. #else
  162. ODom.wkui1101_oth_domains = bufptr;
  163. #endif
  164. #if 0
  165. if ( NERR_Success == NetWkstaUserSetInfo(NULL, 1101, (LPBYTE)&ODom, NULL) )
  166. {
  167. // Make cache be reloaded next time
  168. cache_table[C_ODOM_TABLE].bufptr = NULL;
  169. }
  170. else
  171. {
  172. ErrStat = SNMP_ERRORSTATUS_GENERR;
  173. }
  174. #else
  175. ErrStat = SNMP_ERRORSTATUS_GENERR;
  176. #endif
  177. Exit:
  178. SnmpUtilMemFree( bufptr );
  179. return ErrStat;
  180. } // MIB_odoms_lmset
  181. //
  182. // MIB_odom_lmget
  183. // Retrieve print queue table information from Lan Manager.
  184. // If not cached, sort it and then
  185. // cache it.
  186. //
  187. // Notes:
  188. //
  189. // Return Codes:
  190. // SNMPAPI_NOERROR
  191. // SNMPAPI_ERROR
  192. //
  193. // Error Codes:
  194. // None.
  195. //
  196. SNMPAPI MIB_odoms_lmget(
  197. )
  198. {
  199. DWORD totalentries;
  200. LPBYTE bufptr = NULL;
  201. unsigned lmCode;
  202. WKSTA_USER_INFO_1101 *DataTable;
  203. DOM_OTHER_ENTRY *MIB_DomOtherDomainTableElement ;
  204. char *p;
  205. char *next;
  206. time_t curr_time ;
  207. unsigned i;
  208. SNMPAPI nResult = SNMPAPI_NOERROR;
  209. time(&curr_time); // get the time
  210. //
  211. //
  212. // If cached, return piece of info.
  213. //
  214. //
  215. if((NULL != cache_table[C_ODOM_TABLE].bufptr) &&
  216. (curr_time <
  217. (cache_table[C_ODOM_TABLE].acquisition_time
  218. + cache_expire[C_ODOM_TABLE] ) ) )
  219. { // it has NOT expired!
  220. goto Exit; // the global table is valid
  221. }
  222. //
  223. //
  224. // Do network call to gather information and put it in a nice array
  225. //
  226. //
  227. //
  228. // remember to free the existing data
  229. //
  230. MIB_DomOtherDomainTableElement = MIB_DomOtherDomainTable.Table ;
  231. // iterate over the whole table
  232. for(i=0; i<MIB_DomOtherDomainTable.Len ;i++)
  233. {
  234. // free any alloc'ed elements of the structure
  235. SnmpUtilOidFree(&(MIB_DomOtherDomainTableElement->Oid));
  236. SafeFree(MIB_DomOtherDomainTableElement->domOtherName.stream);
  237. MIB_DomOtherDomainTableElement ++ ; // increment table entry
  238. }
  239. SafeFree(MIB_DomOtherDomainTable.Table) ; // free the base Table
  240. MIB_DomOtherDomainTable.Table = NULL ; // just for safety
  241. MIB_DomOtherDomainTable.Len = 0 ; // just for safety
  242. lmCode =
  243. NetWkstaUserGetInfo(
  244. 0, // required
  245. 1101, // level 0,
  246. &bufptr // data structure to return
  247. );
  248. DataTable = (WKSTA_USER_INFO_1101 *) bufptr ;
  249. if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode))
  250. { // valid so process it, otherwise error
  251. if(NULL==DataTable->wkui1101_oth_domains) {
  252. // Prefix #57350
  253. // free all of the lanman data
  254. SafeBufferFree( bufptr ) ;
  255. // Signal error
  256. nResult = SNMPAPI_ERROR;
  257. goto Exit;
  258. } else { // compute it
  259. totalentries = chrcount((char *)DataTable->wkui1101_oth_domains);
  260. if(0 == MIB_DomOtherDomainTable.Len) { // 1st time, alloc the whole table
  261. // alloc the table space
  262. MIB_DomOtherDomainTable.Table = SnmpUtilMemAlloc(totalentries *
  263. sizeof(DOM_OTHER_ENTRY) );
  264. // Prefix #57349
  265. if (MIB_DomOtherDomainTable.Table == NULL)
  266. {
  267. // free all of the lanman data
  268. SafeBufferFree( bufptr ) ;
  269. // Signal error
  270. nResult = SNMPAPI_ERROR;
  271. goto Exit;
  272. }
  273. }
  274. MIB_DomOtherDomainTableElement = MIB_DomOtherDomainTable.Table ;
  275. // make a pointer to the beginning of the string field
  276. #ifdef UNICODE
  277. SnmpUtilUnicodeToUTF8(
  278. &p,
  279. DataTable->wkui1101_oth_domains,
  280. TRUE);
  281. #else
  282. p = DataTable->wkui1101_oth_domains ;
  283. #endif
  284. // scan through the field, making an entry for each space
  285. // separated domain
  286. while( (NULL != p ) &&
  287. ('\0' != *p) ) { // once for each entry in the buffer
  288. // increment the entry number
  289. MIB_DomOtherDomainTable.Len ++;
  290. // find the end of this one
  291. next = strchr(p,' ');
  292. // if more to come, ready next pointer and mark end of this one
  293. if(NULL != next) {
  294. *next='\0' ; // replace space with EOS
  295. next++ ; // point to beginning of next domain
  296. }
  297. MIB_DomOtherDomainTableElement->domOtherName.stream = SnmpUtilMemAlloc (
  298. strlen( p ) ) ;
  299. MIB_DomOtherDomainTableElement->domOtherName.length =
  300. strlen( p ) ;
  301. MIB_DomOtherDomainTableElement->domOtherName.dynamic = TRUE;
  302. memcpy( MIB_DomOtherDomainTableElement->domOtherName.stream,
  303. p,
  304. strlen( p ) ) ;
  305. MIB_DomOtherDomainTableElement ++ ; // and table entry
  306. DataTable ++ ; // advance pointer to next sess entry in buffer
  307. } // while still more to do
  308. } // if there really were entries
  309. } // if data is valid to process
  310. else
  311. {
  312. // Signal error
  313. nResult = SNMPAPI_ERROR;
  314. goto Exit;
  315. }
  316. // free all of the lan man data
  317. SafeBufferFree( bufptr ) ;
  318. // iterate over the table populating the Oid field
  319. build_odom_entry_oids();
  320. // Sort the table information using MSC QuickSort routine
  321. qsort( (void *)&MIB_DomOtherDomainTable.Table[0], (size_t)MIB_DomOtherDomainTable.Len,
  322. (size_t)sizeof(DOM_OTHER_ENTRY), odom_entry_cmp );
  323. //
  324. //
  325. // Cache table
  326. //
  327. //
  328. if(0 != MIB_DomOtherDomainTable.Len) {
  329. cache_table[C_ODOM_TABLE].acquisition_time = curr_time ;
  330. cache_table[C_ODOM_TABLE].bufptr = bufptr ;
  331. }
  332. //
  333. //
  334. // Return piece of information requested
  335. //
  336. //
  337. Exit:
  338. return nResult;
  339. } // MIB_odom_get
  340. //
  341. // MIB_odom_cmp
  342. // Routine for sorting the session table.
  343. //
  344. // Notes:
  345. //
  346. // Return Codes:
  347. // SNMPAPI_NOERROR
  348. // SNMPAPI_ERROR
  349. //
  350. // Error Codes:
  351. // None.
  352. //
  353. int __cdecl odom_entry_cmp(
  354. IN const DOM_OTHER_ENTRY *A,
  355. IN const DOM_OTHER_ENTRY *B
  356. )
  357. {
  358. // Compare the OID's
  359. return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
  360. (AsnObjectIdentifier *)&B->Oid );
  361. } // MIB_odom_cmp
  362. //
  363. // None.
  364. //
  365. void build_odom_entry_oids(
  366. )
  367. {
  368. AsnOctetString OSA ;
  369. DOM_OTHER_ENTRY *DomOtherEntry ;
  370. unsigned i;
  371. // start pointer at 1st guy in the table
  372. DomOtherEntry = MIB_DomOtherDomainTable.Table ;
  373. // now iterate over the table, creating an oid for each entry
  374. for( i=0; i<MIB_DomOtherDomainTable.Len ; i++) {
  375. // for each entry in the session table
  376. OSA.stream = DomOtherEntry->domOtherName.stream ;
  377. OSA.length = DomOtherEntry->domOtherName.length ;
  378. OSA.dynamic = FALSE;
  379. // Make the entry's OID from string index
  380. MakeOidFromStr( &OSA, &DomOtherEntry->Oid );
  381. DomOtherEntry++; // point to the next guy in the table
  382. } // for
  383. } // build_odom_entry_oids
  384. //-------------------------------- END --------------------------------------