Source code of Windows XP (NT5)
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.

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