Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1258 lines
26 KiB

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include "ntddmodm.h"
#include "windows.h"
#include "t2prot.h"
VOID
SndProt(
IN HANDLE Pipe,
IN UCHAR TokenToSend,
IN ULONG CurrentLine
);
BOOL
RcvProt(
IN HANDLE Pipe,
IN UCHAR ExpectedProt,
IN ULONG CurrentLine
);
int _CRTAPI1 main(int argc,char *argv[]) {
HANDLE hFile1;
HANDLE hFile2;
HANDLE pipeHandle;
HANDLE remoteHandle;
HANDLE targetProcessHandle;
DWORD targetProcessId;
DWORD numberOfBytesRead;
DWORD numberOfBytesWritten1;
DWORD numberOfBytesWritten2;
DWORD numberOfBytesWritten3;
UCHAR protocolToken;
DWORD lastError;
DWORD waitResult;
HANDLE duplicatedHandle;
DWORD numberOfBytesWritten;
DWORD modemStatus;
char *MyPort = "\\\\.\\Hayes Optima 144";
OVERLAPPED olControl;
OVERLAPPED ol1;
OVERLAPPED ol2;
OVERLAPPED ol3;
OVERLAPPED olMask;
HANDLE eventArray[3];
DWORD whatState;
char writeBuffer1[10];
char writeBuffer2[10];
char writeBuffer3[10];
COMMTIMEOUTS timeOuts = {0};
DCB hFile1Dcb;
DWORD repititions = 1000;
DWORD satisfiedMask;
//
// Get the number of types to attempt the test.
//
if (argc > 1) {
sscanf(argv[1],"%d",&repititions);
}
if (!(olControl.hEvent = CreateEvent(
NULL,
FALSE,
FALSE,
NULL
))) {
FAILURE(0);
} else {
olControl.Internal = 0;
olControl.InternalHigh = 0;
olControl.Offset = 0;
olControl.OffsetHigh = 0;
}
if (!(ol1.hEvent = CreateEvent(
NULL,
FALSE,
FALSE,
NULL
))) {
FAILURE(0);
} else {
ol1.Internal = 0;
ol1.InternalHigh = 0;
ol1.Offset = 0;
ol1.OffsetHigh = 0;
}
if (!(ol2.hEvent = CreateEvent(
NULL,
FALSE,
FALSE,
NULL
))) {
FAILURE(0);
} else {
ol2.Internal = 0;
ol2.InternalHigh = 0;
ol2.Offset = 0;
ol2.OffsetHigh = 0;
}
if (!(ol3.hEvent = CreateEvent(
NULL,
FALSE,
FALSE,
NULL
))) {
FAILURE(0);
} else {
ol3.Internal = 0;
ol3.InternalHigh = 0;
ol3.Offset = 0;
ol3.OffsetHigh = 0;
}
if (!(olMask.hEvent = CreateEvent(
NULL,
FALSE,
FALSE,
NULL
))) {
FAILURE(0);
} else {
olMask.Internal = 0;
olMask.InternalHigh = 0;
olMask.Offset = 0;
olMask.OffsetHigh = 0;
}
//
// Create/Open the named pipe.
//
if ((pipeHandle = CreateNamedPipe(
"\\\\.\\pipe\\unitest",
PIPE_ACCESS_DUPLEX,
0,
PIPE_UNLIMITED_INSTANCES,
1000,
1000,
MYPIPETIMEOUT,
0
)) == INVALID_HANDLE_VALUE) {
FAILURE(0);
}
//
// Open the named pipe to the remote machine that will
// set lines for us.
//
if ((remoteHandle = CreateFile(
"\\\\.\\pipe\\uniremote",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
)) == ((HANDLE)-1)) {
FAILURE(GetLastError());
}
//
// We created the named pipe. Now connect to it so that
// we can wait for the client to start up.
//
if (!ConnectNamedPipe(
pipeHandle,
NULL
)) {
FAILURE(GetLastError());
}
eventArray[0] = ol1.hEvent;
eventArray[1] = ol2.hEvent;
eventArray[2] = ol3.hEvent;
//
// Read the process handle for the process that wants the
// duplicate
//
if (!ReadFile(
pipeHandle,
&targetProcessId,
sizeof(targetProcessId),
&numberOfBytesRead,
NULL
)) {
FAILURE(GetLastError());
}
//
// Get the target process Handle.
//
targetProcessHandle = OpenProcess(
PROCESS_DUP_HANDLE,
FALSE,
targetProcessId
);
if (targetProcessHandle == NULL) {
FAILURE(GetLastError());
}
//
// We opened the modem twice. Get our current process handle.
//
// Open the pipe \\.\pipe\unitest
//
// Read from the pipe the process handle of the client
//
// Create a duplicate of the second handle using the process
// handle of the client.
//
// Send the duplicate file handle to the client. Wait on the
// process handle of the client to go away. Then we can exit
// also.
//
do {
if ((hFile1 = CreateFile(
MyPort,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
)) == ((HANDLE)-1)) {
FAILURE(GetLastError());
}
if (!GetCommState(
hFile1,
&hFile1Dcb
)) {
FAILURE(GetLastError());
}
//
// Set the state just how we want it.
//
hFile1Dcb.BaudRate = 9600;
hFile1Dcb.ByteSize = 8;
hFile1Dcb.Parity = NOPARITY;
hFile1Dcb.StopBits = ONESTOPBIT;
//
// Make sure that no flow control is turned on.
//
hFile1Dcb.fOutxDsrFlow = FALSE;
hFile1Dcb.fOutxCtsFlow = FALSE;
hFile1Dcb.fDsrSensitivity = FALSE;
hFile1Dcb.fOutX = FALSE;
hFile1Dcb.fInX = FALSE;
hFile1Dcb.fDtrControl = DTR_CONTROL_ENABLE;
hFile1Dcb.fRtsControl = RTS_CONTROL_ENABLE;
if (!SetCommState(
hFile1,
&hFile1Dcb
)) {
FAILURE(GetLastError());
}
if (!SetCommTimeouts(
hFile1,
&timeOuts
)) {
FAILURE(GetLastError());
}
if ((hFile2 = CreateFile(
MyPort,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
)) == ((HANDLE)-1)) {
FAILURE(GetLastError());
}
if (!DuplicateHandle(
GetCurrentProcess(),
hFile2,
targetProcessHandle,
&duplicatedHandle,
0,
TRUE,
DUPLICATE_SAME_ACCESS
)) {
FAILURE(GetLastError());
}
//
// We have the duplicated handle. Close the original one.
//
if (!CloseHandle(hFile2)) {
FAILURE(GetLastError());
}
//
// Send the handle back to the client.
//
if (!WriteFile(
pipeHandle,
&duplicatedHandle,
sizeof(duplicatedHandle),
&numberOfBytesWritten,
NULL
)) {
FAILURE(GetLastError());
}
//
// Wait for the next byte from the client. This tells us
// that the client has queued off a bunch of IO's.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_STRTED_1_IOS
);
//
// At this point we are going to put the device into no-passthrough.
// This should cause all of the io's to complete.
//
whatState = MODEM_NOPASSTHROUGH;
if (!DeviceIoControl(
hFile1,
IOCTL_MODEM_SET_PASSTHROUGH,
&whatState,
sizeof(whatState),
NULL,
0,
&numberOfBytesWritten,
&olControl
)) {
lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
FAILURE(lastError);
}
waitResult = WaitForSingleObject(
olControl.hEvent,
10000
);
if (waitResult == WAIT_FAILED) {
FAILURE(waitResult);
} else {
if (waitResult != WAIT_OBJECT_0) {
FAILURE(waitResult);
}
}
}
//
// Read that the clients are all done with the io.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_DONE_1_IOS
);
//
// Write out a byte to the client. This will be our indication that
// we've gone into no passthrough mode and it should try a doomed write.
//
SNDPROT(
pipeHandle,
TPROT_SRVR_SET_NOPASS
);
//
// All of the IO's are done from the client. send io's to
// the device to make sure we the owner can still do io.
//
if (!WriteFile(
hFile1,
&writeBuffer1[0],
sizeof(writeBuffer1),
&numberOfBytesWritten1,
&ol1
)) {
lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
FAILURE(lastError);
}
}
if (!WriteFile(
hFile1,
&writeBuffer2[0],
sizeof(writeBuffer2),
&numberOfBytesWritten2,
&ol2
)) {
lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
FAILURE(lastError);
}
}
if (!WriteFile(
hFile1,
&writeBuffer3[0],
sizeof(writeBuffer3),
&numberOfBytesWritten3,
&ol3
)) {
lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
FAILURE(lastError);
}
}
//
// Wait for all the writes to complete.
//
waitResult = WaitForMultipleObjects(
3,
&eventArray[0],
TRUE,
10000
);
if (waitResult == WAIT_FAILED) {
FAILURE(GetLastError());
}
if ((waitResult < WAIT_OBJECT_0) ||
(waitResult > (WAIT_OBJECT_0 + 2))) {
FAILURE(waitResult);
}
RCVPROT(
pipeHandle,
TPROT_CLIENT_TRIED_DOOM_WRITE
);
//
// Put it back into non-sniffing passthrough mode.
//
whatState = MODEM_PASSTHROUGH;
if (!DeviceIoControl(
hFile1,
IOCTL_MODEM_SET_PASSTHROUGH,
&whatState,
sizeof(whatState),
NULL,
0,
&numberOfBytesWritten,
&olControl
)) {
lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
FAILURE(lastError);
}
waitResult = WaitForSingleObject(
olControl.hEvent,
10000
);
if (waitResult == WAIT_FAILED) {
FAILURE(waitResult);
} else {
if (waitResult != WAIT_OBJECT_0) {
FAILURE(waitResult);
}
}
}
//
// Send a byte to the client so that it will try to do some
// io's cause we are back in passthrough mode again.
//
SNDPROT(
pipeHandle,
TPROT_SRVR_SET_PASS
);
//
// Wait for a byte from the client telling us that it strted ios.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_STRTED_2_IOS
);
//
// Wait for a byte from the client telling us that it finished ios.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_DONE_2_IOS
);
//
// Put the device into dcd sniff mode.
//
whatState = MODEM_DCDSNIFF;
if (!DeviceIoControl(
hFile1,
IOCTL_MODEM_SET_PASSTHROUGH,
&whatState,
sizeof(whatState),
NULL,
0,
&numberOfBytesWritten,
&olControl
)) {
lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
FAILURE(lastError);
}
waitResult = WaitForSingleObject(
olControl.hEvent,
10000
);
if (waitResult == WAIT_FAILED) {
FAILURE(waitResult);
} else {
if (waitResult != WAIT_OBJECT_0) {
FAILURE(waitResult);
}
}
}
//
// Tell the client we are sniff mode.
//
SNDPROT(
pipeHandle,
TPROT_SRVR_SET_SNIFF
);
//
// Wait for a byte from the client telling us that it knows.
// about the sniff and that it queued operations
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_ACK_SNIFF
);
//
// Wait for a byte from the client telling us that it
// is done doing various setmasks.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_DID_SETMASKS
);
if (!SetCommMask(
hFile1,
EV_RXFLAG
)) {
FAILURE(GetLastError());
}
if (!SetCommMask(
hFile1,
EV_RXFLAG | EV_DSR | EV_RLSD
)) {
FAILURE(GetLastError());
}
//
// Tell the client we are done with setmasks
//
SNDPROT(
pipeHandle,
TPROT_SRVR_SET_SETMASKS
);
//
// Tell the remote end that we are done setting masks
// and that we want a dcd transition.
//
SNDPROT(
remoteHandle,
TPROT_SRVR_DO_DCDTRANS
);
//
// Wait for the client to tell us it did the
// transition. We should be able to check the
// modem state and find our that we are in
// no passthrough. We should tell our local
// client to check that it's ios are all done.
//
RCVPROT(
remoteHandle,
TPROT_CLIENT_DID_DCDTRANS
);
if (!DeviceIoControl(
hFile1,
IOCTL_MODEM_GET_PASSTHROUGH,
&whatState,
sizeof(whatState),
&whatState,
sizeof(whatState),
&numberOfBytesWritten,
&olControl
)) {
lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
FAILURE(lastError);
}
waitResult = WaitForSingleObject(
olControl.hEvent,
10000
);
if (waitResult == WAIT_FAILED) {
FAILURE(waitResult);
} else {
if (waitResult != WAIT_OBJECT_0) {
FAILURE(waitResult);
}
}
if (whatState != MODEM_NOPASSTHROUGH) {
FAILURE(0);
}
}
//
// Now tell the local client to check that its ios are all
// done.
//
SNDPROT(
pipeHandle,
TPROT_CLIENT_DID_DCDTRANS
);
//
// The local client should tell us it's done with dcd trans
// ios.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_DONE_DCDTRANS
);
//
// Tell the remote client all done with dcd trans
//
SNDPROT(
remoteHandle,
TPROT_CLIENT_DONE_DCDTRANS
);
//
// The local client no should ask us for a break.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_WANTS_BREAK
);
SNDPROT(
remoteHandle,
TPROT_CLIENT_WANTS_BREAK
);
RCVPROT(
remoteHandle,
TPROT_CLIENT_SHOULDA_BROKE
);
SNDPROT(
pipeHandle,
TPROT_CLIENT_SHOULDA_BROKE
);
RCVPROT(
pipeHandle,
TPROT_DONE_BREAK
);
//
// Put us into passthrough for the next test.
//
whatState = MODEM_PASSTHROUGH;
if (!DeviceIoControl(
hFile1,
IOCTL_MODEM_SET_PASSTHROUGH,
&whatState,
sizeof(whatState),
NULL,
0,
&numberOfBytesWritten,
&olControl
)) {
lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
FAILURE(lastError);
}
waitResult = WaitForSingleObject(
olControl.hEvent,
10000
);
if (waitResult == WAIT_FAILED) {
FAILURE(waitResult);
} else {
if (waitResult != WAIT_OBJECT_0) {
FAILURE(waitResult);
}
}
}
//
// Wait for the client to tell us it wants to set it mask up.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_WANTS_NEWMASK
);
if (!SetCommMask(
hFile1,
0
)) {
FAILURE(GetLastError());
}
if (!SetCommMask(
hFile1,
EV_DSR | EV_RLSD
)) {
FAILURE(GetLastError());
}
SNDPROT(
pipeHandle,
TPROT_SRVR_SAYS_DONEWMASK
);
//
// After the client sets up its mask, we queue off a wait so
// that we can make sure that we are the passed down wait
// in the modem driver.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_DONE_NEWMASK
);
//
// Start off the wait.
//
satisfiedMask = 0;
if (!WaitCommEvent(
hFile1,
&satisfiedMask,
&olMask
)) {
lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
FAILURE(lastError);
}
} else {
FAILURE(satisfiedMask);
}
//
// Tell the client to go ahead.
//
SNDPROT(
pipeHandle,
TPROT_SRVR_HEARD_DONENEWMASK
);
//
// Wait for the client to tell us he set up the wait.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_DONE_NEWWAITMASK
);
//
// Make sure that our wait is still pending.
//
waitResult = WaitForSingleObject(
olMask.hEvent,
0
);
if (waitResult != WAIT_TIMEOUT) {
FAILURE(waitResult);
}
//
// Tell the remote pipe to go ahead and send the break.
//
SNDPROT(
remoteHandle,
TPROT_REMOTE_SEND_NEW_BREAK
);
//
// Wait for the remote to tell us that it set and then cleared
// the break.
//
RCVPROT(
remoteHandle,
TPROT_REMOTE_DONE_NEW_BREAK
);
//
// Make sure that our wait is still pending.
//
waitResult = WaitForSingleObject(
olMask.hEvent,
0
);
if (waitResult != WAIT_TIMEOUT) {
FAILURE(satisfiedMask);
}
//
// Tell the client to make sure that it's wait is done.
//
SNDPROT(
pipeHandle,
TPROT_SRVR_HEARD_DONENEWWAITMASK
);
RCVPROT(
pipeHandle,
TPROT_CLIENT_DONE_NEWGETRESULTS
);
//
// Make sure ours is still not finished.
//
// Do a setmask to make sure ours is done.
//
waitResult = WaitForSingleObject(
olMask.hEvent,
0
);
if (waitResult != WAIT_TIMEOUT) {
FAILURE(satisfiedMask);
}
if (!SetCommMask(
hFile1,
0
)) {
FAILURE(GetLastError());
}
waitResult = WaitForSingleObject(
olMask.hEvent,
0
);
if (waitResult != WAIT_OBJECT_0) {
FAILURE(waitResult);
}
//
// Make sure that it's return value is zero.
//
if (!GetOverlappedResult(
hFile1,
&olMask,
&numberOfBytesWritten,
FALSE
)) {
FAILURE(GetLastError());
}
if (numberOfBytesWritten != sizeof(DWORD)) {
FAILURE(numberOfBytesWritten);
}
if (satisfiedMask) {
FAILURE(satisfiedMask);
}
//
// Close the main file handle
//
if (!CloseHandle(hFile1)) {
FAILURE(GetLastError());
}
repititions--;
if (repititions > 0) {
//
// Pipe through that we are going to do another round.
//
SNDPROT(
pipeHandle,
TPROT_SRVR_ANOTHER_TEST
);
SNDPROT(
remoteHandle,
TPROT_SRVR_ANOTHER_TEST
);
//
// Wait for acknowledgement of another round.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_ACK_ANOTHER_TEST
);
RCVPROT(
remoteHandle,
TPROT_CLIENT_ACK_ANOTHER_TEST
);
} else {
SNDPROT(
pipeHandle,
TPROT_SRVR_DONE_TEST
);
SNDPROT(
remoteHandle,
TPROT_SRVR_DONE_TEST
);
//
// Wait for acknowledgement of no more rounds.
//
RCVPROT(
pipeHandle,
TPROT_CLIENT_ACK_DONE_TEST
);
RCVPROT(
remoteHandle,
TPROT_CLIENT_ACK_DONE_TEST
);
break;
}
} while (TRUE);
if (!CloseHandle(pipeHandle)) {
FAILURE(GetLastError());
}
exit(1);
return 1;
}
VOID
SndProt(
IN HANDLE Pipe,
IN UCHAR TokenToSend,
IN ULONG CurrentLine
)
{
UCHAR protocolToken = TokenToSend;
DWORD numberOfBytesWritten;
if (!WriteFile(
Pipe,
&protocolToken,
sizeof(protocolToken),
&numberOfBytesWritten,
NULL
)) {
printf(
"\nCouldn't send token: %d - at line:%d - error: %d\n",
protocolToken,
CurrentLine,
GetLastError()
);
exit(1);
}
}
BOOL
RcvProt(
IN HANDLE Pipe,
IN UCHAR ExpectedProt,
IN ULONG CurrentLine
)
{
UCHAR protocolToken = ExpectedProt;
DWORD numberOfBytesPiped;
if (!ReadFile(
Pipe,
&protocolToken,
sizeof(protocolToken),
&numberOfBytesPiped,
NULL
)) {
printf(
"\nCouldn't read the protocol value at line %d - error: %d\n",
CurrentLine,
GetLastError()
);
exit(1);
}
if (protocolToken != ExpectedProt) {
//
// If it isn't the expected protocol perhaps it's the
// terminating protocol. If it is return TRUE.
//
if (protocolToken == TPROT_SRVR_DONE_TEST) {
return TRUE;
} else {
printf(
"Protocol out of sync: %d/%d (token/required) at line: %d\n",
protocolToken,
ExpectedProt,
CurrentLine
);
exit(1);
}
}
return FALSE;
}