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.

346 lines
7.5 KiB

  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "windows.h"
  5. unsigned char writebuff[10][10000];
  6. OVERLAPPED WriteOl[10];
  7. HANDLE hFile;
  8. HANDLE StartTrailingWriteEvent;
  9. HANDLE EndedTrailingWrites;
  10. DWORD
  11. QueueOtherWrites(
  12. LPVOID Trash
  13. )
  14. {
  15. DWORD k;
  16. UNREFERENCED_PARAMETER(Trash);
  17. WaitForSingleObject(StartTrailingWriteEvent,-1);
  18. printf("Wait Satisfied Sleeping for 3 seconds\n");
  19. Sleep(3000);
  20. for (
  21. k = 5;
  22. k <= 9;
  23. k++
  24. ) {
  25. DWORD NumberWritten;
  26. BOOL WriteDone;
  27. WriteDone = WriteFile(
  28. hFile,
  29. writebuff[k],
  30. 10000,
  31. &NumberWritten,
  32. &WriteOl[k]
  33. );
  34. if (!WriteDone) {
  35. DWORD LastError;
  36. LastError = GetLastError();
  37. if (LastError != ERROR_IO_PENDING) {
  38. printf("Status of failed write %d is: %d\n",k,LastError);
  39. }
  40. }
  41. }
  42. printf("Trailing Writes are all queued thread waits until all are done\n");
  43. WaitForSingleObject(EndedTrailingWrites,-1);
  44. return 1;
  45. }
  46. void main(int argc,char *argv[]) {
  47. DCB MyDcb;
  48. char *MyPort = "COM1";
  49. DWORD j;
  50. DWORD ThreadId;
  51. DWORD Errors;
  52. COMSTAT LocalStat;
  53. if (argc > 1) {
  54. MyPort = argv[1];
  55. }
  56. for (
  57. j = 0;
  58. j <= 9;
  59. j++
  60. ) {
  61. if (!(WriteOl[j].hEvent = CreateEvent(
  62. NULL,
  63. FALSE,
  64. FALSE,
  65. NULL
  66. ))) {
  67. printf("Could not create the write event %d.\n",j);
  68. } else {
  69. WriteOl[j].Internal = 0;
  70. WriteOl[j].InternalHigh = 0;
  71. WriteOl[j].Offset = 0;
  72. WriteOl[j].OffsetHigh = 0;
  73. }
  74. }
  75. if (!(StartTrailingWriteEvent = CreateEvent(
  76. NULL,
  77. TRUE,
  78. FALSE,
  79. NULL
  80. ))) {
  81. printf("Could not create trailing write event\n");
  82. goto cleanup;
  83. }
  84. if (!(EndedTrailingWrites = CreateEvent(
  85. NULL,
  86. TRUE,
  87. FALSE,
  88. NULL
  89. ))) {
  90. printf("Could not create ending trailing write event\n");
  91. goto cleanup;
  92. }
  93. if ((hFile = CreateFile(
  94. MyPort,
  95. GENERIC_READ | GENERIC_WRITE,
  96. 0,
  97. NULL,
  98. CREATE_ALWAYS,
  99. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  100. NULL
  101. )) != ((HANDLE)-1)) {
  102. printf("We successfully opened the %s port.\n",MyPort);
  103. //
  104. // Create the thread that will wait for the
  105. // trailing write event before it queues its reads.
  106. //
  107. if (!CreateThread(
  108. NULL,
  109. 0,
  110. QueueOtherWrites,
  111. NULL,
  112. 0,
  113. &ThreadId
  114. )) {
  115. printf("Could not create the second thread.\n");
  116. goto cleanup;
  117. }
  118. //
  119. // We've successfully opened the file. Set the state of
  120. // the comm device. First we get the old values and
  121. // adjust to our own.
  122. //
  123. if (!GetCommState(
  124. hFile,
  125. &MyDcb
  126. )) {
  127. printf("Couldn't get the comm state: %d\n",GetLastError());
  128. exit(1);
  129. }
  130. MyDcb.BaudRate = 19200;
  131. MyDcb.ByteSize = 8;
  132. MyDcb.Parity = NOPARITY;
  133. MyDcb.StopBits = ONESTOPBIT;
  134. if (SetCommState(
  135. hFile,
  136. &MyDcb
  137. )) {
  138. DWORD k;
  139. for (
  140. k = 0;
  141. k <= 4;
  142. k++
  143. ) {
  144. DWORD NumberWritten;
  145. BOOL WriteDone;
  146. WriteDone = WriteFile(
  147. hFile,
  148. writebuff[k],
  149. 10000,
  150. &NumberWritten,
  151. &WriteOl[k]
  152. );
  153. if (!WriteDone) {
  154. DWORD LastError;
  155. LastError = GetLastError();
  156. if (LastError != ERROR_IO_PENDING) {
  157. printf("Status of failed write %d is: %d\n",k,LastError);
  158. goto cleanup;
  159. }
  160. }
  161. }
  162. SetEvent(StartTrailingWriteEvent);
  163. if (!FlushFileBuffers(hFile)) {
  164. printf("Couldn't flush %d\n",GetLastError());
  165. } else {
  166. printf("Flushed\n");
  167. }
  168. //
  169. // Insure that the first five writes are done.
  170. //
  171. for (
  172. k = 0;
  173. k <= 4;
  174. k++
  175. ) {
  176. DWORD NumberTransferred;
  177. if (!GetOverlappedResult(
  178. hFile,
  179. &WriteOl[k],
  180. &NumberTransferred,
  181. FALSE
  182. )) {
  183. printf("Write %d was not complete!!\n",k);
  184. } else {
  185. if (NumberTransferred != 10000) {
  186. printf("Write %d transferred only %d bytes\n",k,NumberTransferred);
  187. }
  188. }
  189. }
  190. //
  191. // Wrap around until the count is zero.
  192. //
  193. LocalStat.cbOutQue = 1;
  194. while (LocalStat.cbOutQue) {
  195. if (!ClearCommError(
  196. hFile,
  197. &Errors,
  198. &LocalStat
  199. )) {
  200. printf("Couldn't call ClearCommError: %d\n",GetLastError());
  201. exit(1);
  202. }
  203. if (Errors) {
  204. printf("For some odd reason we had errors: %x\n",Errors);
  205. }
  206. printf("Currently in output queue: %d\n",LocalStat.cbOutQue);
  207. Sleep(2000);
  208. }
  209. //
  210. // Wait for the last writes to complete.
  211. //
  212. for (
  213. k = 9;
  214. k >= 5;
  215. k--
  216. ) {
  217. DWORD NumberTransferred;
  218. if (!GetOverlappedResult(
  219. hFile,
  220. &WriteOl[k],
  221. &NumberTransferred,
  222. TRUE
  223. )) {
  224. printf("Bad status from write %d status is %d\n",k,GetLastError());
  225. } else {
  226. if (NumberTransferred != 10000) {
  227. printf("Write %d transferred only %d bytes\n",k,NumberTransferred);
  228. }
  229. }
  230. }
  231. SetEvent(EndedTrailingWrites);
  232. } else {
  233. printf("Couldn't set the comm state\n");
  234. }
  235. } else {
  236. printf("Couldn't open the comm port\n");
  237. }
  238. cleanup:;
  239. }