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
|
||
|