|
|
//*************************************************************
//
// File name: TSrvCon.c
//
// Description: Contains routines to provide TShareSRV
// connection support
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1991-1997
// All rights reserved
//
//*************************************************************
#define DC_HICOLOR
#include <TSrv.h>
#include <TSrvInfo.h>
#include <TSrvCom.h>
#include <TSrvTerm.h>
#include <TSrvCon.h>
#include <_TSrvCon.h>
#include <_TSrvInfo.h>
#include <TSrvSec.h>
#include <at128.h>
#include <at120ex.h>
#include <ndcgmcro.h>
//*************************************************************
//
// TSrvDoConnectResponse()
//
// Purpose: Performs the conf connect process
//
// Parameters: IN [pTSrvInfo] - GCC CreateIndicationMessage
//
// Return: STATUS_SUCCESS - Success
// other - Failure
//
// History: 07-17-97 BrianTa Created
//
//*************************************************************
NTSTATUS TSrvDoConnectResponse(IN PTSRVINFO pTSrvInfo) { NTSTATUS ntStatus;
TRACE((DEBUG_TSHRSRV_FLOW, "TShrSRV: TSrvDoConnectResponse entry\n"));
// Invoke routine to perform actual response
ntStatus = TSrvConfCreateResp(pTSrvInfo);
if (NT_SUCCESS(ntStatus)) { EnterCriticalSection(&pTSrvInfo->cs);
// If this connection was not told to terminate during the
// connection response, then mark the conference state as
// TSRV_GCC_CONF_CONNECTED
if (!pTSrvInfo->fDisconnect) pTSrvInfo->fuConfState = TSRV_CONF_CONNECTED;
LeaveCriticalSection(&pTSrvInfo->cs);
// If we were unable to mark the conf state as CONNECTED, then
// the connection needs to be terminated
if (pTSrvInfo->fuConfState != TSRV_CONF_CONNECTED) { TRACE((DEBUG_TSHRSRV_NORMAL, "TShrSRV: Connection aborted due to termination request\n"));
ntStatus = STATUS_REQUEST_ABORTED; } }
TRACE((DEBUG_TSHRSRV_FLOW, "TShrSRV: TSrvDoConnectResponse exit - 0x%x\n", ntStatus));
return (ntStatus); }
//*************************************************************
//
// TSrvDoConnect()
//
// Purpose: Initiates the conf connect process
//
// Parameters: IN [pTSrvInfo] - GCC CreateIndicationMessage
//
// Return: STATUS_SUCCESS - Success
// other - Failure
//
// History: 07-17-97 BrianTa Created
//
//*************************************************************
NTSTATUS TSrvDoConnect(IN PTSRVINFO pTSrvInfo) { DWORD dwStatus; NTSTATUS ntStatus;
TRACE((DEBUG_TSHRSRV_FLOW, "TShrSRV: TSrvDoConnect entry\n"));
ntStatus = STATUS_TRANSACTION_ABORTED;
if (pTSrvInfo->fDisconnect == FALSE) { TSrvReferenceInfo(pTSrvInfo);
// Wait to be told that a connection is being
// requested via the client
TRACE((DEBUG_TSHRSRV_NORMAL, "TShrSRV: Waiting for connection Ind signal for pTSrvInfo 0x%x\n", pTSrvInfo));
dwStatus = WaitForSingleObject(pTSrvInfo->hWorkEvent, 60000);
TRACE((DEBUG_TSHRSRV_NORMAL, "TShrSRV: Connection Ind signal received for pTSrvInfo %p - 0x%x\n", pTSrvInfo, dwStatus));
// If a client connection request has been recieved, then proceed
// with the acknowledgement process (CreateResponse)
switch (dwStatus) { case WAIT_OBJECT_0: if (pTSrvInfo->fDisconnect == FALSE) ntStatus = TSrvDoConnectResponse(pTSrvInfo); else ntStatus = STATUS_TRANSACTION_ABORTED; break;
case WAIT_TIMEOUT: ntStatus = STATUS_IO_TIMEOUT; break; }
TSrvDereferenceInfo(pTSrvInfo); }
TRACE((DEBUG_TSHRSRV_FLOW, "TShrSRV: TSrvDoConnect exit - 0x%x\n", ntStatus));
return (ntStatus); }
//*************************************************************
//
// TSrvStackConnect()
//
// Purpose: Stack initiated connect
//
// Parameters: IN [hIca] - Ica handle
// IN [hStack] - Ica stack
// OUT [ppTSrvInfo] - Ptr to TSRVINFO ptr
//
// Return: STATUS_SUCCESS - Success
// other - Failure
//
// History: 07-17-97 BrianTa Created
//
//*************************************************************
NTSTATUS TSrvStackConnect(IN HANDLE hIca, IN HANDLE hStack, OUT PTSRVINFO *ppTSrvInfo) { NTSTATUS ntStatus;
TRACE((DEBUG_TSHRSRV_FLOW, "TShrSRV: TSrvStackConnect entry\n"));
ntStatus = STATUS_UNSUCCESSFUL;
if (TSrvIsReady(TRUE)) { TS_ASSERT(hStack);
// Allocate a TSrvInfo object which will be used to
// track this connection instance
ntStatus = TSrvAllocInfo(ppTSrvInfo, hIca, hStack);
if (NT_SUCCESS(ntStatus)) { TS_ASSERT(*ppTSrvInfo);
ntStatus = TSrvDoConnect(*ppTSrvInfo); } }
TRACE((DEBUG_TSHRSRV_FLOW, "TShrSRV: TSrvStackConnect exit - 0x%x\n", ntStatus));
return (ntStatus); }
//*************************************************************
//
// TSrvConsoleConnect()
//
// Purpose: Connest to console session
//
// Parameters: IN [hIca] - Ica handle
// IN [hStack] - Ica stack
// OUT [ppTSrvInfo] - Ptr to TSRVINFO ptr
//
// Return: STATUS_SUCCESS - Success
// other - Failure
//
// History: 11-02-98 MartinRichards (DCL) Created
//
//*************************************************************
NTSTATUS TSrvConsoleConnect(IN HANDLE hIca, IN HANDLE hStack, IN PVOID pBuffer, IN ULONG ulBufferLength, OUT PTSRVINFO *ppTSrvInfo) { NTSTATUS ntStatus; PTSRVINFO pTSrvInfo;
int i; ULONG ulInBufferSize; ULONG ulBytesReturned; PRNS_UD_CS_CORE pCoreData;
PTSHARE_MODULE_DATA pModuleData = (PTSHARE_MODULE_DATA) pBuffer; PTSHARE_MODULE_DATA_B3 pModuleDataB3 = (PTSHARE_MODULE_DATA_B3) pBuffer;
HDC hdc; int screenBpp;
TRACE((DEBUG_TSHRSRV_FLOW, "TShrSRV: TSrvConsoleConnect entry\n"));
ntStatus = STATUS_UNSUCCESSFUL;
if (TSrvIsReady(TRUE)) { TS_ASSERT(hStack);
// Allocate a TSrvInfo object which will be used to
// track this connection instance
ntStatus = STATUS_NO_MEMORY;
// Try allocating a TSRVINFO object
pTSrvInfo = TSrvAllocInfoNew();
// If we managed to get a TSRVINFO object, perform
// default base initialization
if (pTSrvInfo) { pTSrvInfo->hDomain = NULL; pTSrvInfo->hIca = hIca; pTSrvInfo->hStack = hStack; pTSrvInfo->fDisconnect = FALSE; pTSrvInfo->fConsoleStack = TRUE; pTSrvInfo->fuConfState = TSRV_CONF_PENDING; pTSrvInfo->ulReason = 0; pTSrvInfo->ntStatus = STATUS_SUCCESS; pTSrvInfo->bSecurityEnabled = FALSE; pTSrvInfo->SecurityInfo.CertType = CERT_TYPE_INVALID;
/****************************************************************/ /* Build the User data portion (remember that there is not */ /* actually a real client to connect; instead we need to pass */ /* in the relevant information about the console session) */ /****************************************************************/ ulInBufferSize = sizeof(USERDATAINFO) + sizeof(RNS_UD_CS_CORE); pTSrvInfo->pUserDataInfo = TSHeapAlloc(0, ulInBufferSize, TS_HTAG_TSS_USERDATA_OUT); if (pTSrvInfo->pUserDataInfo == NULL) { TRACE((DEBUG_TSHRSRV_ERROR, "TShrSRV: Failed to get user data memory\n")); ntStatus = STATUS_NO_MEMORY; goto Cleanup; } pTSrvInfo->pUserDataInfo->cbSize = sizeof(USERDATAINFO) + sizeof(RNS_UD_CS_CORE); pTSrvInfo->pUserDataInfo->version = RNS_UD_VERSION; pTSrvInfo->pUserDataInfo->hDomain = NULL;
pTSrvInfo->pUserDataInfo->ulUserDataMembers = 1;
pCoreData = (PRNS_UD_CS_CORE)(pTSrvInfo->pUserDataInfo->rgUserData);
pCoreData->header.type = RNS_UD_CS_CORE_ID; pCoreData->header.length = sizeof(RNS_UD_CS_CORE); pCoreData->version = RNS_UD_VERSION;
pCoreData->desktopWidth = (TSUINT16)GetSystemMetrics(SM_CXVIRTUALSCREEN); pCoreData->desktopHeight = (TSUINT16)GetSystemMetrics(SM_CYVIRTUALSCREEN);
//
// The fields colorDepth and supportedColorDepths of pCoreData are
// used as temporary variables. The correct values are set before
// sending the Ioctl below.
//
pCoreData->colorDepth = 0; pCoreData->supportedColorDepths = 0;
//
// Get the color depth and capabilities from the remote client.
//
// B3 and B3_oops! servers used a fixed length user data structure
if ( (ulBufferLength == sizeof(TSHARE_MODULE_DATA_B3)) || (ulBufferLength == sizeof(TSHARE_MODULE_DATA_B3_OOPS)) ) {
pCoreData->colorDepth = pModuleDataB3->clientCoreData.colorDepth;
} else if ( (ulBufferLength >= sizeof(TSHARE_MODULE_DATA)) && (ulBufferLength == (sizeof(TSHARE_MODULE_DATA) + pModuleData->userDataLen - sizeof(RNS_UD_HEADER))) ) {
PRNS_UD_HEADER pHeader; PRNS_UD_HEADER pEnd; PRNS_UD_CS_CORE pClientCoreData;
pHeader = (PRNS_UD_HEADER) &pModuleData->userData; pEnd = (PRNS_UD_HEADER)((PBYTE)pHeader + pModuleData->userDataLen);
// Loop through user data, extracting each piece.
do { if ( pHeader->type == RNS_UD_CS_CORE_ID ) { pClientCoreData = (PRNS_UD_CS_CORE)pHeader;
pCoreData->colorDepth = pClientCoreData->colorDepth;
if (pClientCoreData->header.length >= (FIELDOFFSET(RNS_UD_CS_CORE, supportedColorDepths) + FIELDSIZE(RNS_UD_CS_CORE, supportedColorDepths))) {
pCoreData->supportedColorDepths = pClientCoreData->supportedColorDepths; } break; }
// don't get stuck here for ever...
if (pHeader->length == 0) { break; }
// Move on to the next user data string.
pHeader = (PRNS_UD_HEADER)((PBYTE)pHeader + pHeader->length); } while (pHeader < pEnd); }
switch (pCoreData->colorDepth) { case RNS_UD_COLOR_24BPP: pCoreData->highColorDepth = 24; break;
case RNS_UD_COLOR_16BPP_565: pCoreData->highColorDepth = 16; break;
case RNS_UD_COLOR_16BPP_555: pCoreData->highColorDepth = 15; break;
case RNS_UD_COLOR_8BPP: pCoreData->highColorDepth = 8; break;
case RNS_UD_COLOR_4BPP: pCoreData->highColorDepth = 4; break;
default: pCoreData->highColorDepth = 0; break; }
#ifdef DC_HICOLOR
/****************************************************************/ /* setup color depth based on the screen capabilities */ /****************************************************************/
hdc = GetDC(NULL);
if (hdc) {
screenBpp = GetDeviceCaps(hdc, BITSPIXEL); ReleaseDC(NULL, hdc);
// Avoid bad colors when device bitmaps is enabled and if the
// client connects at 15bpp and the console is at 16bpp.
if ((screenBpp == 16) && (pCoreData->colorDepth == RNS_UD_COLOR_16BPP_555) && (pCoreData->supportedColorDepths & RNS_UD_16BPP_SUPPORT)) {
pCoreData->colorDepth = RNS_UD_COLOR_16BPP_565; pCoreData->highColorDepth = 16;
} else // see if the ColorDepth is valid
if( !((pCoreData->colorDepth == RNS_UD_COLOR_24BPP) || (pCoreData->colorDepth == RNS_UD_COLOR_16BPP_565) || (pCoreData->colorDepth == RNS_UD_COLOR_16BPP_555) || (pCoreData->colorDepth == RNS_UD_COLOR_8BPP) || (pCoreData->colorDepth == RNS_UD_COLOR_4BPP)) ) {
pCoreData->highColorDepth = (TSUINT16)screenBpp;
if (screenBpp >= 24) { pCoreData->colorDepth = RNS_UD_COLOR_24BPP; pCoreData->highColorDepth = 24; } else if (screenBpp == 16) { pCoreData->colorDepth = RNS_UD_COLOR_16BPP_565; } else if (screenBpp == 15) { pCoreData->colorDepth = RNS_UD_COLOR_16BPP_555; } else { pCoreData->colorDepth = RNS_UD_COLOR_8BPP; pCoreData->highColorDepth = 8; } } TRACE((DEBUG_TSHRSRV_NORMAL, "TShrSRV: TSrvConsoleConnect at %d bpp\n", screenBpp)); } #endif
// set new high color fields
pCoreData->supportedColorDepths = (TSUINT16)( RNS_UD_24BPP_SUPPORT || RNS_UD_16BPP_SUPPORT || RNS_UD_15BPP_SUPPORT);
// Pass the data to WDTShare
ulBytesReturned = 0; ntStatus = IcaStackIoControl(pTSrvInfo->hStack, IOCTL_TSHARE_CONSOLE_CONNECT, pTSrvInfo->pUserDataInfo, ulInBufferSize, NULL, 0, &ulBytesReturned);
Cleanup: TRACE((DEBUG_TSHRSRV_FLOW, "TShrSRV: TSrvConsoleConnect exit - 0x%x\n", ntStatus));
pTSrvInfo->ntStatus = ntStatus;
if (NT_SUCCESS(ntStatus)) { EnterCriticalSection(&pTSrvInfo->cs);
// If this connection was not told to terminate during the
// connection response, then mark the conference state as
// TSRV_GCC_CONF_CONNECTED
if (!pTSrvInfo->fDisconnect) pTSrvInfo->fuConfState = TSRV_CONF_CONNECTED;
LeaveCriticalSection(&pTSrvInfo->cs);
// If we were unable to mark the conf state as CONNECTED, then
// the connection needs to be terminated
if (pTSrvInfo->fuConfState != TSRV_CONF_CONNECTED) { TRACE((DEBUG_TSHRSRV_NORMAL, "TShrSRV: Connection aborted due to term request\n")); ntStatus = STATUS_REQUEST_ABORTED; }
} if (!NT_SUCCESS(ntStatus)) { TSrvDereferenceInfo(pTSrvInfo);
pTSrvInfo = NULL; } }
}
if (NT_SUCCESS(ntStatus)) { *ppTSrvInfo = pTSrvInfo; }
TRACE((DEBUG_TSHRSRV_FLOW, "TShrSRV: TSrvConsoleConnect exit - 0x%x\n", ntStatus));
return (ntStatus); }
|