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.

337 lines
7.7 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. w32drcom
  5. Abstract:
  6. This module defines the parent for the Win32 client-side RDP
  7. COM port redirection "device" class hierarchy, W32DrCOM.
  8. Author:
  9. Tad Brockway 3/23/99
  10. Revision History:
  11. --*/
  12. #include <precom.h>
  13. #define TRC_FILE "W32DrCOM"
  14. #include "w32drcom.h"
  15. #include "drobjmgr.h"
  16. #include "proc.h"
  17. #include "drconfig.h"
  18. #include "drdbg.h"
  19. ///////////////////////////////////////////////////////////////
  20. //
  21. // W32DrCOM Members
  22. //
  23. //
  24. W32DrCOM::W32DrCOM(
  25. IN ProcObj *procObj,
  26. IN const DRSTRING portName,
  27. IN ULONG deviceID,
  28. IN const TCHAR *devicePath
  29. ) : W32DrPRT(procObj, portName, deviceID, devicePath)
  30. /*++
  31. Routine Description:
  32. Constructor
  33. Arguments:
  34. processObject - Associated process object.
  35. portName - Name of the port.
  36. id - Device ID for the port.
  37. devicePath - Path that can be opened by CreateFile
  38. for port.
  39. Return Value:
  40. NA
  41. --*/
  42. {
  43. }
  44. #ifndef OS_WINCE
  45. DWORD
  46. W32DrCOM::Enumerate(
  47. IN ProcObj *procObj,
  48. IN DrDeviceMgr *deviceMgr
  49. )
  50. /*++
  51. Routine Description:
  52. Enumerate devices of this type by adding appropriate device
  53. instances to the device manager.
  54. Arguments:
  55. procObj - Corresponding process object.
  56. deviceMgr - Device manager to add devices to.
  57. Return Value:
  58. ERROR_SUCCESS on success. Otherwise, an error code is returned.
  59. --*/
  60. {
  61. ULONG ulPortNum;
  62. TCHAR path[MAX_PATH];
  63. DrDevice *deviceObj;
  64. TCHAR portName[64];
  65. ULONG comPortMax;
  66. DC_BEGIN_FN("W32DrCOM::Enumerate");
  67. if(!procObj->GetVCMgr().GetInitData()->fEnableRedirectPorts)
  68. {
  69. TRC_DBG((TB,_T("Port redirection disabled, bailing out")));
  70. return ERROR_SUCCESS;
  71. }
  72. comPortMax = GetCOMPortMax(procObj);
  73. //
  74. // Scan COM ports.
  75. //
  76. for (ulPortNum=0; ulPortNum<=comPortMax; ulPortNum++) {
  77. StringCchPrintf(portName,
  78. SIZE_TCHARS(portName),
  79. _T("COM%ld"), ulPortNum);
  80. #ifndef OS_WINCE
  81. StringCchPrintf(path,
  82. SIZE_TCHARS(path),
  83. TEXT("\\\\.\\%s"), portName);
  84. #else
  85. StringCchPrintf(path,
  86. SIZE_TCHARS(path),
  87. TEXT("%s:"), portName);
  88. #endif
  89. HANDLE hndl = CreateFile(
  90. path,
  91. GENERIC_READ | GENERIC_WRITE,
  92. 0, // exclusive access
  93. NULL, // no security attrs
  94. OPEN_EXISTING,
  95. FILE_ATTRIBUTE_NORMAL |
  96. FILE_FLAG_OVERLAPPED, // overlapped I/O
  97. NULL
  98. );
  99. if ((hndl != INVALID_HANDLE_VALUE) ||
  100. (GetLastError() != ERROR_FILE_NOT_FOUND)){
  101. #ifndef OS_WINCE
  102. TCHAR TargetPath[MAX_PATH];
  103. #endif
  104. CloseHandle(hndl);
  105. #ifndef OS_WINCE
  106. if (procObj->Is9x() || QueryDosDevice(portName, TargetPath, sizeof(TargetPath) / sizeof(TCHAR))) {
  107. if (_tcsstr(TargetPath, TEXT("RdpDr")) == NULL) {
  108. #endif
  109. //
  110. // Create a new COM port device object.
  111. //
  112. TRC_NRM((TB, _T("Adding COM Device %s."), path));
  113. deviceObj = new W32DrCOM(procObj, portName,
  114. deviceMgr->GetUniqueObjectID(), path);
  115. //
  116. // Add to the device manager if we got a valid object.
  117. //
  118. if (deviceObj != NULL) {
  119. deviceObj->Initialize();
  120. if (!(deviceObj->IsValid() &&
  121. (deviceMgr->AddObject(deviceObj) == STATUS_SUCCESS))) {
  122. delete deviceObj;
  123. }
  124. }
  125. #ifndef OS_WINCE
  126. }
  127. }
  128. #endif
  129. }
  130. }
  131. DC_END_FN();
  132. return ERROR_SUCCESS;
  133. }
  134. #else
  135. DWORD
  136. W32DrCOM::Enumerate(
  137. IN ProcObj *procObj,
  138. IN DrDeviceMgr *deviceMgr
  139. )
  140. {
  141. ULONG ulPortNum;
  142. TCHAR path[MAX_PATH];
  143. DrDevice *deviceObj;
  144. TCHAR portName[64];
  145. DC_BEGIN_FN("W32DrCOM::Enumerate");
  146. if(!procObj->GetVCMgr().GetInitData()->fEnableRedirectPorts)
  147. {
  148. TRC_DBG((TB,_T("Port redirection disabled, bailing out")));
  149. return ERROR_SUCCESS;
  150. }
  151. ulPortNum = GetActivePortsList(L"COM");
  152. if (ulPortNum == 0)
  153. {
  154. TRC_DBG((TB,_T("No COM ports found.")));
  155. return ERROR_SUCCESS;
  156. }
  157. TRC_ASSERT(((ulPortNum & 0xFFFFFC00) == 0), (TB, _T("COM Port numbers > 9 found!")));
  158. for (ULONG i=0; i<10; i++)
  159. {
  160. if ( (ulPortNum & (1 << i)) == 0)
  161. continue;
  162. _stprintf(portName, _T("COM%ld"), i);
  163. _stprintf(path, TEXT("%s:"), portName);
  164. //
  165. // Create a new COM port device object.
  166. //
  167. TRC_NRM((TB, _T("Adding COM Device %s."), path));
  168. deviceObj = new W32DrCOM(procObj, portName,
  169. deviceMgr->GetUniqueObjectID(), path);
  170. //
  171. // Add to the device manager if we got a valid object.
  172. //
  173. if (deviceObj != NULL) {
  174. deviceObj->Initialize();
  175. if (!(deviceObj->IsValid() &&
  176. (deviceMgr->AddObject(deviceObj) == STATUS_SUCCESS))) {
  177. delete deviceObj;
  178. }
  179. }
  180. }
  181. DC_END_FN();
  182. return ERROR_SUCCESS;
  183. }
  184. #endif
  185. DWORD
  186. W32DrCOM::GetCOMPortMax(
  187. IN ProcObj *procObj
  188. )
  189. /*++
  190. Routine Description:
  191. Returns the configurable COM port max ID.
  192. Arguments:
  193. procObj - The relevant process object.
  194. Return Value:
  195. COM Port Max.
  196. --*/
  197. {
  198. DWORD returnValue;
  199. //
  200. // Read the COM Port Max out of the Registry
  201. //
  202. if (procObj->GetDWordParameter(RDPDR_COM_PORT_MAX_PARAM, &returnValue)
  203. != ERROR_SUCCESS ) {
  204. // Default
  205. returnValue = RDPDR_COM_PORT_MAX_PARAM_DEFAULT;
  206. }
  207. return returnValue;
  208. }
  209. DWORD
  210. W32DrCOM::InitializeDevice(IN DrFile* fileObj)
  211. /*++
  212. Routine Description:
  213. Initialize serial port to default state.
  214. Arguments:
  215. fileObj - DrFile that has been created by MsgIrpCreate()
  216. Return Value:
  217. ERROR_SUCCESS or error code.
  218. --*/
  219. {
  220. HANDLE FileHandle;
  221. LPTSTR portName;
  222. DC_BEGIN_FN("W32DrCOM::InitializeDevice");
  223. //
  224. // Our devicePath is formulated as
  225. // sprintf(_devicePath, TEXT("\\\\.\\%s"), portName);
  226. //
  227. portName = _tcsrchr( _devicePath, _T('\\') );
  228. if( portName == NULL ) {
  229. // invalid device path
  230. goto CLEANUPANDEXIT;
  231. }
  232. portName++;
  233. if( !*portName ) {
  234. //
  235. // Invalid port name
  236. //
  237. goto CLEANUPANDEXIT;
  238. }
  239. //
  240. // Get the file handle.
  241. //
  242. FileHandle = fileObj->GetFileHandle();
  243. if (!FileHandle || FileHandle == INVALID_HANDLE_VALUE) {
  244. ASSERT(FALSE);
  245. TRC_ERR((TB, _T("File Object was not created successfully")));
  246. goto CLEANUPANDEXIT;
  247. }
  248. W32DrPRT::InitializeSerialPort(portName, FileHandle);
  249. CLEANUPANDEXIT:
  250. DC_END_FN();
  251. //
  252. // This function always returns success. If the port cannot
  253. // be initialized, then subsequent port commands will fail
  254. // anyway.
  255. //
  256. return ERROR_SUCCESS;
  257. }