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

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name :
  4. serport.cpp
  5. Abstract:
  6. Serial port Device object handles one redirected serial port
  7. Revision History:
  8. --*/
  9. #include "precomp.hxx"
  10. #define TRC_FILE "serport"
  11. #include "trc.h"
  12. extern PDEVICE_OBJECT RDPDYN_PDO; // This still needs a happier home
  13. // remove this ... when I find out where I really need to be accessing this.
  14. const GUID GUID_CLASS_COMPORT =
  15. { 0x86e0d1e0L, 0x8089, 0x11d0, { 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73 } };
  16. DrSerialPort::DrSerialPort(SmartPtr<DrSession> &Session, ULONG DeviceType, ULONG DeviceId,
  17. PUCHAR PreferredDosName) : DrPrinterPort(Session, DeviceType, DeviceId, PreferredDosName)
  18. {
  19. BEGIN_FN("DrSerialPort::DrSerialPort");
  20. SetClassName("DrSerialPort");
  21. _PortType = FILE_DEVICE_SERIAL_PORT;
  22. }
  23. NTSTATUS DrSerialPort::Initialize(PRDPDR_DEVICE_ANNOUNCE DeviceAnnounce, ULONG Length)
  24. {
  25. NTSTATUS Status;
  26. BEGIN_FN("DrSerialPort::Initialize");
  27. if (ShouldCreatePort()) {
  28. Status = DrPrinterPort::Initialize(DeviceAnnounce, Length);
  29. if (NT_SUCCESS(Status) && _Session->GetClientCapabilitySet().PortCap.version > 0) {
  30. Status = CreateSerialPort(DeviceAnnounce);
  31. }
  32. }
  33. else {
  34. Status = STATUS_SUCCESS;
  35. }
  36. return Status;
  37. }
  38. BOOL DrSerialPort::ShouldCreatePrinter()
  39. {
  40. BEGIN_FN("DrSerialPort::ShouldCreatePrinter");
  41. return FALSE;
  42. }
  43. BOOL DrSerialPort::ShouldCreatePort()
  44. {
  45. BEGIN_FN("DrSerialPort::ShouldCreatePort");
  46. return !_Session->DisableComPortMapping();
  47. }
  48. NTSTATUS DrSerialPort::CreateSerialPort(PRDPDR_DEVICE_ANNOUNCE devAnnounceMsg)
  49. {
  50. NTSTATUS Status;
  51. UNICODE_STRING PortName;
  52. WCHAR PortNameBuff[PREFERRED_DOS_NAME_SIZE];
  53. USHORT OemCodePage, AnsiCodePage;
  54. NTSTATUS status;
  55. INT len, comLen;
  56. ULONG portAnnounceEventReqSize;
  57. PRDPDR_PORTDEVICE_SUB portAnnounceEvent;
  58. BEGIN_FN("DrSerialPort::CreateSerialPort");
  59. //
  60. // Convert the com name
  61. //
  62. PortName.MaximumLength = sizeof(PortNameBuff);
  63. PortName.Length = 0;
  64. PortName.Buffer = &PortNameBuff[0];
  65. memset(&PortNameBuff, 0, sizeof(PortNameBuff));
  66. comLen = strlen((char *)_PreferredDosName);
  67. RtlGetDefaultCodePage(&AnsiCodePage,&OemCodePage);
  68. len = ConvertToAndFromWideChar(AnsiCodePage, PortName.Buffer,
  69. PortName.MaximumLength, (char *)_PreferredDosName,
  70. comLen, TRUE);
  71. if (len != -1) {
  72. //
  73. // We need just the COMx portion for later...
  74. //
  75. PortName.Length = (USHORT)len;
  76. PortName.Buffer[len/sizeof(WCHAR)] = L'\0';
  77. } else {
  78. TRC_ERR((TB, "Error converting comName"));
  79. return STATUS_UNSUCCESSFUL;
  80. }
  81. //
  82. // Allocate the port device announce buffer.
  83. //
  84. Status = CreatePortAnnounceEvent(devAnnounceMsg, NULL, 0, L"",
  85. &portAnnounceEventReqSize);
  86. ASSERT(Status == STATUS_BUFFER_TOO_SMALL);
  87. if (Status != STATUS_BUFFER_TOO_SMALL) {
  88. goto CleanUpAndReturn;
  89. }
  90. portAnnounceEvent = (PRDPDR_PORTDEVICE_SUB)new(NonPagedPool)
  91. BYTE[portAnnounceEventReqSize];
  92. if (portAnnounceEvent == NULL) {
  93. TRC_ERR((TB, "Unable to allocate portAnnounceEvent"));
  94. Status = STATUS_NO_MEMORY;
  95. goto CleanUpAndReturn;
  96. }
  97. //
  98. // Create the port anounce message.
  99. //
  100. Status = CreatePortAnnounceEvent(devAnnounceMsg, portAnnounceEvent,
  101. portAnnounceEventReqSize, PortName.Buffer, NULL);
  102. if (Status != STATUS_SUCCESS) {
  103. delete portAnnounceEvent;
  104. #if DBG
  105. portAnnounceEvent = NULL;
  106. #endif
  107. goto CleanUpAndReturn;
  108. }
  109. //
  110. // Dispatch the event to the associated session.
  111. //
  112. Status = RDPDYN_DispatchNewDevMgmtEvent(
  113. portAnnounceEvent,
  114. _Session->GetSessionId(),
  115. RDPDREVT_PORTANNOUNCE,
  116. NULL
  117. );
  118. //
  119. // Create the device map entry.
  120. //
  121. // Where you might normally have:
  122. // Value Name Value
  123. // \Device\Serial0 COM1
  124. //
  125. // We will put:
  126. // Value Name Value
  127. // COM1 COM1
  128. //
  129. //
  130. status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, L"SERIALCOMM",
  131. PortName.Buffer, REG_SZ,
  132. PortName.Buffer,
  133. PortName.Length + sizeof(WCHAR));
  134. CleanUpAndReturn:
  135. return Status;
  136. }