/*++ Copyright (c) 1989 Microsoft Corporation Module Name: tmscli.c Abstract: User mode test program for the mailslot file system. This test program can be built from the command line using the command 'nmake UMTEST=tmscli'. Author: Manny Weiser (mannyw) 17-Jan-1991 Revision History: --*/ #include #include #include #include // // Local definitions // VOID DisplayUsage( PSZ ProgramName ); BOOLEAN NotifyChangeDirectoryTest( VOID ); BOOLEAN QueryVolumeTest( VOID ); BOOLEAN OpenMailslot( PSZ Name, PHANDLE Handle ); BOOLEAN WriteTest( IN HANDLE Handle ); DisplayUnicode( IN WCHAR *UnicodeString, IN ULONG Length ); #define MESSAGE_SIZE 100L #define MAILSLOT_SIZE (10 * MESSAGE_SIZE) char Buffer[MESSAGE_SIZE]; int main( int argc, char *argv[] ) { HANDLE handle; int i; printf("\nStart %s...\n", argv[0]); for (i = 1; i < argc; i++) { switch ( *argv[i] ) { case 'h': case '?': DisplayUsage( argv[0] ); break; case 'o': if ( !OpenMailslot( argv[i] + 1, &handle ) ) { return 3; } break; case 'n': if ( !NotifyChangeDirectoryTest() ) { return 3; } break; case 'c': printf( "Closing file\n" ); NtClose( handle ); break; case 'w': if (!WriteTest(handle)) { return 3; } break; case 'v': if (!QueryVolumeTest()) { return 3; } break; default: printf( "Unknown test ""%s"" skipped.\n", argv[i] ); } } printf( "%s exiting\n", argv[0]); return 0; } BOOLEAN NotifyChangeDirectoryTest( VOID ) { HANDLE rootDirHandle; UCHAR buffer[512]; IO_STATUS_BLOCK ioStatusBlock; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING nameString; NTSTATUS status; RtlInitUnicodeString( &nameString, L"\\Device\\Mailslot\\" ); InitializeObjectAttributes( &objectAttributes, &nameString, OBJ_CASE_INSENSITIVE, NULL, NULL ); printf( "Attempting to open mailslot directory \"%wZ\"\n", &nameString ); status = NtOpenFile ( &rootDirHandle, GENERIC_READ, &objectAttributes, &ioStatusBlock, 0, 0L ); printf( "MSFS root dir open status = %lx\n", status ); if (!NT_SUCCESS(status)) { return FALSE; } status = NtNotifyChangeDirectoryFile( rootDirHandle, (HANDLE) NULL, (PIO_APC_ROUTINE) NULL, (PVOID) NULL, &ioStatusBlock, buffer, sizeof( buffer ), FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA | FILE_NOTIFY_CHANGE_SECURITY, FALSE ); printf("Notify change directory status = %lx\n", status ); if ( !NT_SUCCESS( status )) { return FALSE; } status = NtWaitForSingleObject( rootDirHandle, TRUE, NULL ); printf( "NtWaitForSingleObject returns %lx\n", status ); status = ioStatusBlock.Status; printf( "Find notify final status = %d\n", status ); return( (BOOLEAN)NT_SUCCESS( status )); } BOOLEAN QueryVolumeTest( VOID ) { HANDLE fsHandle; IO_STATUS_BLOCK ioStatusBlock; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING nameString; NTSTATUS status; PFILE_FS_ATTRIBUTE_INFORMATION fsAttributeInfo; RtlInitUnicodeString( &nameString, L"\\Device\\Mailslot" ); InitializeObjectAttributes( &objectAttributes, &nameString, OBJ_CASE_INSENSITIVE, NULL, NULL ); printf( "Attempting to open mailslot fs \"%wZ\"\n", &nameString ); status = NtOpenFile ( &fsHandle, GENERIC_READ, &objectAttributes, &ioStatusBlock, 0, 0L ); printf( "MSFS open status = %lx\n", status ); if (!NT_SUCCESS(status)) { return FALSE; } status = NtQueryVolumeInformationFile( fsHandle, &ioStatusBlock, Buffer, sizeof( Buffer ), FileFsAttributeInformation ); printf("Query volume status = %lx\n", status ); if ( !NT_SUCCESS( status )) { return FALSE; } status = ioStatusBlock.Status; printf( "Query volume final status = %d\n", status ); fsAttributeInfo = (PFILE_FS_ATTRIBUTE_INFORMATION)Buffer; printf (" FileSystemAttributes = %lx\n", fsAttributeInfo->FileSystemAttributes); printf (" MaximumComponentNameLength = %ld\n", fsAttributeInfo->MaximumComponentNameLength); printf (" FileSystemNameLength = %ld\n", fsAttributeInfo->FileSystemNameLength); printf (" FileSystemName = "); DisplayUnicode(fsAttributeInfo->FileSystemName, fsAttributeInfo->FileSystemNameLength); putchar ('\n'); return( (BOOLEAN)NT_SUCCESS( status )); } VOID DisplayUsage( PSZ ProgramName ) { printf( "Usage: %s \\Device\\Mailslot\\Msname\n", ProgramName); } BOOLEAN OpenMailslot( PSZ Name, PHANDLE Handle ) { STRING ansiString; UNICODE_STRING nameString; NTSTATUS status; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatusBlock; RtlInitString(&ansiString, Name ); RtlOemStringToUnicodeString(&nameString, &ansiString, TRUE); // // Open the mailslot // InitializeObjectAttributes( &objectAttributes, &nameString, OBJ_CASE_INSENSITIVE, NULL, NULL ); printf( "Attempting to open mailslot \"%wZ\"\n", &nameString ); status = NtOpenFile ( Handle, FILE_WRITE_DATA | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, FILE_SHARE_WRITE | FILE_SHARE_READ, 0L ); printf( "Status = %x\n", status ); RtlFreeUnicodeString(&nameString); return ( (BOOLEAN) NT_SUCCESS( status ) ); } BOOLEAN WriteTest( IN HANDLE Handle ) { IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; static ULONG messageNumber = 0; messageNumber++; sprintf( Buffer, "Sending message number %d\n", messageNumber); status = NtWriteFile ( Handle, 0L, NULL, NULL, &ioStatusBlock, Buffer, MESSAGE_SIZE, NULL, NULL); printf ("Write status = %lx\n", status ); if (NT_SUCCESS(status)) { status = NtWaitForSingleObject( Handle, TRUE, NULL ); printf( "NtWaitForSingleObject returns %lx\n", status ); status = ioStatusBlock.Status; } printf( "NtWriteFileFinalStatus returns %lx\n", status ); return ( (BOOLEAN)NT_SUCCESS( status ) ); } DisplayUnicode( IN WCHAR *UnicodeString, IN ULONG Length ) { while (Length > 0) { putchar( (CHAR)*UnicodeString ); UnicodeString++; Length -= 2; } return 0; }