windows-nt/Source/XPSP1/NT/ds/netapi/rpcxlate/rxapi/wksuser.c
2020-09-26 16:20:57 +08:00

252 lines
7 KiB
C

/*++
Copyright (c) 1991-92 Microsoft Corporation
Module Name:
WksUser.c
Abstract:
This file contains the RpcXlate code to handle the NetWkstaUserEnum API.
Author:
John Rogers (JohnRo) 19-Nov-1991
Environment:
Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
19-Nov-1991 JohnRo
Implement remote NetWkstaUserEnum().
21-Nov-1991 JohnRo
Removed NT dependencies to reduce recompiles.
07-Feb-1992 JohnRo
Use NetApiBufferAllocate() instead of private version.
14-Oct-1992 JohnRo
RAID 9732: NetWkstaUserEnum to downlevel: wrong EntriesRead, Total?
Set wkui1_oth_domains field.
Use PREFIX_ equates.
03-Nov-1992 JohnRo
RAID 10418: Fixed overactive assert when Status != NO_ERROR.
Fixed memory leak if we couldn't allocate new buffer (old one got lost).
Fixed memory leak if nobody is logged-on to target server.
--*/
// These must be included first:
#include <windef.h> // IN, DWORD, etc.
#include <lmcons.h> // LM20_ equates, NET_API_STATUS, etc.
// These may be included in any order:
#include <dlwksta.h> // WKSTA_INFO_0, MAX_WKSTA_ equates, etc.
#include <lmapibuf.h> // NetApiBufferAllocate().
#include <lmerr.h> // ERROR_ and NERR_ equates.
#include <netdebug.h> // DBGSTATIC, NetpKdPrint(()), FORMAT_ equates.
#include <netlib.h> // NetpCopyStringToBuffer().
#include <prefix.h> // PREFIX_ equates.
#include <rxpdebug.h> // IF_DEBUG().
#include <rxwksta.h> // My prototypes, RxpGetWkstaInfoLevelEquivalent
#include <tstring.h> // STRLEN().
NET_API_STATUS
RxNetWkstaUserEnum (
IN LPTSTR UncServerName,
IN DWORD Level,
OUT LPBYTE *BufPtr,
IN DWORD PrefMaxSize,
OUT LPDWORD EntriesRead,
OUT LPDWORD TotalEntries,
IN OUT LPDWORD ResumeHandle OPTIONAL
)
/*++
Routine Description:
RxNetWkstaUserEnum performs the same function as NetWkstaUserEnum, except
that the server name is known to refer to a downlevel server.
Arguments:
(Same as NetWkstaUserEnum, except UncServerName must not be null, and
must not refer to the local computer.)
Return Value:
(Same as NetWkstaUserEnum.)
--*/
{
LPBYTE NewInfo = NULL; // Buffer to be returned to caller.
DWORD NewFixedSize;
DWORD NewStringSize;
LPWKSTA_INFO_1 OldInfo = NULL;
const DWORD OldLevel = 1;
NET_API_STATUS Status;
UNREFERENCED_PARAMETER(PrefMaxSize);
UNREFERENCED_PARAMETER(ResumeHandle);
IF_DEBUG(WKSTA) {
NetpKdPrint(( PREFIX_NETAPI
"RxNetWkstaUserEnum: starting, server=" FORMAT_LPTSTR
", lvl=" FORMAT_DWORD ".\n", UncServerName, Level));
}
//
// Error check DLL stub and the app.
//
NetpAssert(UncServerName != NULL);
if (BufPtr == NULL) {
Status = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
*BufPtr = NULL; // assume error; it makes error handlers easy to code.
// This also forces possible GP fault before we allocate memory.
//
// Compute size of wksta user structure (including strings)
//
switch (Level) {
case 0 :
NewFixedSize = sizeof(WKSTA_USER_INFO_0);
NewStringSize = (LM20_UNLEN+1) * sizeof(TCHAR);
break;
case 1 :
NewFixedSize = sizeof(WKSTA_USER_INFO_1);
NewStringSize =
(LM20_UNLEN+1 + LM20_DNLEN+1 + MAX_PATH+1) * sizeof(TCHAR);
break;
default:
Status = ERROR_INVALID_LEVEL;
goto Cleanup;
}
//
// Actually remote the API, which will get back the (old) info level
// data in native format.
//
Status = RxpWkstaGetOldInfo(
UncServerName, // Required, with \\name.
OldLevel,
(LPBYTE *) & OldInfo); // buffer (alloc and set this ptr)
NetpAssert( Status != ERROR_MORE_DATA );
NetpAssert( Status != NERR_BufTooSmall );
if (Status == NERR_Success) {
NetpAssert( OldInfo != NULL );
if ( (OldInfo->wki1_username == NULL)
|| ( (*(OldInfo->wki1_username)) == (TCHAR) '\0')) {
//
// Nobody logged on.
//
*BufPtr = NULL;
*EntriesRead = 0;
*TotalEntries = 0;
} else {
// These variables are used by the COPY_STRING macro.
LPBYTE NewFixedEnd;
LPTSTR NewStringTop;
LPWKSTA_INFO_1 src = (LPVOID) OldInfo;
LPWKSTA_USER_INFO_1 dest; // superset info level
//
// Allocate memory for native version of new info, which we'll
// return to caller. (Caller must free it with NetApiBufferFree.)
//
Status = NetApiBufferAllocate(
NewFixedSize + NewStringSize,
(LPVOID *) & NewInfo);
if (Status != NERR_Success) {
goto Cleanup;
}
NetpAssert( NewInfo != NULL );
IF_DEBUG(WKSTA) {
NetpKdPrint(( PREFIX_NETAPI
"RxNetWkstaUserEnum: allocated new buffer at "
FORMAT_LPVOID "\n", (LPVOID) NewInfo ));
}
// Set up pointers for use by NetpCopyStringsToBuffer.
dest = (LPVOID) NewInfo;
NewStringTop = (LPTSTR) NetpPointerPlusSomeBytes(
dest,
NewFixedSize+NewStringSize);
NewFixedEnd = NetpPointerPlusSomeBytes(NewInfo, NewFixedSize);
#define COPY_STRING( InField, OutField ) \
{ \
BOOL CopyOK; \
NetpAssert( dest != NULL); \
NetpAssert( src != NULL); \
NetpAssert( (src -> InField) != NULL); \
CopyOK = NetpCopyStringToBuffer ( \
src->InField, \
STRLEN(src->InField), \
NewFixedEnd, \
& NewStringTop, \
& dest->OutField); \
NetpAssert(CopyOK); \
}
//
// Downlevel server, so one user is logged on.
//
*EntriesRead = 1;
*TotalEntries = 1;
//
// Copy/convert data from OldInfo to NewInfo.
//
// User name is only field in level 0.
COPY_STRING( wki1_username, wkui1_username );
if (Level == 1) {
// Do fields unique to level 1.
COPY_STRING( wki1_logon_domain, wkui1_logon_domain );
COPY_STRING( wki1_oth_domains, wkui1_oth_domains );
COPY_STRING( wki1_logon_server, wkui1_logon_server );
}
NetpAssert( Level < 2 ); // Add code here someday?
*BufPtr = NewInfo;
}
} else {
// An error from RxpWkstaGetOldInfo()...
NetpAssert( OldInfo == NULL );
}
Cleanup:
if (OldInfo != NULL) {
(void) NetApiBufferFree( OldInfo );
}
return (Status);
} // RxNetWkstaUserEnum