|
|
// Replace: // {capgroup} is the name of group in caps as it appears in typedefs. // {date} with today's date in dd-Mmm-yyyy form. // {email} with your email ID. // {filename} with name of this file (including .c at end) // {fullname} with your full name // {header} is the header file name part (e.g. "wksta" in lmwksta.h) // {icgroup} is name of group with initial caps, e.g. "Server". // Take care of all {expand} replacements. // Delete these instructions.
/*++
Copyright (c) 1991-1993 Microsoft Corporation
Module Name:
{filename}
Abstract:
This file contains the RpcXlate code to handle the Net{icgroup}Enum API.
Author:
{fullname} ({email}) {date}
Environment:
Portable to any flat, 32-bit environment. (Uses Win32 typedefs.) Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
{date} {email} Created.
--*/
// These must be included first:
#include <windef.h> // IN, DWORD, etc. #include <lmcons.h> // DEVLEN, NET_API_STATUS, etc.
// These may be included in any order:
#include <apinums.h> // API_ equates. #include <lmapibuf.h> // NetapipBufferAllocate(), NetApiBufferFree(). #include <lm{header}.h> // API's data structures. #include <netdebug.h> // NetpKdPrint(), FORMAT_ equates. #include <netlib.h> // NetpAdjustPreferredMaximum(). #include <rap.h> // LPDESC. #include <remdef.h> // REM16_, REM32_, REMSmb_ equates. #include <rx.h> // RxRemoteApi(). #include <rxp.h> // MAX_TRANSACT_RET_DATA_SIZE, RxpFatalErrorCode(). #include <rx{header}.h> // My prototype(s). #include <strucinf.h> // Netp{icgroup}StructureInfo(). #include <winerror.h> // NO_ERROR and ERROR_ equates.
#define {capgroup}_ARRAY_OVERHEAD_SIZE 0
NET_API_STATUS RxNet{icgroup}Enum ( IN LPTSTR UncServerName, {expand}, IN DWORD Level, OUT LPBYTE *BufPtr, IN DWORD PreferedMaximumSize, OUT LPDWORD EntriesRead, OUT LPDWORD TotalEntries, IN OUT LPDWORD ResumeHandle OPTIONAL )
/*++
Routine Description:
RxNet{icgroup}Enum performs the same function as Net{icgroup}Enum, except that the server name is known to refer to a downlevel server.
Arguments:
(Same as Net{icgroup}Enum, except UncServerName must not be null, and must not refer to the local computer.)
Return Value:
(Same as Net{icgroup}Enum.)
--*/
{ LPDESC DataDesc16; LPDESC DataDesc32; LPDESC DataDescSmb; DWORD EntriesToAllocate; LPVOID InfoArray; DWORD InfoArraySize; DWORD MaxEntrySize; NET_API_STATUS Status;
UNREFERENCED_PARAMETER(ResumeHandle);
// Make sure caller didn't mess up. NetpAssert(UncServerName != NULL); if (BufPtr == NULL) { return (ERROR_INVALID_PARAMETER); }
// Assume something might go wrong, and make error paths easier to // code. Also, check for bad pointers before we do anything. *BufPtr = NULL; *EntriesRead = 0; *TotalEntries = 0;
Status = Netp{icgroup}StructureInfo ( Level, PARMNUM_ALL, // want all fields. TRUE, // want native sizes. & DataDesc16, & DataDesc32, & DataDescSmb, & MaxEntrySize, // API buffer size 32 NULL, // don't need fixed size NULL // don't need string size ); if (Status != NO_ERROR) { *BufPtr = NULL; return (Status); }
// // Downlevel servers don't support resume handles, and we don't // have a way to say "close this resume handle" even if we wanted to // emulate them here. Therefore we have to do everthing in one shot. // So, the first time around, we'll try using the caller's prefered // maximum, but we will enlarge that until we can get everything in one // buffer. //
// First time: try caller's prefered maximum. NetpAdjustPreferedMaximum ( PreferedMaximumSize, // caller's request MaxEntrySize, // byte count per array element {capgroup}_ARRAY_OVERHEAD_SIZE, // num bytes overhead to show array end NULL, // we'll compute byte counts ourselves. & EntriesToAllocate); // num of entries we can get.
// // Loop until we have enough memory or we die for some other reason. // do {
// Figure out how much memory we need. InfoArraySize = (EntriesToAllocate * MaxEntrySize) + {capgroup}_ARRAY_OVERHEAD_SIZE;
// // adjust the size to the maximum amount a down-level server // can handle //
if (InfoArraySize > MAX_TRANSACT_RET_DATA_SIZE) { InfoArraySize = MAX_TRANSACT_RET_DATA_SIZE; } // // Remote the API, which will allocate the array for us. //
Status = RxRemoteApi( API_W{icgroup}Enum, // api number UncServerName, // \\servername REMSmb_Net{icgroup}Enum_P, // parm desc (SMB version) DataDesc16, DataDesc32, DataDescSmb, NULL, // no aux desc 16 NULL, // no aux desc 32 NULL, // no aux desc SMB ALLOCATE_RESPONSE, // flags: allocate buffer for us // rest of API's arguments in 32-bit LM 2.x format: {expand} Level, // sLevel: info level & InfoArray, // Buffer: array (alloc for us) InfoArraySize, // Buffer: array size in bytes EntriesRead, // pcEntriesRead TotalEntries); // pcTotalAvail
if (Status == ERROR_MORE_DATA) {
NetpAssert( InfoArraySize <= MAX_TRANSACT_RET_DATA_SIZE ); if (InfoArraySize == MAX_TRANSACT_RET_DATA_SIZE) { NetpKdPrint(( PREFIX_NETAPI "RxNet{icgroup}Enum: " "**WARNING** protocol limit reached (64KB).\n" )); break; }
(VOID) NetApiBufferFree( InfoArray ); NetpAssert( EntriesToAllocate < *TotalEntries ); EntriesToAllocate = *TotalEntries; } } while (Status == ERROR_MORE_DATA);
if ( (Status == NO_ERROR) && ((*EntriesRead) > 0) ) { *BufPtr = InfoArray; } else { (VOID) NetApiBufferFree( InfoArray ); NetpAssert( *BufPtr == NULL ); }
return (Status);
} // RxNet{icgroup}Enum
|