738 lines
14 KiB
C++
738 lines
14 KiB
C++
//
|
|
// Copyright 1997 - Microsoft
|
|
|
|
//
|
|
// CENUMSIF.CPP - Handles enumerating OSes and Tools SIFs from DS
|
|
//
|
|
|
|
#include "pch.h"
|
|
|
|
#include "cenumsif.h"
|
|
|
|
DEFINE_MODULE("IMADMUI")
|
|
DEFINE_THISCLASS("CEnumIMSIFs")
|
|
#define THISCLASS CEnumIMSIFs
|
|
#define LPTHISCLASS LPENUMSIFS
|
|
|
|
// ************************************************************************
|
|
//
|
|
// Constructor / Destructor
|
|
//
|
|
// ************************************************************************
|
|
|
|
//
|
|
// CreateInstance()
|
|
//
|
|
LPVOID
|
|
CEnumIMSIFs_CreateInstance(
|
|
LPWSTR pszEnumPath,
|
|
LPWSTR pszAttribute,
|
|
DWORD dwFlags,
|
|
IADs * pads )
|
|
{
|
|
TraceFunc( "CEnumIMSIFs_CreateInstance()\n" );
|
|
|
|
LPTHISCLASS lpcc = new THISCLASS( );
|
|
HRESULT hr = THR( lpcc->Init( pszEnumPath, pszAttribute, dwFlags, pads ) );
|
|
|
|
if ( hr )
|
|
{
|
|
delete lpcc;
|
|
RETURN(NULL);
|
|
}
|
|
|
|
RETURN((LPVOID) lpcc);
|
|
}
|
|
|
|
//
|
|
// Constructor
|
|
//
|
|
THISCLASS::THISCLASS( )
|
|
{
|
|
TraceClsFunc( "CEnumIMSIFs()\n" );
|
|
|
|
InterlockIncrement( g_cObjects );
|
|
|
|
TraceFuncExit();
|
|
}
|
|
|
|
//
|
|
// Init()
|
|
//
|
|
STDMETHODIMP
|
|
THISCLASS::Init(
|
|
LPWSTR pszEnumPath,
|
|
LPWSTR pszAttribute,
|
|
DWORD dwFlags,
|
|
IADs * pads )
|
|
{
|
|
TraceClsFunc( "Init()\n" );
|
|
|
|
HRESULT hr = S_OK;
|
|
LPWSTR psz;
|
|
VARIANT var;
|
|
|
|
VariantInit( &var );
|
|
|
|
// IUnknown stuff
|
|
BEGIN_QITABLE_IMP( CEnumIMSIFs, IEnumIMSIFs );
|
|
QITABLE_IMP( IEnumIMSIFs );
|
|
END_QITABLE_IMP( CEnumIMSIFs );
|
|
Assert( _cRef == 0);
|
|
AddRef( );
|
|
|
|
// Private Members
|
|
Assert( _iIndex == 0 );
|
|
Assert( !_pszLanguage );
|
|
Assert( !_pszOS );
|
|
Assert( !_pszArchitecture );
|
|
Assert( !_pszSIF );
|
|
|
|
pads->AddRef( );
|
|
_pads = pads;
|
|
|
|
hr = THR( _pads->Get( NETBOOTSERVER, &var ) );
|
|
if (hr)
|
|
goto Error;
|
|
|
|
psz = V_BSTR( &var );
|
|
hr = THR( DNtoFQDN( psz, &_pszServerName ) );
|
|
if (hr)
|
|
goto Error;
|
|
|
|
_dwFlags = dwFlags;
|
|
|
|
_pszAttribute = (LPWSTR) TraceStrDup( pszAttribute );
|
|
if ( !_pszAttribute )
|
|
{
|
|
hr = THR(E_OUTOFMEMORY);
|
|
goto Error;
|
|
}
|
|
|
|
_pszEnumPath = (LPWSTR) TraceStrDup( pszEnumPath );
|
|
if ( !_pszEnumPath )
|
|
{
|
|
hr = THR(E_OUTOFMEMORY);
|
|
goto Error;
|
|
}
|
|
|
|
_hLanguage = INVALID_HANDLE_VALUE;
|
|
_hOS = INVALID_HANDLE_VALUE;
|
|
_hArchitecture = INVALID_HANDLE_VALUE;
|
|
_hSIF = INVALID_HANDLE_VALUE;
|
|
|
|
Error: // Destructor will handle cleanup
|
|
VariantClear( &var );
|
|
|
|
HRETURN(hr);
|
|
}
|
|
|
|
//
|
|
// Destructor
|
|
//
|
|
THISCLASS::~THISCLASS( )
|
|
{
|
|
TraceClsFunc( "~CEnumIMSIFs()\n" );
|
|
|
|
// Private Members
|
|
if ( _pads )
|
|
{
|
|
// Commit any changes before we release
|
|
THR( _pads->SetInfo( ) );
|
|
_pads->Release( );
|
|
}
|
|
|
|
if ( _pszAttribute )
|
|
TraceFree( _pszAttribute );
|
|
|
|
if ( _pszEnumPath )
|
|
TraceFree( _pszEnumPath );
|
|
|
|
if ( _hLanguage != INVALID_HANDLE_VALUE )
|
|
FindClose( _hLanguage );
|
|
|
|
if ( _hOS != INVALID_HANDLE_VALUE )
|
|
FindClose( _hOS );
|
|
|
|
if ( _hSIF != INVALID_HANDLE_VALUE )
|
|
FindClose( _hSIF );
|
|
|
|
if ( _pszLanguage )
|
|
TraceFree( _pszLanguage );
|
|
|
|
if ( _pszOS )
|
|
TraceFree( _pszOS );
|
|
|
|
if ( _pszSIF )
|
|
TraceFree( _pszSIF );
|
|
|
|
if ( _pszServerName )
|
|
TraceFree( _pszServerName );
|
|
|
|
InterlockDecrement( g_cObjects );
|
|
|
|
TraceFuncExit();
|
|
};
|
|
|
|
// ************************************************************************
|
|
//
|
|
// IUnknown
|
|
//
|
|
// ************************************************************************
|
|
|
|
//
|
|
// QueryInterface()
|
|
//
|
|
STDMETHODIMP
|
|
THISCLASS::QueryInterface(
|
|
REFIID riid,
|
|
LPVOID *ppv )
|
|
{
|
|
TraceClsFunc( "[IUnknown] QueryInterface( riid=" );
|
|
|
|
HRESULT hr = ::QueryInterface( this, _QITable, riid, ppv );
|
|
|
|
QIRETURN( hr, riid );
|
|
}
|
|
|
|
//
|
|
// AddRef()
|
|
//
|
|
STDMETHODIMP_(ULONG)
|
|
THISCLASS::AddRef( void )
|
|
{
|
|
TraceClsFunc( "[IUnknown] AddRef( )\n" );
|
|
|
|
InterlockIncrement( _cRef );
|
|
|
|
RETURN(_cRef);
|
|
}
|
|
|
|
//
|
|
// Release()
|
|
//
|
|
STDMETHODIMP_(ULONG)
|
|
THISCLASS::Release( void )
|
|
{
|
|
TraceClsFunc( "[IUnknown] Release( )\n" );
|
|
|
|
InterlockDecrement( _cRef );
|
|
|
|
if ( _cRef )
|
|
RETURN(_cRef);
|
|
|
|
TraceDo( delete this );
|
|
|
|
RETURN(0);
|
|
}
|
|
|
|
|
|
// ************************************************************************
|
|
//
|
|
// IEnumIMSIFs
|
|
//
|
|
// ************************************************************************
|
|
|
|
//
|
|
// Next( )
|
|
//
|
|
HRESULT
|
|
THISCLASS::Next(
|
|
ULONG celt,
|
|
LPWSTR * rgelt,
|
|
ULONG * pceltFetched )
|
|
{
|
|
TraceClsFunc( "[IEnumIMSIFs] Next( ... )\n" );
|
|
|
|
if ( !rgelt )
|
|
RRETURN(E_POINTER);
|
|
|
|
HRESULT hr;
|
|
|
|
if (pceltFetched)
|
|
*pceltFetched = 0;
|
|
|
|
if ( _fWrite )
|
|
{
|
|
hr = THR(E_NOTIMPL);
|
|
}
|
|
else // READ
|
|
{
|
|
for ( ULONG ul = 0; ul < celt; ul++ )
|
|
{
|
|
hr = _FindNextItem( &rgelt[ ul ] );
|
|
if (hr)
|
|
goto Error;
|
|
}
|
|
|
|
if (pceltFetched)
|
|
*pceltFetched = ul;
|
|
}
|
|
|
|
|
|
Cleanup:
|
|
HRETURN(hr);
|
|
|
|
Error:
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// Skip( )
|
|
//
|
|
HRESULT
|
|
THISCLASS::Skip(
|
|
ULONG celt )
|
|
{
|
|
TraceClsFunc( "[IEnumIMSIFs] Skip( ... )\n" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
for( ULONG ul = 0; ul < celt; ul++ )
|
|
{
|
|
_iIndex++;
|
|
|
|
hr = THR( _FindNextItem( NULL ) );
|
|
if ( hr == E_POINTER )
|
|
{ // expected result
|
|
hr = S_OK;
|
|
}
|
|
else if (hr)
|
|
goto Error;
|
|
}
|
|
|
|
Error:
|
|
HRETURN(hr);
|
|
}
|
|
|
|
|
|
//
|
|
// Reset( )
|
|
//
|
|
HRESULT
|
|
THISCLASS::Reset( void )
|
|
{
|
|
TraceClsFunc( "[IEnumIMSIFs] Reset( ... )\n" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
_iIndex = 0;
|
|
|
|
if ( _hLanguage != INVALID_HANDLE_VALUE )
|
|
{
|
|
FindClose( _hLanguage );
|
|
_hLanguage = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
if ( _hOS != INVALID_HANDLE_VALUE )
|
|
{
|
|
FindClose( _hOS );
|
|
_hOS = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
if ( _hArchitecture )
|
|
{
|
|
FindClose( _hArchitecture );
|
|
_hArchitecture = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
if ( _hSIF )
|
|
{
|
|
FindClose( _hSIF );
|
|
_hSIF = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
HRETURN(hr);
|
|
}
|
|
|
|
|
|
//
|
|
// Clone( )
|
|
//
|
|
HRESULT
|
|
THISCLASS::Clone(
|
|
LPUNKNOWN * ppenum )
|
|
{
|
|
TraceClsFunc( "[IEnumIMSIFs] Clone( ... )\n" );
|
|
|
|
if ( !ppenum )
|
|
RRETURN(E_POINTER);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
*ppenum = (LPUNKNOWN) CEnumIMSIFs_CreateInstance( _pszEnumPath,
|
|
_pszAttribute,
|
|
_dwFlags,
|
|
_pads );
|
|
|
|
if ( !*ppenum )
|
|
{
|
|
hr = THR(E_FAIL);
|
|
}
|
|
|
|
HRETURN(hr);
|
|
}
|
|
|
|
|
|
// ************************************************************************
|
|
//
|
|
// Privates
|
|
//
|
|
// ************************************************************************
|
|
|
|
|
|
//
|
|
// _FindNextItem( )
|
|
//
|
|
HRESULT
|
|
THISCLASS::_FindNextItem(
|
|
LPWSTR * ppszFileName )
|
|
{
|
|
TraceClsFunc( "_FindNextItem( ... )\n" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
WCHAR szFilePath[ MAX_PATH ];
|
|
|
|
if ( _hLanguage == INVALID_HANDLE_VALUE )
|
|
{
|
|
hr = _NextLanguage( );
|
|
if (hr)
|
|
goto Error;
|
|
}
|
|
|
|
if ( _hOS == INVALID_HANDLE_VALUE )
|
|
{
|
|
hr = _NextOS( );
|
|
if (hr)
|
|
goto Error;
|
|
}
|
|
|
|
if ( _hArchitecture == INVALID_HANDLE_VALUE )
|
|
{
|
|
hr = _NextArchitecture( );
|
|
if (hr)
|
|
goto Error;
|
|
}
|
|
|
|
hr = _NextSIF( );
|
|
if (hr)
|
|
goto Error;
|
|
|
|
// NOTE: Skip( ) passes NULL in to "skip" and should except this error.
|
|
if ( !ppszFileName )
|
|
HRETURN(E_POINTER);
|
|
|
|
// Create a buffer
|
|
// 1 2 3
|
|
// 12 345678901234567 8 9 0 12345678901 = 31 + NULL = 32
|
|
// \\%s\REMINST\SETUP\%s\%s\%s\%s\templates\%s
|
|
*ppszFileName = (LPWSTR ) TraceAllocString( LMEM_FIXED, 32
|
|
+ wcslen( _pszServerName )
|
|
+ wcslen( _pszLanguage )
|
|
+ wcslen( _pszEnumPath )
|
|
+ wcslen( _pszOS )
|
|
+ wcslen( _pszArchitecture )
|
|
+ wcslen( _pszSIF ) );
|
|
if ( !*ppszFileName )
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Error;
|
|
}
|
|
|
|
wsprintf( *ppszFileName,
|
|
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\%s\\%s" SLASH_TEMPLATES L"\\%s",
|
|
_pszServerName,
|
|
_pszLanguage,
|
|
_pszEnumPath,
|
|
_pszOS,
|
|
_pszArchitecture,
|
|
_pszSIF );
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
HRETURN(hr);
|
|
|
|
Error:
|
|
*ppszFileName = NULL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// _NextLanguage( )
|
|
//
|
|
HRESULT
|
|
THISCLASS::_NextLanguage( )
|
|
{
|
|
TraceClsFunc( "_NextLanguage( ... )\n" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
WIN32_FIND_DATA fd;
|
|
|
|
if ( _pszLanguage )
|
|
{
|
|
TraceFree( _pszLanguage );
|
|
_pszLanguage = NULL;
|
|
}
|
|
|
|
if ( _hLanguage == INVALID_HANDLE_VALUE )
|
|
{
|
|
WCHAR szFilePath[ MAX_PATH ];
|
|
|
|
wsprintf( szFilePath,
|
|
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\*",
|
|
_pszServerName );
|
|
|
|
DebugMsg( "Enumerating %s...\n", szFilePath );
|
|
|
|
_hLanguage = FindFirstFile( szFilePath, &fd );
|
|
if ( _hLanguage == INVALID_HANDLE_VALUE )
|
|
goto TryAgain;
|
|
|
|
Assert( fd.cFileName[0] == L'.' );
|
|
// we skip the first one because it should be the "." file
|
|
}
|
|
|
|
while ( FindNextFile( _hLanguage, &fd ) )
|
|
{
|
|
if ( fd.cFileName[0] != L'.' )
|
|
{
|
|
_pszLanguage = (LPWSTR) TraceStrDup( fd.cFileName );
|
|
if ( !_pszLanguage )
|
|
{
|
|
hr = THR(E_OUTOFMEMORY);
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Cleanup:
|
|
HRETURN(hr);
|
|
|
|
TryAgain:
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// _NextOS( )
|
|
//
|
|
HRESULT
|
|
THISCLASS::_NextOS( )
|
|
{
|
|
TraceClsFunc( "_NextOS( ... )\n" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
WIN32_FIND_DATA fd;
|
|
|
|
if ( _pszOS )
|
|
{
|
|
TraceFree( _pszOS );
|
|
_pszOS = NULL;
|
|
}
|
|
|
|
if ( _hOS == INVALID_HANDLE_VALUE )
|
|
{
|
|
WCHAR szFilePath[ MAX_PATH ];
|
|
|
|
wsprintf( szFilePath,
|
|
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\*",
|
|
_pszServerName,
|
|
_pszLanguage,
|
|
_pszEnumPath );
|
|
|
|
DebugMsg( "Enumerating %s...\n", szFilePath );
|
|
|
|
_hOS = FindFirstFile( szFilePath, &fd );
|
|
if ( _hOS == INVALID_HANDLE_VALUE )
|
|
goto TryAgain;
|
|
|
|
Assert( fd.cFileName[0] == L'.' );
|
|
// we skip the first one because it should be the "." file
|
|
}
|
|
|
|
while ( FindNextFile( _hOS, &fd ) )
|
|
{
|
|
if ( fd.cFileName[0] != L'.' )
|
|
{
|
|
_pszOS = (LPWSTR) TraceStrDup( fd.cFileName );
|
|
if ( !_pszOS )
|
|
{
|
|
hr = THR(E_OUTOFMEMORY);
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hr)
|
|
goto TryAgain;
|
|
|
|
Cleanup:
|
|
HRETURN(hr);
|
|
|
|
TryAgain:
|
|
if ( _hOS != INVALID_HANDLE_VALUE )
|
|
{
|
|
FindClose( _hOS );
|
|
_hOS = INVALID_HANDLE_VALUE;
|
|
|
|
}
|
|
|
|
hr = _NextLanguage( );
|
|
if (hr)
|
|
goto Cleanup;
|
|
|
|
hr = _NextOS( ); // recurse
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// _NextArchitecture( )
|
|
//
|
|
HRESULT
|
|
THISCLASS::_NextArchitecture( )
|
|
{
|
|
TraceClsFunc( "_NextArchitecture( ... )\n" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
WIN32_FIND_DATA fd;
|
|
|
|
if ( _pszArchitecture )
|
|
{
|
|
TraceFree( _pszArchitecture );
|
|
_pszArchitecture = NULL;
|
|
}
|
|
|
|
if ( _hArchitecture == INVALID_HANDLE_VALUE )
|
|
{
|
|
WCHAR szFilePath[ MAX_PATH ];
|
|
|
|
wsprintf( szFilePath,
|
|
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\%s\\*",
|
|
_pszServerName,
|
|
_pszLanguage,
|
|
_pszEnumPath,
|
|
_pszOS );
|
|
|
|
DebugMsg( "Enumerating %s...\n", szFilePath );
|
|
|
|
_hArchitecture = FindFirstFile( szFilePath, &fd );
|
|
if ( _hArchitecture == INVALID_HANDLE_VALUE )
|
|
goto TryAgain;
|
|
|
|
Assert( fd.cFileName[0] == L'.' );
|
|
// we skip the first one because it should be the "." file
|
|
}
|
|
|
|
while ( FindNextFile( _hArchitecture, &fd ) )
|
|
{
|
|
if ( fd.cFileName[0] != L'.' )
|
|
{
|
|
_pszArchitecture = (LPWSTR) TraceStrDup( fd.cFileName );
|
|
if ( !_pszArchitecture )
|
|
{
|
|
hr = THR(E_OUTOFMEMORY);
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hr)
|
|
goto TryAgain;
|
|
|
|
Cleanup:
|
|
HRETURN(hr);
|
|
|
|
TryAgain:
|
|
if ( _hArchitecture != INVALID_HANDLE_VALUE )
|
|
{
|
|
FindClose( _hArchitecture );
|
|
_hArchitecture = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
hr = _NextOS( );
|
|
if (hr)
|
|
goto Cleanup;
|
|
|
|
hr = _NextArchitecture( ); // recurse
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// _NextSIF( )
|
|
//
|
|
HRESULT
|
|
THISCLASS::_NextSIF( )
|
|
{
|
|
TraceClsFunc( "_NextSIF( ... )\n" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
WIN32_FIND_DATA fd;
|
|
|
|
if ( _pszSIF )
|
|
{
|
|
TraceFree( _pszSIF );
|
|
_pszSIF = NULL;
|
|
}
|
|
|
|
if ( _hSIF == INVALID_HANDLE_VALUE )
|
|
{
|
|
WCHAR szFilePath[ MAX_PATH ];
|
|
|
|
wsprintf( szFilePath,
|
|
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\%s\\%s" SLASH_TEMPLATES L"\\*.sif",
|
|
_pszServerName,
|
|
_pszLanguage,
|
|
_pszEnumPath,
|
|
_pszOS,
|
|
_pszArchitecture );
|
|
|
|
DebugMsg( "Enumerating %s...\n", szFilePath );
|
|
|
|
_hSIF = FindFirstFile( szFilePath, &fd );
|
|
if ( _hSIF == INVALID_HANDLE_VALUE )
|
|
goto TryAgain;
|
|
}
|
|
else
|
|
{
|
|
if ( !FindNextFile( _hSIF, &fd ) )
|
|
goto TryAgain;
|
|
}
|
|
|
|
_pszSIF = (LPWSTR) TraceStrDup( fd.cFileName );
|
|
if ( !_pszSIF )
|
|
{
|
|
hr = THR(E_OUTOFMEMORY);
|
|
goto Cleanup;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
HRETURN(hr);
|
|
|
|
TryAgain:
|
|
if ( _hSIF != INVALID_HANDLE_VALUE )
|
|
{
|
|
FindClose( _hSIF );
|
|
_hSIF = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
hr = _NextArchitecture( );
|
|
if (hr)
|
|
goto Cleanup;
|
|
|
|
hr = _NextSIF( ); // recurse
|
|
goto Cleanup;
|
|
}
|
|
|