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.
441 lines
9.5 KiB
441 lines
9.5 KiB
#include <windows.h>
|
|
#include <winioctl.h>
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
|
|
#include <ntddsac.h>
|
|
|
|
#include <emsapi.h>
|
|
|
|
#include <new.h>
|
|
|
|
#define THREADCOUNT 16
|
|
#define THREAD_WAIT_TIMEOUT 10
|
|
|
|
typedef struct _CHANNEL_THREAD_DATA {
|
|
|
|
HANDLE ExitEvent;
|
|
|
|
WCHAR ChannelName[SAC_MAX_CHANNEL_NAME_LENGTH];
|
|
WCHAR ChannelDescription[SAC_MAX_CHANNEL_DESCRIPTION_LENGTH];
|
|
|
|
} CHANNEL_THREAD_DATA, *PCHANNEL_THREAD_DATA;
|
|
|
|
DWORD
|
|
ChannelThreadVTUTF8Write(
|
|
PVOID Data
|
|
)
|
|
{
|
|
EMSVTUTF8Channel* Channel;
|
|
PCHANNEL_THREAD_DATA ChannelThreadData;
|
|
DWORD Status;
|
|
ULONG i;
|
|
WCHAR Buffer[256];
|
|
|
|
|
|
ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
|
|
|
|
SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
|
|
|
|
//
|
|
// Configure the new channel
|
|
//
|
|
RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
|
|
|
|
Attributes.Type = ChannelTypeVTUTF8;
|
|
Attributes.Name = ChannelThreadData->ChannelName;
|
|
Attributes.Description = ChannelThreadData->ChannelDescription;
|
|
Attributes.Flags = 0;
|
|
Attributes.CloseEvent = NULL;
|
|
Attributes.HasNewDataEvent = NULL;
|
|
Attributes.LockEvent = NULL;
|
|
Attributes.ApplicationType = NULL;
|
|
|
|
//
|
|
// Open the Hello channel
|
|
//
|
|
Channel = EMSVTUTF8Channel::Construct(Attributes);
|
|
|
|
//
|
|
// See if the channel was created
|
|
//
|
|
if (Channel == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Perform thread work
|
|
//
|
|
|
|
i=0;
|
|
|
|
while (1) {
|
|
|
|
Status = WaitForSingleObject(
|
|
ChannelThreadData->ExitEvent,
|
|
THREAD_WAIT_TIMEOUT
|
|
);
|
|
|
|
if (Status != WAIT_TIMEOUT) {
|
|
break;
|
|
}
|
|
|
|
wsprintf(
|
|
Buffer,
|
|
L"%s: %d\r\n",
|
|
ChannelThreadData->ChannelName,
|
|
i++
|
|
);
|
|
|
|
//
|
|
// Write to the Hello Channel
|
|
//
|
|
if (Channel->Write(Buffer)) {
|
|
#if 0
|
|
printf("%S: Successfully printed string to channel\n", ChannelThreadData->ChannelName);
|
|
#endif
|
|
} else {
|
|
printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
|
|
}
|
|
|
|
}
|
|
|
|
delete Channel;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
DWORD
|
|
ChannelThreadRawWrite(
|
|
PVOID Data
|
|
)
|
|
{
|
|
EMSRawChannel* Channel;
|
|
PCHANNEL_THREAD_DATA ChannelThreadData;
|
|
DWORD Status;
|
|
ULONG i;
|
|
BYTE Buffer[256];
|
|
|
|
|
|
ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
|
|
|
|
SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
|
|
|
|
//
|
|
// Configure the new channel
|
|
//
|
|
RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
|
|
|
|
Attributes.Type = ChannelTypeRaw;
|
|
Attributes.Name = ChannelThreadData->ChannelName;
|
|
Attributes.Description = ChannelThreadData->ChannelDescription;
|
|
Attributes.Flags = 0;
|
|
Attributes.CloseEvent = NULL;
|
|
Attributes.HasNewDataEvent = NULL;
|
|
Attributes.LockEvent = NULL;
|
|
Attributes.ApplicationType = NULL;
|
|
|
|
//
|
|
// Open the Hello channel
|
|
//
|
|
Channel = EMSRawChannel::Construct(Attributes);
|
|
|
|
//
|
|
// See if the channel was created
|
|
//
|
|
if (Channel == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Perform thread work
|
|
//
|
|
|
|
i=0;
|
|
|
|
while (1) {
|
|
|
|
Status = WaitForSingleObject(
|
|
ChannelThreadData->ExitEvent,
|
|
THREAD_WAIT_TIMEOUT
|
|
);
|
|
|
|
if (Status != WAIT_TIMEOUT) {
|
|
break;
|
|
}
|
|
|
|
sprintf(
|
|
(CHAR*)Buffer,
|
|
"%S: %d\r\n",
|
|
ChannelThreadData->ChannelName,
|
|
i++
|
|
);
|
|
|
|
//
|
|
// Write to the Hello Channel
|
|
//
|
|
if (Channel->Write(
|
|
Buffer,
|
|
strlen((CHAR*)Buffer)
|
|
)) {
|
|
#if 0
|
|
printf("%S: Successfully printed string to channel\n", ChannelThreadData->ChannelName);
|
|
#endif
|
|
} else {
|
|
printf("%S: Failed to print string to channel\n", ChannelThreadData->ChannelName);
|
|
}
|
|
|
|
}
|
|
|
|
delete Channel;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
DWORD
|
|
ChannelThreadOpenCloseVTUTF8(
|
|
PVOID Data
|
|
)
|
|
{
|
|
EMSRawChannel* Channel;
|
|
PCHANNEL_THREAD_DATA ChannelThreadData;
|
|
DWORD Status;
|
|
ULONG i;
|
|
|
|
ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
|
|
|
|
SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
|
|
|
|
//
|
|
// Configure the new channel
|
|
//
|
|
RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
|
|
|
|
Attributes.Type = ChannelTypeVTUTF8;
|
|
Attributes.Name = ChannelThreadData->ChannelName;
|
|
Attributes.Description = ChannelThreadData->ChannelDescription;
|
|
Attributes.Flags = 0;
|
|
Attributes.CloseEvent = NULL;
|
|
Attributes.HasNewDataEvent = NULL;
|
|
Attributes.LockEvent = NULL;
|
|
Attributes.ApplicationType = NULL;
|
|
|
|
//
|
|
// Perform thread work
|
|
//
|
|
|
|
i=0;
|
|
|
|
while (1) {
|
|
|
|
Status = WaitForSingleObject(
|
|
ChannelThreadData->ExitEvent,
|
|
THREAD_WAIT_TIMEOUT
|
|
);
|
|
|
|
if (Status != WAIT_TIMEOUT) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Open the Hello channel
|
|
//
|
|
Channel = EMSRawChannel::Construct(Attributes);
|
|
|
|
//
|
|
// See if the channel was created
|
|
//
|
|
if (Channel == NULL) {
|
|
continue;
|
|
}
|
|
|
|
delete Channel;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
DWORD
|
|
ChannelThreadOpenCloseRaw(
|
|
PVOID Data
|
|
)
|
|
{
|
|
EMSRawChannel* Channel;
|
|
PCHANNEL_THREAD_DATA ChannelThreadData;
|
|
DWORD Status;
|
|
ULONG i;
|
|
|
|
ChannelThreadData = (PCHANNEL_THREAD_DATA)Data;
|
|
|
|
SAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
|
|
|
|
RtlZeroMemory(&Attributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
|
|
|
|
//
|
|
// Configure the new channel
|
|
//
|
|
Attributes.Type = ChannelTypeRaw;
|
|
Attributes.Name = ChannelThreadData->ChannelName;
|
|
Attributes.Description = ChannelThreadData->ChannelDescription;
|
|
Attributes.Flags = 0;
|
|
Attributes.CloseEvent = NULL;
|
|
Attributes.HasNewDataEvent = NULL;
|
|
Attributes.LockEvent = NULL;
|
|
Attributes.ApplicationType = NULL;
|
|
|
|
//
|
|
// Perform thread work
|
|
//
|
|
|
|
i=0;
|
|
|
|
while (1) {
|
|
|
|
Status = WaitForSingleObject(
|
|
ChannelThreadData->ExitEvent,
|
|
THREAD_WAIT_TIMEOUT
|
|
);
|
|
|
|
if (Status != WAIT_TIMEOUT) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Open the Hello channel
|
|
//
|
|
Channel = EMSRawChannel::Construct(Attributes);
|
|
|
|
//
|
|
// See if the channel was created
|
|
//
|
|
if (Channel == NULL) {
|
|
continue;
|
|
}
|
|
|
|
delete Channel;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
DWORD (*ChannelTests[THREADCOUNT])(PVOID) = {
|
|
ChannelThreadVTUTF8Write,
|
|
ChannelThreadVTUTF8Write,
|
|
ChannelThreadVTUTF8Write,
|
|
ChannelThreadVTUTF8Write,
|
|
ChannelThreadRawWrite,
|
|
ChannelThreadRawWrite,
|
|
ChannelThreadRawWrite,
|
|
ChannelThreadRawWrite,
|
|
ChannelThreadOpenCloseRaw,
|
|
ChannelThreadOpenCloseRaw,
|
|
ChannelThreadOpenCloseRaw,
|
|
ChannelThreadOpenCloseRaw,
|
|
ChannelThreadOpenCloseVTUTF8,
|
|
ChannelThreadOpenCloseVTUTF8,
|
|
ChannelThreadOpenCloseVTUTF8,
|
|
ChannelThreadOpenCloseVTUTF8
|
|
};
|
|
|
|
int __cdecl
|
|
NoMoreMemory(
|
|
size_t
|
|
)
|
|
{
|
|
DebugBreak();
|
|
|
|
OutputDebugString(L"EMS Stress: NoMoreMemory!!\r\n");
|
|
|
|
ExitProcess( 1 );
|
|
}
|
|
|
|
int _cdecl
|
|
wmain(
|
|
int argc,
|
|
WCHAR **argv
|
|
)
|
|
{
|
|
HANDLE Channel[THREADCOUNT];
|
|
CHANNEL_THREAD_DATA ChannelData[THREADCOUNT];
|
|
HANDLE ExitEvent;
|
|
ULONG i;
|
|
|
|
_set_new_handler( NoMoreMemory );
|
|
|
|
ExitEvent = CreateEvent(
|
|
NULL, // no security attributes
|
|
TRUE, // manual-reset event
|
|
FALSE, // initial state is signaled
|
|
NULL // object name
|
|
);
|
|
|
|
if (ExitEvent == NULL) {
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// create the worker threads
|
|
//
|
|
for (i = 0; i < THREADCOUNT; i++) {
|
|
|
|
//
|
|
// populate the thread data structure
|
|
//
|
|
|
|
ChannelData[i].ExitEvent = ExitEvent;
|
|
wsprintf(
|
|
ChannelData[i].ChannelName,
|
|
L"CT%02d",
|
|
i
|
|
);
|
|
ChannelData[i].ChannelDescription[0] = UNICODE_NULL;
|
|
|
|
//
|
|
// create the thread
|
|
//
|
|
|
|
Channel[i] = CreateThread(
|
|
NULL,
|
|
0,
|
|
ChannelTests[i],
|
|
&(ChannelData[i]),
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if (Channel[i] == NULL) {
|
|
goto cleanup;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// wait for local user to end the stress
|
|
//
|
|
getc(stdin);
|
|
|
|
cleanup:
|
|
|
|
SetEvent(ExitEvent);
|
|
|
|
WaitForMultipleObjects(
|
|
THREADCOUNT,
|
|
Channel,
|
|
TRUE,
|
|
INFINITE
|
|
);
|
|
|
|
for (i = 0; i < THREADCOUNT; i++) {
|
|
CloseHandle(Channel[i]);
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|