3142 lines
83 KiB
C
3142 lines
83 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991-1992 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
ApiPrint.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains individual API handlers for the DosPrint APIs.
|
|||
|
|
|||
|
SUPPORTED : DosPrintDestAdd, DosPrintDestControl, DosPrintDestDel,
|
|||
|
DosPrintDestEnum, DosPrintDestGetInfo, DosPrintDestSetInfo,
|
|||
|
DosPrintJobContinue, DosPrintJobDel, DosPrintJobEnum,
|
|||
|
DosPrintJobGetId, DosPrintJobGetInfo, DosPrintJobPause,
|
|||
|
DosPrintJobSetInfo, DosPrintQAdd, DosPrintQContinue,
|
|||
|
DosPrintQDel, DosPrintQEnum, DosPrintQGetInfo,
|
|||
|
DosPrintQPause, DosPrintQPurge, DosPrintQSetInfo.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Shanku Niyogi (w-shanku) 04-Apr-1991
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
18-Jun-1992 JohnRo
|
|||
|
RAID 10324: net print vs. UNICODE.
|
|||
|
Use FORMAT_ equates.
|
|||
|
01-Oct-1992 JohnRo
|
|||
|
RAID 3556: DosPrintQGetInfo(from downlevel) level 3, rc=124. (4&5 too.)
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "XactSrvP.h"
|
|||
|
#include <dosprint.h>
|
|||
|
|
|||
|
//
|
|||
|
// Declaration of descriptor strings.
|
|||
|
//
|
|||
|
|
|||
|
STATIC const LPDESC Desc16_print_dest_0 = REM16_print_dest_0;
|
|||
|
STATIC const LPDESC Desc32_print_dest_0 = REM32_print_dest_0;
|
|||
|
STATIC const LPDESC Desc16_print_dest_1 = REM16_print_dest_1;
|
|||
|
STATIC const LPDESC Desc32_print_dest_1 = REM32_print_dest_1;
|
|||
|
STATIC const LPDESC Desc16_print_dest_2 = REM16_print_dest_2;
|
|||
|
STATIC const LPDESC Desc32_print_dest_2 = REM32_print_dest_2;
|
|||
|
STATIC const LPDESC Desc16_print_dest_3 = REM16_print_dest_3;
|
|||
|
STATIC const LPDESC Desc32_print_dest_3 = REM32_print_dest_3;
|
|||
|
STATIC const LPDESC Desc16_print_dest_3_setinfo = REM16_print_dest_3_setinfo;
|
|||
|
STATIC const LPDESC Desc32_print_dest_3_setinfo = REM32_print_dest_3_setinfo;
|
|||
|
STATIC const LPDESC Desc16_print_job_0 = REM16_print_job_0;
|
|||
|
STATIC const LPDESC Desc32_print_job_0 = REM32_print_job_0;
|
|||
|
STATIC const LPDESC Desc16_print_job_1 = REM16_print_job_1;
|
|||
|
STATIC const LPDESC Desc32_print_job_1 = REM32_print_job_1;
|
|||
|
STATIC const LPDESC Desc16_print_job_1_setinfo = REM16_print_job_1_setinfo;
|
|||
|
STATIC const LPDESC Desc32_print_job_1_setinfo = REM32_print_job_1_setinfo;
|
|||
|
STATIC const LPDESC Desc16_print_job_2 = REM16_print_job_2;
|
|||
|
STATIC const LPDESC Desc32_print_job_2 = REM32_print_job_2;
|
|||
|
STATIC const LPDESC Desc16_print_job_3 = REM16_print_job_3;
|
|||
|
STATIC const LPDESC Desc32_print_job_3 = REM32_print_job_3;
|
|||
|
STATIC const LPDESC Desc16_print_job_3_setinfo = REM16_print_job_3_setinfo;
|
|||
|
STATIC const LPDESC Desc32_print_job_3_setinfo = REM32_print_job_3_setinfo;
|
|||
|
STATIC const LPDESC Desc16_printQ_0 = REM16_printQ_0;
|
|||
|
STATIC const LPDESC Desc32_printQ_0 = REM32_printQ_0;
|
|||
|
STATIC const LPDESC Desc16_printQ_1 = REM16_printQ_1;
|
|||
|
STATIC const LPDESC Desc32_printQ_1 = REM32_printQ_1;
|
|||
|
STATIC const LPDESC Desc16_printQ_1_setinfo = REM16_printQ_1_setinfo;
|
|||
|
STATIC const LPDESC Desc32_printQ_1_setinfo = REM32_printQ_1_setinfo;
|
|||
|
STATIC const LPDESC Desc16_printQ_2 = REM16_printQ_2;
|
|||
|
STATIC const LPDESC Desc32_printQ_2 = REM32_printQ_2;
|
|||
|
STATIC const LPDESC Desc16_printQ_3 = REM16_printQ_3;
|
|||
|
STATIC const LPDESC Desc32_printQ_3 = REM32_printQ_3;
|
|||
|
STATIC const LPDESC Desc16_printQ_3_setinfo = REM16_printQ_3_setinfo;
|
|||
|
STATIC const LPDESC Desc32_printQ_3_setinfo = REM32_printQ_3_setinfo;
|
|||
|
STATIC const LPDESC Desc16_printQ_4 = REM16_printQ_4;
|
|||
|
STATIC const LPDESC Desc32_printQ_4 = REM32_printQ_4;
|
|||
|
STATIC const LPDESC Desc16_printQ_5 = REM16_printQ_5;
|
|||
|
STATIC const LPDESC Desc32_printQ_5 = REM32_printQ_5;
|
|||
|
STATIC const LPDESC Desc16_printQ_52 = REM16_printQ_52;
|
|||
|
STATIC const LPDESC Desc32_printQ_52 = REM32_printQ_52;
|
|||
|
|
|||
|
//
|
|||
|
// DosPrint calls behave differently from Net api calls. On Net api calls,
|
|||
|
// the called routine supplies the buffer to us. DosPrint apis need a
|
|||
|
// supplied buffer and thus can return NERR_BufferTooSmall which means
|
|||
|
// it's an error but return the bytes needed if it's a XXGetInfo call.
|
|||
|
//
|
|||
|
|
|||
|
#define XsPrintApiSuccess( Status ) \
|
|||
|
(( (Status) == NERR_Success ) || ( (Status) == ERROR_MORE_DATA ))
|
|||
|
|
|||
|
//
|
|||
|
// Now that servers can have multiple names (See SrvNetTransportAdd, and clusters),
|
|||
|
// it is necessary to transmit the server name part of a queue name to the spooler.
|
|||
|
// The following three macros aid in the translation.
|
|||
|
//
|
|||
|
#define PREPARE_CONVERT_QUEUE_NAME() \
|
|||
|
WCHAR queueNameBuf[ MAX_PATH ]; \
|
|||
|
CHAR localComputerName[ NETBIOS_NAME_LEN ]; \
|
|||
|
DWORD localComputerNameLen = sizeof( localComputerName ); \
|
|||
|
PUCHAR p = &Header->ServerName[ NETBIOS_NAME_LEN-2 ]; \
|
|||
|
for( ; p > Header->ServerName && *p == ' '; p-- ); \
|
|||
|
p++; \
|
|||
|
GetComputerNameA( localComputerName, &localComputerNameLen );
|
|||
|
|
|||
|
#define CONVERT_QUEUE_NAME( queue ) \
|
|||
|
if( queue && ((DWORD)(p-Header->ServerName) != localComputerNameLen || \
|
|||
|
memcmp( localComputerName, Header->ServerName, localComputerNameLen )) &&\
|
|||
|
mbstowcs( NULL, Header->ServerName, (size_t)(p-Header->ServerName )) <= \
|
|||
|
sizeof( queueNameBuf ) - wcslen(queue)*sizeof(WCHAR) - 4*sizeof(WCHAR)){\
|
|||
|
\
|
|||
|
RtlZeroMemory( queueNameBuf, sizeof( queueNameBuf ) ); \
|
|||
|
queueNameBuf[0] = queueNameBuf[1] = L'\\'; \
|
|||
|
mbstowcs( queueNameBuf+2, Header->ServerName, \
|
|||
|
(size_t)(p-Header->ServerName) ); \
|
|||
|
wcscat( queueNameBuf, L"\\" ); \
|
|||
|
wcscat( queueNameBuf, queue ); \
|
|||
|
NetApiBufferFree( queue ); \
|
|||
|
queue = queueNameBuf; \
|
|||
|
}
|
|||
|
|
|||
|
#define FREE_QUEUE_NAME( queue ) if( queue != queueNameBuf ) NetApiBufferFree( queue )
|
|||
|
|
|||
|
#define GET_LOCAL_SERVER_NAME() \
|
|||
|
WCHAR LocalServerName[ MAX_PATH ]; \
|
|||
|
PUCHAR p = &Header->ServerName[ NETBIOS_NAME_LEN-2 ]; \
|
|||
|
for( ; p > Header->ServerName && *p == ' '; p-- ); \
|
|||
|
p++; \
|
|||
|
LocalServerName[0] = LocalServerName[1] = L'\\'; \
|
|||
|
mbstowcs( LocalServerName+2, Header->ServerName, \
|
|||
|
(size_t)(p-Header->ServerName) ); \
|
|||
|
LocalServerName[2+p-Header->ServerName] = L'\0';
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintDestAdd (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintDestAdd.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_DEST_ADD parameters = Parameters;
|
|||
|
LPVOID buffer = NULL; // Native parameters
|
|||
|
|
|||
|
LPBYTE stringLocation = NULL; // Conversion variables
|
|||
|
DWORD bytesRequired = 0;
|
|||
|
DWORD bufferSize;
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestAdd: header at " FORMAT_LPVOID
|
|||
|
", params at " FORMAT_LPVOID ", "
|
|||
|
"level " FORMAT_DWORD "\n",
|
|||
|
Header,
|
|||
|
parameters,
|
|||
|
SmbGetUshort( ¶meters->Level ) ));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Check for errors.
|
|||
|
//
|
|||
|
|
|||
|
if ( SmbGetUshort( ¶meters->Level ) != 3 ) {
|
|||
|
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
StructureDesc = Desc16_print_dest_3;
|
|||
|
|
|||
|
//
|
|||
|
// Figure out if there is enough room in the buffer for all the
|
|||
|
// data required. If not, return NERR_BufTooSmall.
|
|||
|
//
|
|||
|
|
|||
|
if ( !XsCheckBufferSize(
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
FALSE // not in native format
|
|||
|
)) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestAdd: Buffer too small.\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_BufTooSmall;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Find out how big a buffer we need to allocate to hold the native
|
|||
|
// 32-bit version of the input data structure.
|
|||
|
//
|
|||
|
|
|||
|
bufferSize = XsBytesForConvertedStructure(
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
StructureDesc,
|
|||
|
Desc32_print_dest_3,
|
|||
|
RapToNative,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Allocate enough memory to hold the converted native buffer.
|
|||
|
//
|
|||
|
|
|||
|
buffer = NetpMemoryAllocate( bufferSize );
|
|||
|
|
|||
|
if ( buffer == NULL ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestAdd: failed to create buffer" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_NoRoom;
|
|||
|
goto cleanup;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestAdd: buffer of " FORMAT_DWORD " bytes at " FORMAT_LPVOID "\n",
|
|||
|
bufferSize, buffer ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Convert the buffer from 16-bit to 32-bit.
|
|||
|
//
|
|||
|
|
|||
|
stringLocation = (LPBYTE)buffer + bufferSize;
|
|||
|
bytesRequired = 0;
|
|||
|
|
|||
|
status = RapConvertSingleEntry(
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
StructureDesc,
|
|||
|
TRUE,
|
|||
|
buffer,
|
|||
|
buffer,
|
|||
|
Desc32_print_dest_3,
|
|||
|
FALSE,
|
|||
|
&stringLocation,
|
|||
|
&bytesRequired,
|
|||
|
Response,
|
|||
|
RapToNative
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if ( status != NERR_Success ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestAdd: RapConvertSingleEntry failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
|
|||
|
Header->Status = NERR_InternalError;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintDestAdd(
|
|||
|
NULL,
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
buffer,
|
|||
|
(WORD)bufferSize
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestAdd: DosPrintDestAdd failed: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// There is no real return information for this API.
|
|||
|
//
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
NetpMemoryFree( buffer );
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintDestAdd
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintDestControl (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintDestControl.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_DEST_CONTROL parameters = Parameters;
|
|||
|
LPTSTR nativeDestName = NULL; // Native parameters
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestControl: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"name " FORMAT_LPSTR "\n",
|
|||
|
Header, parameters,
|
|||
|
SmbGetUlong( ¶meters->DestName )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeDestName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->DestName )
|
|||
|
);
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeDestName );
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
status = DosPrintDestControl(
|
|||
|
NULL,
|
|||
|
nativeDestName,
|
|||
|
SmbGetUshort( ¶meters->Control )
|
|||
|
);
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestControl: DosPrintDestControl failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Nothing to return.
|
|||
|
//
|
|||
|
|
|||
|
Header->Status = (WORD)status;
|
|||
|
|
|||
|
FREE_QUEUE_NAME( nativeDestName );
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintDestControl
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintDestDel (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintDestDel.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_DEST_DEL parameters = Parameters;
|
|||
|
LPTSTR nativePrinterName = NULL; // Native parameters
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestDel: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"name " FORMAT_LPSTR "\n",
|
|||
|
Header, parameters,
|
|||
|
SmbGetUlong( ¶meters->PrinterName )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativePrinterName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->PrinterName )
|
|||
|
);
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativePrinterName );
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintDestDel(
|
|||
|
NULL,
|
|||
|
nativePrinterName
|
|||
|
);
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestDel: DosPrintDestDel failed: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Nothing to return.
|
|||
|
//
|
|||
|
|
|||
|
Header->Status = (WORD)status;
|
|||
|
|
|||
|
FREE_QUEUE_NAME( nativePrinterName );
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintDestDel
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintDestEnum (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintDestEnum.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_DEST_ENUM parameters = Parameters;
|
|||
|
LPVOID outBuffer= NULL; // Native parameters
|
|||
|
DWORD outBufferSize;
|
|||
|
DWORD entriesRead = 0;
|
|||
|
DWORD totalEntries = 0;
|
|||
|
|
|||
|
DWORD entriesFilled = 0; // Conversion variables
|
|||
|
DWORD bytesRequired = 0;
|
|||
|
LPDESC nativeStructureDesc;
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestEnum: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"level " FORMAT_DWORD ", buf size " FORMAT_DWORD "\n",
|
|||
|
Header, parameters, SmbGetUshort( ¶meters->Level ),
|
|||
|
SmbGetUshort( ¶meters->BufLen )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Check for errors.
|
|||
|
//
|
|||
|
|
|||
|
if ( XsWordParamOutOfRange( parameters->Level, 0, 3 )) {
|
|||
|
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// !!! Print API mapping layer presently requires a preallocated buffer.
|
|||
|
//
|
|||
|
|
|||
|
outBufferSize = XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen ));
|
|||
|
if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
|
|||
|
|| outBuffer == NULL ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestEnum: cannot allocate memory\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_NoRoom;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintDestEnum(
|
|||
|
NULL,
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
(LPBYTE)outBuffer,
|
|||
|
(WORD)outBufferSize,
|
|||
|
(LPWORD)&entriesRead,
|
|||
|
(LPWORD)&totalEntries
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(API_ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestEnum: DosPrintDestEnum failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestEnum: received " FORMAT_DWORD " entries at " FORMAT_LPVOID "\n",
|
|||
|
entriesRead, outBuffer ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Use the requested level to determine the format of the
|
|||
|
// data structure.
|
|||
|
//
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level ) ) {
|
|||
|
|
|||
|
case 0:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_dest_0;
|
|||
|
StructureDesc = Desc16_print_dest_0;
|
|||
|
break;
|
|||
|
|
|||
|
case 1:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_dest_1;
|
|||
|
StructureDesc = Desc16_print_dest_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_dest_2;
|
|||
|
StructureDesc = Desc16_print_dest_2;
|
|||
|
break;
|
|||
|
|
|||
|
case 3:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_dest_3;
|
|||
|
StructureDesc = Desc16_print_dest_3;
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Do the actual conversion from the 32-bit structures to 16-bit
|
|||
|
// structures.
|
|||
|
//
|
|||
|
|
|||
|
XsFillEnumBuffer(
|
|||
|
outBuffer,
|
|||
|
entriesRead,
|
|||
|
nativeStructureDesc,
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
NULL, // verify function
|
|||
|
&bytesRequired,
|
|||
|
&entriesFilled,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR,"
|
|||
|
" Entries " FORMAT_DWORD " of " FORMAT_DWORD "\n",
|
|||
|
outBuffer, SmbGetUlong( ¶meters->Buffer ),
|
|||
|
bytesRequired, entriesFilled, totalEntries ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If all the entries could not be filled, return ERROR_MORE_DATA,
|
|||
|
// and return the buffer as is. Otherwise, the data needs to be
|
|||
|
// packed so that we don't send too much useless data.
|
|||
|
//
|
|||
|
|
|||
|
if ( entriesFilled < totalEntries ) {
|
|||
|
|
|||
|
Header->Status = ERROR_MORE_DATA;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
Header->Converter = XsPackReturnData(
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
entriesFilled
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up the response parameters.
|
|||
|
//
|
|||
|
|
|||
|
SmbPutUshort( ¶meters->Returned, (WORD)entriesFilled );
|
|||
|
SmbPutUshort( ¶meters->Total, (WORD)totalEntries );
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
NetApiBufferFree( outBuffer );
|
|||
|
|
|||
|
//
|
|||
|
// Determine return buffer size.
|
|||
|
//
|
|||
|
|
|||
|
XsSetDataCount(
|
|||
|
¶meters->BufLen,
|
|||
|
StructureDesc,
|
|||
|
Header->Converter,
|
|||
|
entriesFilled,
|
|||
|
Header->Status
|
|||
|
);
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintDestEnum
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintDestGetInfo (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintDestGetInfo.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_DEST_GET_INFO parameters = Parameters;
|
|||
|
LPTSTR nativeName = NULL; // Native parameters
|
|||
|
LPVOID outBuffer = NULL;
|
|||
|
DWORD outBufferSize;
|
|||
|
WORD bytesNeeded = 0;
|
|||
|
|
|||
|
LPBYTE stringLocation = NULL; // Conversion variables
|
|||
|
DWORD bytesRequired = 0;
|
|||
|
LPDESC nativeStructureDesc;
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestGetInfo: header at " FORMAT_LPVOID ", "
|
|||
|
"params at " FORMAT_LPVOID ", level " FORMAT_DWORD "\n",
|
|||
|
Header, parameters, SmbGetUshort( ¶meters->Level ) ));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
if ( XsWordParamOutOfRange( parameters->Level, 0, 3 )) {
|
|||
|
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->Name )
|
|||
|
);
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeName );
|
|||
|
|
|||
|
//
|
|||
|
// !!! Print API mapping layer presently requires a preallocated buffer.
|
|||
|
//
|
|||
|
|
|||
|
outBufferSize = XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen ));
|
|||
|
if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
|
|||
|
|| outBuffer == NULL ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestGetInfo: cannot allocate memory\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_NoRoom;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintDestGetInfo(
|
|||
|
NULL,
|
|||
|
nativeName,
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
(LPBYTE)outBuffer,
|
|||
|
(WORD)outBufferSize,
|
|||
|
&bytesNeeded
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(API_ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestGetInfo: DosPrintDestGetInfo failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Use the requested level to determine the format of the
|
|||
|
// data structure.
|
|||
|
//
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level ) ) {
|
|||
|
|
|||
|
case 0:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_dest_0;
|
|||
|
StructureDesc = Desc16_print_dest_0;
|
|||
|
break;
|
|||
|
|
|||
|
case 1:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_dest_1;
|
|||
|
StructureDesc = Desc16_print_dest_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_dest_2;
|
|||
|
StructureDesc = Desc16_print_dest_2;
|
|||
|
break;
|
|||
|
|
|||
|
case 3:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_dest_3;
|
|||
|
StructureDesc = Desc16_print_dest_3;
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Convert the structure returned by the 32-bit call to a 16-bit
|
|||
|
// structure. The last possible location for variable data is
|
|||
|
// calculated from buffer location and length.
|
|||
|
//
|
|||
|
|
|||
|
stringLocation = (LPBYTE)( XsSmbGetPointer( ¶meters->Buffer )
|
|||
|
+ SmbGetUshort( ¶meters->BufLen ) );
|
|||
|
|
|||
|
status = RapConvertSingleEntry(
|
|||
|
outBuffer,
|
|||
|
nativeStructureDesc,
|
|||
|
FALSE,
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
StructureDesc,
|
|||
|
TRUE,
|
|||
|
&stringLocation,
|
|||
|
&bytesRequired,
|
|||
|
Response,
|
|||
|
NativeToRap
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if ( status != NERR_Success ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsDosPrintDestGetInfo: RapConvertSingleEntry failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
|
|||
|
Header->Status = NERR_InternalError;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR\n",
|
|||
|
outBuffer, SmbGetUlong( ¶meters->Buffer ),
|
|||
|
bytesRequired ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Determine return code based on the size of the buffer.
|
|||
|
//
|
|||
|
|
|||
|
if ( !XsCheckBufferSize(
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
FALSE // not in native format
|
|||
|
)) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestGetInfo: Buffer too small.\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_BufTooSmall;
|
|||
|
|
|||
|
} else if ( bytesRequired > (DWORD)SmbGetUshort( ¶meters-> BufLen )) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestGetInfo: More data available.\n" ));
|
|||
|
}
|
|||
|
Header->Status = ERROR_MORE_DATA;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Pack the response data.
|
|||
|
//
|
|||
|
|
|||
|
Header->Converter = XsPackReturnData(
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
1
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
bytesNeeded = (WORD)bytesRequired;
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up the response parameters.
|
|||
|
//
|
|||
|
|
|||
|
SmbPutUshort( ¶meters->Needed, bytesNeeded );
|
|||
|
|
|||
|
NetApiBufferFree( outBuffer );
|
|||
|
FREE_QUEUE_NAME( nativeName );
|
|||
|
|
|||
|
//
|
|||
|
// Determine return buffer size.
|
|||
|
//
|
|||
|
|
|||
|
XsSetDataCount(
|
|||
|
¶meters->BufLen,
|
|||
|
StructureDesc,
|
|||
|
Header->Converter,
|
|||
|
1,
|
|||
|
Header->Status
|
|||
|
);
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintDestGetInfo
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintDestSetInfo (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintDestSetInfo.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_DEST_SET_INFO parameters = Parameters;
|
|||
|
LPTSTR nativeName = NULL; // Native parameters
|
|||
|
LPVOID buffer = NULL;
|
|||
|
DWORD bytesRequired;
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
if ( SmbGetUshort( ¶meters->Level ) != 3 ) {
|
|||
|
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
StructureDesc = Desc16_print_dest_3;
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->Name )
|
|||
|
);
|
|||
|
|
|||
|
status = XsConvertSetInfoBuffer(
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
SmbGetUshort( ¶meters->ParmNum ),
|
|||
|
FALSE,
|
|||
|
TRUE,
|
|||
|
StructureDesc,
|
|||
|
Desc32_print_dest_3,
|
|||
|
Desc16_print_dest_3_setinfo,
|
|||
|
Desc32_print_dest_3_setinfo,
|
|||
|
(LPBYTE *)&buffer,
|
|||
|
&bytesRequired
|
|||
|
);
|
|||
|
|
|||
|
if ( status != NERR_Success ) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestSetInfo: Problem with conversion: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeName );
|
|||
|
|
|||
|
//
|
|||
|
// Do the actual local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintDestSetInfo(
|
|||
|
NULL,
|
|||
|
nativeName,
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
(LPBYTE)buffer,
|
|||
|
(WORD)bytesRequired,
|
|||
|
SmbGetUshort( ¶meters->ParmNum )
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintDestSetInfo: DosPrintDestSetInfo failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// No return information for this API.
|
|||
|
//
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If there is a native 32-bit buffer, free it.
|
|||
|
//
|
|||
|
|
|||
|
NetpMemoryFree( buffer );
|
|||
|
FREE_QUEUE_NAME( nativeName );
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintDestSetInfo
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintJobContinue (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintJobContinue.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_JOB_CONTINUE parameters = Parameters;
|
|||
|
|
|||
|
GET_LOCAL_SERVER_NAME();
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobContinue: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"job " FORMAT_WORD_ONLY "\n",
|
|||
|
Header, parameters, SmbGetUshort( ¶meters->JobId )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintJobContinue(
|
|||
|
LocalServerName,
|
|||
|
FALSE,
|
|||
|
SmbGetUshort( ¶meters->JobId )
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobContinue: DosPrintJobContinue failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
}
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Nothing to return.
|
|||
|
//
|
|||
|
|
|||
|
Header->Status = (WORD)status;
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintJobContinue
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintJobDel (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintJobDel.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_JOB_DEL parameters = Parameters;
|
|||
|
|
|||
|
GET_LOCAL_SERVER_NAME();
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobDel: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"job " FORMAT_WORD_ONLY "\n",
|
|||
|
Header, parameters, SmbGetUshort( ¶meters->JobId )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintJobDel(
|
|||
|
LocalServerName,
|
|||
|
FALSE,
|
|||
|
SmbGetUshort( ¶meters->JobId )
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobDel: DosPrintJobDel failed: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
}
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Nothing to return.
|
|||
|
//
|
|||
|
|
|||
|
Header->Status = (WORD)status;
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintJobDel
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintJobEnum (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintJobEnum.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_JOB_ENUM parameters = Parameters;
|
|||
|
LPTSTR nativeQueueName = NULL; // Native parameters
|
|||
|
LPVOID outBuffer= NULL;
|
|||
|
DWORD outBufferSize;
|
|||
|
DWORD entriesRead = 0;
|
|||
|
DWORD totalEntries = 0;
|
|||
|
|
|||
|
DWORD entriesFilled = 0; // Conversion variables
|
|||
|
DWORD bytesRequired = 0;
|
|||
|
LPDESC nativeStructureDesc;
|
|||
|
WORD bufferLength;
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobEnum: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"level " FORMAT_DWORD ", buf size " FORMAT_DWORD "\n",
|
|||
|
Header, parameters, SmbGetUshort( ¶meters->Level ),
|
|||
|
SmbGetUshort( ¶meters->BufLen )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
if ( XsWordParamOutOfRange( parameters->Level, 0, 2 )) {
|
|||
|
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeQueueName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->QueueName )
|
|||
|
);
|
|||
|
|
|||
|
bufferLength = SmbGetUshort( ¶meters->BufLen );
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeQueueName );
|
|||
|
|
|||
|
//
|
|||
|
// !!! Print API mapping layer presently requires a preallocated buffer.
|
|||
|
//
|
|||
|
|
|||
|
outBufferSize = XsNativeBufferSize( bufferLength );
|
|||
|
if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
|
|||
|
|| outBuffer == NULL ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobEnum: cannot allocate memory\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_NoRoom;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintJobEnum(
|
|||
|
NULL,
|
|||
|
nativeQueueName,
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
(LPBYTE)outBuffer,
|
|||
|
(WORD)outBufferSize,
|
|||
|
(LPWORD)&entriesRead,
|
|||
|
(LPWORD)&totalEntries
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(API_ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobEnum: DosPrintJobEnum failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobEnum: received " FORMAT_DWORD " entries at " FORMAT_LPVOID "\n",
|
|||
|
entriesRead, outBuffer ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Use the requested level to determine the format of the
|
|||
|
// data structure.
|
|||
|
//
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level ) ) {
|
|||
|
|
|||
|
case 0:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_job_0;
|
|||
|
StructureDesc = Desc16_print_job_0;
|
|||
|
break;
|
|||
|
|
|||
|
case 1:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_job_1;
|
|||
|
StructureDesc = Desc16_print_job_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_job_2;
|
|||
|
StructureDesc = Desc16_print_job_2;
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Do the actual conversion from the 32-bit structures to 16-bit
|
|||
|
// structures.
|
|||
|
//
|
|||
|
|
|||
|
XsFillEnumBuffer(
|
|||
|
outBuffer,
|
|||
|
entriesRead,
|
|||
|
nativeStructureDesc,
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
(DWORD)bufferLength,
|
|||
|
StructureDesc,
|
|||
|
NULL, // verify function
|
|||
|
&bytesRequired,
|
|||
|
&entriesFilled,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR,"
|
|||
|
" Entries " FORMAT_DWORD " of " FORMAT_DWORD "\n",
|
|||
|
outBuffer, SmbGetUlong( ¶meters->Buffer ),
|
|||
|
bytesRequired, entriesFilled, totalEntries ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If all the entries could not be filled, return ERROR_MORE_DATA,
|
|||
|
// and return the buffer as is. Otherwise, the data needs to be
|
|||
|
// packed so that we don't send too much useless data.
|
|||
|
//
|
|||
|
|
|||
|
if ( (entriesFilled < totalEntries) ||
|
|||
|
(bytesRequired > bufferLength) ) {
|
|||
|
|
|||
|
Header->Status = ERROR_MORE_DATA;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
Header->Converter = XsPackReturnData(
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
bufferLength,
|
|||
|
StructureDesc,
|
|||
|
entriesFilled
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up the response parameters.
|
|||
|
//
|
|||
|
|
|||
|
SmbPutUshort( ¶meters->Returned, (WORD)entriesFilled );
|
|||
|
SmbPutUshort( ¶meters->Total, (WORD)totalEntries );
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
NetApiBufferFree( outBuffer );
|
|||
|
FREE_QUEUE_NAME( nativeQueueName );
|
|||
|
|
|||
|
//
|
|||
|
// Determine return buffer size.
|
|||
|
//
|
|||
|
|
|||
|
XsSetDataCount(
|
|||
|
¶meters->BufLen,
|
|||
|
StructureDesc,
|
|||
|
Header->Converter,
|
|||
|
entriesFilled,
|
|||
|
Header->Status
|
|||
|
);
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintJobEnum
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintJobGetInfo (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintJobGetInfo.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_JOB_GET_INFO parameters = Parameters;
|
|||
|
LPVOID outBuffer = NULL; // Native parameters
|
|||
|
DWORD outBufferSize;
|
|||
|
WORD bytesNeeded = 0;
|
|||
|
|
|||
|
LPBYTE stringLocation = NULL; // Conversion variables
|
|||
|
DWORD bytesRequired = 0;
|
|||
|
LPDESC nativeStructureDesc;
|
|||
|
|
|||
|
GET_LOCAL_SERVER_NAME();
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobGetInfo: header at " FORMAT_LPVOID ", "
|
|||
|
"params at " FORMAT_LPVOID ", level " FORMAT_DWORD "\n",
|
|||
|
Header, parameters, SmbGetUshort( ¶meters->Level ) ));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Check for errors.
|
|||
|
//
|
|||
|
|
|||
|
if ( XsWordParamOutOfRange( parameters->Level, 0, 3 )) {
|
|||
|
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// !!! Print API mapping layer presently requires a preallocated buffer.
|
|||
|
//
|
|||
|
|
|||
|
outBufferSize = XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen ));
|
|||
|
if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
|
|||
|
|| outBuffer == NULL ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobGetInfo: cannot allocate memory\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_NoRoom;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
status = DosPrintJobGetInfo(
|
|||
|
LocalServerName,
|
|||
|
FALSE,
|
|||
|
SmbGetUshort( ¶meters->JobId ),
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
(LPBYTE)outBuffer,
|
|||
|
(WORD)outBufferSize,
|
|||
|
&bytesNeeded
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(API_ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobGetInfo: DosPrintJobGetInfo failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Use the requested level to determine the format of the
|
|||
|
// data structure.
|
|||
|
//
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level ) ) {
|
|||
|
|
|||
|
case 0:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_job_0;
|
|||
|
StructureDesc = Desc16_print_job_0;
|
|||
|
break;
|
|||
|
|
|||
|
case 1:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_job_1;
|
|||
|
StructureDesc = Desc16_print_job_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_job_2;
|
|||
|
StructureDesc = Desc16_print_job_2;
|
|||
|
break;
|
|||
|
|
|||
|
case 3:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_print_job_3;
|
|||
|
StructureDesc = Desc16_print_job_3;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Convert the structure returned by the 32-bit call to a 16-bit
|
|||
|
// structure. The last possible location for variable data is
|
|||
|
// calculated from buffer location and length.
|
|||
|
//
|
|||
|
|
|||
|
stringLocation = (LPBYTE)( XsSmbGetPointer( ¶meters->Buffer )
|
|||
|
+ SmbGetUshort( ¶meters->BufLen ) );
|
|||
|
|
|||
|
status = RapConvertSingleEntry(
|
|||
|
outBuffer,
|
|||
|
nativeStructureDesc,
|
|||
|
FALSE,
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
StructureDesc,
|
|||
|
TRUE,
|
|||
|
&stringLocation,
|
|||
|
&bytesRequired,
|
|||
|
Response,
|
|||
|
NativeToRap
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if ( status != NERR_Success ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsDosPrintJobGetInfo: RapConvertSingleEntry failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
|
|||
|
Header->Status = NERR_InternalError;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR\n",
|
|||
|
outBuffer, SmbGetUlong( ¶meters->Buffer ),
|
|||
|
bytesRequired ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Determine return code based on the size of the buffer.
|
|||
|
//
|
|||
|
|
|||
|
if ( !XsCheckBufferSize(
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
FALSE // not in native format
|
|||
|
)) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobGetInfo: Buffer too small.\n" ));
|
|||
|
}
|
|||
|
|
|||
|
Header->Status = NERR_BufTooSmall;
|
|||
|
|
|||
|
} else if ( bytesRequired > (DWORD)SmbGetUshort( ¶meters-> BufLen )) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobGetInfo: More data available.\n" ));
|
|||
|
}
|
|||
|
Header->Status = ERROR_MORE_DATA;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Pack the response data.
|
|||
|
//
|
|||
|
|
|||
|
Header->Converter = XsPackReturnData(
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
1
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
bytesNeeded = (WORD)bytesRequired;
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up the response parameters.
|
|||
|
//
|
|||
|
|
|||
|
SmbPutUshort( ¶meters->Needed, bytesNeeded );
|
|||
|
|
|||
|
NetApiBufferFree( outBuffer );
|
|||
|
|
|||
|
//
|
|||
|
// Determine return buffer size.
|
|||
|
//
|
|||
|
|
|||
|
XsSetDataCount(
|
|||
|
¶meters->BufLen,
|
|||
|
StructureDesc,
|
|||
|
Header->Converter,
|
|||
|
1,
|
|||
|
Header->Status
|
|||
|
);
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintJobGetInfo
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintJobPause (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintJobPause.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_JOB_PAUSE parameters = Parameters;
|
|||
|
|
|||
|
GET_LOCAL_SERVER_NAME();
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobPause: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"job " FORMAT_WORD_ONLY "\n",
|
|||
|
Header, parameters, SmbGetUshort( ¶meters->JobId )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintJobPause(
|
|||
|
LocalServerName,
|
|||
|
FALSE,
|
|||
|
SmbGetUshort( ¶meters->JobId )
|
|||
|
);
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobPause: DosPrintJobPause failed: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Nothing to return.
|
|||
|
//
|
|||
|
|
|||
|
Header->Status = (WORD)status;
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintJobPause
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintJobSetInfo (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintJobSetInfo.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_JOB_SET_INFO parameters = Parameters;
|
|||
|
LPVOID buffer = NULL; // Native parameters
|
|||
|
DWORD bytesRequired;
|
|||
|
WORD level;
|
|||
|
|
|||
|
DWORD fieldIndex;
|
|||
|
LPDESC setInfoDesc; // Conversion variables
|
|||
|
LPDESC nativeSetInfoDesc;
|
|||
|
LPDESC nativeStructureDesc;
|
|||
|
|
|||
|
GET_LOCAL_SERVER_NAME();
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Check for errors.
|
|||
|
//
|
|||
|
|
|||
|
level = SmbGetUshort( ¶meters->Level );
|
|||
|
|
|||
|
if ( level != 1 && level != 3 ) {
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Determine descriptor strings based on level. Also translate the
|
|||
|
// parmnum value to a field index.
|
|||
|
// !!! - Right now, we don't check for parameters settable in downlevel
|
|||
|
// that are meaningless in the NT mapping layer. Fix this,
|
|||
|
// if necessary, in the descriptor string file (with
|
|||
|
// REM_IGNORE fields).
|
|||
|
//
|
|||
|
|
|||
|
fieldIndex = (DWORD)SmbGetUshort( ¶meters->ParmNum );
|
|||
|
|
|||
|
switch ( level ) {
|
|||
|
|
|||
|
case 1:
|
|||
|
|
|||
|
StructureDesc = Desc16_print_job_1;
|
|||
|
nativeStructureDesc = Desc32_print_job_1;
|
|||
|
setInfoDesc = Desc16_print_job_1_setinfo;
|
|||
|
nativeSetInfoDesc = Desc32_print_job_1_setinfo;
|
|||
|
if ( fieldIndex > 2 ) { // Account for pad field
|
|||
|
fieldIndex++;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case 3:
|
|||
|
|
|||
|
StructureDesc = Desc16_print_job_3;
|
|||
|
nativeStructureDesc = Desc32_print_job_3;
|
|||
|
setInfoDesc = Desc16_print_job_3_setinfo;
|
|||
|
nativeSetInfoDesc = Desc32_print_job_3_setinfo;
|
|||
|
if ( fieldIndex != PARMNUM_ALL && fieldIndex < 15 ) {
|
|||
|
switch ( fieldIndex ) {
|
|||
|
case PRJ_NOTIFYNAME_PARMNUM:
|
|||
|
case PRJ_DATATYPE_PARMNUM:
|
|||
|
case PRJ_PARMS_PARMNUM:
|
|||
|
fieldIndex += 7; break;
|
|||
|
case PRJ_POSITION_PARMNUM:
|
|||
|
fieldIndex = 4; break;
|
|||
|
case PRJ_COMMENT_PARMNUM:
|
|||
|
case PRJ_DOCUMENT_PARMNUM:
|
|||
|
fieldIndex -= 3; break;
|
|||
|
case PRJ_PRIORITY_PARMNUM:
|
|||
|
fieldIndex = 2; break;
|
|||
|
default:
|
|||
|
fieldIndex = 0xFFFFFFFF; // Some invalid field
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
status = XsConvertSetInfoBuffer(
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
(WORD)fieldIndex,
|
|||
|
FALSE,
|
|||
|
TRUE,
|
|||
|
StructureDesc,
|
|||
|
nativeStructureDesc,
|
|||
|
setInfoDesc,
|
|||
|
nativeSetInfoDesc,
|
|||
|
(LPBYTE *)&buffer,
|
|||
|
&bytesRequired
|
|||
|
);
|
|||
|
|
|||
|
if ( status != NERR_Success ) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobSetInfo: Problem with conversion: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Do the actual local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintJobSetInfo(
|
|||
|
LocalServerName,
|
|||
|
FALSE,
|
|||
|
SmbGetUshort( ¶meters->JobId ),
|
|||
|
level,
|
|||
|
(LPBYTE)buffer,
|
|||
|
(WORD)bytesRequired,
|
|||
|
SmbGetUshort( ¶meters->ParmNum )
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintJobSetInfo: DosPrintJobSetInfo failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// No return information for this API.
|
|||
|
//
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If there is a native 32-bit buffer, free it.
|
|||
|
//
|
|||
|
|
|||
|
NetpMemoryFree( buffer );
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintJobSetInfo
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintQAdd (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintQAdd.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_Q_ADD parameters = Parameters;
|
|||
|
LPVOID buffer = NULL; // Native parameters
|
|||
|
|
|||
|
LPBYTE stringLocation = NULL; // Conversion variables
|
|||
|
DWORD bytesRequired = 0;
|
|||
|
LPTSTR nativeStructureDesc;
|
|||
|
DWORD bufferSize;
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintQAdd: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"level " FORMAT_DWORD "\n",
|
|||
|
Header,
|
|||
|
parameters,
|
|||
|
SmbGetUshort( ¶meters->Level ) ));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
|
|||
|
//
|
|||
|
// Determine native structure descriptor based on level.
|
|||
|
//
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level )) {
|
|||
|
|
|||
|
case 1:
|
|||
|
StructureDesc = Desc16_printQ_1;
|
|||
|
nativeStructureDesc = (LPTSTR)Desc32_printQ_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 3:
|
|||
|
StructureDesc = Desc16_printQ_3;
|
|||
|
nativeStructureDesc = (LPTSTR)Desc32_printQ_3;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Figure out if there is enough room in the buffer for all the
|
|||
|
// data required. If not, return NERR_BufTooSmall.
|
|||
|
//
|
|||
|
|
|||
|
if ( !XsCheckBufferSize(
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
FALSE // not in native format
|
|||
|
)) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQAdd: Buffer too small.\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_BufTooSmall;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Find out how big a buffer we need to allocate to hold the native
|
|||
|
// 32-bit version of the input data structure.
|
|||
|
//
|
|||
|
|
|||
|
bufferSize = XsBytesForConvertedStructure(
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
StructureDesc,
|
|||
|
(LPDESC)nativeStructureDesc,
|
|||
|
RapToNative,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Allocate enough memory to hold the converted native buffer.
|
|||
|
//
|
|||
|
|
|||
|
buffer = NetpMemoryAllocate( bufferSize );
|
|||
|
|
|||
|
if ( buffer == NULL ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQAdd: failed to create buffer" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_NoRoom;
|
|||
|
goto cleanup;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintQAdd: buffer of " FORMAT_DWORD " bytes at " FORMAT_LPVOID "\n",
|
|||
|
bufferSize, buffer ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Convert the buffer from 16-bit to 32-bit.
|
|||
|
//
|
|||
|
|
|||
|
stringLocation = (LPBYTE)buffer + bufferSize;
|
|||
|
bytesRequired = 0;
|
|||
|
|
|||
|
status = RapConvertSingleEntry(
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
StructureDesc,
|
|||
|
TRUE,
|
|||
|
buffer,
|
|||
|
buffer,
|
|||
|
(LPDESC)nativeStructureDesc,
|
|||
|
FALSE,
|
|||
|
&stringLocation,
|
|||
|
&bytesRequired,
|
|||
|
Response,
|
|||
|
RapToNative
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if ( status != NERR_Success ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQAdd: RapConvertSingleEntry failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
|
|||
|
Header->Status = NERR_InternalError;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintQAdd(
|
|||
|
NULL,
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
buffer,
|
|||
|
(WORD)bufferSize
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQAdd: DosPrintQAdd failed: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// There is no real return information for this API.
|
|||
|
//
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
NetpMemoryFree( buffer );
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintQAdd
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintQContinue (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintQContinue.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_Q_CONTINUE parameters = Parameters;
|
|||
|
LPTSTR nativeQueueName = NULL; // Native parameters
|
|||
|
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintQContinue: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"name " FORMAT_LPSTR "\n",
|
|||
|
Header, parameters,
|
|||
|
SmbGetUlong( ¶meters->QueueName )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeQueueName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->QueueName )
|
|||
|
);
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeQueueName );
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintQContinue(
|
|||
|
NULL,
|
|||
|
nativeQueueName
|
|||
|
);
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQContinue: DosPrintQContinue failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Nothing to return.
|
|||
|
//
|
|||
|
|
|||
|
Header->Status = (WORD)status;
|
|||
|
|
|||
|
FREE_QUEUE_NAME( nativeQueueName );
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintQContinue
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintQDel (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintQDel.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_Q_DEL parameters = Parameters;
|
|||
|
LPTSTR nativeQueueName = NULL; // Native parameters
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintQDel: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", name " FORMAT_LPSTR "\n",
|
|||
|
Header, parameters,
|
|||
|
SmbGetUlong( ¶meters->QueueName )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeQueueName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->QueueName )
|
|||
|
);
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeQueueName );
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintQDel(
|
|||
|
NULL,
|
|||
|
nativeQueueName
|
|||
|
);
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQDel: DosPrintQDel failed: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Nothing to return.
|
|||
|
//
|
|||
|
|
|||
|
Header->Status = (WORD)status;
|
|||
|
|
|||
|
FREE_QUEUE_NAME( nativeQueueName );
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintQDel
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintQEnum (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintQEnum.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_Q_ENUM parameters = Parameters;
|
|||
|
LPVOID outBuffer= NULL; // Native parameters
|
|||
|
DWORD outBufferSize;
|
|||
|
DWORD entriesRead = 0;
|
|||
|
DWORD totalEntries = 0;
|
|||
|
WORD bufferLength;
|
|||
|
|
|||
|
DWORD entriesFilled = 0; // Conversion variables
|
|||
|
DWORD bytesRequired = 0;
|
|||
|
LPDESC nativeStructureDesc;
|
|||
|
LPDESC nativeAuxStructureDesc;
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintQEnum: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"level " FORMAT_DWORD ", buf size " FORMAT_DWORD "\n",
|
|||
|
Header, parameters, SmbGetUshort( ¶meters->Level ),
|
|||
|
SmbGetUshort( ¶meters->BufLen )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Check for errors.
|
|||
|
//
|
|||
|
|
|||
|
if ( XsWordParamOutOfRange( parameters->Level, 0, 5 )) {
|
|||
|
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// !!! Print API mapping layer presently requires a preallocated buffer.
|
|||
|
//
|
|||
|
|
|||
|
bufferLength = SmbGetUshort( ¶meters->BufLen );
|
|||
|
outBufferSize = XsNativeBufferSize( bufferLength );
|
|||
|
if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
|
|||
|
|| outBuffer == NULL ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQEnum: cannot allocate memory\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_NoRoom;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintQEnum(
|
|||
|
NULL,
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
(LPBYTE)outBuffer,
|
|||
|
(WORD)outBufferSize,
|
|||
|
(LPWORD)&entriesRead,
|
|||
|
(LPWORD)&totalEntries
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(API_ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQEnum: DosPrintQEnum failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintQEnum: received " FORMAT_DWORD " entries at " FORMAT_LPVOID "\n",
|
|||
|
entriesRead, outBuffer ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Use the requested level to determine the format of the
|
|||
|
// data structure.
|
|||
|
//
|
|||
|
|
|||
|
nativeAuxStructureDesc = NULL;
|
|||
|
AuxStructureDesc = NULL;
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level ) ) {
|
|||
|
|
|||
|
case 0:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_0;
|
|||
|
StructureDesc = Desc16_printQ_0;
|
|||
|
break;
|
|||
|
|
|||
|
case 1:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_1;
|
|||
|
StructureDesc = Desc16_printQ_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_2;
|
|||
|
nativeAuxStructureDesc = Desc32_print_job_1;
|
|||
|
StructureDesc = Desc16_printQ_2;
|
|||
|
AuxStructureDesc = Desc16_print_job_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 3:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_3;
|
|||
|
StructureDesc = Desc16_printQ_3;
|
|||
|
break;
|
|||
|
|
|||
|
case 4:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_4;
|
|||
|
nativeAuxStructureDesc = Desc32_print_job_2;
|
|||
|
StructureDesc = Desc16_printQ_4;
|
|||
|
AuxStructureDesc = Desc16_print_job_2;
|
|||
|
break;
|
|||
|
|
|||
|
case 5:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_5;
|
|||
|
StructureDesc = Desc16_printQ_5;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Do the actual conversion from the 32-bit structures to 16-bit
|
|||
|
// structures. Levels 2 and 4 have auxiliary data, other levels call
|
|||
|
// with NULL auxiliary descriptors, so that the normal XsFillEnumBuffer
|
|||
|
// is called.
|
|||
|
//
|
|||
|
|
|||
|
XsFillAuxEnumBuffer(
|
|||
|
outBuffer,
|
|||
|
entriesRead,
|
|||
|
nativeStructureDesc,
|
|||
|
nativeAuxStructureDesc,
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
(DWORD)bufferLength,
|
|||
|
StructureDesc,
|
|||
|
AuxStructureDesc,
|
|||
|
NULL, // verify function
|
|||
|
&bytesRequired,
|
|||
|
&entriesFilled,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "32-bit data at " FORMAT_LPVOID ", 16-bit data at " FORMAT_LPVOID ", " FORMAT_DWORD " BR,"
|
|||
|
" Entries " FORMAT_DWORD " of " FORMAT_DWORD "\n",
|
|||
|
outBuffer, SmbGetUlong( ¶meters->Buffer ),
|
|||
|
bytesRequired, entriesFilled, totalEntries ));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If all the entries could not be filled, return ERROR_MORE_DATA,
|
|||
|
// and return the buffer as is. Otherwise, the data needs to be
|
|||
|
// packed so that we don't send too much useless data. We won't
|
|||
|
// try to pack the ones with the auxiliary structures.
|
|||
|
//
|
|||
|
|
|||
|
if ( (entriesFilled < totalEntries) ||
|
|||
|
(bytesRequired > bufferLength) ) {
|
|||
|
|
|||
|
Header->Status = ERROR_MORE_DATA;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level )) {
|
|||
|
|
|||
|
case 2:
|
|||
|
case 4:
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
Header->Converter = XsPackReturnData(
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
bufferLength,
|
|||
|
StructureDesc,
|
|||
|
entriesFilled
|
|||
|
);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up the response parameters.
|
|||
|
//
|
|||
|
|
|||
|
SmbPutUshort( ¶meters->Returned, (WORD)entriesFilled );
|
|||
|
SmbPutUshort( ¶meters->Total, (WORD)totalEntries );
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
NetApiBufferFree( outBuffer );
|
|||
|
|
|||
|
//
|
|||
|
// Determine return buffer size.
|
|||
|
//
|
|||
|
|
|||
|
XsSetDataCount(
|
|||
|
¶meters->BufLen,
|
|||
|
StructureDesc,
|
|||
|
Header->Converter,
|
|||
|
entriesFilled,
|
|||
|
Header->Status
|
|||
|
);
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintQEnum
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintQGetInfo (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintQGetInfo.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_Q_GET_INFO parameters = Parameters;
|
|||
|
LPTSTR nativeQueueName = NULL; // Native parameters
|
|||
|
LPVOID outBuffer = NULL;
|
|||
|
DWORD outBufferSize;
|
|||
|
WORD bytesNeeded = 0;
|
|||
|
|
|||
|
LPBYTE stringLocation = NULL; // Conversion variables
|
|||
|
DWORD bytesRequired = 0;
|
|||
|
LPDESC nativeStructureDesc = NULL;
|
|||
|
LPDESC nativeAuxStructureDesc = NULL;
|
|||
|
LPDESC longDescriptor = NULL;
|
|||
|
LPDESC longNativeDescriptor = NULL;
|
|||
|
DWORD auxDataCount;
|
|||
|
DWORD i;
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintQGetInfo: header at " FORMAT_LPVOID ", "
|
|||
|
"params at " FORMAT_LPVOID ", level " FORMAT_DWORD "\n",
|
|||
|
Header, parameters, SmbGetUshort( ¶meters->Level ) ));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Level 52 supported for Win95 clients
|
|||
|
//
|
|||
|
if ( XsWordParamOutOfRange( parameters->Level, 0, 5 ) &&
|
|||
|
(DWORD) SmbGetUshort(¶meters->Level) != 52 ) {
|
|||
|
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeQueueName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->QueueName )
|
|||
|
);
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeQueueName );
|
|||
|
|
|||
|
//
|
|||
|
// !!! Print API mapping layer presently requires a preallocated buffer.
|
|||
|
//
|
|||
|
|
|||
|
outBufferSize = XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen ));
|
|||
|
if ( NetapipBufferAllocate( outBufferSize, &outBuffer ) != NERR_Success
|
|||
|
|| outBuffer == NULL ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQGetInfo: cannot allocate memory\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_NoRoom;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintQGetInfo(
|
|||
|
NULL,
|
|||
|
nativeQueueName,
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
(LPBYTE)outBuffer,
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
&bytesNeeded
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(API_ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQGetInfo: DosPrintQGetInfo failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Use the requested level to determine the format of the
|
|||
|
// data structure.
|
|||
|
//
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level ) ) {
|
|||
|
|
|||
|
case 0:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_0;
|
|||
|
StructureDesc = Desc16_printQ_0;
|
|||
|
break;
|
|||
|
|
|||
|
case 1:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_1;
|
|||
|
StructureDesc = Desc16_printQ_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_2;
|
|||
|
nativeAuxStructureDesc = Desc32_print_job_1;
|
|||
|
StructureDesc = Desc16_printQ_2;
|
|||
|
AuxStructureDesc = Desc16_print_job_1;
|
|||
|
break;
|
|||
|
|
|||
|
case 3:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_3;
|
|||
|
StructureDesc = Desc16_printQ_3;
|
|||
|
break;
|
|||
|
|
|||
|
case 4:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_4;
|
|||
|
nativeAuxStructureDesc = Desc32_print_job_2;
|
|||
|
StructureDesc = Desc16_printQ_4;
|
|||
|
AuxStructureDesc = Desc16_print_job_2;
|
|||
|
break;
|
|||
|
|
|||
|
case 5:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_5;
|
|||
|
StructureDesc = Desc16_printQ_5;
|
|||
|
break;
|
|||
|
|
|||
|
case 52:
|
|||
|
|
|||
|
nativeStructureDesc = Desc32_printQ_52;
|
|||
|
StructureDesc = Desc16_printQ_52;
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Common code between cases 2 and 4 - form long descriptors.
|
|||
|
//
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level )) {
|
|||
|
|
|||
|
case 2:
|
|||
|
case 4:
|
|||
|
|
|||
|
//
|
|||
|
// Find the auxiliary data count.
|
|||
|
//
|
|||
|
|
|||
|
auxDataCount = RapAuxDataCount(
|
|||
|
(LPBYTE)outBuffer,
|
|||
|
nativeStructureDesc,
|
|||
|
Response,
|
|||
|
TRUE // native format
|
|||
|
);
|
|||
|
|
|||
|
longDescriptor = NetpMemoryAllocate(
|
|||
|
strlen( StructureDesc )
|
|||
|
+ strlen( AuxStructureDesc ) *
|
|||
|
auxDataCount + 1 );
|
|||
|
longNativeDescriptor = NetpMemoryAllocate(
|
|||
|
strlen( nativeStructureDesc )
|
|||
|
+ strlen( nativeAuxStructureDesc )
|
|||
|
* auxDataCount
|
|||
|
+ 1 );
|
|||
|
|
|||
|
if (( longDescriptor == NULL ) || ( longNativeDescriptor == NULL )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQGetInfo: failed to allocate memory" ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)NERR_NoRoom;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
strcpy( longDescriptor, StructureDesc );
|
|||
|
strcpy( longNativeDescriptor, nativeStructureDesc );
|
|||
|
for ( i = 0; i < auxDataCount; i++ ) {
|
|||
|
strcat( longDescriptor, AuxStructureDesc );
|
|||
|
strcat( longNativeDescriptor, nativeAuxStructureDesc );
|
|||
|
}
|
|||
|
|
|||
|
StructureDesc = longDescriptor;
|
|||
|
nativeStructureDesc = longNativeDescriptor;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Convert the structure returned by the 32-bit call to a 16-bit
|
|||
|
// structure. The last possible location for variable data is
|
|||
|
// calculated from buffer location and length.
|
|||
|
//
|
|||
|
|
|||
|
stringLocation = (LPBYTE)( XsSmbGetPointer( ¶meters->Buffer )
|
|||
|
+ SmbGetUshort( ¶meters->BufLen ) );
|
|||
|
|
|||
|
status = RapConvertSingleEntry(
|
|||
|
outBuffer,
|
|||
|
nativeStructureDesc,
|
|||
|
FALSE,
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
StructureDesc,
|
|||
|
TRUE,
|
|||
|
&stringLocation,
|
|||
|
&bytesRequired,
|
|||
|
Response,
|
|||
|
NativeToRap
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if ( status != NERR_Success ) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsDosPrintQGetInfo: RapConvertSingleEntry failed: "
|
|||
|
FORMAT_API_STATUS "\n", status ));
|
|||
|
}
|
|||
|
|
|||
|
Header->Status = NERR_InternalError;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Determine return code based on the size of the buffer.
|
|||
|
//
|
|||
|
|
|||
|
if ( !XsCheckBufferSize(
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
FALSE // not in native format
|
|||
|
)) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQGetInfo: Buffer too small.\n" ));
|
|||
|
}
|
|||
|
Header->Status = NERR_BufTooSmall;
|
|||
|
|
|||
|
} else if ( bytesRequired > (DWORD)SmbGetUshort( ¶meters-> BufLen )) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQGetInfo: More data available.\n" ));
|
|||
|
}
|
|||
|
Header->Status = ERROR_MORE_DATA;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Pack the response data.
|
|||
|
//
|
|||
|
|
|||
|
Header->Converter = XsPackReturnData(
|
|||
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
StructureDesc,
|
|||
|
1
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
bytesNeeded = (WORD)bytesRequired;
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up the response parameters.
|
|||
|
//
|
|||
|
|
|||
|
SmbPutUshort( ¶meters->Needed, bytesNeeded );
|
|||
|
|
|||
|
//
|
|||
|
// Determine return buffer size.
|
|||
|
//
|
|||
|
|
|||
|
XsSetDataCount(
|
|||
|
¶meters->BufLen,
|
|||
|
StructureDesc, // desc (may be one we created on heap)
|
|||
|
Header->Converter,
|
|||
|
1,
|
|||
|
Header->Status
|
|||
|
);
|
|||
|
|
|||
|
(VOID) NetApiBufferFree( outBuffer );
|
|||
|
FREE_QUEUE_NAME( nativeQueueName );
|
|||
|
NetpMemoryFree( longDescriptor );
|
|||
|
NetpMemoryFree( longNativeDescriptor );
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintQGetInfo
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintQPause (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintQPause.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_Q_PAUSE parameters = Parameters;
|
|||
|
LPTSTR nativeQueueName = NULL; // Native parameters
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintQPause: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"name " FORMAT_LPSTR "\n",
|
|||
|
Header, parameters,
|
|||
|
SmbGetUlong( ¶meters->QueueName )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeQueueName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->QueueName )
|
|||
|
);
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeQueueName );
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintQPause(
|
|||
|
NULL,
|
|||
|
nativeQueueName
|
|||
|
);
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQPause: DosPrintQPause failed: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Nothing to return.
|
|||
|
//
|
|||
|
|
|||
|
Header->Status = (WORD)status;
|
|||
|
|
|||
|
FREE_QUEUE_NAME( nativeQueueName );
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintQPause
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintQPurge (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to DosPrintQPurge.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_Q_PURGE parameters = Parameters;
|
|||
|
LPTSTR nativeQueueName = NULL; // Native parameters
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
IF_DEBUG(PRINT) {
|
|||
|
NetpKdPrint(( "XsNetPrintQPurge: header at " FORMAT_LPVOID ", params at " FORMAT_LPVOID ", "
|
|||
|
"name " FORMAT_LPSTR "\n",
|
|||
|
Header, parameters,
|
|||
|
SmbGetUlong( ¶meters->QueueName )));
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeQueueName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->QueueName )
|
|||
|
);
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeQueueName );
|
|||
|
|
|||
|
//
|
|||
|
// Make the local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintQPurge(
|
|||
|
NULL,
|
|||
|
nativeQueueName
|
|||
|
);
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQPurge: DosPrintQPurge failed: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Nothing to return.
|
|||
|
//
|
|||
|
|
|||
|
Header->Status = (WORD)status;
|
|||
|
|
|||
|
|
|||
|
FREE_QUEUE_NAME( nativeQueueName );
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintQPurge
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
XsNetPrintQSetInfo (
|
|||
|
API_HANDLER_PARAMETERS
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine handles a call to NetPrintQSetInfo.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|||
|
XsTypes.h for details.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SPLERR status;
|
|||
|
|
|||
|
PXS_DOS_PRINT_Q_SET_INFO parameters = Parameters;
|
|||
|
LPTSTR nativeQueueName = NULL; // Native parameters
|
|||
|
LPVOID buffer = NULL;
|
|||
|
DWORD bytesRequired;
|
|||
|
|
|||
|
DWORD fieldIndex;
|
|||
|
LPDESC setInfoDesc; // Conversion variables
|
|||
|
LPDESC nativeSetInfoDesc;
|
|||
|
LPDESC nativeStructureDesc;
|
|||
|
PREPARE_CONVERT_QUEUE_NAME();
|
|||
|
|
|||
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|||
|
|
|||
|
try {
|
|||
|
//
|
|||
|
// Translate parameters, check for errors.
|
|||
|
//
|
|||
|
|
|||
|
if ( SmbGetUshort( ¶meters->Level ) != 1
|
|||
|
&& SmbGetUshort( ¶meters->Level ) != 3 ) {
|
|||
|
|
|||
|
Header->Status = ERROR_INVALID_LEVEL;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
XsConvertTextParameter(
|
|||
|
nativeQueueName,
|
|||
|
(LPSTR)XsSmbGetPointer( ¶meters->QueueName )
|
|||
|
);
|
|||
|
|
|||
|
CONVERT_QUEUE_NAME( nativeQueueName );
|
|||
|
|
|||
|
//
|
|||
|
// Determine descriptor strings based on level. Also translate the
|
|||
|
// parmnum value to a field index.
|
|||
|
// !!! - Right now, we don't check for parameters settable in downlevel
|
|||
|
// that are meaningless in the NT mapping layer.
|
|||
|
//
|
|||
|
|
|||
|
fieldIndex = (DWORD)SmbGetUshort( ¶meters->ParmNum );
|
|||
|
|
|||
|
switch ( SmbGetUshort( ¶meters->Level )) {
|
|||
|
|
|||
|
case 1:
|
|||
|
|
|||
|
StructureDesc = Desc16_printQ_1;
|
|||
|
nativeStructureDesc = Desc32_printQ_1;
|
|||
|
setInfoDesc = Desc16_printQ_1_setinfo;
|
|||
|
nativeSetInfoDesc = Desc32_printQ_1_setinfo;
|
|||
|
|
|||
|
if ( fieldIndex > 1 ) { // Account for pad field
|
|||
|
fieldIndex++;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case 3:
|
|||
|
|
|||
|
StructureDesc = Desc16_printQ_3;
|
|||
|
nativeStructureDesc = Desc32_printQ_3;
|
|||
|
setInfoDesc = Desc16_printQ_3_setinfo;
|
|||
|
nativeSetInfoDesc = Desc32_printQ_3_setinfo;
|
|||
|
if ( fieldIndex == PRQ_DESTINATIONS_PARMNUM ) {
|
|||
|
fieldIndex = (DWORD)-1; // No corresponding field
|
|||
|
} else if ( fieldIndex == PRQ_SEPARATOR_PARMNUM
|
|||
|
|| fieldIndex == PRQ_PROCESSOR_PARMNUM ) {
|
|||
|
fieldIndex++;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
status = XsConvertSetInfoBuffer(
|
|||
|
(LPBYTE)XsSmbGetPointer( ¶meters->Buffer ),
|
|||
|
SmbGetUshort( ¶meters->BufLen ),
|
|||
|
(WORD)fieldIndex,
|
|||
|
FALSE,
|
|||
|
TRUE,
|
|||
|
StructureDesc,
|
|||
|
nativeStructureDesc,
|
|||
|
setInfoDesc,
|
|||
|
nativeSetInfoDesc,
|
|||
|
(LPBYTE *)&buffer,
|
|||
|
&bytesRequired
|
|||
|
);
|
|||
|
|
|||
|
if ( status != NERR_Success ) {
|
|||
|
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQSetInfo: Problem with conversion: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Do the actual local call.
|
|||
|
//
|
|||
|
|
|||
|
status = DosPrintQSetInfo(
|
|||
|
NULL,
|
|||
|
nativeQueueName,
|
|||
|
SmbGetUshort( ¶meters->Level ),
|
|||
|
(LPBYTE)buffer,
|
|||
|
(WORD)bytesRequired,
|
|||
|
SmbGetUshort( ¶meters->ParmNum )
|
|||
|
);
|
|||
|
|
|||
|
if ( !XsPrintApiSuccess( status )) {
|
|||
|
IF_DEBUG(ERRORS) {
|
|||
|
NetpKdPrint(( "XsNetPrintQSetInfo: DosPrintQSetInfo failed: "
|
|||
|
FORMAT_API_STATUS "\n",
|
|||
|
status ));
|
|||
|
}
|
|||
|
Header->Status = (WORD)status;
|
|||
|
goto cleanup;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// No return information for this API.
|
|||
|
//
|
|||
|
|
|||
|
cleanup:
|
|||
|
;
|
|||
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|||
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If there is a native 32-bit buffer, free it.
|
|||
|
//
|
|||
|
|
|||
|
NetpMemoryFree( buffer );
|
|||
|
FREE_QUEUE_NAME( nativeQueueName );
|
|||
|
|
|||
|
return STATUS_SUCCESS;
|
|||
|
|
|||
|
} // XsNetPrintQSetInfo
|
|||
|
|