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.

1481 lines
38 KiB

  1. //
  2. // Copyright 1997 - Microsoft
  3. //
  4. // NEWCLNT.CPP - Handle the "New Clients" IDD_PROP_NEW_CLIENTS property page
  5. //
  6. #include "pch.h"
  7. #include <dnsapi.h>
  8. #include <ntdsapi.h>
  9. #include <dsgetdc.h>
  10. #include <lm.h>
  11. #include <wininet.h>
  12. #include "newclnts.h"
  13. #include "cservice.h"
  14. DEFINE_MODULE("IMADMUI")
  15. DEFINE_THISCLASS("CNewClientsTab")
  16. #define THISCLASS CNewClientsTab
  17. #define LPTHISCLASS LPCNewClientsTab
  18. #define UNKNOWN_INVALID_TEMPLATE L"??"
  19. #include <riname.h>
  20. #include <riname.c>
  21. DWORD aNewClientsHelpMap[] = {
  22. IDC_B_BROWSE, HIDC_B_BROWSE,
  23. IDC_E_NEWMACHINEOU, HIDC_E_NEWMACHINEOU,
  24. IDC_R_SPECIFICLOCATION, HIDC_R_SPECIFICLOCATION,
  25. IDC_R_SAMEASUSER, HIDC_R_SAMEASUSER,
  26. IDC_R_DOMAINDEFAULT, HIDC_R_DOMAINDEFAULT,
  27. IDC_G_CLIENTACCOUNTLOCATION, HIDC_G_CLIENTACCOUNTLOCATION,
  28. IDC_E_SAMPLE, HIDC_E_SAMPLE,
  29. IDC_CB_NAMINGPOLICY, HIDC_CB_NAMINGPOLICY,
  30. IDC_B_ADVANCED, HIDC_B_ADVANCED,
  31. IDC_G_NAMINGFORMAT, HIDC_G_NAMINGFORMAT,
  32. NULL, NULL
  33. };
  34. DWORD aAdvancedHelpMap[] = {
  35. IDC_E_FORMAT, HIDC_E_FORMAT,
  36. IDC_E_SAMPLE, HIDC_E_SAMPLE,
  37. NULL, NULL
  38. };
  39. //
  40. // CreateInstance()
  41. //
  42. LPVOID
  43. CNewClientsTab_CreateInstance( void )
  44. {
  45. TraceFunc( "CNewClientsTab_CreateInstance()\n" );
  46. LPTHISCLASS lpcc = new THISCLASS( );
  47. if ( !lpcc ) {
  48. RETURN(lpcc);
  49. }
  50. HRESULT hr = THR( lpcc->Init( ) );
  51. if ( hr )
  52. {
  53. delete lpcc;
  54. RETURN(NULL);
  55. }
  56. RETURN(lpcc);
  57. }
  58. //
  59. // Constructor
  60. //
  61. THISCLASS::THISCLASS( )
  62. {
  63. TraceClsFunc( "CNewClientsTab()\n" );
  64. InterlockIncrement( g_cObjects );
  65. TraceFuncExit();
  66. }
  67. //
  68. // Init()
  69. //
  70. HRESULT __stdcall
  71. THISCLASS::Init( )
  72. {
  73. HRESULT hr = S_OK;
  74. TraceClsFunc( "Init()\n" );
  75. Assert( !_pszNewMachineOU );
  76. Assert( !_pszServerDN );
  77. HRETURN(hr);
  78. }
  79. //
  80. // Destructor
  81. //
  82. THISCLASS::~THISCLASS( )
  83. {
  84. TraceClsFunc( "~CNewClientsTab()\n" );
  85. if ( _punkService )
  86. _punkService->Release( );
  87. if ( _pszServerDN )
  88. TraceFree( _pszServerDN );
  89. if ( _pszCustomNamingPolicy )
  90. TraceFree( _pszCustomNamingPolicy );
  91. // tell ADS to destroy the notify object
  92. // NOTE: Another property page may do this before us. Ignore errors.
  93. SendMessage( _hNotify, WM_ADSPROP_NOTIFY_EXIT, 0, 0 );
  94. InterlockDecrement( g_cObjects );
  95. TraceFuncExit();
  96. };
  97. // *************************************************************************
  98. //
  99. // ITab
  100. //
  101. // *************************************************************************
  102. STDMETHODIMP
  103. THISCLASS::AddPages(
  104. LPFNADDPROPSHEETPAGE lpfnAddPage,
  105. LPARAM lParam,
  106. LPUNKNOWN punk )
  107. {
  108. TraceClsFunc( "AddPages( )\n" );
  109. HRESULT hr = S_OK;
  110. PROPSHEETPAGE psp;
  111. HPROPSHEETPAGE hpage;
  112. psp.dwSize = sizeof(psp);
  113. psp.dwFlags = PSP_USEREFPARENT | PSP_USECALLBACK;
  114. psp.hInstance = (HINSTANCE) g_hInstance;
  115. psp.pszTemplate = MAKEINTRESOURCE(IDD_PROP_NEW_CLIENTS);
  116. psp.pcRefParent = (UINT *) &g_cObjects;
  117. psp.pfnCallback = (LPFNPSPCALLBACK) PropSheetPageProc;
  118. psp.pfnDlgProc = PropSheetDlgProc;
  119. psp.lParam = (LPARAM) this;
  120. hpage = CreatePropertySheetPage( &psp );
  121. if ( hpage )
  122. {
  123. if ( !lpfnAddPage( hpage, lParam ) )
  124. {
  125. DestroyPropertySheetPage( hpage );
  126. hr = E_FAIL;
  127. goto Error;
  128. }
  129. }
  130. punk->AddRef( ); // matching Release in the destructor
  131. _punkService = punk;
  132. Error:
  133. HRETURN(hr);
  134. }
  135. //
  136. // ReplacePage()
  137. //
  138. STDMETHODIMP
  139. THISCLASS::ReplacePage(
  140. UINT uPageID,
  141. LPFNADDPROPSHEETPAGE lpfnReplaceWith,
  142. LPARAM lParam,
  143. LPUNKNOWN punk )
  144. {
  145. TraceClsFunc( "ReplacePage( ) *** NOT_IMPLEMENTED ***\n" );
  146. RETURN(E_NOTIMPL);
  147. }
  148. //
  149. // QueryInformation( )
  150. //
  151. STDMETHODIMP
  152. THISCLASS::QueryInformation(
  153. LPWSTR pszAttribute,
  154. LPWSTR * pszResult )
  155. {
  156. TraceClsFunc( "QueryInformation( )\n" );
  157. HRETURN(E_NOTIMPL);
  158. }
  159. //
  160. // AllowActivation( )
  161. //
  162. STDMETHODIMP
  163. THISCLASS::AllowActivation(
  164. BOOL * pfAllow )
  165. {
  166. TraceClsFunc( "AllowActivation( )\n" );
  167. HRETURN(E_NOTIMPL);
  168. }
  169. // ************************************************************************
  170. //
  171. // Property Sheet Functions
  172. //
  173. // ************************************************************************
  174. //
  175. // GenerateSample( )
  176. //
  177. DWORD
  178. GenerateSample(
  179. LPWSTR pszPolicy,
  180. LPWSTR pszSampleOut,
  181. LPDWORD maxLength )
  182. {
  183. DWORD error;
  184. GENNAME_VARIABLES variables;
  185. TraceClsFunc( "GenerateSample( )\n" );
  186. if ( !pszPolicy )
  187. HRETURN(E_POINTER);
  188. variables.UserName = L"JOHNSMI";
  189. variables.FirstName = L"John";
  190. variables.LastName = L"Smith";
  191. variables.MacAddress = L"123456789012";
  192. variables.Counter = 123456789;
  193. variables.AllowCounterTruncation = TRUE;
  194. error = GenerateNameFromTemplate(
  195. pszPolicy,
  196. &variables,
  197. pszSampleOut,
  198. DNS_MAX_LABEL_BUFFER_LENGTH,
  199. NULL,
  200. NULL,
  201. maxLength
  202. );
  203. if ( error == GENNAME_TEMPLATE_INVALID ) {
  204. wcscpy( pszSampleOut, UNKNOWN_INVALID_TEMPLATE );
  205. }
  206. RETURN(error);
  207. }
  208. //
  209. // _UpdateSheet()
  210. //
  211. HRESULT
  212. THISCLASS::_UpdateSheet( LPWSTR pszNamingPolicy )
  213. {
  214. TraceClsFunc( "_UpdateSheet( )\n" );
  215. HRESULT hr = S_FALSE;
  216. LPWSTR pszNext;
  217. DWORD dw;
  218. WCHAR szSamples[ 256 ];
  219. HWND hwndCB = GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY );
  220. if (hwndCB == NULL) {
  221. RRETURN(GetLastError());
  222. }
  223. if ( pszNamingPolicy )
  224. {
  225. BOOL fMatched = FALSE;
  226. INT iCount;
  227. INT iOldCount = ComboBox_GetCurSel( hwndCB );
  228. // Retrieve the combobox strings
  229. dw = LoadString( g_hInstance, IDS_SAMPLENAMINGPOLICY, szSamples, ARRAYSIZE( szSamples ) );
  230. Assert( dw );
  231. iCount = 0;
  232. pszNext = szSamples;
  233. while ( *pszNext )
  234. {
  235. LPWSTR pszFriendlyName = pszNext;
  236. // skip the friendly name
  237. pszNext =StrChr( pszNext, L';' );
  238. if ( !pszNext )
  239. break;
  240. *pszNext = L'\0'; // terminate
  241. pszNext++;
  242. LPWSTR pszCodedString = pszNext;
  243. pszNext = StrChr( pszNext, L';' );
  244. if ( !pszNext )
  245. break;
  246. *pszNext = L'\0'; // teminate
  247. if ( pszNamingPolicy && StrCmpI( pszNamingPolicy, pszCodedString ) == 0 )
  248. {
  249. break;
  250. }
  251. iCount++;
  252. pszNext++;
  253. }
  254. if ( iOldCount != iCount )
  255. {
  256. ComboBox_SetCurSel( hwndCB, iCount );
  257. hr = S_OK;
  258. }
  259. }
  260. else
  261. {
  262. INT iCount = ComboBox_GetCurSel( hwndCB );
  263. // Retrieve the combobox strings
  264. dw = LoadString( g_hInstance, IDS_SAMPLENAMINGPOLICY, szSamples, ARRAYSIZE( szSamples ) );
  265. Assert( dw );
  266. pszNext = szSamples;
  267. while ( *pszNext && iCount >= 0 )
  268. {
  269. LPWSTR pszFriendlyName = pszNext;
  270. // skip the friendly name
  271. pszNext =StrChr( pszNext, L';' );
  272. if ( !pszNext )
  273. break;
  274. *pszNext = L'\0'; // terminate
  275. pszNext++;
  276. pszNamingPolicy = pszNext;
  277. pszNext = StrChr( pszNext, L';' );
  278. if ( !pszNext )
  279. break;
  280. *pszNext = L'\0'; // teminate
  281. iCount--;
  282. pszNext++;
  283. }
  284. }
  285. GenerateSample( pszNamingPolicy, _szSampleName, &dw );
  286. SetDlgItemText( _hDlg, IDC_E_SAMPLE, _szSampleName );
  287. RETURN(hr);
  288. }
  289. //
  290. // _InitDialog( )
  291. //
  292. HRESULT
  293. THISCLASS::_InitDialog(
  294. HWND hDlg,
  295. LPARAM lParam )
  296. {
  297. TraceClsFunc( "_InitDialog( )\n" );
  298. HRESULT hr;
  299. HRESULT hResult = S_OK;
  300. DWORD dw;
  301. LPWSTR pszNext;
  302. HWND hwnd;
  303. WCHAR szSamples[ SAMPLES_LIST_SIZE ];
  304. LPWSTR pszNewMachineOU = NULL;
  305. IIntelliMirrorSAP * pimsap = NULL;
  306. _hDlg = hDlg;
  307. dw = LoadString( g_hInstance, IDS_SAMPLENAMINGPOLICY, szSamples, ARRAYSIZE( szSamples ) );
  308. Assert( dw );
  309. Assert( _punkService );
  310. hr = THR( _punkService->QueryInterface( IID_IIntelliMirrorSAP, (void**) &pimsap ) );
  311. if (FAILED( hr ))
  312. goto Error;
  313. hr = THR( pimsap->GetNotifyWindow( &_hNotify ) );
  314. if (FAILED( hr ))
  315. goto Error;
  316. ADsPropSetHwnd( _hNotify, _hDlg );
  317. //
  318. // Populate Naming Policy ComboBox
  319. //
  320. hwnd = GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY );
  321. ComboBox_ResetContent( hwnd );
  322. _iCustomId = 0;
  323. pszNext = szSamples;
  324. while ( *pszNext )
  325. {
  326. // add the friendly name to the combobox
  327. LPWSTR pszFriendlyName = pszNext;
  328. pszNext = StrChr( pszNext, L';' );
  329. if ( !pszNext )
  330. break;
  331. *pszNext = L'\0'; // terminate
  332. ComboBox_AddString( hwnd, pszFriendlyName );
  333. *pszNext = L';'; // restore
  334. // skip the formatted string
  335. pszNext++;
  336. pszNext = StrChr( pszNext, L';' );
  337. if ( !pszNext )
  338. break;
  339. pszNext++;
  340. _iCustomId++;
  341. }
  342. hr = THR( pimsap->IsAdmin( &_fAdmin ) );
  343. Assert( SUCCEEDED(hr) || _fAdmin == FALSE );
  344. EnableWindow( GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY ), _fAdmin );
  345. EnableWindow( GetDlgItem( _hDlg, IDC_B_ADVANCED ), _fAdmin );
  346. EnableWindow( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ), _fAdmin );
  347. EnableWindow( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ), _fAdmin );
  348. EnableWindow( GetDlgItem( _hDlg, IDD_PROP_NEW_CLIENTS ), _fAdmin );
  349. EnableWindow( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ), _fAdmin );
  350. hr = THR( pimsap->GetNewMachineNamingPolicy( &_pszCustomNamingPolicy ) );
  351. if (FAILED( hr ) && hr != E_ADS_PROPERTY_NOT_FOUND && hResult == S_OK )
  352. {
  353. hResult = hr;
  354. }
  355. Assert( SUCCEEDED(hr) || !_pszCustomNamingPolicy );
  356. _UpdateSheet( _pszCustomNamingPolicy );
  357. hr = pimsap->GetNewMachineOU( &pszNewMachineOU );
  358. if (FAILED( hr ) && hr != E_ADS_PROPERTY_NOT_FOUND && hResult == S_OK )
  359. {
  360. hResult = hr;
  361. }
  362. Assert( SUCCEEDED(hr) || !pszNewMachineOU );
  363. hr = THR( pimsap->GetServerDN( &_pszServerDN ) );
  364. if (FAILED( hr ) && hr != E_ADS_PROPERTY_NOT_FOUND && hResult == S_OK )
  365. {
  366. hResult = hr;
  367. }
  368. Assert( SUCCEEDED(hr) || !_pszServerDN );
  369. if ( pszNewMachineOU )
  370. {
  371. if( StrCmp( pszNewMachineOU, _pszServerDN ) !=0 )
  372. {
  373. hr = _MakeOUPretty( DS_FQDN_1779_NAME, DS_CANONICAL_NAME, &pszNewMachineOU );
  374. BOOLEAN temp = _fChanged;
  375. _fChanged =TRUE;// Prevent early turning on of the Apply button.
  376. SetDlgItemText( _hDlg, IDC_E_NEWMACHINEOU, pszNewMachineOU );
  377. _fChanged = temp;
  378. EnableWindow( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), _fAdmin );
  379. EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), _fAdmin );
  380. Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ), BST_CHECKED );
  381. Button_SetCheck( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ), BST_UNCHECKED );
  382. Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ), BST_UNCHECKED );
  383. }
  384. else
  385. {
  386. EnableWindow( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), FALSE );
  387. EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), FALSE );
  388. Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ), BST_UNCHECKED );
  389. Button_SetCheck( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ), BST_CHECKED );
  390. Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ), BST_UNCHECKED );
  391. }
  392. }
  393. else
  394. {
  395. EnableWindow( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), FALSE );
  396. EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), FALSE );
  397. Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ), BST_UNCHECKED );
  398. Button_SetCheck( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ), BST_UNCHECKED );
  399. Button_SetCheck( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ), BST_CHECKED );
  400. }
  401. if ( hResult )
  402. {
  403. MessageBoxFromHResult( _hDlg, IDS_ERROR_READINGCOMPUTERACCOUNT, hResult );
  404. }
  405. Cleanup:
  406. if ( pszNewMachineOU )
  407. TraceFree( pszNewMachineOU );
  408. if ( pimsap )
  409. pimsap->Release( );
  410. HRETURN(hr);
  411. Error:
  412. MessageBoxFromHResult( _hDlg, IDS_ERROR_READINGCOMPUTERACCOUNT, hr );
  413. goto Cleanup;
  414. }
  415. PCWSTR
  416. GetLdapNameOfObjectOu(
  417. PCWSTR InputPath
  418. )
  419. {
  420. PWSTR p,pOut;
  421. DWORD dwLen;
  422. p = StrStrI( InputPath, L"dc=" );
  423. if (!p) {
  424. return(NULL);
  425. }
  426. dwLen = (wcslen(p) + 1)*sizeof(WCHAR) + sizeof(L"LDAP://");
  427. pOut = (PWSTR)TraceAlloc(LMEM_FIXED, dwLen );
  428. if (!pOut) {
  429. return(NULL);
  430. }
  431. wcscpy(pOut, L"LDAP://");
  432. wcscat(pOut, p );
  433. return(pOut);
  434. }
  435. //
  436. // _OnCommand( )
  437. //
  438. HRESULT
  439. THISCLASS::_OnCommand( WPARAM wParam, LPARAM lParam )
  440. {
  441. TraceClsFunc( "_OnCommand( " );
  442. TraceMsg( TF_FUNC, "wParam = 0x%08x, lParam = 0x%08x )\n", wParam, lParam );
  443. BOOL fReturn = FALSE;
  444. BOOL fChanged = FALSE;
  445. HWND hwndCtl = (HWND) lParam;
  446. switch( LOWORD(wParam) )
  447. {
  448. case IDC_B_ADVANCED:
  449. if ( HIWORD( wParam ) == BN_CLICKED )
  450. {
  451. LPWSTR pszNamingPolicy = _pszCustomNamingPolicy;
  452. HRESULT hr = _GetCurrentNamingPolicy( &_pszCustomNamingPolicy );
  453. if ( hr != S_FALSE )
  454. {
  455. TraceFree( pszNamingPolicy );
  456. }
  457. UINT i = (UINT) DialogBoxParam( g_hInstance,
  458. MAKEINTRESOURCE( IDD_ADVANCEDNAMIMG),
  459. _hDlg,
  460. AdvancedDlgProc,
  461. (LPARAM) this );
  462. hr = _UpdateSheet( _pszCustomNamingPolicy );
  463. if ( i == IDOK )
  464. {
  465. fChanged = TRUE;
  466. }
  467. }
  468. break;
  469. case IDC_CB_NAMINGPOLICY:
  470. if ( HIWORD( wParam ) == CBN_SELCHANGE )
  471. {
  472. INT i = ComboBox_GetCurSel( hwndCtl );
  473. if ( i == _iCustomId )
  474. {
  475. UINT i = (UINT) DialogBoxParam( g_hInstance,
  476. MAKEINTRESOURCE( IDD_ADVANCEDNAMIMG),
  477. _hDlg,
  478. AdvancedDlgProc,
  479. (LPARAM) this );
  480. HRESULT hr = _UpdateSheet( _pszCustomNamingPolicy );
  481. if ( i == IDOK )
  482. {
  483. fChanged = TRUE;
  484. }
  485. }
  486. else
  487. {
  488. _UpdateSheet( NULL );
  489. fChanged = TRUE;
  490. }
  491. }
  492. break;
  493. case IDC_R_SPECIFICLOCATION:
  494. if ( HIWORD( wParam ) == BN_CLICKED )
  495. {
  496. HWND hwnd = GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU );
  497. EnableWindow( hwnd, _fAdmin );
  498. EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), _fAdmin );
  499. if ( GetWindowTextLength( hwnd ) != 0 )
  500. {
  501. fChanged = TRUE;
  502. }
  503. }
  504. break;
  505. case IDC_E_NEWMACHINEOU:
  506. if ( HIWORD( wParam ) == EN_CHANGE )
  507. {
  508. HWND hwnd = GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU );
  509. if ( GetWindowTextLength( hwnd ) != 0 )
  510. {
  511. fChanged = TRUE;
  512. }
  513. }
  514. break;
  515. case IDC_R_SAMEASUSER:
  516. case IDC_R_DOMAINDEFAULT:
  517. if ( HIWORD( wParam ) == BN_CLICKED )
  518. {
  519. EnableWindow( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), FALSE );
  520. EnableWindow( GetDlgItem( _hDlg, IDC_B_BROWSE ), FALSE );
  521. fChanged = TRUE;
  522. }
  523. break;
  524. case IDC_B_BROWSE:
  525. if ( HIWORD( wParam ) == BN_CLICKED )
  526. {
  527. DSBROWSEINFO info;
  528. WCHAR szCaption[ 64 ];
  529. WCHAR szTitle[ 64 ];
  530. WCHAR szPath[ INTERNET_MAX_URL_LENGTH ];
  531. DWORD dw;
  532. dw = LoadString( g_hInstance, IDS_BROWSEFOROU_CAPTION, szCaption, ARRAYSIZE( szCaption ) );
  533. Assert( dw );
  534. dw = LoadString( g_hInstance, IDS_BROWSEFOROU_TITLE, szTitle, ARRAYSIZE( szTitle ) );
  535. Assert( dw );
  536. ZeroMemory( &info, sizeof(info) );
  537. info.cbStruct = sizeof(info);
  538. info.hwndOwner = _hDlg;
  539. info.pszRoot = GetLdapNameOfObjectOu(_pszServerDN);
  540. info.pszCaption = szCaption;
  541. info.pszTitle = szTitle;
  542. info.pszPath = szPath;
  543. info.cchPath = ARRAYSIZE(szPath);
  544. info.dwFlags = DSBI_ENTIREDIRECTORY;
  545. if ( IDOK == DsBrowseForContainer( &info ) )
  546. {
  547. // Skip the "LDAP://" part
  548. HRESULT hr = E_FAIL;
  549. LPWSTR pszOU = TraceStrDup( &szPath[7] );
  550. if ( pszOU )
  551. {
  552. hr = _MakeOUPretty( DS_FQDN_1779_NAME, DS_CANONICAL_NAME, &pszOU );
  553. if (SUCCEEDED( hr ))
  554. {
  555. SetWindowText( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), pszOU );
  556. fChanged = TRUE;
  557. }
  558. TraceFree( pszOU );
  559. }
  560. if (FAILED( hr ))
  561. {
  562. SetWindowText( GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU ), &szPath[7] );
  563. fChanged = TRUE;
  564. }
  565. }
  566. if (info.pszRoot) {
  567. TraceFree( (HGLOBAL)info.pszRoot );
  568. }
  569. }
  570. break;
  571. }
  572. if ( fChanged )
  573. {
  574. if ( !_fChanged )
  575. {
  576. _fChanged = TRUE;
  577. SendMessage( GetParent( _hDlg ), PSM_CHANGED, 0, 0 );
  578. }
  579. }
  580. RRETURN(fReturn);
  581. }
  582. //
  583. // _ApplyChanges( )
  584. //
  585. HRESULT
  586. THISCLASS::_ApplyChanges( )
  587. {
  588. TraceClsFunc( "_ApplyChanges( )\n" );
  589. if ( !_fChanged )
  590. HRETURN(S_OK); // nop
  591. HRESULT hr;
  592. HRESULT hResult = S_OK;
  593. LPWSTR pszNamingPolicy = NULL;
  594. UINT iItem;
  595. IIntelliMirrorSAP * pimsap = NULL;
  596. hr = THR( _punkService->QueryInterface( IID_IIntelliMirrorSAP, (void**) &pimsap ) );
  597. if (FAILED( hr ))
  598. goto Error;
  599. if ( Button_GetCheck( GetDlgItem( _hDlg, IDC_R_SPECIFICLOCATION ) ) == BST_CHECKED )
  600. {
  601. HWND hwnd = GetDlgItem( _hDlg, IDC_E_NEWMACHINEOU );
  602. ULONG uLen = GetWindowTextLength( hwnd ) + 1;
  603. LPWSTR pszNewMachineOU = TraceAllocString( LMEM_FIXED, uLen );
  604. if ( pszNewMachineOU )
  605. {
  606. GetWindowText( hwnd, pszNewMachineOU, uLen );
  607. hr = _MakeOUPretty( DS_CANONICAL_NAME, DS_FQDN_1779_NAME, &pszNewMachineOU );
  608. if (SUCCEEDED( hr ))
  609. {
  610. hr = THR( pimsap->SetNewMachineOU( pszNewMachineOU ) );
  611. }
  612. TraceFree( pszNewMachineOU );
  613. if (FAILED(hr) && hResult == S_OK )
  614. {
  615. hResult = hr;
  616. SetFocus( hwnd );
  617. }
  618. }
  619. }
  620. else if ( Button_GetCheck( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ) ) == BST_CHECKED )
  621. {
  622. hr = THR( pimsap->SetNewMachineOU( _pszServerDN ) );
  623. if (FAILED(hr) && hResult == S_OK )
  624. {
  625. hResult = hr;
  626. SetFocus( GetDlgItem( _hDlg, IDC_R_DOMAINDEFAULT ) );
  627. }
  628. }
  629. else
  630. {
  631. hr = THR( pimsap->SetNewMachineOU( NULL ) );
  632. if (FAILED(hr) && hResult == S_OK )
  633. {
  634. hResult = hr;
  635. SetFocus( GetDlgItem( _hDlg, IDC_R_SAMEASUSER ) );
  636. }
  637. }
  638. hr = _GetCurrentNamingPolicy( &pszNamingPolicy );
  639. if (FAILED( hr ) && hResult == S_OK )
  640. {
  641. hResult = hr;
  642. }
  643. hr = THR( pimsap->SetNewMachineNamingPolicy( pszNamingPolicy ) );
  644. if (FAILED( hr ) && hResult == S_OK )
  645. {
  646. SetFocus( GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY ) );
  647. hResult = hr;
  648. }
  649. hr = THR( pimsap->CommitChanges( ) );
  650. if (FAILED( hr ))
  651. goto Error;
  652. if ( hResult )
  653. {
  654. MessageBoxFromHResult( _hDlg, IDS_ERROR_WRITINGTOCOMPUTERACCOUNT, hResult );
  655. hr = hResult;
  656. }
  657. else
  658. {
  659. _fChanged = FALSE;
  660. }
  661. Cleanup:
  662. if ( pimsap )
  663. pimsap->Release( );
  664. if ( pszNamingPolicy )
  665. TraceFree( pszNamingPolicy );
  666. // Tell DSA that someone hit Apply
  667. SendMessage( _hNotify, WM_ADSPROP_NOTIFY_APPLY, !!SUCCEEDED( hr ), 0 );
  668. HRETURN(hr);
  669. Error:
  670. MessageBoxFromHResult( _hDlg, IDS_ERROR_WRITINGTOCOMPUTERACCOUNT, hr );
  671. goto Cleanup;
  672. }
  673. //
  674. // _OnNotify( )
  675. //
  676. INT
  677. THISCLASS::_OnNotify(
  678. WPARAM wParam,
  679. LPARAM lParam )
  680. {
  681. TraceClsFunc( "_OnNotify( " );
  682. TraceMsg( TF_FUNC, "wParam = 0x%08x, lParam = 0x%08x )\n", wParam, lParam );
  683. LPNMHDR lpnmhdr = (LPNMHDR) lParam;
  684. switch( lpnmhdr->code )
  685. {
  686. case PSN_APPLY:
  687. {
  688. HRESULT hr;
  689. TraceMsg( TF_WM, TEXT("WM_NOTIFY: PSN_APPLY\n"));
  690. hr = _ApplyChanges( );
  691. SetWindowLongPtr( _hDlg, DWLP_MSGRESULT, ( SUCCEEDED(hr) ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE ));
  692. RETURN(TRUE);
  693. }
  694. break;
  695. default:
  696. break;
  697. }
  698. RETURN(FALSE);
  699. }
  700. //
  701. // PropSheetDlgProc()
  702. //
  703. INT_PTR CALLBACK
  704. THISCLASS::PropSheetDlgProc(
  705. HWND hDlg,
  706. UINT uMsg,
  707. WPARAM wParam,
  708. LPARAM lParam )
  709. {
  710. //TraceMsg( TEXT("PropSheetDlgProc(") );
  711. //TraceMsg( TF_FUNC, TEXT(" hDlg = 0x%08x, uMsg = 0x%08x, wParam = 0x%08x, lParam = 0x%08x )\n"),
  712. // hDlg, uMsg, wParam, lParam );
  713. LPTHISCLASS pcc = (LPTHISCLASS) GetWindowLongPtr( hDlg, GWLP_USERDATA );
  714. if ( uMsg == WM_INITDIALOG )
  715. {
  716. TraceMsg( TF_WM, TEXT("WM_INITDIALOG\n"));
  717. LPPROPSHEETPAGE psp = (LPPROPSHEETPAGE) lParam;
  718. SetWindowLongPtr( hDlg, GWLP_USERDATA, psp->lParam );
  719. pcc = (LPTHISCLASS) psp->lParam;
  720. pcc->_InitDialog( hDlg, lParam );
  721. }
  722. if (pcc)
  723. {
  724. Assert( hDlg == pcc->_hDlg );
  725. switch ( uMsg )
  726. {
  727. case WM_NOTIFY:
  728. return pcc->_OnNotify( wParam, lParam );
  729. case WM_COMMAND:
  730. TraceMsg( TF_WM, TEXT("WM_COMMAND\n") );
  731. pcc->_OnCommand( wParam, lParam );
  732. break;
  733. case WM_HELP:// F1
  734. {
  735. LPHELPINFO phelp = (LPHELPINFO) lParam;
  736. WinHelp( (HWND) phelp->hItemHandle, g_cszHelpFile, HELP_WM_HELP, (DWORD_PTR) &aNewClientsHelpMap );
  737. }
  738. break;
  739. case WM_CONTEXTMENU: // right mouse click
  740. WinHelp((HWND) wParam, g_cszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR) &aNewClientsHelpMap );
  741. break;
  742. case WM_ADSPROP_PAGE_GET_NOTIFY:
  743. {
  744. HWND *phwnd = (HWND *) wParam;
  745. *phwnd = pcc->_hNotify;
  746. }
  747. return TRUE;
  748. }
  749. }
  750. return FALSE;
  751. }
  752. //
  753. // PropSheetPageProc()
  754. //
  755. UINT CALLBACK
  756. THISCLASS::PropSheetPageProc(
  757. HWND hwnd,
  758. UINT uMsg,
  759. LPPROPSHEETPAGE ppsp )
  760. {
  761. TraceClsFunc( "PropSheetPageProc( " );
  762. TraceMsg( TF_FUNC, TEXT("hwnd = 0x%08x, uMsg = 0x%08x, ppsp= 0x%08x )\n"),
  763. hwnd, uMsg, ppsp );
  764. switch ( uMsg )
  765. {
  766. case PSPCB_CREATE:
  767. RETURN(TRUE); // create it
  768. break;
  769. case PSPCB_RELEASE:
  770. LPTHISCLASS pcc = (LPTHISCLASS) ppsp->lParam;
  771. delete pcc;
  772. break;
  773. }
  774. RETURN(FALSE);
  775. }
  776. // ************************************************************************
  777. //
  778. // Advanced Namimg Dialog Proc
  779. //
  780. // ************************************************************************
  781. //
  782. // Advanced_OnCommand( )
  783. //
  784. UINT CALLBACK
  785. Advanced_OnCommand(
  786. HWND hDlg,
  787. WPARAM wParam,
  788. LPARAM lParam,
  789. LPTHISCLASS pcc )
  790. {
  791. TraceFunc( "Advanced_OnCommand( " );
  792. TraceMsg( TF_FUNC, "hDlg, wParam, lParam, pcc )\n" );
  793. RETURN(TRUE);
  794. }
  795. INT_PTR CALLBACK
  796. AdvancedDlgProc(
  797. HWND hDlg,
  798. UINT uMsg,
  799. WPARAM wParam,
  800. LPARAM lParam )
  801. {
  802. //TraceMsg( TEXT("AdvancedDlgProc(") );
  803. //TraceMsg( TF_FUNC, TEXT(" hDlg = 0x%08x, uMsg = 0x%08x, wParam = 0x%08x, lParam = 0x%08x )\n"),
  804. // hDlg, uMsg, wParam, lParam );
  805. WCHAR szFormat[ DNS_MAX_LABEL_BUFFER_LENGTH ];
  806. LPTHISCLASS pcc = (LPTHISCLASS) GetWindowLongPtr( hDlg, GWLP_USERDATA );
  807. if ( uMsg == WM_INITDIALOG )
  808. {
  809. TraceMsg( TF_WM, TEXT("WM_INITDIALOG\n"));
  810. pcc = (LPTHISCLASS) lParam;
  811. SetWindowLongPtr( hDlg, GWLP_USERDATA, (LPARAM) pcc );
  812. Assert( pcc != NULL );
  813. HWND hwnd = GetDlgItem( hDlg, IDC_E_FORMAT );
  814. Edit_LimitText( hwnd, ARRAYSIZE(szFormat) - 1 );
  815. LPWSTR pszNamingPolicy = NULL;
  816. HRESULT hr = pcc->_GetCurrentNamingPolicy( &pszNamingPolicy );
  817. if (SUCCEEDED( hr ) && (hr != S_FALSE))
  818. {
  819. SetWindowText( hwnd, pszNamingPolicy );
  820. TraceFree( pszNamingPolicy );
  821. }
  822. }
  823. if (pcc)
  824. {
  825. switch ( uMsg )
  826. {
  827. case WM_COMMAND:
  828. {
  829. switch( LOWORD( wParam ) )
  830. {
  831. case IDCANCEL:
  832. if ( HIWORD( wParam ) == BN_CLICKED )
  833. {
  834. EndDialog( hDlg, LOWORD( wParam ) );
  835. return TRUE;
  836. }
  837. break;
  838. case IDOK:
  839. if ( HIWORD( wParam ) == BN_CLICKED )
  840. {
  841. WCHAR szSample[ DNS_MAX_LABEL_BUFFER_LENGTH ];
  842. DWORD maxLength;
  843. DWORD nameError;
  844. GetDlgItemText( hDlg, IDC_E_FORMAT, szFormat, ARRAYSIZE(szFormat) );
  845. nameError = GenerateSample( szFormat, szSample, &maxLength );
  846. Assert( (nameError == GENNAME_NO_ERROR) ||
  847. (nameError == GENNAME_TEMPLATE_INVALID) ||
  848. (nameError == GENNAME_NAME_TOO_LONG) );
  849. if ( nameError == GENNAME_TEMPLATE_INVALID )
  850. {
  851. MessageBoxFromStrings( hDlg,
  852. IDS_ADVANCED_NAMING_RESTRICTIONS_TITLE,
  853. IDS_ADVANCED_NAMING_RESTRICTIONS_TEXT,
  854. MB_OK );
  855. break;
  856. }
  857. else if ( nameError == GENNAME_NAME_TOO_LONG )
  858. {
  859. LRESULT lResult = MessageBoxFromStrings( hDlg,
  860. IDS_DNS_NAME_LENGTH_WARNING_TITLE,
  861. IDS_DNS_NAME_LENGTH_WARNING_TEXT,
  862. MB_YESNO );
  863. if ( lResult == IDNO )
  864. break;
  865. }
  866. pcc->_pszCustomNamingPolicy = (LPWSTR) TraceStrDup( szFormat );
  867. EndDialog( hDlg, LOWORD( wParam ) );
  868. return TRUE;
  869. }
  870. break;
  871. case IDC_E_FORMAT:
  872. if ( HIWORD( wParam ) == EN_CHANGE )
  873. {
  874. WCHAR szSample[ DNS_MAX_LABEL_BUFFER_LENGTH ] = { L"" };
  875. DWORD maxLength;
  876. DWORD nameError;
  877. if ( !GetDlgItemText( hDlg, IDC_E_FORMAT, szFormat, ARRAYSIZE(szFormat) ) )
  878. {
  879. nameError = GENNAME_TEMPLATE_INVALID;
  880. }
  881. else
  882. {
  883. nameError = GenerateSample( szFormat, szSample, &maxLength );
  884. Assert( (nameError == GENNAME_NO_ERROR) ||
  885. (nameError == GENNAME_TEMPLATE_INVALID) ||
  886. (nameError == GENNAME_NAME_TOO_LONG) );
  887. }
  888. if ( DnsValidateDnsName_W( szSample ) != NO_ERROR ) {
  889. nameError = GENNAME_TEMPLATE_INVALID;
  890. wcscpy( szSample, UNKNOWN_INVALID_TEMPLATE );
  891. }
  892. SetDlgItemText( hDlg, IDC_E_SAMPLE, szSample );
  893. EnableWindow( GetDlgItem( hDlg, IDOK ),
  894. (BOOL)(nameError != GENNAME_TEMPLATE_INVALID) );
  895. }
  896. break;
  897. }
  898. }
  899. break; // WM_COMMAND
  900. case WM_HELP:// F1
  901. {
  902. LPHELPINFO phelp = (LPHELPINFO) lParam;
  903. WinHelp( (HWND) phelp->hItemHandle, g_cszHelpFile, HELP_WM_HELP, (DWORD_PTR) &aAdvancedHelpMap );
  904. }
  905. break;
  906. case WM_CONTEXTMENU: // right mouse click
  907. WinHelp((HWND) wParam, g_cszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR) &aAdvancedHelpMap );
  908. break;
  909. }
  910. }
  911. return FALSE;
  912. }
  913. HRESULT
  914. THISCLASS::_GetCurrentNamingPolicy( LPWSTR * ppszNamingPolicy )
  915. {
  916. TraceClsFunc( "_GetCurrentNamingPolicy( )\n" );
  917. if ( !ppszNamingPolicy )
  918. HRETURN(E_POINTER);
  919. HRESULT hr = S_OK;
  920. INT iItem = ComboBox_GetCurSel( GetDlgItem( _hDlg, IDC_CB_NAMINGPOLICY ) );
  921. if ( iItem == - 1 )
  922. {
  923. *ppszNamingPolicy = NULL;
  924. HRETURN(S_FALSE);
  925. }
  926. else if ( iItem == _iCustomId && _pszCustomNamingPolicy )
  927. {
  928. if ( *ppszNamingPolicy == _pszCustomNamingPolicy )
  929. HRETURN(S_FALSE);
  930. *ppszNamingPolicy = TraceStrDup( _pszCustomNamingPolicy );
  931. }
  932. else if ( iItem != _iCustomId )
  933. {
  934. WCHAR szSamples[ SAMPLES_LIST_SIZE ];
  935. LPWSTR pszFormat = NULL;
  936. LPWSTR pszNext = szSamples;
  937. DWORD dw;
  938. dw = LoadString( g_hInstance, IDS_SAMPLENAMINGPOLICY, szSamples, ARRAYSIZE( szSamples ) );
  939. Assert( dw );
  940. for( ; *pszNext && iItem >= 0; iItem-- )
  941. {
  942. // find the end of the friendly name which is terminated by a ';'
  943. pszNext = StrChr( pszNext, L';' );
  944. if ( !pszNext )
  945. {
  946. pszFormat = NULL;
  947. break;
  948. }
  949. pszNext++;
  950. pszFormat = pszNext;
  951. // skip the internal string
  952. pszNext = StrChr( pszNext, L';' );
  953. if ( !pszNext )
  954. {
  955. pszFormat = NULL;
  956. break;
  957. }
  958. // next string please...
  959. pszNext++;
  960. }
  961. Assert( pszFormat );
  962. pszNext = StrChr( pszFormat, L';' );
  963. Assert( pszNext );
  964. *pszNext = L'\0';
  965. *ppszNamingPolicy = TraceStrDup( pszFormat );
  966. }
  967. if ( !*ppszNamingPolicy )
  968. {
  969. hr = E_OUTOFMEMORY;
  970. }
  971. HRETURN(hr);
  972. }
  973. typedef enum {
  974. MOUP_SYNTACTICAL,
  975. MOUP_LOCAL_DC,
  976. MOUP_OTHER_DC,
  977. MOUP_GC
  978. } CRACK_TYPE;
  979. HRESULT
  980. THISCLASS::_MakeOUPretty( DS_NAME_FORMAT inFlag, DS_NAME_FORMAT outFlag, LPWSTR *ppszOU )
  981. {
  982. TraceClsFunc("_MakeOUPretty()\n");
  983. Assert( ppszOU );
  984. if ( !*ppszOU ) {
  985. HRETURN(S_FALSE); // nothing in... nothing out
  986. }
  987. HRESULT hr;
  988. PDS_NAME_RESULT pResults;
  989. DWORD dw;
  990. HANDLE hDS;
  991. CRACK_TYPE crackType;
  992. //
  993. // We might need to call DsCrackNames up to four times. The logic goes like this:
  994. //
  995. // Call DsCrackNames to attempt a local-only syntactical mapping.
  996. // If that fails with DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING,
  997. // Try the local DC.
  998. // If can't find the local DC,
  999. // Try the GC.
  1000. // Else if local DC failed with DS_NAME_ERROR_DOMAIN_ONLY,
  1001. // Try the DC pointed to by the local DC.
  1002. // If can't find the other DC,
  1003. // Try the GC.
  1004. //
  1005. crackType = MOUP_SYNTACTICAL;
  1006. hDS = NULL;
  1007. pResults = NULL;
  1008. while ( TRUE ) {
  1009. //
  1010. // If we have a bind handle left over from the previous pass, unbind it now.
  1011. //
  1012. if ( hDS != NULL ) {
  1013. DsUnBind( &hDS );
  1014. hDS = NULL;
  1015. }
  1016. //
  1017. // Bind to the DC or GC.
  1018. //
  1019. if ( crackType == MOUP_SYNTACTICAL ) {
  1020. hDS = NULL;
  1021. } else if ( crackType == MOUP_LOCAL_DC ) {
  1022. //
  1023. // Find a local DC.
  1024. //
  1025. PDOMAIN_CONTROLLER_INFOW pDCInfo = NULL;
  1026. dw = DsGetDcName(
  1027. NULL,
  1028. NULL,
  1029. NULL,
  1030. NULL,
  1031. DS_DIRECTORY_SERVICE_REQUIRED | DS_IP_REQUIRED,
  1032. &pDCInfo
  1033. );
  1034. if ( dw != NO_ERROR ) {
  1035. //
  1036. // Couldn't find a DC. Try the GC.
  1037. //
  1038. crackType = MOUP_GC;
  1039. continue;
  1040. }
  1041. Assert( pDCInfo != NULL );
  1042. dw = DsBind( pDCInfo->DomainControllerName, NULL, &hDS );
  1043. NetApiBufferFree( pDCInfo );
  1044. if ( dw != NO_ERROR ) {
  1045. //
  1046. // Couldn't bind to the DC. Try the GC.
  1047. //
  1048. crackType = MOUP_GC;
  1049. continue;
  1050. }
  1051. } else if ( crackType == MOUP_OTHER_DC ) {
  1052. //
  1053. // We need to talk to the DC that the local DC referred us to.
  1054. //
  1055. dw = DsBind( NULL, pResults->rItems[0].pDomain, &hDS );
  1056. if ( dw != NO_ERROR ) {
  1057. //
  1058. // Couldn't bind to the DC. Try the GC.
  1059. //
  1060. crackType = MOUP_GC;
  1061. continue;
  1062. }
  1063. } else {
  1064. //
  1065. // Bind to the GC.
  1066. //
  1067. dw = DsBind( NULL, NULL, &hDS );
  1068. if ( dw != NO_ERROR ) {
  1069. //
  1070. // Couldn't bind to the GC. Give up.
  1071. //
  1072. hr = HRESULT_FROM_WIN32( dw );
  1073. break;
  1074. }
  1075. }
  1076. //
  1077. // If we have pResults left over from a previous call, free it now.
  1078. //
  1079. if ( pResults != NULL ) {
  1080. DsFreeNameResult( pResults );
  1081. pResults = NULL;
  1082. }
  1083. //
  1084. // Try to crack the name.
  1085. //
  1086. dw = DsCrackNames( hDS,
  1087. (crackType == MOUP_SYNTACTICAL) ?
  1088. DS_NAME_FLAG_SYNTACTICAL_ONLY : DS_NAME_NO_FLAGS,
  1089. inFlag,
  1090. outFlag,
  1091. 1,
  1092. ppszOU,
  1093. &pResults );
  1094. if ( dw != NO_ERROR ) {
  1095. if ( crackType == MOUP_SYNTACTICAL ) {
  1096. //
  1097. // We were doing a syntactical check. We don't expect this to fail.
  1098. //
  1099. hr = HRESULT_FROM_WIN32( dw );
  1100. break;
  1101. } else if ( crackType == MOUP_LOCAL_DC ) {
  1102. //
  1103. // We had trouble getting to the local DC. Try the GC.
  1104. //
  1105. crackType = MOUP_GC;
  1106. continue;
  1107. } else if ( crackType == MOUP_OTHER_DC ) {
  1108. //
  1109. // We had trouble getting to the other DC. Try the GC.
  1110. //
  1111. crackType = MOUP_GC;
  1112. continue;
  1113. } else {
  1114. //
  1115. // We had trouble getting to the GC. Give up.
  1116. //
  1117. hr = HRESULT_FROM_WIN32( dw );
  1118. break;
  1119. }
  1120. } else {
  1121. Assert( pResults != NULL );
  1122. Assert( pResults->cItems == 1 );
  1123. if ( pResults->rItems[0].status == DS_NAME_NO_ERROR ) {
  1124. //
  1125. // We've got what we wanted.
  1126. //
  1127. hr = S_OK;
  1128. break;
  1129. }
  1130. if ( crackType == MOUP_SYNTACTICAL ) {
  1131. if ( pResults->rItems[0].status != DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING ) {
  1132. //
  1133. // Unexpected error. Give up.
  1134. //
  1135. hr = HRESULT_FROM_WIN32( ERROR_DS_GENERIC_ERROR );
  1136. break;
  1137. }
  1138. //
  1139. // Try the local DC next.
  1140. //
  1141. crackType = MOUP_LOCAL_DC;
  1142. continue;
  1143. } else if ( crackType == MOUP_LOCAL_DC ) {
  1144. if ( pResults->rItems[0].status != DS_NAME_ERROR_DOMAIN_ONLY ) {
  1145. //
  1146. // Unexpected error. Give up.
  1147. //
  1148. hr = HRESULT_FROM_WIN32( ERROR_DS_GENERIC_ERROR );
  1149. break;
  1150. }
  1151. //
  1152. // Try the other DC next.
  1153. //
  1154. crackType = MOUP_OTHER_DC;
  1155. continue;
  1156. } else if ( crackType == MOUP_OTHER_DC ) {
  1157. //
  1158. // Unexpected error. Give up.
  1159. //
  1160. hr = HRESULT_FROM_WIN32( ERROR_DS_GENERIC_ERROR );
  1161. break;
  1162. } else {
  1163. //
  1164. // Couldn't get what we need from the GC. Give up.
  1165. //
  1166. hr = HRESULT_FROM_WIN32( ERROR_DS_GENERIC_ERROR );
  1167. break;
  1168. }
  1169. }
  1170. }
  1171. if ( hr == S_OK ) {
  1172. Assert( pResults != NULL );
  1173. Assert( pResults->cItems == 1 );
  1174. Assert( pResults->rItems[0].status == DS_NAME_NO_ERROR );
  1175. Assert( pResults->rItems[0].pName );
  1176. LPWSTR psz = TraceStrDup( pResults->rItems[0].pName );
  1177. if ( psz != NULL ) {
  1178. TraceFree( *ppszOU );
  1179. *ppszOU = psz;
  1180. } else {
  1181. hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  1182. }
  1183. }
  1184. if ( hDS != NULL ) {
  1185. DsUnBind( &hDS );
  1186. }
  1187. if ( pResults != NULL ) {
  1188. DsFreeNameResult( pResults );
  1189. }
  1190. HRETURN(hr);
  1191. }