Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

341 lines
7.8 KiB

#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <malloc.h>
#include <ntddsac.h>
#include <sacapi.h>
#include <assert.h>
#define THREADCOUNT 2
#define THREAD_WAIT_TIMEOUT 50
enum {
EXIT_EVENT = WAIT_OBJECT_0,
CHANNEL_CLOSE_EVENT,
CHANNEL_HAS_NEW_DATA_EVENT
};
typedef struct _CHANNEL_THREAD_DATA {
HANDLE ExitEvent;
HANDLE HasNewDataEvent;
HANDLE CloseEvent;
WCHAR ChannelName[SAC_MAX_CHANNEL_NAME_LENGTH];
WCHAR ChannelDescription[SAC_MAX_CHANNEL_DESCRIPTION_LENGTH];
SAC_CHANNEL_HANDLE SacChannelHandle;
} CHANNEL_THREAD_DATA, *PCHANNEL_THREAD_DATA;
DWORD
ChannelThreadRawWrite(
PVOID Data
)
{
PCHANNEL_THREAD_DATA ChannelThreadData;
DWORD Status;
BOOL bContinue;
DWORD dwRetVal;
UCHAR Buffer[0x1000];
ULONG BufferSize;
HANDLE handles[2];
ULONG i;
ULONG k;
HANDLE hFile;
ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
//
// Create destination file for read data
//
hFile = CreateFile(
L"sacloop.in",
GENERIC_READ, // open for writing
0, // do not share
NULL, // no security
OPEN_EXISTING, // overwrite existing
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
return 0;
}
//
// Perform thread work
//
handles[0] = ChannelThreadData->ExitEvent;
handles[1] = ChannelThreadData->CloseEvent;
bContinue = TRUE;
while (bContinue) {
dwRetVal = WaitForMultipleObjects(
sizeof(handles)/sizeof(handles[0]),
handles,
FALSE,
THREAD_WAIT_TIMEOUT
);
switch( dwRetVal )
{
case EXIT_EVENT:
case CHANNEL_CLOSE_EVENT:
// close
bContinue = FALSE;
break;
case WAIT_TIMEOUT:
//
// write Channel::stdout
//
bContinue = ReadFile(
hFile,
&Buffer,
1,
&BufferSize,
NULL
);
if (bContinue) {
bContinue = SacChannelRawWrite(
ChannelThreadData->SacChannelHandle,
Buffer,
BufferSize
);
}
break;
default:
break;
}
}
CloseHandle(hFile);
return 0;
}
DWORD
ChannelThreadRawRead(
PVOID Data
)
{
PCHANNEL_THREAD_DATA ChannelThreadData;
DWORD Status;
BOOL bContinue;
DWORD dwRetVal;
UCHAR Buffer[0x1000];
ULONG BufferSize;
HANDLE handles[3];
HANDLE hFile;
ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
//
// Create destination file for read data
//
hFile = CreateFile(
L"sacloop.out",
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // no security
CREATE_ALWAYS, // overwrite existing
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
return 0;
}
//
// Perform thread work
//
handles[0] = ChannelThreadData->ExitEvent;
handles[1] = ChannelThreadData->CloseEvent;
handles[2] = ChannelThreadData->HasNewDataEvent;
bContinue = TRUE;
while (bContinue) {
dwRetVal = WaitForMultipleObjects(
sizeof(handles)/sizeof(handles[0]),
handles,
FALSE,
INFINITE
);
switch( dwRetVal )
{
case EXIT_EVENT:
case CHANNEL_CLOSE_EVENT:
// close
bContinue = FALSE;
break;
case CHANNEL_HAS_NEW_DATA_EVENT:
//
// read Channel::stdin
//
bContinue = SacChannelRead(
ChannelThreadData->SacChannelHandle,
(PUCHAR)Buffer,
sizeof(Buffer),
&BufferSize
);
if (bContinue) {
DWORD dwBytesWritten;
bContinue = WriteFile(
hFile,
Buffer,
BufferSize,
&dwBytesWritten,
NULL
);
}
break;
default:
break;
}
}
CloseHandle(hFile);
return 0;
}
DWORD (*ChannelTests[THREADCOUNT])(PVOID) = {
ChannelThreadRawWrite,
ChannelThreadRawRead
};
int _cdecl
wmain(
int argc,
WCHAR **argv
)
{
SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
HANDLE Channel[THREADCOUNT];
CHANNEL_THREAD_DATA ChannelData;
ULONG i;
ChannelData.ExitEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
ChannelData.CloseEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
ChannelData.HasNewDataEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
swprintf(
ChannelData.ChannelDescription,
L"simsess test channel"
);
swprintf(
ChannelData.ChannelName,
L"simsess"
);
//
// Configure the new channel
//
RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
Attributes.Type = ChannelTypeRaw;
Attributes.Name = ChannelData.ChannelName;
Attributes.Description = ChannelData.ChannelDescription;
Attributes.Flags = SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT | SAC_CHANNEL_FLAG_CLOSE_EVENT;
Attributes.CloseEvent = ChannelData.CloseEvent;
Attributes.HasNewDataEvent = ChannelData.HasNewDataEvent;
Attributes.ApplicationType = NULL;
//
// Open the channel
//
if (SacChannelOpen(
&ChannelData.SacChannelHandle,
&Attributes
)) {
printf("Successfully opened new channel\n");
} else {
printf("Failed to open new channel\n");
goto cleanup;
}
//
// create the worker threads
//
for (i = 0; i < THREADCOUNT; i++) {
//
// create the thread
//
Channel[i] = CreateThread(
NULL,
0,
ChannelTests[i],
&ChannelData,
0,
NULL
);
if (Channel[i] == NULL) {
goto cleanup;
}
}
//
// wait for local user to end the stress
//
getc(stdin);
cleanup:
SetEvent(ChannelData.ExitEvent);
WaitForMultipleObjects(
THREADCOUNT,
Channel,
TRUE,
INFINITE
);
for (i = 0; i < THREADCOUNT; i++) {
CloseHandle(Channel[i]);
}
SacChannelClose(&ChannelData.SacChannelHandle);
return 0;
}