Leaked source code of windows server 2003
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.
 
 
 
 
 
 

310 lines
7.6 KiB

/*************************************************************************
*
* icadis.c
*
* Send notice of ICA disconnect
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* $Author:
*
*************************************************************************/
/*
* Includes
*/
#include "precomp.h"
#pragma hdrstop
#include "ntuser.h"
#include <winsta.h>
#include <wstmsg.h>
#include <icadd.h>
HANDLE WinStationIcaApiPort = NULL;
/*******************************************************************************
*
* ConnectToTerminalServer
*
* ENTRY:
* Access (input)
* security access
*
* EXIT:
* STATUS_SUCCESS - successful
*
******************************************************************************/
NTSTATUS
ConnectToTerminalServer(
ULONG Access,
PHANDLE pPortHandle)
{
UNICODE_STRING PortName;
SECURITY_QUALITY_OF_SERVICE DynamicQos;
WINSTATIONAPI_CONNECT_INFO info;
ULONG ConnectInfoLength;
NTSTATUS Status;
/*
* Set up SM API port name
*/
RtlInitUnicodeString(&PortName, L"\\SmSsWinStationApiPort");
/*
* Set up the security quality of service parameters to use over the
* port. Use the most efficient (least overhead) - which is dynamic
* rather than static tracking.
*/
DynamicQos.ImpersonationLevel = SecurityImpersonation;
DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
DynamicQos.EffectiveOnly = TRUE;
/*
* Fill in the ConnectInfo structure with our access request mask
*/
info.Version = CITRIX_WINSTATIONAPI_VERSION;
info.RequestedAccess = Access;
ConnectInfoLength = sizeof(WINSTATIONAPI_CONNECT_INFO);
// Attempt to connect to the Session Manager API port
Status = NtConnectPort(pPortHandle,
&PortName,
&DynamicQos,
NULL,
NULL,
NULL, // Max message length [select default]
(PVOID)&info,
&ConnectInfoLength);
if (!NT_SUCCESS(Status)) {
// Look at the returned INFO to see why if desired
*pPortHandle = NULL;
#if DBG
if (ConnectInfoLength == sizeof(WINSTATIONAPI_CONNECT_INFO)) {
DbgPrint("WinstationConnectToICASrv: connect failed, Reason 0x%x\n", info.AcceptStatus);
}
DbgPrint("WinstationConnectToICASrv: Connect failed 0x%x\n", Status);
#endif
return (Status);
}
return (STATUS_SUCCESS);
}
/*******************************************************************************
*
* BrokenConnection
*
* ENTRY:
* Reason code
*
* EXIT:
* STATUS_SUCCESS - successful
*
******************************************************************************/
NTSTATUS
BrokenConnection(
BROKENCLASS Reason,
BROKENSOURCECLASS Source)
{
WINSTATION_APIMSG Msg;
NTSTATUS Status;
/*
* Connect to Session Mgr
*/
if (WinStationIcaApiPort == NULL) {
Status = ConnectToTerminalServer(0, &WinStationIcaApiPort);
if (!NT_SUCCESS(Status)) {
return (Status);
}
}
Msg.h.u1.s1.DataLength = sizeof(Msg) - sizeof(PORT_MESSAGE);
Msg.h.u1.s1.TotalLength = sizeof(Msg);
Msg.h.u2.s2.Type = 0; // Kernel will fill in message type
Msg.h.u2.s2.DataInfoOffset = 0;
Msg.WaitForReply = TRUE;
Msg.ApiNumber = SMWinStationBrokenConnection;
Msg.ReturnedStatus = 0;
Msg.u.Broken.Reason = Reason;
Msg.u.Broken.Source = Source;
Status = NtRequestWaitReplyPort(WinStationIcaApiPort, (PPORT_MESSAGE)&Msg, (PPORT_MESSAGE)&Msg);
#if DBG
if (!NT_SUCCESS(Status)) {
DbgPrint("BrokenConnection: rc=0x%x\n", Status);
}
#endif
return (Status);
}
/*******************************************************************************
*
* ReplyMessageToTerminalServer
*
* ENTRY:
*
* EXIT:
* STATUS_SUCCESS - successful
*
******************************************************************************/
NTSTATUS
ReplyMessageToTerminalServer(
NTSTATUS ReplyStatus,
PNTSTATUS pStatus,
ULONG Response,
PULONG pResponse,
HANDLE hEvent
)
{
WINSTATION_APIMSG Msg;
NTSTATUS Status;
HANDLE PortHandle;
/*
* Connect to Session Mgr
*/
Status = ConnectToTerminalServer(0, &PortHandle);
if (!NT_SUCCESS(Status)) {
return (Status);
}
Msg.h.u1.s1.DataLength = sizeof(Msg) - sizeof(PORT_MESSAGE);
Msg.h.u1.s1.TotalLength = sizeof(Msg);
Msg.h.u2.s2.Type = 0; // Kernel will fill in message type
Msg.h.u2.s2.DataInfoOffset = 0;
Msg.WaitForReply = TRUE;
Msg.ApiNumber = SMWinStationIcaReplyMessage;
Msg.ReturnedStatus = 0;
Msg.u.ReplyMessage.Response = Response;
Msg.u.ReplyMessage.pResponse = pResponse;
Msg.u.ReplyMessage.hEvent = hEvent;
Msg.u.ReplyMessage.Status = ReplyStatus;
Msg.u.ReplyMessage.pStatus = pStatus;
Status = NtRequestWaitReplyPort(PortHandle, (PPORT_MESSAGE)&Msg, (PPORT_MESSAGE)&Msg);
#if DBG
if (!NT_SUCCESS(Status)) {
DbgPrint("ReplyMessageToTerminalServer: rc=0x%x\n", Status);
}
#endif
NtClose(PortHandle);
return (Status);
}
NTSTATUS ReplyInvalidWindowToTerminalServer (HWND hWnd, ULONG ulSessionId)
{
WINSTATION_APIMSG Msg;
NTSTATUS Status;
HANDLE PortHandle;
/*
* Connect to Session Mgr
*/
Status = ConnectToTerminalServer(0, &PortHandle);
if (!NT_SUCCESS(Status)) {
return (Status);
}
Msg.h.u1.s1.DataLength = sizeof(Msg) - sizeof(PORT_MESSAGE);
Msg.h.u1.s1.TotalLength = sizeof(Msg);
Msg.h.u2.s2.Type = 0; // Kernel will fill in message type
Msg.h.u2.s2.DataInfoOffset = 0;
Msg.WaitForReply = FALSE;
Msg.ApiNumber = SMWinStationWindowInvalid;
Msg.ReturnedStatus = 0;
Msg.u.WindowInvalid.hWnd = HandleToULong(hWnd);
Msg.u.WindowInvalid.SessionId = ulSessionId;
Status = NtRequestPort(PortHandle, (PPORT_MESSAGE)&Msg);
#if DBG
if (!NT_SUCCESS(Status)) {
DbgPrint("ReplyInvalidWindowToTerminalServer: rc=0x%x\n", Status);
}
#endif
NtClose(PortHandle);
return (Status);
}
/*******************************************************************************
*
* ShadowHotkey
*
* ENTRY:
* none
*
* EXIT:
* STATUS_SUCCESS - successful
*
******************************************************************************/
NTSTATUS
ShadowHotkey()
{
WINSTATION_APIMSG Msg;
NTSTATUS Status;
/*
* Connect to Session Mgr
*/
if (WinStationIcaApiPort == NULL) {
Status = ConnectToTerminalServer(0, &WinStationIcaApiPort);
if (!NT_SUCCESS(Status)) {
return (Status);
}
}
Msg.h.u1.s1.DataLength = sizeof(Msg) - sizeof(PORT_MESSAGE);
Msg.h.u1.s1.TotalLength = sizeof(Msg);
Msg.h.u2.s2.Type = 0; // Kernel will fill in message type
Msg.h.u2.s2.DataInfoOffset = 0;
Msg.WaitForReply = TRUE;
Msg.ApiNumber = SMWinStationIcaShadowHotkey;
Msg.ReturnedStatus = 0;
Status = NtRequestWaitReplyPort(WinStationIcaApiPort, (PPORT_MESSAGE)&Msg, (PPORT_MESSAGE)&Msg);
#if DBG
if (!NT_SUCCESS(Status)) {
DbgPrint("ShadowHotkey: rc=0x%x\n", Status);
}
#endif
return (Status);
}