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.

372 lines
8.6 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. HANDLE hFile;
  28. ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
  29. SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
  30. //
  31. // Configure the new channel
  32. //
  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. // open dump file
  52. //
  53. hFile = CreateFile(
  54. L"emsvtutf8.txt",
  55. GENERIC_WRITE, // open for writing
  56. 0, // do not share
  57. NULL, // no security
  58. CREATE_ALWAYS, // overwrite existing
  59. FILE_ATTRIBUTE_NORMAL, // normal file
  60. NULL); // no attr. template
  61. if (hFile == INVALID_HANDLE_VALUE)
  62. {
  63. return 0;
  64. }
  65. //
  66. // Perform thread work
  67. //
  68. i=0;
  69. while (1) {
  70. Status = WaitForSingleObject(
  71. ChannelThreadData->ExitEvent,
  72. THREAD_WAIT_TIMEOUT
  73. );
  74. if (Status != WAIT_TIMEOUT) {
  75. CloseHandle(hFile);
  76. break;
  77. }
  78. //
  79. // See if there is data to echo
  80. //
  81. bStatus = Channel->HasNewData(&InputWaiting);
  82. if (InputWaiting) {
  83. //
  84. // Read from channel
  85. //
  86. bStatus = Channel->Read(
  87. Buffer,
  88. sizeof(Buffer),
  89. &ByteCount
  90. );
  91. if (bStatus) {
  92. //
  93. // Dump to a file
  94. //
  95. WriteFile(
  96. hFile,
  97. Buffer,
  98. ByteCount,
  99. &i,
  100. NULL
  101. );
  102. //
  103. // Echo to the channel
  104. //
  105. bStatus = Channel->Write(
  106. Buffer,
  107. ByteCount
  108. );
  109. if (! bStatus) {
  110. printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
  111. }
  112. } else {
  113. printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
  114. }
  115. }
  116. }
  117. delete Channel;
  118. return 0;
  119. }
  120. DWORD
  121. ChannelThreadRawEcho(
  122. PVOID Data
  123. )
  124. {
  125. EMSRawChannel* Channel;
  126. PCHANNEL_THREAD_DATA ChannelThreadData;
  127. DWORD Status;
  128. ULONG i;
  129. BYTE Buffer[256];
  130. ULONG ByteCount;
  131. BOOL bStatus;
  132. BOOL InputWaiting;
  133. HANDLE hFile;
  134. ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
  135. SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
  136. //
  137. // Configure the new channel
  138. //
  139. RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
  140. Attributes.Type = ChannelTypeRaw;
  141. Attributes.Name = ChannelThreadData->ChannelName;
  142. Attributes.Description = ChannelThreadData->ChannelDescription;
  143. Attributes.Flags = 0;
  144. Attributes.CloseEvent = NULL;
  145. Attributes.HasNewDataEvent = NULL;
  146. Attributes.ApplicationType = NULL;
  147. //
  148. // Open the Hello channel
  149. //
  150. Channel = EMSRawChannel::Construct(Attributes);
  151. //
  152. // See if the channel was created
  153. //
  154. if (Channel == NULL) {
  155. return 0;
  156. }
  157. //
  158. // open dump file
  159. //
  160. hFile = CreateFile(
  161. L"emsraw.txt",
  162. GENERIC_WRITE, // open for writing
  163. 0, // do not share
  164. NULL, // no security
  165. CREATE_ALWAYS, // overwrite existing
  166. FILE_ATTRIBUTE_NORMAL, // normal file
  167. NULL); // no attr. template
  168. if (hFile == INVALID_HANDLE_VALUE)
  169. {
  170. return 0;
  171. }
  172. //
  173. // Perform thread work
  174. //
  175. i=0;
  176. while (1) {
  177. Status = WaitForSingleObject(
  178. ChannelThreadData->ExitEvent,
  179. THREAD_WAIT_TIMEOUT
  180. );
  181. if (Status != WAIT_TIMEOUT) {
  182. CloseHandle(hFile);
  183. break;
  184. }
  185. //
  186. // See if there is data to echo
  187. //
  188. bStatus = Channel->HasNewData(&InputWaiting);
  189. if (InputWaiting) {
  190. //
  191. // Read from channel
  192. //
  193. bStatus = Channel->Read(
  194. Buffer,
  195. sizeof(Buffer),
  196. &ByteCount
  197. );
  198. if (bStatus) {
  199. //
  200. // Dump to a file
  201. //
  202. WriteFile(
  203. hFile,
  204. Buffer,
  205. ByteCount,
  206. &i,
  207. NULL
  208. );
  209. //
  210. // Echo to the channel
  211. //
  212. bStatus = Channel->Write(
  213. Buffer,
  214. ByteCount
  215. );
  216. if (! bStatus) {
  217. printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
  218. }
  219. } else {
  220. printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
  221. }
  222. }
  223. }
  224. delete Channel;
  225. return 0;
  226. }
  227. DWORD (*ChannelTests[THREADCOUNT])(PVOID) = {
  228. ChannelThreadVTUTF8Echo,
  229. ChannelThreadRawEcho
  230. };
  231. int _cdecl
  232. wmain(
  233. int argc,
  234. WCHAR **argv
  235. )
  236. {
  237. HANDLE Channel[THREADCOUNT];
  238. CHANNEL_THREAD_DATA ChannelData[THREADCOUNT];
  239. HANDLE ExitEvent;
  240. ULONG i;
  241. ExitEvent = CreateEvent(
  242. NULL, // no security attributes
  243. TRUE, // manual-reset event
  244. FALSE, // initial state is signaled
  245. NULL // object name
  246. );
  247. if (ExitEvent == NULL) {
  248. return 1;
  249. }
  250. //
  251. // create the worker threads
  252. //
  253. for (i = 0; i < THREADCOUNT; i++) {
  254. //
  255. // populate the thread data structure
  256. //
  257. ChannelData[i].ExitEvent = ExitEvent;
  258. wsprintf(
  259. ChannelData[i].ChannelName,
  260. L"CT%02d",
  261. i
  262. );
  263. ChannelData[i].ChannelDescription[0] = UNICODE_NULL;
  264. //
  265. // create the thread
  266. //
  267. Channel[i] = CreateThread(
  268. NULL,
  269. 0,
  270. ChannelTests[i],
  271. &(ChannelData[i]),
  272. 0,
  273. NULL
  274. );
  275. if (Channel[i] == NULL) {
  276. goto cleanup;
  277. }
  278. }
  279. //
  280. // wait for local user to end the stress
  281. //
  282. getc(stdin);
  283. cleanup:
  284. SetEvent(ExitEvent);
  285. WaitForMultipleObjects(
  286. THREADCOUNT,
  287. Channel,
  288. TRUE,
  289. INFINITE
  290. );
  291. for (i = 0; i < THREADCOUNT; i++) {
  292. CloseHandle(Channel[i]);
  293. }
  294. return 0;
  295. }