Source code of Windows XP (NT5)
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.

737 lines
14 KiB

  1. //
  2. // Copyright 1997 - Microsoft
  3. //
  4. // CENUMSIF.CPP - Handles enumerating OSes and Tools SIFs from DS
  5. //
  6. #include "pch.h"
  7. #include "cenumsif.h"
  8. DEFINE_MODULE("IMADMUI")
  9. DEFINE_THISCLASS("CEnumIMSIFs")
  10. #define THISCLASS CEnumIMSIFs
  11. #define LPTHISCLASS LPENUMSIFS
  12. // ************************************************************************
  13. //
  14. // Constructor / Destructor
  15. //
  16. // ************************************************************************
  17. //
  18. // CreateInstance()
  19. //
  20. LPVOID
  21. CEnumIMSIFs_CreateInstance(
  22. LPWSTR pszEnumPath,
  23. LPWSTR pszAttribute,
  24. DWORD dwFlags,
  25. IADs * pads )
  26. {
  27. TraceFunc( "CEnumIMSIFs_CreateInstance()\n" );
  28. LPTHISCLASS lpcc = new THISCLASS( );
  29. HRESULT hr = THR( lpcc->Init( pszEnumPath, pszAttribute, dwFlags, pads ) );
  30. if ( hr )
  31. {
  32. delete lpcc;
  33. RETURN(NULL);
  34. }
  35. RETURN((LPVOID) lpcc);
  36. }
  37. //
  38. // Constructor
  39. //
  40. THISCLASS::THISCLASS( )
  41. {
  42. TraceClsFunc( "CEnumIMSIFs()\n" );
  43. InterlockIncrement( g_cObjects );
  44. TraceFuncExit();
  45. }
  46. //
  47. // Init()
  48. //
  49. STDMETHODIMP
  50. THISCLASS::Init(
  51. LPWSTR pszEnumPath,
  52. LPWSTR pszAttribute,
  53. DWORD dwFlags,
  54. IADs * pads )
  55. {
  56. TraceClsFunc( "Init()\n" );
  57. HRESULT hr = S_OK;
  58. LPWSTR psz;
  59. VARIANT var;
  60. VariantInit( &var );
  61. // IUnknown stuff
  62. BEGIN_QITABLE_IMP( CEnumIMSIFs, IEnumIMSIFs );
  63. QITABLE_IMP( IEnumIMSIFs );
  64. END_QITABLE_IMP( CEnumIMSIFs );
  65. Assert( _cRef == 0);
  66. AddRef( );
  67. // Private Members
  68. Assert( _iIndex == 0 );
  69. Assert( !_pszLanguage );
  70. Assert( !_pszOS );
  71. Assert( !_pszArchitecture );
  72. Assert( !_pszSIF );
  73. pads->AddRef( );
  74. _pads = pads;
  75. hr = THR( _pads->Get( NETBOOTSERVER, &var ) );
  76. if (hr)
  77. goto Error;
  78. psz = V_BSTR( &var );
  79. hr = THR( DNtoFQDN( psz, &_pszServerName ) );
  80. if (hr)
  81. goto Error;
  82. _dwFlags = dwFlags;
  83. _pszAttribute = (LPWSTR) TraceStrDup( pszAttribute );
  84. if ( !_pszAttribute )
  85. {
  86. hr = THR(E_OUTOFMEMORY);
  87. goto Error;
  88. }
  89. _pszEnumPath = (LPWSTR) TraceStrDup( pszEnumPath );
  90. if ( !_pszEnumPath )
  91. {
  92. hr = THR(E_OUTOFMEMORY);
  93. goto Error;
  94. }
  95. _hLanguage = INVALID_HANDLE_VALUE;
  96. _hOS = INVALID_HANDLE_VALUE;
  97. _hArchitecture = INVALID_HANDLE_VALUE;
  98. _hSIF = INVALID_HANDLE_VALUE;
  99. Error: // Destructor will handle cleanup
  100. VariantClear( &var );
  101. HRETURN(hr);
  102. }
  103. //
  104. // Destructor
  105. //
  106. THISCLASS::~THISCLASS( )
  107. {
  108. TraceClsFunc( "~CEnumIMSIFs()\n" );
  109. // Private Members
  110. if ( _pads )
  111. {
  112. // Commit any changes before we release
  113. THR( _pads->SetInfo( ) );
  114. _pads->Release( );
  115. }
  116. if ( _pszAttribute )
  117. TraceFree( _pszAttribute );
  118. if ( _pszEnumPath )
  119. TraceFree( _pszEnumPath );
  120. if ( _hLanguage != INVALID_HANDLE_VALUE )
  121. FindClose( _hLanguage );
  122. if ( _hOS != INVALID_HANDLE_VALUE )
  123. FindClose( _hOS );
  124. if ( _hSIF != INVALID_HANDLE_VALUE )
  125. FindClose( _hSIF );
  126. if ( _pszLanguage )
  127. TraceFree( _pszLanguage );
  128. if ( _pszOS )
  129. TraceFree( _pszOS );
  130. if ( _pszSIF )
  131. TraceFree( _pszSIF );
  132. if ( _pszServerName )
  133. TraceFree( _pszServerName );
  134. InterlockDecrement( g_cObjects );
  135. TraceFuncExit();
  136. };
  137. // ************************************************************************
  138. //
  139. // IUnknown
  140. //
  141. // ************************************************************************
  142. //
  143. // QueryInterface()
  144. //
  145. STDMETHODIMP
  146. THISCLASS::QueryInterface(
  147. REFIID riid,
  148. LPVOID *ppv )
  149. {
  150. TraceClsFunc( "[IUnknown] QueryInterface( riid=" );
  151. HRESULT hr = ::QueryInterface( this, _QITable, riid, ppv );
  152. QIRETURN( hr, riid );
  153. }
  154. //
  155. // AddRef()
  156. //
  157. STDMETHODIMP_(ULONG)
  158. THISCLASS::AddRef( void )
  159. {
  160. TraceClsFunc( "[IUnknown] AddRef( )\n" );
  161. InterlockIncrement( _cRef );
  162. RETURN(_cRef);
  163. }
  164. //
  165. // Release()
  166. //
  167. STDMETHODIMP_(ULONG)
  168. THISCLASS::Release( void )
  169. {
  170. TraceClsFunc( "[IUnknown] Release( )\n" );
  171. InterlockDecrement( _cRef );
  172. if ( _cRef )
  173. RETURN(_cRef);
  174. TraceDo( delete this );
  175. RETURN(0);
  176. }
  177. // ************************************************************************
  178. //
  179. // IEnumIMSIFs
  180. //
  181. // ************************************************************************
  182. //
  183. // Next( )
  184. //
  185. HRESULT
  186. THISCLASS::Next(
  187. ULONG celt,
  188. LPWSTR * rgelt,
  189. ULONG * pceltFetched )
  190. {
  191. TraceClsFunc( "[IEnumIMSIFs] Next( ... )\n" );
  192. if ( !rgelt )
  193. RRETURN(E_POINTER);
  194. HRESULT hr;
  195. if (pceltFetched)
  196. *pceltFetched = 0;
  197. if ( _fWrite )
  198. {
  199. hr = THR(E_NOTIMPL);
  200. }
  201. else // READ
  202. {
  203. for ( ULONG ul = 0; ul < celt; ul++ )
  204. {
  205. hr = _FindNextItem( &rgelt[ ul ] );
  206. if (hr)
  207. goto Error;
  208. }
  209. if (pceltFetched)
  210. *pceltFetched = ul;
  211. }
  212. Cleanup:
  213. HRETURN(hr);
  214. Error:
  215. goto Cleanup;
  216. }
  217. //
  218. // Skip( )
  219. //
  220. HRESULT
  221. THISCLASS::Skip(
  222. ULONG celt )
  223. {
  224. TraceClsFunc( "[IEnumIMSIFs] Skip( ... )\n" );
  225. HRESULT hr = S_OK;
  226. for( ULONG ul = 0; ul < celt; ul++ )
  227. {
  228. _iIndex++;
  229. hr = THR( _FindNextItem( NULL ) );
  230. if ( hr == E_POINTER )
  231. { // expected result
  232. hr = S_OK;
  233. }
  234. else if (hr)
  235. goto Error;
  236. }
  237. Error:
  238. HRETURN(hr);
  239. }
  240. //
  241. // Reset( )
  242. //
  243. HRESULT
  244. THISCLASS::Reset( void )
  245. {
  246. TraceClsFunc( "[IEnumIMSIFs] Reset( ... )\n" );
  247. HRESULT hr = S_OK;
  248. _iIndex = 0;
  249. if ( _hLanguage != INVALID_HANDLE_VALUE )
  250. {
  251. FindClose( _hLanguage );
  252. _hLanguage = INVALID_HANDLE_VALUE;
  253. }
  254. if ( _hOS != INVALID_HANDLE_VALUE )
  255. {
  256. FindClose( _hOS );
  257. _hOS = INVALID_HANDLE_VALUE;
  258. }
  259. if ( _hArchitecture )
  260. {
  261. FindClose( _hArchitecture );
  262. _hArchitecture = INVALID_HANDLE_VALUE;
  263. }
  264. if ( _hSIF )
  265. {
  266. FindClose( _hSIF );
  267. _hSIF = INVALID_HANDLE_VALUE;
  268. }
  269. HRETURN(hr);
  270. }
  271. //
  272. // Clone( )
  273. //
  274. HRESULT
  275. THISCLASS::Clone(
  276. LPUNKNOWN * ppenum )
  277. {
  278. TraceClsFunc( "[IEnumIMSIFs] Clone( ... )\n" );
  279. if ( !ppenum )
  280. RRETURN(E_POINTER);
  281. HRESULT hr = S_OK;
  282. *ppenum = (LPUNKNOWN) CEnumIMSIFs_CreateInstance( _pszEnumPath,
  283. _pszAttribute,
  284. _dwFlags,
  285. _pads );
  286. if ( !*ppenum )
  287. {
  288. hr = THR(E_FAIL);
  289. }
  290. HRETURN(hr);
  291. }
  292. // ************************************************************************
  293. //
  294. // Privates
  295. //
  296. // ************************************************************************
  297. //
  298. // _FindNextItem( )
  299. //
  300. HRESULT
  301. THISCLASS::_FindNextItem(
  302. LPWSTR * ppszFileName )
  303. {
  304. TraceClsFunc( "_FindNextItem( ... )\n" );
  305. HRESULT hr = S_FALSE;
  306. WCHAR szFilePath[ MAX_PATH ];
  307. if ( _hLanguage == INVALID_HANDLE_VALUE )
  308. {
  309. hr = _NextLanguage( );
  310. if (hr)
  311. goto Error;
  312. }
  313. if ( _hOS == INVALID_HANDLE_VALUE )
  314. {
  315. hr = _NextOS( );
  316. if (hr)
  317. goto Error;
  318. }
  319. if ( _hArchitecture == INVALID_HANDLE_VALUE )
  320. {
  321. hr = _NextArchitecture( );
  322. if (hr)
  323. goto Error;
  324. }
  325. hr = _NextSIF( );
  326. if (hr)
  327. goto Error;
  328. // NOTE: Skip( ) passes NULL in to "skip" and should except this error.
  329. if ( !ppszFileName )
  330. HRETURN(E_POINTER);
  331. // Create a buffer
  332. // 1 2 3
  333. // 12 345678901234567 8 9 0 12345678901 = 31 + NULL = 32
  334. // \\%s\REMINST\SETUP\%s\%s\%s\%s\templates\%s
  335. *ppszFileName = (LPWSTR ) TraceAllocString( LMEM_FIXED, 32
  336. + wcslen( _pszServerName )
  337. + wcslen( _pszLanguage )
  338. + wcslen( _pszEnumPath )
  339. + wcslen( _pszOS )
  340. + wcslen( _pszArchitecture )
  341. + wcslen( _pszSIF ) );
  342. if ( !*ppszFileName )
  343. {
  344. hr = E_OUTOFMEMORY;
  345. goto Error;
  346. }
  347. wsprintf( *ppszFileName,
  348. L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\%s\\%s" SLASH_TEMPLATES L"\\%s",
  349. _pszServerName,
  350. _pszLanguage,
  351. _pszEnumPath,
  352. _pszOS,
  353. _pszArchitecture,
  354. _pszSIF );
  355. hr = S_OK;
  356. Cleanup:
  357. HRETURN(hr);
  358. Error:
  359. *ppszFileName = NULL;
  360. goto Cleanup;
  361. }
  362. //
  363. // _NextLanguage( )
  364. //
  365. HRESULT
  366. THISCLASS::_NextLanguage( )
  367. {
  368. TraceClsFunc( "_NextLanguage( ... )\n" );
  369. HRESULT hr = S_FALSE;
  370. WIN32_FIND_DATA fd;
  371. if ( _pszLanguage )
  372. {
  373. TraceFree( _pszLanguage );
  374. _pszLanguage = NULL;
  375. }
  376. if ( _hLanguage == INVALID_HANDLE_VALUE )
  377. {
  378. WCHAR szFilePath[ MAX_PATH ];
  379. wsprintf( szFilePath,
  380. L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\*",
  381. _pszServerName );
  382. DebugMsg( "Enumerating %s...\n", szFilePath );
  383. _hLanguage = FindFirstFile( szFilePath, &fd );
  384. if ( _hLanguage == INVALID_HANDLE_VALUE )
  385. goto TryAgain;
  386. Assert( fd.cFileName[0] == L'.' );
  387. // we skip the first one because it should be the "." file
  388. }
  389. while ( FindNextFile( _hLanguage, &fd ) )
  390. {
  391. if ( fd.cFileName[0] != L'.' )
  392. {
  393. _pszLanguage = (LPWSTR) TraceStrDup( fd.cFileName );
  394. if ( !_pszLanguage )
  395. {
  396. hr = THR(E_OUTOFMEMORY);
  397. goto Cleanup;
  398. }
  399. hr = S_OK;
  400. break;
  401. }
  402. }
  403. Cleanup:
  404. HRETURN(hr);
  405. TryAgain:
  406. goto Cleanup;
  407. }
  408. //
  409. // _NextOS( )
  410. //
  411. HRESULT
  412. THISCLASS::_NextOS( )
  413. {
  414. TraceClsFunc( "_NextOS( ... )\n" );
  415. HRESULT hr = S_FALSE;
  416. WIN32_FIND_DATA fd;
  417. if ( _pszOS )
  418. {
  419. TraceFree( _pszOS );
  420. _pszOS = NULL;
  421. }
  422. if ( _hOS == INVALID_HANDLE_VALUE )
  423. {
  424. WCHAR szFilePath[ MAX_PATH ];
  425. wsprintf( szFilePath,
  426. L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\*",
  427. _pszServerName,
  428. _pszLanguage,
  429. _pszEnumPath );
  430. DebugMsg( "Enumerating %s...\n", szFilePath );
  431. _hOS = FindFirstFile( szFilePath, &fd );
  432. if ( _hOS == INVALID_HANDLE_VALUE )
  433. goto TryAgain;
  434. Assert( fd.cFileName[0] == L'.' );
  435. // we skip the first one because it should be the "." file
  436. }
  437. while ( FindNextFile( _hOS, &fd ) )
  438. {
  439. if ( fd.cFileName[0] != L'.' )
  440. {
  441. _pszOS = (LPWSTR) TraceStrDup( fd.cFileName );
  442. if ( !_pszOS )
  443. {
  444. hr = THR(E_OUTOFMEMORY);
  445. goto Cleanup;
  446. }
  447. hr = S_OK;
  448. break;
  449. }
  450. }
  451. if (hr)
  452. goto TryAgain;
  453. Cleanup:
  454. HRETURN(hr);
  455. TryAgain:
  456. if ( _hOS != INVALID_HANDLE_VALUE )
  457. {
  458. FindClose( _hOS );
  459. _hOS = INVALID_HANDLE_VALUE;
  460. }
  461. hr = _NextLanguage( );
  462. if (hr)
  463. goto Cleanup;
  464. hr = _NextOS( ); // recurse
  465. goto Cleanup;
  466. }
  467. //
  468. // _NextArchitecture( )
  469. //
  470. HRESULT
  471. THISCLASS::_NextArchitecture( )
  472. {
  473. TraceClsFunc( "_NextArchitecture( ... )\n" );
  474. HRESULT hr = S_FALSE;
  475. WIN32_FIND_DATA fd;
  476. if ( _pszArchitecture )
  477. {
  478. TraceFree( _pszArchitecture );
  479. _pszArchitecture = NULL;
  480. }
  481. if ( _hArchitecture == INVALID_HANDLE_VALUE )
  482. {
  483. WCHAR szFilePath[ MAX_PATH ];
  484. wsprintf( szFilePath,
  485. L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\%s\\*",
  486. _pszServerName,
  487. _pszLanguage,
  488. _pszEnumPath,
  489. _pszOS );
  490. DebugMsg( "Enumerating %s...\n", szFilePath );
  491. _hArchitecture = FindFirstFile( szFilePath, &fd );
  492. if ( _hArchitecture == INVALID_HANDLE_VALUE )
  493. goto TryAgain;
  494. Assert( fd.cFileName[0] == L'.' );
  495. // we skip the first one because it should be the "." file
  496. }
  497. while ( FindNextFile( _hArchitecture, &fd ) )
  498. {
  499. if ( fd.cFileName[0] != L'.' )
  500. {
  501. _pszArchitecture = (LPWSTR) TraceStrDup( fd.cFileName );
  502. if ( !_pszArchitecture )
  503. {
  504. hr = THR(E_OUTOFMEMORY);
  505. goto Cleanup;
  506. }
  507. hr = S_OK;
  508. break;
  509. }
  510. }
  511. if (hr)
  512. goto TryAgain;
  513. Cleanup:
  514. HRETURN(hr);
  515. TryAgain:
  516. if ( _hArchitecture != INVALID_HANDLE_VALUE )
  517. {
  518. FindClose( _hArchitecture );
  519. _hArchitecture = INVALID_HANDLE_VALUE;
  520. }
  521. hr = _NextOS( );
  522. if (hr)
  523. goto Cleanup;
  524. hr = _NextArchitecture( ); // recurse
  525. goto Cleanup;
  526. }
  527. //
  528. // _NextSIF( )
  529. //
  530. HRESULT
  531. THISCLASS::_NextSIF( )
  532. {
  533. TraceClsFunc( "_NextSIF( ... )\n" );
  534. HRESULT hr = S_FALSE;
  535. WIN32_FIND_DATA fd;
  536. if ( _pszSIF )
  537. {
  538. TraceFree( _pszSIF );
  539. _pszSIF = NULL;
  540. }
  541. if ( _hSIF == INVALID_HANDLE_VALUE )
  542. {
  543. WCHAR szFilePath[ MAX_PATH ];
  544. wsprintf( szFilePath,
  545. L"\\\\%s\\" REMINST_SHARE SLASH_SETUP L"\\%s\\%s\\%s\\%s" SLASH_TEMPLATES L"\\*.sif",
  546. _pszServerName,
  547. _pszLanguage,
  548. _pszEnumPath,
  549. _pszOS,
  550. _pszArchitecture );
  551. DebugMsg( "Enumerating %s...\n", szFilePath );
  552. _hSIF = FindFirstFile( szFilePath, &fd );
  553. if ( _hSIF == INVALID_HANDLE_VALUE )
  554. goto TryAgain;
  555. }
  556. else
  557. {
  558. if ( !FindNextFile( _hSIF, &fd ) )
  559. goto TryAgain;
  560. }
  561. _pszSIF = (LPWSTR) TraceStrDup( fd.cFileName );
  562. if ( !_pszSIF )
  563. {
  564. hr = THR(E_OUTOFMEMORY);
  565. goto Cleanup;
  566. }
  567. hr = S_OK;
  568. Cleanup:
  569. HRETURN(hr);
  570. TryAgain:
  571. if ( _hSIF != INVALID_HANDLE_VALUE )
  572. {
  573. FindClose( _hSIF );
  574. _hSIF = INVALID_HANDLE_VALUE;
  575. }
  576. hr = _NextArchitecture( );
  577. if (hr)
  578. goto Cleanup;
  579. hr = _NextSIF( ); // recurse
  580. goto Cleanup;
  581. }