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.
 
 
 
 
 
 

766 lines
16 KiB

//
// 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 ( FAILED(hr)) {
delete lpcc;
RETURN(NULL);
}
RETURN((LPVOID) lpcc);
}
//
// Constructor
//
THISCLASS::THISCLASS( ) :
_cRef(0),
_pads(NULL),
_pszAttribute(NULL),
_iIndex(0),
_pszServerName(NULL),
_hLanguage(INVALID_HANDLE_VALUE),
_pszLanguage(NULL),
_pszEnumPath(NULL),
_hOS(INVALID_HANDLE_VALUE),
_pszOS(NULL),
_hArchitecture(INVALID_HANDLE_VALUE),
_pszArchitecture(NULL),
_hSIF(INVALID_HANDLE_VALUE),
_pszSIF(NULL)
{
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;
_bstr_t Str;
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;
//
// get the netbootserver property (dn of the RIS server)
//
Str = NETBOOTSERVER;
hr = THR( _pads->Get( Str, &var ) );
if (FAILED(hr)) {
goto Error;
}
//
// now convert it to the FQDN of the server.
//
psz = V_BSTR( &var );
hr = THR( DNtoFQDNEx( psz, &_pszServerName ) );
if (FAILED(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" );
HRESULT hr = S_OK;
if ( !rgelt ) {
RRETURN(E_POINTER);
}
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 != S_OK) {
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 != S_OK ) {
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 != INVALID_HANDLE_VALUE ) {
FindClose( _hArchitecture );
_hArchitecture = INVALID_HANDLE_VALUE;
}
if ( _hSIF != INVALID_HANDLE_VALUE ) {
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 != S_OK) {
goto Error;
}
}
if ( _hOS == INVALID_HANDLE_VALUE ) {
hr = _NextOS( );
if (hr != S_OK) {
goto Error;
}
}
if ( _hArchitecture == INVALID_HANDLE_VALUE ) {
hr = _NextArchitecture( );
if (hr != S_OK) {
goto Error;
}
}
hr = _NextSIF( );
if (hr != S_OK) {
goto Error;
}
// NOTE: Skip( ) passes NULL in to "skip" and should except this error.
if ( !ppszFileName ) {
HRETURN(E_POINTER);
}
//
// make sure we're in an expected internal state.
//
if (!_pszServerName || !_pszLanguage || !_pszEnumPath ||
!_pszOS || !_pszArchitecture || !_pszSIF) {
ASSERT(FALSE);
hr = E_INVALIDARG;
goto Error;
}
// Create a buffer
// 1 2 3
// 12 345678901234567 8 9 0 12345678901 = 31 + NULL = 32
// \\%s\REMINST\SETUP\%s\%s\%s\%s\templates\%s
DWORD dwBufLen = 32 + wcslen( _pszServerName ) + wcslen( _pszServerName ) +
wcslen( _pszLanguage ) + wcslen( _pszEnumPath ) +
wcslen( _pszOS ) + wcslen( _pszArchitecture ) + wcslen( _pszSIF );
*ppszFileName = (LPWSTR ) TraceAllocString( LMEM_FIXED, dwBufLen );
if ( !*ppszFileName ||
_snwprintf( *ppszFileName,
dwBufLen,
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\%s\\%s" SLASH_TEMPLATES L"\\%s",
_pszServerName,
_pszLanguage,
_pszEnumPath,
_pszOS,
_pszArchitecture,
_pszSIF ) < 0) {
hr = E_OUTOFMEMORY;
goto Error;
}
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 ];
if (_snwprintf(
szFilePath,
MAX_PATH,
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\*",
_pszServerName) < 0) {
hr = E_FAIL;
goto Cleanup;
}
DebugMsg( "Enumerating %s...\n", szFilePath );
_hLanguage = FindFirstFile( szFilePath, &fd );
if ( _hLanguage == INVALID_HANDLE_VALUE ) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
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);
}
//
// _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 ];
if (_snwprintf(
szFilePath,
MAX_PATH,
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\*",
_pszServerName,
_pszLanguage,
_pszEnumPath) < 0) {
hr = E_FAIL;
goto Cleanup;
}
szFilePath[MAX_PATH-1] = L'\0';
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 != S_OK) {
goto TryAgain;
}
Cleanup:
HRETURN(hr);
TryAgain:
if ( _hOS != INVALID_HANDLE_VALUE ) {
FindClose( _hOS );
_hOS = INVALID_HANDLE_VALUE;
}
hr = _NextLanguage( );
if (hr != S_OK) {
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 ];
if (_snwprintf(
szFilePath,
MAX_PATH,
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\%s\\*",
_pszServerName,
_pszLanguage,
_pszEnumPath,
_pszOS) < 0) {
hr = E_FAIL;
goto Cleanup;
}
szFilePath[MAX_PATH-1] = L'\0';
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 != S_OK) {
goto TryAgain;
}
Cleanup:
HRETURN(hr);
TryAgain:
if ( _hArchitecture != INVALID_HANDLE_VALUE ) {
FindClose( _hArchitecture );
_hArchitecture = INVALID_HANDLE_VALUE;
}
hr = _NextOS( );
if (hr != S_OK) {
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 ];
if (_snwprintf(
szFilePath,
MAX_PATH,
L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\%s\\%s" SLASH_TEMPLATES L"\\*.sif",
_pszServerName,
_pszLanguage,
_pszEnumPath,
_pszOS,
_pszArchitecture ) < 0) {
hr = E_FAIL;
goto Cleanup;
}
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 != S_OK) {
goto Cleanup;
}
hr = _NextSIF( ); // recurse
goto Cleanup;
}