|
|
//+-------------------------------------------------------------------------
//
// 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); }
|