|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
tmsserv.c
Abstract:
This module contains a user mode mailslot server test program.
This test program can be built from the command line using the command 'nmake UMTEST=tmsserv'.
Author:
Manny Weiser (mannyw) 11-Jan-91
Revision History:
--*/
#include <stdio.h>
#include <stdlib.h>
#include <nt.h>
#include <ntrtl.h>
#include <ntioapi.h>
//
// Local definitions
//
BOOLEAN CreateMailslot( PSZ Name, PHANDLE Handle );
BOOLEAN QueryDirectoryTest( VOID );
BOOLEAN QueryInfoTest( HANDLE Handle );
BOOLEAN PeekTest( HANDLE Handle );
BOOLEAN ReadTest( HANDLE Handle );
VOID DisplayUsage( PSZ ProgramName );
VOID DisplayTime( IN PLARGE_INTEGER );
DisplayUnicode( IN WCHAR *UnicodeString, IN ULONG Length );
#define MESSAGE_SIZE 100L
#define MAILSLOT_SIZE (10 * MESSAGE_SIZE)
#define PEEK_PARAMETER_BYTES 16
#define READ_PARAMETER_BYTES 16
#define MAILSLOT_PARAMETER_BYTES 16 // Max of peek and read param bytes
char Buffer[1000];
int main(argc, argv)
int argc; char **argv;
{ HANDLE handle; ULONG ms, time; LARGE_INTEGER delayTime; int i;
if (argc < 2) { DisplayUsage(argv[0]); return 1; }
if ( !CreateMailslot( argv[1], &handle ) ) { return 2; }
for (i = 2; i < argc; i++) {
switch ( *argv[i] ) {
case 'r': if ( !ReadTest( handle ) ) { return 3; } break;
case 'd': if ( !QueryDirectoryTest() ) { return 3; } break;
case 'p': if ( !PeekTest( handle ) ) { return 3; } break;
case 'q': if ( !QueryInfoTest( handle ) ) { return 3; } break;
case 's': time = atoi( argv[i] + 1);
printf( "%s: sleeping for %lu tenths of a second\n", argv[0], time );
ms = time * 100; delayTime = LiNMul( ms, -10000 ); NtDelayExecution( TRUE, (PLARGE_INTEGER)&delayTime );
printf ("%s: awake\n", argv[0] ); break;
default: printf ("Unknown test ""%s""\n", argv[i] ); break;
}
}
printf( "Closing file\n" ); NtClose( handle );
printf( "%s exiting\n", argv[0] ); return 0; }
VOID DisplayUsage( PSZ ProgramName ) { printf( "Usage: %s \\Device\\Mailslot\\Msname\n", ProgramName); }
BOOLEAN CreateMailslot( PSZ Name, PHANDLE Handle ) { NTSTATUS status; STRING ansiString; UNICODE_STRING nameString; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatusBlock; LARGE_INTEGER readTimeout = { -1, -1 }; // Infinite read timeout
RtlInitString(&ansiString, Name ); RtlOemStringToUnicodeString(&nameString, &ansiString, TRUE);
InitializeObjectAttributes( &objectAttributes, &nameString, OBJ_CASE_INSENSITIVE, NULL, NULL );
printf( "Attempting to create mailslot \"%wZ\"\n", &nameString );
status = NtCreateMailslotFile ( Handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, 0, 0, MESSAGE_SIZE, &readTimeout );
printf( "Open Status = %lx\n", status ); RtlFreeUnicodeString(&nameString);
return ( (BOOLEAN) NT_SUCCESS(status)); }
BOOLEAN QueryDirectoryTest( VOID ) { HANDLE rootDirHandle; BOOLEAN done; IO_STATUS_BLOCK ioStatusBlock; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING nameString; NTSTATUS status; PFILE_FULL_DIR_INFORMATION dirInfo;
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 );
RtlFreeUnicodeString(&nameString); printf( "MSFS root dir open status = %lx\n", status );
status = NtQueryDirectoryFile( rootDirHandle, 0, NULL, NULL, &ioStatusBlock, (PVOID)Buffer, sizeof(Buffer), FileFullDirectoryInformation, FALSE, NULL, FALSE );
printf("Query directory status = %lx\n", status ); printf("Query directory information %d\n", ioStatusBlock.Information );
if ( NT_SUCCESS( status )) { done = FALSE; dirInfo = (PFILE_FULL_DIR_INFORMATION)Buffer; } else { done = TRUE; }
while (!done) { printf ("NextEntry = %d\n", dirInfo->NextEntryOffset); printf ("FileIndex = %ld\n", dirInfo->FileIndex ); printf ("CreationTime = "); DisplayTime( &dirInfo->CreationTime ); printf ("\nLastAccessTime = "); DisplayTime( &dirInfo->LastAccessTime ); printf ("\nLastWriteTime = "); DisplayTime( &dirInfo->LastWriteTime ); printf ("\nChangeTime = "); DisplayTime( &dirInfo->ChangeTime ); printf ("\nEnd of file = %lx%08lx\n", dirInfo->EndOfFile.HighPart, dirInfo->EndOfFile.LowPart ); printf ("Allocation size = %lx%08lx\n", dirInfo->AllocationSize.HighPart, dirInfo->AllocationSize.LowPart ); printf ("File attributes = %x\n", dirInfo->FileAttributes ); printf ("File name length = %x\n", dirInfo->FileNameLength ); printf ("EA size = %x\n", dirInfo->EaSize ); printf ("File Name = "); DisplayUnicode( dirInfo->FileName, dirInfo->FileNameLength ); printf ("\n\n");
if (dirInfo->NextEntryOffset == 0) { done = TRUE; }
dirInfo = (PFILE_FULL_DIR_INFORMATION) ((PCHAR)dirInfo + dirInfo->NextEntryOffset); }
return( (BOOLEAN)NT_SUCCESS( status )); }
BOOLEAN QueryInfoTest( HANDLE Handle ) { PFILE_BASIC_INFORMATION basicInfo; PFILE_STANDARD_INFORMATION standardInfo; PFILE_INTERNAL_INFORMATION internalInfo; PFILE_EA_INFORMATION eaInfo; PFILE_POSITION_INFORMATION positionInfo; PFILE_NAME_INFORMATION nameInfo; NTSTATUS status; IO_STATUS_BLOCK ioStatusBlock;
status = NtQueryInformationFile( Handle, &ioStatusBlock, Buffer, MESSAGE_SIZE, FileAllInformation );
printf ("\nBasic Information:\n");
basicInfo = (PFILE_BASIC_INFORMATION)Buffer; printf (" Creation time: " ); DisplayTime( &basicInfo->CreationTime ); printf ("\n Last access time: " ); DisplayTime( &basicInfo->LastAccessTime ); printf ("\n Last write time: " ); DisplayTime( &basicInfo->LastWriteTime ); printf ("\n Change time: " ); DisplayTime( &basicInfo->ChangeTime ); printf ("\n");
printf ("\nStandard Information:\n");
standardInfo = (PFILE_STANDARD_INFORMATION)(basicInfo + 1); printf (" Number of links: %ld\n", standardInfo->NumberOfLinks ); printf (" Delete pending : %ld\n", standardInfo->DeletePending ); printf (" Directory : %ld\n", standardInfo->Directory );
printf ("\nInternal Information:\n");
internalInfo = (PFILE_INTERNAL_INFORMATION)(standardInfo + 1); printf (" Index Number : %ld\n", internalInfo->IndexNumber );
printf ("\nEa Information:\n");
eaInfo = (PFILE_EA_INFORMATION)(internalInfo + 1); printf (" No ea info\n" );
printf ("\nPosition Information:\n");
positionInfo = (PFILE_POSITION_INFORMATION)(eaInfo+1); printf (" Current offset: %ld\n", positionInfo->CurrentByteOffset );
printf ("\nName Information:\n");
nameInfo = (PFILE_NAME_INFORMATION)(positionInfo + 1); printf (" File name length: %ld\n", nameInfo->FileNameLength ); printf (" File name : "); DisplayUnicode( nameInfo->FileName, nameInfo->FileNameLength ); putchar ('\n');
return TRUE; }
BOOLEAN PeekTest( HANDLE Handle ) { FILE_MAILSLOT_PEEK_BUFFER mailslotPeekBuffer; NTSTATUS status; IO_STATUS_BLOCK ioStatusBlock;
status = NtFsControlFile ( Handle, 0L, NULL, NULL, &ioStatusBlock, FSCTL_MAILSLOT_PEEK, &mailslotPeekBuffer, sizeof(mailslotPeekBuffer), Buffer, MESSAGE_SIZE );
printf( " ReadDataAvailable = %lx\n", mailslotPeekBuffer.ReadDataAvailable ); printf( " NumberOfMessages = %lx\n", mailslotPeekBuffer.NumberOfMessages); printf( " MessageLength = %lx\n", mailslotPeekBuffer.MessageLength); return ( (BOOLEAN) NT_SUCCESS( status ) ); }
BOOLEAN ReadTest( HANDLE Handle ) { IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
status = NtReadFile( Handle, 0L, NULL, NULL, &ioStatusBlock, Buffer, MESSAGE_SIZE, NULL, NULL);
if (NT_SUCCESS(status)) { status = NtWaitForSingleObject( Handle, TRUE, NULL ); printf( "NtWaitForSingleObject returns %lx\n", status ); status = ioStatusBlock.Status; }
printf( "NtReadFileFinalStatus returns %lx\n", status );
if (NT_SUCCESS(status)) { printf ("message is ""%s""\n", Buffer ); }
return ( (BOOLEAN)NT_SUCCESS( status ) ); } VOID DisplayTime( IN PLARGE_INTEGER Time )
{ TIME_FIELDS timeFields;
RtlTimeToTimeFields( Time, &timeFields );
printf("%02d/%02d/%04d @ %02d:%02d:%02d.%d", timeFields.Month, timeFields.Day, timeFields.Year, timeFields.Hour, timeFields.Minute, timeFields.Second, timeFields.Milliseconds );
}
DisplayUnicode( IN WCHAR *UnicodeString, IN ULONG Length ) { while (Length > 0) { putchar( (CHAR)*UnicodeString ); UnicodeString++; Length -= 2; }
return 0; }
|