telnetd.cpp
上传用户:chenchao
上传日期:2007-01-09
资源大小:22k
文件大小:17k
源码类别:

Telnet服务器

开发平台:

Visual C++

  1. #define WIN32_LEAN_AND_MEAN
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include <process.h>
  5. #include <winsock2.h>
  6. #include <stdio.h>
  7. #define ERR_BUFF_LEN 1024
  8. #pragma comment( lib, "wsock32" )
  9. #pragma comment( lib, "advapi32" ) 
  10. extern long restartCount;
  11. extern volatile BOOL requestReset;
  12. //Winsock Data block
  13. WSADATA wi;
  14. //Thread handles
  15. UINT thrid_sock;
  16. UINT thrid_console;
  17. UINT thrid_error;
  18. //Stdin/out handles
  19. HANDLE stdinput;
  20. HANDLE stdoutput;
  21. HANDLE stderror;
  22. // "Input" pipe for the console.
  23. HANDLE readInput;
  24. HANDLE writeInput;
  25. // Console "Output" pipe.
  26. HANDLE readOutput;
  27. HANDLE writeOutput;
  28. // Console stderr pipe.
  29. HANDLE readError;
  30. HANDLE writeError;
  31. //Main "listen" socket.
  32. sockaddr_in myaddr;
  33. SOCKET sock;
  34. //Telnet connection socket
  35. SOCKET talk;
  36. //"Share handles" security descriptor
  37. SECURITY_ATTRIBUTES security = {
  38. sizeof(SECURITY_ATTRIBUTES),
  39. NULL,
  40. TRUE
  41. };
  42. //Console Process creation information
  43. STARTUPINFO si;
  44. PROCESS_INFORMATION pi;
  45. HANDLE m_SocketClosed;
  46. unsigned __stdcall run_sock(void*)
  47. {
  48. char buffer;
  49. int read;
  50. DWORD writ;
  51. while(TRUE)
  52. {
  53. read=recv(talk,&buffer,1,0);
  54. if(!read || read == SOCKET_ERROR)
  55. {
  56. if( m_SocketClosed )
  57. ::SetEvent(m_SocketClosed);
  58. break;
  59. }
  60. send(talk, &buffer, 1,0);
  61. WriteFile( writeInput, &buffer, read, &writ,NULL);
  62. }
  63. return 0;
  64. }
  65. #define BUFF_SIZE 256
  66. unsigned __stdcall run_console(void*)
  67. {
  68. char buffer[BUFF_SIZE];
  69. DWORD read;
  70. while(ReadFile(readOutput,buffer,BUFF_SIZE,&read,NULL))
  71. send(talk,buffer,read,0);
  72. if( m_SocketClosed )
  73. ::SetEvent(m_SocketClosed);
  74. return 0;
  75. }
  76. unsigned __stdcall run_error(void*)
  77. {
  78. char buffer[BUFF_SIZE];
  79. DWORD read;
  80. while(ReadFile(readError,buffer,BUFF_SIZE,&read,NULL))
  81. send(talk,buffer,read,0);
  82. if( m_SocketClosed )
  83. ::SetEvent(m_SocketClosed);
  84. return 0;
  85. }
  86. static BOOL
  87. getAndAllocateLogonSid(
  88. HANDLE hToken,
  89. PSID *pLogonSid
  90. )
  91. {
  92. PTOKEN_GROUPS ptgGroups = NULL;
  93. DWORD cbBuffer  = 0;   /* allocation size */
  94. DWORD dwSidLength; /* required size to hold Sid */
  95. UINT i; /* Sid index counter */
  96. BOOL bSuccess  = FALSE; /* assume this function will fail */
  97. *pLogonSid = NULL; // invalidate pointer
  98. /*
  99. ** Get neccessary memory allocation
  100. */
  101. GetTokenInformation(hToken, TokenGroups, ptgGroups, cbBuffer, &cbBuffer);
  102. if (cbBuffer)
  103. ptgGroups = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbBuffer);
  104. /*
  105. ** Get Sids for all groups the user belongs to
  106. */
  107. bSuccess = GetTokenInformation(
  108. hToken,
  109. TokenGroups,
  110. ptgGroups,
  111. cbBuffer,
  112. &cbBuffer
  113. );
  114. if (bSuccess == FALSE)
  115. goto finish3;
  116. /*
  117. ** Get the logon Sid by looping through the Sids in the token
  118. */
  119. for(i = 0 ; i < ptgGroups->GroupCount ; i++)
  120. {
  121. if (ptgGroups->Groups[i].Attributes & SE_GROUP_LOGON_ID)
  122. {
  123. /*
  124. ** insure we are dealing with a valid Sid
  125. */
  126. bSuccess = IsValidSid(ptgGroups->Groups[i].Sid);
  127. if (bSuccess == FALSE)
  128. goto finish3;
  129. /*
  130. ** get required allocation size to copy the Sid
  131. */
  132. dwSidLength=GetLengthSid(ptgGroups->Groups[i].Sid);
  133. /*
  134. ** allocate storage for the Logon Sid
  135. */
  136. if(
  137. (*pLogonSid = (PSID)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSidLength))
  138. ==
  139. NULL
  140. )
  141. {
  142. bSuccess = FALSE;
  143. goto finish3;
  144. }
  145. /*
  146. ** copy the Logon Sid to the storage we just allocated
  147. */
  148. bSuccess = CopySid(
  149. dwSidLength,
  150. *pLogonSid,
  151. ptgGroups->Groups[i].Sid
  152. );
  153. break;
  154. }
  155. }
  156. finish3:
  157. /*
  158. ** free allocated resources
  159. */
  160. if (bSuccess == FALSE)
  161. {
  162. if(*pLogonSid != NULL)
  163. {
  164. HeapFree(GetProcessHeap(), 0, *pLogonSid);
  165. *pLogonSid = NULL;
  166. }
  167. }
  168. if (ptgGroups != NULL)
  169. HeapFree(GetProcessHeap(), 0, ptgGroups);
  170. return bSuccess;
  171. }
  172.  
  173.  
  174. static BOOL
  175. setSidOnAcl(
  176. PSID pSid,
  177. PACL pAclSource,
  178. PACL *pAclDestination,
  179. DWORD AccessMask,
  180. BOOL bAddSid,
  181. BOOL bFreeOldAcl
  182. )
  183. {
  184. ACL_SIZE_INFORMATION AclInfo;
  185. DWORD dwNewAclSize;
  186. LPVOID pAce;
  187. DWORD AceCounter;
  188. BOOL bSuccess=FALSE;
  189. /*
  190. ** If we were given a NULL Acl, just provide a NULL Acl
  191. */
  192. if (pAclSource == NULL)
  193. {
  194. *pAclDestination = NULL;
  195. return TRUE;
  196. }
  197. if (!IsValidSid(pSid)) return FALSE;
  198. /*
  199. ** Get ACL's parameters
  200. */
  201. if (
  202. !GetAclInformation(
  203. pAclSource,
  204. &AclInfo,
  205. sizeof(ACL_SIZE_INFORMATION),
  206. AclSizeInformation
  207. )
  208. )
  209. return FALSE;
  210. /*
  211. ** Compute size for new ACL, based on
  212. ** addition or subtraction of ACE
  213. */
  214. if (bAddSid)
  215. {
  216. dwNewAclSize = AclInfo.AclBytesInUse  +
  217. sizeof(ACCESS_ALLOWED_ACE)  +
  218. GetLengthSid(pSid)          -
  219. sizeof(DWORD)               ;
  220. }
  221. else
  222. {
  223. dwNewAclSize = AclInfo.AclBytesInUse  -
  224. sizeof(ACCESS_ALLOWED_ACE)  -
  225. GetLengthSid(pSid)          +
  226. sizeof(DWORD)               ;
  227. }
  228. *pAclDestination = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize);
  229. if(*pAclDestination == NULL)
  230. return FALSE;
  231. /*
  232. ** initialize new Acl
  233. */
  234. bSuccess = InitializeAcl(*pAclDestination, dwNewAclSize, ACL_REVISION);
  235. if (bSuccess == FALSE)
  236. goto finish5;
  237. /*
  238. ** copy existing ACEs to new ACL
  239. */
  240. for(AceCounter = 0 ; AceCounter < AclInfo.AceCount ; AceCounter++)
  241. {
  242. /*
  243. ** fetch existing ace
  244. */
  245. bSuccess = GetAce(pAclSource, AceCounter, &pAce);
  246. if (bSuccess == FALSE)
  247. goto finish5;
  248. /*
  249. ** check to see if we are removing the ACE
  250. */
  251. if (!bAddSid)
  252. {
  253. /*
  254. ** we only care about ACCESS_ALLOWED ACEs
  255. */
  256. if ((((PACE_HEADER)pAce)->AceType) == ACCESS_ALLOWED_ACE_TYPE)
  257. {
  258. PSID pTempSid=(PSID)&((PACCESS_ALLOWED_ACE)pAce)->SidStart;
  259. /*
  260. ** if the Sid matches, skip adding this Sid
  261. */
  262. if (EqualSid(pSid, pTempSid)) continue;
  263. }
  264. }
  265. /*
  266. ** append ACE to ACL
  267. */
  268. bSuccess = AddAce(
  269. *pAclDestination,
  270. ACL_REVISION,
  271. 0,  // maintain Ace order
  272. pAce,
  273. ((PACE_HEADER)pAce)->AceSize
  274. );
  275. if (bSuccess == FALSE)
  276. goto finish5;
  277. }
  278. /*
  279. ** If appropriate, add ACE representing pSid
  280. */
  281. if (bAddSid)
  282. bSuccess = AddAccessAllowedAce(
  283. *pAclDestination,
  284. ACL_REVISION,
  285. AccessMask,
  286. pSid
  287. );
  288. finish5:
  289. /*
  290. ** free memory if an error occurred
  291. */
  292. if (!bSuccess)
  293. {
  294. if(*pAclDestination != NULL)
  295. HeapFree(GetProcessHeap(), 0, *pAclDestination);
  296. }
  297. else if (bFreeOldAcl)
  298. HeapFree(GetProcessHeap(), 0, pAclSource);
  299. return bSuccess;
  300. }
  301. static BOOL
  302. setWinstaDesktopSecurity(
  303. HWINSTA hWinsta,
  304. HDESK hDesktop,
  305. PSID pLogonSid,
  306. BOOL bGrant,
  307. HANDLE hToken
  308. )
  309. {
  310. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
  311. PSECURITY_DESCRIPTOR sdDesktop = NULL;
  312. PSECURITY_DESCRIPTOR sdWinsta = NULL;
  313. SECURITY_DESCRIPTOR sdNewDesktop;
  314. SECURITY_DESCRIPTOR sdNewWinsta;
  315. DWORD sdDesktopLength = 0; /* allocation size */
  316. DWORD sdWinstaLength = 0; /* allocation size */
  317. PACL pDesktopDacl; /* previous Dacl on Desktop */
  318. PACL pWinstaDacl;        /* previous Dacl on Winsta */
  319. PACL pNewDesktopDacl = NULL; /* new Dacl for Desktop */
  320. PACL pNewWinstaDacl = NULL; /* new Dacl for Winsta */
  321. BOOL bDesktopDaclPresent;
  322. BOOL bWinstaDaclPresent;
  323. BOOL bDaclDefaultDesktop;
  324. BOOL bDaclDefaultWinsta;
  325. BOOL bSuccess = FALSE;
  326. PSID pUserSid = NULL;
  327. /*
  328. ** Obtain security descriptor for Desktop
  329. */
  330. GetUserObjectSecurity(
  331. hDesktop,
  332. &si,
  333. sdDesktop,
  334. sdDesktopLength,
  335. &sdDesktopLength
  336. );
  337. if (sdDesktopLength)
  338. sdDesktop = (PSECURITY_DESCRIPTOR)HeapAlloc(
  339. GetProcessHeap(), HEAP_ZERO_MEMORY, sdDesktopLength);
  340. bSuccess = GetUserObjectSecurity(
  341. hDesktop,
  342. &si,
  343. sdDesktop,
  344. sdDesktopLength,
  345. &sdDesktopLength
  346. );
  347. if (bSuccess == FALSE)
  348. goto finish4;
  349. /*
  350. ** Obtain security descriptor for Window station
  351. */
  352. GetUserObjectSecurity(
  353. hWinsta,
  354. &si,
  355. sdWinsta,
  356. sdWinstaLength,
  357. &sdWinstaLength
  358. );
  359. if (sdWinstaLength)
  360. sdWinsta = (PSECURITY_DESCRIPTOR)HeapAlloc(
  361. GetProcessHeap(), HEAP_ZERO_MEMORY, sdWinstaLength);
  362. bSuccess = GetUserObjectSecurity(
  363. hWinsta,
  364. &si,
  365. sdWinsta,
  366. sdWinstaLength,
  367. &sdWinstaLength
  368. );
  369. if (bSuccess == FALSE)
  370. goto finish4;
  371. /*
  372. ** Obtain DACL from security descriptor for desktop
  373. */
  374. bSuccess = GetSecurityDescriptorDacl(
  375. sdDesktop,
  376. &bDesktopDaclPresent,
  377. &pDesktopDacl,
  378. &bDaclDefaultDesktop
  379. );
  380. if (bSuccess == FALSE)
  381. goto finish4;
  382. /*
  383. ** Obtain DACL from security descriptor for Window station
  384. */
  385. bSuccess = GetSecurityDescriptorDacl(
  386. sdWinsta,
  387. &bWinstaDaclPresent,
  388. &pWinstaDacl,
  389. &bDaclDefaultWinsta
  390. );
  391. if (bSuccess == FALSE)
  392. goto finish4;
  393. /*
  394. ** Create new DACL with Logon and User Sid for Desktop
  395. */
  396. if(bDesktopDaclPresent) {
  397. bSuccess = setSidOnAcl(
  398. pLogonSid,
  399. pDesktopDacl,
  400. &pNewDesktopDacl,
  401. GENERIC_READ | GENERIC_WRITE | READ_CONTROL
  402. | DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW
  403. | DESKTOP_CREATEMENU | DESKTOP_SWITCHDESKTOP
  404. | DESKTOP_ENUMERATE,
  405. bGrant,
  406. FALSE
  407. );
  408. if (bSuccess == FALSE)
  409. goto finish4;
  410. }
  411. /*
  412. ** Create new DACL with Logon and User Sid for Window station
  413. */
  414. if(bWinstaDaclPresent)
  415. {
  416. bSuccess = setSidOnAcl(
  417. pLogonSid,
  418. pWinstaDacl,
  419. &pNewWinstaDacl,
  420. GENERIC_READ | GENERIC_WRITE | READ_CONTROL
  421. | WINSTA_ACCESSGLOBALATOMS
  422. | WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES
  423. | WINSTA_ACCESSCLIPBOARD | WINSTA_ENUMERATE
  424. | WINSTA_EXITWINDOWS,
  425. bGrant,
  426. FALSE
  427. );
  428. if (bSuccess == FALSE)
  429. goto finish4;
  430. }
  431.  
  432. /*
  433. ** Initialize the target security descriptor for Desktop
  434. */
  435. if (bDesktopDaclPresent)
  436. {
  437. bSuccess = InitializeSecurityDescriptor(
  438. &sdNewDesktop,
  439. SECURITY_DESCRIPTOR_REVISION
  440. );
  441. if (bSuccess == FALSE)
  442. goto finish4;
  443. }
  444. /*
  445. ** Initialize the target security descriptor for Window station
  446. */
  447. if(bWinstaDaclPresent)
  448. {
  449. bSuccess = InitializeSecurityDescriptor(
  450. &sdNewWinsta,
  451. SECURITY_DESCRIPTOR_REVISION
  452. );
  453. if (bSuccess == FALSE)
  454. goto finish4;
  455. }
  456. /*
  457. ** Apply new ACL to the Desktop security descriptor
  458. */
  459. if(bDesktopDaclPresent)
  460. {
  461. bSuccess = SetSecurityDescriptorDacl(
  462. &sdNewDesktop,
  463. TRUE,
  464. pNewDesktopDacl,
  465. bDaclDefaultDesktop
  466. );
  467. if (bSuccess == FALSE)
  468. goto finish4;
  469. }
  470. /*
  471. ** Apply new ACL to the Window station security descriptor
  472. */
  473. if(bWinstaDaclPresent)
  474. {
  475. bSuccess = SetSecurityDescriptorDacl(
  476. &sdNewWinsta,
  477. TRUE,
  478. pNewWinstaDacl,
  479. bDaclDefaultWinsta
  480. );
  481. if (bSuccess == FALSE)
  482. goto finish4;
  483. }
  484. /*
  485. ** Apply security descriptors with new DACLs to Desktop and Window station
  486. */
  487. if (bDesktopDaclPresent)
  488. {
  489. bSuccess = SetUserObjectSecurity(
  490. hDesktop,
  491. &si,
  492. &sdNewDesktop
  493. );
  494. if (bSuccess == FALSE)
  495. goto finish4;
  496. }
  497. if(bWinstaDaclPresent)
  498. bSuccess = SetUserObjectSecurity(
  499. hWinsta,
  500. &si,
  501. &sdNewWinsta
  502. );
  503. if (bSuccess == FALSE)
  504. goto finish4;
  505. finish4:
  506. if (sdDesktop != NULL)
  507. HeapFree(GetProcessHeap(), 0, sdDesktop);
  508. if (sdWinsta != NULL)
  509. HeapFree(GetProcessHeap(), 0, sdWinsta);
  510. if (pNewDesktopDacl != NULL)
  511. HeapFree(GetProcessHeap(), 0, pNewDesktopDacl);
  512. if (pNewWinstaDacl != NULL)
  513. HeapFree(GetProcessHeap(), 0, pNewWinstaDacl);
  514. return bSuccess;
  515. }
  516. static BOOL
  517. allowDesktopAccess(HANDLE hToken)
  518. {
  519. HWINSTA hWinsta = NULL;
  520. HDESK hDesktop = NULL;
  521. PSID pLogonSid = NULL;
  522. BOOL ok = FALSE;
  523. if (!getAndAllocateLogonSid(hToken, &pLogonSid))
  524. return FALSE;
  525. hWinsta=GetProcessWindowStation();
  526. hDesktop=GetThreadDesktop(GetCurrentThreadId());
  527.  
  528. ok = SetHandleInformation(hDesktop,
  529.   HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
  530. if (!ok)
  531. return FALSE;
  532. ok = SetHandleInformation(hWinsta,
  533.   HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
  534. if (!ok)
  535. return FALSE;
  536. ok = setWinstaDesktopSecurity(hWinsta, hDesktop, pLogonSid, TRUE, hToken);
  537. if(pLogonSid != NULL)
  538. HeapFree(GetProcessHeap(), 0, pLogonSid);
  539. return ok;
  540. }
  541. char GetCharFromClient()
  542. {
  543. char ch;
  544. int read=recv(talk,&ch,1,0);
  545. if(!read)
  546. {
  547. ch = -1;
  548. printf("Socket broken at other end....n");
  549. }
  550. return ch;
  551. }
  552. BOOL GetString(char * prompt,char * value,BOOL maskinput)
  553. {
  554. char crlf[3] = {0x0D, 0x0A, 0x00};
  555. send(talk,crlf,strlen(crlf),0);
  556. send(talk,prompt,strlen(prompt),0);
  557. char c = GetCharFromClient();
  558. int index = 0;
  559. while(c >0)
  560. {
  561. if(c == 0x0A) return TRUE;
  562. if(!maskinput)
  563. {
  564. if(c > 0x0D)
  565. send(talk,&c,1,0);
  566. }
  567. else
  568. {
  569. char mask = '*';
  570. if(c > 0x0D)
  571. send(talk,&mask,1,0);
  572. }
  573. if(c > 0x0D)
  574. {
  575. value[index]=c;
  576. index++;
  577. }
  578. else
  579. {
  580. value[index]=0x00;
  581. index++;
  582. }
  583. c = GetCharFromClient();
  584. }
  585. return FALSE;
  586. }
  587. void Cycle(void)
  588. {
  589. // Startup Winsock
  590. WSAStartup(0x0101,&wi);
  591. //create the stop event
  592. m_SocketClosed = CreateEvent(0, TRUE, FALSE, 0);
  593. // Create a Socket to connect to the remote doodaad...
  594. sock = socket(AF_INET,SOCK_STREAM,0);
  595. // Get our own name so we can get our IP...
  596. char hostname[64];
  597. gethostname(hostname,64);
  598. // Get our hostent info
  599. hostent* hent = gethostbyname(hostname);
  600. // Bind our address and the telnet port to the socket
  601. myaddr.sin_family = AF_INET;
  602. myaddr.sin_port = htons(23);
  603. myaddr.sin_addr.s_addr = *(DWORD*)hent->h_addr_list[0];
  604. if( bind(sock,(sockaddr*)&myaddr,sizeof(sockaddr)))
  605. return;
  606. // Listen for an incomming connections...
  607. listen(sock,1);
  608. // accept an incoming
  609. talk = accept(sock,NULL,NULL);
  610. //print the welcome string
  611. char * msg = "Telnet Server Started";
  612. send(talk,msg,strlen(msg),0);
  613. char crlf[3] = {0x0D, 0x0A, 0x00};
  614. send(talk,crlf,strlen(crlf),0);
  615. send(talk,crlf,strlen(crlf),0);
  616. send(talk,crlf,strlen(crlf),0);
  617. //get the username and password
  618. char username[64];
  619. char password[64];
  620. char domain[64];
  621. // Save the "Standard" handles.
  622. stdinput = GetStdHandle(STD_INPUT_HANDLE);
  623. stdoutput = GetStdHandle(STD_OUTPUT_HANDLE);
  624. stderror = GetStdHandle(STD_ERROR_HANDLE);
  625. // Create the "Input" pipe for the console to get stuff from us
  626. CreatePipe(&readInput,&writeInput,&security,0);
  627. // Set the Default "Input" handle of the console to be this pipe
  628. SetStdHandle(STD_INPUT_HANDLE,readInput);
  629. // Create the console's "Output" pipe by which we get stuff back
  630. CreatePipe(&readOutput,&writeOutput,&security,0);
  631. // Set the "Output" handle to be this pipe.
  632. SetStdHandle(STD_OUTPUT_HANDLE,writeOutput);
  633. // Create the console's Error pipe
  634. CreatePipe(&readError,&writeError,&security,0);
  635. // Set the stderr handle to be our pipe.
  636. SetStdHandle(STD_ERROR_HANDLE,writeError);
  637. if(GetString("Username:",username,FALSE))
  638. if(GetString("Password:",password,TRUE))
  639. if(GetString("  Domain:",domain,FALSE))
  640. {
  641. send(talk,crlf,strlen(crlf),0);
  642. send(talk,crlf,strlen(crlf),0);
  643. // Create a thread to handle socket input
  644. unsigned int th1 = _beginthreadex(NULL,0,run_sock,NULL,0,&thrid_sock);
  645. // Create our thread to console input
  646. unsigned int th2 = _beginthreadex(NULL,0,run_console,NULL,0,&thrid_console);
  647. // Create a thread to handle error input
  648. unsigned int th3 = _beginthreadex(NULL,0,run_error,NULL,0,&thrid_error);
  649. HANDLE          hUserToken;
  650. if(LogonUser(
  651. username,
  652. domain,
  653. password,
  654. LOGON32_LOGON_INTERACTIVE,
  655. LOGON32_PROVIDER_DEFAULT,
  656. &hUserToken ))
  657. {
  658. if(allowDesktopAccess(hUserToken))
  659. {
  660. ZeroMemory(&si,sizeof(STARTUPINFO));
  661. si.cb = sizeof(STARTUPINFO);
  662. si.lpReserved = NULL;
  663. si.lpReserved2 = NULL;
  664. si.cbReserved2 = 0;
  665. si.lpDesktop = NULL;
  666. si.wShowWindow = SW_HIDE;
  667. char SysDir[256];
  668. GetSystemDirectory(SysDir,256);
  669. si.dwFlags = 0;
  670. si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  671. si.hStdInput = readInput;
  672. si.hStdOutput = writeOutput;
  673. si.hStdError = writeError;
  674. si.wShowWindow = SW_HIDE;
  675. // Create the process...
  676. if(CreateProcessAsUser(
  677. hUserToken,
  678. getenv("COMSPEC"),
  679. NULL,
  680. NULL,
  681. NULL,
  682. TRUE,
  683. 0,
  684. NULL,
  685. NULL,
  686. &si,
  687. &pi))
  688. {
  689. _flushall();
  690. // make sure the process is dead!
  691. HANDLE wait[2];
  692. wait[0]=pi.hProcess;
  693. wait[1]=m_SocketClosed;
  694. WaitForMultipleObjectsEx(2,wait,FALSE,INFINITE,FALSE);
  695. _flushall();
  696. }
  697. }
  698. CloseHandle(hUserToken);
  699. }
  700. TerminateThread((void*)th1,0);
  701. TerminateThread((void*)th2,0);
  702. TerminateThread((void*)th3,0);
  703. }
  704. closesocket(talk);
  705. closesocket(sock);
  706. CloseHandle(m_SocketClosed);
  707. CloseHandle(readInput);
  708. CloseHandle(writeInput);
  709. CloseHandle(readOutput);
  710. CloseHandle(writeOutput);
  711. CloseHandle(readError);
  712. CloseHandle(writeError);
  713. SetStdHandle(STD_INPUT_HANDLE,stdinput);
  714. SetStdHandle(STD_OUTPUT_HANDLE,stdoutput);
  715. SetStdHandle(STD_ERROR_HANDLE,stderror);
  716. //Cleanup the socket layer
  717. WSACleanup();
  718. }
  719. unsigned __stdcall Daemon(void*)
  720. {
  721. while(TRUE)
  722. {
  723. Cycle();
  724. }
  725. return 0;
  726. }