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.

1422 lines
42 KiB

  1. /*++
  2. Copyright (c) 1991-1992 Microsoft Corporation
  3. Module Name:
  4. ApiSrv.c
  5. Abstract:
  6. This module contains individual API handlers for the NetServer APIs.
  7. SUPPORTED : NetServerDiskEnum, NetServerEnum2, NetServerGetInfo,
  8. NetServerSetInfo.
  9. SEE ALSO : NetServerAuthenticate, NetServerPasswordSet,
  10. NetServerReqChallenge - in ApiLogon.c.
  11. Author:
  12. Shanku Niyogi (w-shanku) 25-Feb-1991
  13. Revision History:
  14. --*/
  15. #include "XactSrvP.h"
  16. #include <lmbrowsr.h> // Definition of I_BrowserServerEnum
  17. //
  18. // Declaration of descriptor strings.
  19. //
  20. STATIC const LPDESC Desc16_server_info_0 = REM16_server_info_0;
  21. STATIC const LPDESC Desc32_server_info_0 = REM32_server_info_0;
  22. STATIC const LPDESC Desc16_server_info_1 = REM16_server_info_1;
  23. STATIC const LPDESC Desc32_server_info_1 = REM32_server_info_1;
  24. STATIC const LPDESC Desc16_server_info_2 = REM16_server_info_2;
  25. STATIC const LPDESC Desc32_server_info_2 = REM32_server_info_2;
  26. STATIC const LPDESC Desc16_server_info_3 = REM16_server_info_3;
  27. STATIC const LPDESC Desc32_server_info_3 = REM32_server_info_3;
  28. NTSTATUS
  29. XsNetServerDiskEnum (
  30. API_HANDLER_PARAMETERS
  31. )
  32. /*++
  33. Routine Description:
  34. This routine handles a call to NetServerDiskEnum.
  35. Arguments:
  36. API_HANDLER_PARAMETERS - information about the API call. See
  37. XsTypes.h for details.
  38. Return Value:
  39. NTSTATUS - STATUS_SUCCESS or reason for failure.
  40. --*/
  41. {
  42. NET_API_STATUS status;
  43. PXS_NET_SERVER_DISK_ENUM parameters = Parameters;
  44. LPBYTE outBuffer = NULL; // Native parameters
  45. DWORD entriesRead;
  46. DWORD totalEntries = 0;
  47. DWORD entriesFilled = 0; // Conversion variables
  48. DWORD bufferLength;
  49. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  50. try {
  51. //
  52. // Check for errors.
  53. //
  54. if ( SmbGetUshort( &parameters->Level ) != 0 ) {
  55. Header->Status = ERROR_INVALID_LEVEL;
  56. goto cleanup;
  57. }
  58. //
  59. // Make the local call.
  60. //
  61. bufferLength = (DWORD)SmbGetUshort( &parameters->BufLen );
  62. status = NetServerDiskEnum(
  63. NULL,
  64. (DWORD)SmbGetUshort( &parameters->Level ),
  65. (LPBYTE *)&outBuffer,
  66. XsNativeBufferSize( bufferLength ),
  67. &entriesRead,
  68. &totalEntries,
  69. NULL
  70. );
  71. if ( !XsApiSuccess( status )) {
  72. IF_DEBUG(ERRORS) {
  73. NetpKdPrint(( "XsNetServer: NetServerDiskEnum failed: "
  74. "%X\n", status ));
  75. }
  76. Header->Status = (WORD)status;
  77. goto cleanup;
  78. }
  79. //
  80. // Calculate how many entries will fit in 16-bit buffer;
  81. //
  82. if ( bufferLength > 0 ) {
  83. DWORD elementSize;
  84. elementSize = RapStructureSize( StructureDesc, Response, FALSE );
  85. if (elementSize != 0) {
  86. entriesFilled = ( bufferLength - 1 ) / elementSize;
  87. }
  88. }
  89. if ( entriesFilled < entriesRead ) {
  90. status = ERROR_MORE_DATA;
  91. } else {
  92. entriesFilled = entriesRead;
  93. status = NERR_Success;
  94. }
  95. //
  96. // Copy native buffer to 16-bit buffer, converting Unicode to Ansi
  97. // if necessary.
  98. //
  99. if ( bufferLength > 0 ) {
  100. DWORD i;
  101. LPTSTR entryIn = (LPTSTR)outBuffer;
  102. LPSTR entryOut = (LPSTR)XsSmbGetPointer( &parameters->Buffer );
  103. for ( i = 0; i < entriesFilled; i++ ) {
  104. NetpCopyWStrToStrDBCS( entryOut, entryIn );
  105. entryOut += ( strlen( entryOut ) + 1 );
  106. entryIn += ( STRLEN( entryIn ) + 1 );
  107. }
  108. strcpy( entryOut, "" );
  109. }
  110. Header->Status = (WORD)status;
  111. cleanup:
  112. ;
  113. } except( EXCEPTION_EXECUTE_HANDLER ) {
  114. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  115. }
  116. //
  117. // Put return data into fields.
  118. //
  119. SmbPutUshort( &parameters->EntriesRead, (WORD)entriesFilled );
  120. SmbPutUshort( &parameters->TotalAvail, (WORD)totalEntries );
  121. return STATUS_SUCCESS;
  122. } // XsNetServerDiskEnum
  123. NTSTATUS
  124. XsNetServerEnum2 (
  125. API_HANDLER_PARAMETERS
  126. )
  127. /*++
  128. Routine Description:
  129. This routine handles a call to NetServerEnum.
  130. Arguments:
  131. API_HANDLER_PARAMETERS - information about the API call. See
  132. XsTypes.h for details.
  133. Transport - The name of the transport provided to the API.
  134. Return Value:
  135. NTSTATUS - STATUS_SUCCESS or reason for failure.
  136. --*/
  137. {
  138. NET_API_STATUS status = NERR_Success;
  139. PXS_NET_SERVER_ENUM_2 parameters = Parameters;
  140. LPTSTR nativeDomain = NULL; // Native parameters
  141. LPVOID outBuffer= NULL;
  142. DWORD entriesRead;
  143. DWORD totalEntries;
  144. LPTSTR clientTransportName = NULL;
  145. LPTSTR clientName = NULL;
  146. DWORD entriesFilled = 0; // Conversion variables
  147. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  148. IF_DEBUG(SERVER) {
  149. NetpKdPrint(( "XsNetServerEnum2: header at %lx, params at %lx, "
  150. "level %ld, buf size %ld\n",
  151. Header, parameters, SmbGetUshort( &parameters->Level ),
  152. SmbGetUshort( &parameters->BufLen )));
  153. }
  154. try {
  155. //
  156. // Translate parameters, check for errors.
  157. //
  158. if ( XsWordParamOutOfRange( parameters->Level, 0, 1 )) {
  159. Header->Status = ERROR_INVALID_LEVEL;
  160. goto cleanup;
  161. }
  162. XsConvertTextParameter(
  163. nativeDomain,
  164. (LPSTR)XsSmbGetPointer( &parameters->Domain )
  165. );
  166. clientTransportName = Header->ClientTransportName;
  167. clientName = Header->ClientMachineName;
  168. //
  169. // Get the actual server information from the local 32-bit call. The
  170. // native level is 100 or 101.
  171. //
  172. if (clientTransportName == NULL) {
  173. status = NetServerEnum(
  174. NULL,
  175. 100 + (DWORD)SmbGetUshort( &parameters->Level ),
  176. (LPBYTE *)&outBuffer,
  177. XsNativeBufferSize( SmbGetUshort( &parameters->BufLen )),
  178. &entriesRead,
  179. &totalEntries,
  180. SmbGetUlong( &parameters->ServerType ),
  181. nativeDomain,
  182. NULL
  183. );
  184. if ( !XsApiSuccess( status ) ) {
  185. IF_DEBUG(API_ERRORS) {
  186. NetpKdPrint(( "XsNetServerEnum2: NetServerEnum failed: %X\n",
  187. status ));
  188. }
  189. Header->Status = (WORD)status;
  190. goto cleanup;
  191. }
  192. Header->Status = XsConvertServerEnumBuffer(
  193. outBuffer,
  194. entriesRead,
  195. &totalEntries,
  196. SmbGetUshort( &parameters->Level ),
  197. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  198. SmbGetUshort( &parameters->BufLen ),
  199. &entriesFilled,
  200. &Header->Converter);
  201. } else {
  202. Header->Status = I_BrowserServerEnumForXactsrv(
  203. clientTransportName,
  204. clientName,
  205. 100 + SmbGetUshort( &parameters->Level ),
  206. SmbGetUshort( &parameters->Level ),
  207. (PVOID)XsSmbGetPointer( &parameters->Buffer ),
  208. SmbGetUshort( &parameters->BufLen ),
  209. XsNativeBufferSize( SmbGetUshort( &parameters->BufLen ) ),
  210. &entriesFilled,
  211. &totalEntries,
  212. SmbGetUlong( &parameters->ServerType ),
  213. nativeDomain,
  214. NULL,
  215. &Header->Converter
  216. );
  217. if (!XsApiSuccess( Header->Status )) {
  218. IF_DEBUG(API_ERRORS) {
  219. NetpKdPrint(( "XsNetServerEnum2: I_BrowserServerEnum failed: %d\n", Header->Status));
  220. }
  221. goto cleanup;
  222. }
  223. }
  224. if ( entriesFilled == 0 ) {
  225. SmbPutUshort( &parameters->BufLen, 0 );
  226. }
  227. //
  228. // Set up the response parameters.
  229. //
  230. SmbPutUshort( &parameters->EntriesRead, (WORD)entriesFilled );
  231. SmbPutUshort( &parameters->TotalAvail, (WORD)totalEntries );
  232. cleanup:
  233. ;
  234. } except( EXCEPTION_EXECUTE_HANDLER ) {
  235. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  236. }
  237. if ( outBuffer != NULL ) {
  238. NetApiBufferFree( outBuffer );
  239. }
  240. NetpMemoryFree( nativeDomain );
  241. //
  242. // Determine return buffer size.
  243. //
  244. XsSetDataCount(
  245. &parameters->BufLen,
  246. SmbGetUshort( &parameters->Level ) == 0 ?
  247. Desc16_server_info_0 :
  248. Desc16_server_info_1,
  249. Header->Converter,
  250. entriesFilled,
  251. Header->Status
  252. );
  253. return STATUS_SUCCESS;
  254. } // XsNetServerEnum2
  255. NTSTATUS
  256. XsNetServerEnum3 (
  257. API_HANDLER_PARAMETERS
  258. )
  259. /*++
  260. Routine Description:
  261. This routine handles a call to NetServerEnum.
  262. Arguments:
  263. API_HANDLER_PARAMETERS - information about the API call. See
  264. XsTypes.h for details.
  265. Transport - The name of the transport provided to the API.
  266. Return Value:
  267. NTSTATUS - STATUS_SUCCESS or reason for failure.
  268. --*/
  269. {
  270. NET_API_STATUS status = NERR_Success;
  271. PXS_NET_SERVER_ENUM_3 parameters = Parameters;
  272. LPTSTR nativeDomain = NULL; // Native parameters
  273. LPTSTR nativeFirstNameToReturn = NULL; // Native parameters
  274. LPVOID outBuffer= NULL;
  275. DWORD entriesRead;
  276. DWORD totalEntries;
  277. LPTSTR clientTransportName = NULL;
  278. LPTSTR clientName = NULL;
  279. DWORD entriesFilled = 0; // Conversion variables
  280. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  281. IF_DEBUG(SERVER) {
  282. NetpKdPrint(( "XsNetServerEnum3: header at %lx, params at %lx, "
  283. "level %ld, buf size %ld\n",
  284. Header, parameters, SmbGetUshort( &parameters->Level ),
  285. SmbGetUshort( &parameters->BufLen )));
  286. }
  287. try {
  288. //
  289. // Translate parameters, check for errors.
  290. //
  291. if ( XsWordParamOutOfRange( parameters->Level, 0, 1 )) {
  292. Header->Status = ERROR_INVALID_LEVEL;
  293. goto cleanup;
  294. }
  295. XsConvertTextParameter(
  296. nativeDomain,
  297. (LPSTR)XsSmbGetPointer( &parameters->Domain )
  298. );
  299. XsConvertTextParameter(
  300. nativeFirstNameToReturn,
  301. (LPSTR)XsSmbGetPointer( &parameters->FirstNameToReturn )
  302. );
  303. clientTransportName = Header->ClientTransportName;
  304. clientName = Header->ClientMachineName;
  305. //
  306. // Get the actual server information from the local 32-bit call. The
  307. // native level is 100 or 101.
  308. //
  309. if (clientTransportName == NULL) {
  310. status = NetServerEnumEx(
  311. NULL,
  312. 100 + (DWORD)SmbGetUshort( &parameters->Level ),
  313. (LPBYTE *)&outBuffer,
  314. XsNativeBufferSize( SmbGetUshort( &parameters->BufLen )),
  315. &entriesRead,
  316. &totalEntries,
  317. SmbGetUlong( &parameters->ServerType ),
  318. nativeDomain,
  319. nativeFirstNameToReturn
  320. );
  321. if ( !XsApiSuccess( status ) ) {
  322. IF_DEBUG(API_ERRORS) {
  323. NetpKdPrint(( "XsNetServerEnum3: NetServerEnum failed: %X\n",
  324. status ));
  325. }
  326. Header->Status = (WORD)status;
  327. goto cleanup;
  328. }
  329. Header->Status = XsConvertServerEnumBuffer(
  330. outBuffer,
  331. entriesRead,
  332. &totalEntries,
  333. SmbGetUshort( &parameters->Level ),
  334. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  335. SmbGetUshort( &parameters->BufLen ),
  336. &entriesFilled,
  337. &Header->Converter);
  338. } else {
  339. Header->Status = I_BrowserServerEnumForXactsrv(
  340. clientTransportName,
  341. clientName,
  342. 100 + SmbGetUshort( &parameters->Level ),
  343. SmbGetUshort( &parameters->Level ),
  344. (PVOID)XsSmbGetPointer( &parameters->Buffer ),
  345. SmbGetUshort( &parameters->BufLen ),
  346. XsNativeBufferSize( SmbGetUshort( &parameters->BufLen ) ),
  347. &entriesFilled,
  348. &totalEntries,
  349. SmbGetUlong( &parameters->ServerType ),
  350. nativeDomain,
  351. nativeFirstNameToReturn,
  352. &Header->Converter
  353. );
  354. if (!XsApiSuccess( Header->Status )) {
  355. IF_DEBUG(API_ERRORS) {
  356. NetpKdPrint(( "XsNetServerEnum3: I_BrowserServerEnum failed: %d\n", Header->Status));
  357. }
  358. goto cleanup;
  359. }
  360. }
  361. if ( entriesFilled == 0 ) {
  362. SmbPutUshort( &parameters->BufLen, 0 );
  363. }
  364. //
  365. // Set up the response parameters.
  366. //
  367. SmbPutUshort( &parameters->EntriesRead, (WORD)entriesFilled );
  368. SmbPutUshort( &parameters->TotalAvail, (WORD)totalEntries );
  369. cleanup:
  370. ;
  371. } except( EXCEPTION_EXECUTE_HANDLER ) {
  372. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  373. }
  374. if ( outBuffer != NULL ) {
  375. NetApiBufferFree( outBuffer );
  376. }
  377. NetpMemoryFree( nativeDomain );
  378. NetpMemoryFree( nativeFirstNameToReturn );
  379. //
  380. // Determine return buffer size.
  381. //
  382. XsSetDataCount(
  383. &parameters->BufLen,
  384. SmbGetUshort( &parameters->Level ) == 0 ?
  385. Desc16_server_info_0 :
  386. Desc16_server_info_1,
  387. Header->Converter,
  388. entriesFilled,
  389. Header->Status
  390. );
  391. return STATUS_SUCCESS;
  392. } // XsNetServerEnum3
  393. USHORT
  394. XsConvertServerEnumBuffer(
  395. IN LPVOID ServerEnumBuffer,
  396. IN DWORD EntriesRead,
  397. IN OUT PDWORD TotalEntries,
  398. IN USHORT Level,
  399. IN LPBYTE ClientBuffer,
  400. IN USHORT BufferLength,
  401. OUT PDWORD EntriesFilled,
  402. OUT PUSHORT Converter
  403. )
  404. /*++
  405. Routine Description:
  406. This routine converts an NT server info array into a down level RAP
  407. server info buffer.
  408. Arguments:
  409. IN LPVOID ServerEnumBuffer - Buffer with NT server info.
  410. IN DWORD EntriesRead - Number of entries in buffer.
  411. IN OUT PDWORD TotalEntries - Total Number of entries.
  412. IN USHORT Level - Downlevel information Level (0 or 1).
  413. IN LPBYTE ClientBuffer - Pointer to 16 bit client side buffer.
  414. IN USHORT BufferLength - Size of client buffer.
  415. OUT PDWORD EntriesFilled - Number of entries converted into client buffer.
  416. OUT PUSHORT Converter - Converter used by client side to convert back.
  417. Return Value:
  418. USHORT - NERR_Success or reason for failure (16 bit DOS error).
  419. --*/
  420. {
  421. USHORT status = NERR_Success;
  422. DWORD invalidEntries;
  423. LPDESC nativeStructureDesc;
  424. DWORD bytesRequired = 0;
  425. PCHAR StructureDesc;
  426. IF_DEBUG(SERVER) {
  427. NetpKdPrint(( "XsConvertServerEnumBuffer: received %ld entries at %lx\n",
  428. EntriesRead, ServerEnumBuffer ));
  429. }
  430. //
  431. // Use the requested level to determine the format of the
  432. // data structure.
  433. //
  434. switch ( Level ) {
  435. case 0:
  436. StructureDesc = Desc16_server_info_0;
  437. nativeStructureDesc = Desc32_server_info_0;
  438. break;
  439. case 1:
  440. StructureDesc = Desc16_server_info_1;
  441. nativeStructureDesc = Desc32_server_info_1;
  442. break;
  443. }
  444. //
  445. // Do the actual conversion from the 32-bit structures to 16-bit
  446. // structures.
  447. //
  448. XsFillEnumBuffer(
  449. ServerEnumBuffer,
  450. EntriesRead,
  451. nativeStructureDesc,
  452. ClientBuffer,
  453. ClientBuffer,
  454. BufferLength,
  455. StructureDesc,
  456. NULL, // verify function
  457. &bytesRequired,
  458. EntriesFilled,
  459. &invalidEntries
  460. );
  461. IF_DEBUG(SERVER) {
  462. NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR,"
  463. " Entries %ld of %ld\n",
  464. ServerEnumBuffer, ClientBuffer ,
  465. bytesRequired, *EntriesFilled, *TotalEntries ));
  466. }
  467. //
  468. // If there are any invalid entries, subtract this from the
  469. // number of total entries to avoid the case where the client
  470. // keeps bugging us for more data.
  471. //
  472. if ( invalidEntries > 0) {
  473. (*TotalEntries) -= invalidEntries;
  474. #if DBG
  475. IF_DEBUG(API_ERRORS) {
  476. NetpKdPrint(( "XsNetServerEnum: %d invalid entries removed."
  477. " Total entries now %d, entries filled %d.\n",
  478. invalidEntries, *TotalEntries, *EntriesFilled ));
  479. }
  480. #endif
  481. }
  482. //
  483. // If all the entries could not be filled, return ERROR_MORE_DATA,
  484. // The data needs to be packed so that we don't send too much
  485. // useless data.
  486. //
  487. if ( (*EntriesFilled < *TotalEntries) ||
  488. (bytesRequired > BufferLength) ) {
  489. status = ERROR_MORE_DATA;
  490. }
  491. *Converter = XsPackReturnData(
  492. ClientBuffer,
  493. BufferLength,
  494. StructureDesc,
  495. *EntriesFilled
  496. );
  497. return status;
  498. } // XsConvertServerEnumBuffer
  499. NTSTATUS
  500. XsNetServerGetInfo (
  501. API_HANDLER_PARAMETERS
  502. )
  503. /*++
  504. Routine Description:
  505. This routine handles a call to NetServerGetInfo. Since NT only provides
  506. levels 100-102, this routine manually fills in default values for other
  507. fields. Because of this, the handling in this procedure is different
  508. from other Xs...GetInfo handlers.
  509. Arguments:
  510. API_HANDLER_PARAMETERS - information about the API call. See
  511. XsTypes.h for details.
  512. Return Value:
  513. NTSTATUS - STATUS_SUCCESS or reason for failure.
  514. --*/
  515. {
  516. NET_API_STATUS status;
  517. PXS_NET_SERVER_GET_INFO parameters = Parameters;
  518. DWORD localLevel; // Native parameters
  519. PSERVER_INFO_102 nativeStruct = NULL;
  520. PSERVER_INFO_502 secondaryNativeStruct = NULL;
  521. LPBYTE stringLocation = NULL; // Conversion variables
  522. DWORD bytesRequired = 0;
  523. DWORD sizeOfFixedStructure;
  524. LPDESC nativeStructureDesc;
  525. PSERVER_16_INFO_3 returnStruct;
  526. BOOLEAN bufferTooSmall = FALSE;
  527. LPWSTR ServerName = NULL;
  528. UCHAR serverNameBuf[ 2 + NETBIOS_NAME_LEN + 1 ];
  529. PUCHAR p;
  530. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  531. IF_DEBUG(SERVER) {
  532. NetpKdPrint(( "XsNetServerGetInfo: header at %lx, "
  533. "params at %lx, level %ld\n",
  534. Header, parameters, SmbGetUshort( &parameters->Level ) ));
  535. }
  536. try {
  537. //
  538. // Check for errors.
  539. //
  540. if ( XsWordParamOutOfRange( parameters->Level, 0, 3 ) ) {
  541. Header->Status = ERROR_INVALID_LEVEL;
  542. goto cleanup;
  543. }
  544. //
  545. // Use the 16-bit level number to determine the NT level number and the
  546. // native descriptor string.
  547. //
  548. switch ( SmbGetUshort( &parameters->Level ) ) {
  549. case 0:
  550. nativeStructureDesc = Desc32_server_info_0;
  551. StructureDesc = Desc16_server_info_0;
  552. localLevel = 100;
  553. break;
  554. case 1:
  555. nativeStructureDesc = Desc32_server_info_1;
  556. StructureDesc = Desc16_server_info_1;
  557. localLevel = 101;
  558. break;
  559. case 2:
  560. nativeStructureDesc = Desc32_server_info_2;
  561. StructureDesc = Desc16_server_info_2;
  562. localLevel = 102;
  563. break;
  564. case 3:
  565. nativeStructureDesc = Desc32_server_info_3;
  566. StructureDesc = Desc16_server_info_3;
  567. localLevel = 102;
  568. break;
  569. }
  570. //
  571. // If the buffer is not big enough, we have to continue doing the
  572. // Rap Conversion so that we can return the right buffer size to
  573. // the caller.
  574. //
  575. sizeOfFixedStructure = RapStructureSize( StructureDesc,
  576. Response,
  577. FALSE );
  578. if ( SmbGetUshort( &parameters->BufLen ) < sizeOfFixedStructure ) {
  579. IF_DEBUG(ERRORS) {
  580. NetpKdPrint(( "XsNetServerGetInfo: Buffer too small.\n" ));
  581. }
  582. bufferTooSmall = TRUE;
  583. }
  584. serverNameBuf[0] = serverNameBuf[1] = '\\';
  585. memcpy( &serverNameBuf[2], Header->ServerName, NETBIOS_NAME_LEN );
  586. for( p = &serverNameBuf[ NETBIOS_NAME_LEN + 1 ]; p > serverNameBuf && *p == ' '; p-- )
  587. ;
  588. *(p+1) = '\0';
  589. ServerName = XsDupStrToWStr( serverNameBuf );
  590. if( ServerName == NULL ) {
  591. Header->Status = NERR_NoRoom;
  592. goto cleanup;
  593. }
  594. //
  595. // Do the actual local call.
  596. //
  597. status = NetServerGetInfo(
  598. ServerName,
  599. localLevel,
  600. (LPBYTE *)&nativeStruct
  601. );
  602. if ( !XsApiSuccess( status )) {
  603. IF_DEBUG(API_ERRORS) {
  604. NetpKdPrint(( "XsNetServerGetInfo: NetServerGetInfo failed: "
  605. "%X\n", status ));
  606. }
  607. Header->Status = (WORD)status;
  608. goto cleanup;
  609. }
  610. //
  611. // For levels 2 and 3 (native level 102), additional data is
  612. // required from native level 502. Do this call.
  613. //
  614. if ( localLevel == 102 ) {
  615. status = NetServerGetInfo(
  616. ServerName,
  617. 502,
  618. (LPBYTE *)&secondaryNativeStruct
  619. );
  620. if ( !XsApiSuccess( status )) {
  621. IF_DEBUG(API_ERRORS) {
  622. NetpKdPrint(( "XsNetServerGetInfo: NetServerGetInfo failed: "
  623. "%X\n", status ));
  624. }
  625. Header->Status = (WORD)status;
  626. goto cleanup;
  627. }
  628. }
  629. //
  630. // Convert the structure returned by the 32-bit call to a 16-bit
  631. // structure. For levels 0 and 1, there is no additional work
  632. // involved after this step, so ConvertSingleEntry can store the
  633. // variable data in the structure. This is indicated by passing
  634. // the end of the entire buffer in stringLocation. For levels 2 and 3,
  635. // the manual filling scheme requires that variable data not be entered
  636. // at this stage, so stringLocation is set to the end of the fixed
  637. // structure.
  638. //
  639. stringLocation = (LPBYTE)XsSmbGetPointer( &parameters->Buffer );
  640. if ( !bufferTooSmall ) {
  641. stringLocation += ( localLevel == 102 ) ?
  642. sizeOfFixedStructure:
  643. SmbGetUshort( &parameters->BufLen );
  644. }
  645. status = RapConvertSingleEntry(
  646. (LPBYTE)nativeStruct,
  647. nativeStructureDesc,
  648. FALSE,
  649. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  650. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  651. StructureDesc,
  652. TRUE,
  653. &stringLocation,
  654. &bytesRequired,
  655. Response,
  656. NativeToRap
  657. );
  658. if ( status != NERR_Success ) {
  659. IF_DEBUG(ERRORS) {
  660. NetpKdPrint(( "XsNetServerGetInfo: RapConvertSingleEntry failed: "
  661. "%X\n", status ));
  662. }
  663. Header->Status = NERR_InternalError;
  664. goto cleanup;
  665. }
  666. //
  667. // For levels 2 and 3, the number of bytes required is, in fact, more than
  668. // that returned by ConvertSingleEntry. We also need space for the
  669. // string defaults.
  670. //
  671. if ( localLevel == 102 ) {
  672. //
  673. // The number we get from rap includes some string lengths.
  674. // We only need the fixed length since we are manually adding
  675. // those ourselves.
  676. //
  677. bytesRequired = sizeOfFixedStructure;
  678. }
  679. switch ( SmbGetUshort( &parameters->Level ) ) {
  680. case 3:
  681. bytesRequired += NetpUnicodeToDBCSLen( DEF16_sv_autopath ) + 1;
  682. case 2:
  683. bytesRequired += ( NetpUnicodeToDBCSLen( DEF16_sv_alerts )
  684. + NetpUnicodeToDBCSLen( DEF16_sv_srvheuristics )
  685. + NetpUnicodeToDBCSLen( nativeStruct->sv102_comment )
  686. + NetpUnicodeToDBCSLen( nativeStruct->sv102_userpath )
  687. + 4 );
  688. }
  689. //
  690. // We don't have room even for the fixed data, abort.
  691. //
  692. if ( bufferTooSmall ) {
  693. Header->Status = NERR_BufTooSmall;
  694. goto cleanup;
  695. }
  696. //
  697. // For levels 2 and 3, fill in the default values in the fixed structure
  698. // manually.
  699. //
  700. returnStruct = (PSERVER_16_INFO_3)XsSmbGetPointer( &parameters->Buffer );
  701. switch ( SmbGetUshort( &parameters->Level ) ) {
  702. case 3:
  703. SmbPutUlong( &returnStruct->sv3_auditedevents, DEF16_sv_auditedevents );
  704. SmbPutUshort( &returnStruct->sv3_autoprofile, DEF16_sv_autoprofile );
  705. case 2:
  706. SmbPutUlong( &returnStruct->sv3_ulist_mtime, DEF16_sv_ulist_mtime );
  707. SmbPutUlong( &returnStruct->sv3_alist_mtime, DEF16_sv_alist_mtime );
  708. SmbPutUlong( &returnStruct->sv3_glist_mtime, DEF16_sv_glist_mtime );
  709. SmbPutUshort( &returnStruct->sv3_security, DEF16_sv_security );
  710. SmbPutUshort( &returnStruct->sv3_auditing, DEF16_sv_auditing );
  711. SmbPutUshort( &returnStruct->sv3_numadmin, (USHORT)DEF16_sv_numadmin );
  712. SmbPutUshort( &returnStruct->sv3_lanmask, DEF16_sv_lanmask );
  713. NetpCopyTStrToStr( returnStruct->sv3_guestacct, DEF16_sv_guestacct );
  714. SmbPutUshort( &returnStruct->sv3_chdevs, DEF16_sv_chdevs );
  715. SmbPutUshort( &returnStruct->sv3_chdevq, DEF16_sv_chdevq );
  716. SmbPutUshort( &returnStruct->sv3_chdevjobs, DEF16_sv_chdevjobs );
  717. SmbPutUshort( &returnStruct->sv3_connections, DEF16_sv_connections );
  718. SmbPutUshort( &returnStruct->sv3_shares, DEF16_sv_shares );
  719. SmbPutUshort( &returnStruct->sv3_openfiles, DEF16_sv_openfiles );
  720. SmbPutUshort( &returnStruct->sv3_sessopens,
  721. (WORD)secondaryNativeStruct->sv502_sessopens );
  722. SmbPutUshort( &returnStruct->sv3_sessvcs,
  723. (WORD)secondaryNativeStruct->sv502_sessvcs );
  724. SmbPutUshort( &returnStruct->sv3_sessreqs, DEF16_sv_sessreqs );
  725. SmbPutUshort( &returnStruct->sv3_opensearch,
  726. (WORD)secondaryNativeStruct->sv502_opensearch );
  727. SmbPutUshort( &returnStruct->sv3_activelocks, DEF16_sv_activelocks );
  728. SmbPutUshort( &returnStruct->sv3_numreqbuf, DEF16_sv_numreqbuf );
  729. SmbPutUshort( &returnStruct->sv3_sizreqbuf,
  730. (WORD)secondaryNativeStruct->sv502_sizreqbuf );
  731. SmbPutUshort( &returnStruct->sv3_numbigbuf, DEF16_sv_numbigbuf );
  732. SmbPutUshort( &returnStruct->sv3_numfiletasks, DEF16_sv_numfiletasks );
  733. SmbPutUshort( &returnStruct->sv3_alertsched, DEF16_sv_alertsched );
  734. SmbPutUshort( &returnStruct->sv3_erroralert, DEF16_sv_erroralert );
  735. SmbPutUshort( &returnStruct->sv3_logonalert, DEF16_sv_logonalert );
  736. SmbPutUshort( &returnStruct->sv3_accessalert, DEF16_sv_accessalert );
  737. SmbPutUshort( &returnStruct->sv3_diskalert, DEF16_sv_diskalert );
  738. SmbPutUshort( &returnStruct->sv3_netioalert, DEF16_sv_netioalert );
  739. SmbPutUshort( &returnStruct->sv3_maxauditsz, DEF16_sv_maxauditsz );
  740. }
  741. //
  742. // Now check if there is room for the variable data. If there isn't,
  743. // set return status and quit. This is done here to prevent code
  744. // below from overwriting the buffer.
  745. //
  746. if ( bytesRequired > (DWORD)SmbGetUshort( &parameters-> BufLen )) {
  747. IF_DEBUG(ERRORS) {
  748. NetpKdPrint(( "NetServerGetInfo: More data available.\n" ));
  749. }
  750. Header->Status = ERROR_MORE_DATA;
  751. goto cleanup;
  752. }
  753. //
  754. // For levels 2 and 3, fill in the variable data manually. The variable
  755. // data is filled in immediately following the fixed structures. For
  756. // other levels, pack the response data as normal.
  757. stringLocation = (LPBYTE)( XsSmbGetPointer( &parameters->Buffer )
  758. + sizeOfFixedStructure );
  759. switch ( SmbGetUshort( &parameters->Level )) {
  760. case 3:
  761. XsAddVarString(
  762. stringLocation,
  763. DEF16_sv_autopath,
  764. &returnStruct->sv3_autopath,
  765. returnStruct
  766. );
  767. case 2:
  768. XsAddVarString(
  769. stringLocation,
  770. DEF16_sv_srvheuristics,
  771. &returnStruct->sv3_srvheuristics,
  772. returnStruct
  773. );
  774. XsAddVarString(
  775. stringLocation,
  776. nativeStruct->sv102_userpath,
  777. &returnStruct->sv3_userpath,
  778. returnStruct
  779. );
  780. XsAddVarString(
  781. stringLocation,
  782. DEF16_sv_alerts,
  783. &returnStruct->sv3_alerts,
  784. returnStruct
  785. );
  786. XsAddVarString(
  787. stringLocation,
  788. nativeStruct->sv102_comment,
  789. &returnStruct->sv3_comment,
  790. returnStruct
  791. );
  792. break;
  793. default:
  794. //
  795. // Pack the response data.
  796. //
  797. Header->Converter = XsPackReturnData(
  798. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  799. SmbGetUshort( &parameters->BufLen ),
  800. StructureDesc,
  801. 1
  802. );
  803. break;
  804. }
  805. cleanup:
  806. ;
  807. } except( EXCEPTION_EXECUTE_HANDLER ) {
  808. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  809. }
  810. if( ServerName != NULL ) {
  811. NetpMemoryFree( ServerName );
  812. }
  813. //
  814. // Set up the response parameters.
  815. //
  816. SmbPutUshort( &parameters->TotalAvail, (WORD)bytesRequired );
  817. NetApiBufferFree( nativeStruct );
  818. NetApiBufferFree( secondaryNativeStruct );
  819. //
  820. // Determine return buffer size.
  821. //
  822. XsSetDataCount(
  823. &parameters->BufLen,
  824. StructureDesc,
  825. Header->Converter,
  826. 1,
  827. Header->Status
  828. );
  829. return STATUS_SUCCESS;
  830. } // XsNetServerGetInfo
  831. NTSTATUS
  832. XsNetServerSetInfo (
  833. API_HANDLER_PARAMETERS
  834. )
  835. /*++
  836. Routine Description:
  837. This routine handles a call to NetServerSetInfo.
  838. Arguments:
  839. API_HANDLER_PARAMETERS - information about the API call. See
  840. XsTypes.h for details.
  841. Return Value:
  842. NTSTATUS - STATUS_SUCCESS or reason for failure.
  843. --*/
  844. {
  845. NET_API_STATUS status;
  846. PXS_NET_SERVER_SET_INFO parameters = Parameters;
  847. LPVOID buffer = NULL; // Native parameters
  848. LPBYTE stringLocation = NULL; // Conversion variables
  849. DWORD bytesRequired = 0;
  850. LPDESC nativeStructureDesc;
  851. DWORD data;
  852. DWORD bufferSize;
  853. DWORD level;
  854. LPTSTR comment = NULL;
  855. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  856. try {
  857. //
  858. // Check for errors.
  859. //
  860. if ( XsWordParamOutOfRange( parameters->Level, 1, 3 )) {
  861. Header->Status = ERROR_INVALID_LEVEL;
  862. goto cleanup;
  863. }
  864. //
  865. // Processing of this API depends on the value of the ParmNum
  866. // parameter.
  867. //
  868. switch ( SmbGetUshort( &parameters->ParmNum )) {
  869. case PARMNUM_ALL:
  870. //
  871. // PARMNUM_ALL.
  872. //
  873. // The structure descriptor given is OK; determine native descriptor
  874. // (and expected minimum buffer length) from level. The buffer then
  875. // needs to be converted into a native 32-bit buffer.
  876. //
  877. switch( SmbGetUshort( &parameters->Level )) {
  878. case 1:
  879. StructureDesc = Desc16_server_info_1;
  880. nativeStructureDesc = Desc32_server_info_1;
  881. break;
  882. case 2:
  883. StructureDesc = Desc16_server_info_2;
  884. nativeStructureDesc = Desc32_server_info_2;
  885. break;
  886. case 3:
  887. StructureDesc = Desc16_server_info_3;
  888. nativeStructureDesc = Desc32_server_info_3;
  889. break;
  890. }
  891. if ( !XsCheckBufferSize(
  892. SmbGetUshort( &parameters->BufLen ),
  893. StructureDesc,
  894. FALSE // native format
  895. )) {
  896. Header->Status = NERR_BufTooSmall;
  897. goto cleanup;
  898. }
  899. //
  900. // Find out how big a 32-bit data buffer we need.
  901. //
  902. bufferSize = XsBytesForConvertedStructure(
  903. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  904. StructureDesc,
  905. nativeStructureDesc,
  906. RapToNative,
  907. TRUE
  908. );
  909. //
  910. // Allocate enough memory to hold the converted native buffer.
  911. //
  912. buffer = NetpMemoryAllocate( bufferSize );
  913. if ( buffer == NULL ) {
  914. IF_DEBUG(ERRORS) {
  915. NetpKdPrint(( "XsNetServerSetInfo: failed to create buffer" ));
  916. }
  917. Header->Status = NERR_NoRoom;
  918. goto cleanup;
  919. }
  920. IF_DEBUG(SERVER) {
  921. NetpKdPrint(( "XsNetServerSetInfo: buffer of %ld bytes at %lx\n",
  922. bufferSize, buffer ));
  923. }
  924. //
  925. // Convert 16-bit data into 32-bit data and store it in the native
  926. // buffer.
  927. //
  928. stringLocation = (LPBYTE)buffer + bufferSize;
  929. bytesRequired = 0;
  930. status = RapConvertSingleEntry(
  931. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  932. StructureDesc,
  933. TRUE,
  934. buffer,
  935. buffer,
  936. nativeStructureDesc,
  937. FALSE,
  938. &stringLocation,
  939. &bytesRequired,
  940. Response,
  941. RapToNative
  942. );
  943. if ( status != NERR_Success ) {
  944. IF_DEBUG(ERRORS) {
  945. NetpKdPrint(( "XsNetServerSetInfo: RapConvertSingleEntry "
  946. "failed: %X\n", status ));
  947. }
  948. Header->Status = NERR_InternalError;
  949. goto cleanup;
  950. }
  951. break;
  952. case SV_COMMENT_PARMNUM:
  953. //
  954. // SV_COMMENT_PARMNUM.
  955. //
  956. // The structure descriptor given is meaningless. The data is actually
  957. // a null terminated string, and can be passed to the native routine
  958. // immediately. Being a string, it must be at least one character long.
  959. //
  960. if ( !XsCheckBufferSize(
  961. SmbGetUshort( &parameters->BufLen ),
  962. "B",
  963. FALSE // not in native format
  964. )) {
  965. Header->Status= NERR_BufTooSmall;
  966. goto cleanup;
  967. }
  968. XsConvertUnicodeTextParameter(
  969. comment,
  970. (LPSTR)XsSmbGetPointer( &parameters->Buffer )
  971. );
  972. if ( comment == NULL ) {
  973. IF_DEBUG(ERRORS) {
  974. NetpKdPrint(( "XsNetServerSetInfo: failed to create buffer" ));
  975. }
  976. Header->Status = NERR_NoRoom;
  977. goto cleanup;
  978. }
  979. buffer = &comment;
  980. break;
  981. case SV_ALERTS_PARMNUM:
  982. case SV_ALERTSCHED_PARMNUM:
  983. case SV_ERRORALERT_PARMNUM:
  984. case SV_LOGONALERT_PARMNUM:
  985. goto cleanup;
  986. case SV_ACCESSALERT_PARMNUM:
  987. case SV_DISKALERT_PARMNUM:
  988. case SV_NETIOALERT_PARMNUM:
  989. case SV_MAXAUDITSZ_PARMNUM:
  990. //
  991. // SV_ALERTS_PARMNUM, SV_ALERTSCHED_PARMNUM, SV_ERRORALERT_PARMNUM,
  992. // SV_LOGONALERT_PARMNUM, SV_ACCESSALERT_PARMNUM, SV_DISKALERT_PARMNUM,
  993. // SV_NETIOALERT_PARMNUM, or SV_MAXAUDITSZ_PARMNUM.
  994. //
  995. // These parameters are not supported in NT, so just return an OK.
  996. //
  997. goto cleanup;
  998. case SV_DISC_PARMNUM:
  999. case SV_HIDDEN_PARMNUM:
  1000. case SV_ANNOUNCE_PARMNUM:
  1001. case SV_ANNDELTA_PARMNUM:
  1002. //
  1003. // SV_DISC_PARMNUM, SV_HIDDEN_PARMNUM, SV_ANNOUNCE_PARMNUM, or
  1004. // SV_ANNDELTA_PARMNUM.
  1005. //
  1006. // The structure descriptor given is meaningless; the data is a word
  1007. // to be converted into a 32-bit DWORD. The length of data must be 2.
  1008. //
  1009. if ( !XsCheckBufferSize(
  1010. SmbGetUshort( &parameters->BufLen ),
  1011. "W",
  1012. FALSE // not in native format
  1013. )) {
  1014. Header->Status= NERR_BufTooSmall;
  1015. goto cleanup;
  1016. }
  1017. data = (DWORD)SmbGetUshort(
  1018. (LPWORD)XsSmbGetPointer( &parameters->Buffer )
  1019. );
  1020. buffer = &data;
  1021. break;
  1022. default:
  1023. Header->Status = ERROR_INVALID_PARAMETER;
  1024. goto cleanup;
  1025. }
  1026. //
  1027. // Do the actual local call.
  1028. //
  1029. level = SmbGetUshort( &parameters->ParmNum );
  1030. if ( level != 0 ) {
  1031. level = level + PARMNUM_BASE_INFOLEVEL;
  1032. } else {
  1033. level = 100 + SmbGetUshort( &parameters->Level );
  1034. if ( level == 103 ) {
  1035. level = 102;
  1036. }
  1037. }
  1038. status = NetServerSetInfo(
  1039. NULL,
  1040. level,
  1041. buffer,
  1042. NULL
  1043. );
  1044. if ( !XsApiSuccess( status )) {
  1045. IF_DEBUG(ERRORS) {
  1046. NetpKdPrint(( "XsNetServerSetInfo: NetServerSetInfo failed: %X\n",
  1047. status ));
  1048. }
  1049. Header->Status = (WORD)status;
  1050. goto cleanup;
  1051. }
  1052. //
  1053. // No return information for this API.
  1054. //
  1055. cleanup:
  1056. ;
  1057. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1058. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  1059. }
  1060. //
  1061. // If there is a native 32-bit buffer, free it.
  1062. //
  1063. if ( SmbGetUshort( &parameters->ParmNum ) == PARMNUM_ALL ) {
  1064. NetpMemoryFree( buffer );
  1065. } else if ( SmbGetUshort( &parameters->ParmNum ) == SV_COMMENT_PARMNUM ) {
  1066. NetpMemoryFree( comment );
  1067. }
  1068. return STATUS_SUCCESS;
  1069. } // XsNetServerSetInfo