Source code of Windows XP (NT5)
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.

380 lines
9.0 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Non-network I/O support.
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000-2001.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "pch.hpp"
  9. #include <kdbg1394.h>
  10. #include <ntdd1394.h>
  11. //----------------------------------------------------------------------------
  12. //
  13. // COM.
  14. //
  15. //----------------------------------------------------------------------------
  16. HRESULT
  17. CreateOverlappedPair(LPOVERLAPPED Read, LPOVERLAPPED Write)
  18. {
  19. ZeroMemory(Read, sizeof(*Read));
  20. ZeroMemory(Write, sizeof(*Write));
  21. Read->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  22. if (Read->hEvent == NULL)
  23. {
  24. return WIN32_LAST_STATUS();
  25. }
  26. Write->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  27. if (Write->hEvent == NULL)
  28. {
  29. CloseHandle(Read->hEvent);
  30. return WIN32_LAST_STATUS();
  31. }
  32. return S_OK;
  33. }
  34. BOOL
  35. ComPortRead(HANDLE Port, PVOID Buffer, ULONG Len, PULONG Done,
  36. LPOVERLAPPED Olap)
  37. {
  38. BOOL Status;
  39. Status = ReadFile(Port, Buffer, Len, Done, Olap);
  40. if (!Status)
  41. {
  42. if (GetLastError() == ERROR_IO_PENDING)
  43. {
  44. Status = GetOverlappedResult(Port, Olap, Done, TRUE);
  45. }
  46. else
  47. {
  48. DWORD TrashErr;
  49. COMSTAT TrashStat;
  50. // Device could be locked up. Clear it just in case.
  51. ClearCommError(Port, &TrashErr, &TrashStat);
  52. }
  53. }
  54. return Status;
  55. }
  56. BOOL
  57. ComPortWrite(HANDLE Port, PVOID Buffer, ULONG Len, PULONG Done,
  58. LPOVERLAPPED Olap)
  59. {
  60. BOOL Status;
  61. Status = WriteFile(Port, Buffer, Len, Done, Olap);
  62. if (!Status)
  63. {
  64. if (GetLastError() == ERROR_IO_PENDING)
  65. {
  66. Status = GetOverlappedResult(Port, Olap, Done, TRUE);
  67. }
  68. else
  69. {
  70. DWORD TrashErr;
  71. COMSTAT TrashStat;
  72. // Device could be locked up. Clear it just in case.
  73. ClearCommError(Port, &TrashErr, &TrashStat);
  74. }
  75. }
  76. return Status;
  77. }
  78. void
  79. SetComPortName(PCSTR Name, PSTR Buffer)
  80. {
  81. if (*Name == 'c' || *Name == 'C')
  82. {
  83. strcpy(Buffer, "\\\\.\\");
  84. strcpy(Buffer + 4, Name);
  85. }
  86. else if (*Name >= '0' && *Name <= '9')
  87. {
  88. PCSTR Scan = Name + 1;
  89. while (*Scan >= '0' && *Scan <= '9')
  90. {
  91. Scan++;
  92. }
  93. if (*Scan == 0)
  94. {
  95. // The name was all digits so assume it's
  96. // a plain com port number.
  97. #ifndef NT_NATIVE
  98. strcpy(Buffer, "\\\\.\\com");
  99. #else
  100. strcpy(Buffer, "\\Device\\Serial");
  101. #endif
  102. strcat(Buffer, Name);
  103. }
  104. else
  105. {
  106. strcpy(Buffer, Name);
  107. }
  108. }
  109. else
  110. {
  111. strcpy(Buffer, Name);
  112. }
  113. }
  114. ULONG
  115. SelectComPortBaud(ULONG NewRate)
  116. {
  117. #define NUM_RATES 4
  118. static DWORD s_Rates[NUM_RATES] = {19200, 38400, 57600, 115200};
  119. static DWORD s_CurRate = NUM_RATES;
  120. DWORD i;
  121. if (NewRate > 0)
  122. {
  123. for (i = 0; NewRate > s_Rates[i] && i < NUM_RATES - 1; i++)
  124. {
  125. // Empty.
  126. }
  127. s_CurRate = (NewRate < s_Rates[i]) ? i : i + 1;
  128. }
  129. else
  130. {
  131. s_CurRate++;
  132. }
  133. if (s_CurRate >= NUM_RATES)
  134. {
  135. s_CurRate = 0;
  136. }
  137. return s_Rates[s_CurRate];
  138. }
  139. HRESULT
  140. SetComPortBaud(HANDLE Port, ULONG NewRate, PULONG RateSet)
  141. {
  142. ULONG OldRate;
  143. DCB LocalDcb;
  144. if (Port == NULL)
  145. {
  146. return E_FAIL;
  147. }
  148. if (!GetCommState(Port, &LocalDcb))
  149. {
  150. return WIN32_LAST_STATUS();
  151. }
  152. OldRate = LocalDcb.BaudRate;
  153. if (!NewRate)
  154. {
  155. NewRate = SelectComPortBaud(OldRate);
  156. }
  157. LocalDcb.BaudRate = NewRate;
  158. LocalDcb.ByteSize = 8;
  159. LocalDcb.Parity = NOPARITY;
  160. LocalDcb.StopBits = ONESTOPBIT;
  161. LocalDcb.fDtrControl = DTR_CONTROL_ENABLE;
  162. LocalDcb.fRtsControl = RTS_CONTROL_ENABLE;
  163. LocalDcb.fBinary = TRUE;
  164. LocalDcb.fOutxCtsFlow = FALSE;
  165. LocalDcb.fOutxDsrFlow = FALSE;
  166. LocalDcb.fOutX = FALSE;
  167. LocalDcb.fInX = FALSE;
  168. if (!SetCommState(Port, &LocalDcb))
  169. {
  170. return WIN32_LAST_STATUS();
  171. }
  172. *RateSet = NewRate;
  173. return S_OK;
  174. }
  175. HRESULT
  176. OpenComPort(PSTR Port, ULONG BaudRate, ULONG Timeout,
  177. PHANDLE Handle, PULONG BaudSet)
  178. {
  179. HANDLE ComHandle;
  180. #ifndef NT_NATIVE
  181. ComHandle = CreateFile(Port,
  182. GENERIC_READ | GENERIC_WRITE,
  183. 0,
  184. NULL,
  185. OPEN_ALWAYS,
  186. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  187. NULL);
  188. #else
  189. ComHandle = NtNativeCreateFileA(Port,
  190. GENERIC_READ | GENERIC_WRITE,
  191. 0,
  192. NULL,
  193. OPEN_ALWAYS,
  194. FILE_ATTRIBUTE_NORMAL |
  195. FILE_FLAG_OVERLAPPED,
  196. NULL,
  197. FALSE);
  198. #endif
  199. if (ComHandle == INVALID_HANDLE_VALUE)
  200. {
  201. return WIN32_LAST_STATUS();
  202. }
  203. if (!SetupComm(ComHandle, 4096, 4096))
  204. {
  205. CloseHandle(ComHandle);
  206. return WIN32_LAST_STATUS();
  207. }
  208. HRESULT Status;
  209. if ((Status = SetComPortBaud(ComHandle, BaudRate, BaudSet)) != S_OK)
  210. {
  211. CloseHandle(ComHandle);
  212. return Status;
  213. }
  214. COMMTIMEOUTS To;
  215. if (Timeout)
  216. {
  217. To.ReadIntervalTimeout = 0;
  218. To.ReadTotalTimeoutMultiplier = 0;
  219. To.ReadTotalTimeoutConstant = Timeout;
  220. To.WriteTotalTimeoutMultiplier = 0;
  221. To.WriteTotalTimeoutConstant = Timeout;
  222. }
  223. else
  224. {
  225. To.ReadIntervalTimeout = 0;
  226. To.ReadTotalTimeoutMultiplier = 0xffffffff;
  227. To.ReadTotalTimeoutConstant = 0xffffffff;
  228. To.WriteTotalTimeoutMultiplier = 0xffffffff;
  229. To.WriteTotalTimeoutConstant = 0xffffffff;
  230. }
  231. if (!SetCommTimeouts(ComHandle, &To))
  232. {
  233. CloseHandle(ComHandle);
  234. return WIN32_LAST_STATUS();
  235. }
  236. *Handle = ComHandle;
  237. return S_OK;
  238. }
  239. //----------------------------------------------------------------------------
  240. //
  241. // 1394.
  242. //
  243. //----------------------------------------------------------------------------
  244. HRESULT
  245. Create1394Channel(ULONG Channel, PSTR Name, PHANDLE Handle)
  246. {
  247. char BusName[] = "\\\\.\\1394BUS0";
  248. HANDLE hDevice;
  249. //
  250. // we need to make sure the 1394vdbg driver is up and loaded.
  251. // send the ADD_DEVICE ioctl to eject the VDO
  252. // Assume one 1394 host controller...
  253. //
  254. hDevice = CreateFile(BusName,
  255. GENERIC_READ | GENERIC_WRITE,
  256. FILE_SHARE_READ | FILE_SHARE_WRITE,
  257. NULL,
  258. OPEN_ALWAYS,
  259. FILE_ATTRIBUTE_NORMAL,
  260. NULL
  261. );
  262. if (hDevice != INVALID_HANDLE_VALUE)
  263. {
  264. char DeviceId[] = "VIRTUAL_HOST_DEBUGGER";
  265. ULONG ulStrLen;
  266. PIEEE1394_API_REQUEST pApiReq;
  267. PIEEE1394_VDEV_PNP_REQUEST pDevPnpReq;
  268. DWORD dwBytesRet;
  269. ulStrLen = strlen(DeviceId) + 1;
  270. pApiReq = (PIEEE1394_API_REQUEST)
  271. malloc(sizeof(IEEE1394_API_REQUEST) + ulStrLen);
  272. if (pApiReq == NULL)
  273. {
  274. CloseHandle(hDevice);
  275. return E_OUTOFMEMORY;
  276. }
  277. pApiReq->RequestNumber = IEEE1394_API_ADD_VIRTUAL_DEVICE;
  278. pApiReq->Flags = IEEE1394_REQUEST_FLAG_PERSISTENT |
  279. IEEE1394_REQUEST_FLAG_USE_LOCAL_HOST_EUI;
  280. pDevPnpReq = &pApiReq->u.RemoveVirtualDevice;
  281. pDevPnpReq->fulFlags = 0;
  282. pDevPnpReq->Reserved = 0;
  283. pDevPnpReq->InstanceId.QuadPart = 0;
  284. strncpy((PSZ)&pDevPnpReq->DeviceId, DeviceId, ulStrLen);
  285. // Failure of this call is not fatal.
  286. DeviceIoControl( hDevice,
  287. IOCTL_IEEE1394_API_REQUEST,
  288. pApiReq,
  289. sizeof(IEEE1394_API_REQUEST)+ulStrLen,
  290. NULL,
  291. 0,
  292. &dwBytesRet,
  293. NULL
  294. );
  295. if (pApiReq)
  296. {
  297. free(pApiReq);
  298. }
  299. CloseHandle(hDevice);
  300. }
  301. else
  302. {
  303. return WIN32_LAST_STATUS();
  304. }
  305. return Open1394Channel(Channel, Name, Handle);
  306. }
  307. HRESULT
  308. Open1394Channel(ULONG Channel, PSTR Name, PHANDLE Handle)
  309. {
  310. sprintf(Name, "\\\\.\\DBG1394_CHANNEL%02d", Channel);
  311. *Handle = CreateFile(Name,
  312. GENERIC_READ | GENERIC_WRITE,
  313. FILE_SHARE_READ | FILE_SHARE_WRITE,
  314. NULL,
  315. OPEN_ALWAYS,
  316. FILE_ATTRIBUTE_NORMAL,
  317. NULL
  318. );
  319. if (*Handle == INVALID_HANDLE_VALUE)
  320. {
  321. return WIN32_LAST_STATUS();
  322. }
  323. return S_OK;
  324. }