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.

314 lines
7.0 KiB

  1. #include <windows.h>
  2. #include <winioctl.h>
  3. #include <stdio.h>
  4. #include <malloc.h>
  5. #include <ntddsac.h>
  6. #include <emsapi.h>
  7. #define THREAD_WAIT_TIMEOUT 100
  8. #define THREADCOUNT 2
  9. typedef struct _CHANNEL_THREAD_DATA {
  10. HANDLE ExitEvent;
  11. WCHAR ChannelName[SAC_MAX_CHANNEL_NAME_LENGTH];
  12. WCHAR ChannelDescription[SAC_MAX_CHANNEL_DESCRIPTION_LENGTH];
  13. } CHANNEL_THREAD_DATA, *PCHANNEL_THREAD_DATA;
  14. DWORD
  15. ChannelThreadVTUTF8Echo(
  16. PVOID Data
  17. )
  18. {
  19. EMSVTUTF8Channel* Channel;
  20. PCHANNEL_THREAD_DATA ChannelThreadData;
  21. DWORD Status;
  22. ULONG i;
  23. WCHAR Buffer[256];
  24. ULONG ByteCount;
  25. BOOL bStatus;
  26. BOOL InputWaiting;
  27. ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
  28. SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
  29. //
  30. // Configure the new channel
  31. //
  32. RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
  33. Attributes.Type = ChannelTypeVTUTF8;
  34. Attributes.Name = ChannelThreadData->ChannelName;
  35. Attributes.Description = ChannelThreadData->ChannelDescription;
  36. Attributes.Flags = 0;
  37. Attributes.CloseEvent = NULL;
  38. Attributes.HasNewDataEvent = NULL;
  39. Attributes.ApplicationType = NULL;
  40. //
  41. // Open the Hello channel
  42. //
  43. Channel = EMSVTUTF8Channel::Construct(Attributes);
  44. //
  45. // See if the channel was created
  46. //
  47. if (Channel == NULL) {
  48. return 0;
  49. }
  50. //
  51. // Perform thread work
  52. //
  53. i=0;
  54. while (1) {
  55. Status = WaitForSingleObject(
  56. ChannelThreadData->ExitEvent,
  57. THREAD_WAIT_TIMEOUT
  58. );
  59. if (Status != WAIT_TIMEOUT) {
  60. break;
  61. }
  62. //
  63. // See if there is data to echo
  64. //
  65. bStatus = Channel->HasNewData(&InputWaiting);
  66. if (InputWaiting) {
  67. //
  68. // Read from channel
  69. //
  70. bStatus = Channel->Read(
  71. Buffer,
  72. sizeof(Buffer),
  73. &ByteCount
  74. );
  75. if (bStatus) {
  76. //
  77. // Echo to the channel
  78. //
  79. bStatus = Channel->Write(
  80. Buffer,
  81. ByteCount
  82. );
  83. if (! bStatus) {
  84. printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
  85. }
  86. } else {
  87. printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
  88. }
  89. }
  90. }
  91. delete Channel;
  92. return 0;
  93. }
  94. DWORD
  95. ChannelThreadRawEcho(
  96. PVOID Data
  97. )
  98. {
  99. EMSRawChannel* Channel;
  100. PCHANNEL_THREAD_DATA ChannelThreadData;
  101. DWORD Status;
  102. ULONG i;
  103. BYTE Buffer[256];
  104. ULONG ByteCount;
  105. BOOL bStatus;
  106. BOOL InputWaiting;
  107. ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
  108. SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
  109. //
  110. // Configure the new channel
  111. //
  112. RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
  113. Attributes.Type = ChannelTypeRaw;
  114. Attributes.Name = ChannelThreadData->ChannelName;
  115. Attributes.Description = ChannelThreadData->ChannelDescription;
  116. Attributes.Flags = 0;
  117. Attributes.CloseEvent = NULL;
  118. Attributes.HasNewDataEvent = NULL;
  119. Attributes.ApplicationType = NULL;
  120. //
  121. // Open the Hello channel
  122. //
  123. Channel = EMSRawChannel::Construct(Attributes);
  124. //
  125. // See if the channel was created
  126. //
  127. if (Channel == NULL) {
  128. return 0;
  129. }
  130. //
  131. // Perform thread work
  132. //
  133. i=0;
  134. while (1) {
  135. Status = WaitForSingleObject(
  136. ChannelThreadData->ExitEvent,
  137. THREAD_WAIT_TIMEOUT
  138. );
  139. if (Status != WAIT_TIMEOUT) {
  140. break;
  141. }
  142. //
  143. // See if there is data to echo
  144. //
  145. bStatus = Channel->HasNewData(&InputWaiting);
  146. if (InputWaiting) {
  147. //
  148. // Read from channel
  149. //
  150. bStatus = Channel->Read(
  151. Buffer,
  152. sizeof(Buffer),
  153. &ByteCount
  154. );
  155. if (bStatus) {
  156. //
  157. // Echo to the channel
  158. //
  159. bStatus = Channel->Write(
  160. Buffer,
  161. ByteCount
  162. );
  163. if (! bStatus) {
  164. printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
  165. }
  166. } else {
  167. printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
  168. }
  169. }
  170. }
  171. delete Channel;
  172. return 0;
  173. }
  174. DWORD (*ChannelTests[THREADCOUNT])(PVOID) = {
  175. ChannelThreadVTUTF8Echo,
  176. ChannelThreadRawEcho
  177. };
  178. int _cdecl
  179. wmain(
  180. int argc,
  181. WCHAR **argv
  182. )
  183. {
  184. HANDLE Channel[THREADCOUNT];
  185. CHANNEL_THREAD_DATA ChannelData[THREADCOUNT];
  186. HANDLE ExitEvent;
  187. ULONG i;
  188. ExitEvent = CreateEvent(
  189. NULL, // no security attributes
  190. TRUE, // manual-reset event
  191. FALSE, // initial state is signaled
  192. NULL // object name
  193. );
  194. if (ExitEvent == NULL) {
  195. return 1;
  196. }
  197. //
  198. // create the worker threads
  199. //
  200. for (i = 0; i < THREADCOUNT; i++) {
  201. //
  202. // populate the thread data structure
  203. //
  204. ChannelData[i].ExitEvent = ExitEvent;
  205. wsprintf(
  206. ChannelData[i].ChannelName,
  207. L"CT%02d",
  208. i
  209. );
  210. ChannelData[i].ChannelDescription[0] = UNICODE_NULL;
  211. //
  212. // create the thread
  213. //
  214. Channel[i] = CreateThread(
  215. NULL,
  216. 0,
  217. ChannelTests[i],
  218. &(ChannelData[i]),
  219. 0,
  220. NULL
  221. );
  222. if (Channel[i] == NULL) {
  223. goto cleanup;
  224. }
  225. }
  226. //
  227. // wait for local user to end the stress
  228. //
  229. getc(stdin);
  230. cleanup:
  231. SetEvent(ExitEvent);
  232. WaitForMultipleObjects(
  233. THREADCOUNT,
  234. Channel,
  235. TRUE,
  236. INFINITE
  237. );
  238. for (i = 0; i < THREADCOUNT; i++) {
  239. CloseHandle(Channel[i]);
  240. }
  241. return 0;
  242. }