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.

505 lines
14 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. shar_lm.c
  5. Abstract:
  6. This file contains MIB_shar_lmget, which actually call lan manager
  7. for the share 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 "shar_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 shar_entry_cmp(
  40. IN const SHARE_ENTRY *A,
  41. IN const SHARE_ENTRY *B
  42. ) ;
  43. BOOL build_shar_entry_oids( );
  44. void FreeShareTable();
  45. //--------------------------- PRIVATE PROCEDURES ----------------------------
  46. //--------------------------- PUBLIC PROCEDURES -----------------------------
  47. //
  48. // MIB_shar_lmget
  49. // Retrieve sharion table information from Lan Manager.
  50. // If not cached, sort it and then
  51. // cache it.
  52. //
  53. // Notes:
  54. //
  55. // Return Codes:
  56. // SNMPAPI_NOERROR
  57. // SNMPAPI_ERROR
  58. //
  59. // Error Codes:
  60. // None.
  61. //
  62. SNMPAPI MIB_shares_lmget(
  63. )
  64. {
  65. DWORD entriesread;
  66. DWORD totalentries;
  67. LPBYTE bufptr;
  68. unsigned lmCode;
  69. unsigned i;
  70. SHARE_INFO_2 *DataTable;
  71. SHARE_ENTRY *MIB_ShareTableElement ;
  72. int First_of_this_block;
  73. time_t curr_time ;
  74. SNMPAPI nResult = SNMPAPI_NOERROR;
  75. DWORD resumehandle=0;
  76. DWORD dwAllocatedEntries=0;
  77. time(&curr_time); // get the time
  78. //
  79. //
  80. // If cached, return piece of info.
  81. //
  82. //
  83. if((NULL != cache_table[C_SHAR_TABLE].bufptr) &&
  84. (curr_time <
  85. (cache_table[C_SHAR_TABLE].acquisition_time
  86. + cache_expire[C_SHAR_TABLE] ) ) )
  87. { // it has NOT expired!
  88. goto Exit ; // the global table is valid
  89. }
  90. //
  91. //
  92. // Do network call to gather information and put it in a nice array
  93. //
  94. //
  95. //
  96. // remember to free the existing data
  97. //
  98. FreeShareTable();
  99. First_of_this_block = 0;
  100. do { // as long as there is more data to process
  101. lmCode =
  102. NetShareEnum(NULL, // local server
  103. 2, // level 2,
  104. &bufptr, // data structure to return
  105. MAX_PREFERRED_LENGTH,
  106. &entriesread,
  107. &totalentries,
  108. &resumehandle // resume handle
  109. );
  110. //
  111. // Filter out all the Admin shares (name ending with $).
  112. //
  113. AdminFilter(2,&entriesread,bufptr);
  114. DataTable = (SHARE_INFO_2 *) bufptr ;
  115. if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode))
  116. { // valid so process it, otherwise error
  117. if(0 == MIB_ShareTable.Len) { // 1st time, alloc the whole table
  118. // alloc the table space
  119. MIB_ShareTable.Table = SnmpUtilMemAlloc(totalentries *
  120. sizeof(SHARE_ENTRY) );
  121. // prefix bugs 445180
  122. if (MIB_ShareTable.Table == NULL) {
  123. // free all of the lan man data
  124. SafeBufferFree( bufptr ) ;
  125. // Signal error
  126. nResult = SNMPAPI_ERROR;
  127. goto Exit;
  128. }
  129. dwAllocatedEntries = totalentries;
  130. }
  131. MIB_ShareTableElement = MIB_ShareTable.Table + First_of_this_block ;
  132. for(i=0; (i<entriesread) && ((i+First_of_this_block) < dwAllocatedEntries); i++) { // once for each entry in the buffer
  133. // increment the entry number
  134. MIB_ShareTable.Len ++;
  135. // Stuff the data into each item in the table
  136. // share name
  137. MIB_ShareTableElement->svShareName.dynamic = TRUE;
  138. #ifdef UNICODE
  139. if (SnmpUtilUnicodeToUTF8(
  140. &MIB_ShareTableElement->svShareName.stream,
  141. DataTable->shi2_netname,
  142. TRUE))
  143. {
  144. MIB_ShareTableElement->svShareName.length = 0;
  145. MIB_ShareTableElement->svShareName.stream = NULL;
  146. MIB_ShareTableElement->svShareName.dynamic = FALSE;
  147. }
  148. else
  149. {
  150. MIB_ShareTableElement->svShareName.length =
  151. strlen(MIB_ShareTableElement->svShareName.stream);
  152. }
  153. #else
  154. MIB_ShareTableElement->svShareName.stream = SnmpUtilMemAlloc (
  155. strlen( DataTable->shi2_netname ) + 1 ) ;
  156. MIB_ShareTableElement->svShareName.length =
  157. strlen( DataTable->shi2_netname ) ;
  158. memcpy( MIB_ShareTableElement->svShareName.stream,
  159. DataTable->shi2_netname,
  160. strlen( DataTable->shi2_netname ) ) ;
  161. #endif
  162. // Share Path
  163. MIB_ShareTableElement->svSharePath.dynamic = TRUE;
  164. #ifdef UNICODE
  165. if (SnmpUtilUnicodeToUTF8(
  166. &MIB_ShareTableElement->svSharePath.stream,
  167. DataTable->shi2_path,
  168. TRUE))
  169. {
  170. MIB_ShareTableElement->svSharePath.length = 0;
  171. MIB_ShareTableElement->svSharePath.stream = NULL;
  172. MIB_ShareTableElement->svSharePath.dynamic = FALSE;
  173. }
  174. else
  175. {
  176. MIB_ShareTableElement->svSharePath.length =
  177. strlen(MIB_ShareTableElement->svSharePath.stream);
  178. }
  179. #else
  180. MIB_ShareTableElement->svSharePath.stream = SnmpUtilMemAlloc (
  181. strlen( DataTable->shi2_path ) + 1 ) ;
  182. MIB_ShareTableElement->svSharePath.length =
  183. strlen( DataTable->shi2_path ) ;
  184. memcpy( MIB_ShareTableElement->svSharePath.stream,
  185. DataTable->shi2_path,
  186. strlen( DataTable->shi2_path ) ) ;
  187. #endif
  188. // Share Comment/Remark
  189. MIB_ShareTableElement->svShareComment.dynamic = TRUE;
  190. #ifdef UNICODE
  191. if (SnmpUtilUnicodeToUTF8(
  192. &MIB_ShareTableElement->svShareComment.stream,
  193. DataTable->shi2_remark,
  194. TRUE))
  195. {
  196. MIB_ShareTableElement->svShareComment.length = 0;
  197. MIB_ShareTableElement->svShareComment.stream = NULL;
  198. MIB_ShareTableElement->svShareComment.dynamic = FALSE;
  199. }
  200. else
  201. {
  202. MIB_ShareTableElement->svShareComment.length =
  203. strlen(MIB_ShareTableElement->svShareComment.stream);
  204. }
  205. #else
  206. MIB_ShareTableElement->svShareComment.stream = SnmpUtilMemAlloc (
  207. strlen( DataTable->shi2_remark ) + 1 ) ;
  208. MIB_ShareTableElement->svShareComment.length =
  209. strlen( DataTable->shi2_remark ) ;
  210. memcpy( MIB_ShareTableElement->svShareComment.stream,
  211. DataTable->shi2_remark,
  212. strlen( DataTable->shi2_remark ) ) ;
  213. #endif
  214. DataTable ++ ; // advance pointer to next shar entry in buffer
  215. MIB_ShareTableElement ++ ; // and table entry
  216. } // for each entry in the data table
  217. // free all of the lan man data
  218. SafeBufferFree( bufptr ) ;
  219. // indicate where to start adding on next pass, if any
  220. First_of_this_block += i ;
  221. } // if data is valid to process
  222. else
  223. {
  224. // Signal error
  225. nResult = SNMPAPI_ERROR;
  226. goto Exit;
  227. }
  228. } while (ERROR_MORE_DATA == lmCode) ;
  229. // iterate over the table populating the Oid field
  230. if (! build_shar_entry_oids())
  231. {
  232. SNMPDBG((
  233. SNMP_LOG_TRACE,
  234. "SNMP: LMMIB2: build_prnt_entry_oids failed\n."));
  235. FreeShareTable();
  236. cache_table[C_SHAR_TABLE].bufptr = NULL;
  237. nResult = SNMPAPI_ERROR;
  238. goto Exit;
  239. }
  240. // Sort the table information using MSC QuickSort routine
  241. qsort( &MIB_ShareTable.Table[0], MIB_ShareTable.Len,
  242. sizeof(SHARE_ENTRY), shar_entry_cmp );
  243. //
  244. //
  245. // Cache table
  246. //
  247. //
  248. if(0 != MIB_ShareTable.Len) {
  249. cache_table[C_SHAR_TABLE].acquisition_time = curr_time ;
  250. cache_table[C_SHAR_TABLE].bufptr = bufptr ;
  251. }
  252. //
  253. //
  254. // Return piece of information requested
  255. //
  256. //
  257. Exit:
  258. return nResult;
  259. } // MIB_shar_get
  260. //
  261. // MIB_shar_cmp
  262. // Routine for sorting the sharion table.
  263. //
  264. // Notes:
  265. //
  266. // Return Codes:
  267. // SNMPAPI_NOERROR
  268. // SNMPAPI_ERROR
  269. //
  270. // Error Codes:
  271. // None.
  272. //
  273. int __cdecl shar_entry_cmp(
  274. IN const SHARE_ENTRY *A,
  275. IN const SHARE_ENTRY *B
  276. )
  277. {
  278. // Compare the OID's
  279. return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
  280. (AsnObjectIdentifier *)&B->Oid );
  281. } // MIB_shar_cmp
  282. //
  283. // None.
  284. //
  285. BOOL build_shar_entry_oids(
  286. )
  287. {
  288. AsnOctetString OSA ;
  289. SHARE_ENTRY *ShareEntry ;
  290. unsigned i;
  291. // start pointer at 1st guy in the table
  292. ShareEntry = MIB_ShareTable.Table ;
  293. // now iterate over the table, creating an oid for each entry
  294. for( i=0; i<MIB_ShareTable.Len ; i++) {
  295. // for each entry in the sharion table
  296. OSA.stream = ShareEntry->svShareName.stream ;
  297. OSA.length = ShareEntry->svShareName.length ;
  298. OSA.dynamic = FALSE;
  299. // Make the entry's OID from string index
  300. if (! MakeOidFromStr( &OSA, &ShareEntry->Oid ))
  301. {
  302. return FALSE;
  303. }
  304. ShareEntry++; // point to the next guy in the table
  305. } // for
  306. return TRUE;
  307. } // build_shar_entry_oids
  308. VOID
  309. AdminFilter(
  310. DWORD Level,
  311. LPDWORD pEntriesRead,
  312. LPBYTE ShareInfo
  313. )
  314. /*++
  315. Routine Description:
  316. This function filters out the admin shares (ones denoted by a
  317. a $ as the last character in the name) from a NetShareEnum
  318. buffer.
  319. This function only supports info levels 0,1, and 2. If any other
  320. level is passed in, the function doesn't perform the filter
  321. operation.
  322. Arguments:
  323. Level - Indicates the info level of the enumeration buffer passed in.
  324. pEntriesRead - Pointer to a location which on entry indicates the
  325. number of entries to be filtered. On exit it will indicate
  326. the number of entries after filtering.
  327. ShareInfo - Pointer to the buffer containing the enumerated structures.
  328. Return Value:
  329. none.
  330. --*/
  331. {
  332. LPBYTE pFiltered = ShareInfo;
  333. DWORD filteredEntries=0;
  334. DWORD i;
  335. DWORD entrySize;
  336. DWORD namePtrOffset;
  337. LPWSTR pName;
  338. switch(Level) {
  339. case 0:
  340. entrySize = sizeof(SHARE_INFO_0);
  341. namePtrOffset = (DWORD)((LPBYTE)&(((LPSHARE_INFO_0)ShareInfo)->shi0_netname) -
  342. ShareInfo);
  343. break;
  344. case 1:
  345. entrySize = sizeof(SHARE_INFO_1);
  346. namePtrOffset = (DWORD)((LPBYTE)&(((LPSHARE_INFO_1)ShareInfo)->shi1_netname) -
  347. ShareInfo);
  348. break;
  349. case 2:
  350. entrySize = sizeof(SHARE_INFO_2);
  351. namePtrOffset = (DWORD)((LPBYTE)&(((LPSHARE_INFO_2)ShareInfo)->shi2_netname) -
  352. ShareInfo);
  353. break;
  354. default:
  355. return;
  356. }
  357. for (i=0; i < *pEntriesRead; i++) {
  358. pName = *((LPWSTR *)(ShareInfo+namePtrOffset));
  359. if (pName[wcslen(pName)-1] != L'$') {
  360. filteredEntries++;
  361. if (pFiltered != ShareInfo) {
  362. memcpy(pFiltered, ShareInfo,entrySize);
  363. }
  364. pFiltered += entrySize;
  365. }
  366. ShareInfo += entrySize;
  367. }
  368. *pEntriesRead = filteredEntries;
  369. }
  370. void FreeShareTable()
  371. {
  372. UINT i;
  373. SHARE_ENTRY *MIB_ShareTableElement ;
  374. MIB_ShareTableElement = MIB_ShareTable.Table ;
  375. if (MIB_ShareTableElement)
  376. {
  377. // iterate over the whole table
  378. for(i=0; i<MIB_ShareTable.Len ;i++)
  379. {
  380. // free any alloc'ed elements of the structure
  381. SnmpUtilOidFree(&(MIB_ShareTableElement->Oid));
  382. SnmpUtilMemFree(MIB_ShareTableElement->svShareName.stream);
  383. SnmpUtilMemFree(MIB_ShareTableElement->svSharePath.stream);
  384. SnmpUtilMemFree(MIB_ShareTableElement->svShareComment.stream);
  385. MIB_ShareTableElement ++ ; // increment table entry
  386. }
  387. SnmpUtilMemFree(MIB_ShareTable.Table) ; // free the base Table
  388. }
  389. MIB_ShareTable.Table = NULL ; // just for safety
  390. MIB_ShareTable.Len = 0 ; // just for safety
  391. }
  392. //-------------------------------- END --------------------------------------