1065 lines
26 KiB
C
1065 lines
26 KiB
C
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1993 - 1999
|
|
|
|
Module Name:
|
|
|
|
Remote.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the main() entry point for Remote.
|
|
Calls the Server or the Client depending on the first parameter.
|
|
|
|
|
|
Author:
|
|
|
|
Rajivendra Nath (rajnath) 2-Jan-1993
|
|
|
|
Environment:
|
|
|
|
Console App. User mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "Remote.h"
|
|
|
|
TCHAR HostName[HOSTNAMELEN];
|
|
TCHAR * ChildCmd;
|
|
TCHAR* PipeName;
|
|
TCHAR* ServerName;
|
|
TCHAR* Username;
|
|
TCHAR* Password;
|
|
HANDLE MyOutHandle;
|
|
BOOL bIPLocked=FALSE;
|
|
|
|
BOOL IsAdvertise=TRUE;
|
|
DWORD ClientToServerFlag;
|
|
|
|
TCHAR* ColorList[]={
|
|
TEXT("black"),
|
|
TEXT("blue"),
|
|
TEXT("green"),
|
|
TEXT("cyan"),
|
|
TEXT("red"),
|
|
TEXT("purple"),
|
|
TEXT("yellow"),
|
|
TEXT("white"),
|
|
TEXT("lblack"),
|
|
TEXT("lblue"),
|
|
TEXT("lgreen"),
|
|
TEXT("lcyan"),
|
|
TEXT("lred"),
|
|
TEXT("lpurple"),
|
|
TEXT("lyellow"),
|
|
TEXT("lwhite")
|
|
};
|
|
|
|
WORD
|
|
GetColorNum(
|
|
TCHAR* color
|
|
);
|
|
|
|
VOID
|
|
SetColor(
|
|
WORD attr
|
|
);
|
|
|
|
BOOL
|
|
GetNextConnectInfo(
|
|
TCHAR** SrvName,
|
|
TCHAR** PipeName
|
|
);
|
|
|
|
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO csbiOriginal;
|
|
|
|
int _cdecl _tmain(int argc, TCHAR *argv[])
|
|
{
|
|
WORD RunType; // Server or Client end of Remote
|
|
DWORD len=HOSTNAMELEN-1;
|
|
int i, FirstArg;
|
|
|
|
BOOL bSetAttrib=FALSE; // Change Console Attributes
|
|
BOOL bPromptForArgs=FALSE; // Is /P option
|
|
BOOL bIPSession=TRUE; // Is /N for Named Pipes
|
|
TCHAR szTitle[100]; // New Title
|
|
TCHAR szOrgTitle[100]; // Old Title
|
|
WORD wAttrib; // Console Attributes
|
|
|
|
GetComputerName((LPTSTR)HostName,&len);
|
|
|
|
MyOutHandle=GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
GetConsoleScreenBufferInfo(MyOutHandle,&csbiOriginal);
|
|
|
|
//
|
|
// Parameter Processing
|
|
//
|
|
// For Server:
|
|
// Remote /S <Executable> <PipeName> [Optional Params]
|
|
//
|
|
// For Client:
|
|
// Remote /C <Server Name> <PipeName> [Optional Params]
|
|
// or
|
|
// Remote /P
|
|
// This will loop continously prompting for different
|
|
// Servers and Pipename
|
|
|
|
|
|
if ((argc<2)||((argv[1][0]!='/')&&(argv[1][0]!='-')))
|
|
{
|
|
|
|
DisplayServerHlp();
|
|
DisplayClientHlp();
|
|
return(1);
|
|
}
|
|
|
|
switch(argv[1][1])
|
|
{
|
|
|
|
case 'c':
|
|
case 'C':
|
|
|
|
//
|
|
// Is Client End of Remote
|
|
//
|
|
|
|
if ((argc<4)||((argv[1][0]!='/')&&(argv[1][0]!='-')))
|
|
{
|
|
|
|
DisplayServerHlp();
|
|
DisplayClientHlp();
|
|
return(1);
|
|
}
|
|
|
|
ServerName=argv[2];
|
|
PipeName=argv[3];
|
|
FirstArg=4;
|
|
RunType=REMOTE_CLIENT;
|
|
break;
|
|
|
|
|
|
case 'p':
|
|
case 'P':
|
|
|
|
//
|
|
// Is Client End of Remote
|
|
//
|
|
|
|
bPromptForArgs=TRUE;
|
|
RunType=REMOTE_CLIENT;
|
|
FirstArg=2;
|
|
break;
|
|
|
|
|
|
case 's':
|
|
case 'S':
|
|
//
|
|
// Is Server End of Remote
|
|
//
|
|
if ((argc<4)||((argv[1][0]!='/')&&(argv[1][0]!='-')))
|
|
{
|
|
|
|
DisplayServerHlp();
|
|
DisplayClientHlp();
|
|
return(1);
|
|
}
|
|
|
|
ChildCmd=argv[2];
|
|
PipeName=argv[3];
|
|
FirstArg=4;
|
|
|
|
RunType=REMOTE_SERVER;
|
|
break;
|
|
|
|
|
|
default:
|
|
DisplayServerHlp();
|
|
DisplayClientHlp();
|
|
return(1);
|
|
}
|
|
|
|
//
|
|
// Save Existing Values
|
|
//
|
|
|
|
//
|
|
//Colors /f <ForeGround> /b <BackGround>
|
|
//
|
|
|
|
wAttrib=csbiOriginal.wAttributes;
|
|
|
|
//
|
|
//Title /T Title
|
|
//
|
|
|
|
GetConsoleTitle( szOrgTitle, lstrlen( szOrgTitle) );
|
|
|
|
if (RunType==REMOTE_SERVER)
|
|
{
|
|
//
|
|
// Base Name of Executable
|
|
// For setting the title
|
|
//
|
|
|
|
TCHAR *tcmd=ChildCmd;
|
|
|
|
while ((*tcmd!=' ') &&(*tcmd!=0)) tcmd++;
|
|
while ((tcmd!=ChildCmd)&&(*tcmd!='\\'))tcmd--;
|
|
|
|
_stprintf( szTitle, TEXT("%-8.8s [WSRemote /C %s %s]"), tcmd, HostName, PipeName);
|
|
}
|
|
|
|
//
|
|
//Process Common (Optional) Parameters
|
|
//
|
|
|
|
for (i=FirstArg;i<argc;i++)
|
|
{
|
|
|
|
if ((argv[i][0]!='/')&&(argv[i][0]!='-'))
|
|
{
|
|
_tprintf( TEXT("Invalid parameter %s:Ignoring\n"),argv[i]);
|
|
continue;
|
|
}
|
|
|
|
switch(argv[i][1])
|
|
{
|
|
case 'u': // Only Valid for Server End
|
|
case 'U': // Username To Use to Connect to Session
|
|
i++;
|
|
if (i>=argc)
|
|
{
|
|
_tprintf( TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
|
|
break;
|
|
}
|
|
Username=(argv[i]);
|
|
break;
|
|
|
|
case 'p': // Only Valid for Server End
|
|
case 'P': // Password To Use to Connect to Session
|
|
i++;
|
|
if (i>=argc)
|
|
{
|
|
_tprintf( TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
|
|
break;
|
|
}
|
|
Password=(argv[i]);
|
|
break;
|
|
|
|
case 'l': // Only Valid for client End
|
|
case 'L': // Max Number of Lines to recieve from Server
|
|
i++;
|
|
if (i>=argc)
|
|
{
|
|
_tprintf(TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
|
|
break;
|
|
}
|
|
LinesToSend=(DWORD)_ttoi(argv[i])+1;
|
|
break;
|
|
|
|
case 't': // Title to be set instead of the default
|
|
case 'T':
|
|
i++;
|
|
if (i>=argc)
|
|
{
|
|
_tprintf(TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
|
|
break;
|
|
}
|
|
_stprintf( szTitle, TEXT("%s"),argv[i]);
|
|
break;
|
|
|
|
case 'b': // Background color
|
|
case 'B':
|
|
i++;
|
|
if (i>=argc)
|
|
{
|
|
_tprintf(TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
|
|
break;
|
|
}
|
|
{
|
|
WORD col=GetColorNum(argv[i]);
|
|
if (col!=0xffff)
|
|
{
|
|
bSetAttrib=TRUE;
|
|
wAttrib=col<<4|(wAttrib&0x000f);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 'f': // Foreground color
|
|
case 'F':
|
|
i++;
|
|
if (i>=argc)
|
|
{
|
|
_tprintf(TEXT("Incomplete Param %s..Ignoring\n"),argv[i-1]);
|
|
break;
|
|
}
|
|
{
|
|
WORD col=GetColorNum(argv[i]);
|
|
if (col!=0xffff)
|
|
{
|
|
bSetAttrib=TRUE;
|
|
wAttrib=col|(wAttrib&0x00f0);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 'q':
|
|
case 'Q':
|
|
IsAdvertise=FALSE;
|
|
ClientToServerFlag|=0x80000000;
|
|
break;
|
|
|
|
case 'n':
|
|
case 'N':
|
|
bIPSession=FALSE;
|
|
break;
|
|
|
|
case 'i':
|
|
case 'I':
|
|
bIPLocked=TRUE;
|
|
break;
|
|
default:
|
|
_tprintf(TEXT("Unknown Parameter=%s %s\n"),argv[i-1],argv[i]);
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
//Now Set various Parameters
|
|
//
|
|
|
|
//
|
|
//Colors
|
|
//
|
|
|
|
SetColor(wAttrib);
|
|
|
|
if (RunType==REMOTE_CLIENT)
|
|
{
|
|
BOOL done=FALSE;
|
|
|
|
//
|
|
// Set Client end defaults and start client
|
|
//
|
|
|
|
|
|
|
|
while(!done)
|
|
{
|
|
if (!bPromptForArgs ||
|
|
GetNextConnectInfo(&ServerName,&PipeName)
|
|
)
|
|
{
|
|
_stprintf( szTitle, TEXT("WSRemote /C %s %s"),ServerName,PipeName);
|
|
SetConsoleTitle(szTitle);
|
|
|
|
|
|
if (!bIPSession)
|
|
{
|
|
//
|
|
// Start Client (Client.C)
|
|
//
|
|
Client(ServerName,PipeName);
|
|
}
|
|
else
|
|
{
|
|
SockClient(ServerName,PipeName);
|
|
}
|
|
}
|
|
done=!bPromptForArgs;
|
|
}
|
|
}
|
|
|
|
if (RunType==REMOTE_SERVER)
|
|
{
|
|
SetConsoleTitle(szTitle);
|
|
|
|
//
|
|
// Start Server (Server.C)
|
|
//
|
|
Server(ChildCmd,PipeName);
|
|
}
|
|
|
|
//
|
|
//Reset Colors
|
|
//
|
|
SetColor(csbiOriginal.wAttributes);
|
|
SetConsoleTitle(szOrgTitle);
|
|
|
|
ExitProcess(0);
|
|
return( 1 );
|
|
}
|
|
/*************************************************************/
|
|
VOID
|
|
ErrorExit(
|
|
TCHAR* str
|
|
)
|
|
{
|
|
_tprintf(TEXT("Error-%d:%s\n"),GetLastError(),str);
|
|
ExitProcess(1);
|
|
}
|
|
|
|
/*************************************************************/
|
|
DWORD
|
|
ReadFixBytes(
|
|
HANDLE hRead,
|
|
TCHAR* Buffer,
|
|
DWORD ToRead,
|
|
DWORD TimeOut //ignore for timebeing
|
|
)
|
|
{
|
|
DWORD xyzBytesRead=0;
|
|
DWORD xyzBytesToRead=ToRead;
|
|
TCHAR* xyzbuff=Buffer;
|
|
|
|
while(xyzBytesToRead!=0)
|
|
{
|
|
if (!ReadFile(hRead,xyzbuff,xyzBytesToRead,&xyzBytesRead,NULL))
|
|
{
|
|
return(xyzBytesToRead);
|
|
}
|
|
|
|
xyzBytesToRead-=xyzBytesRead;
|
|
xyzbuff+=xyzBytesRead;
|
|
}
|
|
return(0);
|
|
|
|
}
|
|
/*************************************************************/
|
|
|
|
/*************************************************************/
|
|
DWORD
|
|
SockReadFixBytes(
|
|
SOCKET hSocket,
|
|
TCHAR* Buffer,
|
|
DWORD ToRead,
|
|
DWORD TimeOut //ignore for timebeing
|
|
)
|
|
{
|
|
DWORD xyzBytesRead=0;
|
|
DWORD xyzBytesToRead=ToRead;
|
|
TCHAR* xyzbuff=Buffer;
|
|
|
|
while(xyzBytesToRead!=0)
|
|
{
|
|
if (!ReadSocket(hSocket,xyzbuff,xyzBytesToRead,&xyzBytesRead))
|
|
{
|
|
return(xyzBytesToRead);
|
|
}
|
|
|
|
xyzBytesToRead-=xyzBytesRead;
|
|
xyzbuff+=xyzBytesRead;
|
|
}
|
|
return(0);
|
|
|
|
}
|
|
/*************************************************************/
|
|
|
|
VOID
|
|
DisplayClientHlp()
|
|
{
|
|
_tprintf(TEXT("\n To Start the CLIENT end of WSREMOTE\n"));
|
|
_tprintf(TEXT(" ---------------------------------\n"));
|
|
_tprintf(TEXT(" Syntax : WSREMOTE /C <ServerName> <Unique Id> [Param]\n"));
|
|
_tprintf(TEXT(" Example: WSREMOTE /C iisdebug 70\n"));
|
|
_tprintf(TEXT(" This would connect to a server session on \n"));
|
|
_tprintf(TEXT(" iisdebug with id \"70\" if there was a\n"));
|
|
_tprintf(TEXT(" WSREMOTE /S <\"Cmd\"> 70\n"));
|
|
_tprintf(TEXT(" started on the machine iisdebug.\n\n"));
|
|
_tprintf(TEXT(" To Exit: %cQ (Leaves the Remote Server Running)\n"),COMMANDCHAR);
|
|
_tprintf(TEXT(" [Param]: /L <# of Lines to Get>\n"));
|
|
_tprintf(TEXT(" [Param]: /F <Foreground color eg blue, lred..>\n"));
|
|
_tprintf(TEXT(" [Param]: /B <Background color eg cyan, lwhite..>\n"));
|
|
_tprintf(TEXT(" [Param]: /N (Connect over Named Pipes)\n"));
|
|
_tprintf(TEXT(" [Param]: /U <Username> (Username to connect)\n"));
|
|
_tprintf(TEXT(" [Param]: /P <Password> (Password to connect)\n"));
|
|
_tprintf(TEXT("\n"));
|
|
}
|
|
/*************************************************************/
|
|
|
|
VOID
|
|
DisplayServerHlp()
|
|
{
|
|
|
|
#define WRITEF2(VArgs) { \
|
|
HANDLE xh=GetStdHandle(STD_OUTPUT_HANDLE); \
|
|
TCHAR VBuff[256]; \
|
|
DWORD tmp; \
|
|
_stprintf VArgs; \
|
|
WriteFile(xh,VBuff,lstrlen(VBuff),&tmp,NULL); \
|
|
} \
|
|
|
|
|
|
_tprintf(TEXT("\n To Start the SERVER end of WSREMOTE\n"));
|
|
_tprintf(TEXT(" ---------------------------------\n"));
|
|
_tprintf(TEXT(" Syntax : WSREMOTE /S <\"Cmd\"> <Unique Id or Port Number> [Param]\n"));
|
|
_tprintf(TEXT(" Syntax : WSREMOTE /S <\"Cmd\"> <Unique Id or Port Number> [Param]\n"));
|
|
_tprintf(TEXT(" Example: WSREMOTE /S \"cmd.exe\" inetinfo\n"));
|
|
_tprintf(TEXT(" To interact with this \"Cmd\" \n"));
|
|
_tprintf(TEXT(" from some other machine\n"));
|
|
_tprintf(TEXT(" - start the client end by:\n"));
|
|
_tprintf(TEXT(" REMOTE /C %s PortNum\n\n"),HostName);
|
|
_tprintf(TEXT(" To Exit: %cK \n"),COMMANDCHAR);
|
|
_tprintf(TEXT(" [Param]: /F <Foreground color eg yellow, black..>\n"));
|
|
_tprintf(TEXT(" [Param]: /B <Background color eg lblue, white..>\n"));
|
|
_tprintf(TEXT(" [Param]: /I (Turns ON IP Blocking)\n"));
|
|
_tprintf(TEXT(" [Param]: /U <Username> (Username to connect)\n"));
|
|
_tprintf(TEXT(" [Param]: /P <Password> (Password to connect)\n"));
|
|
_tprintf(TEXT("\n"));
|
|
|
|
}
|
|
|
|
WORD
|
|
GetColorNum(
|
|
TCHAR *color
|
|
)
|
|
{
|
|
WORD wIndex;
|
|
|
|
_tcslwr(color);
|
|
for (wIndex=0;wIndex<16;wIndex++)
|
|
{
|
|
if (_tcscmp(ColorList[wIndex],color)==0)
|
|
{
|
|
return(wIndex);
|
|
}
|
|
}
|
|
return ((WORD)_ttoi(color));
|
|
}
|
|
|
|
VOID
|
|
SetColor(
|
|
WORD attr
|
|
)
|
|
{
|
|
COORD origin={0,0};
|
|
DWORD dwrite;
|
|
FillConsoleOutputAttribute
|
|
(
|
|
MyOutHandle,attr,csbiOriginal.dwSize.
|
|
X*csbiOriginal.dwSize.Y,origin,&dwrite
|
|
);
|
|
SetConsoleTextAttribute(MyOutHandle,attr);
|
|
}
|
|
|
|
BOOL
|
|
GetNextConnectInfo(
|
|
TCHAR** SrvName,
|
|
TCHAR** PipeName
|
|
)
|
|
{
|
|
static TCHAR szServerName[64];
|
|
static TCHAR szPipeName[32];
|
|
TCHAR *s;
|
|
|
|
__try
|
|
{
|
|
ZeroMemory(szServerName,64);
|
|
ZeroMemory(szPipeName,32);
|
|
SetConsoleTitle( TEXT("Remote - Prompting for next Connection"));
|
|
_tprintf(TEXT("Debugger machine (server): "));
|
|
fflush(stdout);
|
|
|
|
if (((*SrvName=_getts(szServerName))==NULL)||
|
|
(_tcslen(szServerName)==0))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
if (szServerName[0] == COMMANDCHAR &&
|
|
(szServerName[1] == 'q' || szServerName[1] == 'Q')
|
|
)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
if (s = _tcschr( szServerName, ' ' )) {
|
|
*s++ = '\0';
|
|
while (*s == ' ') {
|
|
s += 1;
|
|
}
|
|
*PipeName=_tcscpy(szPipeName, s);
|
|
_tprintf(szPipeName);
|
|
fflush(stdout);
|
|
}
|
|
if (_tcslen(szPipeName) == 0) {
|
|
_tprintf(TEXT("Debuggee machine : "));
|
|
fflush(stdout);
|
|
if ((*PipeName=_getts(szPipeName))==NULL)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
if (s = _tcschr(szPipeName, ' ')) {
|
|
*s++ = '\0';
|
|
}
|
|
|
|
if (szPipeName[0] == COMMANDCHAR &&
|
|
(szPipeName[1] == 'q' || szPipeName[1] == 'Q')
|
|
)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
_tprintf(TEXT("\n\n"));
|
|
}
|
|
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
return(FALSE); // Ignore exceptions
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/*************************************************************/
|
|
VOID
|
|
Errormsg(
|
|
TCHAR* str
|
|
)
|
|
{
|
|
_tprintf(TEXT("Error (%d) - %s\n"),GetLastError(),str);
|
|
}
|
|
|
|
/*************************************************************/
|
|
|
|
BOOL ReadSocket(SOCKET s,TCHAR * buff,int len,DWORD* dread)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD numread;
|
|
|
|
#ifdef UNICODE
|
|
char * pszAnsiStr = (char *)calloc( (len + 1), sizeof(char) );
|
|
|
|
if (pszAnsiStr)
|
|
{
|
|
int nErr;
|
|
numread = (DWORD)recv( s, pszAnsiStr, len, 0);
|
|
|
|
if (SOCKET_ERROR != numread)
|
|
{
|
|
nErr = MultiByteToWideChar( CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
pszAnsiStr,
|
|
len,
|
|
buff,
|
|
len );
|
|
|
|
if (nErr)
|
|
{
|
|
*dread = numread;
|
|
bRet = TRUE;
|
|
}
|
|
|
|
//Base64Decode(buff,DecodeBuffer);
|
|
}
|
|
|
|
free( pszAnsiStr );
|
|
}
|
|
#else
|
|
numread = (DWORD)recv( s, buff, len, 0);
|
|
|
|
if (SOCKET_ERROR != numread)
|
|
{
|
|
*dread = numread;
|
|
bRet = TRUE;
|
|
}
|
|
|
|
#endif
|
|
return bRet;
|
|
}
|
|
|
|
// returns TRUE if successful, false otherwise
|
|
BOOL WriteSocket(
|
|
SOCKET s,
|
|
TCHAR * buff,
|
|
int len,
|
|
DWORD* dsent)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD numsent;
|
|
|
|
#ifdef UNICODE
|
|
|
|
int nStrLen = lstrlen( buff );
|
|
|
|
if (nStrLen)
|
|
{
|
|
char * pszAnsiStr = (char *)malloc( nStrLen + 1 );
|
|
|
|
if (pszAnsiStr)
|
|
{
|
|
int nErr = WideCharToMultiByte( CP_ACP,
|
|
WC_COMPOSITECHECK,
|
|
buff,
|
|
nStrLen,
|
|
pszAnsiStr,
|
|
nStrLen,
|
|
NULL,
|
|
NULL );
|
|
if (nErr)
|
|
{
|
|
numsent = (DWORD)send(s, pszAnsiStr, nStrLen, 0);
|
|
if (SOCKET_ERROR != numsent)
|
|
{
|
|
*dsent = numsent;
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
|
|
//Base64Decode(buff,DecodeBuffer);
|
|
free( pszAnsiStr );
|
|
}
|
|
}
|
|
#else
|
|
numsent = (DWORD)send(s, buff, len, 0);
|
|
if (SOCKET_ERROR != numsent)
|
|
{
|
|
*dsent = numsent;
|
|
bRet = TRUE;
|
|
}
|
|
|
|
#endif
|
|
return bRet;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
// returns TRUE if successful, false otherwise
|
|
BOOL WriteSocketA(
|
|
SOCKET s,
|
|
char * pszAnsiStr,
|
|
int len,
|
|
DWORD * dsent)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD numsent;
|
|
|
|
numsent = (DWORD)send(s, pszAnsiStr, len, 0);
|
|
|
|
if (SOCKET_ERROR != numsent)
|
|
{
|
|
*dsent = numsent;
|
|
bRet = TRUE;
|
|
}
|
|
|
|
//Base64Decode(buff,DecodeBuffer);
|
|
return bRet;
|
|
}
|
|
#endif
|
|
|
|
////////////////////////////////////////////////
|
|
unsigned char Base64Table[64] =
|
|
{'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','+','/'};
|
|
|
|
VOID
|
|
Base64Encode(
|
|
TCHAR * String,
|
|
DWORD StringLength,
|
|
TCHAR * EncodeBuffer)
|
|
{
|
|
DWORD EncodeDword;
|
|
int Index;
|
|
|
|
memset(EncodeBuffer, 0, 2 * StringLength);
|
|
|
|
Index = 0;
|
|
|
|
while (StringLength >= 3) {
|
|
//
|
|
// Encode a three byte chunk
|
|
//
|
|
|
|
EncodeDword = (String[0] << 16) & 0xff0000;
|
|
|
|
EncodeDword += (String[1] << 8) & 0xff00;
|
|
|
|
EncodeDword += String[2] & 0xff;
|
|
|
|
EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 18) & 63];
|
|
EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 12) & 63];
|
|
EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 6) & 63];
|
|
EncodeBuffer[Index++] = Base64Table[EncodeDword & 63];
|
|
|
|
String += 3;
|
|
StringLength -= 3;
|
|
}
|
|
|
|
switch (StringLength) {
|
|
case 1:
|
|
EncodeDword = (String[0] << 16) & 0xff0000;
|
|
EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 18) & 63];
|
|
EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 12) & 63];
|
|
EncodeBuffer[Index++] = '=';
|
|
EncodeBuffer[Index++] = '=';
|
|
break;
|
|
case 2:
|
|
EncodeDword = (String[0] << 16) & 0xff0000;
|
|
EncodeDword += (String[1] << 8) & 0xff00;
|
|
|
|
EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 18) & 63];
|
|
EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 12) & 63];
|
|
EncodeBuffer[Index++] = Base64Table[(EncodeDword >> 6) & 63];
|
|
EncodeBuffer[Index++] = '=';
|
|
break;
|
|
}
|
|
|
|
EncodeBuffer[Index] = 0;
|
|
|
|
return;
|
|
}
|
|
int
|
|
GetBase64Index(
|
|
TCHAR A)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i<64; i++) {
|
|
if (Base64Table[i] == A) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
VOID
|
|
Base64Decode(
|
|
TCHAR * String,
|
|
TCHAR * DecodeBuffer)
|
|
{
|
|
DWORD DecodeDword;
|
|
int Index = 0;
|
|
|
|
memset(DecodeBuffer, 0, _tcslen(String));
|
|
|
|
if (_tcslen(String) % 4) {
|
|
printf("WCAT INTERNAL ERROR %s %d\n", __FILE__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
while (*String) {
|
|
//
|
|
// Decode a four byte chunk
|
|
//
|
|
|
|
if (GetBase64Index(String[0]) < 0) {
|
|
//
|
|
// Invalid string
|
|
//
|
|
|
|
printf("WCAT INTERNAL ERROR %s %d\n", __FILE__, __LINE__);
|
|
return;
|
|
}
|
|
|
|
DecodeDword = ((unsigned int) GetBase64Index(String[0])) << 18;
|
|
|
|
if (GetBase64Index(String[1]) >= 0) {
|
|
//
|
|
// still more characters
|
|
//
|
|
|
|
DecodeDword += ((unsigned int) GetBase64Index(String[1])) << 12;
|
|
if (GetBase64Index(String[2]) >= 0) {
|
|
//
|
|
// still more characters
|
|
//
|
|
|
|
DecodeDword += ((unsigned int) GetBase64Index(String[2])) << 6;
|
|
if (GetBase64Index(String[3]) >= 0) {
|
|
//
|
|
// still more characters
|
|
//
|
|
|
|
DecodeDword += (unsigned int) GetBase64Index(String[3]);
|
|
DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 16) & 0xff);
|
|
DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 8) & 0xff);
|
|
DecodeBuffer[Index++] = (unsigned char) (DecodeDword & 0xff);
|
|
} else {
|
|
DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 16) & 0xff);
|
|
DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 8) & 0xff);
|
|
}
|
|
} else {
|
|
DecodeBuffer[Index++] = (unsigned char) ((DecodeDword >> 16) & 0xff);
|
|
}
|
|
}
|
|
|
|
String += 4;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
SplitUserName(
|
|
TCHAR * FullName,
|
|
TCHAR * Domain,
|
|
TCHAR * UserName)
|
|
{
|
|
TCHAR * Slash;
|
|
Slash = _tcsstr(FullName, TEXT(":"));
|
|
|
|
if (Slash) {
|
|
// there is a domain name
|
|
|
|
*Slash = 0;
|
|
_tcscpy(Domain, FullName);
|
|
_tcscpy(UserName, Slash+1);
|
|
*Slash = ':';
|
|
} else {
|
|
*Domain = 0;
|
|
_tcscpy(UserName, FullName);
|
|
}
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
|
|
// caller must free buffer
|
|
WCHAR * inet_ntoaw(
|
|
struct in_addr stInet
|
|
)
|
|
{
|
|
char * pszAnsiInetStr = inet_ntoa( stInet );
|
|
|
|
int nStrLen = strlen( pszAnsiInetStr );
|
|
|
|
WCHAR * pszInetStr = (WCHAR *)calloc( (nStrLen + 1), sizeof( TCHAR ));
|
|
|
|
int nErr = MultiByteToWideChar( CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
pszAnsiInetStr,
|
|
nStrLen,
|
|
pszInetStr,
|
|
nStrLen );
|
|
|
|
if (!nErr)
|
|
{
|
|
free( pszInetStr );
|
|
pszInetStr = NULL;
|
|
}
|
|
|
|
return pszInetStr;
|
|
}
|
|
|
|
BOOL ReadFileW(
|
|
HANDLE hFile, // handle of file to read
|
|
WCHAR * pszBuffer, // pointer to buffer that receives data
|
|
DWORD dwLength, // number of bytes to read
|
|
LPDWORD pdwRead, // pointer to number of bytes read
|
|
LPOVERLAPPED pData // pointer to structure for data
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
char * pszAnsi = (char *)calloc( dwLength + 1, sizeof(char *));
|
|
|
|
if (pszAnsi)
|
|
{
|
|
bRet = ReadFile( hFile,
|
|
pszAnsi,
|
|
dwLength,
|
|
pdwRead,
|
|
pData);
|
|
|
|
if (bRet)
|
|
{
|
|
int nErr = MultiByteToWideChar( CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
pszAnsi,
|
|
*pdwRead,
|
|
pszBuffer,
|
|
*pdwRead );
|
|
|
|
if (!nErr)
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
free( pszAnsi );
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL WriteFileW(
|
|
HANDLE hFile, // handle to file to write to
|
|
WCHAR * pszBuffer, // pointer to data to write to file
|
|
DWORD dwWrite, // number of bytes to write
|
|
LPDWORD pdwWritten, // pointer to number of bytes written
|
|
LPOVERLAPPED pData // pointer to structure for overlapped I/O
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
int nStrLen = lstrlen( pszBuffer );
|
|
|
|
if (nStrLen)
|
|
{
|
|
char * pszAnsiStr = (char *)malloc( nStrLen + 1 );
|
|
|
|
if (pszAnsiStr)
|
|
{
|
|
int nErr = WideCharToMultiByte( CP_ACP,
|
|
WC_COMPOSITECHECK,
|
|
pszBuffer,
|
|
nStrLen,
|
|
pszAnsiStr,
|
|
nStrLen,
|
|
NULL,
|
|
NULL );
|
|
if (nErr)
|
|
{
|
|
bRet = WriteFile( hFile,
|
|
pszAnsiStr,
|
|
dwWrite,
|
|
pdwWritten,
|
|
pData);
|
|
}
|
|
|
|
free( pszAnsiStr );
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// caller most free buffer
|
|
BOOL GetAnsiStr(
|
|
WCHAR * pszWideStr,
|
|
char * pszAnsiStr,
|
|
UINT uBufSize
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
if (pszWideStr && pszAnsiStr)
|
|
{
|
|
int nStrLen = lstrlen( pszWideStr );
|
|
|
|
if (nStrLen)
|
|
{
|
|
int nErr = WideCharToMultiByte( CP_ACP,
|
|
WC_COMPOSITECHECK,
|
|
pszWideStr,
|
|
nStrLen,
|
|
pszAnsiStr,
|
|
uBufSize - 1,
|
|
NULL,
|
|
NULL );
|
|
if (nErr)
|
|
{
|
|
pszAnsiStr[nStrLen] = '\0';
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
#endif
|