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.
 
 
 
 
 
 

339 lines
7.4 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 2000
//
// File: listfile.cpp
//
//
//--------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "listfile.h"
const TCHAR g_szPin[] = TEXT("Pin");
const TCHAR g_szUnpin[] = TEXT("Unpin");
const TCHAR g_szDefault[] = TEXT("Default");
bool
CDblNulStrIter::Next(
LPCTSTR *ppsz
) const
{
ASSERT(NULL != ppsz);
if (m_pszCurrent && *m_pszCurrent)
{
*ppsz = m_pszCurrent;
while(*m_pszCurrent++)
NULL;
return true;
}
return false;
};
//
// Class used to represent a double-nul terminated list of strings.
// Simplifies counting and enumerating substrings.
//
class CDblNulStr
{
public:
CDblNulStr(LPCTSTR psz)
: m_pszStart(psz) { }
DWORD StringCount(void) const;
CDblNulStrIter GetIter(void) const
{ return CDblNulStrIter(m_pszStart); }
private:
LPCTSTR m_pszStart;
};
DWORD
CDblNulStr::StringCount(
void
) const
{
ASSERT(NULL != m_pszStart);
LPCWSTR psz = m_pszStart;
DWORD n = 0;
while(*psz++)
{
n++;
while(*psz++)
NULL;
}
return n;
}
CListFile::CListFile(
LPCTSTR pszFile
) : m_pszFilesToPin(NULL),
m_pszFilesToUnpin(NULL),
m_pszFilesDefault(NULL)
{
lstrcpyn(m_szFile, pszFile, ARRAYSIZE(m_szFile));
}
CListFile::~CListFile(
void
)
{
if (NULL != m_pszFilesToPin)
{
LocalFree(m_pszFilesToPin);
}
if (NULL != m_pszFilesToUnpin)
{
LocalFree(m_pszFilesToUnpin);
}
if (NULL != m_pszFilesDefault)
{
LocalFree(m_pszFilesDefault);
}
}
HRESULT
CListFile::GetFilesToPin(
CDblNulStrIter *pIter
)
{
HRESULT hr = S_OK;
if (NULL == m_pszFilesToPin)
{
DWORD dwResult = _ReadPathsToPin(&m_pszFilesToPin);
if (ERROR_SUCCESS != dwResult)
{
hr = HRESULT_FROM_WIN32(dwResult);
}
}
if (SUCCEEDED(hr))
{
*pIter = CDblNulStrIter(m_pszFilesToPin);
}
return hr;
}
HRESULT
CListFile::GetFilesToUnpin(
CDblNulStrIter *pIter
)
{
HRESULT hr = S_OK;
if (NULL == m_pszFilesToUnpin)
{
DWORD dwResult = _ReadPathsToUnpin(&m_pszFilesToUnpin);
if (ERROR_SUCCESS != dwResult)
{
hr = HRESULT_FROM_WIN32(dwResult);
}
}
if (SUCCEEDED(hr))
{
*pIter = CDblNulStrIter(m_pszFilesToUnpin);
}
return hr;
}
HRESULT
CListFile::GetFilesDefault(
CDblNulStrIter *pIter
)
{
HRESULT hr = S_OK;
if (NULL == m_pszFilesDefault)
{
DWORD dwResult = _ReadPathsDefault(&m_pszFilesDefault);
if (ERROR_SUCCESS != dwResult)
{
hr = HRESULT_FROM_WIN32(dwResult);
}
}
if (SUCCEEDED(hr))
{
*pIter = CDblNulStrIter(m_pszFilesDefault);
}
return hr;
}
//
// Load a value string from an INI file. Automatically
// grows buffer to necessary length. Returned string must be freed
// using LocalFree().
//
DWORD
CListFile::_ReadString(
LPCTSTR pszAppName, // May be NULL.
LPCTSTR pszKeyName, // May be NULL.
LPCTSTR pszDefault,
LPTSTR *ppszResult
)
{
ASSERT(NULL != pszDefault);
ASSERT(NULL != ppszResult);
LPTSTR pszValue = NULL;
const DWORD CCHGROW = MAX_PATH;
DWORD cchValue = CCHGROW;
DWORD dwResult = ERROR_SUCCESS;
do
{
pszValue = (LPTSTR)LocalAlloc(LPTR, cchValue * sizeof(*pszValue));
if (NULL == pszValue)
{
dwResult = ERROR_INSUFFICIENT_BUFFER;
}
else
{
DWORD cchCopied = GetPrivateProfileString(pszAppName,
pszKeyName,
pszDefault,
pszValue,
cchValue,
m_szFile);
if (((NULL == pszAppName || NULL == pszKeyName) && (cchValue - 2) == cchCopied) ||
((NULL != pszAppName && NULL != pszKeyName) && (cchValue - 1) == cchCopied))
{
//
// Buffer too small. Reallocate and try again.
//
cchValue += CCHGROW;
LocalFree(pszValue);
pszValue = NULL;
}
}
}
while(NULL == pszValue && ERROR_SUCCESS == dwResult);
if (ERROR_SUCCESS == dwResult)
{
//
// Don't forget, this data can be a double-nul terminated string.
// Don't try to copy it to an exact-sized buffer using strcpy.
//
ASSERT(NULL != pszValue);
*ppszResult = pszValue;
}
return dwResult;
}
//
// Read all of the item names in a given INI file section.
// The names are returned in a double-nul term string.
// Caller must free returned string using LocalFree.
// *pbEmpty is set to true if no items were found.
//
DWORD
CListFile::_ReadSectionItemNames(
LPCTSTR pszSection,
LPTSTR *ppszItemNames,
bool *pbEmpty // [optional] Default == NULL.
)
{
bool bEmpty = false;
LPTSTR pszItemNames;
DWORD dwResult = _ReadString(pszSection, NULL, TEXT(""), &pszItemNames);
if (ERROR_SUCCESS == dwResult && TEXT('\0') == *pszItemNames)
{
LocalFree(pszItemNames);
bEmpty = true;
}
else
{
*ppszItemNames = pszItemNames;
}
if (NULL != pbEmpty)
{
*pbEmpty = bEmpty;
}
return dwResult;
}
//
// Read a single item value from an INI file.
// Caller must free returned string using LocalFree.
//
DWORD
CListFile::_ReadItemValue(
LPCTSTR pszSection,
LPCTSTR pszItemName,
LPTSTR *ppszItemValue
)
{
LPTSTR pszValue;
DWORD dwResult = _ReadString(pszSection, pszItemName, TEXT(""), &pszValue);
if (ERROR_SUCCESS == dwResult && TEXT('\0') == *pszValue)
{
LocalFree(pszValue);
dwResult = ERROR_INVALID_DATA;
}
else
{
*ppszItemValue = pszValue;
}
return dwResult;
}
//
// Read the names of all paths in the [Pin] section.
// Caller must free returned string using LocalFree
//
DWORD
CListFile::_ReadPathsToPin(
LPTSTR *ppszNames,
bool *pbEmpty
)
{
return _ReadSectionItemNames(g_szPin, ppszNames, pbEmpty);
}
//
// Read the names of all paths in the [Unpin] section.
// Caller must free returned string using LocalFree
//
DWORD
CListFile::_ReadPathsToUnpin(
LPWSTR *ppszNames,
bool *pbEmpty
)
{
return _ReadSectionItemNames(g_szUnpin, ppszNames, pbEmpty);
}
//
// Read the names of all paths in the [Default] section.
// Caller must free returned string using LocalFree
//
DWORD
CListFile::_ReadPathsDefault(
LPWSTR *ppszNames,
bool *pbEmpty
)
{
return _ReadSectionItemNames(g_szDefault, ppszNames, pbEmpty);
}