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.

1773 lines
34 KiB

  1. //
  2. // Copyright 1997 - Microsoft
  3. //
  4. // CCOMPUTR.CPP - Handles the computer object property pages.
  5. //
  6. #include "pch.h"
  7. #include "imos.h"
  8. #include "local.h"
  9. #include "newclnts.h"
  10. #include "tools.h"
  11. #include "varconv.h"
  12. #include "cservice.h"
  13. #include "cenumsif.h"
  14. DEFINE_MODULE("IMADMUI")
  15. DEFINE_THISCLASS("CService")
  16. #define THISCLASS CService
  17. #define LPTHISCLASS LPSERVICE
  18. // ************************************************************************
  19. //
  20. // Constructor / Destructor
  21. //
  22. // ************************************************************************
  23. //
  24. // CreateInstance()
  25. //
  26. LPVOID
  27. CService_CreateInstance( void )
  28. {
  29. TraceFunc( "CService_CreateInstance()\n" );
  30. LPTHISCLASS lpcc = new THISCLASS( );
  31. HRESULT hr = THR( lpcc->Init( ) );
  32. if ( hr )
  33. {
  34. delete lpcc;
  35. RETURN(NULL);
  36. }
  37. RETURN((LPVOID)lpcc);
  38. }
  39. //
  40. // Constructor
  41. //
  42. THISCLASS::THISCLASS( )
  43. {
  44. TraceClsFunc( "CService()\n" );
  45. InterlockIncrement( g_cObjects );
  46. TraceFuncExit();
  47. }
  48. //
  49. // Init()
  50. //
  51. STDMETHODIMP
  52. THISCLASS::Init( )
  53. {
  54. TraceClsFunc( "Init()\n" );
  55. // IUnknown stuff
  56. BEGIN_QITABLE_IMP( CService, IShellExtInit );
  57. QITABLE_IMP( IShellExtInit );
  58. QITABLE_IMP( IShellPropSheetExt );
  59. QITABLE_IMP( IIntelliMirrorSAP );
  60. END_QITABLE_IMP( CService );
  61. Assert( _cRef == 0);
  62. Assert( !_pads );
  63. Assert( !_pszSCPDN );
  64. Assert( !_pszGroupDN );
  65. Assert( !_pszMachineName );
  66. AddRef( );
  67. _InitParams.dwSize = sizeof(_InitParams);
  68. HRESULT hr = S_OK;
  69. hr = CheckClipboardFormats( );
  70. // Private Members
  71. Assert( _pads == NULL );
  72. _uMode = MODE_SHELL; // default
  73. HRETURN(hr);
  74. }
  75. STDMETHODIMP
  76. THISCLASS::Init2( IADs * pads )
  77. {
  78. TraceClsFunc( "Init2( " );
  79. TraceMsg( TF_FUNC, "pads = 0x%08x )\n", pads );
  80. HRESULT hr;
  81. if ( !pads )
  82. HRETURN(E_INVALIDARG);
  83. _pads = pads;
  84. _pads->AddRef( );
  85. hr = _GetComputerNameFromADs( );
  86. if (FAILED( hr ))
  87. goto Error;
  88. Error:
  89. HRETURN(hr);
  90. }
  91. //
  92. // Destructor
  93. //
  94. THISCLASS::~THISCLASS( )
  95. {
  96. TraceClsFunc( "~CService()\n" );
  97. // Private Members
  98. if ( _pads )
  99. {
  100. //
  101. // note: we shouldn't commit anything in the destructor -- we can't
  102. // catch failures here. We'll just have to make sure that we
  103. // explicitly commit changes when necessary
  104. //
  105. #if 0
  106. // Commit any changes before we release
  107. THR( _pads->SetInfo( ) );
  108. #endif
  109. _pads->Release( );
  110. }
  111. if ( _pszSCPDN )
  112. TraceFree( _pszSCPDN );
  113. if ( _pszGroupDN )
  114. TraceFree( _pszGroupDN );
  115. if ( _pszMachineName )
  116. TraceFree( _pszMachineName );
  117. if ( _pszDSServerName )
  118. TraceFree( _pszDSServerName );
  119. if ( _pDataObj )
  120. _pDataObj->Release( );
  121. #if 0 // EricB might be adding an AddRef( ) to this. Until then, don't release.
  122. if ( _InitParams.pDsObj )
  123. _InitParams.pDsObj->Release( );
  124. #endif
  125. InterlockDecrement( g_cObjects );
  126. TraceFuncExit();
  127. };
  128. // ************************************************************************
  129. //
  130. // IUnknown
  131. //
  132. // ************************************************************************
  133. //
  134. // QueryInterface()
  135. //
  136. STDMETHODIMP
  137. THISCLASS::QueryInterface(
  138. REFIID riid,
  139. LPVOID *ppv )
  140. {
  141. TraceClsFunc( "" );
  142. HRESULT hr = ::QueryInterface( this, _QITable, riid, ppv );
  143. QIRETURN( hr, riid );
  144. }
  145. //
  146. // AddRef()
  147. //
  148. STDMETHODIMP_(ULONG)
  149. THISCLASS::AddRef( void )
  150. {
  151. TraceClsFunc( "[IUnknown] AddRef( )\n" );
  152. InterlockIncrement( _cRef );
  153. RETURN(_cRef);
  154. }
  155. //
  156. // Release()
  157. //
  158. STDMETHODIMP_(ULONG)
  159. THISCLASS::Release( void )
  160. {
  161. TraceClsFunc( "[IUnknown] Release( )\n" );
  162. InterlockDecrement( _cRef );
  163. if ( _cRef )
  164. RETURN(_cRef);
  165. TraceDo( delete this );
  166. RETURN(0);
  167. }
  168. // ************************************************************************
  169. //
  170. // IShellExtInit
  171. //
  172. // ************************************************************************
  173. //
  174. // Initialize()
  175. //
  176. HRESULT
  177. THISCLASS::Initialize(
  178. LPCITEMIDLIST pidlFolder,
  179. LPDATAOBJECT lpdobj, HKEY hkeyProgID)
  180. {
  181. TraceClsFunc( "[IShellExtInit] Initialize( " );
  182. TraceMsg( TF_FUNC, " pidlFolder = 0x%08x, lpdobj = 0x%08x, hkeyProgID = 0x%08x )\n",
  183. pidlFolder, lpdobj, hkeyProgID );
  184. if ( !lpdobj )
  185. RETURN(E_INVALIDARG);
  186. HRESULT hr = S_OK;
  187. FORMATETC fmte;
  188. STGMEDIUM stg = { 0 };
  189. STGMEDIUM stgOptions = { 0 };
  190. LPWSTR pszObjectName;
  191. LPWSTR pszClassName;
  192. LPWSTR pszAttribPrefix;
  193. LPDSOBJECT pDsObject;
  194. LPDSOBJECTNAMES pDsObjectNames;
  195. LPDSDISPLAYSPECOPTIONS pDsDisplayOptions;
  196. BOOL b;
  197. #if 0
  198. IADs * padsGroup = NULL;
  199. LPWSTR pszGroupClass = NULL;
  200. LPWSTR pszParent = NULL;
  201. #endif
  202. _pDataObj = lpdobj;
  203. _pDataObj->AddRef( );
  204. //
  205. // Retrieve the Object Names
  206. //
  207. fmte.cfFormat = (CLIPFORMAT)g_cfDsObjectNames;
  208. fmte.tymed = TYMED_HGLOBAL;
  209. fmte.dwAspect = DVASPECT_CONTENT;
  210. fmte.lindex = -1;
  211. fmte.ptd = 0;
  212. hr = THR( _pDataObj->GetData( &fmte, &stg) );
  213. if ( hr )
  214. goto Cleanup;
  215. pDsObjectNames = (LPDSOBJECTNAMES) stg.hGlobal;
  216. Assert( stg.tymed == TYMED_HGLOBAL );
  217. TraceMsg( TF_ALWAYS, "Object's Namespace CLSID: " );
  218. TraceMsgGUID( TF_ALWAYS, pDsObjectNames->clsidNamespace );
  219. TraceMsg( TF_ALWAYS, "\tNumber of Objects: %u \n", pDsObjectNames->cItems );
  220. Assert( pDsObjectNames->cItems == 1 );
  221. pDsObject = (LPDSOBJECT) pDsObjectNames->aObjects;
  222. pszObjectName = (LPWSTR) PtrToByteOffset( pDsObjectNames, pDsObject->offsetName );
  223. pszClassName = (LPWSTR) PtrToByteOffset( pDsObjectNames, pDsObject->offsetClass );
  224. TraceMsg( TF_ALWAYS, "Object Name (Class): %s (%s)\n", pszObjectName, pszClassName );
  225. _pszDSServerName = TraceStrDup( pszObjectName );
  226. //
  227. // If they handed us a "Computer" object, look at the NETBOOTSAP
  228. // attribute to get the IMSAP object.
  229. //
  230. if ( StrCmp( pszClassName, DSCOMPUTERCLASSNAME ) == 0 )
  231. {
  232. IADs* pads = NULL;
  233. VARIANT var;
  234. VariantInit( &var );
  235. Assert( !_pszMachineName );
  236. //
  237. // Bind to the MAO in the DS
  238. //
  239. hr = THR( ADsGetObject( pszObjectName, IID_IADs, (void **)&pads ) );
  240. if (FAILED( hr ))
  241. goto Computer_Cleanup;
  242. hr = THR( pads->Get( NETBOOTSAP, &var ) );
  243. if (FAILED( hr ))
  244. goto Computer_Cleanup;
  245. Assert( V_VT( &var ) == VT_BSTR );
  246. // Try to parse the string to connect to the same server as the DSADMIN
  247. hr = _FixObjectPath( V_BSTR( &var ), &_pszSCPDN );
  248. if (FAILED( hr ))
  249. goto Computer_Cleanup;
  250. DebugMsg( "SCP Path: %s\n", _pszSCPDN );
  251. VariantClear( &var );
  252. // while we are here, might as well get the server's NETBIOS name
  253. hr = THR( pads->Get( SAMNAME, &var ) );
  254. if (FAILED( hr ))
  255. goto Computer_Cleanup;
  256. Assert( V_VT( &var) == VT_BSTR );
  257. _pszMachineName = TraceStrDup( V_BSTR( &var ) );
  258. if ( _pszMachineName )
  259. {
  260. LPWSTR psz = &_pszMachineName[ wcslen( _pszMachineName ) - 1 ];
  261. if ( *psz == L'$' )
  262. {
  263. *psz = L'\0';
  264. }
  265. DebugMsg( "Server Name: %ws\n", _pszMachineName );
  266. }
  267. Computer_Cleanup:
  268. VariantClear( &var );
  269. if ( pads )
  270. pads->Release( );
  271. if (FAILED( hr ))
  272. goto Error;
  273. // create the DS notify object
  274. hr = THR( ADsPropCreateNotifyObj( _pDataObj, pszObjectName, &_hwndNotify ) );
  275. if (FAILED( hr ))
  276. goto Error;
  277. b = ADsPropGetInitInfo( _hwndNotify, &_InitParams );
  278. if ( !b )
  279. {
  280. hr = E_FAIL;
  281. goto Error;
  282. }
  283. hr = THR( _InitParams.hr );
  284. if (FAILED( hr ))
  285. goto Error;
  286. // Bind to the IMSAP in the DS
  287. Assert( _pszSCPDN );
  288. hr = THR( ADsGetObject( _pszSCPDN, IID_IADs, (void **)&_pads ) );
  289. if (FAILED( hr ))
  290. goto Error;
  291. }
  292. else if ( StrCmp( pszClassName, DSIMSAPCLASSNAME ) )
  293. {
  294. //
  295. // This should be a IMSAP.
  296. //
  297. hr = E_INVALIDARG;
  298. goto Error;
  299. }
  300. else
  301. {
  302. // Keep the DN around
  303. _pszSCPDN = TraceStrDup( pszObjectName );
  304. Assert( !_pszMachineName );
  305. // create the DS notify object
  306. hr = THR( ADsPropCreateNotifyObj( _pDataObj, pszObjectName, &_hwndNotify ) );
  307. if (FAILED( hr ))
  308. goto Error;
  309. b = ADsPropGetInitInfo( _hwndNotify, &_InitParams );
  310. if ( !b )
  311. {
  312. hr = E_FAIL;
  313. goto Error;
  314. }
  315. hr = THR( _InitParams.hr );
  316. if (FAILED( hr ))
  317. goto Error;
  318. // Bind to the IMSAP in the DS
  319. Assert( _pszSCPDN );
  320. hr = THR( _InitParams.pDsObj->QueryInterface( IID_IADs, (void **)&_pads ) );
  321. if (FAILED( hr ))
  322. goto Error;
  323. }
  324. Assert( _pads );
  325. //
  326. // Retrieve the Display Spec Options
  327. //
  328. fmte.cfFormat = (CLIPFORMAT)g_cfDsDisplaySpecOptions;
  329. fmte.tymed = TYMED_HGLOBAL;
  330. fmte.dwAspect = DVASPECT_CONTENT;
  331. fmte.lindex = -1;
  332. fmte.ptd = 0;
  333. hr = THR( _pDataObj->GetData( &fmte, &stgOptions ) );
  334. if ( hr )
  335. goto Error;
  336. pDsDisplayOptions = (LPDSDISPLAYSPECOPTIONS) stgOptions.hGlobal;
  337. Assert( stgOptions.tymed == TYMED_HGLOBAL );
  338. Assert( pDsDisplayOptions->dwSize == sizeof(DSDISPLAYSPECOPTIONS) );
  339. pszAttribPrefix = (LPWSTR) PtrToByteOffset( pDsDisplayOptions, pDsDisplayOptions->offsetAttribPrefix );
  340. // TraceMsg( TF_ALWAYS, TEXT("Attribute Prefix: %s\n"), pszAttribPrefix );
  341. if ( StrCmpW( pszAttribPrefix, STRING_ADMIN ) == 0 )
  342. {
  343. _uMode = MODE_ADMIN;
  344. }
  345. // else default from Init()
  346. TraceMsg( TF_ALWAYS, TEXT("Mode: %s\n"), _uMode == MODE_ADMIN ? TEXT("Admin") : TEXT("Shell") );
  347. ReleaseStgMedium( &stgOptions );
  348. #if 0
  349. //
  350. // Check to see if it is in a Group by checking the parent DN's class
  351. //
  352. pszParent = StrChr( _pszSCPDN, L',' );
  353. Assert( pszParent );
  354. if ( !pszParent ) {
  355. hr = THR(E_FAIL);
  356. goto Error;
  357. }
  358. pszParent++; // move just past the comma
  359. // create a new string by adding "LDAP://server/"
  360. hr = _FixObjectPath( pszParent, &pszParent );
  361. if (FAILED( hr ))
  362. goto Error;
  363. // Bind to the object
  364. hr = THR( ADsGetObject( pszParent, IID_IADs, (void **)&padsGroup ) );
  365. if (FAILED( hr ))
  366. goto Error;
  367. Assert( !pszGroupClass );
  368. hr = THR( padsGroup->get_Class( &pszGroupClass ) );
  369. if (FAILED( hr ))
  370. goto Error;
  371. Assert( !_pszGroupDN );
  372. DebugMsg( "SCP's parents Class is '%s'\n", pszGroupClass );
  373. if ( StrCmpI( pszGroupClass, DSGROUPCLASSNAME ) == 0 ) {
  374. _pszGroupDN = (LPWSTR) TraceStrDup( pszObjectName );
  375. TraceMsg( TF_ALWAYS, TEXT("Server is in group: %s\n"), _pszGroupDN );
  376. }
  377. #endif
  378. Cleanup:
  379. #if 0
  380. if ( pszGroupClass )
  381. SysFreeString( pszGroupClass );
  382. if ( pszParent )
  383. TraceFree( pszParent );
  384. if ( padsGroup )
  385. padsGroup->Release();
  386. #endif
  387. HRETURN(hr);
  388. Error:
  389. MessageBoxFromHResult( NULL, IDS_ERROR_READINGCOMPUTERACCOUNT, hr );
  390. goto Cleanup;
  391. }
  392. // ************************************************************************
  393. //
  394. // IShellPropSheetExt
  395. //
  396. // ************************************************************************
  397. //
  398. // AddPages()
  399. //
  400. HRESULT
  401. THISCLASS::AddPages(
  402. LPFNADDPROPSHEETPAGE lpfnAddPage,
  403. LPARAM lParam)
  404. {
  405. TraceClsFunc( "[IShellPropSheetExt] AddPages( )\n" );
  406. if ( !lpfnAddPage )
  407. RRETURN(E_POINTER);
  408. HRESULT hr = S_OK;
  409. hr = THR( ::AddPagesEx( NULL,
  410. CNewClientsTab_CreateInstance,
  411. lpfnAddPage,
  412. lParam,
  413. (LPUNKNOWN) (IShellExtInit*) this ) );
  414. if (FAILED( hr ))
  415. goto Error;
  416. hr = THR( ::AddPagesEx( NULL,
  417. CIntelliMirrorOSTab_CreateInstance,
  418. lpfnAddPage,
  419. lParam,
  420. (LPUNKNOWN) (IShellExtInit*) this ) );
  421. if (FAILED( hr ))
  422. goto Error;
  423. #ifdef LOCALOS_PAGE
  424. hr = THR( ::AddPagesEx( NULL,
  425. CLocalInstallOSTab_CreateInstance,
  426. lpfnAddPage,
  427. lParam,
  428. (LPUNKNOWN) (IShellExtInit*) this ) );
  429. if (FAILED( hr ))
  430. goto Error;
  431. #endif // LOCALOS_PAGE
  432. hr = THR( ::AddPagesEx( NULL,
  433. CToolsTab_CreateInstance,
  434. lpfnAddPage,
  435. lParam,
  436. (LPUNKNOWN) (IShellExtInit*) this ) );
  437. if (FAILED( hr ))
  438. goto Error;
  439. Error:
  440. HRETURN(hr);
  441. }
  442. //
  443. // ReplacePage()
  444. //
  445. HRESULT
  446. THISCLASS::ReplacePage(
  447. UINT uPageID,
  448. LPFNADDPROPSHEETPAGE lpfnReplaceWith,
  449. LPARAM lParam )
  450. {
  451. TraceClsFunc( "[IShellPropSheetExt] ReplacePage( ) *** NOT_IMPLEMENTED ***\n" );
  452. RETURN(E_NOTIMPL);
  453. }
  454. // ************************************************************************
  455. //
  456. // IIntelliMirrorSAP
  457. //
  458. // ************************************************************************
  459. //
  460. // CommitChanges( )
  461. //
  462. HRESULT
  463. THISCLASS::CommitChanges( void )
  464. {
  465. TraceClsFunc( "[IIntelliMirrorSAP] CommitChanges( )\n" );
  466. Assert( _pads );
  467. HRESULT hr;
  468. SC_HANDLE schManager = NULL;
  469. SC_HANDLE sch = NULL;
  470. SERVICE_STATUS ss;
  471. hr = THR( _pads->SetInfo( ) );
  472. if ( FAILED( hr ) )
  473. goto Error;
  474. // if we don't have this yet, get it now.
  475. if ( !_pszMachineName )
  476. {
  477. hr = _GetComputerNameFromADs( );
  478. if (FAILED( hr ))
  479. goto Error;
  480. }
  481. schManager = OpenSCManager( _pszMachineName, NULL, SC_MANAGER_CONNECT );
  482. if (!schManager)
  483. {
  484. DWORD dwErr = GetLastError( );
  485. hr = HRESULT_FROM_WIN32( dwErr );
  486. goto Error;
  487. }
  488. sch = OpenService( schManager, BINL_SERVER_NAME, SERVICE_USER_DEFINED_CONTROL);
  489. if (!sch)
  490. {
  491. DWORD dwErr = GetLastError( );
  492. hr = HRESULT_FROM_WIN32( dwErr );
  493. goto Error;
  494. }
  495. if ( !ControlService( sch, BINL_SERVICE_REREAD_SETTINGS, &ss ) )
  496. {
  497. DWORD dwErr = GetLastError( );
  498. hr = THR(HRESULT_FROM_WIN32( dwErr ));
  499. goto Error;
  500. }
  501. hr = HRESULT_FROM_WIN32( ss.dwWin32ExitCode );
  502. Error:
  503. if ( sch )
  504. CloseServiceHandle( sch );
  505. if ( schManager )
  506. CloseServiceHandle( schManager );
  507. if ( hr == HRESULT_FROM_WIN32( ERROR_SERVICE_NOT_ACTIVE ) )
  508. {
  509. hr = S_OK; // ignore error... by design
  510. }
  511. HRETURN(hr);
  512. }
  513. //
  514. // IsAdmin( )
  515. //
  516. HRESULT
  517. THISCLASS::IsAdmin(
  518. BOOL * fAdmin )
  519. {
  520. TraceClsFunc( "[IIntelliMirrorSAP] IsAdmin( )\n" );
  521. if ( !fAdmin )
  522. RRETURN( E_INVALIDARG );
  523. HRESULT hr = S_OK;
  524. *fAdmin = (_uMode == MODE_ADMIN);
  525. HRETURN(hr);
  526. }
  527. //
  528. // GetAllowNewClients( )
  529. //
  530. HRESULT
  531. THISCLASS::GetAllowNewClients(
  532. BOOL *pbool )
  533. {
  534. TraceClsFunc("[IIntelliMirrorSAP] GetAllowNewClients( ... )\n" );
  535. if ( !pbool )
  536. RRETURN(E_POINTER);
  537. HRESULT hr;
  538. VARIANT var;
  539. VariantInit( &var );
  540. Assert( _pads );
  541. hr = _pads->Get( NETBOOTALLOWNEWCLIENTS, &var );
  542. if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
  543. goto Cleanup;
  544. if ( V_VT(&var) == VT_BOOL )
  545. {
  546. *pbool = V_BOOL(&var);
  547. hr = S_OK;
  548. }
  549. Cleanup:
  550. VariantClear( &var );
  551. HRETURN(hr);
  552. }
  553. //
  554. // SetAllowNewClients( )
  555. //
  556. HRESULT
  557. THISCLASS::SetAllowNewClients(
  558. BOOL boolval )
  559. {
  560. TraceClsFunc("[IIntelliMirrorSAP] SetAllowNewClients( ... )\n" );
  561. HRESULT hr;
  562. VARIANT var;
  563. VariantInit( &var );
  564. V_VT( &var ) = VT_BOOL;
  565. V_BOOL( &var ) = (VARIANT_BOOL)boolval;
  566. Assert( _pads );
  567. hr = THR( _pads->Put( NETBOOTALLOWNEWCLIENTS, var ) );
  568. VariantClear( &var );
  569. HRETURN(hr);
  570. }
  571. //
  572. // GetLimitClients( )
  573. //
  574. HRESULT
  575. THISCLASS::GetLimitClients(
  576. BOOL *pbool )
  577. {
  578. TraceClsFunc("[IIntelliMirrorSAP] GetLimitClients( ... )\n" );
  579. if ( !pbool )
  580. RRETURN(E_POINTER);
  581. HRESULT hr;
  582. VARIANT var;
  583. VariantInit( &var );
  584. Assert( _pads );
  585. hr = _pads->Get( NETBOOTLIMITCLIENTS, &var );
  586. if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
  587. goto Cleanup;
  588. if ( V_VT(&var) == VT_BOOL )
  589. {
  590. *pbool = V_BOOL(&var);
  591. hr = S_OK;
  592. }
  593. Cleanup:
  594. VariantClear( &var );
  595. HRETURN(hr);
  596. }
  597. //
  598. // SetLimitClients( )
  599. //
  600. HRESULT
  601. THISCLASS::SetLimitClients(
  602. BOOL boolval )
  603. {
  604. TraceClsFunc("[IIntelliMirrorSAP] SetLimitClients( ... )\n" );
  605. HRESULT hr;
  606. VARIANT var;
  607. VariantInit( &var );
  608. V_VT( &var ) = VT_BOOL;
  609. V_BOOL( &var ) = (VARIANT_BOOL)boolval;
  610. Assert( _pads );
  611. hr = THR( _pads->Put( NETBOOTLIMITCLIENTS, var ) );
  612. VariantClear( &var );
  613. HRETURN(hr);
  614. }
  615. //
  616. // GetMaxClients( )
  617. //
  618. HRESULT
  619. THISCLASS::GetMaxClients(
  620. UINT *puMax )
  621. {
  622. TraceClsFunc("[IIntelliMirrorSAP] GetMaxClients( ... )\n" );
  623. if ( !puMax )
  624. RRETURN(E_POINTER);
  625. HRESULT hr;
  626. VARIANT var;
  627. VariantInit( &var );
  628. Assert( _pads );
  629. hr = _pads->Get( NETBOOTMAXCLIENTS, &var );
  630. if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
  631. goto Cleanup;
  632. if ( V_VT(&var) == VT_I4 )
  633. {
  634. *puMax = V_I4(&var);
  635. hr = S_OK;
  636. }
  637. Cleanup:
  638. VariantClear( &var );
  639. HRETURN(hr);
  640. }
  641. //
  642. // SetMaxClients( )
  643. //
  644. HRESULT
  645. THISCLASS::SetMaxClients(
  646. UINT uMax )
  647. {
  648. TraceClsFunc("[IIntelliMirrorSAP] SetMaxClients( ... )\n" );
  649. HRESULT hr;
  650. VARIANT var;
  651. VariantInit( &var );
  652. V_VT( &var ) = VT_I4;
  653. V_I4( &var ) = uMax;
  654. Assert( _pads );
  655. hr = THR( _pads->Put( NETBOOTMAXCLIENTS, var ) );
  656. VariantClear( &var );
  657. HRETURN(hr);
  658. }
  659. //
  660. // GetCurrentClientCount( )
  661. //
  662. HRESULT
  663. THISCLASS::GetCurrentClientCount(
  664. UINT *puCount )
  665. {
  666. TraceClsFunc("[IIntelliMirrorSAP] GetCurrentClientCount( ... )\n" );
  667. if ( !puCount )
  668. RRETURN(E_POINTER);
  669. HRESULT hr;
  670. VARIANT var;
  671. VariantInit( &var );
  672. Assert( _pads );
  673. hr = _pads->Get( NETBOOTCURRENTCLIENTCOUNT, &var );
  674. if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
  675. goto Cleanup;
  676. if ( V_VT(&var) == VT_I4 )
  677. {
  678. *puCount = V_I4(&var);
  679. hr = S_OK;
  680. }
  681. Cleanup:
  682. VariantClear( &var );
  683. HRETURN(hr);
  684. }
  685. //
  686. // SetCurrentClientCount( )
  687. //
  688. HRESULT
  689. THISCLASS::SetCurrentClientCount(
  690. UINT uCount )
  691. {
  692. TraceClsFunc("[IIntelliMirrorSAP] SetCurrentClientCount( ... )\n" );
  693. HRESULT hr;
  694. VARIANT var;
  695. VariantInit( &var );
  696. V_VT( &var ) = VT_I4;
  697. V_I4( &var ) = uCount;
  698. Assert( _pads );
  699. hr = THR( _pads->Put( NETBOOTCURRENTCLIENTCOUNT, var ) );
  700. VariantClear( &var );
  701. HRETURN(hr);
  702. }
  703. //
  704. // GetAnswerRequests( )
  705. //
  706. HRESULT
  707. THISCLASS::GetAnswerRequests(
  708. BOOL *pbool )
  709. {
  710. TraceClsFunc("[IIntelliMirrorSAP] GetAnswerRequests( ... )\n" );
  711. if ( !pbool )
  712. RRETURN(E_POINTER);
  713. HRESULT hr;
  714. VARIANT var;
  715. VariantInit( &var );
  716. Assert( _pads );
  717. hr = _pads->Get( NETBOOTANSWERREQUESTS, &var );
  718. if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
  719. goto Cleanup;
  720. if ( V_VT(&var) == VT_BOOL )
  721. {
  722. *pbool = V_BOOL(&var);
  723. hr = S_OK;
  724. }
  725. Cleanup:
  726. VariantClear( &var );
  727. HRETURN(hr);
  728. }
  729. //
  730. // SetAnswerRequests( )
  731. //
  732. HRESULT
  733. THISCLASS::SetAnswerRequests(
  734. BOOL boolval )
  735. {
  736. TraceClsFunc("[IIntelliMirrorSAP] SetAnswerRequests( ... )\n" );
  737. HRESULT hr;
  738. VARIANT var;
  739. VariantInit( &var );
  740. V_VT( &var ) = VT_BOOL;
  741. V_BOOL( &var ) = (VARIANT_BOOL)boolval;
  742. Assert( _pads );
  743. hr = THR( _pads->Put( NETBOOTANSWERREQUESTS, var ) );
  744. VariantClear( &var );
  745. HRETURN(hr);
  746. }
  747. //
  748. // GetAnswerOnlyValidClients( )
  749. //
  750. HRESULT
  751. THISCLASS::GetAnswerOnlyValidClients(
  752. BOOL *pbool )
  753. {
  754. TraceClsFunc("[IIntelliMirrorSAP] GetAnswerOnlyValidClients( ... )\n" );
  755. if ( !pbool )
  756. RRETURN(E_POINTER);
  757. HRESULT hr;
  758. VARIANT var;
  759. VariantInit( &var );
  760. Assert( _pads );
  761. hr = _pads->Get( NETBOOTANSWERONLYVALIDCLIENTS, &var );
  762. if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
  763. goto Cleanup;
  764. if ( V_VT(&var) == VT_BOOL )
  765. {
  766. *pbool = V_BOOL(&var);
  767. hr = S_OK;
  768. }
  769. Cleanup:
  770. VariantClear( &var );
  771. HRETURN(hr);
  772. }
  773. //
  774. // SetAnswerOnlyValidClients( )
  775. //
  776. HRESULT
  777. THISCLASS::SetAnswerOnlyValidClients(
  778. BOOL boolval )
  779. {
  780. TraceClsFunc("[IIntelliMirrorSAP] SetAnswerOnlyValidClients( ... )\n" );
  781. HRESULT hr;
  782. VARIANT var;
  783. VariantInit( &var );
  784. V_VT( &var ) = VT_BOOL;
  785. V_BOOL( &var ) = (VARIANT_BOOL)boolval;
  786. Assert( _pads );
  787. hr = THR( _pads->Put( NETBOOTANSWERONLYVALIDCLIENTS, var ) );
  788. VariantClear( &var );
  789. HRETURN(hr);
  790. }
  791. //
  792. // GetNewMachineNamingPolicy( )
  793. //
  794. HRESULT
  795. THISCLASS::GetNewMachineNamingPolicy(
  796. LPWSTR *pwsz )
  797. {
  798. TraceClsFunc("[IIntelliMirrorSAP] GetNewMachineNamingPolicy( ... )\n" );
  799. if ( !pwsz )
  800. RRETURN(E_POINTER);
  801. HRESULT hr;
  802. VARIANT var;
  803. VariantInit( &var );
  804. Assert( _pads );
  805. hr = _pads->Get( NETBOOTNEWMACHINENAMINGPOLICY, &var );
  806. if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
  807. goto Cleanup;
  808. if ( V_VT(&var) == VT_BSTR )
  809. {
  810. *pwsz = TraceStrDup( V_BSTR(&var) );
  811. if (!*pwsz)
  812. {
  813. hr = E_OUTOFMEMORY;
  814. }
  815. }
  816. Cleanup:
  817. VariantClear( &var );
  818. HRETURN(hr);
  819. }
  820. //
  821. // SetNewMachineNamingPolicy( )
  822. //
  823. HRESULT
  824. THISCLASS::SetNewMachineNamingPolicy(
  825. LPWSTR pwsz )
  826. {
  827. TraceClsFunc("[IIntelliMirrorSAP] SetNewMachineNamingPolicy( ... )\n" );
  828. HRESULT hr;
  829. VARIANT var;
  830. Assert( _pads );
  831. if ( pwsz )
  832. {
  833. V_VT( &var ) = VT_BSTR;
  834. V_BSTR( &var ) = SysAllocString( pwsz );
  835. if (V_BSTR(&var) == NULL) {
  836. RRETURN(E_OUTOFMEMORY);
  837. }
  838. hr = THR( _pads->Put( NETBOOTNEWMACHINENAMINGPOLICY, var ) );
  839. VariantClear( &var );
  840. }
  841. else
  842. {
  843. VariantInit( &var );
  844. hr = THR( _pads->PutEx( ADS_PROPERTY_CLEAR, NETBOOTNEWMACHINENAMINGPOLICY, var ) );
  845. }
  846. HRETURN(hr);
  847. }
  848. //
  849. // GetNewMachineOU( )
  850. //
  851. HRESULT
  852. THISCLASS::GetNewMachineOU(
  853. LPWSTR *pwsz )
  854. {
  855. TraceClsFunc("[IIntelliMirrorSAP] GetNewMachineOU( ... )\n" );
  856. if ( !pwsz )
  857. RRETURN(E_POINTER);
  858. HRESULT hr;
  859. VARIANT var;
  860. VariantInit( &var );
  861. Assert( _pads );
  862. hr = _pads->Get( NETBOOTNEWMACHINEOU, &var );
  863. if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
  864. goto Cleanup;
  865. if ( V_VT(&var) == VT_BSTR )
  866. {
  867. *pwsz = TraceStrDup( V_BSTR(&var) );
  868. if (!*pwsz)
  869. {
  870. hr = E_OUTOFMEMORY;
  871. }
  872. }
  873. Cleanup:
  874. VariantClear( &var );
  875. HRETURN(hr);
  876. }
  877. //
  878. // SetNewMachineOU( )
  879. //
  880. HRESULT
  881. THISCLASS::SetNewMachineOU(
  882. LPWSTR pwsz )
  883. {
  884. TraceClsFunc("[IIntelliMirrorSAP] SetNewMachineOU( ... )\n" );
  885. HRESULT hr;
  886. VARIANT var;
  887. Assert( _pads );
  888. if ( pwsz )
  889. {
  890. V_VT( &var ) = VT_BSTR;
  891. V_BSTR( &var ) = SysAllocString( pwsz );
  892. if (V_BSTR(&var) == NULL) {
  893. RRETURN(E_OUTOFMEMORY);
  894. }
  895. hr = THR( _pads->Put( NETBOOTNEWMACHINEOU, var ) );
  896. VariantClear( &var );
  897. }
  898. else
  899. {
  900. VariantInit( &var );
  901. hr = THR( _pads->PutEx( ADS_PROPERTY_CLEAR, NETBOOTNEWMACHINEOU, var ) );
  902. }
  903. HRETURN(hr);
  904. }
  905. //
  906. // EnumIntelliMirrorOSes( )
  907. //
  908. HRESULT
  909. THISCLASS::EnumIntelliMirrorOSes(
  910. DWORD dwFlags,
  911. LPUNKNOWN *punk )
  912. {
  913. TraceClsFunc("[IIntelliMirrorSAP] EnumIntelliMirrorOSes( ... )\n" );
  914. if ( !punk )
  915. RRETURN(E_INVALIDARG);
  916. HRESULT hr = S_OK;
  917. Assert( _pads );
  918. *punk = (LPUNKNOWN)
  919. CEnumIMSIFs_CreateInstance( REMOTE_INSTALL_IMAGE_DIR_W, NETBOOTINTELLIMIRROROSES, dwFlags, _pads );
  920. if ( !*punk )
  921. {
  922. hr = E_FAIL;
  923. }
  924. HRETURN(hr);
  925. }
  926. //
  927. // EnumTools( )
  928. //
  929. HRESULT
  930. THISCLASS::EnumTools(
  931. DWORD dwFlags,
  932. LPUNKNOWN *punk )
  933. {
  934. TraceClsFunc("[IIntelliMirrorSAP] EnumTools( ... )\n" );
  935. if ( !punk )
  936. RETURN(E_INVALIDARG);
  937. HRESULT hr = S_OK;
  938. Assert( _pads );
  939. *punk = (LPUNKNOWN)
  940. CEnumIMSIFs_CreateInstance( REMOTE_INSTALL_TOOLS_DIR_W, NETBOOTTOOLS, dwFlags, _pads );
  941. if ( !*punk )
  942. {
  943. hr = E_FAIL;
  944. }
  945. HRETURN(hr);}
  946. //
  947. // EnumLocalInstallOSes( )
  948. //
  949. HRESULT
  950. THISCLASS::EnumLocalInstallOSes(
  951. DWORD dwFlags,
  952. LPUNKNOWN *punk )
  953. {
  954. TraceClsFunc("[IIntelliMirrorSAP] EnumLocalInstallOSes( ... )\n" );
  955. if ( !punk )
  956. RRETURN(E_INVALIDARG);
  957. HRESULT hr = S_OK;
  958. Assert( _pads );
  959. #if 0
  960. *punk = (LPUNKNOWN)
  961. CEnumIMSIFs_CreateInstance( LOCALOSES, NETBOOTLOCALINSTALLOSES, dwFlags, _pads );
  962. #else
  963. *punk = NULL;
  964. #endif
  965. if ( !*punk )
  966. {
  967. hr = E_FAIL;
  968. }
  969. HRETURN(hr);}
  970. //
  971. // GetServerDN( )
  972. //
  973. HRESULT
  974. THISCLASS::GetServerDN(
  975. LPWSTR *pwsz )
  976. {
  977. TraceClsFunc("[IIntelliMirrorSAP] GetServerDN( ... )\n" );
  978. if ( !pwsz )
  979. RRETURN(E_POINTER);
  980. HRESULT hr;
  981. VARIANT var;
  982. VariantInit( &var );
  983. Assert( _pads );
  984. hr = _pads->Get( NETBOOTSERVER, &var );
  985. if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
  986. goto Cleanup;
  987. if ( V_VT(&var) == VT_BSTR )
  988. {
  989. *pwsz = TraceStrDup( V_BSTR(&var) );
  990. if ( !*pwsz )
  991. {
  992. hr = E_OUTOFMEMORY;
  993. }
  994. }
  995. Cleanup:
  996. VariantClear( &var );
  997. HRETURN(hr);
  998. }
  999. //
  1000. // SetServerDN( )
  1001. //
  1002. HRESULT
  1003. THISCLASS::SetServerDN(
  1004. LPWSTR pwsz )
  1005. {
  1006. TraceClsFunc("[IIntelliMirrorSAP] SetServerDN( ... )\n" );
  1007. if ( !pwsz )
  1008. RRETURN(E_INVALIDARG);
  1009. HRESULT hr;
  1010. VARIANT var;
  1011. V_VT( &var ) = VT_BSTR;
  1012. V_BSTR( &var ) = SysAllocString( pwsz );
  1013. if (V_BSTR(&var) == NULL) {
  1014. RRETURN(E_OUTOFMEMORY);
  1015. }
  1016. Assert( _pads );
  1017. hr = THR( _pads->Put( NETBOOTSERVER, var ) );
  1018. VariantClear( &var );
  1019. HRETURN(hr);
  1020. }
  1021. //
  1022. // GetDefaultIntelliMirrorOS( )
  1023. //
  1024. HRESULT
  1025. THISCLASS::GetDefaultIntelliMirrorOS(
  1026. LPWSTR * pszName,
  1027. LPWSTR * pszTimeout )
  1028. {
  1029. TraceClsFunc( "[IIntelliMirrorSAP] GetDefaultIntelliMirrorOS( ...)\n" );
  1030. HRESULT hr;
  1031. hr = _GetDefaultSIF( NETBOOTINTELLIMIRROROSES, pszName, pszTimeout );
  1032. HRETURN(hr);
  1033. }
  1034. //
  1035. // SetDefaultIntelliMirrorOS( )
  1036. //
  1037. HRESULT
  1038. THISCLASS::SetDefaultIntelliMirrorOS(
  1039. LPWSTR pszName,
  1040. LPWSTR pszTimeout )
  1041. {
  1042. TraceClsFunc( "[IIntelliMirrorSAP] SetDefaultIntelliMirrorOS( " );
  1043. TraceMsg( TF_FUNC, "pszName = '%s', pszTimeout = '%s' )\n",
  1044. pszName, pszTimeout );
  1045. HRESULT hr;
  1046. hr = _SetDefaultSIF( NETBOOTINTELLIMIRROROSES, pszName, pszTimeout );
  1047. HRETURN(hr);
  1048. }
  1049. //
  1050. // _GetDefaultSIF( )
  1051. //
  1052. HRESULT
  1053. THISCLASS::_GetDefaultSIF(
  1054. LPWSTR pszAttribute,
  1055. LPWSTR * pszName,
  1056. LPWSTR * pszTimeout )
  1057. {
  1058. TraceClsFunc( "_GetDefaultSIF( " );
  1059. TraceMsg( TF_FUNC, "pszAttribute = '%s', ... )\n" , pszAttribute );
  1060. if ( !pszAttribute )
  1061. RRETURN(E_POINTER);
  1062. if ( !pszName )
  1063. RRETURN(E_POINTER);
  1064. if ( !pszTimeout )
  1065. RRETURN(E_POINTER);
  1066. HRESULT hr;
  1067. LONG lUBound;
  1068. VARIANT var;
  1069. VARIANT * pvar;
  1070. VariantInit( &var );
  1071. *pszName = NULL;
  1072. *pszTimeout = NULL;
  1073. Assert( _pads );
  1074. hr = THR( _pads->GetEx( pszAttribute, &var ) );
  1075. if (FAILED( hr ))
  1076. goto Error;
  1077. //
  1078. // Make sure that the var is an array of VARIANTs
  1079. //
  1080. if ( V_VT( &var ) != ( VT_ARRAY | VT_VARIANT ) )
  1081. {
  1082. hr = ERROR_INVALID_DATA;
  1083. goto Error;
  1084. }
  1085. Assert( SafeArrayGetDim( V_ARRAY( &var ) ) == 1 );
  1086. #ifdef DEBUG
  1087. {
  1088. LONG lLBound;
  1089. SafeArrayGetLBound( V_ARRAY( &var ), 1, &lLBound );
  1090. Assert( lLBound == 0 );
  1091. }
  1092. #endif // DEBUG
  1093. SafeArrayGetUBound( V_ARRAY( &var ), 1, &lUBound );
  1094. //
  1095. // Copy the required data
  1096. //
  1097. SafeArrayAccessData( V_ARRAY( &var ), (void **)&pvar );
  1098. *pszName = (LPWSTR) TraceStrDup( V_BSTR( &pvar[ 0 ] ) );
  1099. if (!*pszName)
  1100. {
  1101. SafeArrayUnaccessData( V_ARRAY( &var ) );
  1102. hr = E_OUTOFMEMORY;
  1103. goto Error;
  1104. }
  1105. if ( lUBound == 2 )
  1106. {
  1107. *pszTimeout = (LPWSTR) TraceStrDup( V_BSTR( &pvar[ 1 ] ) );
  1108. if ( !*pszTimeout )
  1109. {
  1110. SafeArrayUnaccessData( V_ARRAY( &var ) );
  1111. hr = E_OUTOFMEMORY;
  1112. goto Error;
  1113. }
  1114. }
  1115. SafeArrayUnaccessData( V_ARRAY( &var ) );
  1116. Error:
  1117. VariantClear( &var );
  1118. HRETURN(hr);
  1119. }
  1120. //
  1121. // _SetDefaultSIF( )
  1122. //
  1123. HRESULT
  1124. THISCLASS::_SetDefaultSIF(
  1125. LPWSTR pszAttribute,
  1126. LPWSTR pszName,
  1127. LPWSTR pszTimeout )
  1128. {
  1129. TraceClsFunc( "_SetDefaultSIF( " );
  1130. TraceMsg( TF_FUNC, "pszAttribute = '%s', ... )\n" , pszAttribute );
  1131. if ( !pszAttribute )
  1132. RRETURN(E_POINTER);
  1133. if ( !pszName )
  1134. RRETURN(E_POINTER);
  1135. if ( !pszTimeout )
  1136. RRETURN(E_POINTER);
  1137. HRESULT hr;
  1138. LONG lUBound;
  1139. VARIANT var;
  1140. LPWSTR pszStrings[ 2 ];
  1141. pszStrings[0] = pszName;
  1142. pszStrings[1] = pszTimeout;
  1143. VariantInit( &var );
  1144. hr = THR( StringArrayToVariant( &var, pszStrings, 2 ) );
  1145. if (FAILED( hr ))
  1146. goto Error;
  1147. Assert( _pads );
  1148. hr = THR( _pads->Put( pszAttribute, var ) );
  1149. if (FAILED( hr ))
  1150. goto Error;
  1151. Error:
  1152. VariantClear( &var );
  1153. HRETURN(hr);
  1154. }
  1155. //
  1156. // GetSCPDN( )
  1157. //
  1158. HRESULT
  1159. THISCLASS::GetSCPDN(
  1160. LPWSTR * ppwsz )
  1161. {
  1162. TraceClsFunc( "[IIntelliMirrorSAP] GetSCPDN( )\n" );
  1163. HRESULT hr = S_OK;
  1164. if ( !ppwsz )
  1165. HRETURN( E_POINTER );
  1166. if ( _pszSCPDN ) {
  1167. LPWSTR psz = StrRChr( _pszSCPDN, NULL, L'/' );
  1168. if ( psz )
  1169. {
  1170. psz++;
  1171. }
  1172. else
  1173. {
  1174. psz = _pszSCPDN;
  1175. }
  1176. *ppwsz = (LPWSTR) TraceStrDup( psz );
  1177. if ( !*ppwsz )
  1178. {
  1179. hr = E_OUTOFMEMORY;
  1180. }
  1181. } else {
  1182. *ppwsz = NULL;
  1183. }
  1184. HRETURN(hr);
  1185. }
  1186. //
  1187. // GetGroupDN( )
  1188. //
  1189. HRESULT
  1190. THISCLASS::GetGroupDN(
  1191. LPWSTR * ppwsz )
  1192. {
  1193. TraceClsFunc( "[IIntelliMirrorSAP] GetGroupDN( )\n" );
  1194. HRESULT hr = S_OK;
  1195. if ( !ppwsz )
  1196. HRETURN( E_POINTER );
  1197. if ( _pszGroupDN ) {
  1198. *ppwsz = (LPWSTR) TraceStrDup( _pszGroupDN );
  1199. if ( !*ppwsz )
  1200. {
  1201. hr = E_OUTOFMEMORY;
  1202. }
  1203. } else {
  1204. *ppwsz = NULL;
  1205. hr = S_FALSE;
  1206. }
  1207. HRETURN(hr);
  1208. }
  1209. //
  1210. // GetServerName( )
  1211. //
  1212. STDMETHODIMP
  1213. THISCLASS::GetServerName(
  1214. LPWSTR * ppwsz )
  1215. {
  1216. TraceClsFunc( "[IIntelliMirrorSAP] GetServerName( )\n" );
  1217. HRESULT hr = S_OK;
  1218. if ( !ppwsz )
  1219. HRETURN(E_POINTER);
  1220. *ppwsz = NULL;
  1221. if ( !_pszMachineName )
  1222. {
  1223. hr = _GetComputerNameFromADs( );
  1224. if (FAILED( hr ))
  1225. goto Error;
  1226. }
  1227. if ( _pszMachineName )
  1228. {
  1229. *ppwsz = (LPWSTR) TraceStrDup( _pszMachineName );
  1230. if ( !*ppwsz )
  1231. {
  1232. hr = E_OUTOFMEMORY;
  1233. }
  1234. }
  1235. else
  1236. {
  1237. hr = S_FALSE;
  1238. }
  1239. Error:
  1240. HRETURN(hr);
  1241. }
  1242. //
  1243. // _GetComputerNameFromADs( )
  1244. //
  1245. HRESULT
  1246. THISCLASS::_GetComputerNameFromADs( )
  1247. {
  1248. TraceClsFunc( "_GetComputerNameFromADs( )\n" );
  1249. if ( _pszMachineName )
  1250. HRETURN(S_OK); // nop
  1251. HRESULT hr;
  1252. VARIANT var;
  1253. IADs *pads = NULL;
  1254. LPWSTR pszMachinePath = NULL;
  1255. LPWSTR psz;
  1256. VariantInit( &var );
  1257. // Retrieve the NETBOOTSERVER attribute
  1258. hr = THR( _pads->Get( NETBOOTSERVER, &var ) );
  1259. if (FAILED( hr ))
  1260. goto Cleanup;
  1261. Assert( V_VT( &var ) == VT_BSTR );
  1262. hr = _FixObjectPath( V_BSTR( &var ), &pszMachinePath );
  1263. if (FAILED( hr ))
  1264. goto Cleanup;
  1265. VariantClear( &var );
  1266. hr = THR( ADsGetObject( pszMachinePath, IID_IADs, (void**) &pads ) );
  1267. if (FAILED( hr ))
  1268. goto Cleanup;
  1269. hr = THR( pads->Get( SAMNAME, &var ) );
  1270. if (FAILED( hr ))
  1271. goto Cleanup;
  1272. Assert( V_VT( &var ) == VT_BSTR );
  1273. _pszMachineName = TraceStrDup( V_BSTR( &var ) );
  1274. if ( !_pszMachineName )
  1275. goto OutOfMemory;
  1276. psz = &_pszMachineName[ wcslen( _pszMachineName ) - 1 ];
  1277. if ( *psz == L'$' )
  1278. {
  1279. *psz = L'\0';
  1280. }
  1281. DebugMsg( "Server Name: %ws\n", _pszMachineName );
  1282. Cleanup:
  1283. VariantClear( &var );
  1284. if ( pads )
  1285. pads->Release( );
  1286. if ( pszMachinePath )
  1287. TraceFree( pszMachinePath );
  1288. HRETURN(hr);
  1289. OutOfMemory:
  1290. hr = E_OUTOFMEMORY;
  1291. goto Cleanup;
  1292. }
  1293. //
  1294. // _FixObjectPath( )
  1295. //
  1296. HRESULT
  1297. THISCLASS::_FixObjectPath( LPWSTR pszOldObjectPath, LPWSTR *ppszNewObjectPath )
  1298. {
  1299. TraceClsFunc( "_FixObjectPath()\n" );
  1300. if ( !ppszNewObjectPath )
  1301. HRETURN(E_POINTER);
  1302. HRESULT hr;
  1303. LPWSTR psz = NULL;
  1304. *ppszNewObjectPath = NULL;
  1305. // Try to parse the string to connect to the same server as the DSADMIN
  1306. if ( _pszDSServerName && StrCmpNI( _pszDSServerName, L"LDAP://", 7 ) == 0 )
  1307. {
  1308. psz = _pszDSServerName + 7;
  1309. }
  1310. else if ( _pszDSServerName && StrCmpNI( _pszDSServerName, L"GC://", 5 ) == 0 )
  1311. {
  1312. psz = _pszDSServerName + 5;
  1313. }
  1314. if ( psz )
  1315. {
  1316. psz = StrChr( psz, L'/' );
  1317. psz++;
  1318. INT_PTR uLen = psz - _pszDSServerName;
  1319. // get a chunk of memory, pre-zero'ed
  1320. psz = TraceAllocString( LPTR, (size_t) uLen + wcslen( pszOldObjectPath ) + 1 );
  1321. if ( !psz )
  1322. goto OutOfMemory;
  1323. MoveMemory( psz, _pszDSServerName, uLen * sizeof(WCHAR) );
  1324. wcscat( psz, pszOldObjectPath);
  1325. *ppszNewObjectPath = psz;
  1326. }
  1327. else
  1328. { // find another server
  1329. hr = THR( LDAPPrefix( pszOldObjectPath, ppszNewObjectPath ) );
  1330. }
  1331. Assert( ppszNewObjectPath || hr != S_OK );
  1332. HRETURN(hr);
  1333. OutOfMemory:
  1334. HRETURN(E_OUTOFMEMORY);
  1335. }
  1336. //
  1337. // GetDataObject( )
  1338. //
  1339. STDMETHODIMP
  1340. THISCLASS::GetDataObject(
  1341. LPDATAOBJECT * pDataObj
  1342. )
  1343. {
  1344. TraceClsFunc( "GetDataObject( ... )\n" );
  1345. if ( !pDataObj )
  1346. HRETURN( E_POINTER );
  1347. *pDataObj = _pDataObj;
  1348. _pDataObj->AddRef( );
  1349. HRETURN(S_OK);
  1350. }
  1351. //
  1352. // GetNotifyWindow( )
  1353. //
  1354. STDMETHODIMP
  1355. THISCLASS::GetNotifyWindow(
  1356. HWND * phNotifyObj
  1357. )
  1358. {
  1359. TraceClsFunc( "GetNotifyWindow( ... )\n" );
  1360. if ( !phNotifyObj )
  1361. HRETURN(E_POINTER);
  1362. *phNotifyObj = _hwndNotify;
  1363. HRETURN(S_OK);
  1364. }