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.

292 lines
6.4 KiB

  1. #include <windows.h>
  2. #include <winioctl.h>
  3. #include <stdio.h>
  4. #include <malloc.h>
  5. #include <ntddsac.h>
  6. #include <sacapi.h>
  7. #include <assert.h>
  8. #define THREADCOUNT 2
  9. #define THREAD_WAIT_TIMEOUT 50
  10. enum {
  11. EXIT_EVENT = WAIT_OBJECT_0,
  12. CHANNEL_CLOSE_EVENT,
  13. CHANNEL_HAS_NEW_DATA_EVENT
  14. };
  15. typedef struct _CHANNEL_THREAD_DATA {
  16. HANDLE ExitEvent;
  17. HANDLE HasNewDataEvent;
  18. HANDLE CloseEvent;
  19. WCHAR ChannelName[SAC_MAX_CHANNEL_NAME_LENGTH];
  20. WCHAR ChannelDescription[SAC_MAX_CHANNEL_DESCRIPTION_LENGTH];
  21. SAC_CHANNEL_HANDLE SacChannelHandle;
  22. } CHANNEL_THREAD_DATA, *PCHANNEL_THREAD_DATA;
  23. DWORD
  24. ChannelThreadVTUTF8Write(
  25. PVOID Data
  26. )
  27. {
  28. PCHANNEL_THREAD_DATA ChannelThreadData;
  29. DWORD Status;
  30. BOOL bContinue;
  31. DWORD dwRetVal;
  32. WCHAR Buffer[0x1000];
  33. ULONG BufferSize;
  34. HANDLE handles[2];
  35. ULONG i;
  36. ULONG k;
  37. ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
  38. //
  39. // Perform thread work
  40. //
  41. handles[0] = ChannelThreadData->ExitEvent;
  42. handles[1] = ChannelThreadData->CloseEvent;
  43. bContinue = TRUE;
  44. k = 0;
  45. while (bContinue) {
  46. dwRetVal = WaitForMultipleObjects(
  47. sizeof(handles)/sizeof(handles[0]),
  48. handles,
  49. FALSE,
  50. 100
  51. );
  52. switch( dwRetVal )
  53. {
  54. case EXIT_EVENT:
  55. case CHANNEL_CLOSE_EVENT:
  56. // close
  57. bContinue = FALSE;
  58. break;
  59. case WAIT_TIMEOUT:
  60. for (i = 0; i < 24; i++) {
  61. //
  62. //
  63. //
  64. swprintf(
  65. Buffer,
  66. L"%08d:abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv\r\n",
  67. k++
  68. );
  69. //
  70. // Write to the Channel
  71. //
  72. if (SacChannelVTUTF8Write(
  73. ChannelThreadData->SacChannelHandle,
  74. Buffer,
  75. wcslen(Buffer)*sizeof(WCHAR)
  76. )
  77. ) {
  78. } else {
  79. printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
  80. break;
  81. }
  82. }
  83. break;
  84. default:
  85. break;
  86. }
  87. }
  88. return 0;
  89. }
  90. DWORD
  91. ChannelThreadVTUTF8Read(
  92. PVOID Data
  93. )
  94. {
  95. PCHANNEL_THREAD_DATA ChannelThreadData;
  96. DWORD Status;
  97. BOOL bContinue;
  98. DWORD dwRetVal;
  99. WCHAR Buffer[0x1000];
  100. ULONG BufferSize;
  101. HANDLE handles[2];
  102. ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
  103. //
  104. // Perform thread work
  105. //
  106. handles[0] = ChannelThreadData->ExitEvent;
  107. handles[1] = ChannelThreadData->CloseEvent;
  108. bContinue = TRUE;
  109. while (bContinue) {
  110. dwRetVal = WaitForMultipleObjects(
  111. sizeof(handles)/sizeof(handles[0]),
  112. handles,
  113. FALSE,
  114. INFINITE
  115. );
  116. switch( dwRetVal )
  117. {
  118. case EXIT_EVENT:
  119. case CHANNEL_CLOSE_EVENT:
  120. // close
  121. bContinue = FALSE;
  122. break;
  123. case WAIT_TIMEOUT:
  124. //
  125. // read Channel::stdin
  126. //
  127. bContinue = SacChannelRead(
  128. ChannelThreadData->SacChannelHandle,
  129. (PUCHAR)Buffer,
  130. sizeof(Buffer),
  131. &BufferSize
  132. );
  133. break;
  134. default:
  135. break;
  136. }
  137. }
  138. return 0;
  139. }
  140. DWORD (*ChannelTests[THREADCOUNT])(PVOID) = {
  141. ChannelThreadVTUTF8Write,
  142. ChannelThreadVTUTF8Read
  143. };
  144. int _cdecl
  145. wmain(
  146. int argc,
  147. WCHAR **argv
  148. )
  149. {
  150. SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
  151. HANDLE Channel[THREADCOUNT];
  152. CHANNEL_THREAD_DATA ChannelData;
  153. ULONG i;
  154. ChannelData.ExitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  155. ChannelData.CloseEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  156. ChannelData.HasNewDataEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  157. swprintf(
  158. ChannelData.ChannelDescription,
  159. L"simsess test channel"
  160. );
  161. swprintf(
  162. ChannelData.ChannelName,
  163. L"simsess"
  164. );
  165. //
  166. // Configure the new channel
  167. //
  168. RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
  169. Attributes.Type = ChannelTypeVTUTF8;
  170. Attributes.Name = ChannelData.ChannelName;
  171. Attributes.Description = ChannelData.ChannelDescription;
  172. Attributes.Flags = SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT | SAC_CHANNEL_FLAG_CLOSE_EVENT;
  173. Attributes.CloseEvent = ChannelData.CloseEvent;
  174. Attributes.HasNewDataEvent = ChannelData.HasNewDataEvent;
  175. Attributes.ApplicationType = NULL;
  176. //
  177. // Open the channel
  178. //
  179. if (SacChannelOpen(
  180. &ChannelData.SacChannelHandle,
  181. &Attributes
  182. )) {
  183. printf("Successfully opened new channel\n");
  184. } else {
  185. printf("Failed to open new channel\n");
  186. goto cleanup;
  187. }
  188. //
  189. // create the worker threads
  190. //
  191. for (i = 0; i < THREADCOUNT; i++) {
  192. //
  193. // create the thread
  194. //
  195. Channel[i] = CreateThread(
  196. NULL,
  197. 0,
  198. ChannelTests[i],
  199. &ChannelData,
  200. 0,
  201. NULL
  202. );
  203. if (Channel[i] == NULL) {
  204. goto cleanup;
  205. }
  206. }
  207. //
  208. // wait for local user to end the stress
  209. //
  210. getc(stdin);
  211. cleanup:
  212. SetEvent(ChannelData.ExitEvent);
  213. WaitForMultipleObjects(
  214. THREADCOUNT,
  215. Channel,
  216. TRUE,
  217. INFINITE
  218. );
  219. for (i = 0; i < THREADCOUNT; i++) {
  220. CloseHandle(Channel[i]);
  221. }
  222. return 0;
  223. }