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.

906 lines
28 KiB

  1. /*++
  2. Copyright (c) 1991-92 Microsoft Corporation
  3. Module Name:
  4. rxshare.c
  5. Abstract:
  6. Contains down-level remoted RxNetShare routines:
  7. RxNetShareAdd
  8. RxNetShareCheck
  9. RxNetShareDel
  10. RxNetShareEnum
  11. RxNetShareGetInfo
  12. RxNetShareSetInfo
  13. (GetShareInfoDescriptors)
  14. (ConvertMaxUsesField)
  15. Author:
  16. Richard Firth (rfirth) 20-May-1991
  17. Environment:
  18. Win-32/flat address space
  19. Notes:
  20. Routines in this module assume that caller-supplied parameters have
  21. already been verified. No effort is made to further check the veracity
  22. of parms. Any actions causing exceptions must be trapped at a higher
  23. level. This applies to ALL parameters - strings, pointers, buffers, etc.
  24. Revision History:
  25. 08-Apr-1992
  26. Try to avoid >1 calls to down-level server for RxNetShareEnum
  27. Fix problem of converting 16-bit numbers >32768 into negative 32-bit
  28. numbers on GetInfo and Enum: 65535 is a special value; everything
  29. else in unsigned 16-bit
  30. 01-Apr-1992 JohnRo
  31. Prevent too large size requests.
  32. Use NetApiBufferAllocate() instead of private version.
  33. 05-Dec-1991 RFirth
  34. Enum returns in TotalEntries (or EntriesLeft) the number of items to
  35. be enumerated BEFORE this call. Used to be number left after this call
  36. 21-Nov-1991 JohnRo
  37. Removed NT dependencies to reduce recompiles.
  38. 16-Sep-1991 JohnRo
  39. Use DBGSTATIC for nonexported routines.
  40. 13-Sep-1991 JohnRo
  41. Corrected typedef used for descriptors (LPDESC, not LPTSTR).
  42. Made changes suggested by PC-LINT.
  43. 20-May-1991 RFirth
  44. Created
  45. --*/
  46. #include "downlevl.h"
  47. #include "rxshare.h"
  48. #include <lmshare.h> // typedefs for SHARE_INFO etc.
  49. #define SHARE_ADD_LEVEL 2 // only level at which we can add stuff down-stream
  50. #define INITIAL_BUFFER_SIZE 4096 // Arbitrary! But can't be integral multiple of infolen
  51. //
  52. // prototypes
  53. //
  54. DBGSTATIC void
  55. GetShareInfoDescriptors(
  56. IN DWORD level,
  57. OUT LPDESC* pDesc16,
  58. OUT LPDESC* pDesc32,
  59. OUT LPDESC* pDescSmb,
  60. OUT LPDWORD pDatasize
  61. );
  62. DBGSTATIC
  63. VOID
  64. ConvertMaxUsesField(
  65. IN LPSHARE_INFO_2 Buffer,
  66. IN DWORD NumberOfLevel2Structures
  67. );
  68. NET_API_STATUS
  69. RxNetShareAdd(
  70. IN LPTSTR ServerName,
  71. IN DWORD Level,
  72. IN LPBYTE Buffer,
  73. OUT LPDWORD ParmError OPTIONAL
  74. )
  75. /*++
  76. Routine Description:
  77. Attempts the NetShareAdd API at the named server. The server supports an
  78. earlier version of LanMan than that under which we are operating so we
  79. have to slightly modify things in order that the down-level server
  80. understands the request
  81. Note: we don't hand back any ParmError information. This level of info
  82. is primarily supplied by the new (NT) rouines
  83. Arguments:
  84. ServerName - at which server to perform this request
  85. Level - of information being supplied. Must Be 2
  86. Buffer - pointer to supplied level 2 share information buffer
  87. ParmError - place to return the id of the parameter causing strife
  88. Return Value:
  89. NET_API_STATUS:
  90. Success = NERR_Success
  91. Failure = ERROR_INVALID_LEVEL
  92. Level must be 2
  93. (return code from RxRemoteApi)
  94. (return code from remoted NetShareAdd API)
  95. --*/
  96. {
  97. UNREFERENCED_PARAMETER(ParmError);
  98. UNREFERENCED_PARAMETER(Level);
  99. if ( Buffer == NULL )
  100. return ERROR_INVALID_PARAMETER;
  101. #if DBG
  102. //
  103. // The ServerName parameter must be a non-NUL(L) string. We know this must
  104. // be so since (presumably) the server name was used as the criteria to get
  105. // here. Ensure that this is so (in the non-release version).
  106. //
  107. NetpAssert(ServerName != NULL);
  108. NetpAssert(*ServerName);
  109. #endif
  110. return RxRemoteApi(API_WShareAdd, // API #
  111. ServerName, // where it will run
  112. REMSmb_NetShareAdd_P, // parameter descriptor
  113. REM16_share_info_2, // Data descriptor/16-bit
  114. REM32_share_info_2, // Data descriptor/32-bit
  115. REMSmb_share_info_2, // Data descriptor/SMB
  116. NULL, // Aux descriptor/16-bit
  117. NULL, // Aux descriptor/32-bit
  118. NULL, // Aux descriptor/SMB
  119. FALSE, // this call needs user to be logged on
  120. SHARE_ADD_LEVEL, // level. Since there's only 1 push immediate
  121. Buffer, // caller's SHARE_INFO_2 struct
  122. //
  123. // we have to supply the size of the buffer - down-level
  124. // expects it, NT doesn't. Defined as the size of the fixed
  125. // structure (ie a SHARE_INFO_2) plus the lengths of all
  126. // the variable fields (all strings in this case)
  127. //
  128. sizeof(SHARE_INFO_2) + // parameter supplied by us
  129. POSSIBLE_STRSIZE(((SHARE_INFO_2*)Buffer)->shi2_netname) +
  130. POSSIBLE_STRSIZE(((SHARE_INFO_2*)Buffer)->shi2_remark) +
  131. POSSIBLE_STRSIZE(((SHARE_INFO_2*)Buffer)->shi2_path) +
  132. POSSIBLE_STRSIZE(((SHARE_INFO_2*)Buffer)->shi2_passwd)
  133. );
  134. }
  135. NET_API_STATUS
  136. RxNetShareCheck(
  137. IN LPTSTR ServerName,
  138. IN LPTSTR DeviceName,
  139. OUT LPDWORD Type
  140. )
  141. /*++
  142. Routine Description:
  143. Attempts to perform the NetShareCheck API on a remote down-level server
  144. Arguments:
  145. ServerName - where this call will happen
  146. DeviceName - the thing we are querying
  147. Type - where we store share type in the (unlikely) event of success
  148. Return Value:
  149. NET_API_STATUS
  150. Success = NERR_Success
  151. Failure =
  152. --*/
  153. {
  154. #if DBG
  155. //
  156. // The ServerName parameter must be a non-NUL(L) string. We know this must
  157. // be so since (presumably) the server name was used as the criteria to get
  158. // here. Ensure that this is so (in the non-release version).
  159. //
  160. NetpAssert(ServerName != NULL);
  161. NetpAssert(*ServerName);
  162. #endif
  163. //
  164. // We have to have something in the device name
  165. // Ensure that the caller provided us with the address of the place he/she
  166. // wants the type info to be left
  167. //
  168. if (!VALID_STRING(DeviceName) || Type == NULL) {
  169. return ERROR_INVALID_PARAMETER;
  170. }
  171. return RxRemoteApi(API_NetShareCheck,
  172. ServerName, // where it will run
  173. REMSmb_NetShareCheck_P, // parameter descriptor
  174. NULL, // Data descriptor/16-bit
  175. NULL, // Data descriptor/32-bit
  176. NULL, // Data descriptor/SMB
  177. NULL, // Aux descriptor/16-bit
  178. NULL, // Aux descriptor/32-bit
  179. NULL, // Aux descriptor/SMB
  180. FALSE, // this call needs user to be logged on
  181. DeviceName, // parm 1
  182. Type // parm 2
  183. );
  184. }
  185. NET_API_STATUS
  186. RxNetShareDel(
  187. IN LPTSTR ServerName,
  188. IN LPTSTR NetName,
  189. IN DWORD Reserved
  190. )
  191. /*++
  192. Routine Description:
  193. Performs the NetShareDel API at a remote down-level server
  194. Arguments:
  195. ServerName - where to perform the request
  196. NetName - to remove
  197. Reserved - MBZ
  198. Return Value:
  199. NET_API_STATUS
  200. Success = NERR_Success
  201. Failure = ERROR_INVALID_PARAMETER
  202. --*/
  203. {
  204. #if DBG
  205. //
  206. // The ServerName parameter must be a non-NUL(L) string. We know this must
  207. // be so since (presumably) the server name was used as the criteria to get
  208. // here. Ensure that this is so (in the non-release version).
  209. //
  210. NetpAssert(ServerName != NULL);
  211. NetpAssert(*ServerName);
  212. #endif
  213. //
  214. // if the NetName parameter is a NULL pointer or string OR the Reserved
  215. // parameter is NOT 0 then return an error
  216. //
  217. if (!VALID_STRING(NetName) || Reserved) {
  218. return ERROR_INVALID_PARAMETER;
  219. }
  220. //
  221. // Just call the RpcXlate routine to perform it and return the result
  222. //
  223. return RxRemoteApi(API_WShareDel,
  224. ServerName, // where it will run
  225. REMSmb_NetShareDel_P, // parameter descriptor
  226. NULL, // Data descriptor/16-bit
  227. NULL, // Data descriptor/32-bit
  228. NULL, // Data descriptor/SMB
  229. NULL, // Aux descriptor/16-bit
  230. NULL, // Aux descriptor/32-bit
  231. NULL, // Aux descriptor/SMB
  232. FALSE, // this call needs user to be logged on
  233. NetName, // parm 1
  234. 0 // parm 2 (RESERVED - MBZ)
  235. );
  236. }
  237. NET_API_STATUS
  238. RxNetShareEnum(
  239. IN LPTSTR ServerName,
  240. IN DWORD Level,
  241. OUT LPBYTE* Buffer,
  242. IN DWORD PrefMaxLen,
  243. OUT LPDWORD EntriesRead,
  244. OUT LPDWORD EntriesLeft,
  245. IN OUT LPDWORD ResumeHandle OPTIONAL
  246. )
  247. /*++
  248. Routine Description:
  249. Performs NetShareEnum API at a remote down-level server. Any returned info
  250. will be in 32-bit LanMan format. Information returned in buffer sourced by
  251. this routine. Caller must use NetApiBufferFree when returned buffer no
  252. longer required
  253. Arguments:
  254. ServerName - where to perform the request
  255. Level - of info to return. Can be 0, 1 or 2
  256. Buffer - pointer to pointer to returned info buffer
  257. PrefMaxLen - caller preferred maximum size of returned buffer
  258. EntriesRead - pointer to number of entries being returned from this call
  259. EntriesLeft - pointer to total number of share info structures which could be returned
  260. ResumeHandle- NOT Allowed on down level versions. Must Be NULL
  261. Return Value:
  262. NET_API_STATUS
  263. Success = NERR_Success
  264. Failure = ERROR_INVALID_LEVEL
  265. Level parameter not in range 0 <= Level <= 2
  266. ERROR_INVALID_PARAMETER
  267. Non-NULL ResumeHandle. ResumeHandle can be NULL or a
  268. pointer to 0
  269. (return code from NetApiBufferAllocate)
  270. (return code from RxRemoteApi)
  271. --*/
  272. {
  273. NET_API_STATUS rc;
  274. DWORD array_size;
  275. LPDESC pDesc16;
  276. LPDESC pDesc32;
  277. LPDESC pDescSmb;
  278. LPBYTE ourbuf;
  279. DWORD infolen;
  280. DWORD entries_read, total_avail;
  281. UNREFERENCED_PARAMETER(PrefMaxLen);
  282. #if DBG
  283. //
  284. // The ServerName parameter must be a non-NUL(L) string. We know this must
  285. // be so since (presumably) the server name was used as the criteria to get
  286. // here. Ensure that this is so (in the non-release version).
  287. //
  288. NetpAssert(ServerName != NULL);
  289. NetpAssert(*ServerName);
  290. #endif
  291. //
  292. // Set the number of entries read and total available to sensible defaults.
  293. // Side effect of testing writability of supplied parameters
  294. //
  295. //
  296. // I assume that:
  297. // Buffer is a valid, non-NULL pointer
  298. // EntriesRead is a valid, non-NULL pointer
  299. // EntriesLeft is a valid, non-NULL pointer
  300. // since these should have been verified at the API level
  301. //
  302. *Buffer = NULL;
  303. *EntriesRead = 0;
  304. *EntriesLeft = 0;
  305. //
  306. // Check for invalid parameters.
  307. // NB Does Assume that DWORD is unsigned
  308. // Ensure that:
  309. // Level is not >2
  310. // ResumeHandle is NULL or a pointer to NULL
  311. //
  312. if ((ResumeHandle != NULL) && *ResumeHandle) {
  313. return ERROR_INVALID_PARAMETER;
  314. }
  315. if (Level > 2) {
  316. return ERROR_INVALID_LEVEL;
  317. }
  318. //
  319. // Decide which descriptors to use, based on the Level parameter
  320. //
  321. GetShareInfoDescriptors(Level, &pDesc16, &pDesc32, &pDescSmb, &infolen);
  322. ourbuf = NULL;
  323. //
  324. // here we used to let RxRemoteApi allocate a buffer (64K intermediate)
  325. // and do the transaction, returning us a buffer just large enough to
  326. // hold the returned information. WinBall server barfs if it gets a
  327. // request with a 64K buffer, so we have to solicit size info until we
  328. // get everything back. Unfortunately - as of writing - we have no way
  329. // of knowing the type of server we will make the transaction request to
  330. // so we may end up having to make >1 request to a LM 2.1 server where
  331. // we used to be able to get away with 1. On the other hand we can't risk
  332. // upsetting the WB server. Compromise time. Send a 'reasonable' sized
  333. // request to the other side (4K buffer). If it isn't sufficient then
  334. // we loop again, allocating the required buffer
  335. //
  336. //
  337. // what about a LRU cache which keeps the size of the buffer required
  338. // to satisfy an enum request to a particular down-level server?
  339. //
  340. //
  341. // Loop until we have enough memory or we die for some other reason.
  342. //
  343. array_size = INITIAL_BUFFER_SIZE;
  344. do {
  345. // Figure out how much memory we need.
  346. //
  347. // Remote the API, which will allocate the array for us.
  348. //
  349. rc = RxRemoteApi(API_WShareEnum,
  350. ServerName, // where it will run
  351. REMSmb_NetShareEnum_P, // parameter descriptor
  352. pDesc16, // Data descriptor/16-bit
  353. pDesc32, // Data descriptor/32-bit
  354. pDescSmb, // Data descriptor/SMB
  355. NULL, // Aux descriptor/16-bit
  356. NULL, // Aux descriptor/32-bit
  357. NULL, // Aux descriptor/SMB
  358. ALLOCATE_RESPONSE, // allocate a buffer for us
  359. Level, // level parameter
  360. &ourbuf, // pointer to allocated buffer
  361. array_size, // size of down-level buffer
  362. &entries_read, // pointer to entries read variable
  363. &total_avail // pointer to total entries variable
  364. );
  365. if (rc == ERROR_MORE_DATA) {
  366. (void) NetApiBufferFree( ourbuf );
  367. ourbuf = NULL;
  368. if (array_size >= MAX_TRANSACT_RET_DATA_SIZE) {
  369. //
  370. // No point in trying with a larger buffer
  371. //
  372. break;
  373. }
  374. #if DBG
  375. NetpAssert(array_size != total_avail * infolen);
  376. #endif
  377. array_size = (total_avail * infolen);
  378. if (array_size > MAX_TRANSACT_RET_DATA_SIZE) {
  379. //
  380. // Try once more with the maximum-size buffer
  381. //
  382. array_size = MAX_TRANSACT_RET_DATA_SIZE;
  383. }
  384. #if DBG
  385. NetpAssert( array_size != 0 );
  386. #endif
  387. }
  388. } while (rc == ERROR_MORE_DATA);
  389. //
  390. // if we met with an error then free the allocated buffer and return the
  391. // error to the caller. If there was no error then we return the items
  392. // received from the down-level server
  393. //
  394. if (rc) {
  395. if (ourbuf != NULL) {
  396. (void) NetApiBufferFree(ourbuf);
  397. }
  398. } else {
  399. if (Level == 2) {
  400. ConvertMaxUsesField((LPSHARE_INFO_2)ourbuf, entries_read);
  401. }
  402. *Buffer = ourbuf;
  403. *EntriesRead = entries_read;
  404. *EntriesLeft = total_avail;
  405. }
  406. return rc;
  407. }
  408. NET_API_STATUS
  409. RxNetShareGetInfo(
  410. IN LPTSTR ServerName,
  411. IN LPTSTR NetName,
  412. IN DWORD Level,
  413. OUT LPBYTE* Buffer
  414. )
  415. /*++
  416. Routine Description:
  417. Performs the NetShareGetInfo API at a remote down-level server. The returned
  418. information will be in 32-bit LanMan format. Returns single information
  419. structure in a buffer sourced in this routine. Caller must use
  420. NetApiBufferFree when finished with buffer
  421. Arguments:
  422. ServerName - where to perform the request
  423. NetName - name of thing to get information about
  424. Level - level of information requested - 0, 1, 2 are valid
  425. Buffer - pointer to pointer to returned buffer
  426. Return Value:
  427. NET_API_STATUS
  428. Success = NERR_Success
  429. Failure = ERROR_INVALID_LEVEL
  430. ERROR_INVALID_PARAMETER
  431. (return code from NetApiBufferAllocate)
  432. (return code from RxRemoteApi)
  433. --*/
  434. {
  435. NET_API_STATUS rc;
  436. LPDESC pDesc16; // pointer to 16-bit info descriptor for RxRemoteApi
  437. LPDESC pDesc32; // pointer to 32-bit info descriptor for RxRemoteApi
  438. LPDESC pDescSmb; // pointer to SMB info descriptor for RxRemoteApi
  439. LPBYTE ourbuf; // buffer we allocate, fill, and give to the caller
  440. DWORD total_avail; // 32-bit total available if supplied buffer too small
  441. DWORD infolen; // 32-bit place to store size of required buffer
  442. #if DBG
  443. //
  444. // The ServerName parameter must be a non-NUL(L) string. We know this must
  445. // be so since (presumably) the server name was used as the criteria to get
  446. // here. Ensure that this is so (in the non-release version).
  447. //
  448. NetpAssert(ServerName != NULL);
  449. NetpAssert(*ServerName);
  450. #endif
  451. //
  452. // Preset Buffer and check it is valid pointer
  453. //
  454. *Buffer = NULL;
  455. //
  456. // Perform parameter validity checks:
  457. // Level must be in range 0 <= Level <= 2
  458. // NetName must be non-NULL pointer to non-NULL string
  459. // Buffer must be non-NULL pointer
  460. // NB. Assumes DWORD is unsigned quantity
  461. //
  462. if (Level > 2) {
  463. return ERROR_INVALID_LEVEL;
  464. }
  465. if (!VALID_STRING(NetName) || !Buffer) {
  466. return ERROR_INVALID_PARAMETER;
  467. }
  468. //
  469. // Work out the descriptor and buffer size requirements based on the
  470. // requested level
  471. //
  472. GetShareInfoDescriptors(Level, &pDesc16, &pDesc32, &pDescSmb, &infolen);
  473. //
  474. // allocate a buffer size required to fit in 1 structure at info level
  475. // requested. If the allocation fails then return the error
  476. // We have to allocate space for the strings too, don't forget
  477. //
  478. ourbuf = NULL;
  479. rc = RxRemoteApi(API_WShareGetInfo,
  480. ServerName, // where it will happen
  481. REMSmb_NetShareGetInfo_P, // parameter descriptor
  482. pDesc16, // Data descriptor/16-bit
  483. pDesc32, // Data descriptor/32-bit
  484. pDescSmb, // Data descriptor/SMB
  485. NULL, // Aux descriptor/16-bit
  486. NULL, // Aux descriptor/32-bit
  487. NULL, // Aux descriptor/SMB
  488. ALLOCATE_RESPONSE, // allocate a buffer for us
  489. NetName, // pointer to thing to get info on
  490. Level, // level of info
  491. &ourbuf, // pointer to buffer sourced by us
  492. infolen, // size of our sourced buffer
  493. &total_avail // pointer to total available
  494. );
  495. //
  496. // If the remote NetShareGetInfo call succeeded then give the returned
  497. // buffer to the caller
  498. //
  499. if (rc == NERR_Success) {
  500. if (Level == 2) {
  501. ConvertMaxUsesField((LPSHARE_INFO_2)ourbuf, 1);
  502. }
  503. *Buffer = ourbuf;
  504. } else if (ourbuf) {
  505. //
  506. // if we didn't record a success then free the buffer we previously allocated
  507. //
  508. (void) NetApiBufferFree(ourbuf);
  509. }
  510. return rc;
  511. }
  512. NET_API_STATUS
  513. RxNetShareSetInfo(
  514. IN LPTSTR ServerName,
  515. IN LPTSTR NetName,
  516. IN DWORD Level,
  517. IN LPBYTE Buffer,
  518. OUT LPDWORD ParmError OPTIONAL
  519. )
  520. /*++
  521. Routine Description:
  522. Performs the NetShareSetInfo API at a remote down-level server
  523. Arguments:
  524. ServerName - where to perform the request
  525. NetName - name of thing for which to set info
  526. Level - level of information - 0, 1, 2, 1004, 1005, 1006, 1009
  527. Buffer - buffer containing info at defined level
  528. ParmError - pointer to invalid parameter ordinal
  529. Return Value:
  530. NET_API_STATUS
  531. Success = NERR_Success
  532. Failure = ERROR_INVALID_LEVEL
  533. ERROR_INVALID_PARAMETER
  534. (return code from RxRemoteApi)
  535. --*/
  536. {
  537. DWORD infolen; // size of structure
  538. DWORD parmnum; // we have to cobble down-level parmnum from Level
  539. LPDESC pDesc16; // used in call to GetShareInfoDescriptors
  540. LPDESC pDesc32; // ditto. Only interested in length of info structure
  541. LPDESC pDescSmb; // ditto. Only interested in length of info structure
  542. UNREFERENCED_PARAMETER(ParmError);
  543. #if DBG
  544. //
  545. // The ServerName parameter must be a non-NUL(L) string. We know this must
  546. // be so since (presumably) the server name was used as the criteria to get
  547. // here. Ensure that this is so (in the non-release version).
  548. //
  549. NetpAssert(ServerName != NULL);
  550. NetpAssert(*ServerName);
  551. #endif
  552. //
  553. // Perform parameter validity checks:
  554. // NetName must be non-NULL pointer to non-NULL string
  555. // Buffer must be non-NULL pointer to non-NULL pointer
  556. // Level must be in range
  557. // NB. Assumes that DWORD is unsigned!
  558. //
  559. if (!VALID_STRING(NetName) || !Buffer) {
  560. return ERROR_INVALID_PARAMETER;
  561. }
  562. if (Level < 1 || (Level > 2 && (Level < 1004 || (Level > 1006 && Level != 1009)))) {
  563. return ERROR_INVALID_LEVEL;
  564. }
  565. //
  566. // We can set individual info fields using the levels > 1000. We have to
  567. // create level and parmnum info for down-level
  568. //
  569. if (Level > 2) {
  570. //
  571. // Individual fields are indicated by the old (down-level) parmnum,
  572. // augmented by 1000. Split level and parmnum parameters
  573. //
  574. parmnum = Level - PARMNUM_BASE_INFOLEVEL;
  575. Level = 2;
  576. pDesc16 = REM16_share_info_2_setinfo;
  577. pDesc32 = REM32_share_info_2_setinfo;
  578. pDescSmb = REMSmb_share_info_2_setinfo;
  579. switch (parmnum) {
  580. case 4: // remark
  581. case 9: // password
  582. infolen = STRSIZE( (LPTSTR)Buffer );
  583. break;
  584. case 5: // permissions
  585. case 6: // max uses
  586. infolen = sizeof(WORD);
  587. break;
  588. }
  589. } else {
  590. //
  591. // let GetShareInfoDescriptors give us the size of the buffer
  592. // that NetShareSetInfo thinks its getting. We have no other way of
  593. // determining this (have we?). Levels 0 - 2 set the entire structure
  594. //
  595. GetShareInfoDescriptors(Level, &pDesc16, &pDesc32, &pDescSmb, &infolen);
  596. parmnum = PARMNUM_ALL;
  597. }
  598. return RxRemoteApi(API_WShareSetInfo,
  599. ServerName, // where it will run
  600. REMSmb_NetShareSetInfo_P, // parameter descriptor
  601. pDesc16, // Data descriptor/16-bit
  602. pDesc32, // Data descriptor/32-bit
  603. pDescSmb, // Data descriptor/SMB
  604. NULL, // Aux descriptor/16-bit
  605. NULL, // Aux descriptor/32-bit
  606. NULL, // Aux descriptor/SMB
  607. FALSE, // this call needs user to be logged on
  608. NetName, // pointer to thing to set info on
  609. Level, // level of info
  610. Buffer, // pointer to buffer sourced by caller
  611. infolen, // size of our buffer
  612. //
  613. // in this case, the field index and parm num are the
  614. // same value
  615. //
  616. MAKE_PARMNUM_PAIR(parmnum, parmnum) // what we're setting
  617. );
  618. }
  619. DBGSTATIC void
  620. GetShareInfoDescriptors(
  621. DWORD level,
  622. LPDESC* pDesc16,
  623. LPDESC* pDesc32,
  624. LPDESC* pDescSmb,
  625. LPDWORD pDataSize
  626. )
  627. /*++
  628. Routine Description:
  629. A routinette to return pointers to the 16- and 32-bit share info
  630. structure descriptor strings for each level (0, 1, 2). Also returns
  631. the size required for a returned 16-bit structure converted to 32-bit data
  632. Arguments:
  633. level - of information to be returned
  634. pDesc16 - pointer to returned 16-bit descriptor string
  635. pDesc32 - pointer to returned 32-bit descriptor string
  636. pDescSmb - pointer to returned SMB descriptor string
  637. pDataSize - pointer to returned size of 16-bit structure
  638. Return Value:
  639. None.
  640. --*/
  641. {
  642. switch (level) {
  643. case 0:
  644. *pDesc16 = REM16_share_info_0;
  645. *pDesc32 = REM32_share_info_0;
  646. *pDescSmb = REMSmb_share_info_0;
  647. *pDataSize = DWORD_ROUNDUP(sizeof(SHARE_INFO_0) // structure size
  648. + LM20_NNLEN + 1); // + shi0_netname len
  649. break;
  650. case 1:
  651. *pDesc16 = REM16_share_info_1;
  652. *pDesc32 = REM32_share_info_1;
  653. *pDescSmb = REMSmb_share_info_1;
  654. *pDataSize = DWORD_ROUNDUP(sizeof(SHARE_INFO_1) // structure size
  655. + LM20_NNLEN + 1 // + shi1_netname len
  656. + LM20_MAXCOMMENTSZ + 1); // + shi1_remark len
  657. break;
  658. case 2:
  659. *pDesc16 = REM16_share_info_2;
  660. *pDesc32 = REM32_share_info_2;
  661. *pDescSmb = REMSmb_share_info_2;
  662. *pDataSize = DWORD_ROUNDUP(sizeof(SHARE_INFO_2) // structure size
  663. + LM20_NNLEN + 1 // + shi2_netname len
  664. + LM20_MAXCOMMENTSZ + 1 // + shi2_remark len
  665. + LM20_PATHLEN + 1 // + shi2_path len
  666. + SHPWLEN + 1); // + shi2_passwd len
  667. break;
  668. #if DBG
  669. //
  670. // just to be completely paranoid...
  671. //
  672. default:
  673. NetpKdPrint(("%s.%u Unknown Level parameter: %u\n", __FILE__, __LINE__, level));
  674. #endif
  675. }
  676. #if DBG
  677. NetpAssert(INITIAL_BUFFER_SIZE % *pDataSize);
  678. #endif
  679. }
  680. DBGSTATIC
  681. VOID
  682. ConvertMaxUsesField(
  683. IN LPSHARE_INFO_2 Buffer,
  684. IN DWORD NumberOfLevel2Structures
  685. )
  686. /*++
  687. Routine Description:
  688. Given a buffer containing 1 or more SHARE_INFO_2 structures, converts the
  689. shi2_max_uses field to a sensible value. The underlying RAP code converts
  690. the 16-bit number as a signed value, such that 32768 => -32768L. 65535 is
  691. the only 16-bit value which should be sign-extended. Everything else
  692. should be represented as the same number in 32-bits
  693. Arguments:
  694. Buffer - pointer to list of SHARE_INFO_2 structures
  695. NumberOfLevel2Structures - how many structures in list
  696. Return Value:
  697. None.
  698. --*/
  699. {
  700. while (NumberOfLevel2Structures--) {
  701. if (Buffer->shi2_max_uses != -1L) {
  702. Buffer->shi2_max_uses &= 0xffffL;
  703. }
  704. ++Buffer;
  705. }
  706. }