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.

341 lines
7.8 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. ChannelThreadRawWrite(
  25. PVOID Data
  26. )
  27. {
  28. PCHANNEL_THREAD_DATA ChannelThreadData;
  29. DWORD Status;
  30. BOOL bContinue;
  31. DWORD dwRetVal;
  32. UCHAR Buffer[0x1000];
  33. ULONG BufferSize;
  34. HANDLE handles[2];
  35. ULONG i;
  36. ULONG k;
  37. HANDLE hFile;
  38. ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
  39. //
  40. // Create destination file for read data
  41. //
  42. hFile = CreateFile(
  43. L"sacloop.in",
  44. GENERIC_READ, // open for writing
  45. 0, // do not share
  46. NULL, // no security
  47. OPEN_EXISTING, // overwrite existing
  48. FILE_ATTRIBUTE_NORMAL, // normal file
  49. NULL); // no attr. template
  50. if (hFile == INVALID_HANDLE_VALUE)
  51. {
  52. return 0;
  53. }
  54. //
  55. // Perform thread work
  56. //
  57. handles[0] = ChannelThreadData->ExitEvent;
  58. handles[1] = ChannelThreadData->CloseEvent;
  59. bContinue = TRUE;
  60. while (bContinue) {
  61. dwRetVal = WaitForMultipleObjects(
  62. sizeof(handles)/sizeof(handles[0]),
  63. handles,
  64. FALSE,
  65. THREAD_WAIT_TIMEOUT
  66. );
  67. switch( dwRetVal )
  68. {
  69. case EXIT_EVENT:
  70. case CHANNEL_CLOSE_EVENT:
  71. // close
  72. bContinue = FALSE;
  73. break;
  74. case WAIT_TIMEOUT:
  75. //
  76. // write Channel::stdout
  77. //
  78. bContinue = ReadFile(
  79. hFile,
  80. &Buffer,
  81. 1,
  82. &BufferSize,
  83. NULL
  84. );
  85. if (bContinue) {
  86. bContinue = SacChannelRawWrite(
  87. ChannelThreadData->SacChannelHandle,
  88. Buffer,
  89. BufferSize
  90. );
  91. }
  92. break;
  93. default:
  94. break;
  95. }
  96. }
  97. CloseHandle(hFile);
  98. return 0;
  99. }
  100. DWORD
  101. ChannelThreadRawRead(
  102. PVOID Data
  103. )
  104. {
  105. PCHANNEL_THREAD_DATA ChannelThreadData;
  106. DWORD Status;
  107. BOOL bContinue;
  108. DWORD dwRetVal;
  109. UCHAR Buffer[0x1000];
  110. ULONG BufferSize;
  111. HANDLE handles[3];
  112. HANDLE hFile;
  113. ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
  114. //
  115. // Create destination file for read data
  116. //
  117. hFile = CreateFile(
  118. L"sacloop.out",
  119. GENERIC_WRITE, // open for writing
  120. 0, // do not share
  121. NULL, // no security
  122. CREATE_ALWAYS, // overwrite existing
  123. FILE_ATTRIBUTE_NORMAL, // normal file
  124. NULL); // no attr. template
  125. if (hFile == INVALID_HANDLE_VALUE)
  126. {
  127. return 0;
  128. }
  129. //
  130. // Perform thread work
  131. //
  132. handles[0] = ChannelThreadData->ExitEvent;
  133. handles[1] = ChannelThreadData->CloseEvent;
  134. handles[2] = ChannelThreadData->HasNewDataEvent;
  135. bContinue = TRUE;
  136. while (bContinue) {
  137. dwRetVal = WaitForMultipleObjects(
  138. sizeof(handles)/sizeof(handles[0]),
  139. handles,
  140. FALSE,
  141. INFINITE
  142. );
  143. switch( dwRetVal )
  144. {
  145. case EXIT_EVENT:
  146. case CHANNEL_CLOSE_EVENT:
  147. // close
  148. bContinue = FALSE;
  149. break;
  150. case CHANNEL_HAS_NEW_DATA_EVENT:
  151. //
  152. // read Channel::stdin
  153. //
  154. bContinue = SacChannelRead(
  155. ChannelThreadData->SacChannelHandle,
  156. (PUCHAR)Buffer,
  157. sizeof(Buffer),
  158. &BufferSize
  159. );
  160. if (bContinue) {
  161. DWORD dwBytesWritten;
  162. bContinue = WriteFile(
  163. hFile,
  164. Buffer,
  165. BufferSize,
  166. &dwBytesWritten,
  167. NULL
  168. );
  169. }
  170. break;
  171. default:
  172. break;
  173. }
  174. }
  175. CloseHandle(hFile);
  176. return 0;
  177. }
  178. DWORD (*ChannelTests[THREADCOUNT])(PVOID) = {
  179. ChannelThreadRawWrite,
  180. ChannelThreadRawRead
  181. };
  182. int _cdecl
  183. wmain(
  184. int argc,
  185. WCHAR **argv
  186. )
  187. {
  188. SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
  189. HANDLE Channel[THREADCOUNT];
  190. CHANNEL_THREAD_DATA ChannelData;
  191. ULONG i;
  192. ChannelData.ExitEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  193. ChannelData.CloseEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  194. ChannelData.HasNewDataEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  195. swprintf(
  196. ChannelData.ChannelDescription,
  197. L"simsess test channel"
  198. );
  199. swprintf(
  200. ChannelData.ChannelName,
  201. L"simsess"
  202. );
  203. //
  204. // Configure the new channel
  205. //
  206. RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
  207. Attributes.Type = ChannelTypeRaw;
  208. Attributes.Name = ChannelData.ChannelName;
  209. Attributes.Description = ChannelData.ChannelDescription;
  210. Attributes.Flags = SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT | SAC_CHANNEL_FLAG_CLOSE_EVENT;
  211. Attributes.CloseEvent = ChannelData.CloseEvent;
  212. Attributes.HasNewDataEvent = ChannelData.HasNewDataEvent;
  213. Attributes.ApplicationType = NULL;
  214. //
  215. // Open the channel
  216. //
  217. if (SacChannelOpen(
  218. &ChannelData.SacChannelHandle,
  219. &Attributes
  220. )) {
  221. printf("Successfully opened new channel\n");
  222. } else {
  223. printf("Failed to open new channel\n");
  224. goto cleanup;
  225. }
  226. //
  227. // create the worker threads
  228. //
  229. for (i = 0; i < THREADCOUNT; i++) {
  230. //
  231. // create the thread
  232. //
  233. Channel[i] = CreateThread(
  234. NULL,
  235. 0,
  236. ChannelTests[i],
  237. &ChannelData,
  238. 0,
  239. NULL
  240. );
  241. if (Channel[i] == NULL) {
  242. goto cleanup;
  243. }
  244. }
  245. //
  246. // wait for local user to end the stress
  247. //
  248. getc(stdin);
  249. cleanup:
  250. SetEvent(ChannelData.ExitEvent);
  251. WaitForMultipleObjects(
  252. THREADCOUNT,
  253. Channel,
  254. TRUE,
  255. INFINITE
  256. );
  257. for (i = 0; i < THREADCOUNT; i++) {
  258. CloseHandle(Channel[i]);
  259. }
  260. SacChannelClose(&ChannelData.SacChannelHandle);
  261. return 0;
  262. }