252 lines
7 KiB
C
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
|