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.

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