|
|
//////////////////////////////////////////////////////////////////////////////
// //
// Global Definitions //
// //
//////////////////////////////////////////////////////////////////////////////
#define DevPrint
//#define DevPrint DbgPrint
#define Error(N,S) { DbgPrint(#N); DbgPrint(" Error %08lx\n", S); }
#define Delay(SECONDS) { \
LARGE_INTEGER Time; \ Time.QuadPart = -10 * 1000 * 1000, ((LONGLONG)SECONDS); \ NtDelayExecution(TRUE,(PLARGE_INTEGER)&Time); \ }
//////////////////////////////////////////////////////////////////////////////
// //
// Global Variables //
// //
//////////////////////////////////////////////////////////////////////////////
NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; STRING EventName; UNICODE_STRING UnicodeEventName; HANDLE EventHandle; STRING PortName; UNICODE_STRING UnicodePortName; STRING RelativePortName; UNICODE_STRING UnicodeRelativePortName; HANDLE EarPort; HANDLE TalkPort; SECURITY_QUALITY_OF_SERVICE SecurityQos; ULONG RequestCount; HANDLE ClientToken; TOKEN_STATISTICS ClientTokenStatistics; ULONG IgnoreLength;
HANDLE SepServerThread;
//////////////////////////////////////////////////////////////////////////////
// //
// Test Routine Definitions //
// //
//////////////////////////////////////////////////////////////////////////////
BOOLEAN SepClientTestStatic(VOID);
BOOLEAN SepClientTestDynamic(VOID);
BOOLEAN SepClientTestEffectiveOnly( BOOLEAN StaticTest );
BOOLEAN SepClientTestNotEffectiveOnly( BOOLEAN StaticTest );
BOOLEAN SepClientTestAnonymous( BOOLEAN StaticTest, BOOLEAN EffectiveOnly );
BOOLEAN SepClientTestIdentification( BOOLEAN StaticTest, BOOLEAN EffectiveOnly );
BOOLEAN SepClientTestImpersonation( BOOLEAN StaticTest, BOOLEAN EffectiveOnly );
VOID SepClientConnect( SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, SECURITY_CONTEXT_TRACKING_MODE TrackingMode, BOOLEAN EffectiveOnly );
VOID SepClientMakeRemoteCall( VOID );
VOID SepClientDropConnection( VOID );
BOOLEAN SepClientTest(VOID);
NTSTATUS SepClientInitialize( );
BOOLEAN SepServerTestStatic(VOID);
BOOLEAN SepServerTestDynamic(VOID);
BOOLEAN SepServerTestEffectiveOnly( BOOLEAN StaticTest );
BOOLEAN SepServerTestNotEffectiveOnly( BOOLEAN StaticTest );
BOOLEAN SepServerTestAnonymous( BOOLEAN StaticTest, BOOLEAN EffectiveOnly );
BOOLEAN SepServerTestIdentification( BOOLEAN StaticTest, BOOLEAN EffectiveOnly );
BOOLEAN SepServerTestImpersonation( BOOLEAN StaticTest, BOOLEAN EffectiveOnly );
VOID SepServerWaitForNextConnect( VOID );
VOID SepServerGetNextMessage( VOID );
VOID SepServerCompleteMessage( VOID );
VOID SepServerDropConnection( VOID );
BOOLEAN SepServerTest(VOID);
NTSTATUS SepServerInitialize( );
VOID SepServerSpawnClientProcess(VOID);
VOID SepWritePipe( PSZ String );
VOID SepReadPipe(VOID);
VOID SepTransceivePipe( PSZ String );
HANDLE SepServerCreatePipe(VOID);
VOID SepServerListenPipe(VOID);
VOID SepServerImpersonatePipe(VOID);
VOID SepServerDisconnectPipe(VOID);
HANDLE SepClientOpenPipe( VOID );
BOOLEAN CtLnpQos (VOID);
//////////////////////////////////////////////////////////////////////////////
// //
// Client-Side Test Routines //
// //
//////////////////////////////////////////////////////////////////////////////
VOID SepClientConnect( SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, SECURITY_CONTEXT_TRACKING_MODE TrackingMode, BOOLEAN EffectiveOnly )
{
SecurityQos.ImpersonationLevel = ImpersonationLevel; SecurityQos.ContextTrackingMode = TrackingMode; SecurityQos.EffectiveOnly = EffectiveOnly;
DevPrint("\nClient: "); TalkPort = SepClientOpenPipe();
return; }
VOID SepClientMakeRemoteCall( VOID )
{
DevPrint("\nClient: "); SepTransceivePipe( "Make Client Call\n" );
RequestCount += 1;
return; }
VOID SepClientDropConnection( VOID )
{
Status = NtClose( TalkPort ); SEASSERT_SUCCESS(Status);
return;
}
BOOLEAN SepClientTestStatic(VOID)
{
BOOLEAN CompletionStatus;
//
// Static Context Tracking ... Suite
//
CompletionStatus = SepClientTestEffectiveOnly( TRUE );
if (CompletionStatus == TRUE) {
CompletionStatus = SepClientTestNotEffectiveOnly( TRUE ); }
return CompletionStatus;
}
BOOLEAN SepClientTestDynamic(VOID)
{ BOOLEAN CompletionStatus;
//
// Dynamic Context Tracking ... Suite
//
CompletionStatus = SepClientTestEffectiveOnly( FALSE );
if (CompletionStatus == TRUE) {
CompletionStatus = SepClientTestNotEffectiveOnly( FALSE ); }
return CompletionStatus;
}
BOOLEAN SepClientTestEffectiveOnly( BOOLEAN StaticTest )
{
BOOLEAN CompletionStatus;
//
// Effective Only ... Test
//
CompletionStatus = SepClientTestAnonymous( StaticTest, TRUE ); if (CompletionStatus == TRUE) { CompletionStatus = SepClientTestIdentification( StaticTest, TRUE ); } if (CompletionStatus == TRUE) { CompletionStatus = SepClientTestImpersonation( StaticTest, TRUE ); }
return CompletionStatus;
}
BOOLEAN SepClientTestNotEffectiveOnly( BOOLEAN StaticTest )
{ BOOLEAN CompletionStatus;
//
// Not Effective Only ... Test
//
CompletionStatus = SepClientTestAnonymous( StaticTest, FALSE ); if (CompletionStatus == TRUE) { CompletionStatus = SepClientTestIdentification( StaticTest, FALSE ); } if (CompletionStatus == TRUE) { CompletionStatus = SepClientTestImpersonation( StaticTest, FALSE ); }
return CompletionStatus;
}
BOOLEAN SepClientTestAnonymous( BOOLEAN StaticTest, BOOLEAN EffectiveOnly )
{
//////////////////////////////////////////////////////////////////////////
// //
// Anonymous Use Test //
// //
//////////////////////////////////////////////////////////////////////////
SECURITY_CONTEXT_TRACKING_MODE TrackingMode;
if (StaticTest) { TrackingMode = SECURITY_STATIC_TRACKING; } else { TrackingMode = SECURITY_DYNAMIC_TRACKING; }
if (!StaticTest) { //
// No action for dynamic test
//
return TRUE; }
//
// Anonymous Use ... Test
//
SepClientConnect( SecurityAnonymous, TrackingMode, EffectiveOnly );
SepClientMakeRemoteCall();
SepClientDropConnection();
return TRUE; }
BOOLEAN SepClientTestIdentification( BOOLEAN StaticTest, BOOLEAN EffectiveOnly )
{
//////////////////////////////////////////////////////////////////////////
// //
// Identification Use Test //
// //
//////////////////////////////////////////////////////////////////////////
SECURITY_CONTEXT_TRACKING_MODE TrackingMode;
if (StaticTest) { TrackingMode = SECURITY_STATIC_TRACKING; } else { TrackingMode = SECURITY_DYNAMIC_TRACKING; }
//
// Identification Use ... Test
//
SepClientConnect( SecurityIdentification, TrackingMode, EffectiveOnly );
SepClientMakeRemoteCall();
SepClientDropConnection();
return TRUE;
}
BOOLEAN SepClientTestImpersonation( BOOLEAN StaticTest, BOOLEAN EffectiveOnly )
{
//////////////////////////////////////////////////////////////////////////
// //
// Impersonation Use Test //
// //
//////////////////////////////////////////////////////////////////////////
SECURITY_CONTEXT_TRACKING_MODE TrackingMode;
if (StaticTest) { TrackingMode = SECURITY_STATIC_TRACKING; } else { TrackingMode = SECURITY_DYNAMIC_TRACKING; }
//
// Impersonation Use ... Test
//
SepClientConnect( SecurityImpersonation, TrackingMode, EffectiveOnly );
SepClientMakeRemoteCall();
SepClientDropConnection();
return TRUE;
}
BOOLEAN SepClientTest(VOID) //
// Tests:
//
// Static Context Tracking Tests
// Effective Only
// Anonymous
// Identification
// Impersonation
// Not Effective Only
// Anonymous
// Identification
// Impersonation
//
// Dynamic Context Tracking Tests
// Effective Only
// Identification
// Impersonation
// Not Effective Only
// Identification
// Impersonation
//
{
BOOLEAN CompletionStatus;
//
// Run the static test suite...
//
CompletionStatus = SepClientTestStatic();
//
// Run the dynamic test suite...
//
if (CompletionStatus == TRUE) { CompletionStatus = SepClientTestDynamic(); }
DbgPrint("Se: Client Test Complete.\n");
return CompletionStatus; }
NTSTATUS SepClientInitialize( )
{
DbgPrint("Se: Client Initializing ...\n");
RequestCount = 0;
//
// Signal the named event to start the test
//
DbgPrint("Se: Client Starting Test ...\n"); Status = NtSetEvent( EventHandle, NULL ); SEASSERT_SUCCESS(Status);
Status = NtClose( EventHandle ); SEASSERT_SUCCESS(Status);
return STATUS_SUCCESS; }
//////////////////////////////////////////////////////////////////////////////
// //
// Server-Side Test Routines //
// //
//////////////////////////////////////////////////////////////////////////////
VOID SepServerWaitForNextConnect( VOID ) {
DevPrint("\nServer: "); SepServerListenPipe();
Status = NtDuplicateObject( NtCurrentProcess(), // SourceProcessHandle
EarPort, // SourceHandle
NtCurrentProcess(), // TargetProcessHandle
&TalkPort, // TargetHandle
0, // DesiredAccess (over-ridden by option)
0, // HandleAttributes
DUPLICATE_SAME_ACCESS // Options
); ASSERT(NT_SUCCESS(Status));
return;
}
VOID SepServerGetNextMessage( VOID )
{
DevPrint("\nServer: "); SepReadPipe();
RequestCount += 1;
return; }
VOID SepServerCompleteMessage( VOID )
{
DevPrint("\nServer: "); SepWritePipe("Return From Server\n"); return; }
VOID SepServerImpersonateClient( VOID )
{
DevPrint("\nServer: "); SepServerImpersonatePipe( );
}
VOID SepServerRevertToSelf( VOID )
{ NTSTATUS TmpStatus; HANDLE NullHandle;
NullHandle = NULL; TmpStatus = NtSetInformationThread( SepServerThread, ThreadImpersonationToken, (PVOID)&NullHandle, (ULONG)sizeof(HANDLE) ); SEASSERT_SUCCESS(TmpStatus);
}
VOID SepServerDropConnection( VOID )
{ DevPrint("\nServer: "); SepServerDisconnectPipe();
return; }
BOOLEAN SepServerTestStatic(VOID)
{ BOOLEAN CompletionStatus;
DbgPrint("Se: Static Context Tracking ... Suite\n");
CompletionStatus = SepServerTestEffectiveOnly( TRUE );
if (CompletionStatus == TRUE) {
CompletionStatus = SepServerTestNotEffectiveOnly( TRUE ); }
return CompletionStatus;
}
BOOLEAN SepServerTestDynamic(VOID)
{ BOOLEAN CompletionStatus;
DbgPrint("Se: Dynamic Context Tracking ... Suite\n");
CompletionStatus = SepServerTestEffectiveOnly( FALSE );
if (CompletionStatus == TRUE) {
CompletionStatus = SepServerTestNotEffectiveOnly( FALSE ); }
return CompletionStatus;
}
BOOLEAN SepServerTestEffectiveOnly( BOOLEAN StaticTest )
{
BOOLEAN CompletionStatus;
DbgPrint("Se: Effective Only ... Test\n");
CompletionStatus = SepServerTestAnonymous( StaticTest, TRUE ); if (CompletionStatus == TRUE) { CompletionStatus = SepServerTestIdentification( StaticTest, TRUE ); } if (CompletionStatus == TRUE) { CompletionStatus = SepServerTestImpersonation( StaticTest, TRUE ); }
return CompletionStatus;
}
BOOLEAN SepServerTestNotEffectiveOnly( BOOLEAN StaticTest )
{
BOOLEAN CompletionStatus;
DbgPrint("Se: Not Effective Only ... Test\n");
CompletionStatus = SepServerTestAnonymous( StaticTest, FALSE ); if (CompletionStatus == TRUE) { CompletionStatus = SepServerTestIdentification( StaticTest, FALSE ); } if (CompletionStatus == TRUE) { CompletionStatus = SepServerTestImpersonation( StaticTest, FALSE ); }
return CompletionStatus;
}
BOOLEAN SepServerTestAnonymous( BOOLEAN StaticTest, BOOLEAN EffectiveOnly )
{ BOOLEAN CompletionStatus = TRUE;
//////////////////////////////////////////////////////////////////////////
// //
// Anonymous Use Test //
// //
//////////////////////////////////////////////////////////////////////////
if (!StaticTest) { //
// No action for dynamic test
//
return TRUE; }
DbgPrint("Se: Anonymous Use ... ");
SepServerWaitForNextConnect();
SepServerGetNextMessage();
SepServerImpersonateClient(); Status = NtOpenThreadToken( SepServerThread, TOKEN_ALL_ACCESS, TRUE, &ClientToken ); SepServerRevertToSelf(); if (Status == STATUS_CANT_OPEN_ANONYMOUS) {
DbgPrint(" Succeeded\n");
} else { DbgPrint("* ! FAILED (srvr) ! *\n"); DbgPrint("Status is: 0x%lx \n", Status ); CompletionStatus = FALSE; }
SepServerCompleteMessage();
SepServerDropConnection();
//
// Appease the compiler Gods..
//
if (EffectiveOnly) {;}
return CompletionStatus;
}
BOOLEAN SepServerTestIdentification( BOOLEAN StaticTest, BOOLEAN EffectiveOnly )
{
BOOLEAN CompletionStatus = TRUE; //////////////////////////////////////////////////////////////////////////
// //
// Identification Use Test //
// //
//////////////////////////////////////////////////////////////////////////
DbgPrint("Se: Identification Use ... ");
SepServerWaitForNextConnect();
SepServerGetNextMessage();
SepServerImpersonateClient(); Status = NtOpenThreadToken( SepServerThread, TOKEN_ALL_ACCESS, TRUE, &ClientToken ); SEASSERT_SUCCESS(Status); SepServerRevertToSelf(); Status = NtQueryInformationToken( ClientToken, TokenStatistics, &ClientTokenStatistics, (ULONG)sizeof(TOKEN_STATISTICS), &IgnoreLength ); SEASSERT_SUCCESS(Status);
if ( (ClientTokenStatistics.TokenType == TokenImpersonation) && (ClientTokenStatistics.ImpersonationLevel == SecurityIdentification) ) { DbgPrint(" Succeeded\n");
} else { DbgPrint("* ! FAILED (srvr) ! *\n"); CompletionStatus = FALSE; }
SepServerCompleteMessage();
SepServerDropConnection();
//
// Appease the compiler Gods..
//
if (StaticTest) {;} if (EffectiveOnly) {;}
return CompletionStatus; }
BOOLEAN SepServerTestImpersonation( BOOLEAN StaticTest, BOOLEAN EffectiveOnly )
{ BOOLEAN CompletionStatus = TRUE;
//////////////////////////////////////////////////////////////////////////
// //
// Impersonation Use Test //
// //
//////////////////////////////////////////////////////////////////////////
DbgPrint("Se: Impersonation Use ... ");
SepServerWaitForNextConnect();
SepServerGetNextMessage();
SepServerImpersonateClient(); Status = NtOpenThreadToken( SepServerThread, TOKEN_ALL_ACCESS, TRUE, &ClientToken ); SEASSERT_SUCCESS(Status); SepServerRevertToSelf(); Status = NtQueryInformationToken( ClientToken, TokenStatistics, &ClientTokenStatistics, (ULONG)sizeof(TOKEN_STATISTICS), &IgnoreLength ); SEASSERT_SUCCESS(Status);
if ( (ClientTokenStatistics.TokenType == TokenImpersonation) && (ClientTokenStatistics.ImpersonationLevel == SecurityImpersonation) ) { DbgPrint(" Succeeded\n");
} else { DbgPrint("* ! FAILED (srvr) ! *\n"); CompletionStatus = FALSE; }
SepServerCompleteMessage();
SepServerDropConnection();
//
// Appease the compiler gods
//
if (StaticTest) {;} if (EffectiveOnly) {;}
return CompletionStatus; }
BOOLEAN SepServerTest(VOID) //
// Tests:
//
// Static Context Tracking Tests
// Effective Only
// Anonymous
// Identification
// Impersonation
// Not Effective Only
// Anonymous
// Identification
// Impersonation
//
// Dynamic Context Tracking Tests
// Effective Only
// Identification
// Impersonation
// Not Effective Only
// Identification
// Impersonation
//
{
BOOLEAN CompletionStatus;
DbgPrint("Se: Server Starting Test ...\n");
//
// Run the static test suite...
//
CompletionStatus = SepServerTestStatic();
//
// Run the dynamic test suite...
//
if (CompletionStatus == TRUE) { CompletionStatus = SepServerTestDynamic(); }
DbgPrint("Se: Server Test Complete.\n");
//
// Print test results
//
DbgPrint("\n"); DbgPrint("\n"); DbgPrint("**********************\n"); DbgPrint("** **\n");
if (CompletionStatus == TRUE) { DbgPrint("** Test Succeeded **\n"); } else { DbgPrint("** Test Failed !! **\n"); }
DbgPrint("** **\n"); DbgPrint("**********************\n");
return CompletionStatus;
}
NTSTATUS SepServerInitialize( )
{
OBJECT_ATTRIBUTES ThreadAttributes; PTEB CurrentTeb;
DbgPrint("Se: Server Initializing ...\n");
//
// Initialize global variables
//
RequestCount = 0;
//
// Get a handle to our thread to so that we can access our thread
// even when impersonating an anonymous client (which we can't do
// using NtCurrentThread()).
//
CurrentTeb = NtCurrentTeb(); InitializeObjectAttributes(&ThreadAttributes, NULL, 0, NULL, NULL); Status = NtOpenThread( &SepServerThread, // TargetHandle
THREAD_ALL_ACCESS, // DesiredAccess
&ThreadAttributes, // ObjectAttributes
&CurrentTeb->ClientId // ClientId
); ASSERT( NT_SUCCESS(Status) );
//
// Create the server's port
//
EarPort = SepServerCreatePipe();
//
// Spawn a copy of ourselves...
//
DbgPrint("Se: Server Spawning client process ...\n"); SepServerSpawnClientProcess();
DbgPrint("Se: Server waiting for start of test signal ...\n");
Status = NtWaitForSingleObject( EventHandle, TRUE, NULL ); SEASSERT_SUCCESS(Status);
Status = NtClose( EventHandle ); SEASSERT_SUCCESS(Status);
return STATUS_SUCCESS; }
VOID SepServerSpawnClientProcess(VOID)
{
RTL_USER_PROCESS_INFORMATION ProcessInformation; STRING ProgramName; UNICODE_STRING UnicodeProgramName; STRING ImagePathName; UNICODE_STRING UnicodeImagePathName; PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
RtlInitString( &ProgramName, "\\SystemRoot\\Bin\\utlnpqos.exe" ); Status = RtlAnsiStringToUnicodeString( &UnicodeProgramName, &ProgramName, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); RtlInitString( &ImagePathName, "utlnpqos.exe"); Status = RtlAnsiStringToUnicodeString( &UnicodeImagePathName, &ImagePathName, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
Status = RtlCreateProcessParameters( &ProcessParameters, &ImagePathName, // FIX, FIX &UnicodeImagePathName, (when converted to unicode)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
SEASSERT_SUCCESS(Status); RtlFreeUnicodeString( &UnicodeImagePathName );
Status = RtlCreateUserProcess( &ProgramName, // FIX, FIX &UnicodeProgramName (when converted to unicode)
ProcessParameters, // ProcessParameters
NULL, // ProcessSecurityDescriptor
NULL, // ThreadSecurityDescriptor
NtCurrentProcess(), // ParentProcess
FALSE, // InheritHandles
NULL, // DebugPort
NULL, // ExceptionPort
&ProcessInformation // ProcessInformation
); SEASSERT_SUCCESS(Status); RtlFreeUnicodeString( &UnicodeProgramName );
Status = NtResumeThread( ProcessInformation.Thread, NULL ); SEASSERT_SUCCESS(Status);
RtlDestroyProcessParameters( ProcessParameters );
}
//////////////////////////////////////////////////////////////////////////////
// //
// Main Program Entry Routine //
// //
//////////////////////////////////////////////////////////////////////////////
BOOLEAN CtLnpQos (VOID) {
BOOLEAN Result = TRUE;
RtlInitString( &PortName, "\\Device\\NamedPipe\\TestLnpQosServerPort" ); Status = RtlAnsiStringToUnicodeString( &UnicodePortName, &PortName, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
RtlInitString( &RelativePortName, "TestLnpQosServerPort" ); Status = RtlAnsiStringToUnicodeString( &UnicodeRelativePortName, &RelativePortName, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
//
// Determine whether we are the client or server side of the test.
// This is done by creating or opening a named event object. If the
// event does not yet exist, then we are the client, and must create
// the server process. Otherwise, we are the server and the client
// is waiting for us to signal the event.
//
RtlInitString( &EventName, "\\TestLnpQosEvent" ); Status = RtlAnsiStringToUnicodeString( &UnicodeEventName, &EventName, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
InitializeObjectAttributes( &ObjectAttributes, &UnicodeEventName, OBJ_OPENIF, NULL, NULL ); Status = NtCreateEvent( &EventHandle, EVENT_ALL_ACCESS, &ObjectAttributes, SynchronizationEvent, FALSE ); RtlFreeUnicodeString( &UnicodeEventName );
if (Status == STATUS_OBJECT_NAME_EXISTS) {
//
// Server is already running, therefore, this process gets to be
// the client.
//
Status = SepClientInitialize(); SEASSERT_SUCCESS(Status); Result = SepClientTest();
} else {
SEASSERT_SUCCESS(Status);
//
// Event wasn't yet there, so we must be the server.
//
DbgPrint("Se: Starting Local Named Pipe Impersonation Test.\n");
Status = SepServerInitialize(); SEASSERT_SUCCESS(Status); Result = SepServerTest();
DbgPrint("Se: End Test.\n");
}
Status = NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS); SEASSERT_SUCCESS(Status);
return Result;
}
//////////////////////////////////////////////////////////////////////////////
// //
// Named Pipe Common Operations //
// //
//////////////////////////////////////////////////////////////////////////////
VOID SepReadPipe( ) { IO_STATUS_BLOCK Iosb; UCHAR Buffer[512];
DevPrint("ReadPipe...\n", 0);
if (!NT_SUCCESS(Status = NtReadFile( TalkPort, (HANDLE)NULL, (PIO_APC_ROUTINE)NULL, (PVOID)NULL, &Iosb, Buffer, 512, (PLARGE_INTEGER)NULL, (PULONG) NULL ))) { Error( NtReadFile, Status ); }
if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
Error( NtWaitForSingleObject, Status ); }
if (!NT_SUCCESS(Iosb.Status)) {
Error( NtReadFileFinalStatus, Iosb.Status ); }
return; }
VOID SepWritePipe( PSZ String ) { NTSTATUS Status; IO_STATUS_BLOCK Iosb;
DevPrint("WritePipe...\n", 0);
if (!NT_SUCCESS(Status = NtWriteFile( TalkPort, (HANDLE)NULL, (PIO_APC_ROUTINE)NULL, (PVOID)NULL, &Iosb, String, strlen( String ), (PLARGE_INTEGER)NULL, (PULONG)NULL ))) { Error( NtWriteFile, Status ); }
if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
Error( NtWaitForSingleObject, Status ); }
if (!NT_SUCCESS(Iosb.Status)) {
Error( NtWriteFileFinalStatus, Iosb.Status ); }
return; }
VOID SepTransceivePipe( PSZ String ) { NTSTATUS Status; IO_STATUS_BLOCK Iosb; UCHAR Buffer[512];
DevPrint("TransceivePipe...\n", 0);
if (!NT_SUCCESS(Status = NtFsControlFile( TalkPort, NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&Iosb, FSCTL_PIPE_TRANSCEIVE, String, strlen( String ), Buffer, 511 ))) { Error( NtTransceiveFile, Status ); }
if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
Error( NtWaitForSingleObject, Status ); }
if (!NT_SUCCESS(Iosb.Status)) {
Error( NtTransceiveFileFinalStatus, Iosb.Status ); }
return; }
//////////////////////////////////////////////////////////////////////////////
// //
// Named Pipe Server Operations //
// //
//////////////////////////////////////////////////////////////////////////////
HANDLE SepServerCreatePipe( VOID ) { HANDLE PipeHandle; NTSTATUS Status; IO_STATUS_BLOCK Iosb; LARGE_INTEGER Timeout; READ_MODE Mode; ULONG Share; NAMED_PIPE_CONFIGURATION Config = FILE_PIPE_FULL_DUPLEX; NAMED_PIPE_TYPE PipeType = FILE_PIPE_MESSAGE_TYPE; COMPLETION_MODE CompletionMode = FILE_PIPE_QUEUE_OPERATION; ULONG MaximumInstances = 4;
//
// Set the default timeout to 60 seconds, and initalize the attributes
//
Timeout.QuadPart = -10 * 1000 * 1000 * 60;
InitializeObjectAttributes( &ObjectAttributes, &UnicodePortName, OBJ_CASE_INSENSITIVE, NULL, NULL );
//
// Calculate the readmode and share access
//
Mode = (PipeType == FILE_PIPE_MESSAGE_TYPE ? FILE_PIPE_MESSAGE_MODE : FILE_PIPE_BYTE_STREAM_MODE);
Share = (Config == FILE_PIPE_INBOUND ? FILE_SHARE_WRITE : (Config == FILE_PIPE_OUTBOUND ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE));
if (!NT_SUCCESS(Status = NtCreateNamedPipeFile( &PipeHandle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &Iosb, Share, FILE_CREATE, 0, PipeType, Mode, CompletionMode, MaximumInstances, 1024, 1024, (PLARGE_INTEGER)&Timeout ))) {
Error( CreatePipe, Status ); } RtlFreeUnicodeString( &UnicodePortName );
return PipeHandle; }
VOID SepServerListenPipe( ) { NTSTATUS Status; IO_STATUS_BLOCK Iosb;
DevPrint("ListenPipe...\n", 0);
if (!NT_SUCCESS(Status = NtFsControlFile( EarPort, NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&Iosb, FSCTL_PIPE_LISTEN, NULL, // InputBuffer
0, // InputBufferLength,
NULL, // OutputBuffer
0 // OutputBufferLength
))) {
Error( ListenPipe, Status ); } if (!NT_SUCCESS(Status = NtWaitForSingleObject( EarPort, TRUE, NULL ))) {
Error( NtWaitForSingleObject, Status ); }
if (!NT_SUCCESS(Iosb.Status)) {
Error( ListenPipeFinalStatus, Iosb.Status ); }
return; }
VOID SepServerImpersonatePipe( ) { NTSTATUS Status; IO_STATUS_BLOCK Iosb;
DevPrint("ImpersonatePipe...\n", 0);
if (!NT_SUCCESS(Status = NtFsControlFile( TalkPort, NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&Iosb, FSCTL_PIPE_IMPERSONATE, NULL, // InputBuffer
0, // InputBufferLength,
NULL, // OutputBuffer
0 // OutputBufferLength
))) {
Error( ImpersonatePipe, Status ); } if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) {
Error( NtWaitForSingleObject, Status ); }
if (!NT_SUCCESS(Iosb.Status)) {
Error( ImpersonatePipeFinalStatus, Iosb.Status ); }
return; }
VOID SepServerDisconnectPipe( ) { NTSTATUS Status; IO_STATUS_BLOCK Iosb;
DevPrint("DisconnectPipe...\n", 0); DevPrint(" (Flush)...\n", 0);
if (!NT_SUCCESS(Status = NtFlushBuffersFile( TalkPort, &Iosb ))) { Error( DisconnectPipe, Status ); }
if (!NT_SUCCESS(Iosb.Status)) {
Error( FlushPipeFinalStatus, Iosb.Status ); }
DevPrint(" (Close Talk Port)...\n", 0); Status = NtClose( TalkPort ); SEASSERT_SUCCESS(Status);
DevPrint(" (Disconnect)...\n", 0); if (!NT_SUCCESS(Status = NtFsControlFile( EarPort, NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&Iosb, FSCTL_PIPE_DISCONNECT, NULL, // InputBuffer
0, // InputBufferLength,
NULL, // OutputBuffer
0 // OutputBufferLength
))) {
Error( DisconnectPipe, Status ); } if (!NT_SUCCESS(Status = NtWaitForSingleObject( EarPort, TRUE, NULL ))) {
Error( NtWaitForSingleObject, Status ); }
if (!NT_SUCCESS(Iosb.Status)) {
Error( DisconnectPipeFinalStatus, Iosb.Status ); }
return; }
//////////////////////////////////////////////////////////////////////////////
// //
// Named Pipe Client Operations //
// //
//////////////////////////////////////////////////////////////////////////////
HANDLE SepClientOpenPipe( VOID ) { HANDLE PipeHandle, NpfsHandle; NTSTATUS Status; IO_STATUS_BLOCK Iosb; ULONG Share; STRING Npfs; UNICODE_STRING UnicodeNpfs; PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe; ULONG WaitPipeLength; NAMED_PIPE_CONFIGURATION Config = FILE_PIPE_FULL_DUPLEX; READ_MODE ReadMode = FILE_PIPE_MESSAGE_MODE; COMPLETION_MODE CompletionMode = FILE_PIPE_QUEUE_OPERATION;
//#ifdef NOT_YET_WORKING
//
// Wait for the server's pipe to reach a listen state...
//
RtlInitString( &Npfs, "\\Device\\NamedPipe\\"); Status = RtlAnsiStringToUnicodeString( &UnicodeNpfs, &Npfs, TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) );
InitializeObjectAttributes( &ObjectAttributes, &UnicodeNpfs, OBJ_CASE_INSENSITIVE, NULL, NULL);
if (!NT_SUCCESS(Status = NtOpenFile( &NpfsHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &Iosb, FILE_SHARE_READ, 0 ))) {
Error( OpenNpfs, Status ); } RtlFreeUnicodeString( &UnicodeNpfs );
WaitPipeLength = FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[0]) + RelativePortName.MaximumLength; //UNICODEFIX UnicodeRelativePortName.MaximumLength;
WaitPipe = RtlAllocateHeap(RtlProcessHeap(), 0, WaitPipeLength); WaitPipe->TimeoutSpecified = FALSE;
WaitPipe->NameLength = RelativePortName.Length; //UNICODEFIX UnicodeRelativePortName.Length;
strcpy(WaitPipe->Name, RelativePortName.Buffer); //UNICODEFIX UnicodePortName.Buffer;
if (!NT_SUCCESS(Status = NtFsControlFile( NpfsHandle, NULL, // Event
NULL, // ApcRoutine
NULL, // ApcContext
&Iosb, FSCTL_PIPE_WAIT, WaitPipe, // Buffer for data to the FS
WaitPipeLength, NULL, // OutputBuffer
0 // OutputBufferLength
))) {
Error( ClientWaitPipe, Status ); } if (Status == STATUS_PENDING) { if (!NT_SUCCESS(Status = NtWaitForSingleObject( NpfsHandle, TRUE, NULL ))) {
Error( NtWaitForSingleObject, Status ); } }
if (!NT_SUCCESS(Iosb.Status)) {
Error( ClientWaitPipeFinalStatus, Iosb.Status ); }
Status = NtClose( NpfsHandle ); ASSERT(NT_SUCCESS(Status)); //#endif // NOT_YET_WORKING
// Delay(1);
//
// Initialize the attributes
//
InitializeObjectAttributes( &ObjectAttributes, &UnicodePortName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObjectAttributes.SecurityQualityOfService = (PVOID)(&SecurityQos);
//
// Calculate the share access
//
Share = (Config == FILE_PIPE_INBOUND ? FILE_SHARE_WRITE : (Config == FILE_PIPE_OUTBOUND ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE));
//
// And now open it...
//
if (!NT_SUCCESS(Status = NtOpenFile( &PipeHandle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &Iosb, Share, 0 ))) {
Error( OpenPipe, Status ); }
if ((ReadMode != FILE_PIPE_BYTE_STREAM_MODE) || (CompletionMode != FILE_PIPE_QUEUE_OPERATION)) {
FILE_PIPE_INFORMATION Buffer;
Buffer.ReadMode = ReadMode; Buffer.CompletionMode = CompletionMode;
if (!NT_SUCCESS(Status = NtSetInformationFile( PipeHandle, &Iosb, &Buffer, sizeof(FILE_PIPE_INFORMATION), FilePipeInformation ))) {
Error( NtSetInformationFile, Status ); } }
return PipeHandle; }
|