Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

548 lines
14 KiB

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
MWKSTA.C
Abstract:
32 bit version of mapping routines for NetWkstaGet/SetInfo API
Author:
Dan Hinsley (danhi) 06-Jun-1991
Environment:
User Mode - Win32
Revision History:
24-Apr-1991 danhi
Created
06-Jun-1991 Danhi
Sweep to conform to NT coding style
15-Aug-1991 JohnRo
Implement downlevel NetWksta APIs. (Moved DanHi's NetCmd/Map32/MWksta
conversion stuff to NetLib.)
Got rid of _DH hacks.
Made some UNICODE changes.
16-Oct-1991 W-ShankN
Added Unicode mapping layer.
Cleaned up old excess baggage.
--*/
//
// INCLUDES
//
#include <windef.h>
#include <winerror.h>
#include <stdio.h>
#include <memory.h>
#include <tstring.h>
#include <malloc.h>
#include <stddef.h>
#include <excpt.h> // try, finally, etc.
#include <lm.h>
#include <remdef.h> // Descriptor strings
#include <mapsupp.h> // BUILD_LENGTH_ARRAY, NetpMoveStrings
#include "port1632.h" // includes mwksta.h,dlwksta.h
//
// Forward declarations of private functions.
//
DWORD
MNetWkstaGetInfoCommon(
LPTSTR ptszServer,
DWORD nLevel,
LPVOID * ppbBuffer);
DWORD
MNetWkstaSetInfoCommon(
LPTSTR ptszServer,
DWORD nLevel,
LPBYTE pbBuffer,
DWORD nParmNum );
// This allows everything to work until Unicode is used.
#ifdef MAP_UNICODE
// These declarations will save some space.
// setinfos are not available anywhere else.
static const LPTSTR pszDesc_wksta_info_0 = DL_REM_wksta_info_0;
static const LPTSTR pszDesc_wksta_info_0_setinfo =
TEXT("QQQQQQQQQDDDQQQQQQQQQQQQQQDDQQQzQ");
static const LPTSTR pszDesc_wksta_info_1 = DL_REM_wksta_info_1;
static const LPTSTR pszDesc_wksta_info_1_setinfo =
TEXT("QQQQQQQQQDDDQQQQQQQQQQQQQQDDQQQzQQzQ");
static const LPTSTR pszDesc_wksta_info_10 = DL_REM_wksta_info_10;
WORD
MNetWkstaGetInfo(
LPTSTR pszServer,
DWORD nLevel,
LPBYTE * ppbBuffer)
{
DWORD nRes; // return from Netapi
nRes = MNetWkstaGetInfoCommon(pszServer, nLevel, ppbBuffer);
if (nRes == NERR_Success || nRes == ERROR_MORE_DATA)
{
LPTSTR pszDesc;
switch (nLevel)
{
case 0:
default:
pszDesc = pszDesc_wksta_info_0;
break;
case 1:
pszDesc = pszDesc_wksta_info_1;
break;
case 10:
pszDesc = pszDesc_wksta_info_10;
break;
}
}
return (LOWORD(nRes));
}
WORD
MNetWkstaSetInfo(
LPTSTR pszServer,
DWORD nLevel,
LPBYTE pbBuffer,
DWORD cbBufferLength,
DWORD nParmNum)
{
DWORD nRes; // return from Netapi
DWORD nLevelNew;
TCHAR * pszDesc;
TCHAR * pszRealDesc;
UNREFERENCED_PARAMETER(cbBufferLength);
switch (nLevel)
{
case 0:
pszDesc = pszDesc_wksta_info_0_setinfo;
pszRealDesc = pszDesc_wksta_info_0;
break;
case 1:
pszDesc = pszDesc_wksta_info_1_setinfo;
pszRealDesc = pszDesc_wksta_info_1;
break;
default:
return ERROR_INVALID_LEVEL;
}
// Parmnum's are OK.
nLevelNew = nLevel;
// nLevelNew = MxCalcNewInfoFromOldParm(nLevel, nParmNum);
nRes = MNetWkstaSetInfoCommon(pszServer, nLevelNew, pbBuffer, nParmNum);
return LOWORD(nRes);
}
#else // MAP_UNICODE
#endif // def MAP_UNICODE
DWORD
MNetWkstaGetInfoCommon(
IN LPTSTR ptszServer,
IN DWORD nLevel,
LPVOID * ppbBuffer)
{
NET_API_STATUS ReturnCode;
LPTSTR pLevelx02 = NULL;
LPTSTR pLevel10;
PWKSTA_INFO_101 pLevel101;
PWKSTA_USER_INFO_1 pLevelUser_1;
//
// All levels require information from both platform dependant and
// platform independent levels. Get level 101 first, which will
// tell us what platform we're running on (as well as supply some
// of the other information we'll need) then User_1, then either
// 302 or 402 or 502 depending on the platform we're running on.
ReturnCode =
NetWkstaGetInfo(ptszServer, 101, (LPBYTE *) & pLevel101);
if (ReturnCode) {
return(ReturnCode);
}
NetpAssert(pLevel101 != NULL) ; // since API succeeded
ReturnCode =
NetWkstaUserGetInfo(NULL, 1, (LPBYTE *) & pLevelUser_1);
if (ReturnCode) {
NetApiBufferFree(pLevel101);
return(ReturnCode);
}
//
// Now get the platform dependant information
//
if (pLevel101->wki101_platform_id != PLATFORM_ID_NT &&
pLevel101->wki101_platform_id != PLATFORM_ID_OS2 &&
pLevel101->wki101_platform_id != PLATFORM_ID_DOS) {
//
// I got an unknown platform id back, this should never happen!
//
NetApiBufferFree((LPBYTE) pLevel101);
NetApiBufferFree((LPBYTE) pLevelUser_1);
return(ERROR_UNEXP_NET_ERR);
}
//
// This is to be able to call NetApiBufferFree no matter where I
// exit from. Note the indentation level is not incremented for
// the switch. No sense going too deep.
//
try {
//
// It all depends on what info level they've asked for:
//
switch(nLevel) {
case 0:
case 1:
{
PWKSTA_INFO_0 pLevel0or1;
//
// This depends on the platform id being 300 400 500
//
ReturnCode = NetWkstaGetInfo(ptszServer,
pLevel101->wki101_platform_id + 2, (LPBYTE*)&pLevelx02);
if (ReturnCode) {
return(ReturnCode);
}
// Call the platform dependant worker function that builds
// the old structure.
//
if (pLevel101->wki101_platform_id == PLATFORM_ID_NT) {
ReturnCode = NetpMakeWkstaLevelForNT(nLevel, pLevel101,
pLevelUser_1, (PWKSTA_INFO_502) pLevelx02, & pLevel0or1);
if (ReturnCode) {
return(ReturnCode);
}
}
else if (pLevel101->wki101_platform_id == PLATFORM_ID_OS2 ||
pLevel101->wki101_platform_id == PLATFORM_ID_DOS) {
ReturnCode = NetpMakeWkstaLevelForOS2orDOS(nLevel, pLevel101,
pLevelUser_1, (PWKSTA_INFO_402) pLevelx02, & pLevel0or1,
pLevel101->wki101_platform_id);
if (ReturnCode) {
return(ReturnCode);
}
}
//
// I got an unknown platform id back, this should never happen!
//
else {
return(ERROR_UNEXP_NET_ERR);
}
//
// Put the pointer to the new structure in the user's pointer.
//
*ppbBuffer = pLevel0or1;
break;
}
case 10:
{
DWORD Level10_101_Length[2];
DWORD Level10_User_1_Length[3];
DWORD i;
DWORD BytesRequired = 0;
LPBYTE pFloor;
//
// Everything needed for a level 10 is in level 101/User_1
// There's no platform dependant information in this level.
// This is pretty straightforward, let's just do it here.
//
// Initialize the Level10_xxx_Length array with the length of each
// string in the input buffers, and allocate the new buffer
// for WKSTA_INFO_10
//
BUILD_LENGTH_ARRAY(BytesRequired, 10, 101, Wksta)
BUILD_LENGTH_ARRAY(BytesRequired, 10, User_1, Wksta)
// Only NT doesn't support oth_domain
if (pLevel101->wki101_platform_id != PLATFORM_ID_NT) {
// 302 and 402 are the same offsets, so it doesn't matter
// which one this is for
// BUGBUG - until oth_domains gets moved back into level 10x
// I can't call this since it requires a higher security
// privilege than the getinfo on a level 10 does.
// BUILD_LENGTH_ARRAY(BytesRequired, 10, 402, Wksta)
}
//
// Allocate the new buffer which will be returned to the user.
//
ReturnCode =
NetapipBufferAllocate(BytesRequired + sizeof(WKSTA_INFO_10),
(LPVOID *) & pLevel10);
if (ReturnCode) {
return(ERROR_NOT_ENOUGH_MEMORY);
}
//
// First get the floor to start moving strings in at.
//
pFloor = (LPBYTE)pLevel10 + BytesRequired + sizeof(WKSTA_INFO_10);
//
// Now move the variable length entries into the new buffer from
// the 101, 402 and User_1 data structures.
//
NetpMoveStrings((LPTSTR *)&pFloor, (LPTSTR) pLevel101, pLevel10,
NetpWksta10_101, Level10_101_Length);
NetpMoveStrings((LPTSTR *)&pFloor, (LPTSTR) pLevelUser_1, pLevel10,
NetpWksta10_User_1, Level10_User_1_Length);
// Only NT doesn't support oth_domain
// BUGBUG - until oth_domains gets moved back into level 10x
// I can't call this since it requires a higher security
// privilege than the getinfo on a level 10 does. I will at
// least set the field to NULL to make it cleaner
//if (pLevel101->wki101_platform_id != PLATFORM_ID_NT) {
// NetpMoveStrings(& pFloor, pLevelx02, pLevel10,
// Level10_User_1, Level10_User_1_Length);
//}
//else {
((PWKSTA_INFO_10) pLevel10)->wki10_oth_domains = NULL;
//}
//
// Now set the rest of the fields in the fixed length portion
// of the structure
//
((PWKSTA_INFO_10) pLevel10)->wki10_ver_major =
pLevel101->wki101_ver_major;
((PWKSTA_INFO_10) pLevel10)->wki10_ver_minor =
pLevel101->wki101_ver_minor;
//
// Put the pointer to the new structure in the user's pointer.
//
*ppbBuffer = pLevel10;
break;
}
//
// Not a level I recognize
//
default:
return(ERROR_INVALID_LEVEL);
} // end of the switch statement
} // end of the try block
finally {
//
// Free up the buffers returned by NetWkstaGetInfo
//
NetApiBufferFree((LPBYTE) pLevel101);
NetApiBufferFree((LPBYTE) pLevelUser_1);
if (pLevelx02) {
NetApiBufferFree((LPBYTE) pLevelx02);
}
}
return(NERR_Success) ;
}
DWORD
MNetWkstaSetInfoCommon(
IN LPTSTR ptszServer,
IN DWORD nLevel,
IN LPBYTE pbBuffer,
IN DWORD nParmNum)
{
NET_API_STATUS ReturnCode;
DWORD platform_id;
PWKSTA_INFO_101 pLevel101;
//
// Make sure they're using a valid level
//
if (nLevel != 0 && nLevel != 1) {
return(ERROR_INVALID_LEVEL);
}
//
// First I have to know what type of platform I'm running on,
// use NetWkstaGetInfo level 101 to get this information
//
ReturnCode = NetWkstaGetInfo(ptszServer, 101, (LPBYTE *) & pLevel101);
if (ReturnCode) {
return(ReturnCode);
}
//
// Save away the platform id so I can free the buffer now
//
platform_id = pLevel101->wki101_platform_id;
NetApiBufferFree((PTCHAR) pLevel101);
//
// Are they trying to set an individual field, or the whole struct?
//
if (nParmNum == PARMNUM_ALL) {
//
// They want to do it all
//
PWKSTA_INFO_402 pLevelx02;
//
// Create the NT structures based on the old style structure passed in
//
if (platform_id == PLATFORM_ID_NT) {
NetpSplitWkstaForNT(ptszServer, nLevel, (PWKSTA_INFO_0) pbBuffer,
& pLevel101, (PWKSTA_INFO_502 *) & pLevelx02);
}
//
// DOS and OS/2 are enough alike to share the same worker function
//
else if (platform_id == PLATFORM_ID_OS2 ||
platform_id == PLATFORM_ID_DOS) {
NetpSplitWkstaForOS2orDOS(nLevel, platform_id,
(PWKSTA_INFO_0) pbBuffer, & pLevel101, & pLevelx02);
}
else {
return(NERR_InternalError);
}
//
// Now SetInfo for both levels (takes two to cover all the
// information in the old structure
//
//
// There are no settable fields in the 101 structure (for NT or downlevel)
// This code is left here in case any of these fields are changed on NT
// to be settable, then this code would just be uncommented.
//
// ReturnCode = NetWkstaSetInfo(ptszServer, 101, (LPBYTE) pLevel101,
// nParmNum, NULL);
// if (ReturnCode) {
// return(LOWORD(ReturnCode));
// }
ReturnCode = NetWkstaSetInfo(ptszServer, platform_id + 2,
(LPBYTE) pLevelx02, NULL);
if (ReturnCode) {
return(ReturnCode);
}
} /* nParmNum == PARMNUM_ALL */
else {
//
// They just want to set an individual element
//
//
// The only thing that can be set on NT are the char parms, if it's
// not that, just return success. Actually, it's not clear what
// the plan is for ERRLOGSZ, but for the time being we'll say it's
// not settable.
//
if (platform_id == PLATFORM_ID_NT &&
(nParmNum != WKSTA_CHARWAIT_PARMNUM &&
nParmNum != WKSTA_CHARTIME_PARMNUM &&
nParmNum != WKSTA_CHARCOUNT_PARMNUM )) {
return(NERR_Success);
}
//
// Everything is set in the 302/402/502 structure
//
else if (platform_id != PLATFORM_ID_DOS &&
platform_id != PLATFORM_ID_OS2 &&
platform_id != PLATFORM_ID_NT) {
//
// Invalid platform id, shouldn't happen
//
return(NERR_InternalError);
}
ReturnCode = NetWkstaSetInfo(ptszServer,
nParmNum + PARMNUM_BASE_INFOLEVEL, pbBuffer, NULL);
return(ReturnCode);
}
return(NERR_Success);
}