////////////////////////////////////////////////////////////////////////////// // // // 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; }