|
|
/*++
Copyright (c) 1991-1992 Microsoft Corporation
Module Name:
ApiSrv.c
Abstract:
This module contains individual API handlers for the NetServer APIs.
SUPPORTED : NetServerDiskEnum, NetServerEnum2, NetServerGetInfo, NetServerSetInfo.
SEE ALSO : NetServerAuthenticate, NetServerPasswordSet, NetServerReqChallenge - in ApiLogon.c.
Author:
Shanku Niyogi (w-shanku) 25-Feb-1991
Revision History:
--*/
#include "XactSrvP.h"
#include <lmbrowsr.h> // Definition of I_BrowserServerEnum
//
// Declaration of descriptor strings.
//
STATIC const LPDESC Desc16_server_info_0 = REM16_server_info_0; STATIC const LPDESC Desc32_server_info_0 = REM32_server_info_0; STATIC const LPDESC Desc16_server_info_1 = REM16_server_info_1; STATIC const LPDESC Desc32_server_info_1 = REM32_server_info_1; STATIC const LPDESC Desc16_server_info_2 = REM16_server_info_2; STATIC const LPDESC Desc32_server_info_2 = REM32_server_info_2; STATIC const LPDESC Desc16_server_info_3 = REM16_server_info_3; STATIC const LPDESC Desc32_server_info_3 = REM32_server_info_3;
NTSTATUS XsNetServerDiskEnum ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetServerDiskEnum.
Arguments:
API_HANDLER_PARAMETERS - information about the API call. See XsTypes.h for details.
Return Value:
NTSTATUS - STATUS_SUCCESS or reason for failure.
--*/
{ NET_API_STATUS status;
PXS_NET_SERVER_DISK_ENUM parameters = Parameters; LPBYTE outBuffer = NULL; // Native parameters
DWORD entriesRead; DWORD totalEntries = 0; DWORD entriesFilled = 0; // Conversion variables
DWORD bufferLength;
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
try { //
// Check for errors.
//
if ( SmbGetUshort( ¶meters->Level ) != 0 ) {
Header->Status = ERROR_INVALID_LEVEL; goto cleanup;
}
//
// Make the local call.
//
bufferLength = (DWORD)SmbGetUshort( ¶meters->BufLen );
status = NetServerDiskEnum( NULL, (DWORD)SmbGetUshort( ¶meters->Level ), (LPBYTE *)&outBuffer, XsNativeBufferSize( bufferLength ), &entriesRead, &totalEntries, NULL );
if ( !XsApiSuccess( status )) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetServer: NetServerDiskEnum failed: " "%X\n", status )); }
Header->Status = (WORD)status; goto cleanup; }
//
// Calculate how many entries will fit in 16-bit buffer;
//
if ( bufferLength > 0 ) { DWORD elementSize;
elementSize = RapStructureSize( StructureDesc, Response, FALSE );
if (elementSize != 0) { entriesFilled = ( bufferLength - 1 ) / elementSize; } }
if ( entriesFilled < entriesRead ) {
status = ERROR_MORE_DATA; } else {
entriesFilled = entriesRead; status = NERR_Success; }
//
// Copy native buffer to 16-bit buffer, converting Unicode to Ansi
// if necessary.
//
if ( bufferLength > 0 ) {
DWORD i; LPTSTR entryIn = (LPTSTR)outBuffer; LPSTR entryOut = (LPSTR)XsSmbGetPointer( ¶meters->Buffer );
for ( i = 0; i < entriesFilled; i++ ) {
NetpCopyWStrToStrDBCS( entryOut, entryIn ); entryOut += ( strlen( entryOut ) + 1 ); entryIn += ( STRLEN( entryIn ) + 1 );
} strcpy( entryOut, "" ); }
Header->Status = (WORD)status;
cleanup: ; } except( EXCEPTION_EXECUTE_HANDLER ) { Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() ); }
//
// Put return data into fields.
//
SmbPutUshort( ¶meters->EntriesRead, (WORD)entriesFilled ); SmbPutUshort( ¶meters->TotalAvail, (WORD)totalEntries );
return STATUS_SUCCESS;
} // XsNetServerDiskEnum
NTSTATUS XsNetServerEnum2 ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetServerEnum.
Arguments:
API_HANDLER_PARAMETERS - information about the API call. See XsTypes.h for details.
Transport - The name of the transport provided to the API.
Return Value:
NTSTATUS - STATUS_SUCCESS or reason for failure.
--*/
{ NET_API_STATUS status = NERR_Success;
PXS_NET_SERVER_ENUM_2 parameters = Parameters; LPTSTR nativeDomain = NULL; // Native parameters
LPVOID outBuffer= NULL; DWORD entriesRead; DWORD totalEntries; LPTSTR clientTransportName = NULL; LPTSTR clientName = NULL;
DWORD entriesFilled = 0; // Conversion variables
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
IF_DEBUG(SERVER) { NetpKdPrint(( "XsNetServerEnum2: header at %lx, params at %lx, " "level %ld, buf size %ld\n", Header, parameters, SmbGetUshort( ¶meters->Level ), SmbGetUshort( ¶meters->BufLen ))); }
try { //
// Translate parameters, check for errors.
//
if ( XsWordParamOutOfRange( parameters->Level, 0, 1 )) {
Header->Status = ERROR_INVALID_LEVEL; goto cleanup; }
XsConvertTextParameter( nativeDomain, (LPSTR)XsSmbGetPointer( ¶meters->Domain ) );
clientTransportName = Header->ClientTransportName;
clientName = Header->ClientMachineName;
//
// Get the actual server information from the local 32-bit call. The
// native level is 100 or 101.
//
if (clientTransportName == NULL) { status = NetServerEnum( NULL, 100 + (DWORD)SmbGetUshort( ¶meters->Level ), (LPBYTE *)&outBuffer, XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen )), &entriesRead, &totalEntries, SmbGetUlong( ¶meters->ServerType ), nativeDomain, NULL );
if ( !XsApiSuccess( status ) ) { IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetServerEnum2: NetServerEnum failed: %X\n", status )); } Header->Status = (WORD)status; goto cleanup; }
Header->Status = XsConvertServerEnumBuffer( outBuffer, entriesRead, &totalEntries, SmbGetUshort( ¶meters->Level ), (LPVOID)XsSmbGetPointer( ¶meters->Buffer ), SmbGetUshort( ¶meters->BufLen ), &entriesFilled, &Header->Converter);
} else {
Header->Status = I_BrowserServerEnumForXactsrv( clientTransportName, clientName,
100 + SmbGetUshort( ¶meters->Level ), SmbGetUshort( ¶meters->Level ),
(PVOID)XsSmbGetPointer( ¶meters->Buffer ), SmbGetUshort( ¶meters->BufLen ), XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen ) ),
&entriesFilled, &totalEntries,
SmbGetUlong( ¶meters->ServerType ), nativeDomain, NULL,
&Header->Converter
);
if (!XsApiSuccess( Header->Status )) { IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetServerEnum2: I_BrowserServerEnum failed: %d\n", Header->Status)); } goto cleanup; } }
if ( entriesFilled == 0 ) { SmbPutUshort( ¶meters->BufLen, 0 ); }
//
// Set up the response parameters.
//
SmbPutUshort( ¶meters->EntriesRead, (WORD)entriesFilled ); SmbPutUshort( ¶meters->TotalAvail, (WORD)totalEntries );
cleanup: ; } except( EXCEPTION_EXECUTE_HANDLER ) { Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() ); }
if ( outBuffer != NULL ) { NetApiBufferFree( outBuffer ); } NetpMemoryFree( nativeDomain );
//
// Determine return buffer size.
//
XsSetDataCount( ¶meters->BufLen, SmbGetUshort( ¶meters->Level ) == 0 ? Desc16_server_info_0 : Desc16_server_info_1, Header->Converter, entriesFilled, Header->Status );
return STATUS_SUCCESS;
} // XsNetServerEnum2
NTSTATUS XsNetServerEnum3 ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetServerEnum.
Arguments:
API_HANDLER_PARAMETERS - information about the API call. See XsTypes.h for details.
Transport - The name of the transport provided to the API.
Return Value:
NTSTATUS - STATUS_SUCCESS or reason for failure.
--*/
{ NET_API_STATUS status = NERR_Success;
PXS_NET_SERVER_ENUM_3 parameters = Parameters; LPTSTR nativeDomain = NULL; // Native parameters
LPTSTR nativeFirstNameToReturn = NULL; // Native parameters
LPVOID outBuffer= NULL; DWORD entriesRead; DWORD totalEntries; LPTSTR clientTransportName = NULL; LPTSTR clientName = NULL;
DWORD entriesFilled = 0; // Conversion variables
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
IF_DEBUG(SERVER) { NetpKdPrint(( "XsNetServerEnum3: header at %lx, params at %lx, " "level %ld, buf size %ld\n", Header, parameters, SmbGetUshort( ¶meters->Level ), SmbGetUshort( ¶meters->BufLen ))); }
try { //
// Translate parameters, check for errors.
//
if ( XsWordParamOutOfRange( parameters->Level, 0, 1 )) {
Header->Status = ERROR_INVALID_LEVEL; goto cleanup; }
XsConvertTextParameter( nativeDomain, (LPSTR)XsSmbGetPointer( ¶meters->Domain ) );
XsConvertTextParameter( nativeFirstNameToReturn, (LPSTR)XsSmbGetPointer( ¶meters->FirstNameToReturn ) );
clientTransportName = Header->ClientTransportName;
clientName = Header->ClientMachineName;
//
// Get the actual server information from the local 32-bit call. The
// native level is 100 or 101.
//
if (clientTransportName == NULL) { status = NetServerEnumEx( NULL, 100 + (DWORD)SmbGetUshort( ¶meters->Level ), (LPBYTE *)&outBuffer, XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen )), &entriesRead, &totalEntries, SmbGetUlong( ¶meters->ServerType ), nativeDomain, nativeFirstNameToReturn );
if ( !XsApiSuccess( status ) ) { IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetServerEnum3: NetServerEnum failed: %X\n", status )); } Header->Status = (WORD)status; goto cleanup; }
Header->Status = XsConvertServerEnumBuffer( outBuffer, entriesRead, &totalEntries, SmbGetUshort( ¶meters->Level ), (LPVOID)XsSmbGetPointer( ¶meters->Buffer ), SmbGetUshort( ¶meters->BufLen ), &entriesFilled, &Header->Converter);
} else {
Header->Status = I_BrowserServerEnumForXactsrv( clientTransportName, clientName,
100 + SmbGetUshort( ¶meters->Level ), SmbGetUshort( ¶meters->Level ),
(PVOID)XsSmbGetPointer( ¶meters->Buffer ), SmbGetUshort( ¶meters->BufLen ), XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen ) ),
&entriesFilled, &totalEntries,
SmbGetUlong( ¶meters->ServerType ), nativeDomain, nativeFirstNameToReturn,
&Header->Converter
);
if (!XsApiSuccess( Header->Status )) { IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetServerEnum3: I_BrowserServerEnum failed: %d\n", Header->Status)); } goto cleanup; } }
if ( entriesFilled == 0 ) { SmbPutUshort( ¶meters->BufLen, 0 ); }
//
// Set up the response parameters.
//
SmbPutUshort( ¶meters->EntriesRead, (WORD)entriesFilled ); SmbPutUshort( ¶meters->TotalAvail, (WORD)totalEntries );
cleanup: ; } except( EXCEPTION_EXECUTE_HANDLER ) { Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() ); }
if ( outBuffer != NULL ) { NetApiBufferFree( outBuffer ); } NetpMemoryFree( nativeDomain ); NetpMemoryFree( nativeFirstNameToReturn );
//
// Determine return buffer size.
//
XsSetDataCount( ¶meters->BufLen, SmbGetUshort( ¶meters->Level ) == 0 ? Desc16_server_info_0 : Desc16_server_info_1, Header->Converter, entriesFilled, Header->Status );
return STATUS_SUCCESS;
} // XsNetServerEnum3
USHORT XsConvertServerEnumBuffer( IN LPVOID ServerEnumBuffer, IN DWORD EntriesRead, IN OUT PDWORD TotalEntries, IN USHORT Level, IN LPBYTE ClientBuffer, IN USHORT BufferLength, OUT PDWORD EntriesFilled, OUT PUSHORT Converter ) /*++
Routine Description:
This routine converts an NT server info array into a down level RAP server info buffer.
Arguments:
IN LPVOID ServerEnumBuffer - Buffer with NT server info. IN DWORD EntriesRead - Number of entries in buffer. IN OUT PDWORD TotalEntries - Total Number of entries. IN USHORT Level - Downlevel information Level (0 or 1). IN LPBYTE ClientBuffer - Pointer to 16 bit client side buffer. IN USHORT BufferLength - Size of client buffer. OUT PDWORD EntriesFilled - Number of entries converted into client buffer. OUT PUSHORT Converter - Converter used by client side to convert back.
Return Value:
USHORT - NERR_Success or reason for failure (16 bit DOS error).
--*/
{ USHORT status = NERR_Success; DWORD invalidEntries; LPDESC nativeStructureDesc; DWORD bytesRequired = 0; PCHAR StructureDesc;
IF_DEBUG(SERVER) { NetpKdPrint(( "XsConvertServerEnumBuffer: received %ld entries at %lx\n", EntriesRead, ServerEnumBuffer )); }
//
// Use the requested level to determine the format of the
// data structure.
//
switch ( Level ) {
case 0:
StructureDesc = Desc16_server_info_0; nativeStructureDesc = Desc32_server_info_0; break;
case 1:
StructureDesc = Desc16_server_info_1; nativeStructureDesc = Desc32_server_info_1; break;
}
//
// Do the actual conversion from the 32-bit structures to 16-bit
// structures.
//
XsFillEnumBuffer( ServerEnumBuffer, EntriesRead, nativeStructureDesc, ClientBuffer, ClientBuffer, BufferLength, StructureDesc, NULL, // verify function
&bytesRequired, EntriesFilled, &invalidEntries );
IF_DEBUG(SERVER) { NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR," " Entries %ld of %ld\n", ServerEnumBuffer, ClientBuffer , bytesRequired, *EntriesFilled, *TotalEntries )); }
//
// If there are any invalid entries, subtract this from the
// number of total entries to avoid the case where the client
// keeps bugging us for more data.
//
if ( invalidEntries > 0) { (*TotalEntries) -= invalidEntries; #if DBG
IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetServerEnum: %d invalid entries removed." " Total entries now %d, entries filled %d.\n", invalidEntries, *TotalEntries, *EntriesFilled )); } #endif
}
//
// If all the entries could not be filled, return ERROR_MORE_DATA,
// The data needs to be packed so that we don't send too much
// useless data.
//
if ( (*EntriesFilled < *TotalEntries) || (bytesRequired > BufferLength) ) {
status = ERROR_MORE_DATA; }
*Converter = XsPackReturnData( ClientBuffer, BufferLength, StructureDesc, *EntriesFilled );
return status; } // XsConvertServerEnumBuffer
NTSTATUS XsNetServerGetInfo ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetServerGetInfo. Since NT only provides levels 100-102, this routine manually fills in default values for other fields. Because of this, the handling in this procedure is different from other Xs...GetInfo handlers.
Arguments:
API_HANDLER_PARAMETERS - information about the API call. See XsTypes.h for details.
Return Value:
NTSTATUS - STATUS_SUCCESS or reason for failure.
--*/
{ NET_API_STATUS status;
PXS_NET_SERVER_GET_INFO parameters = Parameters; DWORD localLevel; // Native parameters
PSERVER_INFO_102 nativeStruct = NULL; PSERVER_INFO_502 secondaryNativeStruct = NULL;
LPBYTE stringLocation = NULL; // Conversion variables
DWORD bytesRequired = 0; DWORD sizeOfFixedStructure; LPDESC nativeStructureDesc; PSERVER_16_INFO_3 returnStruct; BOOLEAN bufferTooSmall = FALSE; LPWSTR ServerName = NULL; UCHAR serverNameBuf[ 2 + NETBIOS_NAME_LEN + 1 ]; PUCHAR p;
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
IF_DEBUG(SERVER) { NetpKdPrint(( "XsNetServerGetInfo: header at %lx, " "params at %lx, level %ld\n", Header, parameters, SmbGetUshort( ¶meters->Level ) )); }
try { //
// Check for errors.
//
if ( XsWordParamOutOfRange( parameters->Level, 0, 3 ) ) {
Header->Status = ERROR_INVALID_LEVEL; goto cleanup; }
//
// Use the 16-bit level number to determine the NT level number and the
// native descriptor string.
//
switch ( SmbGetUshort( ¶meters->Level ) ) {
case 0:
nativeStructureDesc = Desc32_server_info_0; StructureDesc = Desc16_server_info_0; localLevel = 100; break;
case 1:
nativeStructureDesc = Desc32_server_info_1; StructureDesc = Desc16_server_info_1; localLevel = 101; break;
case 2:
nativeStructureDesc = Desc32_server_info_2; StructureDesc = Desc16_server_info_2; localLevel = 102; break;
case 3:
nativeStructureDesc = Desc32_server_info_3; StructureDesc = Desc16_server_info_3; localLevel = 102; break;
}
//
// If the buffer is not big enough, we have to continue doing the
// Rap Conversion so that we can return the right buffer size to
// the caller.
//
sizeOfFixedStructure = RapStructureSize( StructureDesc, Response, FALSE );
if ( SmbGetUshort( ¶meters->BufLen ) < sizeOfFixedStructure ) {
IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetServerGetInfo: Buffer too small.\n" )); }
bufferTooSmall = TRUE; }
serverNameBuf[0] = serverNameBuf[1] = '\\'; memcpy( &serverNameBuf[2], Header->ServerName, NETBIOS_NAME_LEN ); for( p = &serverNameBuf[ NETBIOS_NAME_LEN + 1 ]; p > serverNameBuf && *p == ' '; p-- ) ; *(p+1) = '\0';
ServerName = XsDupStrToWStr( serverNameBuf );
if( ServerName == NULL ) { Header->Status = NERR_NoRoom; goto cleanup; }
//
// Do the actual local call.
//
status = NetServerGetInfo( ServerName, localLevel, (LPBYTE *)&nativeStruct );
if ( !XsApiSuccess( status )) { IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetServerGetInfo: NetServerGetInfo failed: " "%X\n", status )); } Header->Status = (WORD)status; goto cleanup;
}
//
// For levels 2 and 3 (native level 102), additional data is
// required from native level 502. Do this call.
//
if ( localLevel == 102 ) {
status = NetServerGetInfo( ServerName, 502, (LPBYTE *)&secondaryNativeStruct );
if ( !XsApiSuccess( status )) { IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetServerGetInfo: NetServerGetInfo failed: " "%X\n", status )); } Header->Status = (WORD)status; goto cleanup;
} }
//
// Convert the structure returned by the 32-bit call to a 16-bit
// structure. For levels 0 and 1, there is no additional work
// involved after this step, so ConvertSingleEntry can store the
// variable data in the structure. This is indicated by passing
// the end of the entire buffer in stringLocation. For levels 2 and 3,
// the manual filling scheme requires that variable data not be entered
// at this stage, so stringLocation is set to the end of the fixed
// structure.
//
stringLocation = (LPBYTE)XsSmbGetPointer( ¶meters->Buffer );
if ( !bufferTooSmall ) { stringLocation += ( localLevel == 102 ) ? sizeOfFixedStructure: SmbGetUshort( ¶meters->BufLen ); }
status = RapConvertSingleEntry( (LPBYTE)nativeStruct, nativeStructureDesc, FALSE, (LPBYTE)XsSmbGetPointer( ¶meters->Buffer ), (LPBYTE)XsSmbGetPointer( ¶meters->Buffer ), StructureDesc, TRUE, &stringLocation, &bytesRequired, Response, NativeToRap );
if ( status != NERR_Success ) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetServerGetInfo: RapConvertSingleEntry failed: " "%X\n", status )); }
Header->Status = NERR_InternalError; goto cleanup; }
//
// For levels 2 and 3, the number of bytes required is, in fact, more than
// that returned by ConvertSingleEntry. We also need space for the
// string defaults.
//
if ( localLevel == 102 ) {
//
// The number we get from rap includes some string lengths.
// We only need the fixed length since we are manually adding
// those ourselves.
//
bytesRequired = sizeOfFixedStructure; }
switch ( SmbGetUshort( ¶meters->Level ) ) {
case 3:
bytesRequired += NetpUnicodeToDBCSLen( DEF16_sv_autopath ) + 1;
case 2:
bytesRequired += ( NetpUnicodeToDBCSLen( DEF16_sv_alerts ) + NetpUnicodeToDBCSLen( DEF16_sv_srvheuristics ) + NetpUnicodeToDBCSLen( nativeStruct->sv102_comment ) + NetpUnicodeToDBCSLen( nativeStruct->sv102_userpath ) + 4 ); }
//
// We don't have room even for the fixed data, abort.
//
if ( bufferTooSmall ) {
Header->Status = NERR_BufTooSmall; goto cleanup; }
//
// For levels 2 and 3, fill in the default values in the fixed structure
// manually.
//
returnStruct = (PSERVER_16_INFO_3)XsSmbGetPointer( ¶meters->Buffer );
switch ( SmbGetUshort( ¶meters->Level ) ) {
case 3:
SmbPutUlong( &returnStruct->sv3_auditedevents, DEF16_sv_auditedevents ); SmbPutUshort( &returnStruct->sv3_autoprofile, DEF16_sv_autoprofile );
case 2:
SmbPutUlong( &returnStruct->sv3_ulist_mtime, DEF16_sv_ulist_mtime ); SmbPutUlong( &returnStruct->sv3_alist_mtime, DEF16_sv_alist_mtime ); SmbPutUlong( &returnStruct->sv3_glist_mtime, DEF16_sv_glist_mtime ); SmbPutUshort( &returnStruct->sv3_security, DEF16_sv_security ); SmbPutUshort( &returnStruct->sv3_auditing, DEF16_sv_auditing ); SmbPutUshort( &returnStruct->sv3_numadmin, (USHORT)DEF16_sv_numadmin ); SmbPutUshort( &returnStruct->sv3_lanmask, DEF16_sv_lanmask ); NetpCopyTStrToStr( returnStruct->sv3_guestacct, DEF16_sv_guestacct ); SmbPutUshort( &returnStruct->sv3_chdevs, DEF16_sv_chdevs ); SmbPutUshort( &returnStruct->sv3_chdevq, DEF16_sv_chdevq ); SmbPutUshort( &returnStruct->sv3_chdevjobs, DEF16_sv_chdevjobs ); SmbPutUshort( &returnStruct->sv3_connections, DEF16_sv_connections ); SmbPutUshort( &returnStruct->sv3_shares, DEF16_sv_shares ); SmbPutUshort( &returnStruct->sv3_openfiles, DEF16_sv_openfiles ); SmbPutUshort( &returnStruct->sv3_sessopens, (WORD)secondaryNativeStruct->sv502_sessopens ); SmbPutUshort( &returnStruct->sv3_sessvcs, (WORD)secondaryNativeStruct->sv502_sessvcs ); SmbPutUshort( &returnStruct->sv3_sessreqs, DEF16_sv_sessreqs ); SmbPutUshort( &returnStruct->sv3_opensearch, (WORD)secondaryNativeStruct->sv502_opensearch ); SmbPutUshort( &returnStruct->sv3_activelocks, DEF16_sv_activelocks ); SmbPutUshort( &returnStruct->sv3_numreqbuf, DEF16_sv_numreqbuf ); SmbPutUshort( &returnStruct->sv3_sizreqbuf, (WORD)secondaryNativeStruct->sv502_sizreqbuf ); SmbPutUshort( &returnStruct->sv3_numbigbuf, DEF16_sv_numbigbuf ); SmbPutUshort( &returnStruct->sv3_numfiletasks, DEF16_sv_numfiletasks ); SmbPutUshort( &returnStruct->sv3_alertsched, DEF16_sv_alertsched ); SmbPutUshort( &returnStruct->sv3_erroralert, DEF16_sv_erroralert ); SmbPutUshort( &returnStruct->sv3_logonalert, DEF16_sv_logonalert ); SmbPutUshort( &returnStruct->sv3_accessalert, DEF16_sv_accessalert ); SmbPutUshort( &returnStruct->sv3_diskalert, DEF16_sv_diskalert ); SmbPutUshort( &returnStruct->sv3_netioalert, DEF16_sv_netioalert ); SmbPutUshort( &returnStruct->sv3_maxauditsz, DEF16_sv_maxauditsz ); }
//
// Now check if there is room for the variable data. If there isn't,
// set return status and quit. This is done here to prevent code
// below from overwriting the buffer.
//
if ( bytesRequired > (DWORD)SmbGetUshort( ¶meters-> BufLen )) {
IF_DEBUG(ERRORS) { NetpKdPrint(( "NetServerGetInfo: More data available.\n" )); } Header->Status = ERROR_MORE_DATA; goto cleanup; }
//
// For levels 2 and 3, fill in the variable data manually. The variable
// data is filled in immediately following the fixed structures. For
// other levels, pack the response data as normal.
stringLocation = (LPBYTE)( XsSmbGetPointer( ¶meters->Buffer ) + sizeOfFixedStructure );
switch ( SmbGetUshort( ¶meters->Level )) {
case 3:
XsAddVarString( stringLocation, DEF16_sv_autopath, &returnStruct->sv3_autopath, returnStruct );
case 2:
XsAddVarString( stringLocation, DEF16_sv_srvheuristics, &returnStruct->sv3_srvheuristics, returnStruct );
XsAddVarString( stringLocation, nativeStruct->sv102_userpath, &returnStruct->sv3_userpath, returnStruct );
XsAddVarString( stringLocation, DEF16_sv_alerts, &returnStruct->sv3_alerts, returnStruct );
XsAddVarString( stringLocation, nativeStruct->sv102_comment, &returnStruct->sv3_comment, returnStruct );
break;
default:
//
// Pack the response data.
//
Header->Converter = XsPackReturnData( (LPVOID)XsSmbGetPointer( ¶meters->Buffer ), SmbGetUshort( ¶meters->BufLen ), StructureDesc, 1 );
break;
}
cleanup: ; } except( EXCEPTION_EXECUTE_HANDLER ) { Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() ); }
if( ServerName != NULL ) { NetpMemoryFree( ServerName ); }
//
// Set up the response parameters.
//
SmbPutUshort( ¶meters->TotalAvail, (WORD)bytesRequired );
NetApiBufferFree( nativeStruct ); NetApiBufferFree( secondaryNativeStruct );
//
// Determine return buffer size.
//
XsSetDataCount( ¶meters->BufLen, StructureDesc, Header->Converter, 1, Header->Status );
return STATUS_SUCCESS;
} // XsNetServerGetInfo
NTSTATUS XsNetServerSetInfo ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetServerSetInfo.
Arguments:
API_HANDLER_PARAMETERS - information about the API call. See XsTypes.h for details.
Return Value:
NTSTATUS - STATUS_SUCCESS or reason for failure.
--*/
{
NET_API_STATUS status;
PXS_NET_SERVER_SET_INFO parameters = Parameters; LPVOID buffer = NULL; // Native parameters
LPBYTE stringLocation = NULL; // Conversion variables
DWORD bytesRequired = 0; LPDESC nativeStructureDesc; DWORD data; DWORD bufferSize; DWORD level; LPTSTR comment = NULL;
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
try { //
// Check for errors.
//
if ( XsWordParamOutOfRange( parameters->Level, 1, 3 )) {
Header->Status = ERROR_INVALID_LEVEL; goto cleanup; }
//
// Processing of this API depends on the value of the ParmNum
// parameter.
//
switch ( SmbGetUshort( ¶meters->ParmNum )) {
case PARMNUM_ALL:
//
// PARMNUM_ALL.
//
// The structure descriptor given is OK; determine native descriptor
// (and expected minimum buffer length) from level. The buffer then
// needs to be converted into a native 32-bit buffer.
//
switch( SmbGetUshort( ¶meters->Level )) {
case 1:
StructureDesc = Desc16_server_info_1; nativeStructureDesc = Desc32_server_info_1; break;
case 2:
StructureDesc = Desc16_server_info_2; nativeStructureDesc = Desc32_server_info_2; break;
case 3:
StructureDesc = Desc16_server_info_3; nativeStructureDesc = Desc32_server_info_3; break;
}
if ( !XsCheckBufferSize( SmbGetUshort( ¶meters->BufLen ), StructureDesc, FALSE // native format
)) {
Header->Status = NERR_BufTooSmall; goto cleanup; }
//
// Find out how big a 32-bit data buffer we need.
//
bufferSize = XsBytesForConvertedStructure( (LPBYTE)XsSmbGetPointer( ¶meters->Buffer ), StructureDesc, nativeStructureDesc, RapToNative, TRUE );
//
// Allocate enough memory to hold the converted native buffer.
//
buffer = NetpMemoryAllocate( bufferSize );
if ( buffer == NULL ) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetServerSetInfo: failed to create buffer" )); } Header->Status = NERR_NoRoom; goto cleanup;
}
IF_DEBUG(SERVER) { NetpKdPrint(( "XsNetServerSetInfo: buffer of %ld bytes at %lx\n", bufferSize, buffer )); }
//
// Convert 16-bit data into 32-bit data and store it in the native
// buffer.
//
stringLocation = (LPBYTE)buffer + bufferSize; bytesRequired = 0;
status = RapConvertSingleEntry( (LPBYTE)XsSmbGetPointer( ¶meters->Buffer ), StructureDesc, TRUE, buffer, buffer, nativeStructureDesc, FALSE, &stringLocation, &bytesRequired, Response, RapToNative );
if ( status != NERR_Success ) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetServerSetInfo: RapConvertSingleEntry " "failed: %X\n", status )); }
Header->Status = NERR_InternalError; goto cleanup; }
break;
case SV_COMMENT_PARMNUM:
//
// SV_COMMENT_PARMNUM.
//
// The structure descriptor given is meaningless. The data is actually
// a null terminated string, and can be passed to the native routine
// immediately. Being a string, it must be at least one character long.
//
if ( !XsCheckBufferSize( SmbGetUshort( ¶meters->BufLen ), "B", FALSE // not in native format
)) {
Header->Status= NERR_BufTooSmall; goto cleanup; }
XsConvertUnicodeTextParameter( comment, (LPSTR)XsSmbGetPointer( ¶meters->Buffer ) );
if ( comment == NULL ) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetServerSetInfo: failed to create buffer" )); } Header->Status = NERR_NoRoom; goto cleanup; }
buffer = &comment;
break;
case SV_ALERTS_PARMNUM: case SV_ALERTSCHED_PARMNUM: case SV_ERRORALERT_PARMNUM: case SV_LOGONALERT_PARMNUM:
goto cleanup;
case SV_ACCESSALERT_PARMNUM: case SV_DISKALERT_PARMNUM: case SV_NETIOALERT_PARMNUM: case SV_MAXAUDITSZ_PARMNUM:
//
// SV_ALERTS_PARMNUM, SV_ALERTSCHED_PARMNUM, SV_ERRORALERT_PARMNUM,
// SV_LOGONALERT_PARMNUM, SV_ACCESSALERT_PARMNUM, SV_DISKALERT_PARMNUM,
// SV_NETIOALERT_PARMNUM, or SV_MAXAUDITSZ_PARMNUM.
//
// These parameters are not supported in NT, so just return an OK.
//
goto cleanup;
case SV_DISC_PARMNUM: case SV_HIDDEN_PARMNUM: case SV_ANNOUNCE_PARMNUM: case SV_ANNDELTA_PARMNUM:
//
// SV_DISC_PARMNUM, SV_HIDDEN_PARMNUM, SV_ANNOUNCE_PARMNUM, or
// SV_ANNDELTA_PARMNUM.
//
// The structure descriptor given is meaningless; the data is a word
// to be converted into a 32-bit DWORD. The length of data must be 2.
//
if ( !XsCheckBufferSize( SmbGetUshort( ¶meters->BufLen ), "W", FALSE // not in native format
)) {
Header->Status= NERR_BufTooSmall; goto cleanup; }
data = (DWORD)SmbGetUshort( (LPWORD)XsSmbGetPointer( ¶meters->Buffer ) ); buffer = &data;
break;
default:
Header->Status = ERROR_INVALID_PARAMETER; goto cleanup; }
//
// Do the actual local call.
//
level = SmbGetUshort( ¶meters->ParmNum ); if ( level != 0 ) { level = level + PARMNUM_BASE_INFOLEVEL; } else { level = 100 + SmbGetUshort( ¶meters->Level ); if ( level == 103 ) { level = 102; } }
status = NetServerSetInfo( NULL, level, buffer, NULL );
if ( !XsApiSuccess( status )) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetServerSetInfo: NetServerSetInfo failed: %X\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.
//
if ( SmbGetUshort( ¶meters->ParmNum ) == PARMNUM_ALL ) { NetpMemoryFree( buffer ); } else if ( SmbGetUshort( ¶meters->ParmNum ) == SV_COMMENT_PARMNUM ) { NetpMemoryFree( comment ); }
return STATUS_SUCCESS;
} // XsNetServerSetInfo
|