392 lines
8.8 KiB
C
392 lines
8.8 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
svccdevq.c
|
||
|
||
Abstract:
|
||
|
||
This module contains routines for supporting the character device
|
||
APIs in the server service, SrvNetCharDevQEnum, SrvNetCharDevQGetInfo,
|
||
SrvNetCharDevQPurge and SrvNetCharDevQSetInfo.
|
||
|
||
Author:
|
||
|
||
David Treadwell (davidtr) 31-Jan-1991
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "precomp.h"
|
||
#pragma hdrstop
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text( PAGE, SrvNetCharDevQEnum )
|
||
#pragma alloc_text( PAGE, SrvNetCharDevQPurge )
|
||
#pragma alloc_text( PAGE, SrvNetCharDevQSetInfo )
|
||
#if SRV_COMM_DEVICES
|
||
#pragma alloc_text( PAGE, FillCharDevQInfoBuffer )
|
||
#pragma alloc_text( PAGE, FilterCharDevQs )
|
||
#pragma alloc_text( PAGE, SizeCharDevQs )
|
||
#endif
|
||
#endif
|
||
|
||
//
|
||
// Forward declarations.
|
||
//
|
||
|
||
VOID
|
||
FillCharDevQInfoBuffer (
|
||
IN PSERVER_REQUEST_PACKET Srp,
|
||
IN PVOID Block,
|
||
IN OUT PVOID *FixedStructure,
|
||
IN LPTSTR *EndOfVariableData
|
||
);
|
||
|
||
BOOLEAN
|
||
FilterCharDevQs (
|
||
IN PSERVER_REQUEST_PACKET Srp,
|
||
IN PVOID Block
|
||
);
|
||
|
||
ULONG
|
||
SizeCharDevQs (
|
||
IN PSERVER_REQUEST_PACKET Srp,
|
||
IN PVOID Block
|
||
);
|
||
|
||
//
|
||
// Macros to determine the size a character device would take up at one of the
|
||
// levels of chardev information.
|
||
//
|
||
|
||
#define TOTAL_SIZE_OF_CHARDEVQ(level,share) \
|
||
( (level) == 0 ? sizeof(CHARDEVQ_INFO_0) + \
|
||
SrvLengthOfStringInApiBuffer(&(share)->ShareName) : \
|
||
sizeof(CHARDEVQ_INFO_1) + \
|
||
SrvLengthOfStringInApiBuffer(&(share)->ShareName) + \
|
||
SrvLengthOfStringInApiBuffer( \
|
||
&(share)->Type.CommDevice->DosPathName) )
|
||
|
||
#define FIXED_SIZE_OF_CHARDEVQ(level) \
|
||
( (level) == 0 ? sizeof(CHARDEVQ_INFO_0) : \
|
||
sizeof(CHARDEVQ_INFO_1) )
|
||
|
||
|
||
NTSTATUS
|
||
SrvNetCharDevQEnum (
|
||
IN PSERVER_REQUEST_PACKET Srp,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferLength
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine processes the NetCharDevQEnum API in the server.
|
||
|
||
Arguments:
|
||
|
||
Srp - a pointer to the server request packet that contains all
|
||
the information necessary to satisfy the request. This includes:
|
||
|
||
INPUT:
|
||
|
||
Level - level of information to return, 0, or 1.
|
||
|
||
Name1 - a username; the number of requests ahead of a specified
|
||
user is written to cq1_numahead in lm2.x; since NT doesn't
|
||
support queueing or pooling of comm devices, we only use
|
||
the existence of a username to know to set the field to
|
||
CHARDEVQ_NO_REQUESTS.
|
||
|
||
OUTPUT:
|
||
|
||
Parameters.Get.EntriesRead - the number of entries that fit in
|
||
the output buffer.
|
||
|
||
Parameters.Get.TotalEntries - the total number of entries that
|
||
would be returned with a large enough buffer.
|
||
|
||
Parameters.Get.TotalBytesNeeded - the buffer size that would be
|
||
required to hold all the entries.
|
||
|
||
Buffer - a pointer to the buffer for results.
|
||
|
||
BufferLength - the length of this buffer.
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - result of operation to return to the server service.
|
||
|
||
--*/
|
||
|
||
{
|
||
PAGED_CODE( );
|
||
|
||
#if SRV_COMM_DEVICES
|
||
return SrvShareEnumApiHandler(
|
||
Srp,
|
||
Buffer,
|
||
BufferLength,
|
||
FilterCharDevQs,
|
||
SizeCharDevQs,
|
||
FillCharDevQInfoBuffer
|
||
);
|
||
#else
|
||
Srp->Parameters.Get.EntriesRead = 0;
|
||
Srp->Parameters.Get.TotalEntries = 0;
|
||
Srp->Parameters.Get.TotalBytesNeeded = 0;
|
||
Srp->ErrorCode = NO_ERROR;
|
||
return STATUS_SUCCESS;
|
||
#endif
|
||
|
||
} // SrvNetCharDevQEnum
|
||
|
||
|
||
NTSTATUS
|
||
SrvNetCharDevQPurge (
|
||
IN PSERVER_REQUEST_PACKET Srp,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferLength
|
||
)
|
||
{
|
||
PAGED_CODE( );
|
||
|
||
Srp, Buffer, BufferLength;
|
||
return STATUS_NOT_IMPLEMENTED;
|
||
|
||
} // SrvNetCharDevQPurge
|
||
|
||
|
||
NTSTATUS
|
||
SrvNetCharDevQSetInfo (
|
||
IN PSERVER_REQUEST_PACKET Srp,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferLength
|
||
)
|
||
{
|
||
PAGED_CODE( );
|
||
|
||
Srp, Buffer, BufferLength;
|
||
return STATUS_NOT_IMPLEMENTED;
|
||
|
||
} // SrvNetCharDevQSetInfo
|
||
|
||
|
||
#if SRV_COMM_DEVICES
|
||
VOID
|
||
FillCharDevQInfoBuffer (
|
||
IN PSERVER_REQUEST_PACKET Srp,
|
||
IN PVOID Block,
|
||
IN OUT PVOID *FixedStructure,
|
||
IN LPTSTR *EndOfVariableData
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine puts a single fixed file structure and associated
|
||
variable data, into a buffer. Fixed data goes at the beginning of
|
||
the buffer, variable data at the end.
|
||
|
||
*** This routine assumes that ALL the data, both fixed and variable,
|
||
will fit.
|
||
|
||
Arguments:
|
||
|
||
Srp - a pointer to the SRP for the operation. Only the Level
|
||
field is used.
|
||
|
||
Block - the comm share from which to get information.
|
||
|
||
FixedStructure - where the in the buffer to place the fixed structure.
|
||
This pointer is updated to point to the next available
|
||
position for a fixed structure.
|
||
|
||
EndOfVariableData - the last position on the buffer that variable
|
||
data for this structure can occupy. The actual variable data
|
||
is written before this position as long as it won't overwrite
|
||
fixed structures. It is would overwrite fixed structures, it
|
||
is not written.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
PCHARDEVQ_INFO_1 cq1 = *FixedStructure;
|
||
PSHARE share = Block;
|
||
|
||
PAGED_CODE( );
|
||
|
||
//
|
||
// Update FixedStructure to point to the next structure location.
|
||
//
|
||
|
||
*FixedStructure = (PCHAR)*FixedStructure +
|
||
FIXED_SIZE_OF_CHARDEVQ( Srp->Level );
|
||
ASSERT( (ULONG)*EndOfVariableData >= (ULONG)*FixedStructure );
|
||
|
||
//
|
||
// Case on the level to fill in the fixed structure appropriately.
|
||
// We fill in actual pointers in the output structure. This is
|
||
// possible because we are in the server FSD, hence the server
|
||
// service's process and address space.
|
||
//
|
||
// *** Using the switch statement in this fashion relies on the fact
|
||
// that the first fields on the different chardev structures are
|
||
// identical (with the exception of level 10, which is handled
|
||
// separately).
|
||
//
|
||
|
||
switch( Srp->Level ) {
|
||
|
||
case 1:
|
||
|
||
//
|
||
// Fill in level-1 fields of char dev Q structure.
|
||
//
|
||
|
||
// !!! we could store the priority in the share block and
|
||
// return it here, even though it has no impact on the way
|
||
// things operate. Does this make sense? Would it be
|
||
// confusing?
|
||
|
||
cq1->cq1_priority = 0;
|
||
|
||
SrvCopyUnicodeStringToBuffer(
|
||
&share->Type.CommDevice->DosPathName,
|
||
*FixedStructure,
|
||
EndOfVariableData,
|
||
&cq1->cq1_devs
|
||
);
|
||
|
||
cq1->cq1_numusers = 0;
|
||
|
||
if ( Srp->Name1.Buffer == NULL ) {
|
||
cq1->cq1_numahead = 0;
|
||
} else {
|
||
cq1->cq1_numahead = (ULONG)CHARDEVQ_NO_REQUESTS;
|
||
}
|
||
|
||
// *** lack of break is intentional!
|
||
|
||
case 0:
|
||
|
||
//
|
||
// Set up the share name in the output buffer.
|
||
//
|
||
|
||
SrvCopyUnicodeStringToBuffer(
|
||
&share->ShareName,
|
||
*FixedStructure,
|
||
EndOfVariableData,
|
||
&cq1->cq1_dev
|
||
);
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
//
|
||
// This should never happen. The server service should have
|
||
// checked for an invalid level.
|
||
//
|
||
|
||
INTERNAL_ERROR(
|
||
ERROR_LEVEL_UNEXPECTED,
|
||
"FillCharDevInfoBuffer: invalid level number: %ld",
|
||
Srp->Level,
|
||
NULL
|
||
);
|
||
|
||
SrvLogInvalidSmb( NULL );
|
||
}
|
||
|
||
return;
|
||
|
||
} // FillCharDevQInfoBuffer
|
||
|
||
|
||
BOOLEAN
|
||
FilterCharDevQs (
|
||
IN PSERVER_REQUEST_PACKET Srp,
|
||
IN PVOID Block
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is intended to be called by SrvEnumApiHandler to check
|
||
whether a particular share is a comm queue.
|
||
|
||
Arguments:
|
||
|
||
Srp - a pointer to the SRP for the operation.
|
||
|
||
Block - a pointer to the share to check.
|
||
|
||
Return Value:
|
||
|
||
TRUE if the block should be placed in the output buffer, FALSE
|
||
if it should be passed over.
|
||
|
||
--*/
|
||
|
||
{
|
||
PSHARE share = Block;
|
||
|
||
PAGED_CODE( );
|
||
|
||
return (BOOLEAN)( share->ShareType == ShareTypeComm );
|
||
|
||
} // FilterCharDevQs
|
||
|
||
|
||
ULONG
|
||
SizeCharDevQs (
|
||
IN PSERVER_REQUEST_PACKET Srp,
|
||
IN PVOID Block
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine returns the size the passed-in comm share would take
|
||
up in an API output buffer.
|
||
|
||
Arguments:
|
||
|
||
Srp - a pointer to the SRP for the operation. Only the level
|
||
parameter is used.
|
||
|
||
Block - a pointer to the comm device to size.
|
||
|
||
Return Value:
|
||
|
||
ULONG - The number of bytes the comm device would take up in the
|
||
output buffer.
|
||
|
||
--*/
|
||
|
||
{
|
||
PSHARE share = Block;
|
||
|
||
PAGED_CODE( );
|
||
|
||
return TOTAL_SIZE_OF_CHARDEVQ( Srp->Level, share );
|
||
|
||
} // SizeCharDevQs
|
||
#endif // SRV_COMM_DEVICES
|
||
|