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

582 lines
23 KiB
C

/*++
Copyright (c) 1991-1993 Microsoft Corporation
Module Name:
ConvSrv.c
Abstract:
This file contains routines to convert between old and new server
info levels.
Author:
John Rogers (JohnRo) 02-May-1991
Environment:
Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
02-May-1991 JohnRo
Created.
11-May-1991 JohnRo
Added level 402,403 support. Use PLATFORM_ID equates from lncons.h.
19-May-1991 JohnRo
Clean up LPBYTE vs. LPTSTR handling, as suggested by PC-LINT.
05-Jun-1991 JohnRo
Added level 101 to 1 conversion. Also 100 to 0 and 102 to 2.
Added support for sv403_autopath.
Added more debug output when we fail.
07-Jun-1991 JohnRo
Really added 102 to 2 conversion.
14-Jun-1991 JohnRo
For debug, display the entire incoming structure.
18-Jun-1991 JohnRo
Added svX_licenses support.
08-Aug-1991 JohnRo
Implement downlevel NetWksta APIs. (Moved DanHi's NetCmd/Map32/MServer
stuff here.)
21-Nov-1991 JohnRo
Removed NT dependencies to reduce recompiles.
05-May-1993 JohnRo
RAID 8720: bad data from WFW can cause RxNetServerEnum GP fault.
Avoid compiler warnings.
Minor debug output changes.
Use PREFIX_ equates.
Made changes suggested by PC-LINT 5.0
--*/
// These must be included first:
#include <windef.h> // IN, LPVOID, etc.
#include <lmcons.h> // NET_API_STATUS, CNLEN, etc.
// These may be included in any order:
#include <debuglib.h> // IF_DEBUG(CONVSRV).
#include <dlserver.h> // Old info levels, MAX_ equates, my prototype.
#include <lmapibuf.h> // NetapipBufferAllocate().
#include <lmerr.h> // NERR_ and ERROR_ equates.
#include <lmserver.h> // New info level structures & conv routines.
#include <mapsupp.h> // NetpMoveStrings().
#include <netdebug.h> // NetpKdPrint(()), FORMAT_ equates, etc.
#include <netlib.h> // NetpPointerPlusSomeBytes().
#include <prefix.h> // PREFIX_ equates.
#include <tstr.h> // STRLEN().
#include <xsdef16.h> // xactsrv defaults for values not supported on NT
NET_API_STATUS
NetpConvertServerInfo (
IN DWORD FromLevel,
IN LPVOID FromInfo,
IN BOOL FromNative,
IN DWORD ToLevel,
OUT LPVOID ToInfo,
IN DWORD ToFixedSize,
IN DWORD ToStringSize,
IN BOOL ToNative,
IN OUT LPTSTR * ToStringTopPtr OPTIONAL
)
/*++
Routine Description:
NetpConvertServerInfo handles "old" (LanMan 2.x) and "new" (portable
LanMan, including NT/LAN) server info levels. Only certain pairs of
conversions are allowed:
0 to 100
1 to 101
2 to 102
2 to 402
3 to 403
100 to 0
101 to 1
102 to 2
Arguments:
FromLevel - a DWORD which gives the info level being converted from.
FromInfo - the actual data being converted.
FromNative - a BOOLEAN indicating whether or not FromInfo is in native
(local machine) format, as opposed to "RAP" format.
ToLevel - a DWORD which gives the info level being converted to.
ToInfo - Points to an area which will contain the converted
info structure.
ToFixedSize - Size of the ToInfo fixed area, in bytes.
ToStringSize - Size of the ToStringTopPtr string area, in bytes.
ToNative - a BOOLEAN indicating whether or not the "to" info is to be
in native (local machine) format, as opposed to "RAP" format.
ToStringTopPtr - optionally points a pointer to the top of the area to be
used for variable-length items. If ToStringTopPtr is NULL, then
NetpConvertServerInfo will use ToInfo+ToFixedSize as this area.
Otherwise, this routine will update *ToStringTopPtr. This allows
this routine to be used to convert arrays of entries.
Return Value:
NET_API_STATUS - NERR_Success, ERROR_INVALID_LEVEL, etc.
--*/
{
BOOL CopyOK;
LPBYTE ToFixedEnd;
DWORD ToInfoSize;
LPTSTR ToStringTop;
//
// These parameters are not used in non-debug code for the moment.
// ToLevel might be used in the future, if we allow more combinations of
// level conversions. FromNative and ToNative will eventually be used
// by RapConvertSingleEntry.
//
DBG_UNREFERENCED_PARAMETER(CopyOK); // debug only
NetpAssert(FromNative == TRUE);
DBG_UNREFERENCED_PARAMETER(FromNative);
DBG_UNREFERENCED_PARAMETER(ToLevel);
NetpAssert(ToNative == TRUE);
DBG_UNREFERENCED_PARAMETER(ToNative);
// Check caller's parameters for null pointers.
if (FromInfo==NULL) {
NetpKdPrint(( PREFIX_NETLIB
"NetpConvertServerInfo: invalid FromInfo pointer.\n" ));
return (ERROR_INVALID_PARAMETER);
} else if (ToInfo==NULL) {
NetpKdPrint(( PREFIX_NETLIB
"NetpConvertServerInfo: invalid ToInfo pointer.\n" ));
return (ERROR_INVALID_PARAMETER);
}
// Set up pointers for use by NetpCopyStringsToBuffer.
if (ToStringTopPtr != NULL) {
ToStringTop = *ToStringTopPtr;
} else {
ToStringTop = (LPTSTR)
NetpPointerPlusSomeBytes(ToInfo, ToFixedSize+ToStringSize);
}
ToInfoSize = ToFixedSize + ToStringSize;
ToFixedEnd = NetpPointerPlusSomeBytes(ToInfo, ToFixedSize);
// Make sure info levels are OK and caller didn't mess up otherwise.
NetpAssert(ToInfoSize > 0);
switch (FromLevel) {
case 0 :
NetpAssert(ToLevel == 100);
break;
case 1 :
NetpAssert(ToLevel == 101);
break;
case 2 :
NetpAssert( (ToLevel == 102) || (ToLevel == 402) );
break;
case 3 :
NetpAssert(ToLevel == 403);
break;
case 100 :
NetpAssert(ToLevel == 0);
break;
case 101 :
NetpAssert(ToLevel == 1);
break;
case 102 :
NetpAssert(ToLevel == 2);
break;
default :
NetpKdPrint(( PREFIX_NETLIB
"NetpConvertServerInfo: invalid FromLevel ("
FORMAT_DWORD ").\n", FromLevel ));
return (ERROR_INVALID_LEVEL);
}
// Convert fields. This is done with a "switch" that takes advantage
// of the fact that certain info levels are subsets of other ones.
switch (FromLevel) {
case 102 :
{
LPSERVER_INFO_2 psv2 = ToInfo;
LPSERVER_INFO_102 psv102 = FromInfo;
// Do unique fields for level 1.
psv2->sv2_users = psv102->sv102_users;
psv2->sv2_disc = psv102->sv102_disc;
if (psv102->sv102_hidden) {
psv2->sv2_hidden = SV_HIDDEN;
} else {
psv2->sv2_hidden = SV_VISIBLE;
}
psv2->sv2_announce = psv102->sv102_announce;
psv2->sv2_anndelta = psv102->sv102_anndelta;
psv2->sv2_licenses = psv102->sv102_licenses;
NetpAssert(psv102->sv102_userpath != NULL); // Avoid STRLEN err.
CopyOK = NetpCopyStringToBuffer (
psv102->sv102_userpath, // in string
STRLEN(psv102->sv102_userpath), // input string length
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv2->sv2_userpath); // output string pointer
NetpAssert(CopyOK);
// Make sure it's OK to use level 101 => level 1 code.
CHECK_SERVER_OFFSETS( 1, 2, version_major);
CHECK_SERVER_OFFSETS(101, 102, version_major);
CHECK_SERVER_OFFSETS( 1, 2, version_minor);
CHECK_SERVER_OFFSETS(101, 102, version_minor);
CHECK_SERVER_OFFSETS( 1, 2, type);
CHECK_SERVER_OFFSETS(101, 102, type);
CHECK_SERVER_OFFSETS( 1, 2, comment);
CHECK_SERVER_OFFSETS(101, 102, comment);
}
/* FALLTHROUGH */
case 101 :
{
LPSERVER_INFO_1 psv1 = ToInfo;
LPSERVER_INFO_101 psv101 = FromInfo;
// Do unique fields for level 1.
psv1->sv1_version_major = psv101->sv101_version_major;
psv1->sv1_version_minor = psv101->sv101_version_minor;
psv1->sv1_type = psv101->sv101_type;
NetpAssert(psv101->sv101_comment != NULL); // Avoid STRLEN err.
CopyOK = NetpCopyStringToBuffer (
psv101->sv101_comment, // in string
STRLEN(psv101->sv101_comment), // input string length
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv1->sv1_comment); // output string pointer
NetpAssert(CopyOK);
// Make sure it's OK to use level 100 => level 0 code.
CHECK_SERVER_OFFSETS( 0, 1, name);
CHECK_SERVER_OFFSETS(100, 101, name);
}
/* FALLTHROUGH */
case 100 :
{
LPSERVER_INFO_0 psv0 = ToInfo;
LPSERVER_INFO_100 psv100 = FromInfo;
// All fields are unique for level 0.
NetpAssert(psv100->sv100_name != NULL); // Avoid STRLEN err.
CopyOK = NetpCopyStringToBuffer (
psv100->sv100_name, // in string
STRLEN(psv100->sv100_name), // input string length
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv0->sv0_name); // output string pointer
NetpAssert(CopyOK);
}
break;
case 3 :
{
LPSERVER_INFO_3 psv3 = FromInfo;
LPSERVER_INFO_403 psv403 = ToInfo;
// Do unique fields for level 403.
psv403->sv403_auditedevents = psv3->sv3_auditedevents;
psv403->sv403_autoprofile = psv3->sv3_autoprofile;
NetpAssert(psv3->sv3_autopath != NULL); // avoid STRLEN err.
CopyOK = NetpCopyStringToBuffer (
psv3->sv3_autopath, // in string
STRLEN(psv3->sv3_autopath), // input string length
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv403->sv403_autopath); // output string pointer
NetpAssert(CopyOK);
// Make sure it's OK to fall through to next level conv.
CHECK_SERVER_OFFSETS( 2, 3, ulist_mtime);
CHECK_SERVER_OFFSETS( 2, 3, glist_mtime);
CHECK_SERVER_OFFSETS( 2, 3, alist_mtime);
CHECK_SERVER_OFFSETS( 2, 3, alerts);
CHECK_SERVER_OFFSETS( 2, 3, security);
CHECK_SERVER_OFFSETS( 2, 3, numadmin);
CHECK_SERVER_OFFSETS( 2, 3, lanmask);
CHECK_SERVER_OFFSETS( 2, 3, guestacct);
CHECK_SERVER_OFFSETS( 2, 3, chdevs);
CHECK_SERVER_OFFSETS( 2, 3, chdevq);
CHECK_SERVER_OFFSETS( 2, 3, chdevjobs);
CHECK_SERVER_OFFSETS( 2, 3, connections);
CHECK_SERVER_OFFSETS( 2, 3, shares);
CHECK_SERVER_OFFSETS( 2, 3, openfiles);
CHECK_SERVER_OFFSETS( 2, 3, sessopens);
CHECK_SERVER_OFFSETS( 2, 3, sessvcs);
CHECK_SERVER_OFFSETS( 2, 3, sessreqs);
CHECK_SERVER_OFFSETS( 2, 3, opensearch);
CHECK_SERVER_OFFSETS( 2, 3, activelocks);
CHECK_SERVER_OFFSETS( 2, 3, numreqbuf);
CHECK_SERVER_OFFSETS( 2, 3, sizreqbuf);
CHECK_SERVER_OFFSETS( 2, 3, numbigbuf);
CHECK_SERVER_OFFSETS( 2, 3, numfiletasks);
CHECK_SERVER_OFFSETS( 2, 3, alertsched);
CHECK_SERVER_OFFSETS( 2, 3, erroralert);
CHECK_SERVER_OFFSETS( 2, 3, logonalert);
CHECK_SERVER_OFFSETS( 2, 3, accessalert);
CHECK_SERVER_OFFSETS( 2, 3, diskalert);
CHECK_SERVER_OFFSETS( 2, 3, netioalert);
CHECK_SERVER_OFFSETS( 2, 3, maxauditsz);
CHECK_SERVER_OFFSETS( 2, 3, srvheuristics);
CHECK_SERVER_OFFSETS(402, 403, ulist_mtime);
CHECK_SERVER_OFFSETS(402, 403, glist_mtime);
CHECK_SERVER_OFFSETS(402, 403, alist_mtime);
CHECK_SERVER_OFFSETS(402, 403, alerts);
CHECK_SERVER_OFFSETS(402, 403, security);
CHECK_SERVER_OFFSETS(402, 403, numadmin);
CHECK_SERVER_OFFSETS(402, 403, lanmask);
CHECK_SERVER_OFFSETS(402, 403, guestacct);
CHECK_SERVER_OFFSETS(402, 403, chdevs);
CHECK_SERVER_OFFSETS(402, 403, chdevq);
CHECK_SERVER_OFFSETS(402, 403, chdevjobs);
CHECK_SERVER_OFFSETS(402, 403, connections);
CHECK_SERVER_OFFSETS(402, 403, shares);
CHECK_SERVER_OFFSETS(402, 403, openfiles);
CHECK_SERVER_OFFSETS(402, 403, sessopens);
CHECK_SERVER_OFFSETS(402, 403, sessvcs);
CHECK_SERVER_OFFSETS(402, 403, sessreqs);
CHECK_SERVER_OFFSETS(402, 403, opensearch);
CHECK_SERVER_OFFSETS(402, 403, activelocks);
CHECK_SERVER_OFFSETS(402, 403, numreqbuf);
CHECK_SERVER_OFFSETS(402, 403, sizreqbuf);
CHECK_SERVER_OFFSETS(402, 403, numbigbuf);
CHECK_SERVER_OFFSETS(402, 403, numfiletasks);
CHECK_SERVER_OFFSETS(402, 403, alertsched);
CHECK_SERVER_OFFSETS(402, 403, erroralert);
CHECK_SERVER_OFFSETS(402, 403, logonalert);
CHECK_SERVER_OFFSETS(402, 403, accessalert);
CHECK_SERVER_OFFSETS(402, 403, diskalert);
CHECK_SERVER_OFFSETS(402, 403, netioalert);
CHECK_SERVER_OFFSETS(402, 403, maxauditsz);
CHECK_SERVER_OFFSETS(402, 403, srvheuristics);
}
/* FALLTHROUGH */
case 2 :
{
LPSERVER_INFO_2 psv2 = FromInfo;
LPSERVER_INFO_102 psv102 = ToInfo;
LPSERVER_INFO_402 psv402 = ToInfo;
switch (ToLevel) {
case 402 : /*FALLTHROUGH*/
case 403 :
psv402->sv402_ulist_mtime = psv2->sv2_ulist_mtime;
psv402->sv402_glist_mtime = psv2->sv2_glist_mtime;
psv402->sv402_alist_mtime = psv2->sv2_alist_mtime;
NetpAssert(psv2->sv2_alerts != NULL); // avoid STRLEN err.
CopyOK = NetpCopyStringToBuffer (
psv2->sv2_alerts, // in string
STRLEN(psv2->sv2_alerts), // input string length
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv402->sv402_alerts); // output string pointer
NetpAssert(CopyOK);
psv402->sv402_security = psv2->sv2_security;
psv402->sv402_numadmin = psv2->sv2_numadmin;
psv402->sv402_lanmask = psv2->sv2_lanmask;
NetpAssert(psv2->sv2_guestacct != NULL); // Protect STRLEN.
CopyOK = NetpCopyStringToBuffer (
psv2->sv2_guestacct, // in string
STRLEN(psv2->sv2_guestacct), // input string length
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv402->sv402_guestacct); // output string ptr
NetpAssert(CopyOK);
psv402->sv402_chdevs = psv2->sv2_chdevs;
psv402->sv402_chdevq = psv2->sv2_chdevq;
psv402->sv402_chdevjobs = psv2->sv2_chdevjobs;
psv402->sv402_connections = psv2->sv2_connections;
psv402->sv402_shares = psv2->sv2_shares;
psv402->sv402_openfiles = psv2->sv2_openfiles;
psv402->sv402_sessopens = psv2->sv2_sessopens;
psv402->sv402_sessvcs = psv2->sv2_sessvcs;
psv402->sv402_sessreqs = psv2->sv2_sessreqs;
psv402->sv402_opensearch = psv2->sv2_opensearch;
psv402->sv402_activelocks = psv2->sv2_activelocks;
psv402->sv402_numreqbuf = psv2->sv2_numreqbuf;
psv402->sv402_sizreqbuf = psv2->sv2_sizreqbuf;
psv402->sv402_numbigbuf = psv2->sv2_numbigbuf;
psv402->sv402_numfiletasks = psv2->sv2_numfiletasks;
psv402->sv402_alertsched = psv2->sv2_alertsched;
psv402->sv402_erroralert = psv2->sv2_erroralert;
psv402->sv402_logonalert = psv2->sv2_logonalert;
psv402->sv402_accessalert = psv2->sv2_accessalert;
psv402->sv402_diskalert = psv2->sv2_diskalert;
psv402->sv402_netioalert = psv2->sv2_netioalert;
psv402->sv402_maxauditsz = psv2->sv2_maxauditsz;
NetpAssert(psv2->sv2_srvheuristics != NULL); // Prot STRLEN.
CopyOK = NetpCopyStringToBuffer (
psv2->sv2_srvheuristics, // in string
STRLEN(psv2->sv2_srvheuristics), // input str len
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv402->sv402_srvheuristics); // output str ptr
NetpAssert(CopyOK);
goto Done; // In nested switch, so "break" won't work.
case 102 : // 2 to 102.
// Set unique fields for levels 2 and 102.
NetpAssert(ToLevel == 102);
psv102->sv102_users = psv2->sv2_users;
psv102->sv102_disc = psv2->sv2_disc;
if (psv2->sv2_hidden == SV_HIDDEN) {;
psv102->sv102_hidden = TRUE;
} else {
psv102->sv102_hidden = FALSE;
}
psv102->sv102_announce = psv2->sv2_announce;
psv102->sv102_anndelta = psv2->sv2_anndelta;
psv102->sv102_licenses = psv2->sv2_licenses;
NetpAssert(psv2->sv2_userpath != NULL);
CopyOK = NetpCopyStringToBuffer (
psv2->sv2_userpath, // in string
STRLEN(psv2->sv2_userpath), // input string length
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv102->sv102_userpath); // output string pointer
NetpAssert(CopyOK);
// Make sure it's OK to fall through to next level conv.
CHECK_SERVER_OFFSETS( 1, 2, name);
CHECK_SERVER_OFFSETS( 1, 2, version_major);
CHECK_SERVER_OFFSETS( 1, 2, version_minor);
CHECK_SERVER_OFFSETS( 1, 2, type);
CHECK_SERVER_OFFSETS( 1, 2, comment);
CHECK_SERVER_OFFSETS(101, 102, platform_id);
CHECK_SERVER_OFFSETS(101, 102, name);
CHECK_SERVER_OFFSETS(101, 102, version_major);
CHECK_SERVER_OFFSETS(101, 102, version_minor);
CHECK_SERVER_OFFSETS(101, 102, type);
CHECK_SERVER_OFFSETS(101, 102, comment);
break;
default:
NetpAssert( FALSE ); // Can't happen.
}
}
/* FALLTHROUGH */
case 1 :
{
DWORD CommentSize;
LPSERVER_INFO_1 psv1 = FromInfo;
LPSERVER_INFO_101 psv101 = ToInfo;
psv101->sv101_version_major = psv1->sv1_version_major;
psv101->sv101_version_minor = psv1->sv1_version_minor;
psv101->sv101_type = psv1->sv1_type;
// Copy comment string. Note that null ptr and ptr to null
// char are both allowed here.
if (psv1->sv1_comment != NULL) {
CommentSize = STRLEN(psv1->sv1_comment);
} else {
CommentSize = 0;
}
CopyOK = NetpCopyStringToBuffer (
psv1->sv1_comment, // in string
CommentSize, // input string length
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv101->sv101_comment); // output string pointer
NetpAssert(CopyOK);
// Make sure it's OK to use level 0 => level 100 code.
CHECK_SERVER_OFFSETS( 0, 1, name);
CHECK_SERVER_OFFSETS(100, 101, name);
CHECK_SERVER_OFFSETS(100, 101, platform_id);
}
/* FALLTHROUGH */
case 0 :
{
LPSERVER_INFO_0 psv0 = FromInfo;
LPSERVER_INFO_100 psv100 = ToInfo;
if (FromLevel != 0) {
LPSERVER_INFO_101 psv101 = ToInfo;
if (psv101->sv101_type & SV_TYPE_NT) {
psv100->sv100_platform_id = PLATFORM_ID_NT;
} else {
psv100->sv100_platform_id = PLATFORM_ID_OS2;
}
} else {
psv100->sv100_platform_id = PLATFORM_ID_OS2;
}
NetpAssert(psv0->sv0_name != NULL); // or STRLEN() will fail.
CopyOK = NetpCopyStringToBuffer (
psv0->sv0_name, // in string
STRLEN(psv0->sv0_name), // input string length
ToFixedEnd, // fixed data end
& ToStringTop, // var area end (ptr updated)
& psv100->sv100_name); // output string pointer
NetpAssert(CopyOK);
break;
}
default :
NetpKdPrint(( PREFIX_NETLIB
"NetpConvertServerInfo: unexpected error.\n" ));
return (NERR_InternalError);
}
Done:
// Done converting.
NetpAssert(ToInfo != NULL);
NetpSetOptionalArg(ToStringTopPtr, ToStringTop);
return (NERR_Success);
} // NetpConvertServerInfo