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.
 
 
 
 
 
 

171 lines
4.6 KiB

/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name :
serport.cpp
Abstract:
Serial port Device object handles one redirected serial port
Revision History:
--*/
#include "precomp.hxx"
#define TRC_FILE "serport"
#include "trc.h"
extern PDEVICE_OBJECT RDPDYN_PDO; // This still needs a happier home
// remove this ... when I find out where I really need to be accessing this.
const GUID GUID_CLASS_COMPORT =
{ 0x86e0d1e0L, 0x8089, 0x11d0, { 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73 } };
DrSerialPort::DrSerialPort(SmartPtr<DrSession> &Session, ULONG DeviceType, ULONG DeviceId,
PUCHAR PreferredDosName) : DrPrinterPort(Session, DeviceType, DeviceId, PreferredDosName)
{
BEGIN_FN("DrSerialPort::DrSerialPort");
SetClassName("DrSerialPort");
_PortType = FILE_DEVICE_SERIAL_PORT;
}
NTSTATUS DrSerialPort::Initialize(PRDPDR_DEVICE_ANNOUNCE DeviceAnnounce, ULONG Length)
{
NTSTATUS Status;
BEGIN_FN("DrSerialPort::Initialize");
if (ShouldCreatePort()) {
Status = DrPrinterPort::Initialize(DeviceAnnounce, Length);
if (NT_SUCCESS(Status) && _Session->GetClientCapabilitySet().PortCap.version > 0) {
Status = CreateSerialPort(DeviceAnnounce);
}
}
else {
Status = STATUS_SUCCESS;
}
return Status;
}
BOOL DrSerialPort::ShouldCreatePrinter()
{
BEGIN_FN("DrSerialPort::ShouldCreatePrinter");
return FALSE;
}
BOOL DrSerialPort::ShouldCreatePort()
{
BEGIN_FN("DrSerialPort::ShouldCreatePort");
return !_Session->DisableComPortMapping();
}
NTSTATUS DrSerialPort::CreateSerialPort(PRDPDR_DEVICE_ANNOUNCE devAnnounceMsg)
{
NTSTATUS Status;
UNICODE_STRING PortName;
WCHAR PortNameBuff[PREFERRED_DOS_NAME_SIZE];
USHORT OemCodePage, AnsiCodePage;
NTSTATUS status;
INT len, comLen;
ULONG portAnnounceEventReqSize;
PRDPDR_PORTDEVICE_SUB portAnnounceEvent;
BEGIN_FN("DrSerialPort::CreateSerialPort");
//
// Convert the com name
//
PortName.MaximumLength = sizeof(PortNameBuff);
PortName.Length = 0;
PortName.Buffer = &PortNameBuff[0];
memset(&PortNameBuff, 0, sizeof(PortNameBuff));
comLen = strlen((char *)_PreferredDosName);
RtlGetDefaultCodePage(&AnsiCodePage,&OemCodePage);
len = ConvertToAndFromWideChar(AnsiCodePage, PortName.Buffer,
PortName.MaximumLength, (char *)_PreferredDosName,
comLen, TRUE);
if (len != -1) {
//
// We need just the COMx portion for later...
//
PortName.Length = (USHORT)len;
PortName.Buffer[len/sizeof(WCHAR)] = L'\0';
} else {
TRC_ERR((TB, "Error converting comName"));
return STATUS_UNSUCCESSFUL;
}
//
// Allocate the port device announce buffer.
//
Status = CreatePortAnnounceEvent(devAnnounceMsg, NULL, 0, L"",
&portAnnounceEventReqSize);
ASSERT(Status == STATUS_BUFFER_TOO_SMALL);
if (Status != STATUS_BUFFER_TOO_SMALL) {
goto CleanUpAndReturn;
}
portAnnounceEvent = (PRDPDR_PORTDEVICE_SUB)new(NonPagedPool)
BYTE[portAnnounceEventReqSize];
if (portAnnounceEvent == NULL) {
TRC_ERR((TB, "Unable to allocate portAnnounceEvent"));
Status = STATUS_NO_MEMORY;
goto CleanUpAndReturn;
}
//
// Create the port anounce message.
//
Status = CreatePortAnnounceEvent(devAnnounceMsg, portAnnounceEvent,
portAnnounceEventReqSize, PortName.Buffer, NULL);
if (Status != STATUS_SUCCESS) {
delete portAnnounceEvent;
#if DBG
portAnnounceEvent = NULL;
#endif
goto CleanUpAndReturn;
}
//
// Dispatch the event to the associated session.
//
Status = RDPDYN_DispatchNewDevMgmtEvent(
portAnnounceEvent,
_Session->GetSessionId(),
RDPDREVT_PORTANNOUNCE,
NULL
);
//
// Create the device map entry.
//
// Where you might normally have:
// Value Name Value
// \Device\Serial0 COM1
//
// We will put:
// Value Name Value
// COM1 COM1
//
//
status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, L"SERIALCOMM",
PortName.Buffer, REG_SZ,
PortName.Buffer,
PortName.Length + sizeof(WCHAR));
CleanUpAndReturn:
return Status;
}