windows-nt/Source/XPSP1/NT/base/ntos/se/ctlnpqos.c

1730 lines
40 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//////////////////////////////////////////////////////////////////////////////
// //
// 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;
}