Windows2003-3790/termsrv/newclient/rdpdr/utl.cpp
2020-09-30 16:53:55 +02:00

304 lines
7.0 KiB
C++

/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name:
utl.cpp
Abstract:
Misc. Shared and Platform-Indepdent Utilities for the RDP Client
Device Redirector
Author:
Tad Brockway
Revision History:
--*/
#include <precom.h>
#define TRC_FILE "utl"
#include "utl.h"
#include "atrcapi.h"
#include "drdbg.h"
DWORD
GetUserSessionID()
{
DC_BEGIN_FN("GetUserSessionID");
//
// Fetch user TS session ID
//
DWORD tsSessionId = INVALID_SESSIONID;
HMODULE hKernel32 = NULL;
PROCESSIDTOSESSIONID hGetProcAddress;
BOOL bSuccess = FALSE;
hKernel32 = LoadLibrary( TEXT("KERNEL32.DLL") );
if( hKernel32 ) {
#ifndef OS_WINCE
hGetProcAddress = (PROCESSIDTOSESSIONID)GetProcAddress( hKernel32, "ProcessIdToSessionId");
#else
hGetProcAddress = (PROCESSIDTOSESSIONID)GetProcAddress( hKernel32, L"ProcessIdToSessionId");
#endif
if( NULL != hGetProcAddress ) {
bSuccess = (hGetProcAddress)( GetCurrentProcessId(), &tsSessionId );
if (!bSuccess) {
tsSessionId = INVALID_SESSIONID;
}
}
}
if( NULL != hKernel32 ) {
FreeLibrary( hKernel32) ;
}
DC_END_FN();
return tsSessionId;
}
NTSTATUS DrUTL_CheckIOBufInputSize(
IN PRDPDR_IOREQUEST_PACKET pIoReq,
IN ULONG requiredSize
)
/*++
Routine Description:
Confirm that the IOCTL input buffer matches the expected size.
Arguments:
pIoReq - Request packet from server.
requiredSize - Expected size.
Return Value:
None
--*/
{
DC_BEGIN_FN("DrUTL_CheckIOBufInputSize");
NTSTATUS status;
if (pIoReq->IoRequest.Parameters.DeviceIoControl.InputBufferLength <
requiredSize) {
status = STATUS_BUFFER_TOO_SMALL;
ASSERT(FALSE);
}
else {
status = STATUS_SUCCESS;
}
DC_END_FN();
return status;
}
NTSTATUS DrUTL_CheckIOBufOutputSize(
IN PRDPDR_IOREQUEST_PACKET pIoReq,
IN ULONG requiredSize
)
/*++
Routine Description:
Confirm that the IOCTL output buf matches the expected size.
Arguments:
pIoReq - Request packet from server.
requiredSize - Expected size.
Return Value:
None
--*/
{
DC_BEGIN_FN("DrUTL_CheckIOBufOutputSize");
NTSTATUS status;
if (pIoReq->IoRequest.Parameters.DeviceIoControl.OutputBufferLength <
requiredSize) {
status = STATUS_BUFFER_TOO_SMALL;
ASSERT(FALSE);
}
else {
status = STATUS_SUCCESS;
}
DC_END_FN();
return status;
}
NTSTATUS
DrUTL_AllocateReplyBuf(
IN PRDPDR_IOREQUEST_PACKET pIoReq,
OUT PRDPDR_IOCOMPLETION_PACKET *pReplyPacket,
OUT ULONG *replyPacketSize
)
/*++
Routine Description:
Allocate a reply buffer to be returned in response to a server
request.
Arguments:
pIoReq - Request packet from server.
pReplyPacket - Reply packet is returned here.
replyPacketSize - Size of reply packet is returned here.
Return Value:
None
--*/
{
DC_BEGIN_FN("DrUTL_AllocateReplyBuf");
NTSTATUS status = STATUS_SUCCESS;
*replyPacketSize = (ULONG)FIELD_OFFSET(
RDPDR_IOCOMPLETION_PACKET,
IoCompletion.Parameters.DeviceIoControl.OutputBuffer) +
pIoReq->IoRequest.Parameters.DeviceIoControl.OutputBufferLength;
*pReplyPacket = DrUTL_AllocIOCompletePacket(pIoReq, *replyPacketSize) ;
if (*pReplyPacket == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
TRC_ERR((TB, _T("Failed to alloc %ld bytes."),*replyPacketSize));
}
else {
status = STATUS_SUCCESS;
}
DC_END_FN();
return status;
}
PRDPDR_IOCOMPLETION_PACKET
DrUTL_AllocIOCompletePacket(
IN const PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN ULONG sz
)
/*++
Routine Description:
Allocate/release a IO request completion packet for a specified IO
request packet.
Arguments:
pIoRequestPacket - IO request from server.
Return Value:
None
--*/
{
PRDPDR_IOCOMPLETION_PACKET ppIoComp;
PRDPDR_DEVICE_IOREQUEST pIoRequest;
DC_BEGIN_FN("DrUTL_AllocIOCompletePacket");
//
// Get IO request pointer.
//
pIoRequest = &pIoRequestPacket->IoRequest;
ppIoComp = (PRDPDR_IOCOMPLETION_PACKET)new BYTE[ sz ];
if( ppIoComp != NULL ) {
memset(ppIoComp, 0, (size_t)sz);
ppIoComp->IoCompletion.DeviceId = pIoRequest->DeviceId;
ppIoComp->IoCompletion.CompletionId = pIoRequest->CompletionId;
ppIoComp->Header.Component = RDPDR_CTYP_CORE;
ppIoComp->Header.PacketId = DR_CORE_DEVICE_IOCOMPLETION;
}
else {
TRC_ERR((TB, _T("Alloc failed.")));
}
DC_END_FN();
return ppIoComp;
}
VOID DrUTL_FreeIOCompletePacket(
IN PRDPDR_IOCOMPLETION_PACKET packet
)
/*++
Routine Description:
Free an IO complete packet allocated by DrUTL_AllocIOCompletePacket.
Arguments:
packet - Packet to free.
Return Value:
None
--*/
{
DC_BEGIN_FN("DrUTL_FreeIOCompletePacket");
delete []((BYTE *)packet);
DC_END_FN();
}
#ifdef OS_WINCE
ULONG GetActivePortsList(TCHAR *pszPort)
{
DC_BEGIN_FN("GetActivePortsList");
ULONG ulPorts = 0;
TCHAR szActive[] = _T("Drivers\\Active");
HKEY hkActive = NULL;
int nPortLen = _tcslen(pszPort);
if ((ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szActive, 0, 0, &hkActive)) && (hkActive != NULL))
{
TCHAR szName[64];
DWORD dwCount = sizeof(szName)/sizeof(TCHAR);
DWORD dwIndex = 0;
while ((ERROR_SUCCESS == RegEnumKeyEx(hkActive, dwIndex++, szName, &dwCount, NULL, NULL, NULL, NULL)) &&
(dwCount < (sizeof(szName)/sizeof(TCHAR)) ))
{
HKEY hk = NULL;
TCHAR szValue[MAX_PATH];
DWORD dwType = 0;
DWORD dwSize = sizeof(szValue);
if ((ERROR_SUCCESS == RegOpenKeyEx(hkActive, szName, 0, 0, &hk)) &&
(hk != NULL) &&
(ERROR_SUCCESS == RegQueryValueEx(hk, _T("Name"), NULL, &dwType, (LPBYTE )szValue, &dwSize)) &&
(dwType == REG_SZ) && (dwSize < sizeof(szValue)) && (0 == _tcsncmp(pszPort, szValue, nPortLen)) &&
(_tcslen(szValue) == 5) && (szValue[4] == _T(':')) && ((szValue[3] - _T('0')) < 10) )
{
int nPortNum = szValue[3] - _T('0');
TRC_ASSERT( ((ulPorts & (1 << nPortNum)) == 0), (TB, _T("Duplicate port found!")));
ulPorts |= (1 << nPortNum);
}
if (hk)
RegCloseKey(hk);
dwCount = sizeof(szName)/sizeof(TCHAR);
}
RegCloseKey(hkActive);
}
DC_END_FN();
return ulPorts;
}
#endif