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.

759 lines
19 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. ApiUse.c
  5. Abstract:
  6. This module contains individual API handlers for the NetUse APIs.
  7. SUPPORTED : NetUseAdd, NetUseDel, NetUseEnum, NetUseGetInfo.
  8. NOTE : These handlers are only provided as exports by the XACTSRV
  9. DLL, for use by clients such as VDM. They are not supported
  10. for remote clients.
  11. Author:
  12. Shanku Niyogi (w-shanku) 31-Jan-1991
  13. Revision History:
  14. --*/
  15. #include "XactSrvP.h"
  16. //
  17. // Declaration of descriptor strings.
  18. //
  19. STATIC const LPDESC Desc16_use_info_0 = REM16_use_info_0;
  20. STATIC const LPDESC Desc32_use_info_0 = REM32_use_info_0;
  21. STATIC const LPDESC Desc16_use_info_1 = REM16_use_info_1;
  22. STATIC const LPDESC Desc32_use_info_1 = REM32_use_info_1;
  23. STATIC NET_API_STATUS
  24. XsNetUseEnumVerify (
  25. IN NET_API_STATUS ConvertStatus,
  26. IN PBYTE ConvertedEntry,
  27. IN PBYTE BaseAddress
  28. )
  29. /*++
  30. Routine Description:
  31. This function is called by XsFillEnumBuffer after each entry is
  32. converted, in order to determine whether the entry should be retained
  33. in the enum buffer or discarded.
  34. The use_info_x structures contain sharenames in a field with the format
  35. \\computername\sharename. XACTSRV must not return information about
  36. shares or computers with names longer than are allowed under LanMan 2.0.
  37. RapConvertSingleEntry can only insure that the entire field does not
  38. exceed the specified length; it cannot verify the lengths of individual
  39. components of a sharename. So this function is called by
  40. XsFillEnumBuffer after each call to RapConvertSingleEntry in order to
  41. check whether the converted entry satisfies this additional constraint.
  42. Arguments:
  43. ConvertStatus - The return code from RapConvertSingleEntry.
  44. ConvertedEntry - The converted entry created by RapConvertSingleEntry.
  45. BaseAddress - A pointer to the base used to calculate offsets.
  46. Return Value:
  47. NTSTATUS - STATUS_INVALID_PARAMETER if the entry should be retained, or
  48. an error code if the entry should be discarded.
  49. --*/
  50. {
  51. NTSTATUS status;
  52. DWORD remote;
  53. PUSE_16_INFO_0 use = (PUSE_16_INFO_0)ConvertedEntry;
  54. //
  55. // If RapConvertSingleEntry failed, discard the entry.
  56. //
  57. if ( ConvertStatus != NERR_Success ) {
  58. return ERROR_INVALID_PARAMETER;
  59. }
  60. //
  61. // If the sharename is too long, discard the entry.
  62. //
  63. remote = (DWORD)SmbGetUlong( &use->ui0_remote );
  64. status = ( remote == 0 ) ? NERR_Success
  65. : XsValidateShareName( BaseAddress + remote );
  66. IF_DEBUG(CONVERT) {
  67. if ( !NT_SUCCESS(status) ) {
  68. NetpKdPrint(( "XsNetUseEnumVerify: sharename too long: "
  69. "discarding entry\n" ));
  70. }
  71. }
  72. return status;
  73. }
  74. NTSTATUS
  75. XsNetUseAdd (
  76. API_HANDLER_PARAMETERS
  77. )
  78. /*++
  79. Routine Description:
  80. This routine handles a call to NetUseAdd.
  81. Arguments:
  82. API_HANDLER_PARAMETERS - information about the API call. See
  83. XsTypes.h for details.
  84. Return Value:
  85. NTSTATUS - STATUS_SUCCESS or reason for failure.
  86. --*/
  87. {
  88. NET_API_STATUS status;
  89. PXS_NET_USE_ADD parameters = Parameters;
  90. LPVOID buffer = NULL; // Native parameters
  91. LPBYTE stringLocation = NULL; // Conversion variables
  92. DWORD bytesRequired = 0;
  93. DWORD bufferSize;
  94. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  95. IF_DEBUG(USE) {
  96. NetpKdPrint(( "XsNetUseAdd: header at %lx, params at %lx, level %ld\n",
  97. Header, parameters, SmbGetUshort( &parameters->Level ) ));
  98. }
  99. try {
  100. //
  101. // Check for errors.
  102. //
  103. if ( SmbGetUshort( &parameters->Level ) != 1 ) {
  104. Header->Status = ERROR_INVALID_LEVEL;
  105. goto cleanup;
  106. }
  107. StructureDesc = Desc16_use_info_1;
  108. //
  109. // Figure out if there is enough room in the buffer for all the
  110. // data required. If not, return NERR_BufTooSmall.
  111. //
  112. if ( !XsCheckBufferSize(
  113. SmbGetUshort( &parameters->BufLen ),
  114. StructureDesc,
  115. FALSE // not in native format yet
  116. )) {
  117. IF_DEBUG(ERRORS) {
  118. NetpKdPrint(( "XsNetUseAdd: Buffer too small.\n" ));
  119. }
  120. Header->Status = NERR_BufTooSmall;
  121. goto cleanup;
  122. }
  123. //
  124. // Find out how big a buffer we need to allocate to hold the native
  125. // 32-bit version of the input data structure.
  126. //
  127. bufferSize = XsBytesForConvertedStructure(
  128. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  129. StructureDesc,
  130. Desc32_use_info_1,
  131. RapToNative,
  132. TRUE
  133. );
  134. //
  135. // Allocate enough memory to hold the converted native buffer.
  136. //
  137. buffer = NetpMemoryAllocate( bufferSize );
  138. if ( buffer == NULL ) {
  139. IF_DEBUG(ERRORS) {
  140. NetpKdPrint(( "XsNetUseAdd: failed to create buffer" ));
  141. }
  142. Header->Status = NERR_NoRoom;
  143. goto cleanup;
  144. }
  145. IF_DEBUG(USE) {
  146. NetpKdPrint(( "XsNetUseAdd: buffer of %ld bytes at %lx\n",
  147. bufferSize, buffer ));
  148. }
  149. //
  150. // Convert the buffer from 16-bit to 32-bit.
  151. //
  152. stringLocation = (LPBYTE)buffer + bufferSize;
  153. bytesRequired = 0;
  154. status = RapConvertSingleEntry(
  155. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  156. StructureDesc,
  157. TRUE,
  158. buffer,
  159. buffer,
  160. Desc32_use_info_1,
  161. FALSE,
  162. &stringLocation,
  163. &bytesRequired,
  164. Response,
  165. RapToNative
  166. );
  167. if ( status != NERR_Success ) {
  168. IF_DEBUG(ERRORS) {
  169. NetpKdPrint(( "XsNetUseAdd: RapConvertSingleEntry failed: "
  170. "%X\n", status ));
  171. }
  172. Header->Status = NERR_InternalError;
  173. goto cleanup;
  174. }
  175. //
  176. // RLF
  177. //
  178. // if use_info_1.ui1_asg_type is 0xffff meaning wildcard, we have to
  179. // convert it to 0xffffffff since NetUseAdd is going to compare it
  180. // against (DWORD)(-1) and RapConvertSingleEntry has only converted it
  181. // to 0x0000ffff which results in an error
  182. //
  183. if (((LPUSE_INFO_1)buffer)->ui1_asg_type == 0xffff) {
  184. ((LPUSE_INFO_1)buffer)->ui1_asg_type = 0xffffffff;
  185. }
  186. //
  187. // Do the actual local call.
  188. //
  189. status = NetUseAdd(
  190. NULL,
  191. (DWORD)SmbGetUshort( &parameters->Level ),
  192. (LPBYTE)buffer,
  193. NULL
  194. );
  195. if ( !XsApiSuccess( status )) {
  196. IF_DEBUG(ERRORS) {
  197. NetpKdPrint(( "XsNetUseAdd: NetUseAdd failed: %X\n", status ));
  198. }
  199. Header->Status = (WORD)status;
  200. goto cleanup;
  201. }
  202. //
  203. // There is no real return information for this API.
  204. //
  205. cleanup:
  206. ;
  207. } except( EXCEPTION_EXECUTE_HANDLER ) {
  208. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  209. }
  210. NetpMemoryFree( buffer );
  211. return STATUS_SUCCESS;
  212. } // XsNetUseAdd
  213. NTSTATUS
  214. XsNetUseDel (
  215. API_HANDLER_PARAMETERS
  216. )
  217. /*++
  218. Routine Description:
  219. This routine handles a call to NetUseDel.
  220. Arguments:
  221. API_HANDLER_PARAMETERS - information about the API call. See
  222. XsTypes.h for details.
  223. Return Value:
  224. NTSTATUS - STATUS_SUCCESS or reason for failure.
  225. --*/
  226. {
  227. NET_API_STATUS status;
  228. PXS_NET_USE_DEL parameters = Parameters;
  229. LPTSTR nativeUseName = NULL; // Native parameters
  230. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  231. IF_DEBUG(USE) {
  232. NetpKdPrint(( "XsNetUseDel: header at %lx, params at %lx, device %s\n",
  233. Header, parameters, SmbGetUlong( &parameters->UseName )));
  234. }
  235. try {
  236. //
  237. // Translate parameters, check for errors.
  238. //
  239. XsConvertTextParameter(
  240. nativeUseName,
  241. (LPSTR)XsSmbGetPointer( &parameters->UseName )
  242. );
  243. //
  244. // Do local call, with converted parameter values.
  245. //
  246. status = NetUseDel(
  247. NULL,
  248. nativeUseName,
  249. (DWORD)SmbGetUshort( &parameters->Force )
  250. );
  251. if ( !XsApiSuccess( status )) {
  252. IF_DEBUG(ERRORS) {
  253. NetpKdPrint(( "XsNetUseDel: NetUseDel failed: %X\n", status ));
  254. }
  255. }
  256. //
  257. // Nothing to return.
  258. //
  259. Header->Status = (WORD)status;
  260. cleanup:
  261. ;
  262. } except( EXCEPTION_EXECUTE_HANDLER ) {
  263. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  264. }
  265. NetpMemoryFree( nativeUseName );
  266. return STATUS_SUCCESS;
  267. } // XsNetUseDel
  268. NTSTATUS
  269. XsNetUseEnum (
  270. API_HANDLER_PARAMETERS
  271. )
  272. /*+
  273. Routine Description:
  274. This routine handles a call to NetUseEnum.
  275. Arguments:
  276. API_HANDLER_PARAMETERS - information about the API call. See
  277. XsTypes.h for details.
  278. Return Value:
  279. NTSTATUS - STATUS_SUCCESS or reason for failure.
  280. +
  281. --*/
  282. {
  283. NET_API_STATUS status;
  284. PXS_NET_USE_ENUM parameters = Parameters;
  285. LPVOID outBuffer = NULL; // Native parameters
  286. DWORD entriesRead;
  287. DWORD totalEntries;
  288. DWORD entriesFilled = 0; // Conversion variables
  289. DWORD invalidEntries = 0;
  290. DWORD bytesRequired;
  291. LPDESC nativeStructureDesc;
  292. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  293. IF_DEBUG(USE) {
  294. NetpKdPrint(( "XsNetUseEnum: header at %lx, params at %lx, level %ld, "
  295. "buf size %ld\n",
  296. Header, parameters, SmbGetUshort( &parameters->Level ),
  297. SmbGetUshort( &parameters->BufLen )));
  298. }
  299. try {
  300. //
  301. // Check for errors.
  302. //
  303. if ( XsWordParamOutOfRange( parameters->Level, 0, 1 )) {
  304. Header->Status = ERROR_INVALID_LEVEL;
  305. goto cleanup;
  306. }
  307. //
  308. // Make the local call.
  309. //
  310. status = NetUseEnum(
  311. NULL,
  312. (DWORD)SmbGetUshort( &parameters->Level ),
  313. (LPBYTE *)&outBuffer,
  314. XsNativeBufferSize( SmbGetUshort( &parameters->BufLen )),
  315. &entriesRead,
  316. &totalEntries,
  317. NULL
  318. );
  319. if ( !XsApiSuccess( status )) {
  320. IF_DEBUG(API_ERRORS) {
  321. NetpKdPrint(( "XsNetUseEnum: NetUseEnum failed: %X\n", status ));
  322. }
  323. Header->Status = (WORD)status;
  324. goto cleanup;
  325. }
  326. IF_DEBUG(USE) {
  327. NetpKdPrint(( "XsNetUseEnum: received %ld entries at %lx\n",
  328. entriesRead, outBuffer ));
  329. }
  330. //
  331. // Use the requested level to determine the format of the
  332. // data structure.
  333. //
  334. switch ( SmbGetUshort( &parameters->Level ) ) {
  335. case 0:
  336. nativeStructureDesc = Desc32_use_info_0;
  337. StructureDesc = Desc16_use_info_0;
  338. break;
  339. case 1:
  340. nativeStructureDesc = Desc32_use_info_1;
  341. StructureDesc = Desc16_use_info_1;
  342. break;
  343. }
  344. //
  345. // Do the actual conversion from the 32-bit structures to 16-bit
  346. // structures.
  347. //
  348. XsFillEnumBuffer(
  349. outBuffer,
  350. entriesRead,
  351. nativeStructureDesc,
  352. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  353. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  354. SmbGetUshort( &parameters->BufLen ),
  355. StructureDesc,
  356. &XsNetUseEnumVerify,
  357. &bytesRequired,
  358. &entriesFilled,
  359. &invalidEntries
  360. );
  361. IF_DEBUG(USE) {
  362. NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR,"
  363. " Entries %ld of %ld\n",
  364. outBuffer, SmbGetUlong( &parameters->Buffer ),
  365. bytesRequired, entriesFilled, totalEntries ));
  366. }
  367. //
  368. // If all the entries could not be filled, return ERROR_MORE_DATA,
  369. // and return the buffer as is. Otherwise, the data needs to be
  370. // packed so that we don't send too much useless data.
  371. //
  372. if (( entriesFilled + invalidEntries ) < totalEntries ) {
  373. Header->Status = ERROR_MORE_DATA;
  374. } else {
  375. Header->Converter = XsPackReturnData(
  376. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  377. SmbGetUshort( &parameters->BufLen ),
  378. StructureDesc,
  379. entriesFilled
  380. );
  381. }
  382. //
  383. // Set up the response parameters.
  384. //
  385. SmbPutUshort( &parameters->EntriesRead, (WORD)entriesFilled );
  386. SmbPutUshort( &parameters->TotalAvail,
  387. (WORD)( totalEntries - invalidEntries ));
  388. cleanup:
  389. ;
  390. } except( EXCEPTION_EXECUTE_HANDLER ) {
  391. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  392. }
  393. NetApiBufferFree( outBuffer );
  394. //
  395. // Determine return buffer size.
  396. //
  397. XsSetDataCount(
  398. &parameters->BufLen,
  399. StructureDesc,
  400. Header->Converter,
  401. entriesFilled,
  402. Header->Status
  403. );
  404. return STATUS_SUCCESS;
  405. } // NetUseEnum
  406. NTSTATUS
  407. XsNetUseGetInfo (
  408. API_HANDLER_PARAMETERS
  409. )
  410. /*++
  411. Routine Description:
  412. This routine handles a call to NetUseGetInfo.
  413. Arguments:
  414. API_HANDLER_PARAMETERS - information about the API call. See
  415. XsTypes.h for details.
  416. Return Value:
  417. NTSTATUS - STATUS_SUCCESS or reason for failure.
  418. --*/
  419. {
  420. NET_API_STATUS status;
  421. PXS_NET_USE_GET_INFO parameters = Parameters;
  422. LPTSTR nativeUseName = NULL; // Native parameters
  423. LPVOID outBuffer = NULL;
  424. LPBYTE stringLocation = NULL; // Conversion variables
  425. DWORD bytesRequired = 0;
  426. LPDESC nativeStructureDesc;
  427. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  428. IF_DEBUG(USE) {
  429. NetpKdPrint(( "XsNetUseGetInfo: header at %lx, "
  430. "params at %lx, level %ld\n",
  431. Header, parameters, SmbGetUshort( &parameters->Level ) ));
  432. }
  433. try {
  434. //
  435. // Translate parameters, check for errors.
  436. //
  437. XsConvertTextParameter(
  438. nativeUseName,
  439. (LPSTR)XsSmbGetPointer( &parameters->UseName )
  440. );
  441. //
  442. // Do the actual local call.
  443. //
  444. status = NetUseGetInfo(
  445. NULL,
  446. nativeUseName,
  447. (DWORD)SmbGetUshort( &parameters->Level ),
  448. (LPBYTE *)&outBuffer
  449. );
  450. if ( !XsApiSuccess( status )) {
  451. IF_DEBUG(API_ERRORS) {
  452. NetpKdPrint(( "XsNetUseGetInfo: NetUseGetInfo failed: "
  453. "%X\n", status ));
  454. }
  455. Header->Status = (WORD)status;
  456. goto cleanup;
  457. }
  458. //
  459. // Use the requested level to determine the format of the 32-bit
  460. // structure we got back from NetUseGetInfo. The format of the
  461. // 16-bit structure is stored in the transaction block, and we
  462. // got a pointer to it as a parameter.
  463. //
  464. switch ( SmbGetUshort( &parameters->Level ) ) {
  465. case 0:
  466. nativeStructureDesc = Desc32_use_info_0;
  467. StructureDesc = Desc16_use_info_0;
  468. break;
  469. case 1:
  470. nativeStructureDesc = Desc32_use_info_1;
  471. StructureDesc = Desc16_use_info_1;
  472. break;
  473. }
  474. //
  475. // Convert the structure returned by the 32-bit call to a 16-bit
  476. // structure. The last possible location for variable data is
  477. // calculated from buffer location and length.
  478. //
  479. stringLocation = (LPBYTE)( XsSmbGetPointer( &parameters->Buffer )
  480. + SmbGetUshort( &parameters->BufLen ) );
  481. status = RapConvertSingleEntry(
  482. outBuffer,
  483. nativeStructureDesc,
  484. FALSE,
  485. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  486. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  487. StructureDesc,
  488. TRUE,
  489. &stringLocation,
  490. &bytesRequired,
  491. Response,
  492. NativeToRap
  493. );
  494. if ( status != NERR_Success ) {
  495. IF_DEBUG(ERRORS) {
  496. NetpKdPrint(( "XsNetUseGetInfo: RapConvertSingleEntry failed: "
  497. "%X\n", status ));
  498. }
  499. Header->Status = NERR_InternalError;
  500. goto cleanup;
  501. }
  502. IF_DEBUG(USE) {
  503. NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR\n",
  504. outBuffer, SmbGetUlong( &parameters->Buffer ),
  505. bytesRequired ));
  506. }
  507. //
  508. // Determine return code based on the size of the buffer.
  509. //
  510. if ( !XsCheckBufferSize(
  511. SmbGetUshort( &parameters->BufLen ),
  512. StructureDesc,
  513. FALSE // not in native format
  514. )) {
  515. IF_DEBUG(ERRORS) {
  516. NetpKdPrint(( "XsNetUseGetInfo: Buffer too small.\n" ));
  517. }
  518. Header->Status = NERR_BufTooSmall;
  519. } else if ( bytesRequired > (DWORD)SmbGetUshort( &parameters-> BufLen )) {
  520. IF_DEBUG(ERRORS) {
  521. NetpKdPrint(( "NetUseGetInfo: More data available.\n" ));
  522. }
  523. Header->Status = ERROR_MORE_DATA;
  524. } else {
  525. //
  526. // Pack the response data.
  527. //
  528. Header->Converter = XsPackReturnData(
  529. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  530. SmbGetUshort( &parameters->BufLen ),
  531. StructureDesc,
  532. 1
  533. );
  534. }
  535. //
  536. // Set up the response parameters.
  537. //
  538. SmbPutUshort( &parameters->TotalAvail, (WORD)bytesRequired );
  539. cleanup:
  540. ;
  541. } except( EXCEPTION_EXECUTE_HANDLER ) {
  542. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  543. }
  544. NetApiBufferFree( outBuffer );
  545. //
  546. // Determine return buffer size.
  547. //
  548. XsSetDataCount(
  549. &parameters->BufLen,
  550. StructureDesc,
  551. Header->Converter,
  552. 1,
  553. Header->Status
  554. );
  555. return STATUS_SUCCESS;
  556. } // NetUseGetInfo