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

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