|
|
/****************************************************************************/ // icarpc.c
//
// winsta.dll RPC client code for interaction with termsrv.exe.
//
// Copyright (C) 1997-2000 Microsoft Corporation
/****************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntddkbd.h>
#include <ntddmou.h>
#include <windows.h>
#include <winbase.h>
#include <winerror.h>
#include <winsta.h>
#include <icadd.h>
#include "rpcwire.h"
/****************************************************************************
* ValidUserBuffer * * This function verifies that the caller if WinStationQueryInformation/ * WinStationSetInformation has the correct structure size (i.e. client * application built with the same header files as winsta.dll). * * ENTRY: * BufferSize * The size of the bufferr. * * InfoClass * The WinStationQuery/Set information class. * * EXIT: * Retures TRUE if the buffer is valid, otherwise FALSE. ****************************************************************************/ BOOLEAN ValidUserBuffer(ULONG BufferSize, WINSTATIONINFOCLASS InfoClass) { switch (InfoClass) { case WinStationLoadIndicator: return(BufferSize >= sizeof(WINSTATIONLOADINDICATORDATA));
case WinStationCreateData: return(BufferSize == sizeof(WINSTATIONCREATEW));
case WinStationConfiguration: return(BufferSize == sizeof(WINSTATIONCONFIGW));
case WinStationPdParams: return(BufferSize == sizeof(PDPARAMSW));
case WinStationWd: return(BufferSize == sizeof(WDCONFIGW));
case WinStationPd: return(BufferSize == sizeof(PDCONFIGW));
case WinStationPrinter: return(BufferSize == sizeof(WINSTATIONPRINTERW));
case WinStationClient: return(BufferSize == sizeof(WINSTATIONCLIENTW));
case WinStationModules: return(TRUE);
case WinStationInformation: return(BufferSize == sizeof(WINSTATIONINFORMATIONW));
case WinStationTrace: return(BufferSize == sizeof(ICA_TRACE));
case WinStationBeep: return(BufferSize == sizeof(BEEPINPUT));
case WinStationEncryptionOff: case WinStationEncryptionPerm: case WinStationNtSecurity: return(TRUE);
case WinStationUserToken: return(BufferSize == sizeof(WINSTATIONUSERTOKEN));
case WinStationVideoData: case WinStationInitialProgram: case WinStationCd: case WinStationSystemTrace: case WinStationVirtualData: return(TRUE); // Not Implemented - let server handle it
case WinStationClientData: return(BufferSize >= sizeof(WINSTATIONCLIENTDATA));
case WinStationLoadBalanceSessionTarget: return (BufferSize >= sizeof(ULONG));
case WinStationShadowInfo: return(BufferSize == sizeof(WINSTATIONSHADOW));
case WinStationDigProductId: return(BufferSize >= sizeof(WINSTATIONPRODID));
case WinStationLockedState: return(BufferSize >= sizeof(BOOL));
case WinStationRemoteAddress: return(BufferSize >= sizeof(WINSTATIONREMOTEADDRESS));
case WinStationLastReconnectType: return(BufferSize >= sizeof(ULONG));
case WinStationDisallowAutoReconnect: return(BufferSize >= sizeof(BOOLEAN));
case WinStationMprNotifyInfo: return(BufferSize >= sizeof(ExtendedClientCredentials));
default: return(FALSE); } }
/****************************************************************************
* CreateGenericWireBuf * * This function creates a generic wire buffer for structures which may * have new fields added to the end. * * ENTRY: * * DataSize (input) * The size of the structure. * pBuffer (output) * Pointer to the allocated buffer. * pBufSize (output) * Pointer to the wire buffer size. * * EXIT: * Returns ERROR_SUCCESS if successful. If successful, pBuffer * contains the generic wire buffer. ****************************************************************************/ ULONG CreateGenericWireBuf(ULONG DataSize, PVOID *ppBuffer, PULONG pBufSize) { ULONG BufSize; PVARDATA_WIRE pVarData;
BufSize = sizeof(VARDATA_WIRE) + DataSize; if ((pVarData = (PVARDATA_WIRE)LocalAlloc(0,BufSize)) == NULL) return(ERROR_NOT_ENOUGH_MEMORY);
InitVarData(pVarData, DataSize, sizeof(VARDATA_WIRE)); *ppBuffer = (PVOID) pVarData; *pBufSize = BufSize; return ERROR_SUCCESS; }
/****************************************************************************
* CheckUserBuffer * * This function determines if the buffer type should be converted to a * wire format. If so, a wire buffer is allocated. * * ENTRY: * InfoClass (input) * WinStationQuery/Set information class. * * UserBuf(input) * The client bufferr. * * UserBufLen (input) * The client buffer length. * * ppWireBuf(output) * Pointer to wirebuf pointer, updated with allocated wire buffer if * BufAllocated is TRUE. * pWireBufLen (output) * Pointer to the length of the wire buffer allocated, updated if * BufAllocated is TRUE. * pBufAllocated (output) * Pointer to flag indicating if a wire buffer was allocated. * EXIT: * Returns ERROR_SUCCESS if successful. If successful, BufAllocated * indicated whether a wire buffer was allocated. * on failure, an error code is returned. ****************************************************************************/ ULONG CheckUserBuffer( WINSTATIONINFOCLASS InfoClass, PVOID UserBuf, ULONG UserBufLen, PVOID *ppWireBuf, PULONG pWireBufLen, BOOLEAN *pBufAllocated) { ULONG BufSize; ULONG Error; PPDCONFIGWIREW PdConfigWire; PPDCONFIGW PdConfig; PPDPARAMSWIREW PdParamsWire; PPDPARAMSW PdParam; PWINSTACONFIGWIREW WinStaConfigWire; PWINSTATIONCONFIGW WinStaConfig; PVOID WireBuf;
if (!ValidUserBuffer(UserBufLen, InfoClass)) { return(ERROR_INSUFFICIENT_BUFFER); }
switch (InfoClass) { case WinStationPd: BufSize = sizeof(PDCONFIGWIREW) + sizeof(PDCONFIG2W) + sizeof(PDPARAMSW); if ((WireBuf = (PCHAR)LocalAlloc(0,BufSize)) == NULL) return(ERROR_NOT_ENOUGH_MEMORY);
PdConfigWire = (PPDCONFIGWIREW)WireBuf; InitVarData(&PdConfigWire->PdConfig2W, sizeof(PDCONFIG2W), sizeof(PDCONFIGWIREW)); InitVarData(&PdConfigWire->PdParams.SdClassSpecific, sizeof(PDPARAMSW) - sizeof(SDCLASS), NextOffset(&PdConfigWire->PdConfig2W)); break; case WinStationPdParams: BufSize = sizeof(PDPARAMSWIREW) + sizeof(PDPARAMSW); if ((WireBuf = (PCHAR)LocalAlloc(0,BufSize)) == NULL) return(ERROR_NOT_ENOUGH_MEMORY);
PdParamsWire = (PPDPARAMSWIREW)WireBuf; InitVarData(&PdParamsWire->SdClassSpecific, sizeof(PDPARAMSW), sizeof(PDPARAMSWIREW)); break;
case WinStationConfiguration: BufSize = sizeof(WINSTACONFIGWIREW) + sizeof(USERCONFIGW); if ((WireBuf = (PCHAR)LocalAlloc(0,BufSize)) == NULL) return(ERROR_NOT_ENOUGH_MEMORY);
WinStaConfigWire = (PWINSTACONFIGWIREW)WireBuf; InitVarData(&WinStaConfigWire->UserConfig, sizeof(USERCONFIGW), sizeof(WINSTACONFIGWIREW)); InitVarData(&WinStaConfigWire->NewFields, 0, NextOffset(&WinStaConfigWire->UserConfig)); break;
case WinStationInformation: if ((Error = CreateGenericWireBuf(sizeof(WINSTATIONINFORMATIONW), &WireBuf, &BufSize)) != ERROR_SUCCESS) return(Error); break;
case WinStationWd: if ((Error = CreateGenericWireBuf(sizeof(WDCONFIGW), &WireBuf, &BufSize)) != ERROR_SUCCESS) return(Error); break;
case WinStationClient: if ((Error = CreateGenericWireBuf(sizeof(WINSTATIONCLIENTW), &WireBuf, &BufSize)) != ERROR_SUCCESS) return(Error); break; default: *ppWireBuf = NULL; *pBufAllocated = FALSE; return ERROR_SUCCESS; }
*pWireBufLen = BufSize; *ppWireBuf = WireBuf; *pBufAllocated = TRUE; return ERROR_SUCCESS; }
|