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.
1030 lines
24 KiB
1030 lines
24 KiB
// RASrv.cpp : Implementation of CRASrv
|
|
|
|
#include "stdafx.h"
|
|
#include "Raserver.h"
|
|
#include "RASrv.h"
|
|
|
|
#include <ProjectConstants.h>
|
|
#include <rcbdyctl.h>
|
|
#include <rcbdyctl_i.c>
|
|
|
|
#define SIZE_BUFF 256
|
|
|
|
/*extern "C"
|
|
{
|
|
DWORD APIENTRY SquishAddress(WCHAR *szIp, WCHAR *szCompIp);
|
|
DWORD APIENTRY ExpandAddress(WCHAR *szIp, WCHAR *szCompIp);
|
|
};
|
|
*/
|
|
|
|
// **** This code was in the ICSHelper
|
|
|
|
/****************************************************************************
|
|
**
|
|
** Address String Compression routines
|
|
**
|
|
*****************************************************************************
|
|
**
|
|
** The following is a group of routines designed to compress and expand
|
|
** IPV4 addresses into the absolute minimum size possible. This is to
|
|
** provide a compressed ASCII string that can be parsed using standard
|
|
** shell routines for command line parsing.
|
|
** The compressed string has the following restrictions:
|
|
** -> Must not expand to more characters if UTF8 encoded.
|
|
** -> Must not contain the NULL character so that string libs work.
|
|
** -> Cannot contain double quote character, the shell needs that.
|
|
** -> Does not have to be human readable.
|
|
**
|
|
** Data Types:
|
|
** There are three data types used here:
|
|
** szAddr The orginal IPV4 string address ("X.X.X.X:port")
|
|
** blobAddr Six byte struct with 4 bytes of address, and 2 bytes of port
|
|
** szComp Eight byte ascii string of compressed IPV4 address
|
|
**
|
|
****************************************************************************/
|
|
|
|
#define COMP_OFFSET '#'
|
|
#define COMP_SEPERATOR '!'
|
|
|
|
#pragma pack(push,1)
|
|
|
|
typedef struct _BLOB_ADDR {
|
|
UCHAR addr_d; // highest order address byte
|
|
UCHAR addr_c;
|
|
UCHAR addr_b;
|
|
UCHAR addr_a; // lowest order byte (last in IP string address)
|
|
WORD port;
|
|
} BLOB_ADDR, *PBLOB_ADDR;
|
|
|
|
#pragma pack(pop)
|
|
|
|
WCHAR b64Char[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','+','/'
|
|
};
|
|
|
|
|
|
/****************************************************************************
|
|
** char * atob(char *szVal, UCHAR *result)
|
|
****************************************************************************/
|
|
WCHAR *atob(WCHAR *szVal, UCHAR *result)
|
|
{
|
|
WCHAR *lptr;
|
|
WCHAR ucb;
|
|
UCHAR foo;
|
|
|
|
if (!result || !szVal)
|
|
{
|
|
OutputDebugString(L"ERROR: NULL ptr passed in atob");
|
|
return NULL;
|
|
}
|
|
// start ptr at the beginning of string
|
|
lptr = szVal;
|
|
foo = 0;
|
|
ucb = *lptr++ - '0';
|
|
|
|
while (ucb >= 0 && ucb <= 9)
|
|
{
|
|
foo *= 10;
|
|
foo += ucb;
|
|
ucb = (*lptr++)-'0';
|
|
}
|
|
|
|
*result = (UCHAR)foo;
|
|
return lptr;
|
|
}
|
|
|
|
/****************************************************************************
|
|
**
|
|
** CompressAddr(pszAddr, pblobAddr);
|
|
** Takes an ascii IP address (X.X.X.X:port) and converts it to a
|
|
** 6 byte binary blob.
|
|
**
|
|
** returns TRUE for success, FALSE for failure.
|
|
**
|
|
****************************************************************************/
|
|
|
|
BOOL CompressAddr(WCHAR *pszAddr, PBLOB_ADDR pblobAddr)
|
|
{
|
|
BLOB_ADDR lblob;
|
|
WCHAR *lpsz;
|
|
|
|
if (!pszAddr || !pblobAddr)
|
|
{
|
|
OutputDebugString(L"ERROR: NULL ptr passed in CompressAddr");
|
|
return FALSE;
|
|
}
|
|
|
|
lpsz = pszAddr;
|
|
|
|
lpsz = atob(lpsz, &lblob.addr_d);
|
|
if (*(lpsz-1) != '.')
|
|
{
|
|
OutputDebugString(L"ERROR: bad address[0] passed in CompressAddr");
|
|
return FALSE;
|
|
}
|
|
|
|
lpsz = atob(lpsz, &lblob.addr_c);
|
|
if (*(lpsz-1) != '.')
|
|
{
|
|
OutputDebugString(L"ERROR: bad address[1] passed in CompressAddr");
|
|
return FALSE;
|
|
}
|
|
|
|
lpsz = atob(lpsz, &lblob.addr_b);
|
|
if (*(lpsz-1) != '.')
|
|
{
|
|
OutputDebugString(L"ERROR: bad address[2] passed in CompressAddr");
|
|
return FALSE;
|
|
}
|
|
|
|
lpsz = atob(lpsz, &lblob.addr_a);
|
|
|
|
// is there a port number here?
|
|
if (*(lpsz-1) == ':')
|
|
lblob.port = (WORD)_wtoi(lpsz);
|
|
else
|
|
lblob.port = 0;
|
|
|
|
// copy back the result
|
|
memcpy(pblobAddr, &lblob, sizeof(*pblobAddr));
|
|
return TRUE;
|
|
}
|
|
|
|
/****************************************************************************
|
|
**
|
|
** ExpandAddr(pszAddr, pblobAddr);
|
|
** Takes 6 byte binary blob and converts it into an ascii IP
|
|
** address (X.X.X.X:port)
|
|
**
|
|
** returns TRUE for success, FALSE for failure.
|
|
**
|
|
****************************************************************************/
|
|
|
|
BOOL ExpandAddr(WCHAR *pszAddr, PBLOB_ADDR pba)
|
|
{
|
|
if (!pszAddr || !pba)
|
|
{
|
|
OutputDebugString(L"ERROR: NULL ptr passed in ExpandAddr");
|
|
return FALSE;
|
|
}
|
|
|
|
wsprintf(pszAddr, L"%d.%d.%d.%d", pba->addr_d, pba->addr_c,
|
|
pba->addr_b, pba->addr_a);
|
|
if (pba->port)
|
|
{
|
|
WCHAR scratch[8];
|
|
wsprintf(scratch, L":%d", pba->port);
|
|
wcscat(pszAddr, scratch);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/****************************************************************************
|
|
**
|
|
** AsciifyAddr(pszAddr, pblobAddr);
|
|
** Takes 6 byte binary blob and converts it into compressed ascii
|
|
** will return either 6 or 8 bytes of string
|
|
**
|
|
** returns TRUE for success, FALSE for failure.
|
|
**
|
|
****************************************************************************/
|
|
|
|
BOOL AsciifyAddr(WCHAR *pszAddr, PBLOB_ADDR pba)
|
|
{
|
|
UCHAR tmp;
|
|
DWORDLONG dwl;
|
|
int i, iCnt;
|
|
|
|
if (!pszAddr || !pba)
|
|
{
|
|
OutputDebugString(L"ERROR: NULL ptr passed in AsciifyAddr");
|
|
return FALSE;
|
|
}
|
|
|
|
iCnt = 6;
|
|
if (pba->port)
|
|
iCnt = 8;
|
|
|
|
dwl = 0;
|
|
memcpy(&dwl, pba, sizeof(*pba));
|
|
|
|
for (i = 0; i < iCnt; i++)
|
|
{
|
|
// get 6 bits of data
|
|
tmp = (UCHAR)(dwl & 0x3f);
|
|
// add the offset to asciify this
|
|
// offset must be bigger the double-quote char.
|
|
pszAddr[i] = b64Char[tmp]; // (WCHAR)(tmp + COMP_OFFSET);
|
|
|
|
// Shift right 6 bits
|
|
dwl = Int64ShrlMod32(dwl, 6);
|
|
}
|
|
// terminating NULL
|
|
pszAddr[iCnt] = 0;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/****************************************************************************
|
|
**
|
|
** DeAsciifyAddr(pszAddr, pblobAddr);
|
|
** Takes a compressed ascii string and converts it into a
|
|
** 6 or 8 byte binary blob
|
|
**
|
|
** returns TRUE for success, FALSE for failure.
|
|
**
|
|
****************************************************************************/
|
|
|
|
BOOL DeAsciifyAddr(WCHAR *pszAddr, PBLOB_ADDR pba)
|
|
{
|
|
UCHAR tmp;
|
|
WCHAR wtmp;
|
|
DWORDLONG dwl;
|
|
int i;
|
|
int iCnt;
|
|
|
|
if (!pszAddr || !pba)
|
|
{
|
|
OutputDebugString(L"ERROR: NULL ptr passed in DeAsciifyAddr");
|
|
return FALSE;
|
|
}
|
|
|
|
/* how long is this string?
|
|
* if it is 6 bytes, then there is no port
|
|
* else it should be 8 bytes
|
|
*/
|
|
i = wcslen(pszAddr);
|
|
if (i == 6 || i == 8)
|
|
iCnt = i;
|
|
else
|
|
{
|
|
iCnt = 8;
|
|
OutputDebugString(L"Strlen is wrong in DeAsciifyAddr");
|
|
}
|
|
|
|
dwl = 0;
|
|
for (i = iCnt-1; i >= 0; i--)
|
|
{
|
|
wtmp = pszAddr[i];
|
|
|
|
if (wtmp >= L'A' && wtmp <= L'Z')
|
|
tmp = wtmp - L'A';
|
|
else if (wtmp >= L'a' && wtmp <= L'z')
|
|
tmp = wtmp - L'a' + 26;
|
|
else if (wtmp >= L'0' && wtmp <= L'9')
|
|
tmp = wtmp - L'0' + 52;
|
|
else if (wtmp == L'+')
|
|
tmp = 62;
|
|
else if (wtmp == L'/')
|
|
tmp = 63;
|
|
else
|
|
{
|
|
tmp = 0;
|
|
OutputDebugString(L"ERROR:found invalid character in decode stream");
|
|
}
|
|
|
|
// tmp = (UCHAR)(pszAddr[i] - COMP_OFFSET);
|
|
|
|
if (tmp > 63)
|
|
{
|
|
tmp = 0;
|
|
OutputDebugString(L"ERROR:screwup in DeAsciify");
|
|
}
|
|
|
|
dwl = Int64ShllMod32(dwl, 6);
|
|
dwl |= tmp;
|
|
}
|
|
|
|
memcpy(pba, &dwl, sizeof(*pba));
|
|
return TRUE;
|
|
}
|
|
|
|
/****************************************************************************
|
|
**
|
|
** SquishAddress(char *szIp, char *szCompIp)
|
|
** Takes one IP address and compresses it to minimum size
|
|
**
|
|
****************************************************************************/
|
|
|
|
DWORD APIENTRY SquishAddress(WCHAR *szIp, WCHAR *szCompIp)
|
|
{
|
|
WCHAR *thisAddr, *nextAddr;
|
|
BLOB_ADDR ba;
|
|
|
|
if (!szIp || !szCompIp)
|
|
{
|
|
OutputDebugString(L"SquishAddress called with NULL ptr");
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// TRIVIAL_MSG((L"SquishAddress(%s)", szIp));
|
|
|
|
thisAddr = szIp;
|
|
szCompIp[0] = 0;
|
|
|
|
while (thisAddr)
|
|
{
|
|
WCHAR scr[10];
|
|
|
|
nextAddr = wcschr(thisAddr, L';');
|
|
if (nextAddr && *(nextAddr+1))
|
|
{
|
|
*nextAddr = 0;
|
|
}
|
|
else
|
|
nextAddr=0;
|
|
|
|
CompressAddr(thisAddr, &ba);
|
|
AsciifyAddr(scr, &ba);
|
|
|
|
wcscat(szCompIp, scr);
|
|
|
|
if (nextAddr)
|
|
{
|
|
// restore seperator found earlier
|
|
*nextAddr = ';';
|
|
|
|
nextAddr++;
|
|
wcscat(szCompIp, L"!" /* COMP_SEPERATOR */);
|
|
}
|
|
thisAddr = nextAddr;
|
|
}
|
|
|
|
// TRIVIAL_MSG((L"SquishAddress returns [%s]", szCompIp));
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
**
|
|
** ExpandAddress(char *szIp, char *szCompIp)
|
|
** Takes a compressed IP address and returns it to
|
|
** "normal"
|
|
**
|
|
****************************************************************************/
|
|
|
|
DWORD APIENTRY ExpandAddress(WCHAR *szIp, WCHAR *szCompIp)
|
|
{
|
|
BLOB_ADDR ba;
|
|
WCHAR *thisAddr, *nextAddr;
|
|
|
|
if (!szIp || !szCompIp)
|
|
{
|
|
OutputDebugString(L"ExpandAddress called with NULL ptr");
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// TRIVIAL_MSG((L"ExpandAddress(%s)", szCompIp));
|
|
|
|
thisAddr = szCompIp;
|
|
szIp[0] = 0;
|
|
|
|
while (thisAddr)
|
|
{
|
|
WCHAR scr[32];
|
|
|
|
nextAddr = wcschr(thisAddr, COMP_SEPERATOR);
|
|
if (nextAddr) *nextAddr = 0;
|
|
|
|
DeAsciifyAddr(thisAddr, &ba);
|
|
ExpandAddr(scr, &ba);
|
|
|
|
wcscat(szIp, scr);
|
|
|
|
if (nextAddr)
|
|
{
|
|
// restore seperator found earlier
|
|
*nextAddr = COMP_SEPERATOR;
|
|
|
|
nextAddr++;
|
|
wcscat(szIp, L";");
|
|
}
|
|
thisAddr = nextAddr;
|
|
}
|
|
|
|
// TRIVIAL_MSG((L"ExpandAddress returns [%s]", szIp));
|
|
return ERROR_SUCCESS;
|
|
}
|
|
// ***** END ICSHelper code
|
|
|
|
bool CRASrv::InApprovedDomain()
|
|
{
|
|
// WCHAR ourUrl[INTERNET_MAX_URL_LENGTH];
|
|
CComBSTR cbOurURL;
|
|
|
|
if (!GetOurUrl(cbOurURL))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return IsApprovedDomain(cbOurURL);
|
|
}
|
|
|
|
bool CRASrv::GetOurUrl(CComBSTR & cbOurURL)
|
|
{
|
|
HRESULT hr;
|
|
CComPtr<IServiceProvider> spSrvProv;
|
|
CComPtr<IWebBrowser2> spWebBrowser;
|
|
|
|
// Get site pointer...
|
|
CComPtr<IOleClientSite> spClientSite;
|
|
|
|
hr = GetClientSite((IOleClientSite**)&spClientSite);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
hr = spClientSite->QueryInterface(IID_IServiceProvider, (void **)&spSrvProv);
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
hr = spSrvProv->QueryService(SID_SWebBrowserApp,
|
|
IID_IWebBrowser2,
|
|
(void**)&spWebBrowser);
|
|
if (FAILED(hr))
|
|
return false;
|
|
|
|
|
|
|
|
CComBSTR bstrURL;
|
|
if (FAILED(spWebBrowser->get_LocationURL(&bstrURL)))
|
|
return false;
|
|
|
|
|
|
cbOurURL = bstrURL.Copy();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CRASrv::IsApprovedDomain(CComBSTR & cbOurURL)
|
|
{
|
|
// Only allow http access.
|
|
// You can change this to allow file:// access.
|
|
//
|
|
INTERNET_SCHEME isResult;
|
|
|
|
isResult = GetScheme(cbOurURL);
|
|
|
|
if ( (isResult != INTERNET_SCHEME_HTTPS) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//char ourDomain[256];
|
|
CComBSTR cbOurDomain;
|
|
CComBSTR cbGoodDomain[] = {L"www.microsoft.com",
|
|
L"microsoft.com",
|
|
L"microsoft"};
|
|
|
|
if (!GetDomain(cbOurURL, cbOurDomain))
|
|
return false;
|
|
// Go through all the domains that should work
|
|
if (MatchDomains(cbGoodDomain[0], cbOurDomain) ||
|
|
MatchDomains(cbGoodDomain[1], cbOurDomain) ||
|
|
MatchDomains(cbGoodDomain[2], cbOurDomain)
|
|
)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
INTERNET_SCHEME CRASrv::GetScheme(CComBSTR & cbUrl)
|
|
{
|
|
WCHAR buf[32];
|
|
URL_COMPONENTS uc;
|
|
ZeroMemory(&uc, sizeof uc);
|
|
|
|
uc.dwStructSize = sizeof(uc);
|
|
uc.lpszScheme = buf;
|
|
uc.dwSchemeLength = sizeof buf;
|
|
|
|
if (InternetCrackUrl(cbUrl, cbUrl.Length() , ICU_DECODE, &uc))
|
|
return uc.nScheme;
|
|
else
|
|
return INTERNET_SCHEME_UNKNOWN;
|
|
}
|
|
|
|
bool CRASrv::GetDomain(CComBSTR & cbUrl, CComBSTR & cbBuf)
|
|
{
|
|
bool bRet = TRUE;
|
|
|
|
URL_COMPONENTS uc;
|
|
ZeroMemory(&uc, sizeof uc);
|
|
WCHAR buf[INTERNET_MAX_URL_LENGTH];
|
|
int cbBuff = sizeof(WCHAR) * INTERNET_MAX_URL_LENGTH;
|
|
|
|
uc.dwStructSize = sizeof uc;
|
|
uc.lpszHostName = buf;
|
|
uc.dwHostNameLength = cbBuff;
|
|
|
|
if (!InternetCrackUrl(cbUrl, cbUrl.Length(), ICU_DECODE, &uc))
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
cbBuf = buf;
|
|
bRet = true;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// Return if ourDomain is within approvedDomain.
|
|
// approvedDomain must either match ourDomain
|
|
// or be a suffix preceded by a dot.
|
|
//
|
|
bool CRASrv::MatchDomains(CComBSTR& approvedDomain, CComBSTR& ourDomain)
|
|
{
|
|
/* int apDomLen = lstrlen(approvedDomain);
|
|
int ourDomLen = lstrlen(ourDomain);
|
|
|
|
if (apDomLen > ourDomLen)
|
|
return false;
|
|
|
|
if (lstrcmpi(ourDomain+ourDomLen-apDomLen, approvedDomain)
|
|
!= 0)
|
|
return false;
|
|
|
|
if (apDomLen == ourDomLen)
|
|
return true;
|
|
|
|
if (ourDomain[ourDomLen - apDomLen - 1] == '.')
|
|
return true;
|
|
*/
|
|
return approvedDomain == ourDomain ? true : false;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CRASrv
|
|
|
|
// CRAServer
|
|
|
|
// Function: StartRA
|
|
//
|
|
// Parameter: BSTR strData - contains the following in a comma delimited string
|
|
// <IPLIST>,<SessionID>,<PublicKey>
|
|
|
|
STDMETHODIMP CRASrv::StartRA(BSTR strData, BSTR strPassword)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
STARTUPINFO StartUp;
|
|
PROCESS_INFORMATION p_i;
|
|
|
|
BOOL result;
|
|
|
|
if ((strData == NULL) || (*strData == L'\0'))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
if (strData[1] == NULL)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
// Note, there is not always a strPassword so don't fail if it's NULL
|
|
|
|
if (!InApprovedDomain())
|
|
{
|
|
hr = E_FAIL;
|
|
return hr;
|
|
}
|
|
|
|
// **** Parse out the components of the string into CComBSTRs
|
|
|
|
CComBSTR strIn; // Used as the local storage
|
|
|
|
strIn = strData; // Copy the contents so that we can parse
|
|
|
|
CComBSTR strVer;
|
|
BOOL bPassword = FALSE;
|
|
BOOL bModem = FALSE;
|
|
CComBSTR strIPList;
|
|
CComBSTR strSessionID;
|
|
CComBSTR strPublicKey;
|
|
WCHAR * tok;
|
|
CComBSTR strSquishedIPList;
|
|
CComBSTR strExpandedIPList;
|
|
DWORD dwRet = 0x0;
|
|
|
|
CComBSTR strExe( HC_ROOT_HELPSVC_BINARIES L"\\HelpCtr.exe" );
|
|
WCHAR * pStr;
|
|
int iSizeStr = 128;
|
|
|
|
// Expand environment variables in strExe
|
|
pStr = new WCHAR[iSizeStr];
|
|
|
|
dwRet = ::ExpandEnvironmentStrings(strExe, pStr, iSizeStr);
|
|
if (dwRet == 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
if (dwRet >= 128) // if the Buffer is too small
|
|
{
|
|
delete [] pStr;
|
|
|
|
pStr = new WCHAR[dwRet];
|
|
|
|
dwRet = ::ExpandEnvironmentStrings(strExe, pStr, dwRet);
|
|
if (dwRet == 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
// Copy the new expanded buffer back to strExe
|
|
strExe = pStr;
|
|
|
|
// Release the memory allocated to expand the Env Vars
|
|
delete [] pStr;
|
|
|
|
// Parse the BSTR (strIn) to get the ticket info.
|
|
|
|
// Grab the lower byte of the first WCHAR and then get the squished IP List
|
|
tok = ::wcstok(strIn, L",");
|
|
if (tok != NULL)
|
|
{
|
|
|
|
// Check the password flag (bit 0)
|
|
if (tok[0] & 0x1)
|
|
bPassword = TRUE;
|
|
else
|
|
bPassword = FALSE;
|
|
|
|
// Check the Modem flag (bit 1)
|
|
if (tok[0] & 0x2)
|
|
bModem = TRUE;
|
|
else
|
|
bModem = FALSE;
|
|
|
|
tok = &tok[1]; // Move to the next WCHAR to start the Squished IPLIST
|
|
|
|
strSquishedIPList = tok;
|
|
|
|
}
|
|
else
|
|
{
|
|
hr = ERROR_INVALID_USER_BUFFER;
|
|
return hr;
|
|
}
|
|
|
|
tok = ::wcstok(NULL, L",");
|
|
if (tok != NULL)
|
|
{
|
|
strSessionID = tok;
|
|
}
|
|
else
|
|
{
|
|
hr = ERROR_INVALID_USER_BUFFER;
|
|
return hr;
|
|
}
|
|
|
|
tok = ::wcstok(NULL, L",");
|
|
if (tok != NULL)
|
|
{
|
|
strPublicKey = tok;
|
|
}
|
|
else
|
|
{
|
|
hr = ERROR_INVALID_USER_BUFFER;
|
|
return hr;
|
|
}
|
|
|
|
// Now convert the SquishedIPList to an ExpandedIPList
|
|
WCHAR szIP[50];
|
|
|
|
tok = ::wcstok(strSquishedIPList, L";");
|
|
while (tok != NULL)
|
|
{
|
|
// Expand the current SquishedIP we are looking at
|
|
::ZeroMemory(szIP,sizeof(szIP));
|
|
::ExpandAddress(&szIP[0], (WCHAR*)tok);
|
|
|
|
strExpandedIPList += szIP;
|
|
|
|
// Grab Next Token
|
|
tok = ::wcstok(NULL, L";");
|
|
|
|
// add a ; at the end of each IP in the ExpandedIPList
|
|
// ONLY if it's not the last IP in the list.
|
|
if (tok != NULL)
|
|
strExpandedIPList += L";";
|
|
}
|
|
|
|
strIPList = strExpandedIPList;
|
|
|
|
// **** Create a temp file in the temp dir to store the ticket
|
|
CComBSTR strTempPath;
|
|
CComBSTR strTempFile;
|
|
CComBSTR strPathFile; // Used as the full path and name of the file
|
|
|
|
WCHAR buff[SIZE_BUFF];
|
|
WCHAR buff2[SIZE_BUFF];
|
|
|
|
// Clear out the memory in the buffer
|
|
ZeroMemory(buff,sizeof(WCHAR)*SIZE_BUFF);
|
|
|
|
if (!::GetTempPathW(SIZE_BUFF, (LPWSTR)&buff))
|
|
{
|
|
OutputDebugStringW(L"GetTempPath failed!\r\n");
|
|
return E_FAIL;
|
|
}
|
|
|
|
strTempPath = buff;
|
|
strTempPath += L"RA\\";
|
|
|
|
// Create this directory
|
|
if (!CreateDirectory((LPCWSTR)strTempPath, NULL))
|
|
{
|
|
if (ERROR_ALREADY_EXISTS != GetLastError())
|
|
{
|
|
OutputDebugStringW(L"CreateDirectory failed!\r\n");
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
ZeroMemory(buff2,sizeof(WCHAR)*SIZE_BUFF);
|
|
|
|
if (!::GetTempFileNameW((LPCWSTR)strTempPath, NULL, 0, (LPWSTR)&buff2))
|
|
{
|
|
OutputDebugStringW(L"GetTempFileName failed!\r\n");
|
|
return E_FAIL;
|
|
}
|
|
|
|
strTempFile = buff2;
|
|
|
|
// Write the ticket to the file
|
|
CComBSTR strXMLTicket;
|
|
|
|
strXMLTicket = L"<?xml version=\"1.0\" encoding=\"Unicode\" ?><UPLOADINFO TYPE=\"Escalated\"><UPLOADDATA RCTICKET=\"65538,1,";
|
|
strXMLTicket += strIPList;
|
|
strXMLTicket += L",";
|
|
strXMLTicket += L"*assistantAccountPwd";
|
|
strXMLTicket += L",";
|
|
strXMLTicket += strSessionID;
|
|
strXMLTicket += L",";
|
|
strXMLTicket += L"*SolicitedHelp";
|
|
strXMLTicket += L",";
|
|
strXMLTicket += L"*helpSessionName";
|
|
strXMLTicket += L",";
|
|
strXMLTicket += strPublicKey;
|
|
strXMLTicket += L"\" ";
|
|
strXMLTicket += L"RCTICKETENCRYPTED=\"";
|
|
strXMLTicket += (bPassword ? L"1\"" : L"0\"");
|
|
strXMLTicket += L" L=";
|
|
strXMLTicket += (bModem ? L"\"1\" " : L"\"0\" ");
|
|
//strXMLTicket += L"DeleteTicket=\"1\" ";
|
|
if (!bPassword)
|
|
{
|
|
strXMLTicket += L"URA=\"1\" ";
|
|
}
|
|
else
|
|
{
|
|
strXMLTicket += L"PassStub=\"";
|
|
strXMLTicket += strSessionID;
|
|
strXMLTicket += L"\" ";
|
|
|
|
}
|
|
strXMLTicket += "/></UPLOADINFO>";
|
|
|
|
DWORD dwWritten = 0x0;
|
|
|
|
// Create XML File for the incident
|
|
CComPtr<IXMLDOMDocument> spXMLDoc;
|
|
VARIANT_BOOL vbSuccess;
|
|
CComVariant cvStrTempFile;
|
|
|
|
hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&spXMLDoc);
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
hr = spXMLDoc->loadXML(strXMLTicket, &vbSuccess);
|
|
if (FAILED(hr) || (vbSuccess == VARIANT_FALSE))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
cvStrTempFile = strTempFile;
|
|
|
|
hr = spXMLDoc->save(cvStrTempFile);
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
// Start helpctr.exe with this ticket in order to start Remote Assistance
|
|
// as an Expert
|
|
|
|
strExe += L" -Mode \"hcp://system/Remote Assistance/RAHelpeeAcceptLayout.xml\" -url \"hcp://system/Remote Assistance/Interaction/Client/RcToolscreen1.htm\" -ExtraArgument \"IncidentFile=";
|
|
strExe += strTempFile;
|
|
strExe += L"\"";
|
|
|
|
// initialize our structs
|
|
ZeroMemory(&p_i, sizeof(p_i));
|
|
ZeroMemory(&StartUp, sizeof(StartUp));
|
|
StartUp.cb = sizeof(StartUp);
|
|
StartUp.dwFlags = STARTF_USESHOWWINDOW;
|
|
StartUp.wShowWindow = SW_SHOWNORMAL;
|
|
|
|
result = CreateProcess(NULL, strExe,
|
|
NULL, NULL, TRUE,
|
|
NORMAL_PRIORITY_CLASS + CREATE_UNICODE_ENVIRONMENT ,
|
|
NULL, // Environment block (must use the CREATE_UNICODE_ENVIRONMENT flag)
|
|
NULL, &StartUp, &p_i);
|
|
|
|
if (!result)
|
|
{
|
|
// CreateProcess Failed!
|
|
dwRet = GetLastError();
|
|
|
|
OutputDebugStringW(L"CreateProcessW failed!");
|
|
return E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*
|
|
STDMETHODIMP CRASrv::QueryOS(long *pRes)
|
|
{
|
|
OSVERSIONINFOEX osinfo;
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!pRes)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
memset((OSVERSIONINFO *)&osinfo, 0, sizeof(osinfo));
|
|
osinfo.dwOSVersionInfoSize = sizeof(osinfo);
|
|
|
|
if (!GetVersionEx((OSVERSIONINFO *)&osinfo))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Return the correct value
|
|
// Operating System Constant
|
|
// Windows XP 0x01
|
|
// Windows 2000 0x02
|
|
// Windows NT 0x03
|
|
// Windows ME 0x04
|
|
// Windows 98 0x05
|
|
// Windows 95 0x06
|
|
// Windows 3.x 0x07
|
|
// Other 0x10
|
|
|
|
switch(osinfo.dwMajorVersion)
|
|
{
|
|
case 5:
|
|
switch(osinfo.dwMinorVersion)
|
|
{
|
|
case 1:
|
|
*pRes = 0x01;
|
|
break;
|
|
case 0:
|
|
*pRes = 0x02;
|
|
break;
|
|
default:
|
|
// Nothing
|
|
break;
|
|
}
|
|
break;
|
|
case 4:
|
|
switch(osinfo.dwMinorVersion)
|
|
{
|
|
case 0:
|
|
// Win95 or NT 4
|
|
*pRes = 0x03;
|
|
break;
|
|
case 10:
|
|
// Win98
|
|
*pRes = 0x05;
|
|
break;
|
|
case 90:
|
|
//WinME
|
|
*pRes = 0x04;
|
|
break;
|
|
default:
|
|
// Nothing
|
|
break;
|
|
}
|
|
break;
|
|
case 3:
|
|
//WinNT3.51
|
|
*pRes = 0x07;
|
|
default:
|
|
*pRes = 0x10;
|
|
break;
|
|
}
|
|
|
|
return hr ;
|
|
}
|
|
*/
|
|
|
|
//
|
|
// Function: Cleanup()
|
|
//
|
|
// Description:
|
|
//
|
|
// This function goes into the RA temporary files directory
|
|
// and cleans up all the files that are older than 5 minutes.
|
|
|
|
bool CRASrv::Cleanup()
|
|
{
|
|
bool bRet = TRUE;
|
|
WCHAR buff[SIZE_BUFF];
|
|
|
|
CComBSTR strTempDir,
|
|
strTempDirWild;
|
|
CComBSTR strTempFile;
|
|
HANDLE hFile;
|
|
|
|
// *** Find out what the temp directory is
|
|
|
|
// Clear out the memory in the buffer
|
|
ZeroMemory(buff,sizeof(WCHAR)*SIZE_BUFF);
|
|
|
|
if (!::GetTempPathW(SIZE_BUFF, (LPWSTR)&buff))
|
|
{
|
|
OutputDebugStringW(L"GetTempPath failed!\r\n");
|
|
return false;
|
|
}
|
|
|
|
strTempDir = buff;
|
|
strTempDir += L"RA\\";
|
|
strTempDirWild = strTempDir;
|
|
strTempDirWild += L"*.*";
|
|
|
|
WIN32_FIND_DATA ffd;
|
|
|
|
// then enumerate all the files in this directory
|
|
hFile = ::FindFirstFileW((LPCWSTR)strTempDirWild, &ffd);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
bool bCont = true;
|
|
|
|
FILETIME ftSystemTime;
|
|
SYSTEMTIME st;
|
|
::GetSystemTime(&st);
|
|
|
|
::SystemTimeToFileTime(&st, &ftSystemTime);
|
|
|
|
int iTimeDelta,
|
|
iTimeThreshold = 0x1; // The threshold is dec(0x1 0000 0000)*(1/60)*10^-9
|
|
// which is approximately 7-8 minutes
|
|
|
|
while (bCont)
|
|
{
|
|
// get the timestamp on this file if it's not . or ..
|
|
if (!(
|
|
(::wcscmp(L".", ffd.cFileName) == 0) ||
|
|
(::wcscmp(L"..", ffd.cFileName) == 0)
|
|
)
|
|
)
|
|
{
|
|
iTimeDelta = ftSystemTime.dwHighDateTime - ffd.ftCreationTime.dwHighDateTime;
|
|
if (iTimeDelta > iTimeThreshold)
|
|
{
|
|
// The file is older than the threshold, delete the file
|
|
|
|
strTempFile = strTempDir;
|
|
strTempFile += ffd.cFileName;
|
|
|
|
::DeleteFileW((LPCWSTR)strTempFile);
|
|
}
|
|
}
|
|
|
|
// Grab the next file
|
|
if (!::FindNextFileW(hFile, &ffd))
|
|
{
|
|
if (ERROR_NO_MORE_FILES == GetLastError())
|
|
{
|
|
bCont = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return bRet;
|
|
}
|