// 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 // IN, DWORD, etc. #include // DEVLEN, NET_API_STATUS, etc. // These may be included in any order: #include // API_ equates. #include // NetapipBufferAllocate(), NetApiBufferFree(). #include // API's data structures. #include // NetpKdPrint(), FORMAT_ equates. #include // NetpAdjustPreferredMaximum(). #include // LPDESC. #include // REM16_, REM32_, REMSmb_ equates. #include // RxRemoteApi(). #include // MAX_TRANSACT_RET_DATA_SIZE, RxpFatalErrorCode(). #include // My prototype(s). #include // Netp{icgroup}StructureInfo(). #include // 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