|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
ApiShare.c
Abstract:
This module contains individual API handlers for the NetShare APIs.
SUPPORTED : NetShareAdd, NetShareCheck, NetShareDel, NetShareEnum, NetShareGetInfo, NetShareSetInfo.
Author:
David Treadwell (davidtr) 07-Jan-1991 Shanku Niyogi (w-shanku)
Revision History:
--*/
#include "XactSrvP.h"
//
// Declaration of descriptor strings.
//
STATIC const LPDESC Desc16_share_info_0 = REM16_share_info_0; STATIC const LPDESC Desc32_share_info_0 = REM32_share_info_0; STATIC const LPDESC Desc16_share_info_1 = REM16_share_info_1; STATIC const LPDESC Desc32_share_info_1 = REM32_share_info_1; STATIC const LPDESC Desc16_share_info_1_setinfo = REM16_share_info_1_setinfo; STATIC const LPDESC Desc32_share_info_1_setinfo = REM32_share_info_1_setinfo; STATIC const LPDESC Desc16_share_info_2 = REM16_share_info_2; STATIC const LPDESC Desc32_share_info_2 = REM32_share_info_2; STATIC const LPDESC Desc16_share_info_2_setinfo = REM16_share_info_2_setinfo; STATIC const LPDESC Desc32_share_info_2_setinfo = REM32_share_info_2_setinfo;
NTSTATUS XsNetShareAdd ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetShareAdd.
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_SHARE_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(SHARE) { NetpKdPrint(( "XsNetShareAdd: header at %lx, params at %lx, " "level %ld\n", Header, parameters, SmbGetUshort( ¶meters->Level ) )); }
try { //
// Check for errors.
//
if ( SmbGetUshort( ¶meters->Level ) != 2 ) {
Header->Status = ERROR_INVALID_LEVEL; goto cleanup; }
StructureDesc = Desc16_share_info_2;
//
// 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(( "XsNetShareAdd: 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_share_info_2, RapToNative, TRUE );
//
// Allocate enough memory to hold the converted native buffer.
//
buffer = NetpMemoryAllocate( bufferSize );
if ( buffer == NULL ) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetShareAdd: failed to create buffer" )); } Header->Status = NERR_NoRoom; goto cleanup;
}
IF_DEBUG(SHARE) { NetpKdPrint(( "XsNetShareAdd: buffer of %ld bytes at %lx\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_share_info_2, FALSE, &stringLocation, &bytesRequired, Response, RapToNative );
if ( status != NERR_Success ) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetShareAdd: RapConvertSingleEntry failed: " "%X\n", status )); }
Header->Status = NERR_InternalError; goto cleanup; }
//
// Make the local call.
//
status = NetShareAdd( NULL, (DWORD)SmbGetUshort( ¶meters->Level ), buffer, NULL );
if ( !XsApiSuccess( status )) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetShareAdd: NetShareAdd failed: %X\n", status )); }
if ( status == ERROR_DIRECTORY ) { Header->Status = NERR_UnknownDevDir; } else { 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;
} // XsNetShareAdd
NTSTATUS XsNetShareCheck ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetShareCheck.
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_SHARE_CHECK parameters = Parameters; LPTSTR nativeDeviceName = NULL; // Native parameters
DWORD shareType;
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
try { //
// Translate parameters, check for errors.
//
XsConvertTextParameter( nativeDeviceName, (LPSTR)XsSmbGetPointer( ¶meters->DeviceName ) );
//
// Do the local call.
//
status = NetShareCheck( NULL, nativeDeviceName, &shareType );
if ( !XsApiSuccess( status )) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetShareCheck: NetShareCheck failed: " "%X\n", status )); } }
//
// Put type into return field.
//
SmbPutUshort( ¶meters->Type, (WORD)shareType );
Header->Status = (WORD)status;
cleanup: ; } except( EXCEPTION_EXECUTE_HANDLER ) { Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() ); }
NetpMemoryFree( nativeDeviceName ); return STATUS_SUCCESS;
} // XsNetShareCheck
NTSTATUS XsNetShareDel ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetShareDel.
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_SHARE_DEL parameters = Parameters; LPTSTR nativeNetName = NULL; // Native parameters
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
IF_DEBUG(SHARE) { NetpKdPrint(( "XsNetShareDel: header at %lx, params at %lx, name %s\n", Header, parameters, SmbGetUlong( ¶meters->NetName ))); }
try { //
// Translate parameters, check for errors.
//
XsConvertTextParameter( nativeNetName, (LPSTR)XsSmbGetPointer( ¶meters->NetName ) );
//
// Make the local call.
//
status = NetShareDel( NULL, nativeNetName, (DWORD)SmbGetUshort( ¶meters->Reserved ) );
if ( !XsApiSuccess( status )) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetShareDel: NetShareDel failed: %X\n", status )); } }
//
// Nothing to return.
//
Header->Status = (WORD)status;
cleanup: ; } except( EXCEPTION_EXECUTE_HANDLER ) { Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() ); }
NetpMemoryFree( nativeNetName ); return STATUS_SUCCESS;
} // XsNetShareDel
NTSTATUS XsNetShareEnum ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetShareEnum.
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_SHARE_ENUM parameters = Parameters; LPVOID outBuffer= NULL; // Native parameters
DWORD entriesRead = 0; DWORD totalEntries;
DWORD entriesFilled = 0; // Conversion variables
DWORD bytesRequired = 0; DWORD invalidEntries = 0; LPDESC nativeStructureDesc;
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
IF_DEBUG(SHARE) { NetpKdPrint(( "XsNetShareEnum: header at %lx, params at %lx, " "level %ld, buf size %ld\n", Header, parameters, SmbGetUshort( ¶meters->Level ), SmbGetUshort( ¶meters->BufLen ))); }
try { //
// Check for errors.
//
if ( XsWordParamOutOfRange( parameters->Level, 0, 2 )) {
Header->Status = ERROR_INVALID_LEVEL; goto cleanup; }
//
// Make the local call.
//
status = NetShareEnum( NULL, (DWORD)SmbGetUshort( ¶meters->Level ), (LPBYTE *)&outBuffer, XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen )), &entriesRead, &totalEntries, NULL );
if ( !XsApiSuccess( status )) { IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetShareEnum: NetShareEnum failed: " "%X\n", status )); } Header->Status = (WORD)status; goto cleanup; }
IF_DEBUG(SHARE) { NetpKdPrint(( "XsNetShareEnum: received %ld entries at %lx\n", entriesRead, outBuffer )); }
//
// Use the requested level to determine the format of the
// data structure.
//
switch ( SmbGetUshort( ¶meters->Level ) ) {
case 0:
nativeStructureDesc = Desc32_share_info_0; StructureDesc = Desc16_share_info_0; break;
case 1:
nativeStructureDesc = Desc32_share_info_1; StructureDesc = Desc16_share_info_1; break;
case 2:
nativeStructureDesc = Desc32_share_info_2; StructureDesc = Desc16_share_info_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 ), SmbGetUshort( ¶meters->BufLen ), StructureDesc, NULL, // verify function
&bytesRequired, &entriesFilled, &invalidEntries );
IF_DEBUG(SHARE) { NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR," " Entries %ld of %ld\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 + invalidEntries < 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->EntriesRead, (WORD)entriesFilled ); SmbPutUshort( ¶meters->TotalAvail, (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;
} // XsNetShareEnum
NTSTATUS XsNetShareGetInfo ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetShareGetInfo.
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_SHARE_GET_INFO parameters = Parameters; LPTSTR nativeNetName = NULL; // Native parameters
LPVOID outBuffer = NULL;
LPBYTE stringLocation = NULL; // Conversion variables
DWORD bytesRequired = 0; LPDESC nativeStructureDesc;
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
IF_DEBUG(SHARE) { NetpKdPrint(( "XsNetShareGetInfo: header at %lx, " "params at %lx, level %ld\n", Header, parameters, SmbGetUshort( ¶meters->Level ) )); }
try { //
// Translate parameters, check for errors.
//
if ( XsWordParamOutOfRange( parameters->Level, 0, 2 )) {
Header->Status = ERROR_INVALID_LEVEL; goto cleanup; }
XsConvertTextParameter( nativeNetName, (LPSTR)XsSmbGetPointer( ¶meters->NetName ) );
//
// Make the local call.
//
status = NetShareGetInfo( NULL, nativeNetName, (DWORD)SmbGetUshort( ¶meters->Level ), (LPBYTE *)&outBuffer );
if ( !XsApiSuccess( status )) { IF_DEBUG(API_ERRORS) { NetpKdPrint(( "XsNetShareGetInfo: NetShareGetInfo failed: " "%X\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_share_info_0; StructureDesc = Desc16_share_info_0; break;
case 1:
nativeStructureDesc = Desc32_share_info_1; StructureDesc = Desc16_share_info_1; break;
case 2:
nativeStructureDesc = Desc32_share_info_2; StructureDesc = Desc16_share_info_2; 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(( "XsNetShareGetInfo: RapConvertSingleEntry failed: " "%X\n", status )); }
Header->Status = NERR_InternalError; goto cleanup; }
IF_DEBUG(SHARE) { NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld 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(( "XsNetShareGetInfo: Buffer too small.\n" )); } Header->Status = NERR_BufTooSmall;
} else if ( bytesRequired > (DWORD)SmbGetUshort( ¶meters-> BufLen )) {
IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetShareGetInfo: 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 ); }
//
// Set up the response parameters.
//
SmbPutUshort( ¶meters->TotalAvail, (WORD)bytesRequired );
cleanup: ; } except( EXCEPTION_EXECUTE_HANDLER ) { Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() ); }
NetApiBufferFree( outBuffer ); NetpMemoryFree( nativeNetName );
//
// Determine return buffer size.
//
XsSetDataCount( ¶meters->BufLen, StructureDesc, Header->Converter, 1, Header->Status );
return STATUS_SUCCESS;
} // XsNetShareGetInfo
NTSTATUS XsNetShareSetInfo ( API_HANDLER_PARAMETERS )
/*++
Routine Description:
This routine handles a call to NetShareSetInfo.
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_SHARE_SET_INFO parameters = Parameters; LPTSTR nativeNetName = NULL; // Native parameters
LPVOID buffer = NULL; DWORD level;
LPDESC setInfoDesc; // Conversion variables
LPDESC nativeSetInfoDesc; LPDESC nativeStructureDesc;
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
try { //
// Translate parameters, check for errors.
//
XsConvertTextParameter( nativeNetName, (LPSTR)XsSmbGetPointer( ¶meters->NetName ) );
//
// Determine descriptor strings based on level.
//
switch ( SmbGetUshort( ¶meters->Level )) {
case 1:
StructureDesc = Desc16_share_info_1; nativeStructureDesc = Desc32_share_info_1; setInfoDesc = Desc16_share_info_1_setinfo; nativeSetInfoDesc = Desc32_share_info_1_setinfo;
break;
case 2:
StructureDesc = Desc16_share_info_2; nativeStructureDesc = Desc32_share_info_2; setInfoDesc = Desc16_share_info_2_setinfo; nativeSetInfoDesc = Desc32_share_info_2_setinfo;
break;
default:
Header->Status = ERROR_INVALID_LEVEL; goto cleanup; }
status = XsConvertSetInfoBuffer( (LPBYTE)XsSmbGetPointer( ¶meters->Buffer ), SmbGetUshort( ¶meters->BufLen ), SmbGetUshort( ¶meters->ParmNum ), FALSE, TRUE, StructureDesc, nativeStructureDesc, setInfoDesc, nativeSetInfoDesc, (LPBYTE *)&buffer, NULL );
if ( status != NERR_Success ) {
IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetShareSetInfo: Problem with conversion: %X\n", status )); } Header->Status = (WORD)status; goto cleanup;
}
//
// Do the actual local call.
//
level = SmbGetUshort( ¶meters->ParmNum ); if ( level != 0 ) { level = level + PARMNUM_BASE_INFOLEVEL; } else { level = SmbGetUshort( ¶meters->Level ); }
status = NetShareSetInfo( NULL, nativeNetName, level, (LPBYTE)buffer, NULL );
if ( !XsApiSuccess( status )) { IF_DEBUG(ERRORS) { NetpKdPrint(( "XsNetShareSetInfo: NetShareSetInfo 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.
//
NetpMemoryFree( buffer ); NetpMemoryFree( nativeNetName );
return STATUS_SUCCESS;
} // XsNetShareSetInfo
|