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.

1104 lines
28 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1993 - 1999
  3. Module Name:
  4. Remote.c
  5. Abstract:
  6. This module contains the main() entry point for Remote.
  7. Calls the Server or the Client depending on the first parameter.
  8. Author:
  9. Rajivendra Nath (rajnath) 2-Jan-1993
  10. Environment:
  11. Console App. User mode.
  12. Revision History:
  13. --*/
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include "Remote.h"
  17. TCHAR HostName[HOSTNAMELEN];
  18. TCHAR * ChildCmd;
  19. TCHAR* PipeName;
  20. TCHAR* ServerName;
  21. TCHAR* Username;
  22. TCHAR* Password;
  23. HANDLE MyOutHandle;
  24. BOOL bIPLocked=FALSE;
  25. BOOL IsAdvertise=TRUE;
  26. DWORD ClientToServerFlag;
  27. TCHAR* ColorList[]={
  28. TEXT("black"),
  29. TEXT("blue"),
  30. TEXT("green"),
  31. TEXT("cyan"),
  32. TEXT("red"),
  33. TEXT("purple"),
  34. TEXT("yellow"),
  35. TEXT("white"),
  36. TEXT("lblack"),
  37. TEXT("lblue"),
  38. TEXT("lgreen"),
  39. TEXT("lcyan"),
  40. TEXT("lred"),
  41. TEXT("lpurple"),
  42. TEXT("lyellow"),
  43. TEXT("lwhite")
  44. };
  45. WORD
  46. GetColorNum(
  47. TCHAR* color
  48. );
  49. VOID
  50. SetColor(
  51. WORD attr
  52. );
  53. BOOL
  54. GetNextConnectInfo(
  55. TCHAR** SrvName,
  56. TCHAR** PipeName
  57. );
  58. CONSOLE_SCREEN_BUFFER_INFO csbiOriginal;
  59. int _cdecl _tmain(int argc, TCHAR *argv[])
  60. {
  61. WORD RunType; // Server or Client end of Remote
  62. DWORD len=HOSTNAMELEN-1;
  63. int i, FirstArg;
  64. BOOL bSetAttrib=FALSE; // Change Console Attributes
  65. BOOL bPromptForArgs=FALSE; // Is /P option
  66. BOOL bIPSession=TRUE; // Is /N for Named Pipes
  67. TCHAR szTitle[100]; // New Title
  68. TCHAR orgTitle[100]; // Old Title
  69. WORD wAttrib; // Console Attributes
  70. GetComputerName((LPTSTR)HostName,&len);
  71. MyOutHandle=GetStdHandle(STD_OUTPUT_HANDLE);
  72. //
  73. // Save Existing Values
  74. //
  75. //
  76. //Colors /f <ForeGround> /b <BackGround>
  77. //
  78. //
  79. //Title /T Title
  80. //
  81. if (GetConsoleScreenBufferInfo(MyOutHandle,&csbiOriginal)) {
  82. wAttrib = csbiOriginal.wAttributes;
  83. if (!GetConsoleTitle(orgTitle,sizeof(orgTitle)/sizeof(orgTitle[0]))) {
  84. orgTitle[0] = 0;
  85. }
  86. } else {
  87. //
  88. // either stdout is a pipe, or it wasn't opened for
  89. // GENERIC_READ along with GENERIC_WRITE, in which
  90. // case our color manipulations will work so we need
  91. // to pick default colors.
  92. //
  93. wAttrib = FOREGROUND_GREEN |
  94. FOREGROUND_INTENSITY;
  95. orgTitle[0] = 0;
  96. }
  97. //
  98. // Parameter Processing
  99. //
  100. // For Server:
  101. // Remote /S <Executable> <PipeName> [Optional Params]
  102. //
  103. // For Client:
  104. // Remote /C <Server Name> <PipeName> [Optional Params]
  105. // or
  106. // Remote /P
  107. // This will loop continously prompting for different
  108. // Servers and Pipename
  109. if ((argc<2)||((argv[1][0]!='/')&&(argv[1][0]!='-')))
  110. {
  111. DisplayServerHlp();
  112. DisplayClientHlp();
  113. return(1);
  114. }
  115. switch(argv[1][1])
  116. {
  117. case 'c':
  118. case 'C':
  119. //
  120. // Is Client End of Remote
  121. //
  122. if ((argc<4)||((argv[1][0]!='/')&&(argv[1][0]!='-')))
  123. {
  124. DisplayServerHlp();
  125. DisplayClientHlp();
  126. return(1);
  127. }
  128. ServerName=argv[2];
  129. PipeName=argv[3];
  130. FirstArg=4;
  131. RunType=REMOTE_CLIENT;
  132. break;
  133. case 'p':
  134. case 'P':
  135. //
  136. // Is Client End of Remote
  137. //
  138. bPromptForArgs=TRUE;
  139. RunType=REMOTE_CLIENT;
  140. FirstArg=2;
  141. break;
  142. case 's':
  143. case 'S':
  144. //
  145. // Is Server End of Remote
  146. //
  147. if ((argc<4)||((argv[1][0]!='/')&&(argv[1][0]!='-')))
  148. {
  149. DisplayServerHlp();
  150. DisplayClientHlp();
  151. return(1);
  152. }
  153. ChildCmd=argv[2];
  154. PipeName=argv[3];
  155. FirstArg=4;
  156. RunType=REMOTE_SERVER;
  157. break;
  158. default:
  159. DisplayServerHlp();
  160. DisplayClientHlp();
  161. return(1);
  162. }
  163. if (RunType==REMOTE_SERVER)
  164. {
  165. //
  166. // Base Name of Executable
  167. // For setting the title
  168. //
  169. TCHAR *tcmd=ChildCmd;
  170. while ((*tcmd!=' ') &&(*tcmd!=0)) tcmd++;
  171. while ((tcmd!=ChildCmd)&&(*tcmd!='\\'))tcmd--;
  172. _stprintf( szTitle, TEXT("%-8.8s [WSRemote /C %s %s]"), tcmd, HostName, PipeName);
  173. }
  174. //
  175. //Process Common (Optional) Parameters
  176. //
  177. for (i=FirstArg;i<argc;i++)
  178. {
  179. if ((argv[i][0]!='/')&&(argv[i][0]!='-'))
  180. {
  181. _tprintf( TEXT("Invalid parameter %s:Ignoring\n"),argv[i]);
  182. continue;
  183. }
  184. switch(argv[i][1])
  185. {
  186. case 'u': // Only Valid for Server End
  187. case 'U': // Username To Use to Connect to Session
  188. i++;
  189. if (i>=argc)
  190. {
  191. _tprintf( TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
  192. break;
  193. }
  194. Username=(argv[i]);
  195. break;
  196. case 'p': // Only Valid for Server End
  197. case 'P': // Password To Use to Connect to Session
  198. i++;
  199. if (i>=argc)
  200. {
  201. _tprintf( TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
  202. break;
  203. }
  204. Password=(argv[i]);
  205. break;
  206. case 'l': // Only Valid for client End
  207. case 'L': // Max Number of Lines to recieve from Server
  208. i++;
  209. if (i>=argc)
  210. {
  211. _tprintf(TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
  212. break;
  213. }
  214. LinesToSend=(DWORD)_ttoi(argv[i])+1;
  215. break;
  216. case 't': // Title to be set instead of the default
  217. case 'T':
  218. i++;
  219. if (i>=argc)
  220. {
  221. _tprintf(TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
  222. break;
  223. }
  224. _stprintf( szTitle, TEXT("%s"),argv[i]);
  225. break;
  226. case 'b': // Background color
  227. case 'B':
  228. i++;
  229. if (i>=argc)
  230. {
  231. _tprintf(TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
  232. break;
  233. }
  234. {
  235. WORD col=GetColorNum(argv[i]);
  236. if (col!=0xffff)
  237. {
  238. bSetAttrib=TRUE;
  239. wAttrib=col<<4|(wAttrib&0x000f);
  240. }
  241. break;
  242. }
  243. case 'f': // Foreground color
  244. case 'F':
  245. i++;
  246. if (i>=argc)
  247. {
  248. _tprintf(TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
  249. break;
  250. }
  251. {
  252. WORD col=GetColorNum(argv[i]);
  253. if (col!=0xffff)
  254. {
  255. bSetAttrib=TRUE;
  256. wAttrib=col|(wAttrib&0x00f0);
  257. }
  258. break;
  259. }
  260. case 'q':
  261. case 'Q':
  262. IsAdvertise=FALSE;
  263. ClientToServerFlag|=0x80000000;
  264. break;
  265. case 'n':
  266. case 'N':
  267. bIPSession=FALSE;
  268. break;
  269. case 'i':
  270. case 'I':
  271. bIPLocked=TRUE;
  272. break;
  273. default:
  274. _tprintf(TEXT("Unknown Parameter=%s %s\n"),argv[i-1],argv[i]);
  275. break;
  276. }
  277. }
  278. //
  279. //Now Set various Parameters
  280. //
  281. //
  282. //Colors
  283. //
  284. SetColor(wAttrib);
  285. if (RunType==REMOTE_CLIENT)
  286. {
  287. BOOL done=FALSE;
  288. //
  289. // Set Client end defaults and start client
  290. //
  291. while(!done)
  292. {
  293. if (!bPromptForArgs ||
  294. GetNextConnectInfo(&ServerName,&PipeName)
  295. )
  296. {
  297. _stprintf( szTitle, TEXT("WSRemote /C %s %s"),ServerName,PipeName);
  298. SetConsoleTitle(szTitle);
  299. if (!bIPSession)
  300. {
  301. //
  302. // Start Client (Client.C)
  303. //
  304. Client(ServerName,PipeName);
  305. }
  306. else
  307. {
  308. SockClient(ServerName,PipeName);
  309. }
  310. }
  311. done=!bPromptForArgs;
  312. }
  313. }
  314. if (RunType==REMOTE_SERVER)
  315. {
  316. SetConsoleTitle(szTitle);
  317. //
  318. // Start Server (Server.C)
  319. //
  320. Server(ChildCmd,PipeName);
  321. }
  322. //
  323. //Reset Colors
  324. //
  325. SetColor(csbiOriginal.wAttributes);
  326. if (orgTitle[0]) {
  327. SetConsoleTitle(orgTitle);
  328. }
  329. ExitProcess(0);
  330. return( 1 );
  331. }
  332. /*************************************************************/
  333. VOID
  334. ErrorExit(
  335. TCHAR* str
  336. )
  337. {
  338. _tprintf(TEXT("Error-%d:%s\n"),GetLastError(),str);
  339. ExitProcess(1);
  340. }
  341. /*************************************************************/
  342. DWORD
  343. ReadFixBytes(
  344. HANDLE hRead,
  345. TCHAR* Buffer,
  346. DWORD ToRead,
  347. DWORD TimeOut //ignore for timebeing
  348. )
  349. {
  350. DWORD xyzBytesRead=0;
  351. DWORD xyzBytesToRead=ToRead;
  352. TCHAR* xyzbuff=Buffer;
  353. while(xyzBytesToRead!=0)
  354. {
  355. if (!ReadFile(hRead,xyzbuff,xyzBytesToRead,&xyzBytesRead,NULL))
  356. {
  357. return(xyzBytesToRead);
  358. }
  359. xyzBytesToRead-=xyzBytesRead;
  360. xyzbuff+=xyzBytesRead;
  361. }
  362. return(0);
  363. }
  364. /*************************************************************/
  365. /*************************************************************/
  366. DWORD
  367. SockReadFixBytes(
  368. SOCKET hSocket,
  369. TCHAR* Buffer,
  370. DWORD ToRead,
  371. DWORD TimeOut //ignore for timebeing
  372. )
  373. {
  374. DWORD xyzBytesRead=0;
  375. DWORD xyzBytesToRead=ToRead;
  376. TCHAR* xyzbuff=Buffer;
  377. while(xyzBytesToRead!=0)
  378. {
  379. if (!ReadSocket(hSocket,xyzbuff,xyzBytesToRead,&xyzBytesRead))
  380. {
  381. return(xyzBytesToRead);
  382. }
  383. xyzBytesToRead-=xyzBytesRead;
  384. xyzbuff+=xyzBytesRead;
  385. }
  386. return(0);
  387. }
  388. /*************************************************************/
  389. VOID
  390. DisplayClientHlp()
  391. {
  392. _tprintf(TEXT("\n To Start the CLIENT end of WSREMOTE\n"));
  393. _tprintf(TEXT(" ---------------------------------\n"));
  394. _tprintf(TEXT(" Syntax : WSREMOTE /C <ServerName> <Unique Id> [Param]\n"));
  395. _tprintf(TEXT(" Example: WSREMOTE /C iisdebug 70\n"));
  396. _tprintf(TEXT(" This would connect to a server session on \n"));
  397. _tprintf(TEXT(" iisdebug with id \"70\" if there was a\n"));
  398. _tprintf(TEXT(" WSREMOTE /S <\"Cmd\"> 70\n"));
  399. _tprintf(TEXT(" started on the machine iisdebug.\n\n"));
  400. _tprintf(TEXT(" To Exit: %cQ (Leaves the Remote Server Running)\n"),COMMANDCHAR);
  401. _tprintf(TEXT(" [Param]: /L <# of Lines to Get>\n"));
  402. _tprintf(TEXT(" [Param]: /F <Foreground color eg blue, lred..>\n"));
  403. _tprintf(TEXT(" [Param]: /B <Background color eg cyan, lwhite..>\n"));
  404. _tprintf(TEXT(" [Param]: /N (Connect over Named Pipes)\n"));
  405. _tprintf(TEXT(" [Param]: /U <Username> (Username to connect)\n"));
  406. _tprintf(TEXT(" [Param]: /P <Password> (Password to connect)\n"));
  407. _tprintf(TEXT("\n"));
  408. }
  409. /*************************************************************/
  410. VOID
  411. DisplayServerHlp()
  412. {
  413. #define WRITEF2(VArgs) { \
  414. HANDLE xh=GetStdHandle(STD_OUTPUT_HANDLE); \
  415. TCHAR VBuff[256]; \
  416. DWORD tmp; \
  417. _stprintf VArgs; \
  418. WriteFile(xh,VBuff,lstrlen(VBuff),&tmp,NULL); \
  419. } \
  420. _tprintf(TEXT("\n To Start the SERVER end of WSREMOTE\n"));
  421. _tprintf(TEXT(" ---------------------------------\n"));
  422. _tprintf(TEXT(" Syntax : WSREMOTE /S <\"Cmd\"> <Unique Id or Port Number> [Param]\n"));
  423. _tprintf(TEXT(" Syntax : WSREMOTE /S <\"Cmd\"> <Unique Id or Port Number> [Param]\n"));
  424. _tprintf(TEXT(" Example: WSREMOTE /S \"cmd.exe\" inetinfo\n"));
  425. _tprintf(TEXT(" To interact with this \"Cmd\" \n"));
  426. _tprintf(TEXT(" from some other machine\n"));
  427. _tprintf(TEXT(" - start the client end by:\n"));
  428. _tprintf(TEXT(" REMOTE /C %s PortNum\n\n"),HostName);
  429. _tprintf(TEXT(" To Exit: %cK \n"),COMMANDCHAR);
  430. _tprintf(TEXT(" [Param]: /F <Foreground color eg yellow, black..>\n"));
  431. _tprintf(TEXT(" [Param]: /B <Background color eg lblue, white..>\n"));
  432. _tprintf(TEXT(" [Param]: /I (Turns ON IP Blocking)\n"));
  433. _tprintf(TEXT(" [Param]: /U <Username> (Username to connect)\n"));
  434. _tprintf(TEXT(" [Param]: /P <Password> (Password to connect)\n"));
  435. _tprintf(TEXT("\n"));
  436. }
  437. WORD
  438. GetColorNum(
  439. TCHAR *color
  440. )
  441. {
  442. WORD wIndex;
  443. _tcslwr(color);
  444. for (wIndex=0;wIndex<16;wIndex++)
  445. {
  446. if (_tcscmp(ColorList[wIndex],color)==0)
  447. {
  448. return(wIndex);
  449. }
  450. }
  451. return ((WORD)_ttoi(color));
  452. }
  453. VOID
  454. SetColor(
  455. WORD attr
  456. )
  457. {
  458. COORD origin={0,0};
  459. DWORD dwrite;
  460. FillConsoleOutputAttribute
  461. (
  462. MyOutHandle,attr,csbiOriginal.dwSize.
  463. X*csbiOriginal.dwSize.Y,origin,&dwrite
  464. );
  465. SetConsoleTextAttribute(MyOutHandle,attr);
  466. }
  467. BOOL
  468. GetNextConnectInfo(
  469. TCHAR** SrvName,
  470. TCHAR** PipeName
  471. )
  472. {
  473. static TCHAR szServerName[64];
  474. static TCHAR szPipeName[32];
  475. TCHAR *s;
  476. int StringLen;
  477. __try
  478. {
  479. ZeroMemory(szServerName,64);
  480. ZeroMemory(szPipeName,32);
  481. SetConsoleTitle( TEXT("Remote - Prompting for next Connection"));
  482. _tprintf(TEXT("Debugger machine (server): "));
  483. fflush(stdout);
  484. if (!fgets(szServerName, sizeof(szServerName), stdin)) {
  485. return FALSE;
  486. }
  487. StringLen = strlen(szServerName);
  488. if (!StringLen || (!feof(stdin) && szServerName[StringLen-1] != '\n')) {
  489. return FALSE;
  490. }
  491. if (szServerName[StringLen-1] == '\n') {
  492. if (StringLen == 1) {
  493. return (FALSE);
  494. }
  495. szServerName[StringLen-1] = '\0';
  496. }
  497. if (szServerName[0] == COMMANDCHAR &&
  498. (szServerName[1] == 'q' || szServerName[1] == 'Q')
  499. )
  500. {
  501. return(FALSE);
  502. }
  503. if (s = _tcschr( szServerName, ' ' )) {
  504. *s++ = '\0';
  505. while (*s == ' ') {
  506. s += 1;
  507. }
  508. *PipeName=_tcscpy(szPipeName, s);
  509. _tprintf(szPipeName);
  510. fflush(stdout);
  511. }
  512. if (_tcslen(szPipeName) == 0) {
  513. _tprintf(TEXT("Debuggee machine : "));
  514. fflush(stdout);
  515. if (!fgets(szPipeName, sizeof(szPipeName), stdin)) {
  516. return FALSE;
  517. }
  518. StringLen = strlen(szPipeName);
  519. if (!StringLen || (!feof(stdin) && szPipeName[StringLen-1] != '\n')) {
  520. return FALSE;
  521. }
  522. if (szPipeName[StringLen-1] == '\n') {
  523. szPipeName[StringLen-1] = '\0';
  524. }
  525. }
  526. if (s = _tcschr(szPipeName, ' ')) {
  527. *s++ = '\0';
  528. }
  529. if (szPipeName[0] == COMMANDCHAR &&
  530. (szPipeName[1] == 'q' || szPipeName[1] == 'Q')
  531. )
  532. {
  533. return(FALSE);
  534. }
  535. _tprintf(TEXT("\n\n"));
  536. }
  537. __except(EXCEPTION_EXECUTE_HANDLER)
  538. {
  539. return(FALSE); // Ignore exceptions
  540. }
  541. return(TRUE);
  542. }
  543. /*************************************************************/
  544. VOID
  545. Errormsg(
  546. TCHAR* str
  547. )
  548. {
  549. _tprintf(TEXT("Error (%d) - %s\n"),GetLastError(),str);
  550. }
  551. /*************************************************************/
  552. BOOL ReadSocket(SOCKET s,TCHAR * buff,int len,DWORD* dread)
  553. {
  554. BOOL bRet = FALSE;
  555. DWORD numread;
  556. #ifdef UNICODE
  557. char * pszAnsiStr = (char *)calloc( (len + 1), sizeof(char) );
  558. if (pszAnsiStr)
  559. {
  560. int nErr;
  561. numread = (DWORD)recv( s, pszAnsiStr, len, 0);
  562. if (SOCKET_ERROR != numread)
  563. {
  564. nErr = MultiByteToWideChar( CP_ACP,
  565. MB_PRECOMPOSED,
  566. pszAnsiStr,
  567. len,
  568. buff,
  569. len );
  570. if (nErr)
  571. {
  572. *dread = numread;
  573. bRet = TRUE;
  574. }
  575. //Base64Decode(buff,DecodeBuffer);
  576. }
  577. free( pszAnsiStr );
  578. }
  579. #else
  580. numread = (DWORD)recv( s, buff, len, 0);
  581. if (SOCKET_ERROR != numread)
  582. {
  583. *dread = numread;
  584. bRet = TRUE;
  585. }
  586. #endif
  587. return bRet;
  588. }
  589. // returns TRUE if successful, false otherwise
  590. BOOL WriteSocket(
  591. SOCKET s,
  592. TCHAR * buff,
  593. int len,
  594. DWORD* dsent)
  595. {
  596. BOOL bRet = FALSE;
  597. DWORD numsent;
  598. #ifdef UNICODE
  599. int nStrLen = lstrlen( buff );
  600. if (nStrLen)
  601. {
  602. char * pszAnsiStr = (char *)malloc( nStrLen + 1 );
  603. if (pszAnsiStr)
  604. {
  605. int nErr = WideCharToMultiByte( CP_ACP,
  606. WC_COMPOSITECHECK,
  607. buff,
  608. nStrLen,
  609. pszAnsiStr,
  610. nStrLen,
  611. NULL,
  612. NULL );
  613. if (nErr)
  614. {
  615. numsent = (DWORD)send(s, pszAnsiStr, nStrLen, 0);
  616. if (SOCKET_ERROR != numsent)
  617. {
  618. *dsent = numsent;
  619. bRet = TRUE;
  620. }
  621. }
  622. //Base64Decode(buff,DecodeBuffer);
  623. free( pszAnsiStr );
  624. }
  625. }
  626. #else
  627. numsent = (DWORD)send(s, buff, len, 0);
  628. if (SOCKET_ERROR != numsent)
  629. {
  630. *dsent = numsent;
  631. bRet = TRUE;
  632. }
  633. #endif
  634. return bRet;
  635. }
  636. #ifdef UNICODE
  637. // returns TRUE if successful, false otherwise
  638. BOOL WriteSocketA(
  639. SOCKET s,
  640. char * pszAnsiStr,
  641. int len,
  642. DWORD * dsent)
  643. {
  644. BOOL bRet = FALSE;
  645. DWORD numsent;
  646. numsent = (DWORD)send(s, pszAnsiStr, len, 0);
  647. if (SOCKET_ERROR != numsent)
  648. {
  649. *dsent = numsent;
  650. bRet = TRUE;
  651. }
  652. //Base64Decode(buff,DecodeBuffer);
  653. return bRet;
  654. }
  655. #endif
  656. ////////////////////////////////////////////////
  657. unsigned char Base64Table[64] =
  658. {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'};
  659. VOID
  660. Base64Encode(
  661. TCHAR * String,
  662. DWORD StringLength,
  663. TCHAR * EncodeBuffer)
  664. {
  665. DWORD EncodeDword;
  666. int Index;
  667. memset(EncodeBuffer, 0, 2 * StringLength);
  668. Index = 0;
  669. while (StringLength >= 3) {
  670. //
  671. // Encode a three byte chunk
  672. //
  673. EncodeDword = (String[0] << 16) & 0xff0000;
  674. EncodeDword += (String[1] << 8) & 0xff00;
  675. EncodeDword += String[2] & 0xff;
  676. EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 18) & 63];
  677. EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 12) & 63];
  678. EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 6) & 63];
  679. EncodeBuffer[Index++] = Base64Table[EncodeDword & 63];
  680. String += 3;
  681. StringLength -= 3;
  682. }
  683. switch (StringLength) {
  684. case 1:
  685. EncodeDword = (String[0] << 16) & 0xff0000;
  686. EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 18) & 63];
  687. EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 12) & 63];
  688. EncodeBuffer[Index++] = '=';
  689. EncodeBuffer[Index++] = '=';
  690. break;
  691. case 2:
  692. EncodeDword = (String[0] << 16) & 0xff0000;
  693. EncodeDword += (String[1] << 8) & 0xff00;
  694. EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 18) & 63];
  695. EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 12) & 63];
  696. EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 6) & 63];
  697. EncodeBuffer[Index++] = '=';
  698. break;
  699. }
  700. EncodeBuffer[Index] = 0;
  701. return;
  702. }
  703. int
  704. GetBase64Index(
  705. TCHAR A)
  706. {
  707. int i;
  708. for (i=0; i<64; i++) {
  709. if (Base64Table[i] == A) {
  710. return i;
  711. }
  712. }
  713. return -1;
  714. }
  715. VOID
  716. Base64Decode(
  717. TCHAR * String,
  718. TCHAR * DecodeBuffer)
  719. {
  720. DWORD DecodeDword;
  721. int Index = 0;
  722. memset(DecodeBuffer, 0, _tcslen(String));
  723. if (_tcslen(String) % 4) {
  724. printf("WCAT INTERNAL ERROR %s %d\n", __FILE__, __LINE__);
  725. return;
  726. }
  727. while (*String) {
  728. //
  729. // Decode a four byte chunk
  730. //
  731. if (GetBase64Index(String[0]) < 0) {
  732. //
  733. // Invalid string
  734. //
  735. printf("WCAT INTERNAL ERROR %s %d\n", __FILE__, __LINE__);
  736. return;
  737. }
  738. DecodeDword = ((unsigned int) GetBase64Index(String[0])) << 18;
  739. if (GetBase64Index(String[1]) >= 0) {
  740. //
  741. // still more characters
  742. //
  743. DecodeDword += ((unsigned int) GetBase64Index(String[1])) << 12;
  744. if (GetBase64Index(String[2]) >= 0) {
  745. //
  746. // still more characters
  747. //
  748. DecodeDword += ((unsigned int) GetBase64Index(String[2])) << 6;
  749. if (GetBase64Index(String[3]) >= 0) {
  750. //
  751. // still more characters
  752. //
  753. DecodeDword += (unsigned int) GetBase64Index(String[3]);
  754. DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 16) & 0xff);
  755. DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 8) & 0xff);
  756. DecodeBuffer[Index++] = (unsigned char) (DecodeDword & 0xff);
  757. } else {
  758. DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 16) & 0xff);
  759. DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 8) & 0xff);
  760. }
  761. } else {
  762. DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 16) & 0xff);
  763. }
  764. }
  765. String += 4;
  766. }
  767. return;
  768. }
  769. VOID
  770. SplitUserName(
  771. TCHAR * FullName,
  772. TCHAR * Domain,
  773. TCHAR * UserName)
  774. {
  775. TCHAR * Slash;
  776. Slash = _tcsstr(FullName, TEXT(":"));
  777. if (Slash) {
  778. // there is a domain name
  779. *Slash = 0;
  780. _tcscpy(Domain, FullName);
  781. _tcscpy(UserName, Slash+1);
  782. *Slash = ':';
  783. } else {
  784. *Domain = 0;
  785. _tcscpy(UserName, FullName);
  786. }
  787. }
  788. #ifdef UNICODE
  789. // caller must free buffer
  790. WCHAR * inet_ntoaw(
  791. struct in_addr stInet
  792. )
  793. {
  794. char * pszAnsiInetStr = inet_ntoa( stInet );
  795. int nStrLen = strlen( pszAnsiInetStr );
  796. WCHAR * pszInetStr = (WCHAR *)calloc( (nStrLen + 1), sizeof( TCHAR ));
  797. int nErr = MultiByteToWideChar( CP_ACP,
  798. MB_PRECOMPOSED,
  799. pszAnsiInetStr,
  800. nStrLen,
  801. pszInetStr,
  802. nStrLen );
  803. if (!nErr)
  804. {
  805. free( pszInetStr );
  806. pszInetStr = NULL;
  807. }
  808. return pszInetStr;
  809. }
  810. BOOL ReadFileW(
  811. HANDLE hFile, // handle of file to read
  812. WCHAR * pszBuffer, // pointer to buffer that receives data
  813. DWORD dwLength, // number of bytes to read
  814. LPDWORD pdwRead, // pointer to number of bytes read
  815. LPOVERLAPPED pData // pointer to structure for data
  816. )
  817. {
  818. BOOL bRet = FALSE;
  819. char * pszAnsi = (char *)calloc( dwLength + 1, sizeof(char *));
  820. if (pszAnsi)
  821. {
  822. bRet = ReadFile( hFile,
  823. pszAnsi,
  824. dwLength,
  825. pdwRead,
  826. pData);
  827. if (bRet)
  828. {
  829. int nErr = MultiByteToWideChar( CP_ACP,
  830. MB_PRECOMPOSED,
  831. pszAnsi,
  832. *pdwRead,
  833. pszBuffer,
  834. *pdwRead );
  835. if (!nErr)
  836. {
  837. bRet = FALSE;
  838. }
  839. }
  840. free( pszAnsi );
  841. }
  842. return bRet;
  843. }
  844. BOOL WriteFileW(
  845. HANDLE hFile, // handle to file to write to
  846. WCHAR * pszBuffer, // pointer to data to write to file
  847. DWORD dwWrite, // number of bytes to write
  848. LPDWORD pdwWritten, // pointer to number of bytes written
  849. LPOVERLAPPED pData // pointer to structure for overlapped I/O
  850. )
  851. {
  852. BOOL bRet = FALSE;
  853. int nStrLen = lstrlen( pszBuffer );
  854. if (nStrLen)
  855. {
  856. char * pszAnsiStr = (char *)malloc( nStrLen + 1 );
  857. if (pszAnsiStr)
  858. {
  859. int nErr = WideCharToMultiByte( CP_ACP,
  860. WC_COMPOSITECHECK,
  861. pszBuffer,
  862. nStrLen,
  863. pszAnsiStr,
  864. nStrLen,
  865. NULL,
  866. NULL );
  867. if (nErr)
  868. {
  869. bRet = WriteFile( hFile,
  870. pszAnsiStr,
  871. dwWrite,
  872. pdwWritten,
  873. pData);
  874. }
  875. free( pszAnsiStr );
  876. }
  877. }
  878. return bRet;
  879. }
  880. // caller most free buffer
  881. BOOL GetAnsiStr(
  882. WCHAR * pszWideStr,
  883. char * pszAnsiStr,
  884. UINT uBufSize
  885. )
  886. {
  887. BOOL bRet = FALSE;
  888. if (pszWideStr && pszAnsiStr)
  889. {
  890. int nStrLen = lstrlen( pszWideStr );
  891. if (nStrLen)
  892. {
  893. int nErr = WideCharToMultiByte( CP_ACP,
  894. WC_COMPOSITECHECK,
  895. pszWideStr,
  896. nStrLen,
  897. pszAnsiStr,
  898. uBufSize - 1,
  899. NULL,
  900. NULL );
  901. if (nErr)
  902. {
  903. pszAnsiStr[nStrLen] = '\0';
  904. bRet = TRUE;
  905. }
  906. }
  907. }
  908. return bRet;
  909. }
  910. #endif