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.

1048 lines
25 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation **/
  4. /**********************************************************************/
  5. /*
  6. helper.cpp
  7. Implementation of the following helper classes:
  8. CDlgHelper -- enable, check, getcheck of dialog items
  9. CStrArray -- manages an array of CString*
  10. It doesn't duplicate the string when add
  11. It deletes the pointers during destruction
  12. It imports and exports SAFEARRAY of BSTRs
  13. It has copy operatators
  14. CManagedPage -- provide a middle layer between CpropertyPage and
  15. real property page class to manage: readonly, set modify, and
  16. context help info.
  17. And global functions:
  18. BOOL CheckADsError() -- check error code from ADSI
  19. void DecorateName() -- make new name to "CN=name" for LDAP
  20. FILE HISTORY:
  21. */
  22. #include "stdafx.h"
  23. #include <afxtempl.h>
  24. #include <winldap.h>
  25. #include "helper.h"
  26. #include "resource.h"
  27. #include "lm.h"
  28. #include "dsrole.h"
  29. #include "lmserver.h"
  30. #include "iastrace.h"
  31. #include "raseapif.h"
  32. //build a StrArray from a safe array
  33. CBYTEArray::CBYTEArray(SAFEARRAY* pSA)
  34. {
  35. if(pSA) AppendSA(pSA);
  36. }
  37. //build a DWArray from another array
  38. CBYTEArray::CBYTEArray(const CBYTEArray& ba)
  39. {
  40. int count = ba.GetSize();
  41. for(int i = 0; i < count; i++)
  42. {
  43. try{
  44. Add(ba[i]);
  45. }
  46. catch(CMemoryException*)
  47. {
  48. throw;
  49. }
  50. }
  51. }
  52. //build a StrArray from a safe array
  53. bool CBYTEArray::AppendSA(SAFEARRAY* pSA)
  54. {
  55. if(!pSA) return false;
  56. CString* pString = NULL;
  57. long lIter;
  58. long lBound, uBound;
  59. union {
  60. VARIANT v;
  61. BYTE b;
  62. } value;
  63. bool bSuc = true; // ser return value to true;
  64. USES_CONVERSION;
  65. VariantInit(&(value.v));
  66. SafeArrayGetLBound(pSA, 1, &lBound);
  67. SafeArrayGetUBound(pSA, 1, &uBound);
  68. for(lIter = lBound; lIter <= uBound; lIter++)
  69. {
  70. if(SUCCEEDED(SafeArrayGetElement(pSA, &lIter, &value)))
  71. {
  72. if(pSA->cbElements == sizeof(VARIANT))
  73. Add(V_UI1(&(value.v)));
  74. else
  75. Add(value.b);
  76. }
  77. }
  78. return bSuc;
  79. }
  80. // convert an array of CString to SAFEARRAY
  81. CBYTEArray::operator SAFEARRAY*()
  82. {
  83. USES_CONVERSION;
  84. int count = GetSize();
  85. if(count == 0) return NULL;
  86. SAFEARRAYBOUND bound[1];
  87. SAFEARRAY* pSA = NULL;
  88. long l[2];
  89. VARIANT v;
  90. VariantInit(&v);
  91. bound[0].cElements = count;
  92. bound[0].lLbound = 0;
  93. try{
  94. // creat empty right size array
  95. #ifdef ARRAY_OF_VARIANT_OF_UI1
  96. pSA = SafeArrayCreate(VT_VARIANT, 1, bound);
  97. #else
  98. pSA = SafeArrayCreate(VT_UI1, 1, bound);
  99. #endif
  100. if(NULL == pSA) return NULL;
  101. // put in each element
  102. for (long i = 0; i < count; i++)
  103. {
  104. #ifdef ARRAY_OF_VARIANT_OF_UI1
  105. V_VT(&v) = VT_UI1;
  106. V_UI1(&v) = GetAt(i);
  107. l[0] = i;
  108. HRESULT hr = SafeArrayPutElement(pSA, l, &v);
  109. VariantClear(&v);
  110. if (FAILED(hr))
  111. {
  112. throw hr;
  113. }
  114. #else
  115. BYTE ele = GetAt(i);
  116. l[0] = i;
  117. HRESULT hr = SafeArrayPutElement(pSA, l, &ele);
  118. if (FAILED(hr))
  119. {
  120. throw hr;
  121. }
  122. #endif
  123. }
  124. }
  125. catch(...)
  126. {
  127. SafeArrayDestroy(pSA);
  128. pSA = NULL;
  129. VariantClear(&v);
  130. throw;
  131. }
  132. return pSA;
  133. }
  134. // return index if found, otherwise -1;
  135. int CBYTEArray::Find(const BYTE b) const
  136. {
  137. int count = GetSize();
  138. while(count--)
  139. {
  140. if(GetAt(count) == b) break;
  141. }
  142. return count;
  143. }
  144. CBYTEArray& CBYTEArray::operator = (const CBYTEArray& ba)
  145. {
  146. int count;
  147. RemoveAll();
  148. // copy new
  149. count = ba.GetSize();
  150. for(int i = 0; i < count; i++)
  151. {
  152. Add(ba[i]);
  153. }
  154. return *this;
  155. }
  156. HRESULT CBYTEArray::AssignBlob(PBYTE pByte, DWORD size)
  157. {
  158. RemoveAll();
  159. // copy new
  160. try{
  161. for(int i = 0; i < size; i++)
  162. {
  163. Add(*pByte++);
  164. }
  165. }
  166. catch(CMemoryException* pException)
  167. {
  168. pException->Delete();
  169. RemoveAll();
  170. return E_OUTOFMEMORY;
  171. }
  172. return S_OK;
  173. }
  174. HRESULT CBYTEArray::GetBlob(PBYTE pByte, DWORD* pSize)
  175. {
  176. *pSize = GetSize();
  177. if(pByte == NULL) return S_OK;
  178. ASSERT(*pSize >= GetSize());
  179. int i = 0;
  180. while(i < GetSize() && i < *pSize)
  181. {
  182. *pByte++ = GetAt(i++);
  183. }
  184. *pSize = i;
  185. return S_OK;
  186. }
  187. // helper function -- enable a dialog button
  188. void CDlgHelper::EnableDlgItem(CDialog* pDialog, int id, bool bEnable)
  189. {
  190. CWnd* pWnd = pDialog->GetDlgItem(id);
  191. ASSERT(pWnd);
  192. pWnd->EnableWindow(bEnable);
  193. }
  194. // helper function -- set check status of a dialog button
  195. void CDlgHelper::SetDlgItemCheck(CDialog* pDialog, int id, int nCheck)
  196. {
  197. CButton* pButton = (CButton*)pDialog->GetDlgItem(id);
  198. ASSERT(pButton);
  199. pButton->SetCheck(nCheck);
  200. }
  201. // helper function -- get check status of a dialog button
  202. int CDlgHelper::GetDlgItemCheck(CDialog* pDialog, int id)
  203. {
  204. CButton* pButton = (CButton*)(pDialog->GetDlgItem(id));
  205. ASSERT(pButton);
  206. return pButton->GetCheck();
  207. }
  208. CStrArray& CStrArray::operator = (const CStrArray& sarray)
  209. {
  210. int count = GetSize();
  211. CString* pString;
  212. // remove existing members
  213. while(count --)
  214. {
  215. pString = GetAt(0);
  216. RemoveAt(0);
  217. delete pString;
  218. }
  219. // copy new
  220. count = sarray.GetSize();
  221. for(int i = 0; i < count; i++)
  222. {
  223. pString = new CString(*sarray[i]);
  224. Add(pString);
  225. }
  226. return *this;
  227. }
  228. // convert an array of CString to SAFEARRAY
  229. CStrArray::operator SAFEARRAY*()
  230. {
  231. USES_CONVERSION;
  232. int count = GetSize();
  233. if(count == 0) return NULL;
  234. SAFEARRAYBOUND bound[1];
  235. SAFEARRAY* pSA = NULL;
  236. CString* pStr = NULL;
  237. long l[2];
  238. VARIANT v;
  239. VariantInit(&v);
  240. bound[0].cElements = count;
  241. bound[0].lLbound = 0;
  242. try{
  243. // creat empty right size array
  244. pSA = SafeArrayCreate(VT_VARIANT, 1, bound);
  245. if(NULL == pSA) return NULL;
  246. // put in each element
  247. for (long i = 0; i < count; i++)
  248. {
  249. pStr = GetAt(i);
  250. V_VT(&v) = VT_BSTR;
  251. V_BSTR(&v) = T2BSTR((LPTSTR)(LPCTSTR)(*pStr));
  252. l[0] = i;
  253. HRESULT hr = SafeArrayPutElement(pSA, l, &v);
  254. VariantClear(&v);
  255. if ( FAILED(hr) )
  256. {
  257. throw hr;
  258. }
  259. }
  260. }
  261. catch(...)
  262. {
  263. SafeArrayDestroy(pSA);
  264. pSA = NULL;
  265. VariantClear(&v);
  266. throw;
  267. }
  268. return pSA;
  269. }
  270. //build a StrArray from another array
  271. CStrArray::CStrArray(const CStrArray& sarray)
  272. {
  273. CString* pString = NULL;
  274. for (int i = 0; i < sarray.GetSize(); i++)
  275. {
  276. try
  277. {
  278. pString = new CString(*sarray[i]);
  279. Add(pString);
  280. }
  281. catch(CMemoryException*)
  282. {
  283. delete pString;
  284. throw;
  285. }
  286. }
  287. }
  288. int CStrArray::AddDuplicate(const CString& Str)
  289. {
  290. CString* pString;
  291. // no need to set a default value. Will throw if Add fails
  292. int position;
  293. try
  294. {
  295. pString = new CString(Str);
  296. position = Add(pString);
  297. }
  298. catch(CMemoryException*)
  299. {
  300. delete pString;
  301. throw;
  302. }
  303. return position;
  304. }
  305. void CStrArray::DeleteAt(int nIndex)
  306. {
  307. CString* pString = GetAt(nIndex);
  308. RemoveAt(nIndex);
  309. delete pString;
  310. }
  311. //build a StrArray from a safe array
  312. CStrArray::CStrArray(SAFEARRAY* pSA)
  313. {
  314. if(pSA) AppendSA(pSA);
  315. }
  316. //remove the elements from the array and delete them
  317. int CStrArray::DeleteAll()
  318. {
  319. int ret, count;
  320. CString* pStr;
  321. ret = count = GetSize();
  322. while(count--)
  323. {
  324. pStr = GetAt(0);
  325. RemoveAt(0);
  326. delete pStr;
  327. }
  328. return ret;
  329. }
  330. //build a StrArray from a safe array
  331. bool CStrArray::AppendSA(SAFEARRAY* pSA)
  332. {
  333. if(!pSA) return false;
  334. CString* pString = NULL;
  335. long lIter;
  336. long lBound, uBound;
  337. VARIANT v;
  338. bool bSuc = true; // ser return value to true;
  339. USES_CONVERSION;
  340. VariantInit(&v);
  341. try{
  342. SafeArrayGetLBound(pSA, 1, &lBound);
  343. SafeArrayGetUBound(pSA, 1, &uBound);
  344. for(lIter = lBound; lIter <= uBound; lIter++)
  345. {
  346. if(SUCCEEDED(SafeArrayGetElement(pSA, &lIter, &v)))
  347. {
  348. if(V_VT(&v) == VT_BSTR)
  349. {
  350. pString = new CString;
  351. (*pString) = (LPCTSTR)W2T(V_BSTR(&v));
  352. Add(pString);
  353. }
  354. }
  355. }
  356. }
  357. catch(CMemoryException*)
  358. {
  359. delete pString;
  360. VariantClear(&v);
  361. bSuc = false;
  362. throw;
  363. }
  364. return bSuc;
  365. }
  366. //build a StrArray from a safe array
  367. CStrArray::~CStrArray()
  368. {
  369. DeleteAll();
  370. }
  371. // return index if found, otherwise -1;
  372. int CStrArray::Find(const CString& Str) const
  373. {
  374. int count = GetSize();
  375. while(count--)
  376. {
  377. if (*GetAt(count) == Str) break;
  378. }
  379. return count;
  380. }
  381. //build a StrArray from a safe array
  382. CDWArray::CDWArray(SAFEARRAY* pSA)
  383. {
  384. if(pSA) AppendSA(pSA);
  385. }
  386. //build a DWArray from another array
  387. CDWArray::CDWArray(const CDWArray& dwarray)
  388. {
  389. int count = dwarray.GetSize();
  390. for(int i = 0; i < count; i++)
  391. {
  392. try{
  393. Add(dwarray[i]);
  394. }
  395. catch(CMemoryException*)
  396. {
  397. throw;
  398. }
  399. }
  400. }
  401. //build a StrArray from a safe array
  402. bool CDWArray::AppendSA(SAFEARRAY* pSA)
  403. {
  404. if(!pSA) return false;
  405. CString* pString = NULL;
  406. long lIter;
  407. long lBound, uBound;
  408. union {
  409. VARIANT v;
  410. DWORD dw;
  411. } value;
  412. bool bSuc = true; // ser return value to true;
  413. USES_CONVERSION;
  414. VariantInit(&(value.v));
  415. SafeArrayGetLBound(pSA, 1, &lBound);
  416. SafeArrayGetUBound(pSA, 1, &uBound);
  417. for(lIter = lBound; lIter <= uBound; lIter++)
  418. {
  419. if(SUCCEEDED(SafeArrayGetElement(pSA, &lIter, &value)))
  420. {
  421. if(pSA->cbElements == sizeof(VARIANT))
  422. Add(V_I4(&(value.v)));
  423. else
  424. Add(value.dw);
  425. }
  426. }
  427. return bSuc;
  428. }
  429. // convert an array of CString to SAFEARRAY
  430. CDWArray::operator SAFEARRAY*()
  431. {
  432. USES_CONVERSION;
  433. int count = GetSize();
  434. if(count == 0) return NULL;
  435. SAFEARRAYBOUND bound[1];
  436. SAFEARRAY* pSA = NULL;
  437. long l[2];
  438. #if 1
  439. VARIANT v;
  440. VariantInit(&v);
  441. #endif
  442. bound[0].cElements = count;
  443. bound[0].lLbound = 0;
  444. try{
  445. // creat empty right size array
  446. pSA = SafeArrayCreate(VT_VARIANT, 1, bound);
  447. if(NULL == pSA) return NULL;
  448. // put in each element
  449. for (long i = 0; i < count; i++)
  450. {
  451. #if 1 // changed to use VT_I4 directly, rather inside a variant
  452. V_VT(&v) = VT_I4;
  453. V_I4(&v) = GetAt(i);
  454. l[0] = i;
  455. HRESULT hr = SafeArrayPutElement(pSA, l, &v);
  456. VariantClear(&v);
  457. if (FAILED(hr))
  458. {
  459. throw hr;
  460. }
  461. #else
  462. int ele = GetAt(i);
  463. l[0] = i;
  464. HRESULT hr = SafeArrayPutElement(pSA, l, &ele);
  465. if (FAILED(hr))
  466. {
  467. throw hr;
  468. }
  469. #endif
  470. }
  471. }
  472. catch(...)
  473. {
  474. SafeArrayDestroy(pSA);
  475. pSA = NULL;
  476. #if 0
  477. VariantClear(&v);
  478. #endif
  479. throw;
  480. }
  481. return pSA;
  482. }
  483. // return index if found, otherwise -1;
  484. int CDWArray::Find(const DWORD dw) const
  485. {
  486. int count = GetSize();
  487. while(count--)
  488. {
  489. if(GetAt(count) == dw) break;
  490. }
  491. return count;
  492. }
  493. CDWArray& CDWArray::operator = (const CDWArray& dwarray)
  494. {
  495. int count;
  496. RemoveAll();
  497. // copy new
  498. count = dwarray.GetSize();
  499. for(int i = 0; i < count; i++)
  500. {
  501. Add(dwarray[i]);
  502. }
  503. return *this;
  504. }
  505. IMPLEMENT_DYNCREATE(CManagedPage, CPropertyPage)
  506. void CManagedPage::OnContextMenu(CWnd* pWnd, CPoint point)
  507. {
  508. if (m_pHelpTable)
  509. ::WinHelp (pWnd->m_hWnd, AfxGetApp()->m_pszHelpFilePath,
  510. HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID)m_pHelpTable);
  511. }
  512. BOOL CManagedPage::OnHelpInfo(HELPINFO* pHelpInfo)
  513. {
  514. if (pHelpInfo->iContextType == HELPINFO_WINDOW && m_pHelpTable)
  515. {
  516. ::WinHelp ((HWND)pHelpInfo->hItemHandle,
  517. AfxGetApp()->m_pszHelpFilePath,
  518. HELP_WM_HELP,
  519. (DWORD_PTR)(LPVOID)m_pHelpTable);
  520. }
  521. return TRUE;
  522. }
  523. int CManagedPage::MyMessageBox(UINT ids, UINT nType)
  524. {
  525. CString string;
  526. string.LoadString(ids);
  527. return MyMessageBox1(string, NULL, nType);
  528. }
  529. int CManagedPage::MyMessageBox1(LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType)
  530. {
  531. CString caption;
  532. if (lpszCaption == NULL)
  533. {
  534. GetWindowText(caption);
  535. }
  536. else
  537. {
  538. caption = lpszCaption;
  539. }
  540. return MessageBox(lpszText, caption, nType);
  541. }
  542. //+----------------------------------------------------------------------------
  543. //
  544. // Function: CheckADsError
  545. //
  546. // Sysnopsis: Checks the result code from an ADSI call.
  547. //
  548. // Returns: TRUE if no error.
  549. //
  550. //-----------------------------------------------------------------------------
  551. BOOL CheckADsError(HRESULT hr, BOOL fIgnoreAttrNotFound, PSTR file,
  552. int line)
  553. {
  554. if (SUCCEEDED(hr))
  555. return TRUE;
  556. if( hr == E_ADS_PROPERTY_NOT_FOUND && fIgnoreAttrNotFound)
  557. return TRUE;
  558. if (hr == HRESULT_FROM_WIN32(ERROR_EXTENDED_ERROR))
  559. {
  560. DWORD dwErr;
  561. WCHAR wszErrBuf[MAX_PATH+1];
  562. WCHAR wszNameBuf[MAX_PATH+1];
  563. ADsGetLastError(&dwErr, wszErrBuf, MAX_PATH, wszNameBuf, MAX_PATH);
  564. if ((LDAP_RETCODE)dwErr == LDAP_NO_SUCH_ATTRIBUTE && fIgnoreAttrNotFound)
  565. {
  566. return TRUE;
  567. }
  568. IASTracePrintf("Extended Error 0x%x: %ws %ws (%s @line %d)", dwErr,
  569. wszErrBuf, wszNameBuf, file, line);
  570. }
  571. else
  572. IASTracePrintf("Error %08lx (%s @line %d)", hr, file, line);
  573. return FALSE;
  574. }
  575. void DecorateName(LPWSTR outString, LPCWSTR inString)
  576. {
  577. wcscpy (outString, L"CN=");
  578. wcscat(outString, inString);
  579. }
  580. void FindNameByDN(LPWSTR outString, LPCWSTR inString)
  581. {
  582. LPWSTR p = wcsstr(inString, L"CN=");
  583. if(!p)
  584. p = wcsstr(inString, L"cn=");
  585. if(!p)
  586. wcscpy(outString, inString);
  587. else
  588. {
  589. p+=3;
  590. LPWSTR p1 = outString;
  591. while(*p == L' ') p++;
  592. while(*p != L',')
  593. *p1++ = *p++;
  594. *p1 = L'\0';
  595. }
  596. }
  597. #define MAX_STRING 1024
  598. //+----------------------------------------------------------------------------
  599. //
  600. // Function: ReportError
  601. //
  602. // Sysnopsis: Attempts to get a user-friendly error message from the system.
  603. //
  604. //-----------------------------------------------------------------------------
  605. void ReportError(HRESULT hr, int nStr, HWND hWnd)
  606. {
  607. PTSTR ptzSysMsg;
  608. int cch;
  609. CString AppStr;
  610. CString SysStr;
  611. CString ErrTitle;
  612. CString ErrMsg;
  613. if(S_OK == hr)
  614. return;
  615. IASTracePrintf("*+*+* ReportError called with hr = %lx", hr);
  616. if (!hWnd)
  617. {
  618. hWnd = GetDesktopWindow();
  619. }
  620. try{
  621. if (nStr)
  622. {
  623. AppStr.LoadString(nStr);
  624. }
  625. if(HRESULT_FACILITY(hr) == FACILITY_WIN32) // if win32 error code
  626. cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  627. NULL, HRESULT_CODE(hr), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  628. (PTSTR)&ptzSysMsg, 0, NULL);
  629. else
  630. cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  631. NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  632. (PTSTR)&ptzSysMsg, 0, NULL);
  633. if (!cch) { //try ads errors
  634. HMODULE adsMod;
  635. adsMod = GetModuleHandle (L"activeds.dll");
  636. cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE,
  637. adsMod, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  638. (PTSTR)&ptzSysMsg, 0, NULL);
  639. }
  640. if (!cch)
  641. {
  642. CString str;
  643. str.LoadString(IDS_ERR_ERRORCODE);
  644. SysStr.Format(str, hr);
  645. }
  646. else
  647. {
  648. SysStr = ptzSysMsg;
  649. LocalFree(ptzSysMsg);
  650. }
  651. ErrTitle.LoadString(IDS_ERR_TITLE);
  652. if(!AppStr.IsEmpty())
  653. {
  654. ErrMsg.Format(AppStr, (LPCTSTR)SysStr);
  655. }
  656. else
  657. {
  658. ErrMsg = SysStr;
  659. }
  660. MessageBox(hWnd, (LPCTSTR)ErrMsg, (LPCTSTR)ErrTitle, MB_OK | MB_ICONINFORMATION);
  661. }catch(CMemoryException* pException)
  662. {
  663. pException->Delete();
  664. MessageBox(hWnd, _T("No enought memory, please close other applications and try again."), _T("ACS Snapin Error"), MB_OK | MB_ICONINFORMATION);
  665. }
  666. }
  667. /////////////////////////////////////////////////////////////////////////////
  668. // Min Chars Dialog Data Validation
  669. void AFXAPI DDV_MinChars(CDataExchange* pDX, CString const& value, int nChars)
  670. {
  671. ASSERT(nChars >= 1); // allow them something
  672. if (pDX->m_bSaveAndValidate && value.GetLength() < nChars)
  673. {
  674. TCHAR szT[32];
  675. wsprintf(szT, _T("%d"), nChars);
  676. CString prompt;
  677. AfxFormatString1(prompt, IDS_MIN_CHARS, szT);
  678. AfxMessageBox(prompt, MB_ICONEXCLAMATION, IDS_MIN_CHARS);
  679. prompt.Empty(); // exception prep
  680. pDX->Fail();
  681. }
  682. }
  683. /*!--------------------------------------------------------------------------
  684. HrIsStandaloneServer
  685. Returns S_OK if the machine name passed in is a standalone server,
  686. or if pszMachineName is S_FALSE.
  687. Returns FALSE otherwise.
  688. Author: WeiJiang
  689. ---------------------------------------------------------------------------*/
  690. HRESULT HrIsStandaloneServer(LPCWSTR pMachineName)
  691. {
  692. DWORD netRet = 0;
  693. HRESULT hr = S_OK;
  694. DSROLE_PRIMARY_DOMAIN_INFO_BASIC* pdsRole = NULL;
  695. netRet = DsRoleGetPrimaryDomainInformation(pMachineName, DsRolePrimaryDomainInfoBasic, (LPBYTE*)&pdsRole);
  696. if(netRet != 0)
  697. {
  698. hr = HRESULT_FROM_WIN32(netRet);
  699. goto L_ERR;
  700. }
  701. ASSERT(pdsRole);
  702. // if the machine is not a standalone server
  703. if(pdsRole->MachineRole != DsRole_RoleStandaloneServer)
  704. {
  705. hr = S_FALSE;
  706. }
  707. L_ERR:
  708. if(pdsRole)
  709. DsRoleFreeMemory(pdsRole);
  710. return hr;
  711. }
  712. /*!--------------------------------------------------------------------------
  713. HrIsNTServer
  714. Author:
  715. ---------------------------------------------------------------------------*/
  716. HRESULT HrIsNTServer(LPCWSTR pMachineName)
  717. {
  718. HRESULT hr = S_OK;
  719. SERVER_INFO_102* pServerInfo102 = NULL;
  720. NET_API_STATUS netRet = 0;
  721. netRet = NetServerGetInfo((LPWSTR)pMachineName, 102, (LPBYTE*)&pServerInfo102);
  722. if(netRet != 0)
  723. {
  724. hr = HRESULT_FROM_WIN32(netRet);
  725. goto L_ERR;
  726. }
  727. ASSERT(pServerInfo102);
  728. if (!(pServerInfo102->sv102_type & SV_TYPE_SERVER_NT))
  729. {
  730. hr = S_FALSE;
  731. }
  732. L_ERR:
  733. if(pServerInfo102)
  734. NetApiBufferFree(pServerInfo102);
  735. return hr;
  736. }
  737. struct EnableChildControlsEnumParam
  738. {
  739. HWND m_hWndParent;
  740. DWORD m_dwFlags;
  741. };
  742. BOOL CALLBACK EnableChildControlsEnumProc(HWND hWnd, LPARAM lParam)
  743. {
  744. EnableChildControlsEnumParam * pParam;
  745. pParam = reinterpret_cast<EnableChildControlsEnumParam *>(lParam);
  746. // Enable/disable only if this is an immediate descendent
  747. if (GetParent(hWnd) == pParam->m_hWndParent)
  748. {
  749. if (pParam->m_dwFlags & PROPPAGE_CHILD_SHOW)
  750. ::ShowWindow(hWnd, SW_SHOW);
  751. else if (pParam->m_dwFlags & PROPPAGE_CHILD_HIDE)
  752. ::ShowWindow(hWnd, SW_HIDE);
  753. if (pParam->m_dwFlags & PROPPAGE_CHILD_ENABLE)
  754. ::EnableWindow(hWnd, TRUE);
  755. else if (pParam->m_dwFlags & PROPPAGE_CHILD_DISABLE)
  756. ::EnableWindow(hWnd, FALSE);
  757. }
  758. return TRUE;
  759. }
  760. HRESULT EnableChildControls(HWND hWnd, DWORD dwFlags)
  761. {
  762. EnableChildControlsEnumParam param;
  763. param.m_hWndParent = hWnd;
  764. param.m_dwFlags = dwFlags;
  765. EnumChildWindows(hWnd, EnableChildControlsEnumProc, (LPARAM) &param);
  766. return S_OK;
  767. }
  768. HRESULT LoadEapProviders(HKEY hkeyBase, AuthProviderArray *pProvList, BOOL bStandAlone);
  769. HRESULT GetEapProviders(LPCWSTR pServerName, AuthProviderArray *pProvList)
  770. {
  771. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  772. BOOL bStandAlone = ( S_OK == HrIsStandaloneServer(pServerName));
  773. // Get the list of EAP providers
  774. // ----------------------------------------------------------------
  775. HRESULT hr = S_OK;
  776. RegKey regkeyEap;
  777. DWORD dwErr = regkeyEap.Open(
  778. HKEY_LOCAL_MACHINE,
  779. RAS_EAP_REGISTRY_LOCATION,
  780. KEY_ALL_ACCESS,
  781. pServerName
  782. );
  783. if ( ERROR_SUCCESS == dwErr )
  784. {
  785. hr = LoadEapProviders(regkeyEap, pProvList, bStandAlone);
  786. }
  787. else
  788. {
  789. hr = HRESULT_FROM_WIN32(dwErr);
  790. }
  791. return hr;
  792. }
  793. /*!--------------------------------------------------------------------------
  794. DATA_SRV_AUTH::LoadEapProviders
  795. -
  796. Author: KennT
  797. ---------------------------------------------------------------------------*/
  798. HRESULT LoadEapProviders(HKEY hkeyBase, AuthProviderArray *pProvList, BOOL bStandAlone)
  799. {
  800. RegKey regkeyProviders;
  801. HRESULT hr = S_OK;
  802. HRESULT hrIter;
  803. RegKeyIterator regkeyIter;
  804. CString stKey;
  805. RegKey regkeyProv;
  806. AuthProviderData data;
  807. DWORD dwErr;
  808. DWORD dwData;
  809. ASSERT(hkeyBase);
  810. ASSERT(pProvList);
  811. // Open the providers key
  812. // ----------------------------------------------------------------
  813. regkeyProviders.Attach(hkeyBase);
  814. CHECK_HR(hr = regkeyIter.Init(&regkeyProviders) );
  815. for ( hrIter=regkeyIter.Next(&stKey); hrIter == S_OK;
  816. hrIter=regkeyIter.Next(&stKey), regkeyProv.Close() )
  817. {
  818. // Open the key
  819. // ------------------------------------------------------------
  820. dwErr = regkeyProv.Open(regkeyProviders, stKey, KEY_READ);
  821. if ( dwErr != ERROR_SUCCESS )
  822. continue;
  823. // Initialize the data structure
  824. // ------------------------------------------------------------
  825. data.m_stKey = stKey;
  826. data.m_stTitle.Empty();
  827. data.m_stConfigCLSID.Empty();
  828. data.m_stGuid.Empty();
  829. data.m_fSupportsEncryption = FALSE;
  830. data.m_stServerTitle.Empty();
  831. // Read in the values that we require
  832. // ------------------------------------------------------------
  833. regkeyProv.QueryValue(RAS_EAP_VALUENAME_FRIENDLY_NAME, data.m_stTitle);
  834. regkeyProv.QueryValue(
  835. RAS_EAP_VALUENAME_CONFIG_CLSID,
  836. data.m_stConfigCLSID
  837. );
  838. regkeyProv.QueryValue(RAS_EAP_VALUENAME_ENCRYPTION, dwData);
  839. data.m_fSupportsEncryption = (dwData != 0);
  840. if (ERROR_SUCCESS != regkeyProv.QueryValue(
  841. RAS_EAP_VALUENAME_PER_POLICY_CONFIG,
  842. dwData
  843. ))
  844. {
  845. dwData = 0;
  846. }
  847. if ((dwData != 0) || data.m_stConfigCLSID.IsEmpty())
  848. {
  849. data.m_stServerTitle = data.m_stTitle;
  850. }
  851. else
  852. {
  853. AfxFormatString1(
  854. data.m_stServerTitle,
  855. IDS_NO_PER_POLICY_EAP,
  856. data.m_stTitle
  857. );
  858. }
  859. // Read in the standalone supported value.
  860. // ------------------------------------------------------------
  861. if (ERROR_SUCCESS != regkeyProv.QueryValue(
  862. RAS_EAP_VALUENAME_STANDALONE_SUPPORTED,
  863. dwData
  864. ))
  865. {
  866. dwData = 1; // the default
  867. }
  868. if (dwData || !bStandAlone)
  869. {
  870. DWORD role;
  871. dwErr = regkeyProv.QueryValue(
  872. RAS_EAP_VALUENAME_ROLES_SUPPORTED,
  873. role
  874. );
  875. if ((dwErr != ERROR_SUCCESS) ||
  876. (((role & RAS_EAP_ROLE_AUTHENTICATOR) == 1) &&
  877. ((role & RAS_EAP_ROLE_EXCLUDE_IN_EAP) == 0)))
  878. {
  879. pProvList->Add(data);
  880. }
  881. }
  882. }
  883. L_ERR:
  884. regkeyProviders.Detach();
  885. return hr;
  886. }