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.
 
 
 
 
 
 

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;
}