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.

748 lines
19 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation **/
  4. /**********************************************************************/
  5. /*
  6. helper.h
  7. This file defines the following macros helper classes and functions:
  8. Macros to check HRESULT
  9. CDlgHelper -- helper class to Enable/Check dialog Item,
  10. CManagedPage -- helper class for PropertyPage,
  11. It manages ReadOnly, SetModified, and ContextHelp
  12. CStrArray -- an array of pointer to CString
  13. It does NOT duplicate the string upon Add
  14. and It deletes the pointer during destruction
  15. It imports and exports SAFEARRAY
  16. CReadWriteLock -- class for share read or exclusive write lock
  17. CStrBox -- wrapper class for CListBox and CComboBox
  18. CIPAddress -- wrapper for IPAddress
  19. CFramedRoute -- Wrapper for FramedRoute
  20. CStrParse -- parses string for TimeOfDay
  21. FILE HISTORY:
  22. */
  23. // helper functions for dialog and dialog items
  24. #ifndef _DLGHELPER_
  25. #define _DLGHELPER_
  26. #include "iastrace.h"
  27. #define SAYOK { return S_OK;}
  28. #define NOIMP { return E_NOTIMPL;}
  29. // to reduce the step to set VARIANT
  30. #define V__BOOL(v, v1)\
  31. V_VT(v) = VT_BOOL, V_BOOL(v) = (v1)
  32. #define V__I4(v, v1)\
  33. V_VT(v) = VT_I4, V_I4(v) = (v1)
  34. #define V__I2(v, v1)\
  35. V_VT(v) = VT_I2, V_I2(v) = (v1)
  36. #define V__UI1(v, v1)\
  37. V_VT(v) = VT_UI1, V_UI1(v) = (v1)
  38. #define V__BSTR(v, v1)\
  39. V_VT(v) = VT_BSTR, V_BSTR(v) = (v1)
  40. #define V__ARRAY(v, v1)\
  41. V_VT(v) = VT_ARRAY, V_ARRAY(v) = (v1)
  42. #define REPORT_ERROR(hr) \
  43. IASTracePrintf("**** ERROR RETURN <%s @line %d> -> %08lx", \
  44. __FILE__, __LINE__, hr)); \
  45. ReportError(hr, 0, 0);
  46. #ifdef _DEBUG
  47. #define CHECK_HR(hr)\
  48. {if(!CheckADsError(hr, FALSE, __FILE__, __LINE__)){goto L_ERR;}}
  49. #else
  50. #define CHECK_HR(hr)\
  51. if FAILED(hr) goto L_ERR
  52. #endif
  53. #ifdef _DEBUG
  54. #define NOTINCACHE(hr)\
  55. (CheckADsError(hr, TRUE, __FILE__, __LINE__))
  56. #else
  57. #define NOTINCACHE(hr)\
  58. (E_ADS_PROPERTY_NOT_FOUND == (hr))
  59. #endif
  60. BOOL CheckADsError(HRESULT hr, BOOL fIgnoreAttrNotFound, PSTR file, int line);
  61. #ifdef _DEBUG
  62. #define TRACEAfxMessageBox(id) {\
  63. IASTracePrintf("AfxMessageBox <%s @line %d> ID: %d", \
  64. __FILE__, __LINE__, id); \
  65. AfxMessageBox(id);}\
  66. #else
  67. #define TRACEAfxMessageBox(id) AfxMessageBox(id)
  68. #endif
  69. // change string Name to CN=Name
  70. void DecorateName(LPWSTR outString, LPCWSTR inString);
  71. // find name from DN for example LDAP://CN=userA,CN=users... returns userA
  72. void FindNameByDN(LPWSTR outString, LPCWSTR inString);
  73. class CDlgHelper
  74. {
  75. public:
  76. static void EnableDlgItem(CDialog* pDialog, int id, bool bEnable = true);
  77. static int GetDlgItemCheck(CDialog* pDialog, int id);
  78. static void SetDlgItemCheck(CDialog* pDialog, int id, int nCheck);
  79. };
  80. // class CPageManager and CManagedPage together handle the situation when
  81. // the property sheet need to do some processing when OnApply function is called
  82. // on some of the pages
  83. class CPageManager
  84. {
  85. public:
  86. CPageManager(){ m_bModified = FALSE; m_bReadOnly = FALSE;};
  87. BOOL GetModified(){ return m_bModified;};
  88. void SetModified(BOOL bModified){ m_bModified = bModified;};
  89. void SetReadOnly(BOOL bReadOnly){ m_bReadOnly = bReadOnly;};
  90. BOOL GetReadOnly(){ return m_bReadOnly;};
  91. virtual BOOL OnApply()
  92. {
  93. if (!GetModified()) return FALSE;
  94. SetModified(FALSE); // prevent from doing this more than once
  95. return TRUE;
  96. }; // to be implemented by the propertysheet
  97. protected:
  98. BOOL m_bModified;
  99. BOOL m_bReadOnly;
  100. };
  101. class CManagedPage : public CPropertyPage // talk back to property sheet
  102. {
  103. DECLARE_DYNCREATE(CManagedPage)
  104. public:
  105. CManagedPage() : CPropertyPage(){
  106. m_bModified = FALSE;
  107. m_bNeedToSave = FALSE;
  108. m_pManager = NULL;
  109. };
  110. CManagedPage(UINT nIDTemplate) : CPropertyPage(nIDTemplate)
  111. {
  112. m_bModified = FALSE;
  113. m_bNeedToSave = FALSE;
  114. m_pManager = NULL;
  115. };
  116. void SetModified( BOOL bModified = TRUE )
  117. {
  118. ASSERT(m_pManager);
  119. if(!m_pManager->GetReadOnly()) // if NOT readonly
  120. {
  121. m_bModified = bModified;
  122. m_bNeedToSave= bModified;
  123. CPropertyPage::SetModified(bModified);
  124. // only set change
  125. if(bModified) m_pManager->SetModified(TRUE);
  126. }
  127. };
  128. BOOL GetModified() { return m_bModified;};
  129. BOOL OnApply()
  130. {
  131. m_bModified = FALSE;
  132. BOOL b = TRUE;
  133. if(m_pManager->GetModified()) // prevent from entering more than once
  134. b= m_pManager->OnApply();
  135. return (b && CPropertyPage::OnApply());
  136. };
  137. // a page has three states: not dirty, dirty and need to save, and not dirty but need to save
  138. // m_bModified == dirty flag
  139. // m_bNeedToSave == need to save flag
  140. // When m_bNeedToSave && !m_bModified is detected upon on saved failure, the modified flag of the page is set
  141. BOOL OnSaved(BOOL bSaved)
  142. {
  143. if(bSaved)
  144. {
  145. m_bModified = FALSE;
  146. m_bNeedToSave = FALSE;
  147. }
  148. else if(m_bNeedToSave && !m_bModified)
  149. SetModified(TRUE);
  150. return TRUE;
  151. };
  152. void SetManager(CPageManager* pManager) { m_pManager = pManager;};
  153. CPageManager* GetManager() { return m_pManager;};
  154. protected:
  155. // help info process
  156. BOOL OnHelpInfo(HELPINFO* pHelpInfo);
  157. void OnContextMenu(CWnd* pWnd, ::CPoint point);
  158. void SetHelpTable(const DWORD* pTable) { m_pHelpTable = pTable;};
  159. int MyMessageBox(UINT ids, UINT nType = MB_OK);
  160. int MyMessageBox1(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK);
  161. protected:
  162. CPageManager* m_pManager;
  163. BOOL m_bModified;
  164. BOOL m_bNeedToSave;
  165. const DWORD* m_pHelpTable;
  166. };
  167. #include <afxtempl.h>
  168. class CStrArray : public CArray< ::CString*, ::CString* >
  169. {
  170. public:
  171. CStrArray(SAFEARRAY* pSA = NULL);
  172. CStrArray(const CStrArray& sarray);
  173. int Find(const ::CString& Str) const;
  174. int DeleteAll();
  175. virtual ~CStrArray();
  176. operator SAFEARRAY*();
  177. CStrArray& operator = (const CStrArray& sarray);
  178. bool AppendSA(SAFEARRAY* pSA);
  179. int AddDuplicate(const ::CString& Str);
  180. void DeleteAt(int nIndex);
  181. };
  182. class CDWArray : public CArray< DWORD, DWORD >
  183. {
  184. public:
  185. CDWArray(const CDWArray& dwarray);
  186. int Find(const DWORD dw) const;
  187. int DeleteAll(){ RemoveAll(); return 0;};
  188. virtual ~CDWArray(){RemoveAll();};
  189. CDWArray& operator = (const CDWArray& dwarray);
  190. operator SAFEARRAY*();
  191. bool AppendSA(SAFEARRAY* pSA);
  192. CDWArray(SAFEARRAY* pSA = NULL);
  193. };
  194. class CBYTEArray : public CArray< BYTE, BYTE >
  195. {
  196. public:
  197. CBYTEArray(const CBYTEArray& bytearray);
  198. int Find(const BYTE byte) const;
  199. int DeleteAll(){ RemoveAll(); return 0;};
  200. virtual ~CBYTEArray(){RemoveAll();};
  201. CBYTEArray& operator = (const CBYTEArray& bytearray);
  202. operator SAFEARRAY*();
  203. bool AppendSA(SAFEARRAY* pSA);
  204. HRESULT AssignBlob(PBYTE pByte, DWORD size);
  205. HRESULT GetBlob(PBYTE pByte, DWORD* pSize);
  206. CBYTEArray(SAFEARRAY* pSA = NULL);
  207. };
  208. // a lock to allow multiple read access exclusive or only one write access
  209. class CReadWriteLock // sharable read, exclusive write
  210. {
  211. public:
  212. CReadWriteLock() : m_nRead(0)
  213. {
  214. #ifdef _DEBUG
  215. d_bWrite = false;
  216. #endif
  217. };
  218. void EnterRead()
  219. {
  220. IASTraceString("Entering Read Lock ...");
  221. m_csRead.Lock();
  222. if (!m_nRead++)
  223. m_csWrite.Lock();
  224. m_csRead.Unlock();
  225. IASTraceString("Entered Read Lock");
  226. };
  227. void LeaveRead()
  228. {
  229. IASTraceString("Leaving Read Lock ...");
  230. m_csRead.Lock();
  231. ASSERT(m_nRead > 0);
  232. if (!--m_nRead)
  233. m_csWrite.Unlock();
  234. m_csRead.Unlock();
  235. IASTraceString("Left Read Lock");
  236. };
  237. void EnterWrite()
  238. {
  239. IASTraceString("Entering Write Lock ...");
  240. m_csWrite.Lock();
  241. IASTraceString("Entered Write Lock");
  242. #ifdef _DEBUG
  243. d_bWrite = true;
  244. #endif
  245. };
  246. void LeaveWrite()
  247. {
  248. #ifdef _DEBUG
  249. d_bWrite = false;
  250. #endif
  251. m_csWrite.Unlock();
  252. IASTraceString("Left Write Lock");
  253. };
  254. public:
  255. #ifdef _DEBUG
  256. bool d_bWrite;
  257. #endif
  258. protected:
  259. CCriticalSection m_csRead;
  260. CCriticalSection m_csWrite;
  261. int m_nRead;
  262. };
  263. // to manage a list box/ combo box
  264. template <class CBox>
  265. class CStrBox
  266. {
  267. public:
  268. CStrBox(CDialog* pDialog, int id, CStrArray& Strings)
  269. : m_Strings(Strings), m_id(id)
  270. {
  271. m_pDialog = pDialog;
  272. m_pBox = NULL;
  273. };
  274. int Fill()
  275. {
  276. m_pBox = (CBox*)m_pDialog->GetDlgItem(m_id);
  277. ASSERT(m_pBox);
  278. m_pBox->ResetContent();
  279. int count = (int)m_Strings.GetSize();
  280. int index;
  281. for(int i = 0; i < count; i++)
  282. {
  283. index = m_pBox->AddString(*m_Strings[(INT_PTR)i]);
  284. m_pBox->SetItemDataPtr(index, m_Strings[(INT_PTR)i]);
  285. }
  286. return count;
  287. };
  288. int DeleteSelected()
  289. {
  290. int index;
  291. ASSERT(m_pBox);
  292. index = m_pBox->GetCurSel();
  293. // if there is any selected
  294. if( index != LB_ERR )
  295. {
  296. CString* pStr;
  297. pStr = (CString*)m_pBox->GetItemDataPtr(index);
  298. // remove the entry from the box
  299. m_pBox->DeleteString(index);
  300. // find the string in the String array
  301. int count = static_cast<int>(m_Strings.GetSize());
  302. for(int i = 0; i < count; i++)
  303. {
  304. if (m_Strings[(INT_PTR)i] == pStr)
  305. break;
  306. }
  307. ASSERT(i < count);
  308. // remove the string from the string array
  309. m_Strings.RemoveAt(i);
  310. index = i;
  311. delete pStr;
  312. }
  313. return index;
  314. };
  315. int AddString(::CString* pStr) // the pStr needs to dynamically allocated
  316. {
  317. int index;
  318. ASSERT(m_pBox && pStr);
  319. index = m_pBox->AddString(*pStr);
  320. m_pBox->SetItemDataPtr(index, pStr);
  321. return m_Strings.Add(pStr);
  322. };
  323. int Select(int arrayindex) // the pStr needs to dynamically allocated
  324. {
  325. ASSERT(arrayindex < m_Strings.GetSize());
  326. return m_pBox->SelectString(0, *m_Strings[(INT_PTR)arrayindex]);
  327. };
  328. void Enable(BOOL b) // the pStr needs to dynamically allocated
  329. {
  330. ASSERT(m_pBox);
  331. m_pBox->EnableWindow(b);
  332. };
  333. int GetSelected() // it returns the index where the
  334. {
  335. int index;
  336. ASSERT(m_pBox);
  337. index = m_pBox->GetCurSel();
  338. // if there is any selected
  339. if( index != LB_ERR )
  340. {
  341. ::CString* pStr;
  342. pStr = (::CString*)m_pBox->GetItemDataPtr(index);
  343. // find the string in the String array
  344. int count = (int)m_Strings.GetSize();
  345. for(int i = 0; i < count; i++)
  346. {
  347. if (m_Strings[(INT_PTR)i] == pStr)
  348. break;
  349. }
  350. ASSERT(i < count);
  351. index = i;
  352. }
  353. return index;
  354. };
  355. CBox* m_pBox;
  356. protected:
  357. int m_id;
  358. CStrArray& m_Strings;
  359. CDialog* m_pDialog;
  360. };
  361. // class to take care of ip address
  362. class CIPAddress
  363. {
  364. public:
  365. CIPAddress(DWORD address = 0)
  366. {
  367. m_dwAddress = address;
  368. };
  369. operator DWORD() { return m_dwAddress;};
  370. operator ::CString()
  371. {
  372. ::CString str;
  373. WORD hi = HIWORD(m_dwAddress);
  374. WORD lo = LOWORD(m_dwAddress);
  375. str.Format(_T("%-d.%-d.%-d.%d"), HIBYTE(hi), LOBYTE(hi), HIBYTE(lo), LOBYTE(lo));
  376. return str;
  377. };
  378. DWORD m_dwAddress;
  379. };
  380. // format of framedroute: mask dest metric ; mask and dest in dot format
  381. class CFramedRoute
  382. {
  383. public:
  384. void SetRoute(::CString* pRoute)
  385. {
  386. m_pStrRoute = pRoute;
  387. m_pStrRoute->TrimLeft();
  388. m_pStrRoute->TrimRight();
  389. m_iFirstSpace = m_pStrRoute->Find(_T(' ')) ;
  390. m_iLastSpace = m_pStrRoute->ReverseFind(_T(' ')) ;
  391. };
  392. ::CString& GetDest(::CString& dest) const
  393. {
  394. int i = m_pStrRoute->Find(_T('/'));
  395. if(i == -1)
  396. i = m_iFirstSpace;
  397. dest = m_pStrRoute->Left(i);
  398. return dest;
  399. };
  400. ::CString& GetNextStop(::CString& nextStop) const
  401. {
  402. nextStop = m_pStrRoute->Mid(m_iFirstSpace + 1, m_iLastSpace - m_iFirstSpace -1 );
  403. return nextStop;
  404. };
  405. ::CString& GetPrefixLength(::CString& prefixLength) const
  406. {
  407. int i = m_pStrRoute->Find(_T('/'));
  408. if( i != -1)
  409. {
  410. prefixLength = m_pStrRoute->Mid(i + 1, m_iFirstSpace - i - 1);
  411. }
  412. else
  413. prefixLength = _T("");
  414. return prefixLength;
  415. };
  416. ::CString& GetMask(::CString& mask) const
  417. {
  418. int i = m_pStrRoute->Find(_T('/'));
  419. DWORD dwMask = 0;
  420. DWORD dwBit = 0x80000000;
  421. DWORD dwPrefixLen;
  422. if( i != -1)
  423. {
  424. mask = m_pStrRoute->Mid(i + 1, m_iFirstSpace - i - 1);
  425. dwPrefixLen = _ttol((LPCTSTR)mask);
  426. while(dwPrefixLen--)
  427. {
  428. dwMask |= dwBit;
  429. dwBit >>= 1;
  430. }
  431. }
  432. else
  433. dwMask = 0;
  434. WORD hi1, lo1;
  435. hi1 = HIWORD(dwMask); lo1 = LOWORD(dwMask);
  436. mask.Format(_T("%-d.%-d.%d.%d"),
  437. HIBYTE(hi1), LOBYTE(hi1), HIBYTE(lo1), LOBYTE(lo1));
  438. return mask;
  439. };
  440. ::CString& GetMetric(::CString& metric) const
  441. {
  442. metric = m_pStrRoute->Mid(m_iLastSpace + 1);
  443. return metric;
  444. };
  445. protected:
  446. // WARNING: the string is not copied, so user need to make sure the origin is valid
  447. ::CString* m_pStrRoute;
  448. int m_iFirstSpace;
  449. int m_iLastSpace;
  450. };
  451. class CStrParser
  452. {
  453. public:
  454. CStrParser(LPCTSTR pStr = NULL) : m_pStr(pStr) { }
  455. // get the current string position
  456. LPCTSTR GetStr() const { return m_pStr;};
  457. void SetStr(LPCTSTR pStr) { m_pStr = pStr;};
  458. // find a unsigned interger and return it, -1 == not found
  459. int GetUINT()
  460. {
  461. UINT ret = 0;
  462. while((*m_pStr < _T('0') || *m_pStr > _T('9')) && *m_pStr != _T('\0'))
  463. m_pStr++;
  464. if(*m_pStr == _T('\0')) return -1;
  465. while(*m_pStr >= _T('0') && *m_pStr <= _T('9'))
  466. {
  467. ret = ret * 10 + *m_pStr - _T('0');
  468. m_pStr++;
  469. }
  470. return ret;
  471. };
  472. // find c and skip it
  473. int GotoAfter(TCHAR c)
  474. {
  475. int ret = 0;
  476. // go until find c or end of string
  477. while(*m_pStr != c && *m_pStr != _T('\0'))
  478. m_pStr++, ret++;
  479. // if found
  480. if(*m_pStr == c)
  481. m_pStr++, ret++;
  482. else
  483. ret = -1;
  484. return ret;
  485. };
  486. // skip blank characters space tab
  487. void SkipBlank()
  488. {
  489. while((*m_pStr == _T(' ') || *m_pStr == _T('\t')) && *m_pStr != _T('\0'))
  490. m_pStr++;
  491. };
  492. // check to see if the first character is '0'-'6' for Monday(0) to Sunday(6)
  493. int DayOfWeek() {
  494. SkipBlank();
  495. if(*m_pStr >= _T('0') && *m_pStr <= _T('6'))
  496. return (*m_pStr++ - _T('0'));
  497. else
  498. return -1; // not day of week
  499. };
  500. protected:
  501. LPCTSTR m_pStr;
  502. private:
  503. ::CString _strTemp;
  504. };
  505. void ReportError(HRESULT hr, int nStr, HWND hWnd);
  506. // number of characters
  507. void AFXAPI DDV_MinChars(CDataExchange* pDX, ::CString const& value, int nChars);
  508. /*!--------------------------------------------------------------------------
  509. IsStandaloneServer
  510. Returns S_OK if the machine name passed in is a standalone server,
  511. or if pszMachineName is S_FALSE.
  512. Returns S_FALSE otherwise.
  513. Author: WeiJiang
  514. ---------------------------------------------------------------------------*/
  515. HRESULT HrIsStandaloneServer(LPCTSTR pszMachineName);
  516. HRESULT HrIsNTServer(LPCWSTR pMachineName);
  517. class CBSTR
  518. {
  519. public:
  520. CBSTR() : m_bstr(NULL) {};
  521. CBSTR(LPCSTR cstr) : m_bstr(NULL)
  522. {
  523. USES_CONVERSION;
  524. m_bstr = A2BSTR(cstr);
  525. };
  526. CBSTR(LPCWSTR wstr) : m_bstr(NULL)
  527. {
  528. USES_CONVERSION;
  529. m_bstr = W2BSTR(wstr);
  530. };
  531. BSTR AssignBlob(const char* pByte, UINT size)
  532. {
  533. SysFreeString(m_bstr);
  534. m_bstr = SysAllocStringByteLen(pByte, size);
  535. return m_bstr;
  536. };
  537. BSTR AssignBSTR(const BSTR bstr)
  538. {
  539. return AssignBlob((const char *)bstr, SysStringByteLen(bstr));
  540. };
  541. UINT ByteLen()
  542. {
  543. UINT n = 0;
  544. if(m_bstr)
  545. n = SysStringByteLen(m_bstr);
  546. return n;
  547. };
  548. operator BSTR() { return m_bstr;};
  549. void Clean()
  550. {
  551. SysFreeString(m_bstr);
  552. m_bstr = NULL;
  553. };
  554. ~CBSTR()
  555. {
  556. Clean();
  557. };
  558. BSTR m_bstr;
  559. };
  560. template<class T> class CNetDataPtr
  561. {
  562. public:
  563. CNetDataPtr():m_pData(NULL){};
  564. ~CNetDataPtr()
  565. {
  566. NetApiBufferFree(m_pData);
  567. };
  568. T** operator&()
  569. {
  570. return &m_pData;
  571. };
  572. operator T*()
  573. {
  574. return m_pData;
  575. };
  576. T* operator ->()
  577. {
  578. return m_pData;
  579. };
  580. T* m_pData;
  581. };
  582. /*!--------------------------------------------------------------------------
  583. EnableChildControls
  584. Use this function to enable/disable/hide/show all child controls
  585. on a page (actually it will work with any child windows, the
  586. parent does not have to be a property page).
  587. Author: KennT
  588. ---------------------------------------------------------------------------*/
  589. HRESULT EnableChildControls(HWND hWnd, DWORD dwFlags);
  590. #define PROPPAGE_CHILD_SHOW 0x00000001
  591. #define PROPPAGE_CHILD_HIDE 0x00000002
  592. #define PROPPAGE_CHILD_ENABLE 0x00000004
  593. #define PROPPAGE_CHILD_DISABLE 0x00000008
  594. /*---------------------------------------------------------------------------
  595. Struct: AuthProviderData
  596. This structure is used to hold information for Authentication AND
  597. Accounting providers.
  598. ---------------------------------------------------------------------------*/
  599. struct AuthProviderData
  600. {
  601. // The following fields will hold data for ALL auth/acct/EAP providers
  602. ::CString m_stTitle;
  603. ::CString m_stConfigCLSID; // CLSID for config object
  604. ::CString m_stProviderTypeGUID; // GUID for the provider type
  605. // These fields are used by auth/acct providers.
  606. ::CString m_stGuid; // the identifying guid
  607. // This flag is used for EAP providers
  608. ::CString m_stKey; // name of registry key (for this provider)
  609. BOOL m_fSupportsEncryption; // used by EAP provider data
  610. ::CString m_stServerTitle; // Title displayed on server.
  611. };
  612. typedef CArray<AuthProviderData, AuthProviderData&> AuthProviderArray;
  613. #ifndef IASAPI
  614. #define IASAPI __declspec(dllimport)
  615. #endif
  616. HRESULT IASAPI GetEapProviders(
  617. LPCWSTR machineName,
  618. AuthProviderArray *pProvList
  619. );
  620. #endif