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.
 
 
 
 
 
 

1361 lines
32 KiB

#include "inspch.h"
#include <regstr.h>
#include "resource.h"
#include "insobj.h"
#define STR_FILELIST "filelist.dat"
#define GENERAL_SECTION "General"
#define MIN_SUPPORTED_FILELIST_VER 1
#define CURRENT_FILELIST_VER "1"
HRESULT GetICifFileFromFile(ICifFile **p, LPCSTR pszPath)
{
HRESULT hr;
CCifFile *pcif;
*p = 0;
pcif = new CCifFile();
if(pcif)
{
hr = pcif->SetCifFile(pszPath, FALSE); // FALSE: Read version
if(FAILED(hr))
delete pcif;
else
{
pcif->AddRef();
*p = (ICifFile *)pcif;
}
}
else
hr = E_OUTOFMEMORY;
return hr;
}
HRESULT GetICifRWFileFromFile(ICifRWFile **p, LPCSTR pszPath)
{
HRESULT hr;
CCifRWFile *pcifrw;
*p = 0;
pcifrw = new CCifRWFile();
if(pcifrw)
{
hr = pcifrw->SetCifFile(pszPath, TRUE); // TRUE: ReadWrite version
if(FAILED(hr))
delete pcifrw;
else
{
pcifrw->AddRef();
*p = (ICifRWFile *)pcifrw;
}
}
else
hr = E_OUTOFMEMORY;
return hr;
}
CCifFile::CCifFile()
{
_cRef = 0;
_cComp = 0;
_cGroup = 0;
_cMode = 0;
_rpGroup = 0;
_rpComp = 0;
_rpMode = 0;
_rpRWGroup = 0;
_rpRWComp = 0;
_rpRWMode = 0;
_fCleanDir = FALSE;
_pLastCriticalComp = NULL;
}
CCifFile::~CCifFile()
{
UINT i;
if(_rpGroup)
{
CCifGroup *pgrp;
i = 0;
for(pgrp = _rpGroup[i]; pgrp != 0; pgrp = _rpGroup[++i])
delete pgrp;
free(_rpGroup);
}
if(_rpComp)
{
CCifComponent *pcomp;
i = 0;
for(pcomp = _rpComp[i]; pcomp != 0; pcomp = _rpComp[++i])
delete pcomp;
free(_rpComp);
}
if(_rpMode)
{
CCifMode *pmode;
i = 0;
for(pmode = _rpMode[i]; pmode != 0; pmode = _rpMode[++i])
delete pmode;
free(_rpMode);
}
if(_fCleanDir)
{
GetParentDir(_szCifPath);
CleanUpTempDir(_szCifPath);
}
}
//************ IUnknown implementation ***************
STDMETHODIMP_(ULONG) CCifFile::AddRef()
{
return(_cRef++);
}
STDMETHODIMP_(ULONG) CCifFile::Release()
{
ULONG temp = --_cRef;
if(temp == 0)
delete this;
return temp;
}
STDMETHODIMP CCifFile::QueryInterface(REFIID riid, void **ppv)
{
*ppv = 0;
if((riid == IID_IUnknown) || (riid == IID_ICifFile))
*ppv = (ICifFile *)this;
if(*ppv == NULL)
return E_NOINTERFACE;
AddRef();
return NOERROR;
}
// ICifFile implementation
STDMETHODIMP CCifFile::EnumComponents(IEnumCifComponents **pp, DWORD dwFilter, LPVOID pv)
{
CCifComponentEnum *pce;
HRESULT hr = E_FAIL;
*pp = 0;
pce = new CCifComponentEnum(_rpComp, dwFilter, PARENTTYPE_CIF, NULL);
if(pce)
{
*pp = (IEnumCifComponents *) pce;
(*pp)->AddRef();
hr = NOERROR;
}
return hr;
}
STDMETHODIMP CCifFile::FindComponent(LPCSTR pszID, ICifComponent **p)
{
CCifComponent *pcomp;
UINT i = 0;
*p = 0;
if(_rpComp)
{
for(pcomp = _rpComp[i]; pcomp != 0; pcomp = _rpComp[++i])
if(pcomp->IsID(pszID))
{
*p = (ICifComponent *) pcomp;
return NOERROR;
}
}
return E_FAIL;
}
STDMETHODIMP CCifFile::EnumGroups(IEnumCifGroups **pp, DWORD dwFilter, LPVOID pv)
{
CCifGroupEnum *pge;
HRESULT hr = E_FAIL;
*pp = 0;
pge = new CCifGroupEnum(_rpGroup, dwFilter);
if(pge)
{
*pp = (IEnumCifGroups *) pge;
(*pp)->AddRef();
hr = NOERROR;
}
return hr;
}
STDMETHODIMP CCifFile::FindGroup(LPCSTR pszID, ICifGroup **p)
{
CCifGroup *pgrp;
UINT i = 0;
*p = 0;
if(_rpGroup)
{
for(pgrp = _rpGroup[i]; pgrp != 0; pgrp = _rpGroup[++i])
if(pgrp->IsID(pszID))
{
*p = (ICifGroup *) pgrp;
return NOERROR;
}
}
return E_FAIL;
}
STDMETHODIMP CCifFile::EnumModes(IEnumCifModes **pp, DWORD dwFilter, LPVOID pv)
{
CCifModeEnum *pme;
HRESULT hr = E_FAIL;
*pp = 0;
pme = new CCifModeEnum(_rpMode, dwFilter);
if(pme)
{
*pp = (IEnumCifModes *) pme;
(*pp)->AddRef();
hr = NOERROR;
}
return hr;
}
STDMETHODIMP CCifFile::FindMode(LPCSTR pszID, ICifMode **p)
{
CCifMode *pmode;
UINT i = 0;
*p = 0;
if(_rpMode)
{
for(pmode = _rpMode[i]; pmode != 0; pmode = _rpMode[++i])
if(pmode->IsID(pszID))
{
*p = (ICifMode *) pmode;
return NOERROR;
}
}
return E_FAIL;
}
STDMETHODIMP CCifFile::GetDescription(LPSTR pszDesc, DWORD dwSize)
{
// Get display title out of version section
if(FAILED(MyTranslateString(_szCifPath, "Version", DISPLAYNAME_KEY, pszDesc, dwSize)))
LoadSz(IDS_DEFAULTTITLE, pszDesc, dwSize);
return NOERROR;
}
STDMETHODIMP CCifFile::GetDetDlls(LPSTR pszDlls, DWORD dwSize)
{
return(GetPrivateProfileString("Version", DETDLLS_KEY, "", pszDlls, dwSize, _szCifPath)?NOERROR:E_FAIL);
}
//const char c_gszRegstrPathIExplore[] = REGSTR_PATH_APPPATHS "\\iexplore.exe";
HRESULT CCifFile::SetCifFile(LPCSTR pszCifPath, BOOL bRWFlag)
{
HRESULT hr = NOERROR;
UINT i;
// if it is not quallified, start from ie
if(PathIsFileSpec(pszCifPath))
{
DWORD dwSize, dwType;
char szTmp[MAX_PATH];
if ( SUCCEEDED(hr=GetIEPath(szTmp, sizeof(szTmp))))
{
lstrcpy(_szCifPath, szTmp);
SafeAddPath(_szCifPath, pszCifPath, sizeof(_szCifPath));
}
}
else // we were given a full path
lstrcpyn(_szCifPath, pszCifPath, MAX_PATH);
if(SUCCEEDED(hr))
{
if(_rpComp)
{
// we already have a cif, so just reset cached stuff, and pray...
for(i = 0; i < _cComp; i++)
{
_rpComp[i]->ClearCachedInfo();
}
for(i = 0; i < _cGroup; i++)
{
_rpGroup[i]->ClearCachedInfo();
}
for(i = 0; i < _cMode; i++)
{
_rpMode[i]->ClearCachedInfo();
}
// Sort all again, in case priorities changed
SortEntries();
}
else
hr = _ParseCifFile(bRWFlag);
}
return(hr);
}
HRESULT CCifFile::_ParseCifFile(BOOL bRWFlag)
{
LPSTR pszSections;
LPSTR pszSectionsPreFail = NULL;
DWORD dwSize = ALLOC_CHUNK_SIZE;
LPSTR pszTemp;
char szEntryBuf[MAX_DISPLAYNAME_LENGTH];
pszSections = (LPSTR) malloc(dwSize);
// when the buffer is too small, GPPS returns bufsize - 2
while(pszSections &&
(GetPrivateProfileStringA(NULL, NULL, "", pszSections, dwSize, _szCifPath) == (dwSize - 2)))
{
dwSize += ALLOC_CHUNK_SIZE;
pszSectionsPreFail = pszSections;
#pragma prefast(suppress: 308, "PREfast noise - pointer was saved before")
pszSections = (LPSTR) realloc(pszSections, dwSize);
}
if(!pszSections)
{
if(pszSectionsPreFail)
free(pszSectionsPreFail);
return E_OUTOFMEMORY;
}
if(lstrlen(pszSections) == 0)
return E_FAIL;
// whip thru the sections, and find counts for modes, groups, and components
_cComp = _cGroup = _cMode = 0;
for(pszTemp = pszSections; *pszTemp != 0; pszTemp += (lstrlen(pszTemp) + 1))
{
// skip String section and Version section
if( (lstrcmpi(pszTemp, "Strings") != 0)
&& (lstrcmpi(pszTemp, "Version") != 0) )
{
GetPrivateProfileString(pszTemp, ENTRYTYPE_KEY, ENTRYTYPE_COMP, szEntryBuf, sizeof(szEntryBuf), _szCifPath);
// see if this is a comp, group, or mode
if(lstrcmpi(szEntryBuf, ENTRYTYPE_COMP) == 0)
_cComp++;
else if(lstrcmpi(szEntryBuf, ENTRYTYPE_GROUP) == 0)
_cGroup++;
else if(lstrcmpi(szEntryBuf, ENTRYTYPE_MODE) == 0)
_cMode++;
}
}
// alloc arrays to hold each type (1 more than count - last entry null)
if (bRWFlag)
{
_rpRWComp = (CCifRWComponent **) calloc(sizeof(CCifRWComponent *), _cComp + 1);
_rpRWGroup = (CCifRWGroup **) calloc(sizeof(CCifRWGroup *), _cGroup + 1);
_rpRWMode = (CCifRWMode **) calloc(sizeof(CCifRWMode *), _cMode + 1);
}
else
{
_rpComp = (CCifComponent **) calloc(sizeof(CCifComponent *), _cComp + 1);
_rpGroup = (CCifGroup **) calloc(sizeof(CCifGroup *), _cGroup + 1);
_rpMode = (CCifMode **) calloc(sizeof(CCifMode *), _cMode + 1);
}
_cComp = _cGroup = _cMode = 0;
if((!bRWFlag && _rpComp && _rpGroup && _rpMode) || (bRWFlag && _rpRWComp && _rpRWGroup && _rpRWMode))
{
// pass thru sections again, adding to lists
for(pszTemp = pszSections; *pszTemp != 0; pszTemp += (lstrlen(pszTemp) + 1))
{
// skip String section and Version section
if( (lstrcmpi(pszTemp, "Strings") != 0)
&& (lstrcmpi(pszTemp, "Version") != 0) )
{
GetPrivateProfileString(pszTemp, ENTRYTYPE_KEY, ENTRYTYPE_COMP, szEntryBuf, sizeof(szEntryBuf), _szCifPath);
// see if this is a comp, group, or mode
if(lstrcmpi(szEntryBuf, ENTRYTYPE_COMP) == 0)
{
if (bRWFlag)
_rpRWComp[_cComp++] = new CCifRWComponent(pszTemp, this);
else
_rpComp[_cComp++] = new CCifComponent(pszTemp, this);
}
else if(lstrcmpi(szEntryBuf, ENTRYTYPE_GROUP) == 0)
{
if (bRWFlag)
_rpRWGroup[_cGroup++] = new CCifRWGroup(pszTemp, _cGroup, this);
else
_rpGroup[_cGroup++] = new CCifGroup(pszTemp, _cGroup, this);
}
else if(lstrcmpi(szEntryBuf, ENTRYTYPE_MODE) == 0)
{
if (bRWFlag)
_rpRWMode[_cMode++] = new CCifRWMode(pszTemp, this);
else
_rpMode[_cMode++] = new CCifMode(pszTemp, this);
}
}
}
}
if(_cComp) _cComp--;
if(_cGroup) _cGroup--;
if(_cMode) _cMode--;
if (!bRWFlag)
SortEntries();
free(pszSections);
return NOERROR;
}
void CCifFile::ReinsertComponent(CCifComponent *pComp)
{
int i,j;
// find it in list
for(i = 0; i <= (int) _cComp; i++)
{
if(pComp == _rpComp[i])
{
// once found, move everything under it up
for(j = i + 1; j <=(int) (_cComp + 1); j++)
_rpComp[j-1] = _rpComp[j];
break;
}
}
// now find where we should insert it
for(i = 0; _rpComp[i] != 0; i++)
{
if(_rpComp[i]->GetCurrentPriority() < pComp->GetCurrentPriority())
break;
}
// we want to isert new guy at i
// move everyone down first
for(j = _cComp; j >= i; j--)
_rpComp[j+1] = _rpComp[j];
// reinsert at i
_rpComp[i] = pComp;
// Now check that the dependencies are maintained.
_CheckDependencyPriority();
}
void CCifFile::SortEntries()
{
_SortComponents(_rpComp, 0, _cComp);
_SortGroups(_rpGroup, 0, _cGroup);
_CheckDependencyPriority();
}
void CCifFile::_CheckDependencyPriority()
{
char szCompBuf[MAX_ID_LENGTH];
CCifComponent *pCompxkokr;
CCifComponent *pCompxenus;
DWORD ixkokr = 0xffffffff;
DWORD ixenus = 0xffffffff;
// this is a complete hack for Outlook 98 Korean, which has bugs
// in prorities.
for(int i = 0; _rpComp[i] != 0; i++)
{
if(_rpComp[i]->IsID("Outlook98_xkokr"))
{
pCompxkokr = _rpComp[i];
ixkokr = i;
}
else if(_rpComp[i]->IsID("Outlook98_xenus"))
{
pCompxenus = _rpComp[i];
ixenus = i;
}
}
if(ixkokr != 0xffffffff && ixenus != 0xffffffff)
{
if(ixenus > ixkokr)
{
_rpComp[ixenus] = pCompxkokr;
_rpComp[ixkokr] = pCompxenus;
}
}
}
void CCifFile::ClearQueueState()
{
for(int i = 0; _rpComp[i] != 0; i++)
{
_rpComp[i]->ClearQueueState();
}
}
void CCifFile::_SortComponents(CCifComponent * a[], UINT p, UINT r)
{
UINT i, j, x;
CCifComponent *t;
if(p < r)
{
i = p - 1;
j = r + 1;
x = a[p]->GetCurrentPriority();
for(;;)
{
while(a[++i]->GetCurrentPriority() > x);
while(a[--j]->GetCurrentPriority() < x);
if(i >= j) break;
t = a[i]; a[i] = a[j]; a[j] = t;
}
_SortComponents(a, p, j);
_SortComponents(a, j + 1, r);
}
}
void CCifFile::_SortGroups(CCifGroup * a[], UINT p, UINT r)
{
UINT i, j, x;
CCifGroup *t;
if(p < r)
{
i = p - 1;
j = r + 1;
x = a[p]->GetCurrentPriority();
for(;;)
{
while(a[++i]->GetCurrentPriority() > x);
while(a[--j]->GetCurrentPriority() < x);
if(i >= j) break;
t = a[i]; a[i] = a[j]; a[j] = t;
}
_SortGroups(a, p, j);
_SortGroups(a, j + 1, r);
}
}
void CCifFile::SetDownloadDir(LPCSTR pszDownloadDir)
{
char szBuf[MAX_PATH];
DWORD dwLen;
DWORD dwVer;
lstrcpyn(_szDLDir, pszDownloadDir, MAX_PATH);
if(_szDLDir[0] >= 'a' && _szDLDir[0] <= 'z')
_szDLDir[0] -= 32;
lstrcpyn(_szFilelist, pszDownloadDir, MAX_PATH);
SafeAddPath(_szFilelist, STR_FILELIST, MAX_PATH);
// check to see if the download list has a version we like
dwVer = GetPrivateProfileInt(GENERAL_SECTION, VERSION_KEY, 0, _szFilelist);
if(dwVer < MIN_SUPPORTED_FILELIST_VER)
DeleteFilelist(_szFilelist);
WritePrivateProfileString(GENERAL_SECTION, VERSION_KEY, CURRENT_FILELIST_VER, _szFilelist);
// flush due to wierd stacker bug
WritePrivateProfileString(NULL, NULL, NULL, _szFilelist);
}
HRESULT CCifFile::Download()
{
CCifComponent *pcomp;
UINT i = 0;
HRESULT hr = NOERROR;
for(pcomp = _rpComp[i]; pcomp != 0 && SUCCEEDED(hr); pcomp = _rpComp[++i])
{
// if it is queued up and not downloded, download it
if((pcomp->GetInstallQueueState() == SETACTION_INSTALL) &&
(pcomp->IsComponentDownloaded() == S_FALSE) )
{
hr = pcomp->Download();
if(FAILED(hr) && _pInsEng->IgnoreDownloadError() && hr != E_ABORT)
hr = NOERROR;
if(SUCCEEDED(hr))
hr = _pInsEng->CheckForContinue();
}
}
return hr;
}
HRESULT CCifFile::Install(BOOL *pfOneInstalled)
{
CCifComponent *pcomp;
UINT i = 0;
*pfOneInstalled = FALSE;
HRESULT hr = NOERROR;
for(pcomp = _rpComp[i]; (pcomp != 0) && SUCCEEDED(hr); pcomp = _rpComp[++i])
{
// if it is queued up and not downloded, download it
if(pcomp->GetInstallQueueState() == SETACTION_INSTALL)
{
hr = pcomp->Install();
if(SUCCEEDED(hr))
*pfOneInstalled = TRUE;
if(hr != E_ABORT)
hr = NOERROR;
if(SUCCEEDED(hr))
hr = _pInsEng->CheckForContinue();
}
}
return hr;
}
HRESULT CCifFile::_ExtractDetDlls( LPCSTR pszCab, LPCSTR pszPath )
{
char szDetDlls[MAX_PATH];
char szLogBuf[MAX_PATH*2];
char szBuf[64];
UINT i = 0;
LPSTR pszTmp;
HRESULT hr = NOERROR;
// check if we need to extract & copy the detection dlls
if (SUCCEEDED(GetDetDlls(szDetDlls, sizeof(szDetDlls))))
{
while(SUCCEEDED(hr) && GetStringField(szDetDlls, i++, szBuf, sizeof(szBuf)))
{
if(SUCCEEDED(ExtractFiles(pszCab, pszPath, 0, szBuf, NULL, 0)))
{
wsprintf(szLogBuf, "Extract DetDll path:%s file:%s\r\n",pszPath, szBuf );
_pInsEng->WriteToLog(szLogBuf, TRUE);
}
else
{
wsprintf(szLogBuf, "Extract DetDll:%s from: %s\r\n", szBuf, pszCab);
_pInsEng->WriteToLog(szLogBuf, TRUE);
hr = E_FAIL;
}
}
}
return hr;
}
HRESULT CCifFile::_CopyDetDlls( LPCSTR pszPath )
{
char szDetDlls[MAX_PATH];
char szSrcFile[MAX_PATH];
char szDestFile[MAX_PATH];
char szLogBuf[MAX_PATH*2];
char szBuf[64];
UINT i = 0;
LPSTR pszTmp;
// check if we need to extract & copy the detection dlls
if (SUCCEEDED(GetDetDlls(szDetDlls, sizeof(szDetDlls))))
{
lstrcpy(szDestFile, _szCifPath);
GetParentDir(szDestFile);
pszTmp = szDestFile + lstrlen(szDestFile);
while(GetStringField(szDetDlls, i++, szBuf, sizeof(szBuf)))
{
lstrcpy(szSrcFile, pszPath);
AddPath(szSrcFile, szBuf);
*pszTmp = 0;
AddPath(szDestFile, szBuf);
CopyFile(szSrcFile, szDestFile, FALSE);
wsprintf(szLogBuf, "Copy DetDll fr:%s to:%s\r\n", szSrcFile, szDestFile);
_pInsEng->WriteToLog(szLogBuf, TRUE);
}
return NOERROR;
}
else
return E_FAIL;
}
HRESULT CCifFile::DownloadCifFile(LPCSTR pszUrl, LPCSTR pszCif)
{
HRESULT hr;
char szTempfile[MAX_PATH];
char szDownldfile[MAX_PATH];
char szPath[MAX_PATH];
_pInsEng->AddRef();
_pInsEng->OnEngineStatusChange(ENGINESTATUS_LOADING, 0);
CDownloader *pDL = _pInsEng->GetDownloader();
if(!pDL)
return E_UNEXPECTED;
hr = pDL->SetupDownload(pszUrl, NULL, 0, NULL);
szPath[0] = 0;
if(SUCCEEDED(hr))
hr = pDL->DoDownload(szDownldfile, sizeof(szDownldfile));
if(SUCCEEDED(hr))
{
hr = ::CheckTrustEx(pszUrl, szDownldfile, _pInsEng->GetHWND(), FALSE, NULL);
if (hr == S_FALSE)
hr = TRUST_E_FAIL;
// For compat reasons, we need to copy the cif cab into the download dir
if(SUCCEEDED(hr))
{
lstrcpy(szPath, _szDLDir);
SafeAddPath(szPath, ParseURLA(pszUrl), sizeof(szPath));
CopyFile(szDownldfile, szPath, FALSE);
}
lstrcpy(szPath, szDownldfile);
GetParentDir(szPath);
}
if(SUCCEEDED(hr))
hr=ExtractFiles(szDownldfile, szPath, 0, pszCif, NULL, 0);
if(SUCCEEDED(hr))
{
//BUGBUG: we should validate cif we got somehow!
// if we already have a cif, copy what we need over old cif, delete temp now
if(_rpComp)
{
// Dest
lstrcpy(szTempfile, _szCifPath);
GetParentDir(szTempfile);
AddPath(szTempfile, pszCif);
// source
SafeAddPath(szPath, pszCif, sizeof(szPath));
// copy to old one
CopyFile(szPath, szTempfile, FALSE);
hr = SetCifFile(szTempfile, FALSE); // read only version
GetParentDir(szPath);
// check if we need to extract & copy the detection dlls
if (SUCCEEDED(hr))
{
if(SUCCEEDED(hr =_ExtractDetDlls(szDownldfile,szPath)))
_CopyDetDlls(szPath);
}
DelNode(szPath, 0);
}
else
{
// new cif, use it in place in temp dir, mark temp dir to clean up
_fCleanDir = TRUE;
SafeAddPath(szPath, pszCif, sizeof(szPath));
hr = SetCifFile(szPath, FALSE); // read only version
if (SUCCEEDED(hr))
{
GetParentDir(szPath);
hr =_ExtractDetDlls(szDownldfile,szPath);
}
}
}
else
{
// cleanup now
if(szPath[0] != 0)
DelNode(szPath, 0);
}
_pInsEng->OnEngineStatusChange(SUCCEEDED(hr) ? ENGINESTATUS_READY : ENGINESTATUS_NOTREADY, hr);
// we are done; release the install engine
_pInsEng->Release();
return hr;
}
HRESULT CCifFile::_FindCifComponent(LPCSTR pszID, CCifComponent **p)
{
CCifComponent *pcomp;
UINT i = 0;
*p = 0;
if(_rpComp)
{
for(pcomp = _rpComp[i]; pcomp != 0; pcomp = _rpComp[++i])
if(pcomp->IsID(pszID))
{
*p = pcomp;
return NOERROR;
}
}
return E_FAIL;
}
void CCifFile::MarkCriticalComponents(CCifComponent *pOwner)
{
char szID[MAX_ID_LENGTH];
UINT j;
CCifComponent *pComp;
for(j = 0;SUCCEEDED(pOwner->GetTreatAsOneComponents(j, szID, sizeof(szID))); j++)
{
if(SUCCEEDED(_FindCifComponent(szID, &pComp)))
{
if(pComp->GetInstallQueueState() == SETACTION_INSTALL)
{
if(_pLastCriticalComp == NULL)
_pLastCriticalComp = pComp;
else
{
UINT i = 0;
CCifComponent *ptemp;
for(ptemp = _rpComp[i]; ptemp != 0 && ptemp != _pLastCriticalComp && ptemp != pComp ; ptemp = _rpComp[++i]);
if(ptemp == _pLastCriticalComp)
_pLastCriticalComp = pComp;
}
}
}
}
}
void CCifFile::RemoveFromCriticalComponents(CCifComponent *pComp)
{
if(_pLastCriticalComp == pComp)
_pLastCriticalComp = NULL;
}
DWORD WINAPI DownloadCifFile(LPVOID pv)
{
SETCIFARGS *p = (SETCIFARGS *) pv;
p->pCif->DownloadCifFile(p->szUrl, p->szCif);
delete p;
return 0;
}
CCifRWFile::CCifRWFile() : CCifFile()
{
_cCompUnused = 0;
_cGroupUnused = 0;
_cModeUnused = 0;
}
CCifRWFile::~CCifRWFile()
{
// flus out the cif file
WritePrivateProfileString( NULL, NULL, NULL, _szCifPath );
if(_rpRWGroup)
{
for ( UINT i=0; i<=_cGroup; i++)
delete(_rpRWGroup[i]);
free(_rpRWGroup);
}
if(_rpRWComp)
{
for ( UINT i=0; i<=_cComp; i++)
delete(_rpRWComp[i]);
free(_rpRWComp);
}
if(_rpRWMode)
{
for ( UINT i=0; i<=_cMode; i++)
delete(_rpRWMode[i]);
free(_rpRWMode);
}
}
// ICifRWFile implementation
// wrapper of the CCifFile functions
STDMETHODIMP CCifRWFile::QueryInterface(REFIID riid, LPVOID * ppvObj)
{
return (CCifFile::QueryInterface(riid, ppvObj));
}
STDMETHODIMP_(ULONG) CCifRWFile::AddRef()
{
return(_cRef++);
}
STDMETHODIMP_(ULONG) CCifRWFile::Release()
{
ULONG temp = --_cRef;
if(temp == 0)
delete this;
return temp;
}
STDMETHODIMP CCifRWFile::EnumComponents(IEnumCifComponents **pp, DWORD dwFilter, LPVOID pv)
{
CCifComponentEnum *pce;
HRESULT hr = E_FAIL;
*pp = 0;
pce = new CCifComponentEnum((CCifComponent **)_rpRWComp, dwFilter, PARENTTYPE_CIF, NULL);
if(pce)
{
*pp = (IEnumCifComponents *) pce;
(*pp)->AddRef();
hr = NOERROR;
}
return hr;
}
STDMETHODIMP CCifRWFile::FindComponent(LPCSTR pszID, ICifComponent **p)
{
CCifRWComponent *pcomp;
UINT i = 0;
*p = 0;
if(_rpRWComp)
{
for(pcomp = _rpRWComp[i]; pcomp != 0; pcomp = _rpRWComp[++i])
if(pcomp->IsID(pszID))
{
CCifComponent *ptmp;
ptmp = (CCifComponent *)pcomp;
*p = (ICifComponent *) ptmp;
return NOERROR;
}
}
return E_FAIL;
}
STDMETHODIMP CCifRWFile::EnumGroups(IEnumCifGroups **pp, DWORD dwFilter, LPVOID pv)
{
CCifGroupEnum *pge;
HRESULT hr = E_FAIL;
*pp = 0;
pge = new CCifGroupEnum((CCifGroup **)_rpRWGroup, dwFilter);
if(pge)
{
*pp = (IEnumCifGroups *) pge;
(*pp)->AddRef();
hr = NOERROR;
}
return hr;
}
STDMETHODIMP CCifRWFile::FindGroup(LPCSTR pszID, ICifGroup **p)
{
CCifRWGroup *pgrp;
UINT i = 0;
*p = 0;
if(_rpRWGroup)
{
for(pgrp = _rpRWGroup[i]; pgrp != 0; pgrp = _rpRWGroup[++i])
if(pgrp->IsID(pszID))
{
CCifGroup *ptmp;
ptmp = (CCifGroup *)pgrp;
*p = (ICifGroup *) ptmp;
return NOERROR;
}
}
return E_FAIL;
}
STDMETHODIMP CCifRWFile::EnumModes(IEnumCifModes **pp, DWORD dwFilter, LPVOID pv)
{
CCifModeEnum *pme;
HRESULT hr = E_FAIL;
*pp = 0;
pme = new CCifModeEnum((CCifMode **)_rpRWMode, dwFilter);
if(pme)
{
*pp = (IEnumCifModes *) pme;
(*pp)->AddRef();
hr = NOERROR;
}
return hr;
}
STDMETHODIMP CCifRWFile::FindMode(LPCSTR pszID, ICifMode **p)
{
CCifRWMode *pmode;
UINT i = 0;
*p = 0;
if(_rpRWMode)
{
for(pmode = _rpRWMode[i]; pmode != 0; pmode = _rpRWMode[++i])
if(pmode->IsID(pszID))
{
CCifMode *ptmp;
ptmp = (CCifMode *)pmode;
*p = (ICifMode *) ptmp;
return NOERROR;
}
}
return E_FAIL;
}
STDMETHODIMP CCifRWFile::GetDescription(LPSTR pszDesc, DWORD dwSize)
{
return(CCifFile::GetDescription(pszDesc, dwSize));
}
STDMETHODIMP CCifRWFile::GetDetDlls(LPSTR pszDlls, DWORD dwSize)
{
return(CCifFile::GetDetDlls(pszDlls, dwSize));
}
STDMETHODIMP CCifRWFile::SetDescription(LPCSTR pszDesc)
{
return(WriteTokenizeString(_szCifPath, "Version", DISPLAYNAME_KEY, pszDesc));
}
STDMETHODIMP CCifRWFile::CreateComponent(LPCSTR pszID, ICifRWComponent **p)
{
CCifRWComponent *prwcomp;
CCifRWComponent **ppRWCompPreFail;
BOOL bFound = FALSE;
UINT i = 0;
*p = 0;
for(prwcomp = _rpRWComp[i]; prwcomp != 0; prwcomp = _rpRWComp[++i])
{
if(prwcomp->IsID(pszID))
{
*p = (ICifRWComponent*)prwcomp;
bFound = TRUE;
break;
}
}
// create the new component
if (!bFound)
{
prwcomp = new CCifRWComponent(pszID, this);
if (!prwcomp)
return E_OUTOFMEMORY;
// check to see if we need to grow the array size
if (_cCompUnused <= 0)
{
// growing the array size to acomdate the new component
ppRWCompPreFail = _rpRWComp;
#pragma prefast(suppress: 308, "PREfast noise - pointer was saved before")
_rpRWComp = (CCifRWComponent **) realloc(_rpRWComp, sizeof(CCifRWComponent **)*(i+10));
if (_rpRWComp)
{
_cCompUnused = 9; // terminator used up one slot and the new comp use the one, s
}
else
{
if(ppRWCompPreFail)
{
for ( UINT i=0; i<=_cComp; i++)
delete(ppRWCompPreFail[i]);
free(ppRWCompPreFail);
}
return E_OUTOFMEMORY;
}
}
_rpRWComp[i] = prwcomp;
_rpRWComp[i+1] = 0;
_cCompUnused--;
_cComp++;
*p = (ICifRWComponent*)prwcomp;
WritePrivateProfileString(pszID, ENTRYTYPE_KEY, ENTRYTYPE_COMP, _szCifPath);
}
return NOERROR;
}
STDMETHODIMP CCifRWFile::CreateGroup(LPCSTR pszID, ICifRWGroup **p)
{
CCifRWGroup *prwgroup;
CCifRWGroup **ppwgroupPreFail;
BOOL bFound = FALSE;
UINT i = 0;
*p = 0;
for(prwgroup = _rpRWGroup[i]; prwgroup != 0; prwgroup = _rpRWGroup[++i])
{
if(prwgroup->IsID(pszID))
{
*p = (ICifRWGroup *)prwgroup;
bFound = TRUE;
break;
}
}
// create the new component
if (!bFound)
{
prwgroup = new CCifRWGroup(pszID, i+1, this);
if (!prwgroup)
return E_OUTOFMEMORY;
// check to see if we need to grow the array size
if (_cGroupUnused <= 0)
{
ppwgroupPreFail = _rpRWGroup;
// growing the array size to acomdate the new component
#pragma prefast(suppress: 308, "PREfast noise - pointer was saved before")
_rpRWGroup = (CCifRWGroup **) realloc(_rpRWGroup, sizeof(CCifRWGroup **)*(i+10));
if (_rpRWGroup)
{
_cGroupUnused = 9;
}
else
{
if(ppwgroupPreFail)
{
for ( UINT i=0; i<=_cGroup; i++)
delete(ppwgroupPreFail[i]);
free(ppwgroupPreFail);
}
return E_OUTOFMEMORY;
}
}
_rpRWGroup[i] = prwgroup;
_rpRWGroup[i+1] = 0;
_cGroupUnused--;
_cGroup++;
*p = (ICifRWGroup *)prwgroup;
WritePrivateProfileString(pszID, ENTRYTYPE_KEY, ENTRYTYPE_GROUP, _szCifPath);
}
return NOERROR;
}
STDMETHODIMP CCifRWFile::CreateMode(LPCSTR pszID, ICifRWMode **p)
{
CCifRWMode *prwmode;
CCifRWMode **prwmodePreFail;
BOOL bFound = FALSE;
UINT i = 0;
*p = 0;
for(prwmode = _rpRWMode[i]; prwmode != 0; prwmode = _rpRWMode[++i])
{
if(prwmode->IsID(pszID))
{
*p = (ICifRWMode *)prwmode;
bFound = TRUE;
break;
}
}
// create the new component
if (!bFound)
{
prwmode = new CCifRWMode(pszID, this);
if (!prwmode)
return E_OUTOFMEMORY;
// check to see if we need to grow the array size
if (_cModeUnused <= 0)
{
prwmodePreFail = _rpRWMode;
// growing the array size to acomdate the new component
#pragma prefast(suppress: 308, "PREfast noise - pointer was saved before")
_rpRWMode = (CCifRWMode **) realloc(_rpRWMode, sizeof(CCifRWMode **)*(i+10));
if (_rpRWMode)
{
_cModeUnused = 9;
}
else
{
if(prwmodePreFail)
{
for ( UINT i=0; i<=_cMode; i++)
delete(prwmodePreFail[i]);
free(prwmodePreFail);
}
return E_OUTOFMEMORY;
}
}
_rpRWMode[i] = prwmode;
_rpRWMode[i+1] = 0;
_cModeUnused--;
_cMode++;
*p = (ICifRWMode *)prwmode;
WritePrivateProfileString(pszID, ENTRYTYPE_KEY, ENTRYTYPE_MODE, _szCifPath);
}
return NOERROR;
}
STDMETHODIMP CCifRWFile::DeleteComponent(LPCSTR pszID)
{
CCifRWComponent *prwcomp;
BOOL bFound = FALSE;
UINT i = 0;
for(prwcomp = _rpRWComp[i]; prwcomp != 0; prwcomp = _rpRWComp[++i])
{
if(prwcomp->IsID(pszID))
{
bFound = TRUE;
break;
}
}
// Delete the component
if (bFound)
{
delete(prwcomp);
for ( UINT j=i+1; j<=_cComp; j++)
{
_rpRWComp[i] = _rpRWComp[j];
i= j;
}
_rpRWComp[i] = 0;
_cCompUnused++;
_cComp--;
}
return (WritePrivateProfileString(pszID, NULL, NULL, _szCifPath)?NOERROR:E_FAIL);
}
STDMETHODIMP CCifRWFile::DeleteGroup(LPCSTR pszID)
{
CCifRWGroup *prwgroup;
BOOL bFound = FALSE;
UINT i = 0;
for(prwgroup = _rpRWGroup[i]; prwgroup != 0; prwgroup = _rpRWGroup[++i])
{
if(prwgroup->IsID(pszID))
{
bFound = TRUE;
break;
}
}
// Delete the Group
if (bFound)
{
delete(prwgroup);
for (UINT j=i+1; j<=_cGroup; j++)
{
_rpRWGroup[i] = _rpRWGroup[j];
i= j;
}
_rpRWGroup[i] = 0;
_cGroupUnused++;
_cGroup--;
}
return (WritePrivateProfileString(pszID, NULL, NULL, _szCifPath)?NOERROR:E_FAIL);
}
STDMETHODIMP CCifRWFile::DeleteMode(LPCSTR pszID)
{
CCifRWMode *prwmode;
BOOL bFound = FALSE;
UINT i = 0;
for(prwmode = _rpRWMode[i]; prwmode != 0; prwmode = _rpRWMode[++i])
{
if(prwmode->IsID(pszID))
{
bFound = TRUE;
break;
}
}
// Delete the Mode
if (bFound)
{
delete(prwmode);
for (UINT j=i+1; j<=_cMode; j++)
{
_rpRWMode[i] = _rpRWMode[j];
i= j;
}
_rpRWMode[i] = 0;
_cModeUnused++;
_cMode--;
}
return (WritePrivateProfileString(pszID, NULL, NULL, _szCifPath)?NOERROR:E_FAIL);
}
STDMETHODIMP CCifRWFile::Flush()
{
WritePrivateProfileString(NULL, NULL, NULL, _szCifPath);
return NOERROR;
}