Source code of Windows XP (NT5)
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.

376 lines
7.6 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. tmscli.c
  5. Abstract:
  6. User mode test program for the mailslot file system.
  7. This test program can be built from the command line using the
  8. command 'nmake UMTEST=tmscli'.
  9. Author:
  10. Manny Weiser (mannyw) 17-Jan-1991
  11. Revision History:
  12. --*/
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. //
  18. // Local definitions
  19. //
  20. VOID
  21. DisplayUsage(
  22. PSZ ProgramName
  23. );
  24. BOOLEAN
  25. NotifyChangeDirectoryTest(
  26. VOID
  27. );
  28. BOOLEAN
  29. QueryVolumeTest(
  30. VOID
  31. );
  32. BOOLEAN
  33. OpenMailslot(
  34. PSZ Name,
  35. PHANDLE Handle
  36. );
  37. BOOLEAN
  38. WriteTest(
  39. IN HANDLE Handle
  40. );
  41. DisplayUnicode(
  42. IN WCHAR *UnicodeString,
  43. IN ULONG Length
  44. );
  45. #define MESSAGE_SIZE 100L
  46. #define MAILSLOT_SIZE (10 * MESSAGE_SIZE)
  47. char Buffer[MESSAGE_SIZE];
  48. int
  49. main(
  50. int argc,
  51. char *argv[]
  52. )
  53. {
  54. HANDLE handle;
  55. int i;
  56. printf("\nStart %s...\n", argv[0]);
  57. for (i = 1; i < argc; i++) {
  58. switch ( *argv[i] ) {
  59. case 'h':
  60. case '?':
  61. DisplayUsage( argv[0] );
  62. break;
  63. case 'o':
  64. if ( !OpenMailslot( argv[i] + 1, &handle ) ) {
  65. return 3;
  66. }
  67. break;
  68. case 'n':
  69. if ( !NotifyChangeDirectoryTest() ) {
  70. return 3;
  71. }
  72. break;
  73. case 'c':
  74. printf( "Closing file\n" );
  75. NtClose( handle );
  76. break;
  77. case 'w':
  78. if (!WriteTest(handle)) {
  79. return 3;
  80. }
  81. break;
  82. case 'v':
  83. if (!QueryVolumeTest()) {
  84. return 3;
  85. }
  86. break;
  87. default:
  88. printf( "Unknown test ""%s"" skipped.\n", argv[i] );
  89. }
  90. }
  91. printf( "%s exiting\n", argv[0]);
  92. return 0;
  93. }
  94. BOOLEAN
  95. NotifyChangeDirectoryTest(
  96. VOID
  97. )
  98. {
  99. HANDLE rootDirHandle;
  100. UCHAR buffer[512];
  101. IO_STATUS_BLOCK ioStatusBlock;
  102. OBJECT_ATTRIBUTES objectAttributes;
  103. UNICODE_STRING nameString;
  104. NTSTATUS status;
  105. RtlInitUnicodeString( &nameString, L"\\Device\\Mailslot\\" );
  106. InitializeObjectAttributes(
  107. &objectAttributes,
  108. &nameString,
  109. OBJ_CASE_INSENSITIVE,
  110. NULL,
  111. NULL
  112. );
  113. printf( "Attempting to open mailslot directory \"%wZ\"\n", &nameString );
  114. status = NtOpenFile (
  115. &rootDirHandle,
  116. GENERIC_READ,
  117. &objectAttributes,
  118. &ioStatusBlock,
  119. 0,
  120. 0L
  121. );
  122. printf( "MSFS root dir open status = %lx\n", status );
  123. if (!NT_SUCCESS(status)) {
  124. return FALSE;
  125. }
  126. status = NtNotifyChangeDirectoryFile(
  127. rootDirHandle,
  128. (HANDLE) NULL,
  129. (PIO_APC_ROUTINE) NULL,
  130. (PVOID) NULL,
  131. &ioStatusBlock,
  132. buffer,
  133. sizeof( buffer ),
  134. FILE_NOTIFY_CHANGE_NAME |
  135. FILE_NOTIFY_CHANGE_ATTRIBUTES |
  136. FILE_NOTIFY_CHANGE_SIZE |
  137. FILE_NOTIFY_CHANGE_LAST_WRITE |
  138. FILE_NOTIFY_CHANGE_LAST_ACCESS |
  139. FILE_NOTIFY_CHANGE_CREATION |
  140. FILE_NOTIFY_CHANGE_EA |
  141. FILE_NOTIFY_CHANGE_SECURITY,
  142. FALSE );
  143. printf("Notify change directory status = %lx\n", status );
  144. if ( !NT_SUCCESS( status )) {
  145. return FALSE;
  146. }
  147. status = NtWaitForSingleObject( rootDirHandle, TRUE, NULL );
  148. printf( "NtWaitForSingleObject returns %lx\n", status );
  149. status = ioStatusBlock.Status;
  150. printf( "Find notify final status = %d\n", status );
  151. return( (BOOLEAN)NT_SUCCESS( status ));
  152. }
  153. BOOLEAN
  154. QueryVolumeTest(
  155. VOID
  156. )
  157. {
  158. HANDLE fsHandle;
  159. IO_STATUS_BLOCK ioStatusBlock;
  160. OBJECT_ATTRIBUTES objectAttributes;
  161. UNICODE_STRING nameString;
  162. NTSTATUS status;
  163. PFILE_FS_ATTRIBUTE_INFORMATION fsAttributeInfo;
  164. RtlInitUnicodeString( &nameString, L"\\Device\\Mailslot" );
  165. InitializeObjectAttributes(
  166. &objectAttributes,
  167. &nameString,
  168. OBJ_CASE_INSENSITIVE,
  169. NULL,
  170. NULL
  171. );
  172. printf( "Attempting to open mailslot fs \"%wZ\"\n", &nameString );
  173. status = NtOpenFile (
  174. &fsHandle,
  175. GENERIC_READ,
  176. &objectAttributes,
  177. &ioStatusBlock,
  178. 0,
  179. 0L
  180. );
  181. printf( "MSFS open status = %lx\n", status );
  182. if (!NT_SUCCESS(status)) {
  183. return FALSE;
  184. }
  185. status = NtQueryVolumeInformationFile(
  186. fsHandle,
  187. &ioStatusBlock,
  188. Buffer,
  189. sizeof( Buffer ),
  190. FileFsAttributeInformation );
  191. printf("Query volume status = %lx\n", status );
  192. if ( !NT_SUCCESS( status )) {
  193. return FALSE;
  194. }
  195. status = ioStatusBlock.Status;
  196. printf( "Query volume final status = %d\n", status );
  197. fsAttributeInfo = (PFILE_FS_ATTRIBUTE_INFORMATION)Buffer;
  198. printf (" FileSystemAttributes = %lx\n",
  199. fsAttributeInfo->FileSystemAttributes);
  200. printf (" MaximumComponentNameLength = %ld\n",
  201. fsAttributeInfo->MaximumComponentNameLength);
  202. printf (" FileSystemNameLength = %ld\n",
  203. fsAttributeInfo->FileSystemNameLength);
  204. printf (" FileSystemName = ");
  205. DisplayUnicode(fsAttributeInfo->FileSystemName,
  206. fsAttributeInfo->FileSystemNameLength);
  207. putchar ('\n');
  208. return( (BOOLEAN)NT_SUCCESS( status ));
  209. }
  210. VOID
  211. DisplayUsage(
  212. PSZ ProgramName
  213. )
  214. {
  215. printf( "Usage: %s \\Device\\Mailslot\\Msname\n", ProgramName);
  216. }
  217. BOOLEAN
  218. OpenMailslot(
  219. PSZ Name,
  220. PHANDLE Handle
  221. )
  222. {
  223. STRING ansiString;
  224. UNICODE_STRING nameString;
  225. NTSTATUS status;
  226. OBJECT_ATTRIBUTES objectAttributes;
  227. IO_STATUS_BLOCK ioStatusBlock;
  228. RtlInitString(&ansiString, Name );
  229. RtlOemStringToUnicodeString(&nameString, &ansiString, TRUE);
  230. //
  231. // Open the mailslot
  232. //
  233. InitializeObjectAttributes(
  234. &objectAttributes,
  235. &nameString,
  236. OBJ_CASE_INSENSITIVE,
  237. NULL,
  238. NULL
  239. );
  240. printf( "Attempting to open mailslot \"%wZ\"\n", &nameString );
  241. status = NtOpenFile (
  242. Handle,
  243. FILE_WRITE_DATA | SYNCHRONIZE,
  244. &objectAttributes,
  245. &ioStatusBlock,
  246. FILE_SHARE_WRITE | FILE_SHARE_READ,
  247. 0L
  248. );
  249. printf( "Status = %x\n", status );
  250. RtlFreeUnicodeString(&nameString);
  251. return ( (BOOLEAN) NT_SUCCESS( status ) );
  252. }
  253. BOOLEAN
  254. WriteTest(
  255. IN HANDLE Handle
  256. )
  257. {
  258. IO_STATUS_BLOCK ioStatusBlock;
  259. NTSTATUS status;
  260. static ULONG messageNumber = 0;
  261. messageNumber++;
  262. sprintf( Buffer, "Sending message number %d\n", messageNumber);
  263. status = NtWriteFile (
  264. Handle,
  265. 0L,
  266. NULL,
  267. NULL,
  268. &ioStatusBlock,
  269. Buffer,
  270. MESSAGE_SIZE,
  271. NULL,
  272. NULL);
  273. printf ("Write status = %lx\n", status );
  274. if (NT_SUCCESS(status)) {
  275. status = NtWaitForSingleObject( Handle, TRUE, NULL );
  276. printf( "NtWaitForSingleObject returns %lx\n", status );
  277. status = ioStatusBlock.Status;
  278. }
  279. printf( "NtWriteFileFinalStatus returns %lx\n", status );
  280. return ( (BOOLEAN)NT_SUCCESS( status ) );
  281. }
  282. DisplayUnicode(
  283. IN WCHAR *UnicodeString,
  284. IN ULONG Length
  285. )
  286. {
  287. while (Length > 0) {
  288. putchar( (CHAR)*UnicodeString );
  289. UnicodeString++;
  290. Length -= 2;
  291. }
  292. return 0;
  293. }