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.

3141 lines
83 KiB

  1. /*++
  2. Copyright (c) 1991-1992 Microsoft Corporation
  3. Module Name:
  4. ApiPrint.c
  5. Abstract:
  6. This module contains individual API handlers for the DosPrint APIs.
  7. SUPPORTED : DosPrintDestAdd, DosPrintDestControl, DosPrintDestDel,
  8. DosPrintDestEnum, DosPrintDestGetInfo, DosPrintDestSetInfo,
  9. DosPrintJobContinue, DosPrintJobDel, DosPrintJobEnum,
  10. DosPrintJobGetId, DosPrintJobGetInfo, DosPrintJobPause,
  11. DosPrintJobSetInfo, DosPrintQAdd, DosPrintQContinue,
  12. DosPrintQDel, DosPrintQEnum, DosPrintQGetInfo,
  13. DosPrintQPause, DosPrintQPurge, DosPrintQSetInfo.
  14. Author:
  15. Shanku Niyogi (w-shanku) 04-Apr-1991
  16. Revision History:
  17. 18-Jun-1992 JohnRo
  18. RAID 10324: net print vs. UNICODE.
  19. Use FORMAT_ equates.
  20. 01-Oct-1992 JohnRo
  21. RAID 3556: DosPrintQGetInfo(from downlevel) level 3, rc=124. (4&5 too.)
  22. --*/
  23. #include "XactSrvP.h"
  24. #include <dosprint.h>
  25. //
  26. // Declaration of descriptor strings.
  27. //
  28. STATIC const LPDESC Desc16_print_dest_0 = REM16_print_dest_0;
  29. STATIC const LPDESC Desc32_print_dest_0 = REM32_print_dest_0;
  30. STATIC const LPDESC Desc16_print_dest_1 = REM16_print_dest_1;
  31. STATIC const LPDESC Desc32_print_dest_1 = REM32_print_dest_1;
  32. STATIC const LPDESC Desc16_print_dest_2 = REM16_print_dest_2;
  33. STATIC const LPDESC Desc32_print_dest_2 = REM32_print_dest_2;
  34. STATIC const LPDESC Desc16_print_dest_3 = REM16_print_dest_3;
  35. STATIC const LPDESC Desc32_print_dest_3 = REM32_print_dest_3;
  36. STATIC const LPDESC Desc16_print_dest_3_setinfo = REM16_print_dest_3_setinfo;
  37. STATIC const LPDESC Desc32_print_dest_3_setinfo = REM32_print_dest_3_setinfo;
  38. STATIC const LPDESC Desc16_print_job_0 = REM16_print_job_0;
  39. STATIC const LPDESC Desc32_print_job_0 = REM32_print_job_0;
  40. STATIC const LPDESC Desc16_print_job_1 = REM16_print_job_1;
  41. STATIC const LPDESC Desc32_print_job_1 = REM32_print_job_1;
  42. STATIC const LPDESC Desc16_print_job_1_setinfo = REM16_print_job_1_setinfo;
  43. STATIC const LPDESC Desc32_print_job_1_setinfo = REM32_print_job_1_setinfo;
  44. STATIC const LPDESC Desc16_print_job_2 = REM16_print_job_2;
  45. STATIC const LPDESC Desc32_print_job_2 = REM32_print_job_2;
  46. STATIC const LPDESC Desc16_print_job_3 = REM16_print_job_3;
  47. STATIC const LPDESC Desc32_print_job_3 = REM32_print_job_3;
  48. STATIC const LPDESC Desc16_print_job_3_setinfo = REM16_print_job_3_setinfo;
  49. STATIC const LPDESC Desc32_print_job_3_setinfo = REM32_print_job_3_setinfo;
  50. STATIC const LPDESC Desc16_printQ_0 = REM16_printQ_0;
  51. STATIC const LPDESC Desc32_printQ_0 = REM32_printQ_0;
  52. STATIC const LPDESC Desc16_printQ_1 = REM16_printQ_1;
  53. STATIC const LPDESC Desc32_printQ_1 = REM32_printQ_1;
  54. STATIC const LPDESC Desc16_printQ_1_setinfo = REM16_printQ_1_setinfo;
  55. STATIC const LPDESC Desc32_printQ_1_setinfo = REM32_printQ_1_setinfo;
  56. STATIC const LPDESC Desc16_printQ_2 = REM16_printQ_2;
  57. STATIC const LPDESC Desc32_printQ_2 = REM32_printQ_2;
  58. STATIC const LPDESC Desc16_printQ_3 = REM16_printQ_3;
  59. STATIC const LPDESC Desc32_printQ_3 = REM32_printQ_3;
  60. STATIC const LPDESC Desc16_printQ_3_setinfo = REM16_printQ_3_setinfo;
  61. STATIC const LPDESC Desc32_printQ_3_setinfo = REM32_printQ_3_setinfo;
  62. STATIC const LPDESC Desc16_printQ_4 = REM16_printQ_4;
  63. STATIC const LPDESC Desc32_printQ_4 = REM32_printQ_4;
  64. STATIC const LPDESC Desc16_printQ_5 = REM16_printQ_5;
  65. STATIC const LPDESC Desc32_printQ_5 = REM32_printQ_5;
  66. STATIC const LPDESC Desc16_printQ_52 = REM16_printQ_52;
  67. STATIC const LPDESC Desc32_printQ_52 = REM32_printQ_52;
  68. //
  69. // DosPrint calls behave differently from Net api calls. On Net api calls,
  70. // the called routine supplies the buffer to us. DosPrint apis need a
  71. // supplied buffer and thus can return NERR_BufferTooSmall which means
  72. // it's an error but return the bytes needed if it's a XXGetInfo call.
  73. //
  74. #define XsPrintApiSuccess( Status ) \
  75. (( (Status) == NERR_Success ) || ( (Status) == ERROR_MORE_DATA ))
  76. //
  77. // Now that servers can have multiple names (See SrvNetTransportAdd, and clusters),
  78. // it is necessary to transmit the server name part of a queue name to the spooler.
  79. // The following three macros aid in the translation.
  80. //
  81. #define PREPARE_CONVERT_QUEUE_NAME() \
  82. WCHAR queueNameBuf[ MAX_PATH ]; \
  83. CHAR localComputerName[ NETBIOS_NAME_LEN ]; \
  84. DWORD localComputerNameLen = sizeof( localComputerName ); \
  85. PUCHAR p = &Header->ServerName[ NETBIOS_NAME_LEN-2 ]; \
  86. for( ; p > Header->ServerName && *p == ' '; p-- ); \
  87. p++; \
  88. GetComputerNameA( localComputerName, &localComputerNameLen );
  89. #define CONVERT_QUEUE_NAME( queue ) \
  90. if( queue && ((DWORD)(p-Header->ServerName) != localComputerNameLen || \
  91. memcmp( localComputerName, Header->ServerName, localComputerNameLen )) &&\
  92. mbstowcs( NULL, Header->ServerName, (size_t)(p-Header->ServerName )) <= \
  93. sizeof( queueNameBuf ) - wcslen(queue)*sizeof(WCHAR) - 4*sizeof(WCHAR)){\
  94. \
  95. RtlZeroMemory( queueNameBuf, sizeof( queueNameBuf ) ); \
  96. queueNameBuf[0] = queueNameBuf[1] = L'\\'; \
  97. mbstowcs( queueNameBuf+2, Header->ServerName, \
  98. (size_t)(p-Header->ServerName) ); \
  99. wcscat( queueNameBuf, L"\\" ); \
  100. wcscat( queueNameBuf, queue ); \
  101. NetApiBufferFree( queue ); \
  102. queue = queueNameBuf; \
  103. }
  104. #define FREE_QUEUE_NAME( queue ) if( queue != queueNameBuf ) NetApiBufferFree( queue )
  105. #define GET_LOCAL_SERVER_NAME() \
  106. WCHAR LocalServerName[ MAX_PATH ]; \
  107. PUCHAR p = &Header->ServerName[ NETBIOS_NAME_LEN-2 ]; \
  108. for( ; p > Header->ServerName && *p == ' '; p-- ); \
  109. p++; \
  110. LocalServerName[0] = LocalServerName[1] = L'\\'; \
  111. mbstowcs( LocalServerName+2, Header->ServerName, \
  112. (size_t)(p-Header->ServerName) ); \
  113. LocalServerName[2+p-Header->ServerName] = L'\0';
  114. NTSTATUS
  115. XsNetPrintDestAdd (
  116. API_HANDLER_PARAMETERS
  117. )
  118. /*++
  119. Routine Description:
  120. This routine handles a call to DosPrintDestAdd.
  121. Arguments:
  122. API_HANDLER_PARAMETERS - information about the API call. See
  123. XsTypes.h for details.
  124. Return Value:
  125. NTSTATUS - STATUS_SUCCESS or reason for failure.
  126. --*/
  127. {
  128. SPLERR status;
  129. PXS_DOS_PRINT_DEST_ADD parameters = Parameters;
  130. LPVOID buffer = NULL; // Native parameters
  131. LPBYTE stringLocation = NULL; // Conversion variables
  132. DWORD bytesRequired = 0;
  133. DWORD bufferSize;
  134. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  135. IF_DEBUG(PRINT) {
  136. NetpKdPrint(( "XsNetPrintDestAdd: header at " FORMAT_LPVOID
  137. ", params at " FORMAT_LPVOID ", "
  138. "level " FORMAT_DWORD "\n",
  139. Header,
  140. parameters,
  141. SmbGetUshort( &parameters->Level ) ));
  142. }
  143. try {
  144. //
  145. // Check for errors.
  146. //
  147. if ( SmbGetUshort( &parameters->Level ) != 3 ) {
  148. Header->Status = ERROR_INVALID_LEVEL;
  149. goto cleanup;
  150. }
  151. StructureDesc = Desc16_print_dest_3;
  152. //
  153. // Figure out if there is enough room in the buffer for all the
  154. // data required. If not, return NERR_BufTooSmall.
  155. //
  156. if ( !XsCheckBufferSize(
  157. SmbGetUshort( &parameters->BufLen ),
  158. StructureDesc,
  159. FALSE // not in native format
  160. )) {
  161. IF_DEBUG(ERRORS) {
  162. NetpKdPrint(( "XsNetPrintDestAdd: Buffer too small.\n" ));
  163. }
  164. Header->Status = NERR_BufTooSmall;
  165. goto cleanup;
  166. }
  167. //
  168. // Find out how big a buffer we need to allocate to hold the native
  169. // 32-bit version of the input data structure.
  170. //
  171. bufferSize = XsBytesForConvertedStructure(
  172. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  173. StructureDesc,
  174. Desc32_print_dest_3,
  175. RapToNative,
  176. TRUE
  177. );
  178. //
  179. // Allocate enough memory to hold the converted native buffer.
  180. //
  181. buffer = NetpMemoryAllocate( bufferSize );
  182. if ( buffer == NULL ) {
  183. IF_DEBUG(ERRORS) {
  184. NetpKdPrint(( "XsNetPrintDestAdd: failed to create buffer" ));
  185. }
  186. Header->Status = NERR_NoRoom;
  187. goto cleanup;
  188. }
  189. IF_DEBUG(PRINT) {
  190. NetpKdPrint(( "XsNetPrintDestAdd: buffer of " FORMAT_DWORD " bytes at " FORMAT_LPVOID "\n",
  191. bufferSize, buffer ));
  192. }
  193. //
  194. // Convert the buffer from 16-bit to 32-bit.
  195. //
  196. stringLocation = (LPBYTE)buffer + bufferSize;
  197. bytesRequired = 0;
  198. status = RapConvertSingleEntry(
  199. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  200. StructureDesc,
  201. TRUE,
  202. buffer,
  203. buffer,
  204. Desc32_print_dest_3,
  205. FALSE,
  206. &stringLocation,
  207. &bytesRequired,
  208. Response,
  209. RapToNative
  210. );
  211. if ( status != NERR_Success ) {
  212. IF_DEBUG(ERRORS) {
  213. NetpKdPrint(( "XsNetPrintDestAdd: RapConvertSingleEntry failed: "
  214. FORMAT_API_STATUS "\n", status ));
  215. }
  216. Header->Status = NERR_InternalError;
  217. goto cleanup;
  218. }
  219. //
  220. // Make the local call.
  221. //
  222. status = DosPrintDestAdd(
  223. NULL,
  224. SmbGetUshort( &parameters->Level ),
  225. buffer,
  226. (WORD)bufferSize
  227. );
  228. if ( !XsPrintApiSuccess( status )) {
  229. IF_DEBUG(ERRORS) {
  230. NetpKdPrint(( "XsNetPrintDestAdd: DosPrintDestAdd failed: "
  231. FORMAT_API_STATUS "\n",
  232. status ));
  233. }
  234. Header->Status = (WORD)status;
  235. goto cleanup;
  236. }
  237. //
  238. // There is no real return information for this API.
  239. //
  240. cleanup:
  241. ;
  242. } except( EXCEPTION_EXECUTE_HANDLER ) {
  243. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  244. }
  245. NetpMemoryFree( buffer );
  246. return STATUS_SUCCESS;
  247. } // XsNetPrintDestAdd
  248. NTSTATUS
  249. XsNetPrintDestControl (
  250. API_HANDLER_PARAMETERS
  251. )
  252. /*++
  253. Routine Description:
  254. This routine handles a call to DosPrintDestControl.
  255. Arguments:
  256. API_HANDLER_PARAMETERS - information about the API call. See
  257. XsTypes.h for details.
  258. Return Value:
  259. NTSTATUS - STATUS_SUCCESS or reason for failure.
  260. --*/
  261. {
  262. SPLERR status;
  263. PXS_DOS_PRINT_DEST_CONTROL parameters = Parameters;
  264. LPTSTR nativeDestName = NULL; // Native parameters
  265. PREPARE_CONVERT_QUEUE_NAME();
  266. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  267. IF_DEBUG(PRINT) {
  268. NetpKdPrint(( "XsNetPrintDestControl: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  269. "name " FORMAT_LPSTR "\n",
  270. Header, parameters,
  271. SmbGetUlong( &parameters->DestName )));
  272. }
  273. try {
  274. //
  275. // Translate parameters, check for errors.
  276. //
  277. XsConvertTextParameter(
  278. nativeDestName,
  279. (LPSTR)XsSmbGetPointer( &parameters->DestName )
  280. );
  281. CONVERT_QUEUE_NAME( nativeDestName );
  282. //
  283. // Make the local call.
  284. //
  285. status = DosPrintDestControl(
  286. NULL,
  287. nativeDestName,
  288. SmbGetUshort( &parameters->Control )
  289. );
  290. cleanup:
  291. ;
  292. } except( EXCEPTION_EXECUTE_HANDLER ) {
  293. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  294. }
  295. if ( !XsPrintApiSuccess( status )) {
  296. IF_DEBUG(ERRORS) {
  297. NetpKdPrint(( "XsNetPrintDestControl: DosPrintDestControl failed: "
  298. FORMAT_API_STATUS "\n", status ));
  299. }
  300. }
  301. //
  302. // Nothing to return.
  303. //
  304. Header->Status = (WORD)status;
  305. FREE_QUEUE_NAME( nativeDestName );
  306. return STATUS_SUCCESS;
  307. } // XsNetPrintDestControl
  308. NTSTATUS
  309. XsNetPrintDestDel (
  310. API_HANDLER_PARAMETERS
  311. )
  312. /*++
  313. Routine Description:
  314. This routine handles a call to DosPrintDestDel.
  315. Arguments:
  316. API_HANDLER_PARAMETERS - information about the API call. See
  317. XsTypes.h for details.
  318. Return Value:
  319. NTSTATUS - STATUS_SUCCESS or reason for failure.
  320. --*/
  321. {
  322. SPLERR status;
  323. PXS_DOS_PRINT_DEST_DEL parameters = Parameters;
  324. LPTSTR nativePrinterName = NULL; // Native parameters
  325. PREPARE_CONVERT_QUEUE_NAME();
  326. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  327. IF_DEBUG(PRINT) {
  328. NetpKdPrint(( "XsNetPrintDestDel: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  329. "name " FORMAT_LPSTR "\n",
  330. Header, parameters,
  331. SmbGetUlong( &parameters->PrinterName )));
  332. }
  333. try {
  334. //
  335. // Translate parameters, check for errors.
  336. //
  337. XsConvertTextParameter(
  338. nativePrinterName,
  339. (LPSTR)XsSmbGetPointer( &parameters->PrinterName )
  340. );
  341. CONVERT_QUEUE_NAME( nativePrinterName );
  342. //
  343. // Make the local call.
  344. //
  345. status = DosPrintDestDel(
  346. NULL,
  347. nativePrinterName
  348. );
  349. cleanup:
  350. ;
  351. } except( EXCEPTION_EXECUTE_HANDLER ) {
  352. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  353. }
  354. if ( !XsPrintApiSuccess( status )) {
  355. IF_DEBUG(ERRORS) {
  356. NetpKdPrint(( "XsNetPrintDestDel: DosPrintDestDel failed: "
  357. FORMAT_API_STATUS "\n",
  358. status ));
  359. }
  360. }
  361. //
  362. // Nothing to return.
  363. //
  364. Header->Status = (WORD)status;
  365. FREE_QUEUE_NAME( nativePrinterName );
  366. return STATUS_SUCCESS;
  367. } // XsNetPrintDestDel
  368. NTSTATUS
  369. XsNetPrintDestEnum (
  370. API_HANDLER_PARAMETERS
  371. )
  372. /*++
  373. Routine Description:
  374. This routine handles a call to DosPrintDestEnum.
  375. Arguments:
  376. API_HANDLER_PARAMETERS - information about the API call. See
  377. XsTypes.h for details.
  378. Return Value:
  379. NTSTATUS - STATUS_SUCCESS or reason for failure.
  380. --*/
  381. {
  382. SPLERR status;
  383. PXS_DOS_PRINT_DEST_ENUM parameters = Parameters;
  384. LPVOID outBuffer= NULL; // Native parameters
  385. DWORD outBufferSize;
  386. DWORD entriesRead = 0;
  387. DWORD totalEntries = 0;
  388. DWORD entriesFilled = 0; // Conversion variables
  389. DWORD bytesRequired = 0;
  390. LPDESC nativeStructureDesc;
  391. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  392. IF_DEBUG(PRINT) {
  393. NetpKdPrint(( "XsNetPrintDestEnum: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  394. "level " FORMAT_DWORD ", buf size " FORMAT_DWORD "\n",
  395. Header, parameters, SmbGetUshort( &parameters->Level ),
  396. SmbGetUshort( &parameters->BufLen )));
  397. }
  398. try {
  399. //
  400. // Check for errors.
  401. //
  402. if ( XsWordParamOutOfRange( parameters->Level, 0, 3 )) {
  403. Header->Status = ERROR_INVALID_LEVEL;
  404. goto cleanup;
  405. }
  406. //
  407. // !!! Print API mapping layer presently requires a preallocated buffer.
  408. //
  409. outBufferSize = XsNativeBufferSize( SmbGetUshort( &parameters->BufLen ));
  410. if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
  411. || outBuffer == NULL ) {
  412. IF_DEBUG(ERRORS) {
  413. NetpKdPrint(( "XsNetPrintDestEnum: cannot allocate memory\n" ));
  414. }
  415. Header->Status = NERR_NoRoom;
  416. goto cleanup;
  417. }
  418. //
  419. // Make the local call.
  420. //
  421. status = DosPrintDestEnum(
  422. NULL,
  423. SmbGetUshort( &parameters->Level ),
  424. (LPBYTE)outBuffer,
  425. (WORD)outBufferSize,
  426. (LPWORD)&entriesRead,
  427. (LPWORD)&totalEntries
  428. );
  429. if ( !XsPrintApiSuccess( status )) {
  430. IF_DEBUG(API_ERRORS) {
  431. NetpKdPrint(( "XsNetPrintDestEnum: DosPrintDestEnum failed: "
  432. FORMAT_API_STATUS "\n", status ));
  433. }
  434. Header->Status = (WORD)status;
  435. goto cleanup;
  436. }
  437. IF_DEBUG(PRINT) {
  438. NetpKdPrint(( "XsNetPrintDestEnum: received " FORMAT_DWORD " entries at " FORMAT_LPVOID "\n",
  439. entriesRead, outBuffer ));
  440. }
  441. //
  442. // Use the requested level to determine the format of the
  443. // data structure.
  444. //
  445. switch ( SmbGetUshort( &parameters->Level ) ) {
  446. case 0:
  447. nativeStructureDesc = Desc32_print_dest_0;
  448. StructureDesc = Desc16_print_dest_0;
  449. break;
  450. case 1:
  451. nativeStructureDesc = Desc32_print_dest_1;
  452. StructureDesc = Desc16_print_dest_1;
  453. break;
  454. case 2:
  455. nativeStructureDesc = Desc32_print_dest_2;
  456. StructureDesc = Desc16_print_dest_2;
  457. break;
  458. case 3:
  459. nativeStructureDesc = Desc32_print_dest_3;
  460. StructureDesc = Desc16_print_dest_3;
  461. break;
  462. }
  463. //
  464. // Do the actual conversion from the 32-bit structures to 16-bit
  465. // structures.
  466. //
  467. XsFillEnumBuffer(
  468. outBuffer,
  469. entriesRead,
  470. nativeStructureDesc,
  471. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  472. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  473. SmbGetUshort( &parameters->BufLen ),
  474. StructureDesc,
  475. NULL, // verify function
  476. &bytesRequired,
  477. &entriesFilled,
  478. NULL
  479. );
  480. IF_DEBUG(PRINT) {
  481. NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR,"
  482. " Entries " FORMAT_DWORD " of " FORMAT_DWORD "\n",
  483. outBuffer, SmbGetUlong( &parameters->Buffer ),
  484. bytesRequired, entriesFilled, totalEntries ));
  485. }
  486. //
  487. // If all the entries could not be filled, return ERROR_MORE_DATA,
  488. // and return the buffer as is. Otherwise, the data needs to be
  489. // packed so that we don't send too much useless data.
  490. //
  491. if ( entriesFilled < totalEntries ) {
  492. Header->Status = ERROR_MORE_DATA;
  493. } else {
  494. Header->Converter = XsPackReturnData(
  495. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  496. SmbGetUshort( &parameters->BufLen ),
  497. StructureDesc,
  498. entriesFilled
  499. );
  500. }
  501. //
  502. // Set up the response parameters.
  503. //
  504. SmbPutUshort( &parameters->Returned, (WORD)entriesFilled );
  505. SmbPutUshort( &parameters->Total, (WORD)totalEntries );
  506. cleanup:
  507. ;
  508. } except( EXCEPTION_EXECUTE_HANDLER ) {
  509. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  510. }
  511. NetApiBufferFree( outBuffer );
  512. //
  513. // Determine return buffer size.
  514. //
  515. XsSetDataCount(
  516. &parameters->BufLen,
  517. StructureDesc,
  518. Header->Converter,
  519. entriesFilled,
  520. Header->Status
  521. );
  522. return STATUS_SUCCESS;
  523. } // XsNetPrintDestEnum
  524. NTSTATUS
  525. XsNetPrintDestGetInfo (
  526. API_HANDLER_PARAMETERS
  527. )
  528. /*++
  529. Routine Description:
  530. This routine handles a call to DosPrintDestGetInfo.
  531. Arguments:
  532. API_HANDLER_PARAMETERS - information about the API call. See
  533. XsTypes.h for details.
  534. Return Value:
  535. NTSTATUS - STATUS_SUCCESS or reason for failure.
  536. --*/
  537. {
  538. SPLERR status;
  539. PXS_DOS_PRINT_DEST_GET_INFO parameters = Parameters;
  540. LPTSTR nativeName = NULL; // Native parameters
  541. LPVOID outBuffer = NULL;
  542. DWORD outBufferSize;
  543. WORD bytesNeeded = 0;
  544. LPBYTE stringLocation = NULL; // Conversion variables
  545. DWORD bytesRequired = 0;
  546. LPDESC nativeStructureDesc;
  547. PREPARE_CONVERT_QUEUE_NAME();
  548. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  549. IF_DEBUG(PRINT) {
  550. NetpKdPrint(( "XsNetPrintDestGetInfo: header at " FORMAT_LPVOID ", "
  551. "params at " FORMAT_LPVOID ", level " FORMAT_DWORD "\n",
  552. Header, parameters, SmbGetUshort( &parameters->Level ) ));
  553. }
  554. try {
  555. //
  556. // Translate parameters, check for errors.
  557. //
  558. if ( XsWordParamOutOfRange( parameters->Level, 0, 3 )) {
  559. Header->Status = ERROR_INVALID_LEVEL;
  560. goto cleanup;
  561. }
  562. XsConvertTextParameter(
  563. nativeName,
  564. (LPSTR)XsSmbGetPointer( &parameters->Name )
  565. );
  566. CONVERT_QUEUE_NAME( nativeName );
  567. //
  568. // !!! Print API mapping layer presently requires a preallocated buffer.
  569. //
  570. outBufferSize = XsNativeBufferSize( SmbGetUshort( &parameters->BufLen ));
  571. if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
  572. || outBuffer == NULL ) {
  573. IF_DEBUG(ERRORS) {
  574. NetpKdPrint(( "XsNetPrintDestGetInfo: cannot allocate memory\n" ));
  575. }
  576. Header->Status = NERR_NoRoom;
  577. goto cleanup;
  578. }
  579. //
  580. // Make the local call.
  581. //
  582. status = DosPrintDestGetInfo(
  583. NULL,
  584. nativeName,
  585. SmbGetUshort( &parameters->Level ),
  586. (LPBYTE)outBuffer,
  587. (WORD)outBufferSize,
  588. &bytesNeeded
  589. );
  590. if ( !XsPrintApiSuccess( status )) {
  591. IF_DEBUG(API_ERRORS) {
  592. NetpKdPrint(( "XsNetPrintDestGetInfo: DosPrintDestGetInfo failed: "
  593. FORMAT_API_STATUS "\n", status ));
  594. }
  595. Header->Status = (WORD)status;
  596. goto cleanup;
  597. }
  598. //
  599. // Use the requested level to determine the format of the
  600. // data structure.
  601. //
  602. switch ( SmbGetUshort( &parameters->Level ) ) {
  603. case 0:
  604. nativeStructureDesc = Desc32_print_dest_0;
  605. StructureDesc = Desc16_print_dest_0;
  606. break;
  607. case 1:
  608. nativeStructureDesc = Desc32_print_dest_1;
  609. StructureDesc = Desc16_print_dest_1;
  610. break;
  611. case 2:
  612. nativeStructureDesc = Desc32_print_dest_2;
  613. StructureDesc = Desc16_print_dest_2;
  614. break;
  615. case 3:
  616. nativeStructureDesc = Desc32_print_dest_3;
  617. StructureDesc = Desc16_print_dest_3;
  618. break;
  619. }
  620. //
  621. // Convert the structure returned by the 32-bit call to a 16-bit
  622. // structure. The last possible location for variable data is
  623. // calculated from buffer location and length.
  624. //
  625. stringLocation = (LPBYTE)( XsSmbGetPointer( &parameters->Buffer )
  626. + SmbGetUshort( &parameters->BufLen ) );
  627. status = RapConvertSingleEntry(
  628. outBuffer,
  629. nativeStructureDesc,
  630. FALSE,
  631. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  632. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  633. StructureDesc,
  634. TRUE,
  635. &stringLocation,
  636. &bytesRequired,
  637. Response,
  638. NativeToRap
  639. );
  640. if ( status != NERR_Success ) {
  641. IF_DEBUG(ERRORS) {
  642. NetpKdPrint(( "XsDosPrintDestGetInfo: RapConvertSingleEntry failed: "
  643. FORMAT_API_STATUS "\n", status ));
  644. }
  645. Header->Status = NERR_InternalError;
  646. goto cleanup;
  647. }
  648. IF_DEBUG(PRINT) {
  649. NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR\n",
  650. outBuffer, SmbGetUlong( &parameters->Buffer ),
  651. bytesRequired ));
  652. }
  653. //
  654. // Determine return code based on the size of the buffer.
  655. //
  656. if ( !XsCheckBufferSize(
  657. SmbGetUshort( &parameters->BufLen ),
  658. StructureDesc,
  659. FALSE // not in native format
  660. )) {
  661. IF_DEBUG(ERRORS) {
  662. NetpKdPrint(( "XsNetPrintDestGetInfo: Buffer too small.\n" ));
  663. }
  664. Header->Status = NERR_BufTooSmall;
  665. } else if ( bytesRequired > (DWORD)SmbGetUshort( &parameters-> BufLen )) {
  666. IF_DEBUG(ERRORS) {
  667. NetpKdPrint(( "XsNetPrintDestGetInfo: More data available.\n" ));
  668. }
  669. Header->Status = ERROR_MORE_DATA;
  670. } else {
  671. //
  672. // Pack the response data.
  673. //
  674. Header->Converter = XsPackReturnData(
  675. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  676. SmbGetUshort( &parameters->BufLen ),
  677. StructureDesc,
  678. 1
  679. );
  680. }
  681. bytesNeeded = (WORD)bytesRequired;
  682. cleanup:
  683. ;
  684. } except( EXCEPTION_EXECUTE_HANDLER ) {
  685. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  686. }
  687. //
  688. // Set up the response parameters.
  689. //
  690. SmbPutUshort( &parameters->Needed, bytesNeeded );
  691. NetApiBufferFree( outBuffer );
  692. FREE_QUEUE_NAME( nativeName );
  693. //
  694. // Determine return buffer size.
  695. //
  696. XsSetDataCount(
  697. &parameters->BufLen,
  698. StructureDesc,
  699. Header->Converter,
  700. 1,
  701. Header->Status
  702. );
  703. return STATUS_SUCCESS;
  704. } // XsNetPrintDestGetInfo
  705. NTSTATUS
  706. XsNetPrintDestSetInfo (
  707. API_HANDLER_PARAMETERS
  708. )
  709. /*++
  710. Routine Description:
  711. This routine handles a call to DosPrintDestSetInfo.
  712. Arguments:
  713. API_HANDLER_PARAMETERS - information about the API call. See
  714. XsTypes.h for details.
  715. Return Value:
  716. NTSTATUS - STATUS_SUCCESS or reason for failure.
  717. --*/
  718. {
  719. SPLERR status;
  720. PXS_DOS_PRINT_DEST_SET_INFO parameters = Parameters;
  721. LPTSTR nativeName = NULL; // Native parameters
  722. LPVOID buffer = NULL;
  723. DWORD bytesRequired;
  724. PREPARE_CONVERT_QUEUE_NAME();
  725. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  726. try {
  727. //
  728. // Translate parameters, check for errors.
  729. //
  730. if ( SmbGetUshort( &parameters->Level ) != 3 ) {
  731. Header->Status = ERROR_INVALID_LEVEL;
  732. goto cleanup;
  733. }
  734. StructureDesc = Desc16_print_dest_3;
  735. XsConvertTextParameter(
  736. nativeName,
  737. (LPSTR)XsSmbGetPointer( &parameters->Name )
  738. );
  739. status = XsConvertSetInfoBuffer(
  740. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  741. SmbGetUshort( &parameters->BufLen ),
  742. SmbGetUshort( &parameters->ParmNum ),
  743. FALSE,
  744. TRUE,
  745. StructureDesc,
  746. Desc32_print_dest_3,
  747. Desc16_print_dest_3_setinfo,
  748. Desc32_print_dest_3_setinfo,
  749. (LPBYTE *)&buffer,
  750. &bytesRequired
  751. );
  752. if ( status != NERR_Success ) {
  753. IF_DEBUG(ERRORS) {
  754. NetpKdPrint(( "XsNetPrintDestSetInfo: Problem with conversion: "
  755. FORMAT_API_STATUS "\n", status ));
  756. }
  757. Header->Status = (WORD)status;
  758. goto cleanup;
  759. }
  760. CONVERT_QUEUE_NAME( nativeName );
  761. //
  762. // Do the actual local call.
  763. //
  764. status = DosPrintDestSetInfo(
  765. NULL,
  766. nativeName,
  767. SmbGetUshort( &parameters->Level ),
  768. (LPBYTE)buffer,
  769. (WORD)bytesRequired,
  770. SmbGetUshort( &parameters->ParmNum )
  771. );
  772. if ( !XsPrintApiSuccess( status )) {
  773. IF_DEBUG(ERRORS) {
  774. NetpKdPrint(( "XsNetPrintDestSetInfo: DosPrintDestSetInfo failed: "
  775. FORMAT_API_STATUS "\n", status ));
  776. }
  777. Header->Status = (WORD)status;
  778. goto cleanup;
  779. }
  780. //
  781. // No return information for this API.
  782. //
  783. cleanup:
  784. ;
  785. } except( EXCEPTION_EXECUTE_HANDLER ) {
  786. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  787. }
  788. //
  789. // If there is a native 32-bit buffer, free it.
  790. //
  791. NetpMemoryFree( buffer );
  792. FREE_QUEUE_NAME( nativeName );
  793. return STATUS_SUCCESS;
  794. } // XsNetPrintDestSetInfo
  795. NTSTATUS
  796. XsNetPrintJobContinue (
  797. API_HANDLER_PARAMETERS
  798. )
  799. /*++
  800. Routine Description:
  801. This routine handles a call to DosPrintJobContinue.
  802. Arguments:
  803. API_HANDLER_PARAMETERS - information about the API call. See
  804. XsTypes.h for details.
  805. Return Value:
  806. NTSTATUS - STATUS_SUCCESS or reason for failure.
  807. --*/
  808. {
  809. SPLERR status;
  810. PXS_DOS_PRINT_JOB_CONTINUE parameters = Parameters;
  811. GET_LOCAL_SERVER_NAME();
  812. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  813. IF_DEBUG(PRINT) {
  814. NetpKdPrint(( "XsNetPrintJobContinue: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  815. "job " FORMAT_WORD_ONLY "\n",
  816. Header, parameters, SmbGetUshort( &parameters->JobId )));
  817. }
  818. try {
  819. //
  820. // Make the local call.
  821. //
  822. status = DosPrintJobContinue(
  823. LocalServerName,
  824. FALSE,
  825. SmbGetUshort( &parameters->JobId )
  826. );
  827. if ( !XsPrintApiSuccess( status )) {
  828. IF_DEBUG(ERRORS) {
  829. NetpKdPrint(( "XsNetPrintJobContinue: DosPrintJobContinue failed: "
  830. FORMAT_API_STATUS "\n", status ));
  831. }
  832. }
  833. } except( EXCEPTION_EXECUTE_HANDLER ) {
  834. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  835. }
  836. //
  837. // Nothing to return.
  838. //
  839. Header->Status = (WORD)status;
  840. return STATUS_SUCCESS;
  841. } // XsNetPrintJobContinue
  842. NTSTATUS
  843. XsNetPrintJobDel (
  844. API_HANDLER_PARAMETERS
  845. )
  846. /*++
  847. Routine Description:
  848. This routine handles a call to DosPrintJobDel.
  849. Arguments:
  850. API_HANDLER_PARAMETERS - information about the API call. See
  851. XsTypes.h for details.
  852. Return Value:
  853. NTSTATUS - STATUS_SUCCESS or reason for failure.
  854. --*/
  855. {
  856. SPLERR status;
  857. PXS_DOS_PRINT_JOB_DEL parameters = Parameters;
  858. GET_LOCAL_SERVER_NAME();
  859. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  860. IF_DEBUG(PRINT) {
  861. NetpKdPrint(( "XsNetPrintJobDel: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  862. "job " FORMAT_WORD_ONLY "\n",
  863. Header, parameters, SmbGetUshort( &parameters->JobId )));
  864. }
  865. try {
  866. //
  867. // Make the local call.
  868. //
  869. status = DosPrintJobDel(
  870. LocalServerName,
  871. FALSE,
  872. SmbGetUshort( &parameters->JobId )
  873. );
  874. if ( !XsPrintApiSuccess( status )) {
  875. IF_DEBUG(ERRORS) {
  876. NetpKdPrint(( "XsNetPrintJobDel: DosPrintJobDel failed: "
  877. FORMAT_API_STATUS "\n",
  878. status ));
  879. }
  880. }
  881. } except( EXCEPTION_EXECUTE_HANDLER ) {
  882. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  883. }
  884. //
  885. // Nothing to return.
  886. //
  887. Header->Status = (WORD)status;
  888. return STATUS_SUCCESS;
  889. } // XsNetPrintJobDel
  890. NTSTATUS
  891. XsNetPrintJobEnum (
  892. API_HANDLER_PARAMETERS
  893. )
  894. /*++
  895. Routine Description:
  896. This routine handles a call to DosPrintJobEnum.
  897. Arguments:
  898. API_HANDLER_PARAMETERS - information about the API call. See
  899. XsTypes.h for details.
  900. Return Value:
  901. NTSTATUS - STATUS_SUCCESS or reason for failure.
  902. --*/
  903. {
  904. SPLERR status;
  905. PXS_DOS_PRINT_JOB_ENUM parameters = Parameters;
  906. LPTSTR nativeQueueName = NULL; // Native parameters
  907. LPVOID outBuffer= NULL;
  908. DWORD outBufferSize;
  909. DWORD entriesRead = 0;
  910. DWORD totalEntries = 0;
  911. DWORD entriesFilled = 0; // Conversion variables
  912. DWORD bytesRequired = 0;
  913. LPDESC nativeStructureDesc;
  914. WORD bufferLength;
  915. PREPARE_CONVERT_QUEUE_NAME();
  916. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  917. IF_DEBUG(PRINT) {
  918. NetpKdPrint(( "XsNetPrintJobEnum: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  919. "level " FORMAT_DWORD ", buf size " FORMAT_DWORD "\n",
  920. Header, parameters, SmbGetUshort( &parameters->Level ),
  921. SmbGetUshort( &parameters->BufLen )));
  922. }
  923. try {
  924. //
  925. // Translate parameters, check for errors.
  926. //
  927. if ( XsWordParamOutOfRange( parameters->Level, 0, 2 )) {
  928. Header->Status = ERROR_INVALID_LEVEL;
  929. goto cleanup;
  930. }
  931. XsConvertTextParameter(
  932. nativeQueueName,
  933. (LPSTR)XsSmbGetPointer( &parameters->QueueName )
  934. );
  935. bufferLength = SmbGetUshort( &parameters->BufLen );
  936. CONVERT_QUEUE_NAME( nativeQueueName );
  937. //
  938. // !!! Print API mapping layer presently requires a preallocated buffer.
  939. //
  940. outBufferSize = XsNativeBufferSize( bufferLength );
  941. if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
  942. || outBuffer == NULL ) {
  943. IF_DEBUG(ERRORS) {
  944. NetpKdPrint(( "XsNetPrintJobEnum: cannot allocate memory\n" ));
  945. }
  946. Header->Status = NERR_NoRoom;
  947. goto cleanup;
  948. }
  949. //
  950. // Make the local call.
  951. //
  952. status = DosPrintJobEnum(
  953. NULL,
  954. nativeQueueName,
  955. SmbGetUshort( &parameters->Level ),
  956. (LPBYTE)outBuffer,
  957. (WORD)outBufferSize,
  958. (LPWORD)&entriesRead,
  959. (LPWORD)&totalEntries
  960. );
  961. if ( !XsPrintApiSuccess( status )) {
  962. IF_DEBUG(API_ERRORS) {
  963. NetpKdPrint(( "XsNetPrintJobEnum: DosPrintJobEnum failed: "
  964. FORMAT_API_STATUS "\n", status ));
  965. }
  966. Header->Status = (WORD)status;
  967. goto cleanup;
  968. }
  969. IF_DEBUG(PRINT) {
  970. NetpKdPrint(( "XsNetPrintJobEnum: received " FORMAT_DWORD " entries at " FORMAT_LPVOID "\n",
  971. entriesRead, outBuffer ));
  972. }
  973. //
  974. // Use the requested level to determine the format of the
  975. // data structure.
  976. //
  977. switch ( SmbGetUshort( &parameters->Level ) ) {
  978. case 0:
  979. nativeStructureDesc = Desc32_print_job_0;
  980. StructureDesc = Desc16_print_job_0;
  981. break;
  982. case 1:
  983. nativeStructureDesc = Desc32_print_job_1;
  984. StructureDesc = Desc16_print_job_1;
  985. break;
  986. case 2:
  987. nativeStructureDesc = Desc32_print_job_2;
  988. StructureDesc = Desc16_print_job_2;
  989. break;
  990. }
  991. //
  992. // Do the actual conversion from the 32-bit structures to 16-bit
  993. // structures.
  994. //
  995. XsFillEnumBuffer(
  996. outBuffer,
  997. entriesRead,
  998. nativeStructureDesc,
  999. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  1000. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  1001. (DWORD)bufferLength,
  1002. StructureDesc,
  1003. NULL, // verify function
  1004. &bytesRequired,
  1005. &entriesFilled,
  1006. NULL
  1007. );
  1008. IF_DEBUG(PRINT) {
  1009. NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR,"
  1010. " Entries " FORMAT_DWORD " of " FORMAT_DWORD "\n",
  1011. outBuffer, SmbGetUlong( &parameters->Buffer ),
  1012. bytesRequired, entriesFilled, totalEntries ));
  1013. }
  1014. //
  1015. // If all the entries could not be filled, return ERROR_MORE_DATA,
  1016. // and return the buffer as is. Otherwise, the data needs to be
  1017. // packed so that we don't send too much useless data.
  1018. //
  1019. if ( (entriesFilled < totalEntries) ||
  1020. (bytesRequired > bufferLength) ) {
  1021. Header->Status = ERROR_MORE_DATA;
  1022. } else {
  1023. Header->Converter = XsPackReturnData(
  1024. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  1025. bufferLength,
  1026. StructureDesc,
  1027. entriesFilled
  1028. );
  1029. }
  1030. //
  1031. // Set up the response parameters.
  1032. //
  1033. SmbPutUshort( &parameters->Returned, (WORD)entriesFilled );
  1034. SmbPutUshort( &parameters->Total, (WORD)totalEntries );
  1035. cleanup:
  1036. ;
  1037. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1038. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  1039. }
  1040. NetApiBufferFree( outBuffer );
  1041. FREE_QUEUE_NAME( nativeQueueName );
  1042. //
  1043. // Determine return buffer size.
  1044. //
  1045. XsSetDataCount(
  1046. &parameters->BufLen,
  1047. StructureDesc,
  1048. Header->Converter,
  1049. entriesFilled,
  1050. Header->Status
  1051. );
  1052. return STATUS_SUCCESS;
  1053. } // XsNetPrintJobEnum
  1054. NTSTATUS
  1055. XsNetPrintJobGetInfo (
  1056. API_HANDLER_PARAMETERS
  1057. )
  1058. /*++
  1059. Routine Description:
  1060. This routine handles a call to DosPrintJobGetInfo.
  1061. Arguments:
  1062. API_HANDLER_PARAMETERS - information about the API call. See
  1063. XsTypes.h for details.
  1064. Return Value:
  1065. NTSTATUS - STATUS_SUCCESS or reason for failure.
  1066. --*/
  1067. {
  1068. SPLERR status;
  1069. PXS_DOS_PRINT_JOB_GET_INFO parameters = Parameters;
  1070. LPVOID outBuffer = NULL; // Native parameters
  1071. DWORD outBufferSize;
  1072. WORD bytesNeeded = 0;
  1073. LPBYTE stringLocation = NULL; // Conversion variables
  1074. DWORD bytesRequired = 0;
  1075. LPDESC nativeStructureDesc;
  1076. GET_LOCAL_SERVER_NAME();
  1077. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  1078. IF_DEBUG(PRINT) {
  1079. NetpKdPrint(( "XsNetPrintJobGetInfo: header at " FORMAT_LPVOID ", "
  1080. "params at " FORMAT_LPVOID ", level " FORMAT_DWORD "\n",
  1081. Header, parameters, SmbGetUshort( &parameters->Level ) ));
  1082. }
  1083. try {
  1084. //
  1085. // Check for errors.
  1086. //
  1087. if ( XsWordParamOutOfRange( parameters->Level, 0, 3 )) {
  1088. Header->Status = ERROR_INVALID_LEVEL;
  1089. goto cleanup;
  1090. }
  1091. //
  1092. // !!! Print API mapping layer presently requires a preallocated buffer.
  1093. //
  1094. outBufferSize = XsNativeBufferSize( SmbGetUshort( &parameters->BufLen ));
  1095. if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
  1096. || outBuffer == NULL ) {
  1097. IF_DEBUG(ERRORS) {
  1098. NetpKdPrint(( "XsNetPrintJobGetInfo: cannot allocate memory\n" ));
  1099. }
  1100. Header->Status = NERR_NoRoom;
  1101. goto cleanup;
  1102. }
  1103. //
  1104. // Make the local call.
  1105. //
  1106. status = DosPrintJobGetInfo(
  1107. LocalServerName,
  1108. FALSE,
  1109. SmbGetUshort( &parameters->JobId ),
  1110. SmbGetUshort( &parameters->Level ),
  1111. (LPBYTE)outBuffer,
  1112. (WORD)outBufferSize,
  1113. &bytesNeeded
  1114. );
  1115. if ( !XsPrintApiSuccess( status )) {
  1116. IF_DEBUG(API_ERRORS) {
  1117. NetpKdPrint(( "XsNetPrintJobGetInfo: DosPrintJobGetInfo failed: "
  1118. FORMAT_API_STATUS "\n", status ));
  1119. }
  1120. Header->Status = (WORD)status;
  1121. goto cleanup;
  1122. }
  1123. //
  1124. // Use the requested level to determine the format of the
  1125. // data structure.
  1126. //
  1127. switch ( SmbGetUshort( &parameters->Level ) ) {
  1128. case 0:
  1129. nativeStructureDesc = Desc32_print_job_0;
  1130. StructureDesc = Desc16_print_job_0;
  1131. break;
  1132. case 1:
  1133. nativeStructureDesc = Desc32_print_job_1;
  1134. StructureDesc = Desc16_print_job_1;
  1135. break;
  1136. case 2:
  1137. nativeStructureDesc = Desc32_print_job_2;
  1138. StructureDesc = Desc16_print_job_2;
  1139. break;
  1140. case 3:
  1141. nativeStructureDesc = Desc32_print_job_3;
  1142. StructureDesc = Desc16_print_job_3;
  1143. break;
  1144. }
  1145. //
  1146. // Convert the structure returned by the 32-bit call to a 16-bit
  1147. // structure. The last possible location for variable data is
  1148. // calculated from buffer location and length.
  1149. //
  1150. stringLocation = (LPBYTE)( XsSmbGetPointer( &parameters->Buffer )
  1151. + SmbGetUshort( &parameters->BufLen ) );
  1152. status = RapConvertSingleEntry(
  1153. outBuffer,
  1154. nativeStructureDesc,
  1155. FALSE,
  1156. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  1157. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  1158. StructureDesc,
  1159. TRUE,
  1160. &stringLocation,
  1161. &bytesRequired,
  1162. Response,
  1163. NativeToRap
  1164. );
  1165. if ( status != NERR_Success ) {
  1166. IF_DEBUG(ERRORS) {
  1167. NetpKdPrint(( "XsDosPrintJobGetInfo: RapConvertSingleEntry failed: "
  1168. FORMAT_API_STATUS "\n", status ));
  1169. }
  1170. Header->Status = NERR_InternalError;
  1171. goto cleanup;
  1172. }
  1173. IF_DEBUG(PRINT) {
  1174. NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR\n",
  1175. outBuffer, SmbGetUlong( &parameters->Buffer ),
  1176. bytesRequired ));
  1177. }
  1178. //
  1179. // Determine return code based on the size of the buffer.
  1180. //
  1181. if ( !XsCheckBufferSize(
  1182. SmbGetUshort( &parameters->BufLen ),
  1183. StructureDesc,
  1184. FALSE // not in native format
  1185. )) {
  1186. IF_DEBUG(ERRORS) {
  1187. NetpKdPrint(( "XsNetPrintJobGetInfo: Buffer too small.\n" ));
  1188. }
  1189. Header->Status = NERR_BufTooSmall;
  1190. } else if ( bytesRequired > (DWORD)SmbGetUshort( &parameters-> BufLen )) {
  1191. IF_DEBUG(ERRORS) {
  1192. NetpKdPrint(( "XsNetPrintJobGetInfo: More data available.\n" ));
  1193. }
  1194. Header->Status = ERROR_MORE_DATA;
  1195. } else {
  1196. //
  1197. // Pack the response data.
  1198. //
  1199. Header->Converter = XsPackReturnData(
  1200. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  1201. SmbGetUshort( &parameters->BufLen ),
  1202. StructureDesc,
  1203. 1
  1204. );
  1205. }
  1206. bytesNeeded = (WORD)bytesRequired;
  1207. cleanup:
  1208. ;
  1209. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1210. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  1211. }
  1212. //
  1213. // Set up the response parameters.
  1214. //
  1215. SmbPutUshort( &parameters->Needed, bytesNeeded );
  1216. NetApiBufferFree( outBuffer );
  1217. //
  1218. // Determine return buffer size.
  1219. //
  1220. XsSetDataCount(
  1221. &parameters->BufLen,
  1222. StructureDesc,
  1223. Header->Converter,
  1224. 1,
  1225. Header->Status
  1226. );
  1227. return STATUS_SUCCESS;
  1228. } // XsNetPrintJobGetInfo
  1229. NTSTATUS
  1230. XsNetPrintJobPause (
  1231. API_HANDLER_PARAMETERS
  1232. )
  1233. /*++
  1234. Routine Description:
  1235. This routine handles a call to DosPrintJobPause.
  1236. Arguments:
  1237. API_HANDLER_PARAMETERS - information about the API call. See
  1238. XsTypes.h for details.
  1239. Return Value:
  1240. NTSTATUS - STATUS_SUCCESS or reason for failure.
  1241. --*/
  1242. {
  1243. SPLERR status;
  1244. PXS_DOS_PRINT_JOB_PAUSE parameters = Parameters;
  1245. GET_LOCAL_SERVER_NAME();
  1246. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  1247. IF_DEBUG(PRINT) {
  1248. NetpKdPrint(( "XsNetPrintJobPause: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  1249. "job " FORMAT_WORD_ONLY "\n",
  1250. Header, parameters, SmbGetUshort( &parameters->JobId )));
  1251. }
  1252. try {
  1253. //
  1254. // Make the local call.
  1255. //
  1256. status = DosPrintJobPause(
  1257. LocalServerName,
  1258. FALSE,
  1259. SmbGetUshort( &parameters->JobId )
  1260. );
  1261. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1262. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  1263. }
  1264. if ( !XsPrintApiSuccess( status )) {
  1265. IF_DEBUG(ERRORS) {
  1266. NetpKdPrint(( "XsNetPrintJobPause: DosPrintJobPause failed: "
  1267. FORMAT_API_STATUS "\n",
  1268. status ));
  1269. }
  1270. }
  1271. //
  1272. // Nothing to return.
  1273. //
  1274. Header->Status = (WORD)status;
  1275. return STATUS_SUCCESS;
  1276. } // XsNetPrintJobPause
  1277. NTSTATUS
  1278. XsNetPrintJobSetInfo (
  1279. API_HANDLER_PARAMETERS
  1280. )
  1281. /*++
  1282. Routine Description:
  1283. This routine handles a call to DosPrintJobSetInfo.
  1284. Arguments:
  1285. API_HANDLER_PARAMETERS - information about the API call. See
  1286. XsTypes.h for details.
  1287. Return Value:
  1288. NTSTATUS - STATUS_SUCCESS or reason for failure.
  1289. --*/
  1290. {
  1291. SPLERR status;
  1292. PXS_DOS_PRINT_JOB_SET_INFO parameters = Parameters;
  1293. LPVOID buffer = NULL; // Native parameters
  1294. DWORD bytesRequired;
  1295. WORD level;
  1296. DWORD fieldIndex;
  1297. LPDESC setInfoDesc; // Conversion variables
  1298. LPDESC nativeSetInfoDesc;
  1299. LPDESC nativeStructureDesc;
  1300. GET_LOCAL_SERVER_NAME();
  1301. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  1302. try {
  1303. //
  1304. // Check for errors.
  1305. //
  1306. level = SmbGetUshort( &parameters->Level );
  1307. if ( level != 1 && level != 3 ) {
  1308. Header->Status = ERROR_INVALID_LEVEL;
  1309. goto cleanup;
  1310. }
  1311. //
  1312. // Determine descriptor strings based on level. Also translate the
  1313. // parmnum value to a field index.
  1314. // !!! - Right now, we don't check for parameters settable in downlevel
  1315. // that are meaningless in the NT mapping layer. Fix this,
  1316. // if necessary, in the descriptor string file (with
  1317. // REM_IGNORE fields).
  1318. //
  1319. fieldIndex = (DWORD)SmbGetUshort( &parameters->ParmNum );
  1320. switch ( level ) {
  1321. case 1:
  1322. StructureDesc = Desc16_print_job_1;
  1323. nativeStructureDesc = Desc32_print_job_1;
  1324. setInfoDesc = Desc16_print_job_1_setinfo;
  1325. nativeSetInfoDesc = Desc32_print_job_1_setinfo;
  1326. if ( fieldIndex > 2 ) { // Account for pad field
  1327. fieldIndex++;
  1328. }
  1329. break;
  1330. case 3:
  1331. StructureDesc = Desc16_print_job_3;
  1332. nativeStructureDesc = Desc32_print_job_3;
  1333. setInfoDesc = Desc16_print_job_3_setinfo;
  1334. nativeSetInfoDesc = Desc32_print_job_3_setinfo;
  1335. if ( fieldIndex != PARMNUM_ALL && fieldIndex < 15 ) {
  1336. switch ( fieldIndex ) {
  1337. case PRJ_NOTIFYNAME_PARMNUM:
  1338. case PRJ_DATATYPE_PARMNUM:
  1339. case PRJ_PARMS_PARMNUM:
  1340. fieldIndex += 7; break;
  1341. case PRJ_POSITION_PARMNUM:
  1342. fieldIndex = 4; break;
  1343. case PRJ_COMMENT_PARMNUM:
  1344. case PRJ_DOCUMENT_PARMNUM:
  1345. fieldIndex -= 3; break;
  1346. case PRJ_PRIORITY_PARMNUM:
  1347. fieldIndex = 2; break;
  1348. default:
  1349. fieldIndex = 0xFFFFFFFF; // Some invalid field
  1350. }
  1351. }
  1352. break;
  1353. }
  1354. status = XsConvertSetInfoBuffer(
  1355. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  1356. SmbGetUshort( &parameters->BufLen ),
  1357. (WORD)fieldIndex,
  1358. FALSE,
  1359. TRUE,
  1360. StructureDesc,
  1361. nativeStructureDesc,
  1362. setInfoDesc,
  1363. nativeSetInfoDesc,
  1364. (LPBYTE *)&buffer,
  1365. &bytesRequired
  1366. );
  1367. if ( status != NERR_Success ) {
  1368. IF_DEBUG(ERRORS) {
  1369. NetpKdPrint(( "XsNetPrintJobSetInfo: Problem with conversion: "
  1370. FORMAT_API_STATUS "\n", status ));
  1371. }
  1372. Header->Status = (WORD)status;
  1373. goto cleanup;
  1374. }
  1375. //
  1376. // Do the actual local call.
  1377. //
  1378. status = DosPrintJobSetInfo(
  1379. LocalServerName,
  1380. FALSE,
  1381. SmbGetUshort( &parameters->JobId ),
  1382. level,
  1383. (LPBYTE)buffer,
  1384. (WORD)bytesRequired,
  1385. SmbGetUshort( &parameters->ParmNum )
  1386. );
  1387. if ( !XsPrintApiSuccess( status )) {
  1388. IF_DEBUG(ERRORS) {
  1389. NetpKdPrint(( "XsNetPrintJobSetInfo: DosPrintJobSetInfo failed: "
  1390. FORMAT_API_STATUS "\n", status ));
  1391. }
  1392. Header->Status = (WORD)status;
  1393. goto cleanup;
  1394. }
  1395. //
  1396. // No return information for this API.
  1397. //
  1398. cleanup:
  1399. ;
  1400. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1401. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  1402. }
  1403. //
  1404. // If there is a native 32-bit buffer, free it.
  1405. //
  1406. NetpMemoryFree( buffer );
  1407. return STATUS_SUCCESS;
  1408. } // XsNetPrintJobSetInfo
  1409. NTSTATUS
  1410. XsNetPrintQAdd (
  1411. API_HANDLER_PARAMETERS
  1412. )
  1413. /*++
  1414. Routine Description:
  1415. This routine handles a call to DosPrintQAdd.
  1416. Arguments:
  1417. API_HANDLER_PARAMETERS - information about the API call. See
  1418. XsTypes.h for details.
  1419. Return Value:
  1420. NTSTATUS - STATUS_SUCCESS or reason for failure.
  1421. --*/
  1422. {
  1423. SPLERR status;
  1424. PXS_DOS_PRINT_Q_ADD parameters = Parameters;
  1425. LPVOID buffer = NULL; // Native parameters
  1426. LPBYTE stringLocation = NULL; // Conversion variables
  1427. DWORD bytesRequired = 0;
  1428. LPTSTR nativeStructureDesc;
  1429. DWORD bufferSize;
  1430. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  1431. IF_DEBUG(PRINT) {
  1432. NetpKdPrint(( "XsNetPrintQAdd: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  1433. "level " FORMAT_DWORD "\n",
  1434. Header,
  1435. parameters,
  1436. SmbGetUshort( &parameters->Level ) ));
  1437. }
  1438. try {
  1439. //
  1440. // Determine native structure descriptor based on level.
  1441. //
  1442. switch ( SmbGetUshort( &parameters->Level )) {
  1443. case 1:
  1444. StructureDesc = Desc16_printQ_1;
  1445. nativeStructureDesc = (LPTSTR)Desc32_printQ_1;
  1446. break;
  1447. case 3:
  1448. StructureDesc = Desc16_printQ_3;
  1449. nativeStructureDesc = (LPTSTR)Desc32_printQ_3;
  1450. break;
  1451. default:
  1452. Header->Status = ERROR_INVALID_LEVEL;
  1453. goto cleanup;
  1454. }
  1455. //
  1456. // Figure out if there is enough room in the buffer for all the
  1457. // data required. If not, return NERR_BufTooSmall.
  1458. //
  1459. if ( !XsCheckBufferSize(
  1460. SmbGetUshort( &parameters->BufLen ),
  1461. StructureDesc,
  1462. FALSE // not in native format
  1463. )) {
  1464. IF_DEBUG(ERRORS) {
  1465. NetpKdPrint(( "XsNetPrintQAdd: Buffer too small.\n" ));
  1466. }
  1467. Header->Status = NERR_BufTooSmall;
  1468. goto cleanup;
  1469. }
  1470. //
  1471. // Find out how big a buffer we need to allocate to hold the native
  1472. // 32-bit version of the input data structure.
  1473. //
  1474. bufferSize = XsBytesForConvertedStructure(
  1475. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  1476. StructureDesc,
  1477. (LPDESC)nativeStructureDesc,
  1478. RapToNative,
  1479. TRUE
  1480. );
  1481. //
  1482. // Allocate enough memory to hold the converted native buffer.
  1483. //
  1484. buffer = NetpMemoryAllocate( bufferSize );
  1485. if ( buffer == NULL ) {
  1486. IF_DEBUG(ERRORS) {
  1487. NetpKdPrint(( "XsNetPrintQAdd: failed to create buffer" ));
  1488. }
  1489. Header->Status = NERR_NoRoom;
  1490. goto cleanup;
  1491. }
  1492. IF_DEBUG(PRINT) {
  1493. NetpKdPrint(( "XsNetPrintQAdd: buffer of " FORMAT_DWORD " bytes at " FORMAT_LPVOID "\n",
  1494. bufferSize, buffer ));
  1495. }
  1496. //
  1497. // Convert the buffer from 16-bit to 32-bit.
  1498. //
  1499. stringLocation = (LPBYTE)buffer + bufferSize;
  1500. bytesRequired = 0;
  1501. status = RapConvertSingleEntry(
  1502. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  1503. StructureDesc,
  1504. TRUE,
  1505. buffer,
  1506. buffer,
  1507. (LPDESC)nativeStructureDesc,
  1508. FALSE,
  1509. &stringLocation,
  1510. &bytesRequired,
  1511. Response,
  1512. RapToNative
  1513. );
  1514. if ( status != NERR_Success ) {
  1515. IF_DEBUG(ERRORS) {
  1516. NetpKdPrint(( "XsNetPrintQAdd: RapConvertSingleEntry failed: "
  1517. FORMAT_API_STATUS "\n", status ));
  1518. }
  1519. Header->Status = NERR_InternalError;
  1520. goto cleanup;
  1521. }
  1522. //
  1523. // Make the local call.
  1524. //
  1525. status = DosPrintQAdd(
  1526. NULL,
  1527. SmbGetUshort( &parameters->Level ),
  1528. buffer,
  1529. (WORD)bufferSize
  1530. );
  1531. if ( !XsPrintApiSuccess( status )) {
  1532. IF_DEBUG(ERRORS) {
  1533. NetpKdPrint(( "XsNetPrintQAdd: DosPrintQAdd failed: "
  1534. FORMAT_API_STATUS "\n",
  1535. status ));
  1536. }
  1537. Header->Status = (WORD)status;
  1538. goto cleanup;
  1539. }
  1540. //
  1541. // There is no real return information for this API.
  1542. //
  1543. cleanup:
  1544. ;
  1545. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1546. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  1547. }
  1548. NetpMemoryFree( buffer );
  1549. return STATUS_SUCCESS;
  1550. } // XsNetPrintQAdd
  1551. NTSTATUS
  1552. XsNetPrintQContinue (
  1553. API_HANDLER_PARAMETERS
  1554. )
  1555. /*++
  1556. Routine Description:
  1557. This routine handles a call to DosPrintQContinue.
  1558. Arguments:
  1559. API_HANDLER_PARAMETERS - information about the API call. See
  1560. XsTypes.h for details.
  1561. Return Value:
  1562. NTSTATUS - STATUS_SUCCESS or reason for failure.
  1563. --*/
  1564. {
  1565. SPLERR status;
  1566. PXS_DOS_PRINT_Q_CONTINUE parameters = Parameters;
  1567. LPTSTR nativeQueueName = NULL; // Native parameters
  1568. PREPARE_CONVERT_QUEUE_NAME();
  1569. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  1570. IF_DEBUG(PRINT) {
  1571. NetpKdPrint(( "XsNetPrintQContinue: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  1572. "name " FORMAT_LPSTR "\n",
  1573. Header, parameters,
  1574. SmbGetUlong( &parameters->QueueName )));
  1575. }
  1576. try {
  1577. //
  1578. // Translate parameters, check for errors.
  1579. //
  1580. XsConvertTextParameter(
  1581. nativeQueueName,
  1582. (LPSTR)XsSmbGetPointer( &parameters->QueueName )
  1583. );
  1584. CONVERT_QUEUE_NAME( nativeQueueName );
  1585. //
  1586. // Make the local call.
  1587. //
  1588. status = DosPrintQContinue(
  1589. NULL,
  1590. nativeQueueName
  1591. );
  1592. cleanup:
  1593. ;
  1594. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1595. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  1596. }
  1597. if ( !XsPrintApiSuccess( status )) {
  1598. IF_DEBUG(ERRORS) {
  1599. NetpKdPrint(( "XsNetPrintQContinue: DosPrintQContinue failed: "
  1600. FORMAT_API_STATUS "\n", status ));
  1601. }
  1602. }
  1603. //
  1604. // Nothing to return.
  1605. //
  1606. Header->Status = (WORD)status;
  1607. FREE_QUEUE_NAME( nativeQueueName );
  1608. return STATUS_SUCCESS;
  1609. } // XsNetPrintQContinue
  1610. NTSTATUS
  1611. XsNetPrintQDel (
  1612. API_HANDLER_PARAMETERS
  1613. )
  1614. /*++
  1615. Routine Description:
  1616. This routine handles a call to DosPrintQDel.
  1617. Arguments:
  1618. API_HANDLER_PARAMETERS - information about the API call. See
  1619. XsTypes.h for details.
  1620. Return Value:
  1621. NTSTATUS - STATUS_SUCCESS or reason for failure.
  1622. --*/
  1623. {
  1624. SPLERR status;
  1625. PXS_DOS_PRINT_Q_DEL parameters = Parameters;
  1626. LPTSTR nativeQueueName = NULL; // Native parameters
  1627. PREPARE_CONVERT_QUEUE_NAME();
  1628. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  1629. IF_DEBUG(PRINT) {
  1630. NetpKdPrint(( "XsNetPrintQDel: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", name " FORMAT_LPSTR "\n",
  1631. Header, parameters,
  1632. SmbGetUlong( &parameters->QueueName )));
  1633. }
  1634. try {
  1635. //
  1636. // Translate parameters, check for errors.
  1637. //
  1638. XsConvertTextParameter(
  1639. nativeQueueName,
  1640. (LPSTR)XsSmbGetPointer( &parameters->QueueName )
  1641. );
  1642. CONVERT_QUEUE_NAME( nativeQueueName );
  1643. //
  1644. // Make the local call.
  1645. //
  1646. status = DosPrintQDel(
  1647. NULL,
  1648. nativeQueueName
  1649. );
  1650. cleanup:
  1651. ;
  1652. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1653. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  1654. }
  1655. if ( !XsPrintApiSuccess( status )) {
  1656. IF_DEBUG(ERRORS) {
  1657. NetpKdPrint(( "XsNetPrintQDel: DosPrintQDel failed: "
  1658. FORMAT_API_STATUS "\n",
  1659. status ));
  1660. }
  1661. }
  1662. //
  1663. // Nothing to return.
  1664. //
  1665. Header->Status = (WORD)status;
  1666. FREE_QUEUE_NAME( nativeQueueName );
  1667. return STATUS_SUCCESS;
  1668. } // XsNetPrintQDel
  1669. NTSTATUS
  1670. XsNetPrintQEnum (
  1671. API_HANDLER_PARAMETERS
  1672. )
  1673. /*++
  1674. Routine Description:
  1675. This routine handles a call to DosPrintQEnum.
  1676. Arguments:
  1677. API_HANDLER_PARAMETERS - information about the API call. See
  1678. XsTypes.h for details.
  1679. Return Value:
  1680. NTSTATUS - STATUS_SUCCESS or reason for failure.
  1681. --*/
  1682. {
  1683. SPLERR status;
  1684. PXS_DOS_PRINT_Q_ENUM parameters = Parameters;
  1685. LPVOID outBuffer= NULL; // Native parameters
  1686. DWORD outBufferSize;
  1687. DWORD entriesRead = 0;
  1688. DWORD totalEntries = 0;
  1689. WORD bufferLength;
  1690. DWORD entriesFilled = 0; // Conversion variables
  1691. DWORD bytesRequired = 0;
  1692. LPDESC nativeStructureDesc;
  1693. LPDESC nativeAuxStructureDesc;
  1694. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  1695. IF_DEBUG(PRINT) {
  1696. NetpKdPrint(( "XsNetPrintQEnum: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  1697. "level " FORMAT_DWORD ", buf size " FORMAT_DWORD "\n",
  1698. Header, parameters, SmbGetUshort( &parameters->Level ),
  1699. SmbGetUshort( &parameters->BufLen )));
  1700. }
  1701. try {
  1702. //
  1703. // Check for errors.
  1704. //
  1705. if ( XsWordParamOutOfRange( parameters->Level, 0, 5 )) {
  1706. Header->Status = ERROR_INVALID_LEVEL;
  1707. goto cleanup;
  1708. }
  1709. //
  1710. // !!! Print API mapping layer presently requires a preallocated buffer.
  1711. //
  1712. bufferLength = SmbGetUshort( &parameters->BufLen );
  1713. outBufferSize = XsNativeBufferSize( bufferLength );
  1714. if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
  1715. || outBuffer == NULL ) {
  1716. IF_DEBUG(ERRORS) {
  1717. NetpKdPrint(( "XsNetPrintQEnum: cannot allocate memory\n" ));
  1718. }
  1719. Header->Status = NERR_NoRoom;
  1720. goto cleanup;
  1721. }
  1722. //
  1723. // Make the local call.
  1724. //
  1725. status = DosPrintQEnum(
  1726. NULL,
  1727. SmbGetUshort( &parameters->Level ),
  1728. (LPBYTE)outBuffer,
  1729. (WORD)outBufferSize,
  1730. (LPWORD)&entriesRead,
  1731. (LPWORD)&totalEntries
  1732. );
  1733. if ( !XsPrintApiSuccess( status )) {
  1734. IF_DEBUG(API_ERRORS) {
  1735. NetpKdPrint(( "XsNetPrintQEnum: DosPrintQEnum failed: "
  1736. FORMAT_API_STATUS "\n", status ));
  1737. }
  1738. Header->Status = (WORD)status;
  1739. goto cleanup;
  1740. }
  1741. IF_DEBUG(PRINT) {
  1742. NetpKdPrint(( "XsNetPrintQEnum: received " FORMAT_DWORD " entries at " FORMAT_LPVOID "\n",
  1743. entriesRead, outBuffer ));
  1744. }
  1745. //
  1746. // Use the requested level to determine the format of the
  1747. // data structure.
  1748. //
  1749. nativeAuxStructureDesc = NULL;
  1750. AuxStructureDesc = NULL;
  1751. switch ( SmbGetUshort( &parameters->Level ) ) {
  1752. case 0:
  1753. nativeStructureDesc = Desc32_printQ_0;
  1754. StructureDesc = Desc16_printQ_0;
  1755. break;
  1756. case 1:
  1757. nativeStructureDesc = Desc32_printQ_1;
  1758. StructureDesc = Desc16_printQ_1;
  1759. break;
  1760. case 2:
  1761. nativeStructureDesc = Desc32_printQ_2;
  1762. nativeAuxStructureDesc = Desc32_print_job_1;
  1763. StructureDesc = Desc16_printQ_2;
  1764. AuxStructureDesc = Desc16_print_job_1;
  1765. break;
  1766. case 3:
  1767. nativeStructureDesc = Desc32_printQ_3;
  1768. StructureDesc = Desc16_printQ_3;
  1769. break;
  1770. case 4:
  1771. nativeStructureDesc = Desc32_printQ_4;
  1772. nativeAuxStructureDesc = Desc32_print_job_2;
  1773. StructureDesc = Desc16_printQ_4;
  1774. AuxStructureDesc = Desc16_print_job_2;
  1775. break;
  1776. case 5:
  1777. nativeStructureDesc = Desc32_printQ_5;
  1778. StructureDesc = Desc16_printQ_5;
  1779. break;
  1780. }
  1781. //
  1782. // Do the actual conversion from the 32-bit structures to 16-bit
  1783. // structures. Levels 2 and 4 have auxiliary data, other levels call
  1784. // with NULL auxiliary descriptors, so that the normal XsFillEnumBuffer
  1785. // is called.
  1786. //
  1787. XsFillAuxEnumBuffer(
  1788. outBuffer,
  1789. entriesRead,
  1790. nativeStructureDesc,
  1791. nativeAuxStructureDesc,
  1792. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  1793. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  1794. (DWORD)bufferLength,
  1795. StructureDesc,
  1796. AuxStructureDesc,
  1797. NULL, // verify function
  1798. &bytesRequired,
  1799. &entriesFilled,
  1800. NULL
  1801. );
  1802. IF_DEBUG(PRINT) {
  1803. NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR,"
  1804. " Entries " FORMAT_DWORD " of " FORMAT_DWORD "\n",
  1805. outBuffer, SmbGetUlong( &parameters->Buffer ),
  1806. bytesRequired, entriesFilled, totalEntries ));
  1807. }
  1808. //
  1809. // If all the entries could not be filled, return ERROR_MORE_DATA,
  1810. // and return the buffer as is. Otherwise, the data needs to be
  1811. // packed so that we don't send too much useless data. We won't
  1812. // try to pack the ones with the auxiliary structures.
  1813. //
  1814. if ( (entriesFilled < totalEntries) ||
  1815. (bytesRequired > bufferLength) ) {
  1816. Header->Status = ERROR_MORE_DATA;
  1817. } else {
  1818. switch ( SmbGetUshort( &parameters->Level )) {
  1819. case 2:
  1820. case 4:
  1821. break;
  1822. default:
  1823. Header->Converter = XsPackReturnData(
  1824. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  1825. bufferLength,
  1826. StructureDesc,
  1827. entriesFilled
  1828. );
  1829. }
  1830. }
  1831. //
  1832. // Set up the response parameters.
  1833. //
  1834. SmbPutUshort( &parameters->Returned, (WORD)entriesFilled );
  1835. SmbPutUshort( &parameters->Total, (WORD)totalEntries );
  1836. cleanup:
  1837. ;
  1838. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1839. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  1840. }
  1841. NetApiBufferFree( outBuffer );
  1842. //
  1843. // Determine return buffer size.
  1844. //
  1845. XsSetDataCount(
  1846. &parameters->BufLen,
  1847. StructureDesc,
  1848. Header->Converter,
  1849. entriesFilled,
  1850. Header->Status
  1851. );
  1852. return STATUS_SUCCESS;
  1853. } // XsNetPrintQEnum
  1854. NTSTATUS
  1855. XsNetPrintQGetInfo (
  1856. API_HANDLER_PARAMETERS
  1857. )
  1858. /*++
  1859. Routine Description:
  1860. This routine handles a call to DosPrintQGetInfo.
  1861. Arguments:
  1862. API_HANDLER_PARAMETERS - information about the API call. See
  1863. XsTypes.h for details.
  1864. Return Value:
  1865. NTSTATUS - STATUS_SUCCESS or reason for failure.
  1866. --*/
  1867. {
  1868. SPLERR status;
  1869. PXS_DOS_PRINT_Q_GET_INFO parameters = Parameters;
  1870. LPTSTR nativeQueueName = NULL; // Native parameters
  1871. LPVOID outBuffer = NULL;
  1872. DWORD outBufferSize;
  1873. WORD bytesNeeded = 0;
  1874. LPBYTE stringLocation = NULL; // Conversion variables
  1875. DWORD bytesRequired = 0;
  1876. LPDESC nativeStructureDesc = NULL;
  1877. LPDESC nativeAuxStructureDesc = NULL;
  1878. LPDESC longDescriptor = NULL;
  1879. LPDESC longNativeDescriptor = NULL;
  1880. DWORD auxDataCount;
  1881. DWORD i;
  1882. PREPARE_CONVERT_QUEUE_NAME();
  1883. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  1884. IF_DEBUG(PRINT) {
  1885. NetpKdPrint(( "XsNetPrintQGetInfo: header at " FORMAT_LPVOID ", "
  1886. "params at " FORMAT_LPVOID ", level " FORMAT_DWORD "\n",
  1887. Header, parameters, SmbGetUshort( &parameters->Level ) ));
  1888. }
  1889. try {
  1890. //
  1891. // Translate parameters, check for errors.
  1892. //
  1893. //
  1894. // Level 52 supported for Win95 clients
  1895. //
  1896. if ( XsWordParamOutOfRange( parameters->Level, 0, 5 ) &&
  1897. (DWORD) SmbGetUshort(&parameters->Level) != 52 ) {
  1898. Header->Status = ERROR_INVALID_LEVEL;
  1899. goto cleanup;
  1900. }
  1901. XsConvertTextParameter(
  1902. nativeQueueName,
  1903. (LPSTR)XsSmbGetPointer( &parameters->QueueName )
  1904. );
  1905. CONVERT_QUEUE_NAME( nativeQueueName );
  1906. //
  1907. // !!! Print API mapping layer presently requires a preallocated buffer.
  1908. //
  1909. outBufferSize = XsNativeBufferSize( SmbGetUshort( &parameters->BufLen ));
  1910. if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
  1911. || outBuffer == NULL ) {
  1912. IF_DEBUG(ERRORS) {
  1913. NetpKdPrint(( "XsNetPrintQGetInfo: cannot allocate memory\n" ));
  1914. }
  1915. Header->Status = NERR_NoRoom;
  1916. goto cleanup;
  1917. }
  1918. //
  1919. // Make the local call.
  1920. //
  1921. status = DosPrintQGetInfo(
  1922. NULL,
  1923. nativeQueueName,
  1924. SmbGetUshort( &parameters->Level ),
  1925. (LPBYTE)outBuffer,
  1926. SmbGetUshort( &parameters->BufLen ),
  1927. &bytesNeeded
  1928. );
  1929. if ( !XsPrintApiSuccess( status )) {
  1930. IF_DEBUG(API_ERRORS) {
  1931. NetpKdPrint(( "XsNetPrintQGetInfo: DosPrintQGetInfo failed: "
  1932. FORMAT_API_STATUS "\n", status ));
  1933. }
  1934. Header->Status = (WORD)status;
  1935. goto cleanup;
  1936. }
  1937. //
  1938. // Use the requested level to determine the format of the
  1939. // data structure.
  1940. //
  1941. switch ( SmbGetUshort( &parameters->Level ) ) {
  1942. case 0:
  1943. nativeStructureDesc = Desc32_printQ_0;
  1944. StructureDesc = Desc16_printQ_0;
  1945. break;
  1946. case 1:
  1947. nativeStructureDesc = Desc32_printQ_1;
  1948. StructureDesc = Desc16_printQ_1;
  1949. break;
  1950. case 2:
  1951. nativeStructureDesc = Desc32_printQ_2;
  1952. nativeAuxStructureDesc = Desc32_print_job_1;
  1953. StructureDesc = Desc16_printQ_2;
  1954. AuxStructureDesc = Desc16_print_job_1;
  1955. break;
  1956. case 3:
  1957. nativeStructureDesc = Desc32_printQ_3;
  1958. StructureDesc = Desc16_printQ_3;
  1959. break;
  1960. case 4:
  1961. nativeStructureDesc = Desc32_printQ_4;
  1962. nativeAuxStructureDesc = Desc32_print_job_2;
  1963. StructureDesc = Desc16_printQ_4;
  1964. AuxStructureDesc = Desc16_print_job_2;
  1965. break;
  1966. case 5:
  1967. nativeStructureDesc = Desc32_printQ_5;
  1968. StructureDesc = Desc16_printQ_5;
  1969. break;
  1970. case 52:
  1971. nativeStructureDesc = Desc32_printQ_52;
  1972. StructureDesc = Desc16_printQ_52;
  1973. break;
  1974. }
  1975. //
  1976. // Common code between cases 2 and 4 - form long descriptors.
  1977. //
  1978. switch ( SmbGetUshort( &parameters->Level )) {
  1979. case 2:
  1980. case 4:
  1981. //
  1982. // Find the auxiliary data count.
  1983. //
  1984. auxDataCount = RapAuxDataCount(
  1985. (LPBYTE)outBuffer,
  1986. nativeStructureDesc,
  1987. Response,
  1988. TRUE // native format
  1989. );
  1990. longDescriptor = NetpMemoryAllocate(
  1991. strlen( StructureDesc )
  1992. + strlen( AuxStructureDesc ) *
  1993. auxDataCount + 1 );
  1994. longNativeDescriptor = NetpMemoryAllocate(
  1995. strlen( nativeStructureDesc )
  1996. + strlen( nativeAuxStructureDesc )
  1997. * auxDataCount
  1998. + 1 );
  1999. if (( longDescriptor == NULL ) || ( longNativeDescriptor == NULL )) {
  2000. IF_DEBUG(ERRORS) {
  2001. NetpKdPrint(( "XsNetPrintQGetInfo: failed to allocate memory" ));
  2002. }
  2003. Header->Status = (WORD)NERR_NoRoom;
  2004. goto cleanup;
  2005. }
  2006. strcpy( longDescriptor, StructureDesc );
  2007. strcpy( longNativeDescriptor, nativeStructureDesc );
  2008. for ( i = 0; i < auxDataCount; i++ ) {
  2009. strcat( longDescriptor, AuxStructureDesc );
  2010. strcat( longNativeDescriptor, nativeAuxStructureDesc );
  2011. }
  2012. StructureDesc = longDescriptor;
  2013. nativeStructureDesc = longNativeDescriptor;
  2014. break;
  2015. }
  2016. //
  2017. // Convert the structure returned by the 32-bit call to a 16-bit
  2018. // structure. The last possible location for variable data is
  2019. // calculated from buffer location and length.
  2020. //
  2021. stringLocation = (LPBYTE)( XsSmbGetPointer( &parameters->Buffer )
  2022. + SmbGetUshort( &parameters->BufLen ) );
  2023. status = RapConvertSingleEntry(
  2024. outBuffer,
  2025. nativeStructureDesc,
  2026. FALSE,
  2027. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  2028. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  2029. StructureDesc,
  2030. TRUE,
  2031. &stringLocation,
  2032. &bytesRequired,
  2033. Response,
  2034. NativeToRap
  2035. );
  2036. if ( status != NERR_Success ) {
  2037. IF_DEBUG(ERRORS) {
  2038. NetpKdPrint(( "XsDosPrintQGetInfo: RapConvertSingleEntry failed: "
  2039. FORMAT_API_STATUS "\n", status ));
  2040. }
  2041. Header->Status = NERR_InternalError;
  2042. goto cleanup;
  2043. }
  2044. //
  2045. // Determine return code based on the size of the buffer.
  2046. //
  2047. if ( !XsCheckBufferSize(
  2048. SmbGetUshort( &parameters->BufLen ),
  2049. StructureDesc,
  2050. FALSE // not in native format
  2051. )) {
  2052. IF_DEBUG(ERRORS) {
  2053. NetpKdPrint(( "XsNetPrintQGetInfo: Buffer too small.\n" ));
  2054. }
  2055. Header->Status = NERR_BufTooSmall;
  2056. } else if ( bytesRequired > (DWORD)SmbGetUshort( &parameters-> BufLen )) {
  2057. IF_DEBUG(ERRORS) {
  2058. NetpKdPrint(( "XsNetPrintQGetInfo: More data available.\n" ));
  2059. }
  2060. Header->Status = ERROR_MORE_DATA;
  2061. } else {
  2062. //
  2063. // Pack the response data.
  2064. //
  2065. Header->Converter = XsPackReturnData(
  2066. (LPVOID)XsSmbGetPointer( &parameters->Buffer ),
  2067. SmbGetUshort( &parameters->BufLen ),
  2068. StructureDesc,
  2069. 1
  2070. );
  2071. }
  2072. bytesNeeded = (WORD)bytesRequired;
  2073. cleanup:
  2074. ;
  2075. } except( EXCEPTION_EXECUTE_HANDLER ) {
  2076. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  2077. }
  2078. //
  2079. // Set up the response parameters.
  2080. //
  2081. SmbPutUshort( &parameters->Needed, bytesNeeded );
  2082. //
  2083. // Determine return buffer size.
  2084. //
  2085. XsSetDataCount(
  2086. &parameters->BufLen,
  2087. StructureDesc, // desc (may be one we created on heap)
  2088. Header->Converter,
  2089. 1,
  2090. Header->Status
  2091. );
  2092. (VOID) NetApiBufferFree( outBuffer );
  2093. FREE_QUEUE_NAME( nativeQueueName );
  2094. NetpMemoryFree( longDescriptor );
  2095. NetpMemoryFree( longNativeDescriptor );
  2096. return STATUS_SUCCESS;
  2097. } // XsNetPrintQGetInfo
  2098. NTSTATUS
  2099. XsNetPrintQPause (
  2100. API_HANDLER_PARAMETERS
  2101. )
  2102. /*++
  2103. Routine Description:
  2104. This routine handles a call to DosPrintQPause.
  2105. Arguments:
  2106. API_HANDLER_PARAMETERS - information about the API call. See
  2107. XsTypes.h for details.
  2108. Return Value:
  2109. NTSTATUS - STATUS_SUCCESS or reason for failure.
  2110. --*/
  2111. {
  2112. SPLERR status;
  2113. PXS_DOS_PRINT_Q_PAUSE parameters = Parameters;
  2114. LPTSTR nativeQueueName = NULL; // Native parameters
  2115. PREPARE_CONVERT_QUEUE_NAME();
  2116. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  2117. IF_DEBUG(PRINT) {
  2118. NetpKdPrint(( "XsNetPrintQPause: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  2119. "name " FORMAT_LPSTR "\n",
  2120. Header, parameters,
  2121. SmbGetUlong( &parameters->QueueName )));
  2122. }
  2123. try {
  2124. //
  2125. // Translate parameters, check for errors.
  2126. //
  2127. XsConvertTextParameter(
  2128. nativeQueueName,
  2129. (LPSTR)XsSmbGetPointer( &parameters->QueueName )
  2130. );
  2131. CONVERT_QUEUE_NAME( nativeQueueName );
  2132. //
  2133. // Make the local call.
  2134. //
  2135. status = DosPrintQPause(
  2136. NULL,
  2137. nativeQueueName
  2138. );
  2139. cleanup:
  2140. ;
  2141. } except( EXCEPTION_EXECUTE_HANDLER ) {
  2142. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  2143. }
  2144. if ( !XsPrintApiSuccess( status )) {
  2145. IF_DEBUG(ERRORS) {
  2146. NetpKdPrint(( "XsNetPrintQPause: DosPrintQPause failed: "
  2147. FORMAT_API_STATUS "\n",
  2148. status ));
  2149. }
  2150. }
  2151. //
  2152. // Nothing to return.
  2153. //
  2154. Header->Status = (WORD)status;
  2155. FREE_QUEUE_NAME( nativeQueueName );
  2156. return STATUS_SUCCESS;
  2157. } // XsNetPrintQPause
  2158. NTSTATUS
  2159. XsNetPrintQPurge (
  2160. API_HANDLER_PARAMETERS
  2161. )
  2162. /*++
  2163. Routine Description:
  2164. This routine handles a call to DosPrintQPurge.
  2165. Arguments:
  2166. API_HANDLER_PARAMETERS - information about the API call. See
  2167. XsTypes.h for details.
  2168. Return Value:
  2169. NTSTATUS - STATUS_SUCCESS or reason for failure.
  2170. --*/
  2171. {
  2172. SPLERR status;
  2173. PXS_DOS_PRINT_Q_PURGE parameters = Parameters;
  2174. LPTSTR nativeQueueName = NULL; // Native parameters
  2175. PREPARE_CONVERT_QUEUE_NAME();
  2176. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  2177. IF_DEBUG(PRINT) {
  2178. NetpKdPrint(( "XsNetPrintQPurge: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
  2179. "name " FORMAT_LPSTR "\n",
  2180. Header, parameters,
  2181. SmbGetUlong( &parameters->QueueName )));
  2182. }
  2183. try {
  2184. //
  2185. // Translate parameters, check for errors.
  2186. //
  2187. XsConvertTextParameter(
  2188. nativeQueueName,
  2189. (LPSTR)XsSmbGetPointer( &parameters->QueueName )
  2190. );
  2191. CONVERT_QUEUE_NAME( nativeQueueName );
  2192. //
  2193. // Make the local call.
  2194. //
  2195. status = DosPrintQPurge(
  2196. NULL,
  2197. nativeQueueName
  2198. );
  2199. cleanup:
  2200. ;
  2201. } except( EXCEPTION_EXECUTE_HANDLER ) {
  2202. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  2203. }
  2204. if ( !XsPrintApiSuccess( status )) {
  2205. IF_DEBUG(ERRORS) {
  2206. NetpKdPrint(( "XsNetPrintQPurge: DosPrintQPurge failed: "
  2207. FORMAT_API_STATUS "\n",
  2208. status ));
  2209. }
  2210. }
  2211. //
  2212. // Nothing to return.
  2213. //
  2214. Header->Status = (WORD)status;
  2215. FREE_QUEUE_NAME( nativeQueueName );
  2216. return STATUS_SUCCESS;
  2217. } // XsNetPrintQPurge
  2218. NTSTATUS
  2219. XsNetPrintQSetInfo (
  2220. API_HANDLER_PARAMETERS
  2221. )
  2222. /*++
  2223. Routine Description:
  2224. This routine handles a call to NetPrintQSetInfo.
  2225. Arguments:
  2226. API_HANDLER_PARAMETERS - information about the API call. See
  2227. XsTypes.h for details.
  2228. Return Value:
  2229. NTSTATUS - STATUS_SUCCESS or reason for failure.
  2230. --*/
  2231. {
  2232. SPLERR status;
  2233. PXS_DOS_PRINT_Q_SET_INFO parameters = Parameters;
  2234. LPTSTR nativeQueueName = NULL; // Native parameters
  2235. LPVOID buffer = NULL;
  2236. DWORD bytesRequired;
  2237. DWORD fieldIndex;
  2238. LPDESC setInfoDesc; // Conversion variables
  2239. LPDESC nativeSetInfoDesc;
  2240. LPDESC nativeStructureDesc;
  2241. PREPARE_CONVERT_QUEUE_NAME();
  2242. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  2243. try {
  2244. //
  2245. // Translate parameters, check for errors.
  2246. //
  2247. if ( SmbGetUshort( &parameters->Level ) != 1
  2248. && SmbGetUshort( &parameters->Level ) != 3 ) {
  2249. Header->Status = ERROR_INVALID_LEVEL;
  2250. goto cleanup;
  2251. }
  2252. XsConvertTextParameter(
  2253. nativeQueueName,
  2254. (LPSTR)XsSmbGetPointer( &parameters->QueueName )
  2255. );
  2256. CONVERT_QUEUE_NAME( nativeQueueName );
  2257. //
  2258. // Determine descriptor strings based on level. Also translate the
  2259. // parmnum value to a field index.
  2260. // !!! - Right now, we don't check for parameters settable in downlevel
  2261. // that are meaningless in the NT mapping layer.
  2262. //
  2263. fieldIndex = (DWORD)SmbGetUshort( &parameters->ParmNum );
  2264. switch ( SmbGetUshort( &parameters->Level )) {
  2265. case 1:
  2266. StructureDesc = Desc16_printQ_1;
  2267. nativeStructureDesc = Desc32_printQ_1;
  2268. setInfoDesc = Desc16_printQ_1_setinfo;
  2269. nativeSetInfoDesc = Desc32_printQ_1_setinfo;
  2270. if ( fieldIndex > 1 ) { // Account for pad field
  2271. fieldIndex++;
  2272. }
  2273. break;
  2274. case 3:
  2275. StructureDesc = Desc16_printQ_3;
  2276. nativeStructureDesc = Desc32_printQ_3;
  2277. setInfoDesc = Desc16_printQ_3_setinfo;
  2278. nativeSetInfoDesc = Desc32_printQ_3_setinfo;
  2279. if ( fieldIndex == PRQ_DESTINATIONS_PARMNUM ) {
  2280. fieldIndex = (DWORD)-1; // No corresponding field
  2281. } else if ( fieldIndex == PRQ_SEPARATOR_PARMNUM
  2282. || fieldIndex == PRQ_PROCESSOR_PARMNUM ) {
  2283. fieldIndex++;
  2284. }
  2285. break;
  2286. }
  2287. status = XsConvertSetInfoBuffer(
  2288. (LPBYTE)XsSmbGetPointer( &parameters->Buffer ),
  2289. SmbGetUshort( &parameters->BufLen ),
  2290. (WORD)fieldIndex,
  2291. FALSE,
  2292. TRUE,
  2293. StructureDesc,
  2294. nativeStructureDesc,
  2295. setInfoDesc,
  2296. nativeSetInfoDesc,
  2297. (LPBYTE *)&buffer,
  2298. &bytesRequired
  2299. );
  2300. if ( status != NERR_Success ) {
  2301. IF_DEBUG(ERRORS) {
  2302. NetpKdPrint(( "XsNetPrintQSetInfo: Problem with conversion: "
  2303. FORMAT_API_STATUS "\n",
  2304. status ));
  2305. }
  2306. Header->Status = (WORD)status;
  2307. goto cleanup;
  2308. }
  2309. //
  2310. // Do the actual local call.
  2311. //
  2312. status = DosPrintQSetInfo(
  2313. NULL,
  2314. nativeQueueName,
  2315. SmbGetUshort( &parameters->Level ),
  2316. (LPBYTE)buffer,
  2317. (WORD)bytesRequired,
  2318. SmbGetUshort( &parameters->ParmNum )
  2319. );
  2320. if ( !XsPrintApiSuccess( status )) {
  2321. IF_DEBUG(ERRORS) {
  2322. NetpKdPrint(( "XsNetPrintQSetInfo: DosPrintQSetInfo failed: "
  2323. FORMAT_API_STATUS "\n",
  2324. status ));
  2325. }
  2326. Header->Status = (WORD)status;
  2327. goto cleanup;
  2328. }
  2329. //
  2330. // No return information for this API.
  2331. //
  2332. cleanup:
  2333. ;
  2334. } except( EXCEPTION_EXECUTE_HANDLER ) {
  2335. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  2336. }
  2337. //
  2338. // If there is a native 32-bit buffer, free it.
  2339. //
  2340. NetpMemoryFree( buffer );
  2341. FREE_QUEUE_NAME( nativeQueueName );
  2342. return STATUS_SUCCESS;
  2343. } // XsNetPrintQSetInfo