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.

475 lines
11 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. tmsserv.c
  5. Abstract:
  6. This module contains a user mode mailslot server test program.
  7. This test program can be built from the command line using the
  8. command 'nmake UMTEST=tmsserv'.
  9. Author:
  10. Manny Weiser (mannyw) 11-Jan-91
  11. Revision History:
  12. --*/
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <ntioapi.h>
  18. //
  19. // Local definitions
  20. //
  21. BOOLEAN
  22. CreateMailslot(
  23. PSZ Name,
  24. PHANDLE Handle
  25. );
  26. BOOLEAN
  27. QueryDirectoryTest(
  28. VOID
  29. );
  30. BOOLEAN
  31. QueryInfoTest(
  32. HANDLE Handle
  33. );
  34. BOOLEAN
  35. PeekTest(
  36. HANDLE Handle
  37. );
  38. BOOLEAN
  39. ReadTest(
  40. HANDLE Handle
  41. );
  42. VOID
  43. DisplayUsage(
  44. PSZ ProgramName
  45. );
  46. VOID
  47. DisplayTime(
  48. IN PLARGE_INTEGER
  49. );
  50. DisplayUnicode(
  51. IN WCHAR *UnicodeString,
  52. IN ULONG Length
  53. );
  54. #define MESSAGE_SIZE 100L
  55. #define MAILSLOT_SIZE (10 * MESSAGE_SIZE)
  56. #define PEEK_PARAMETER_BYTES 16
  57. #define READ_PARAMETER_BYTES 16
  58. #define MAILSLOT_PARAMETER_BYTES 16 // Max of peek and read param bytes
  59. char Buffer[1000];
  60. int
  61. main(argc, argv)
  62. int argc;
  63. char **argv;
  64. {
  65. HANDLE handle;
  66. ULONG ms, time;
  67. LARGE_INTEGER delayTime;
  68. int i;
  69. if (argc < 2) {
  70. DisplayUsage(argv[0]);
  71. return 1;
  72. }
  73. if ( !CreateMailslot( argv[1], &handle ) ) {
  74. return 2;
  75. }
  76. for (i = 2; i < argc; i++) {
  77. switch ( *argv[i] ) {
  78. case 'r':
  79. if ( !ReadTest( handle ) ) {
  80. return 3;
  81. }
  82. break;
  83. case 'd':
  84. if ( !QueryDirectoryTest() ) {
  85. return 3;
  86. }
  87. break;
  88. case 'p':
  89. if ( !PeekTest( handle ) ) {
  90. return 3;
  91. }
  92. break;
  93. case 'q':
  94. if ( !QueryInfoTest( handle ) ) {
  95. return 3;
  96. }
  97. break;
  98. case 's':
  99. time = atoi( argv[i] + 1);
  100. printf( "%s: sleeping for %lu tenths of a second\n",
  101. argv[0],
  102. time );
  103. ms = time * 100;
  104. delayTime = LiNMul( ms, -10000 );
  105. NtDelayExecution( TRUE, (PLARGE_INTEGER)&delayTime );
  106. printf ("%s: awake\n", argv[0] );
  107. break;
  108. default:
  109. printf ("Unknown test ""%s""\n", argv[i] );
  110. break;
  111. }
  112. }
  113. printf( "Closing file\n" );
  114. NtClose( handle );
  115. printf( "%s exiting\n", argv[0] );
  116. return 0;
  117. }
  118. VOID
  119. DisplayUsage(
  120. PSZ ProgramName
  121. )
  122. {
  123. printf( "Usage: %s \\Device\\Mailslot\\Msname\n", ProgramName);
  124. }
  125. BOOLEAN
  126. CreateMailslot(
  127. PSZ Name,
  128. PHANDLE Handle
  129. )
  130. {
  131. NTSTATUS status;
  132. STRING ansiString;
  133. UNICODE_STRING nameString;
  134. OBJECT_ATTRIBUTES objectAttributes;
  135. IO_STATUS_BLOCK ioStatusBlock;
  136. LARGE_INTEGER readTimeout = { -1, -1 }; // Infinite read timeout
  137. RtlInitString(&ansiString, Name );
  138. RtlOemStringToUnicodeString(&nameString, &ansiString, TRUE);
  139. InitializeObjectAttributes(
  140. &objectAttributes,
  141. &nameString,
  142. OBJ_CASE_INSENSITIVE,
  143. NULL,
  144. NULL
  145. );
  146. printf( "Attempting to create mailslot \"%wZ\"\n", &nameString );
  147. status = NtCreateMailslotFile (
  148. Handle,
  149. GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
  150. &objectAttributes,
  151. &ioStatusBlock,
  152. 0,
  153. 0,
  154. MESSAGE_SIZE,
  155. &readTimeout
  156. );
  157. printf( "Open Status = %lx\n", status );
  158. RtlFreeUnicodeString(&nameString);
  159. return ( (BOOLEAN) NT_SUCCESS(status));
  160. }
  161. BOOLEAN
  162. QueryDirectoryTest(
  163. VOID
  164. )
  165. {
  166. HANDLE rootDirHandle;
  167. BOOLEAN done;
  168. IO_STATUS_BLOCK ioStatusBlock;
  169. OBJECT_ATTRIBUTES objectAttributes;
  170. UNICODE_STRING nameString;
  171. NTSTATUS status;
  172. PFILE_FULL_DIR_INFORMATION dirInfo;
  173. RtlInitUnicodeString(&nameString, L"\\Device\\Mailslot\\" );
  174. InitializeObjectAttributes(
  175. &objectAttributes,
  176. &nameString,
  177. OBJ_CASE_INSENSITIVE,
  178. NULL,
  179. NULL
  180. );
  181. printf( "Attempting to open mailslot directory \"%wZ\"\n", &nameString );
  182. status = NtOpenFile (
  183. &rootDirHandle,
  184. GENERIC_READ,
  185. &objectAttributes,
  186. &ioStatusBlock,
  187. 0,
  188. 0L
  189. );
  190. RtlFreeUnicodeString(&nameString);
  191. printf( "MSFS root dir open status = %lx\n", status );
  192. status = NtQueryDirectoryFile(
  193. rootDirHandle,
  194. 0,
  195. NULL,
  196. NULL,
  197. &ioStatusBlock,
  198. (PVOID)Buffer,
  199. sizeof(Buffer),
  200. FileFullDirectoryInformation,
  201. FALSE,
  202. NULL,
  203. FALSE );
  204. printf("Query directory status = %lx\n", status );
  205. printf("Query directory information %d\n", ioStatusBlock.Information );
  206. if ( NT_SUCCESS( status )) {
  207. done = FALSE;
  208. dirInfo = (PFILE_FULL_DIR_INFORMATION)Buffer;
  209. } else {
  210. done = TRUE;
  211. }
  212. while (!done) {
  213. printf ("NextEntry = %d\n", dirInfo->NextEntryOffset);
  214. printf ("FileIndex = %ld\n", dirInfo->FileIndex );
  215. printf ("CreationTime = ");
  216. DisplayTime( &dirInfo->CreationTime );
  217. printf ("\nLastAccessTime = ");
  218. DisplayTime( &dirInfo->LastAccessTime );
  219. printf ("\nLastWriteTime = ");
  220. DisplayTime( &dirInfo->LastWriteTime );
  221. printf ("\nChangeTime = ");
  222. DisplayTime( &dirInfo->ChangeTime );
  223. printf ("\nEnd of file = %lx%08lx\n",
  224. dirInfo->EndOfFile.HighPart,
  225. dirInfo->EndOfFile.LowPart );
  226. printf ("Allocation size = %lx%08lx\n",
  227. dirInfo->AllocationSize.HighPart,
  228. dirInfo->AllocationSize.LowPart );
  229. printf ("File attributes = %x\n", dirInfo->FileAttributes );
  230. printf ("File name length = %x\n", dirInfo->FileNameLength );
  231. printf ("EA size = %x\n", dirInfo->EaSize );
  232. printf ("File Name = ");
  233. DisplayUnicode( dirInfo->FileName, dirInfo->FileNameLength );
  234. printf ("\n\n");
  235. if (dirInfo->NextEntryOffset == 0) {
  236. done = TRUE;
  237. }
  238. dirInfo = (PFILE_FULL_DIR_INFORMATION)
  239. ((PCHAR)dirInfo + dirInfo->NextEntryOffset);
  240. }
  241. return( (BOOLEAN)NT_SUCCESS( status ));
  242. }
  243. BOOLEAN
  244. QueryInfoTest(
  245. HANDLE Handle
  246. )
  247. {
  248. PFILE_BASIC_INFORMATION basicInfo;
  249. PFILE_STANDARD_INFORMATION standardInfo;
  250. PFILE_INTERNAL_INFORMATION internalInfo;
  251. PFILE_EA_INFORMATION eaInfo;
  252. PFILE_POSITION_INFORMATION positionInfo;
  253. PFILE_NAME_INFORMATION nameInfo;
  254. NTSTATUS status;
  255. IO_STATUS_BLOCK ioStatusBlock;
  256. status = NtQueryInformationFile( Handle,
  257. &ioStatusBlock,
  258. Buffer,
  259. MESSAGE_SIZE,
  260. FileAllInformation );
  261. printf ("\nBasic Information:\n");
  262. basicInfo = (PFILE_BASIC_INFORMATION)Buffer;
  263. printf (" Creation time: " );
  264. DisplayTime( &basicInfo->CreationTime );
  265. printf ("\n Last access time: " );
  266. DisplayTime( &basicInfo->LastAccessTime );
  267. printf ("\n Last write time: " );
  268. DisplayTime( &basicInfo->LastWriteTime );
  269. printf ("\n Change time: " );
  270. DisplayTime( &basicInfo->ChangeTime );
  271. printf ("\n");
  272. printf ("\nStandard Information:\n");
  273. standardInfo = (PFILE_STANDARD_INFORMATION)(basicInfo + 1);
  274. printf (" Number of links: %ld\n", standardInfo->NumberOfLinks );
  275. printf (" Delete pending : %ld\n", standardInfo->DeletePending );
  276. printf (" Directory : %ld\n", standardInfo->Directory );
  277. printf ("\nInternal Information:\n");
  278. internalInfo = (PFILE_INTERNAL_INFORMATION)(standardInfo + 1);
  279. printf (" Index Number : %ld\n", internalInfo->IndexNumber );
  280. printf ("\nEa Information:\n");
  281. eaInfo = (PFILE_EA_INFORMATION)(internalInfo + 1);
  282. printf (" No ea info\n" );
  283. printf ("\nPosition Information:\n");
  284. positionInfo = (PFILE_POSITION_INFORMATION)(eaInfo+1);
  285. printf (" Current offset: %ld\n", positionInfo->CurrentByteOffset );
  286. printf ("\nName Information:\n");
  287. nameInfo = (PFILE_NAME_INFORMATION)(positionInfo + 1);
  288. printf (" File name length: %ld\n", nameInfo->FileNameLength );
  289. printf (" File name : ");
  290. DisplayUnicode( nameInfo->FileName, nameInfo->FileNameLength );
  291. putchar ('\n');
  292. return TRUE;
  293. }
  294. BOOLEAN
  295. PeekTest(
  296. HANDLE Handle
  297. )
  298. {
  299. FILE_MAILSLOT_PEEK_BUFFER mailslotPeekBuffer;
  300. NTSTATUS status;
  301. IO_STATUS_BLOCK ioStatusBlock;
  302. status = NtFsControlFile (
  303. Handle,
  304. 0L,
  305. NULL,
  306. NULL,
  307. &ioStatusBlock,
  308. FSCTL_MAILSLOT_PEEK,
  309. &mailslotPeekBuffer,
  310. sizeof(mailslotPeekBuffer),
  311. Buffer,
  312. MESSAGE_SIZE );
  313. printf( " ReadDataAvailable = %lx\n", mailslotPeekBuffer.ReadDataAvailable );
  314. printf( " NumberOfMessages = %lx\n", mailslotPeekBuffer.NumberOfMessages);
  315. printf( " MessageLength = %lx\n", mailslotPeekBuffer.MessageLength);
  316. return ( (BOOLEAN) NT_SUCCESS( status ) );
  317. }
  318. BOOLEAN
  319. ReadTest(
  320. HANDLE Handle
  321. )
  322. {
  323. IO_STATUS_BLOCK ioStatusBlock;
  324. NTSTATUS status;
  325. status = NtReadFile(
  326. Handle,
  327. 0L,
  328. NULL,
  329. NULL,
  330. &ioStatusBlock,
  331. Buffer,
  332. MESSAGE_SIZE,
  333. NULL,
  334. NULL);
  335. if (NT_SUCCESS(status)) {
  336. status = NtWaitForSingleObject( Handle, TRUE, NULL );
  337. printf( "NtWaitForSingleObject returns %lx\n", status );
  338. status = ioStatusBlock.Status;
  339. }
  340. printf( "NtReadFileFinalStatus returns %lx\n", status );
  341. if (NT_SUCCESS(status)) {
  342. printf ("message is ""%s""\n", Buffer );
  343. }
  344. return ( (BOOLEAN)NT_SUCCESS( status ) );
  345. }
  346. VOID
  347. DisplayTime(
  348. IN PLARGE_INTEGER Time
  349. )
  350. {
  351. TIME_FIELDS timeFields;
  352. RtlTimeToTimeFields( Time, &timeFields );
  353. printf("%02d/%02d/%04d @ %02d:%02d:%02d.%d",
  354. timeFields.Month,
  355. timeFields.Day,
  356. timeFields.Year,
  357. timeFields.Hour,
  358. timeFields.Minute,
  359. timeFields.Second,
  360. timeFields.Milliseconds );
  361. }
  362. DisplayUnicode(
  363. IN WCHAR *UnicodeString,
  364. IN ULONG Length
  365. )
  366. {
  367. while (Length > 0) {
  368. putchar( (CHAR)*UnicodeString );
  369. UnicodeString++;
  370. Length -= 2;
  371. }
  372. return 0;
  373. }