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.

666 lines
21 KiB

  1. // AUsrExe.cpp : Implementation of WinMain
  2. #include "stdafx.h"
  3. #include "resource.h"
  4. // DLL\Inc
  5. #include <wizchain.h>
  6. #include <propuid.h>
  7. #include <AUsrUtil.h>
  8. #include <singleinst.h>
  9. #include <cmdline.h>
  10. #include <proputil.h>
  11. #include <AU_Accnt.h> // Core User component (account, mailbox, group)
  12. #include <P3admin.h>
  13. #include <checkuser.h>
  14. #include <lmaccess.h>
  15. #include <lmapibuf.h>
  16. #include <lmserver.h>
  17. #include <lmshare.h>
  18. #include <iads.h>
  19. #include <adshlp.h>
  20. #include <adserr.h>
  21. #include <dsgetdc.h>
  22. #define ERROR_CREATION 0x01
  23. #define ERROR_PROPERTIES 0x02
  24. #define ERROR_MAILBOX 0x04
  25. #define ERROR_MEMBERSHIPS 0x08
  26. #define ERROR_PASSWORD 0x10
  27. #define ERROR_DUPE 0x20
  28. #define ERROR_GROUP 0x40
  29. // Defines for account flags.
  30. #define PASSWD_NOCHANGE 0x01
  31. #define PASSWD_CANCHANGE 0x02
  32. #define PASSWD_MUSTCHANGE 0x04
  33. #define ACCOUNT_DISABLED 0x10
  34. #define MAX_GUID_STRING_LENGTH 64
  35. #define SINGLE_INST_NAME _T("{19C2E967-1198-4e4c-A55F-515C5F13B73F}")
  36. HINSTANCE g_hInstance;
  37. DWORD g_dwAutoCompMode;
  38. TCHAR g_szUserOU[MAX_PATH*2] = {0};
  39. // Prototypes
  40. DWORD FixParams( void );
  41. // ****************************************************************************
  42. inline void MakeLDAPUpper( TCHAR* szIn )
  43. {
  44. if( !szIn ) return;
  45. if( _tcsnicmp( szIn, _T("ldap://"), 7 ) == 0 )
  46. {
  47. szIn[0] = _T('L');
  48. szIn[1] = _T('D');
  49. szIn[2] = _T('A');
  50. szIn[3] = _T('P');
  51. }
  52. }
  53. class CHBmp
  54. {
  55. public:
  56. CHBmp()
  57. {
  58. m_hbmp = NULL;
  59. }
  60. CHBmp( HINSTANCE hinst, INT iRes )
  61. {
  62. m_hbmp = (HBITMAP)LoadImage( hinst, MAKEINTRESOURCE(iRes), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR );
  63. }
  64. ~CHBmp()
  65. {
  66. if ( m_hbmp )
  67. DeleteObject((HGDIOBJ)m_hbmp);
  68. }
  69. HBITMAP SetBmp( HINSTANCE hinst, INT iRes )
  70. {
  71. m_hbmp = (HBITMAP)LoadImage( hinst, MAKEINTRESOURCE(iRes), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR );
  72. return(m_hbmp);
  73. }
  74. HBITMAP GetBmp()
  75. {
  76. return(m_hbmp);
  77. }
  78. private:
  79. HBITMAP m_hbmp;
  80. };
  81. CComModule _Module;
  82. BEGIN_OBJECT_MAP(ObjectMap)
  83. END_OBJECT_MAP()
  84. // ----------------------------------------------------------------------------
  85. // SetPBagPropStr()
  86. // ----------------------------------------------------------------------------
  87. HRESULT SetPBagPropStr( IChainWiz *spCW, LPCTSTR szPropGuid, LPCTSTR szValue, PPPBAG_TYPE dwFlags )
  88. {
  89. HRESULT hr = E_FAIL;
  90. if ( !spCW || !szPropGuid )
  91. return E_FAIL;
  92. CComPtr<IDispatch> spDisp;
  93. spCW->get_PropertyBag( &spDisp );
  94. CComQIPtr<IPropertyPagePropertyBag> spPPPBag(spDisp);
  95. if ( spPPPBag )
  96. {
  97. hr = S_OK;
  98. CComBSTR bstrPropGuid = szPropGuid;
  99. CComVariant var = szValue;
  100. spPPPBag->SetProperty (bstrPropGuid, &var, dwFlags);
  101. }
  102. return hr;
  103. }
  104. // ----------------------------------------------------------------------------
  105. // SetPBagPropBool()
  106. // ----------------------------------------------------------------------------
  107. HRESULT SetPBagPropBool( IChainWiz *spCW, LPCTSTR szPropGuid, BOOL fValue, PPPBAG_TYPE dwFlags )
  108. {
  109. HRESULT hr = E_FAIL;
  110. if ( !spCW || !szPropGuid )
  111. return E_FAIL;
  112. CComPtr<IDispatch> spDisp;
  113. spCW->get_PropertyBag( &spDisp );
  114. CComQIPtr<IPropertyPagePropertyBag> spPPPBag(spDisp);
  115. if ( spPPPBag )
  116. {
  117. hr = S_OK;
  118. CComBSTR bstrPropGuid = szPropGuid;
  119. CComVariant var = (bool) !!fValue;
  120. spPPPBag->SetProperty (bstrPropGuid, &var, dwFlags);
  121. }
  122. return hr;
  123. }
  124. // ----------------------------------------------------------------------------
  125. // SetPBagPropInt4()
  126. // ----------------------------------------------------------------------------
  127. HRESULT SetPBagPropInt4( IChainWiz *spCW, LPCTSTR szPropGuid, long lValue, PPPBAG_TYPE dwFlags )
  128. {
  129. HRESULT hr = E_FAIL;
  130. if ( !spCW || !szPropGuid )
  131. return E_FAIL;
  132. CComPtr<IDispatch> spDisp;
  133. spCW->get_PropertyBag( &spDisp );
  134. CComQIPtr<IPropertyPagePropertyBag> spPPPBag(spDisp);
  135. if ( spPPPBag )
  136. {
  137. hr = S_OK;
  138. CComBSTR bstrPropGuid = szPropGuid;
  139. WriteInt4 (spPPPBag, bstrPropGuid, lValue, dwFlags == PPPBAG_TYPE_READONLY ? true : false);
  140. }
  141. return hr;
  142. }
  143. // ----------------------------------------------------------------------------
  144. // TmpSetProps()
  145. // ----------------------------------------------------------------------------
  146. HRESULT TmpSetProps(IChainWiz *spCW)
  147. {
  148. if ( !spCW )
  149. return(E_FAIL);
  150. SetPBagPropInt4( spCW, PROP_AUTOCOMPLETE_MODE, g_dwAutoCompMode, PPPBAG_TYPE_READWRITE );
  151. SetPBagPropStr ( spCW, PROP_USEROU_GUID_STRING, g_szUserOU, PPPBAG_TYPE_READWRITE );
  152. // Check for POP3 installation
  153. BOOL bPOP3Installed = FALSE;
  154. BOOL bPOP3Valid = FALSE;
  155. CRegKey cReg;
  156. //To detect if POP3 is installed:
  157. //Key: HKLM\SOFTWARE\Microsoft\POP3 Service
  158. //Value: Version REG_SZ eg. "1.0"
  159. tstring strPath = _T("Software\\Microsoft\\POP3 Service");
  160. tstring strKey = _T("Version");
  161. if( cReg.Open( HKEY_LOCAL_MACHINE, strPath.c_str() ) == ERROR_SUCCESS )
  162. {
  163. TCHAR szValue[MAX_PATH] = {0};
  164. DWORD dwSize = MAX_PATH;
  165. bPOP3Installed = (cReg.QueryValue( szValue, strKey.c_str(), &dwSize ) == ERROR_SUCCESS);
  166. cReg.Close();
  167. }
  168. if( bPOP3Installed )
  169. {
  170. // Test if there is at least one domain
  171. HRESULT hr = S_OK;
  172. CComPtr<IP3Config> spConfig = NULL;
  173. CComPtr<IP3Domains> spDomains = NULL;
  174. CComPtr<IP3Domain> spDomain = NULL;
  175. long lCount = 0;
  176. // Open our Pop3 Admin Interface
  177. hr = CoCreateInstance(__uuidof(P3Config), NULL, CLSCTX_ALL, __uuidof(IP3Config), (LPVOID*)&spConfig);
  178. if( SUCCEEDED(hr) )
  179. {
  180. // Get the Domains
  181. hr = spConfig->get_Domains( &spDomains );
  182. }
  183. if( SUCCEEDED(hr) )
  184. {
  185. hr = spDomains->get_Count( &lCount );
  186. }
  187. bPOP3Valid = (lCount > 0);
  188. }
  189. SetPBagPropBool( spCW, PROP_POP3_CREATE_MB_GUID_STRING, bPOP3Valid, PPPBAG_TYPE_READWRITE );
  190. SetPBagPropBool( spCW, PROP_POP3_VALID_GUID_STRING, bPOP3Valid, PPPBAG_TYPE_READWRITE );
  191. SetPBagPropBool( spCW, PROP_POP3_INSTALLED_GUID_STRING, bPOP3Installed, PPPBAG_TYPE_READWRITE );
  192. return(S_OK);
  193. }
  194. // ----------------------------------------------------------------------------
  195. // DoAddUsr( )
  196. // ----------------------------------------------------------------------------
  197. HRESULT DoAddUsr( )
  198. {
  199. HRESULT hr = S_OK;
  200. CHBmp bmpLarge(g_hInstance, IDB_BMP_LARGE);
  201. CHBmp bmpSmall(g_hInstance, IDB_BMP_SMALL);
  202. CString strTitle = _T("");
  203. CString strWelcomeHeader = _T("");
  204. CString strWelcomeText = _T("");
  205. CString strWelcomeNext = _T("");
  206. CString strFinishHeader = _T("");
  207. CString strFinishIntro = _T("");
  208. CString strFinishText = _T("");
  209. CLSID clsidChainWiz;
  210. CComPtr<IChainWiz> spCW;
  211. // ------------------------------------------------------------------------
  212. // Init:
  213. // Initialize the wizard's text.
  214. // ------------------------------------------------------------------------
  215. strTitle.LoadString ( IDS_TITLE );
  216. strWelcomeHeader.LoadString ( IDS_WELCOME_HEADER );
  217. strWelcomeText.LoadString ( IDS_WELCOME_TEXT );
  218. strWelcomeNext.LoadString ( IDS_WELCOME_TEXT_NEXT );
  219. strFinishHeader.LoadString ( IDS_FINISH_HEADER );
  220. strFinishIntro.LoadString ( IDS_FINISH_TEXT );
  221. strWelcomeText += strWelcomeNext;
  222. // ------------------------------------------------------------------------
  223. // Initialize the wizard.
  224. // ------------------------------------------------------------------------
  225. hr = CLSIDFromProgID( L"WizChain.ChainWiz", &clsidChainWiz );
  226. _ASSERT( hr == S_OK && "CLSIDFromProgID failed" );
  227. hr = CoCreateInstance( clsidChainWiz, NULL, CLSCTX_INPROC_SERVER, __uuidof(IChainWiz), (void **)&spCW );
  228. _ASSERT( spCW != NULL && "CoCreateInstance failed to create WizChain.ChainWiz" );
  229. if( FAILED(hr) || !spCW )
  230. {
  231. ErrorMsg(IDS_ERROR_MISSINGDLL, IDS_ERROR_TITLE);
  232. return(hr);
  233. }
  234. CComPtr<IDispatch> spDisp;
  235. spCW->get_PropertyBag( &spDisp );
  236. CComQIPtr<IPropertyPagePropertyBag> spPPPBag(spDisp);
  237. USES_CONVERSION;
  238. OLECHAR szClsid[MAX_GUID_STRING_LENGTH] = {0};
  239. // --------------------------------------------------------------------
  240. // Setup and run the wizard.
  241. // --------------------------------------------------------------------
  242. TmpSetProps( spCW ); // This is to populate the bag
  243. // Initialize the wizard.
  244. hr = spCW->Initialize( bmpLarge.GetBmp(),
  245. bmpSmall.GetBmp(),
  246. T2W((LPTSTR)(LPCTSTR)strTitle),
  247. T2W((LPTSTR)(LPCTSTR)strWelcomeHeader),
  248. T2W((LPTSTR)(LPCTSTR)strWelcomeText),
  249. T2W((LPTSTR)(LPCTSTR)strFinishHeader),
  250. T2W((LPTSTR)(LPCTSTR)strFinishIntro),
  251. T2W((LPTSTR)(LPCTSTR)strFinishText) );
  252. if ( FAILED(hr) )
  253. return(hr);
  254. // Add the AddUser Account component.
  255. szClsid[0] = 0;
  256. StringFromGUID2( __uuidof(AddUser_AccntWiz), szClsid, 50 );
  257. hr = spCW->AddWizardComponent(szClsid);
  258. if ( FAILED(hr) )
  259. {
  260. ErrorMsg(IDS_ERROR_MISSINGDLL, IDS_ERROR_TITLE);
  261. return(hr);
  262. }
  263. // Run the wizard.
  264. LONG lRet = 0;
  265. spCW->DoModal(&lRet);
  266. // --------------------------------------------------------------------
  267. // Run the Committer(s) -- Commit()
  268. // lRet != 1 means they cancelled the wizard.
  269. // --------------------------------------------------------------------
  270. if ( lRet != 1 )
  271. {
  272. return hr;
  273. }
  274. CComPtr<IWizardCommit> spWAccntCommit = NULL;
  275. CComPtr<IStatusDlg> spSD = NULL;
  276. CComPtr<IStatusProgress> spComponentProg = NULL;
  277. BOOL bRO = FALSE;
  278. DWORD dwErrCode = 0;
  279. DWORD dwErrTemp = 0;
  280. CString strError = StrFormatSystemError(E_FAIL).c_str();
  281. strTitle.LoadString(IDS_TITLE);
  282. // Get the AU_Accnt component.
  283. hr = CoCreateInstance( __uuidof(AddUser_AccntCommit), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWizardCommit), (void**)&spWAccntCommit );
  284. if ( FAILED(hr) || !spWAccntCommit ) return FAILED(hr) ? hr : E_FAIL;
  285. // Get the Status Dialog
  286. hr = CoCreateInstance( __uuidof(StatusDlg), NULL, CLSCTX_INPROC_SERVER, __uuidof(IStatusDlg), (void **) &spSD );
  287. if ( FAILED(hr) || !spSD ) return FAILED(hr) ? hr : E_FAIL;
  288. // Initialize the Status Dialog
  289. VARIANT var;
  290. CString csText;
  291. CString csDescription;
  292. long lAccount;
  293. csText.LoadString(IDS_STATUS_INFO);
  294. VariantInit(&var);
  295. V_VT(&var) = VT_I4;
  296. var.lVal = SD_BUTTON_OK | SD_PROGRESS_OVERALL;
  297. hr = spSD->Initialize( CComBSTR(strTitle), CComBSTR(csText), var );
  298. if( FAILED(hr) ) return hr;
  299. // Add our four components
  300. csDescription.LoadString(IDS_STATUS_ACCNT);
  301. hr = spSD->AddComponent(CComBSTR(csDescription), &lAccount);
  302. if( FAILED(hr) ) return hr;
  303. // Display the Status Bar
  304. hr = spSD->Display(TRUE);
  305. if( FAILED(hr) ) return hr;
  306. // Get the Progress component
  307. hr = spSD->get_OverallProgress(&spComponentProg);
  308. if ( FAILED(hr) || !spComponentProg ) return FAILED(hr) ? hr : E_FAIL;
  309. // Initialize our stepping
  310. hr = spComponentProg->put_Step(1);
  311. if( FAILED(hr) ) return hr;
  312. // Initialize our starting spot
  313. hr = spComponentProg->put_Position(0);
  314. if( FAILED(hr) ) return hr;
  315. // Initialize our range
  316. hr = spComponentProg->put_Range(1); // Just the one!
  317. if( FAILED(hr) ) return hr;
  318. bool bDeleteUser = false;
  319. // Wipe out the component status checkmarks
  320. spSD->SetStatus(lAccount, SD_STATUS_NONE);
  321. // Put up the Progress text
  322. CString csFormatString = _T("");
  323. CString csUserName = _T("");
  324. // Read the two string to format
  325. csFormatString.LoadString(IDS_ERR_FORMAT_NAME);
  326. ReadString( spPPPBag, PROP_USER_CN, csUserName, &bRO );
  327. // This will be in the format "CN=USERNAME"
  328. csUserName = csUserName.Right(csUserName.GetLength()-3);
  329. // Format the string and display it
  330. TCHAR szTempAccount[1024] = {0};
  331. _sntprintf( szTempAccount, 1023, csFormatString, csUserName );
  332. CComBSTR bstrUserName = szTempAccount;
  333. spComponentProg->put_Text( bstrUserName );
  334. // Set the Account running
  335. spSD->SetStatus(lAccount, SD_STATUS_RUNNING);
  336. // Accnt Commit
  337. hr = spWAccntCommit->Commit( spDisp );
  338. if ( FAILED(hr) )
  339. {
  340. // We failed this component
  341. spSD->SetStatus(lAccount, SD_STATUS_FAILED);
  342. ReadInt4 ( spPPPBag, PROP_ACCNT_ERROR_CODE_GUID_STRING, (PLONG)&dwErrCode, &bRO );
  343. ReadString ( spPPPBag, PROP_ACCNT_ERROR_STR_GUID_STRING, strError, &bRO );
  344. if ( dwErrCode & ERROR_DUPE )
  345. {
  346. MessageBox(NULL, strError, strTitle, MB_OK | MB_ICONERROR);
  347. }
  348. else if ( dwErrCode & (ERROR_CREATION | ERROR_PROPERTIES) )
  349. {
  350. ::MessageBox(NULL, strError, strTitle, MB_OK | MB_ICONERROR);
  351. spWAccntCommit->Revert();
  352. }
  353. else if ( dwErrCode & (ERROR_MAILBOX | ERROR_MEMBERSHIPS | ERROR_PASSWORD) )
  354. {
  355. CString strOutput;
  356. strOutput.FormatMessage( IDS_ERROR_EXTENDED_FMT, strError );
  357. // Do they want to revert?
  358. if ( MessageBox(NULL, strOutput, strTitle, MB_YESNO | MB_ICONERROR) == IDYES )
  359. {
  360. spWAccntCommit->Revert();
  361. }
  362. }
  363. else
  364. {
  365. _ASSERT(FALSE);
  366. }
  367. }
  368. else
  369. {
  370. spSD->SetStatus(lAccount, SD_STATUS_SUCCEEDED);
  371. }
  372. // Done with the Committer Component
  373. spComponentProg->StepIt(1);
  374. spSD->WaitForUser();
  375. // ------------------------------------------------------------------------
  376. // All done.
  377. // ------------------------------------------------------------------------
  378. return hr;
  379. }
  380. // ----------------------------------------------------------------------------
  381. // Main()
  382. // ----------------------------------------------------------------------------
  383. extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
  384. {
  385. // Check that we are not already open.
  386. CSingleInstance cInst( SINGLE_INST_NAME );
  387. if ( cInst.IsOpen() )
  388. {
  389. return E_UNEXPECTED;
  390. }
  391. HRESULT hrAdmin = IsUserInGroup( DOMAIN_ALIAS_RID_ADMINS );
  392. if( hrAdmin != S_OK )
  393. {
  394. ErrorMsg(IDS_NOT_ADMIN, IDS_ERROR_TITLE);
  395. return E_ACCESSDENIED;
  396. }
  397. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  398. HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  399. #else
  400. HRESULT hRes = CoInitialize(NULL);
  401. #endif
  402. _ASSERT(SUCCEEDED(hRes));
  403. BOOL fBadUsage = FALSE;
  404. LPCTSTR lpszToken = NULL;
  405. LPTSTR pszCurrentPos = NULL;
  406. CString csTmp;
  407. // Init Global Vars.
  408. g_dwAutoCompMode = 0;
  409. g_szUserOU[0] = 0;
  410. lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
  411. _Module.Init(ObjectMap, hInstance);
  412. g_hInstance = hInstance;
  413. // ------------------------------------------------------------------------
  414. // Do the initial validation to make sure that we can execute the wizard.
  415. // If we can't, show an error and exit, if so, get the cmd line parameters
  416. // and do the wizard.
  417. // ------------------------------------------------------------------------
  418. int iTmp = -1;
  419. // ------------------------------------------------------------------------
  420. // Parse command line
  421. // ------------------------------------------------------------------------
  422. for ( fBadUsage = FALSE, lpszToken = _FindOption(lpCmdLine) ; // Init to no bad usage and get the first param.
  423. (!fBadUsage) && (lpszToken != NULL) && (pszCurrentPos = const_cast<LPTSTR>(lpszToken)) ; // While no bad usage and we still have a param...
  424. lpszToken = _FindOption(pszCurrentPos) ) // Get the next parameter.
  425. {
  426. switch ( *pszCurrentPos )
  427. {
  428. case _T('u'): // HomeOU
  429. case _T('U'):
  430. {
  431. // Only reads in MAX_PATH
  432. TCHAR szTemp[MAX_PATH+1] = {0};
  433. if ( !_ReadParam(pszCurrentPos, szTemp) )
  434. {
  435. fBadUsage = TRUE;
  436. }
  437. else
  438. {
  439. _tcsncpy( g_szUserOU, szTemp, MAX_PATH );
  440. MakeLDAPUpper( g_szUserOU );
  441. }
  442. break;
  443. }
  444. case _T('L'): // Auto Completion Mode
  445. case _T('l'):
  446. {
  447. TCHAR szMode[MAX_PATH+1] = {0};
  448. // Only reads in MAX_PATH
  449. if( !_ReadParam(pszCurrentPos, szMode) )
  450. {
  451. fBadUsage = TRUE;
  452. }
  453. else
  454. {
  455. g_dwAutoCompMode = _ttoi(szMode);
  456. }
  457. break;
  458. }
  459. default: // Unknown parameter.
  460. {
  461. fBadUsage = TRUE;
  462. break;
  463. }
  464. }
  465. }
  466. // ------------------------------------------------------------------------
  467. // Fix up the command line params and launch the wizard.
  468. // ------------------------------------------------------------------------
  469. if ( FixParams() )
  470. {
  471. DoAddUsr();
  472. }
  473. _Module.Term();
  474. CoUninitialize();
  475. return(S_OK);
  476. }
  477. DWORD FixParams(void)
  478. {
  479. CComPtr<IADs> pDS = NULL;
  480. NET_API_STATUS nApi;
  481. HRESULT hr = S_OK;
  482. CString csDns = L"";
  483. CString csNetbios = L"";
  484. PDOMAIN_CONTROLLER_INFO pDCInfo = NULL;
  485. PDOMAIN_CONTROLLER_INFO pDCI = NULL;
  486. DWORD dwErr = 0;
  487. ULONG ulGetDcFlags = DS_DIRECTORY_SERVICE_REQUIRED | DS_IP_REQUIRED |
  488. DS_WRITABLE_REQUIRED | DS_RETURN_FLAT_NAME;
  489. hr = DsGetDcName(NULL, NULL, NULL, NULL, DS_DIRECTORY_SERVICE_REQUIRED | DS_RETURN_DNS_NAME, &pDCI);
  490. if ( (hr == S_OK) && (pDCI != NULL) )
  491. {
  492. csDns = pDCI->DomainName;
  493. NetApiBufferFree (pDCI);
  494. pDCI = NULL;
  495. }
  496. // Pre-Windows2000 DNS name
  497. dwErr = DsGetDcName(NULL, (LPCWSTR)csDns, NULL, NULL, ulGetDcFlags, &pDCInfo);
  498. if ( pDCInfo )
  499. {
  500. csNetbios = pDCInfo->DomainName; // Get the NT4 DNS name.
  501. NetApiBufferFree(pDCInfo); // Free up the memory DsGetDcName() might have allocated.
  502. pDCInfo = NULL;
  503. }
  504. if ( dwErr != ERROR_SUCCESS ) // If there was a problem, try again.
  505. {
  506. ulGetDcFlags |= DS_FORCE_REDISCOVERY;
  507. dwErr = DsGetDcName(NULL, (LPCWSTR)csDns, NULL, NULL, ulGetDcFlags, &pDCInfo);
  508. if ( pDCInfo )
  509. {
  510. csNetbios = pDCInfo->DomainName; // Get the NT4 DNS name.
  511. NetApiBufferFree(pDCInfo); // Free up the memory DsGetDcName() might have allocated.
  512. pDCInfo = NULL;
  513. }
  514. }
  515. tstring strTemp = GetDomainPath((LPCTSTR)csDns);
  516. if ( strTemp.empty() )
  517. {
  518. ErrorMsg(IDS_CANT_FIND_DC, IDS_TITLE);
  519. return(0);
  520. }
  521. TCHAR szDomainOU[MAX_PATH] = {0};
  522. _sntprintf( szDomainOU, MAX_PATH-1, _T("LDAP://%s"), strTemp.c_str() );
  523. if ( FAILED(ADsGetObject(szDomainOU, IID_IADs, (void**)&pDS)) )
  524. {
  525. ErrorMsg(IDS_CANT_FIND_DC, IDS_TITLE);
  526. return(0);
  527. }
  528. // ------------------------------------------------------------------------
  529. // g_szUserOU
  530. // ------------------------------------------------------------------------
  531. if ( !_tcslen(g_szUserOU) || FAILED(ADsGetObject(g_szUserOU, IID_IADs, (void**) &pDS)) )
  532. {
  533. _sntprintf( g_szUserOU, (MAX_PATH*2)-1, L"LDAP://CN=Users,%s", strTemp.c_str() );
  534. }
  535. pDS = NULL;
  536. if( g_dwAutoCompMode > 3 )
  537. {
  538. g_dwAutoCompMode = 0;
  539. }
  540. return(1);
  541. }