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.
 
 
 
 
 
 

450 lines
11 KiB

#include "stdafx.h"
#include "enumStorage.h"
#include <stdio.h>
//#include "findleak.h"
//DECLARE_THIS_FILE;
//
// Construction/Destruction
//
CEnumStorage::CEnumStorage()
{
m_rgFindData = NULL;
m_iCurItem = 0;
m_cItems = 0;
m_fIsDevice = FALSE;
memset( m_szStartPath, 0, sizeof(m_szStartPath) );
}
HRESULT CEnumStorage::Init(LPCWSTR startPath, BOOL fIsDevice, IMDSPDevice *pDevice)
{
HRESULT hr = S_OK;
CE_FIND_DATA *rgFindData = NULL;
WCHAR szSearchPath[MAX_PATH];
DWORD cItems = 0;
DWORD cStorageCardItems = 0;
DWORD i = 0;
BOOL fIsRootDevice = FALSE;
if( NULL == pDevice ||
NULL == startPath )
{
return( E_INVALIDARG );
}
m_spDevice = pDevice;
m_fIsDevice = fIsDevice;
if( startPath[0] != L'\\' )
{
wcscpy( m_szStartPath, L"\\" );
hr = StringCbCatW(m_szStartPath, sizeof(m_szStartPath), startPath);
}
else
{
hr = StringCbCopyW(m_szStartPath, sizeof(m_szStartPath), startPath);
}
if (FAILED(hr))
{
return HRESULT_FROM_WIN32(HRESULT_CODE(hr)) ;
}
//
// Check for root!
//
fIsRootDevice = ( 0 == _wcsicmp( L"\\", m_szStartPath ) );
//
// Make SURE there is a "My Documents" directory so that Cyprus's default storage lookup
// stuff works properly
//
if( fIsDevice )
{
WCHAR szCreateDir[MAX_PATH];
if( fIsRootDevice )
{
hr = StringCbPrintfW(szCreateDir, sizeof(szCreateDir), L"\\%s", L"My Documents");
}
else
{
hr = StringCbPrintfW(szCreateDir, sizeof(szCreateDir), L"%s\\%s", m_szStartPath, L"My Documents");
}
if (FAILED(hr))
{
return HRESULT_FROM_WIN32(HRESULT_CODE(hr)) ;
}
CeCreateDirectory( szCreateDir, NULL );
}
if( !m_fIsDevice || // Are we a device at all?
(m_fIsDevice && !fIsRootDevice) ) // Are we a storage card?
{
if( !m_fIsDevice )
{
if( fIsRootDevice )
{
hr = StringCbPrintfW(szSearchPath, sizeof(szSearchPath), L"%s*.*", m_szStartPath );
}
else
{
hr = StringCbPrintfW (szSearchPath, sizeof(szSearchPath), L"%s\\*.*", m_szStartPath );
}
}
else
{
hr = StringCbCopyW(szSearchPath, sizeof(szSearchPath), m_szStartPath);
}
if (FAILED(hr))
{
return HRESULT_FROM_WIN32(HRESULT_CODE(hr)) ;
}
if( !CeFindAllFiles( szSearchPath,
FAF_ATTRIBUTES |
FAF_CREATION_TIME |
FAF_LASTACCESS_TIME |
FAF_LASTWRITE_TIME |
FAF_SIZE_HIGH |
FAF_SIZE_LOW |
FAF_OID |
FAF_NAME,
&cItems,
&rgFindData ) )
{
hr = HRESULT_FROM_WIN32( CeGetLastError() );
if( SUCCEEDED( hr ) )
{
hr = CeRapiGetError();
}
}
//
// if this is the CE device, then skip storage cards
//
if( SUCCEEDED( hr ) && fIsRootDevice )
{
for( i = 0; i < cItems; i ++ )
{
if( rgFindData[i].dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY )
{
cStorageCardItems++;
}
}
}
if( SUCCEEDED( hr ) )
{
m_rgFindData = new CE_FIND_DATA[cItems - cStorageCardItems];
if( NULL == m_rgFindData )
{
hr = E_OUTOFMEMORY;
}
else
{
if( fIsRootDevice )
{
m_cItems = 0;
for( i = 0; i < cItems; i++ )
{
if( !(rgFindData[i].dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) )
{
memcpy( &m_rgFindData[m_cItems], &rgFindData[i], sizeof(rgFindData[i]) );
m_cItems++;
}
}
}
else
{
m_cItems = cItems;
memcpy( m_rgFindData, rgFindData, cItems * sizeof(rgFindData[0]) );
}
}
if( rgFindData )
{
CeRapiFreeBuffer( rgFindData );
rgFindData = NULL;
}
//
// Since CE doesn't set the FILE_ATTRIBUTE_HAS_CHILDREN, then I have to do it myself
//
DWORD idxItems = m_cItems;
while( SUCCEEDED( hr ) && idxItems-- )
{
WCHAR szDirPath[MAX_PATH];
DWORD dirItems = 0;
if( !( m_rgFindData[idxItems].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
{
continue;
}
memset( szDirPath, 0, sizeof(szDirPath) );
if( !m_fIsDevice )
{
if( fIsRootDevice )
{
hr = StringCbPrintfW(szDirPath, sizeof(szDirPath), L"\\%s\\*.*", m_rgFindData[idxItems].cFileName );
}
else
{
hr = StringCbPrintfW(szDirPath, sizeof(szDirPath), L"%s\\%s\\*.*", m_szStartPath, m_rgFindData[idxItems].cFileName );
}
}
else
{
hr = StringCbPrintf(szDirPath, sizeof(szDirPath), L"%s\\*.*", m_szStartPath ); // , m_rgFindData[idxItems].cFileName );
}
if (FAILED(hr))
{
continue;
}
if( !CeFindAllFiles( szDirPath,
FAF_FOLDERS_ONLY,
&dirItems,
&rgFindData ) )
{
hr = HRESULT_FROM_WIN32( CeGetLastError() );
if( SUCCEEDED( hr ) )
{
hr = CeRapiGetError();
}
}
if( SUCCEEDED( hr ) )
{
if( 0 != dirItems &&
dirItems != cStorageCardItems )
{
m_rgFindData[idxItems].dwFileAttributes |= FILE_ATTRIBUTE_HAS_CHILDREN;
}
if( rgFindData )
{
CeRapiFreeBuffer( rgFindData );
rgFindData = NULL;
}
}
}
}
}
else
{
m_cItems = 1;
m_rgFindData = new CE_FIND_DATA[m_cItems];
if( NULL == m_rgFindData )
{
hr = E_OUTOFMEMORY;
}
if( SUCCEEDED( hr ) )
{
memset( &m_rgFindData[0], 0, sizeof(m_rgFindData[0]) );
if( fIsRootDevice )
{
//
// We must make up a date, and set attributes & name
//
if( SUCCEEDED( hr ) )
{
m_rgFindData[0].dwFileAttributes = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HAS_CHILDREN;
wcscpy(m_rgFindData[0].cFileName, L"\\");
GetSystemTimeAsFileTime( &m_rgFindData[0].ftCreationTime );
GetSystemTimeAsFileTime( &m_rgFindData[0].ftLastAccessTime );
GetSystemTimeAsFileTime( &m_rgFindData[0].ftLastWriteTime );
}
}
}
}
return( hr );
}
HRESULT CEnumStorage::Init(CEnumStorage *pCopy, IMDSPDevice *pDevice)
{
HRESULT hr = S_OK;
if( NULL == pCopy || NULL == pDevice)
{
return( E_INVALIDARG );
}
m_spDevice = pDevice;
m_cItems = pCopy->m_cItems;
m_iCurItem = pCopy->m_iCurItem;
wcsncpy(m_szStartPath, pCopy->m_szStartPath, sizeof(m_szStartPath)/sizeof(m_szStartPath[0]) - 1 );
m_rgFindData = new CE_FIND_DATA[ m_cItems ];
if( NULL == m_rgFindData )
{
hr = E_OUTOFMEMORY;
}
if( SUCCEEDED( hr ) )
{
memcpy(m_rgFindData, pCopy->m_rgFindData, m_cItems * sizeof(m_rgFindData[0]) );
}
return( hr );
}
void CEnumStorage::FinalRelease()
{
if( m_rgFindData )
{
delete [] m_rgFindData;
}
}
//
// IMDSPEnumStorage
//
STDMETHODIMP CEnumStorage::Next( ULONG celt, IMDSPStorage ** ppStorage, ULONG *pceltFetched )
{
ULONG celtFetched = 0;
HRESULT hr = S_OK;
ULONG i;
if( NULL == pceltFetched && celt != 1 )
{
return( E_INVALIDARG );
}
if( NULL == ppStorage )
{
return( E_POINTER );
}
for( i = 0; i < celt; i++ )
{
ppStorage[i] = NULL;
}
while( celtFetched != celt && SUCCEEDED( hr ) )
{
if( m_iCurItem >= m_cItems )
{
hr = S_FALSE;
break;
}
CComStorage *pNewStorage = NULL;
hr = CComStorage::CreateInstance( &pNewStorage );
if( SUCCEEDED( hr ) )
{
hr = pNewStorage->Init(&m_rgFindData[m_iCurItem], m_szStartPath, m_fIsDevice, m_spDevice);
}
if( SUCCEEDED( hr ) )
{
ppStorage[celtFetched] = pNewStorage;
ppStorage[celtFetched++]->AddRef();
m_iCurItem++;
}
}
if( FAILED(hr) )
{
while( celtFetched-- )
{
ppStorage[celtFetched]->Release();
ppStorage[celtFetched] = NULL;
m_iCurItem--;
}
celtFetched = 0;
}
if( NULL != pceltFetched )
{
*pceltFetched = celtFetched;
}
return( hr );
}
STDMETHODIMP CEnumStorage::Skip( ULONG celt, ULONG *pceltFetched )
{
ULONG celtSkipped = 0;
HRESULT hr = S_OK;
if( celt + m_iCurItem >= m_cItems )
{
celtSkipped = m_cItems - m_iCurItem;
m_iCurItem = m_cItems;
hr = S_FALSE;
}
else
{
celtSkipped = celt;
m_iCurItem += celt;
}
if( NULL != pceltFetched )
{
*pceltFetched = celtSkipped;
}
return( hr );
}
STDMETHODIMP CEnumStorage::Reset( void )
{
m_iCurItem = 0;
return( S_OK );
}
STDMETHODIMP CEnumStorage::Clone( IMDSPEnumStorage ** ppStorage )
{
CComEnumStorage *pNewEnum;
CComPtr<IMDSPEnumStorage> spEnum;
HRESULT hr = S_OK;
if( SUCCEEDED(hr) )
{
hr = CComEnumStorage ::CreateInstance(&pNewEnum);
spEnum = pNewEnum;
}
if( SUCCEEDED(hr) )
{
hr = pNewEnum->Init( this , m_spDevice );
}
if( SUCCEEDED(hr) )
{
*ppStorage = spEnum;
spEnum.Detach();
}
return( hr );
}