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.
 
 
 
 
 
 

475 lines
10 KiB

#include <fusenetincludes.h>
#include <bits.h>
#include "regdb.h"
#include "list.h"
#include "assemblydownload.h"
#include "macros.h"
#define REG_KEY_FUSION_PENDING_JOBS TEXT("1.0.0.0\\PendingJobs\\")
#define TEMP_FILE_STRING TEXT("TempFile")
#define URL_STRING TEXT("Url")
struct CJobGuid
{
GUID guid;
};
HRESULT AddJobToRegistry(LPWSTR pwzURL,
LPWSTR pwzTempFile,
IBackgroundCopyJob *pJob,
DWORD dwFlags)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
GUID JobGUID;
CString sRegKey;
CString sGUID;
CRegEmit *pRegEmit = NULL;
// ASSERT( lstrlen(sURL._pwz) && lstrlen(sTempFile._pwz) && pJob);
IF_FAILED_EXIT(pJob->GetId( &JobGUID));
FusionFormatGUID(JobGUID, sGUID);
// GUIDToString(&JobGUID, sGUID);
IF_FAILED_EXIT(sRegKey.Assign(REG_KEY_FUSION_PENDING_JOBS));
IF_FAILED_EXIT(sRegKey.Append(sGUID));
IF_FAILED_EXIT(CRegEmit::Create(&pRegEmit, sRegKey._pwz));
IF_FAILED_EXIT(pRegEmit->WriteString(URL_STRING, pwzURL));
IF_FAILED_EXIT(pRegEmit->WriteString(TEMP_FILE_STRING, pwzTempFile));
exit:
SAFEDELETE(pRegEmit);
return hr;
}
HRESULT RemoveJobFromRegistry(IBackgroundCopyJob *pJob,
GUID *pGUID, SHREGDEL_FLAGS dwDelRegFlags, DWORD dwFlags)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
GUID JobGUID;
LONG lResult;
CString sRegKey;
CString sGUID;
CRegEmit *pRegEmit = NULL;
CRegImport *pRegImp = NULL;
// ASSERT( lstrlen(sURL._pwz) && lstrlen(sTempFile._pwz) && pJob);
if(pJob)
{
IF_FAILED_EXIT(pJob->GetId( &JobGUID));
}
else
{
JobGUID = *pGUID;
}
FusionFormatGUID(JobGUID, sGUID);
// GUIDToString(&JobGUID, sGUID);
IF_FAILED_EXIT(sRegKey.Assign(REG_KEY_FUSION_PENDING_JOBS));
IF_FAILED_EXIT(sRegKey.Append(sGUID));
IF_FAILED_EXIT(CRegImport::Create(&pRegImp, sRegKey._pwz));
if(hr == S_FALSE)
goto exit;
if(dwFlags & RJFR_DELETE_FILES) // delete the temp files also
{
CString sTempPath;
IF_FAILED_EXIT(pRegImp->ReadString(TEMP_FILE_STRING, sTempPath));
IF_FAILED_EXIT(sTempPath.RemoveLastElement());
IF_FAILED_EXIT(RemoveDirectoryAndChildren(sTempPath._pwz));
}
IF_FAILED_EXIT(sRegKey.Assign(REG_KEY_FUSION_PENDING_JOBS));
IF_FAILED_EXIT(CRegEmit::Create(&pRegEmit, sRegKey._pwz));
IF_FAILED_EXIT(pRegEmit->DeleteKey(sGUID._pwz));
exit:
SAFEDELETE(pRegEmit);
SAFEDELETE(pRegImp);
return hr;
}
#define CCH_GUID (38)
void FusionFormatGUID(GUID guid, CString& sGUID)
{
WCHAR szBuf[MAX_PATH+1];
// ASSERT(sGUID);
wnsprintf(szBuf, MAX_PATH, L"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1],
guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
sGUID.Assign(szBuf);
}
int HexDigitToValue(WCHAR wch)
{
if ((wch >= L'a') && (wch <= L'f'))
return 10 + (wch - L'a');
else if ((wch >= L'A') && (wch <= 'F'))
return 10 + (wch - L'A');
else if (wch >= '0' && wch <= '9')
return (wch - L'0');
else
return -1;
}
bool IsHexDigit(WCHAR wch)
{
return (((wch >= L'0') && (wch <= L'9')) ||
((wch >= L'a') && (wch <= L'f')) ||
((wch >= L'A') && (wch <= L'F')));
}
HRESULT FusionParseGUID(
LPWSTR String,
SIZE_T Cch,
GUID &rGuid
)
{
HRESULT hr = S_OK;
SIZE_T ich;
ULONG i;
ULONG acc;
if (Cch != CCH_GUID)
{
hr = E_INVALIDARG;
goto exit;
}
ich = 1;
if (*String++ != L'{')
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
// Parse the first segment...
acc = 0;
for (i=0; i<8; i++)
{
WCHAR wch = *String++;
if (!::IsHexDigit(wch))
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
acc = acc << 4;
acc += HexDigitToValue(wch);
}
rGuid.Data1 = acc;
// Look for the dash...
if (*String++ != L'-')
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
acc = 0;
for (i=0; i<4; i++)
{
WCHAR wch = *String++;
if (!::IsHexDigit(wch))
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
acc = acc << 4;
acc += HexDigitToValue(wch);
}
rGuid.Data2 = static_cast<USHORT>(acc);
// Look for the dash...
if (*String++ != L'-')
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
acc = 0;
for (i=0; i<4; i++)
{
WCHAR wch = *String++;
if (!::IsHexDigit(wch))
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
acc = acc << 4;
acc += HexDigitToValue(wch);
}
rGuid.Data3 = static_cast<USHORT>(acc);
// Look for the dash...
if (*String++ != L'-')
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
for (i=0; i<8; i++)
{
WCHAR wch1, wch2;
wch1 = *String++;
if (!::IsHexDigit(wch1))
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
wch2 = *String++;
if (!::IsHexDigit(wch2))
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
rGuid.Data4[i] = static_cast<unsigned char>((::HexDigitToValue(wch1) << 4) | ::HexDigitToValue(wch2));
// There's a dash after the 2nd byte
if (i == 1)
{
if (*String++ != L'-')
{
hr = E_INVALIDARG;
goto exit;
}
ich++;
}
}
// This replacement should be made.
//INTERNAL_ERROR_CHECK(ich == CCH_GUID);
// ASSERT(ich == CCH_GUID);
if (*String != L'}')
{
hr = E_INVALIDARG;
goto exit;
}
exit:
return hr;
}
#define FROMHEX(a) ((a)>=L'a' ? a - L'a' + 10 : a - L'0')
#define TOLOWER(a) (((a) >= L'A' && (a) <= L'Z') ? (L'a' + (a - L'A')) : (a))
//--------------------------------------------------------------------
// GUIDToUnicodeHex
//--------------------------------------------------------------------
HRESULT GUIDToString(GUID *pGUID, CString& sGUID)
{
HRESULT hr = S_OK;
WCHAR pDst[MAX_PATH];
LPBYTE pSrc = (LPBYTE) pGUID;
UINT cSrc = sizeof(GUID);
UINT x;
UINT y;
#define TOHEX(a) ((a)>=10 ? L'a'+(a)-10 : L'0'+(a))
for ( x = 0, y = 0 ; x < cSrc ; ++x )
{
UINT v;
v = pSrc[x]>>4;
pDst[y++] = TOHEX( v );
v = pSrc[x] & 0x0f;
pDst[y++] = TOHEX( v );
}
pDst[y] = '\0';
hr = sGUID.Assign(pDst);
// exit :
return hr;
}
//--------------------------------------------------------------------
// UnicodeHexToGUID
//--------------------------------------------------------------------
HRESULT StringToGUID(LPCWSTR pSrc, UINT cSrc, GUID *pGUID)
{
BYTE v;
LPBYTE pd = (LPBYTE) pGUID;
LPCWSTR ps = pSrc;
for (UINT i = 0; i < cSrc-1; i+=2)
{
v = FROMHEX(TOLOWER(ps[i])) << 4;
v |= FROMHEX(TOLOWER(ps[i+1]));
*(pd++) = v;
}
return S_OK;
}
HRESULT EnumPendingJobs(List <CJobGuid*> **ppJobList)
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
CRegImport *pRegImp=NULL;
GUID JobGUID = {0};
CString sRegKey;
int iIndex = 0;
List<CJobGuid *> *pJobList= new (List<CJobGuid *>);
CJobGuid *pNode;
CString sGUID;
*ppJobList = NULL;
sRegKey.Assign(REG_KEY_FUSION_PENDING_JOBS);
IF_FAILED_EXIT(CRegImport::Create(&pRegImp, sRegKey._pwz));
if(hr == S_FALSE)
goto exit;
while ( (hr = pRegImp->EnumKeys(iIndex++, sGUID)) == S_OK )
{
IF_FAILED_EXIT(FusionParseGUID(sGUID._pwz, lstrlen(sGUID._pwz), JobGUID));
IF_ALLOC_FAILED_EXIT(pNode = new (CJobGuid));
pNode->guid = JobGUID;
pJobList->AddHead(pNode);
}
if(hr == S_FALSE)
hr = S_OK;
else
goto exit;
*ppJobList = pJobList;
exit :
if(!(*ppJobList))
{
SAFEDELETE(pJobList); // this should call RemoveAll();
}
SAFEDELETE(pRegImp);
return hr;
}
HRESULT SalvageOrphanedJob(IBackgroundCopyJob *pJob)
{
return E_NOTIMPL;
}
HRESULT ProcessOrphanedJobs()
{
HRESULT hr = S_OK;
MAKE_ERROR_MACROS_STATIC(hr);
List <CJobGuid*> *pJobList = NULL;
LISTNODE pTempList=NULL;
int iJobCount=0,i=0;
CJobGuid *pTargetJob;
IBackgroundCopyJob *pJob = NULL;
IF_FAILED_EXIT( EnumPendingJobs( &pJobList));
IF_FAILED_EXIT(CAssemblyDownload::InitBITS());
// process list .....
pTempList = pJobList->GetHeadPosition();
iJobCount = pJobList->GetCount();
for(i=0; i<iJobCount; i++)
{
pTargetJob = pJobList->GetNext(pTempList); // Element from list;
pJob = NULL;
hr = g_pBITSManager->GetJob(pTargetJob->guid, &pJob);
// Check if we can salvage this job
if( FAILED(hr = SalvageOrphanedJob(pJob)))
{
if(pJob)
hr = pJob->Cancel();
// if cancel fails, log it.
// RemoveDirectoryAndChildren();
IF_FAILED_EXIT(RemoveJobFromRegistry(pJob, &(pTargetJob->guid), SHREGDEL_HKCU, RJFR_DELETE_FILES));
}
SAFERELEASE(pJob);
}
exit:
// destroy list.
if(pJobList)
{
pTempList = pJobList->GetHeadPosition();
iJobCount = pJobList->GetCount();
for(i=0; i<iJobCount; i++)
{
pTargetJob = pJobList->GetNext(pTempList); // Element from list;
SAFEDELETE(pTargetJob);
}
pJobList->RemoveAll();
SAFEDELETE(pJobList); // this should call RemoveAll
}
SAFERELEASE(pJob);
return hr;
}