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.

1393 lines
34 KiB

  1. /****************************************************************************
  2. *
  3. * FILE: ConfUtil.cpp
  4. *
  5. * CONTENTS: CConfRoom and app level utility functions
  6. *
  7. ****************************************************************************/
  8. #include "precomp.h"
  9. #include "resource.h"
  10. #include "confwnd.h"
  11. #include "rostinfo.h"
  12. #include "conf.h"
  13. #include "nmmkcert.h"
  14. #include "certui.h"
  15. #include <ulsreg.h>
  16. #include <confreg.h>
  17. #include "shlWAPI.h"
  18. #include "confutil.h"
  19. #include "confpolicies.h"
  20. #include "rend.h"
  21. HFONT g_hfontDlg = NULL; // Default dialog font
  22. #ifdef DEBUG
  23. HDBGZONE ghZoneOther = NULL; // Other, conf.exe specific zones
  24. static PTCHAR _rgZonesOther[] = {
  25. TEXT("UI"),
  26. TEXT("API"),
  27. TEXT("Video"),
  28. TEXT("Wizard"),
  29. TEXT("QoS"),
  30. TEXT("RefCount"),
  31. TEXT("Objects "),
  32. TEXT("UI Msg"),
  33. TEXT("Call Control"),
  34. };
  35. BOOL InitDebugZones(VOID)
  36. {
  37. DBGINIT(&ghZoneOther, _rgZonesOther);
  38. return TRUE;
  39. }
  40. VOID DeinitDebugZones(VOID)
  41. {
  42. DBGDEINIT(&ghZoneOther);
  43. }
  44. VOID DbgMsg(UINT iZone, PSTR pszFormat,...)
  45. {
  46. if (GETZONEMASK(ghZoneOther) & (1 << iZone))
  47. {
  48. va_list v1;
  49. va_start(v1, pszFormat);
  50. DbgZVPrintf(ghZoneOther, iZone, pszFormat, v1);
  51. va_end(v1);
  52. }
  53. }
  54. VOID DbgMsgRefCount(PSTR pszFormat,...)
  55. {
  56. if (GETZONEMASK(ghZoneOther) & ZONE_REFCOUNT)
  57. {
  58. va_list v1;
  59. va_start(v1, pszFormat);
  60. DbgZVPrintf(ghZoneOther, iZONE_REFCOUNT, pszFormat, v1);
  61. va_end(v1);
  62. }
  63. }
  64. VOID DbgMsgApi(PSTR pszFormat,...)
  65. {
  66. if (GETZONEMASK(ghZoneOther) & ZONE_API)
  67. {
  68. va_list v1;
  69. va_start(v1, pszFormat);
  70. DbgZVPrintf(ghZoneOther, iZONE_API, pszFormat, v1);
  71. va_end(v1);
  72. }
  73. }
  74. VOID DbgMsgVideo(PSTR pszFormat,...)
  75. {
  76. if (GETZONEMASK(ghZoneOther) & ZONE_VIDEO)
  77. {
  78. va_list v1;
  79. va_start(v1, pszFormat);
  80. DbgZVPrintf(ghZoneOther, iZONE_VIDEO, pszFormat, v1);
  81. va_end(v1);
  82. }
  83. }
  84. VOID DbgMsgUI(PSTR pszFormat,...)
  85. {
  86. if (GETZONEMASK(ghZoneOther) & ZONE_UI)
  87. {
  88. va_list v1;
  89. va_start(v1, pszFormat);
  90. DbgZVPrintf(ghZoneOther, iZONE_UI, pszFormat, v1);
  91. va_end(v1);
  92. }
  93. }
  94. VOID DbgMsgCall(PSTR pszFormat,...)
  95. {
  96. if (GETZONEMASK(ghZoneOther) & ZONE_UI)
  97. {
  98. va_list v1;
  99. va_start(v1, pszFormat);
  100. DbgZVPrintf(ghZoneOther, iZONE_UI, pszFormat, v1);
  101. va_end(v1);
  102. }
  103. }
  104. #endif /* DEBUG */
  105. /* F L O A D S T R I N G */
  106. /*----------------------------------------------------------------------------
  107. %%Function: FLoadString
  108. Load a resource string.
  109. Assumes the buffer is valid and can hold the resource.
  110. ----------------------------------------------------------------------------*/
  111. BOOL FLoadString(UINT id, LPTSTR lpsz, UINT cch)
  112. {
  113. ASSERT(NULL != _Module.GetModuleInstance());
  114. ASSERT(NULL != lpsz);
  115. if (0 == ::LoadString(_Module.GetResourceModule(), id, lpsz, cch))
  116. {
  117. ERROR_OUT(("*** Resource %d does not exist", id));
  118. *lpsz = _T('\0');
  119. return FALSE;
  120. }
  121. return TRUE;
  122. }
  123. /* F L O A D S T R I N G 1 */
  124. /*----------------------------------------------------------------------------
  125. %%Function: FLoadString1
  126. Loads a resource string an formats it with the parameter.
  127. Assumes the resource is less than MAX_PATH characters
  128. ----------------------------------------------------------------------------*/
  129. BOOL FLoadString1(UINT id, LPTSTR lpsz, LPVOID p)
  130. {
  131. TCHAR sz[MAX_PATH];
  132. if (!FLoadString(id, sz, CCHMAX(sz)))
  133. return FALSE;
  134. wsprintf(lpsz, sz, p);
  135. return TRUE;
  136. }
  137. /* F L O A D S T R I N G 2 */
  138. /*----------------------------------------------------------------------------
  139. %%Function: FLoadString2
  140. Load a resource string. Return the length.
  141. Assumes the buffer is valid and can hold the resource.
  142. ----------------------------------------------------------------------------*/
  143. int FLoadString2(UINT id, LPTSTR lpsz, UINT cch)
  144. {
  145. ASSERT(NULL != _Module.GetModuleInstance());
  146. ASSERT(NULL != lpsz);
  147. int length = ::LoadString(_Module.GetResourceModule(), id, lpsz, cch);
  148. if (0 == length)
  149. {
  150. ERROR_OUT(("*** Resource %d does not exist", id));
  151. *lpsz = _T('\0');
  152. }
  153. return length;
  154. }
  155. /* P S Z L O A D S T R I N G */
  156. /*-------------------------------------------------------------------------
  157. %%Function: PszLoadString
  158. Return the string associated with the resource.
  159. -------------------------------------------------------------------------*/
  160. LPTSTR PszLoadString(UINT id)
  161. {
  162. TCHAR sz[MAX_PATH];
  163. if (0 == ::LoadString(::GetInstanceHandle(), id, sz, CCHMAX(sz)))
  164. {
  165. ERROR_OUT(("*** Resource %d does not exist", id));
  166. sz[0] = _T('\0');
  167. }
  168. return PszAlloc(sz);
  169. }
  170. /* L O A D R E S I N T */
  171. /*-------------------------------------------------------------------------
  172. %%Function: LoadResInt
  173. Return the integer associated with the resource string.
  174. -------------------------------------------------------------------------*/
  175. int LoadResInt(UINT id, int iDefault)
  176. {
  177. TCHAR sz[MAX_PATH];
  178. if (0 == ::LoadString(::GetInstanceHandle(), id, sz, CCHMAX(sz)))
  179. return iDefault;
  180. return RtStrToInt(sz);
  181. }
  182. /* F C R E A T E I L S N A M E */
  183. /*-------------------------------------------------------------------------
  184. %%Function: FCreateIlsName
  185. Combine the server and email names to form an ILS name.
  186. Return TRUE if the result fit in the buffer.
  187. -------------------------------------------------------------------------*/
  188. BOOL FCreateIlsName(LPTSTR pszDest, LPCTSTR pszServer, LPCTSTR pszEmail, int cchMax)
  189. {
  190. ASSERT(NULL != pszDest);
  191. TCHAR szServer[MAX_PATH];
  192. if (FEmptySz(pszServer))
  193. {
  194. lstrcpyn( szServer, CDirectoryManager::get_defaultServer(), CCHMAX( szServer ) );
  195. pszServer = szServer;
  196. }
  197. if (FEmptySz(pszEmail))
  198. {
  199. WARNING_OUT(("FCreateIlsName: Null email name?"));
  200. return FALSE;
  201. }
  202. int cch = lstrlen(pszServer);
  203. lstrcpyn(pszDest, pszServer, cchMax);
  204. if (cch >= (cchMax-2))
  205. return FALSE;
  206. pszDest += cch;
  207. *pszDest++ = _T('/');
  208. cchMax -= (cch+1);
  209. lstrcpyn(pszDest, pszEmail, cchMax);
  210. return (lstrlen(pszEmail) < cchMax);
  211. }
  212. /* G E T D E F A U L T N A M E */
  213. /*-------------------------------------------------------------------------
  214. %%Function: GetDefaultName
  215. -------------------------------------------------------------------------*/
  216. BOOL GetDefaultName(LPTSTR pszName, int nBufferMax)
  217. {
  218. BOOL bRet = TRUE;
  219. ASSERT(pszName);
  220. // First, try to get the Registered User Name from Windows:
  221. RegEntry re(WINDOWS_CUR_VER_KEY, HKEY_LOCAL_MACHINE);
  222. lstrcpyn(pszName, re.GetString(REGVAL_REGISTERED_OWNER), nBufferMax);
  223. if (_T('\0') == pszName[0])
  224. {
  225. // The registered name was empty, try the computer name:
  226. DWORD dwBufMax = nBufferMax;
  227. if ((FALSE == ::GetComputerName(pszName, &dwBufMax)) ||
  228. (_T('\0') == pszName[0]))
  229. {
  230. // The computer name was empty, use UNKNOWN:
  231. bRet = FLoadString(IDS_UNKNOWN, pszName, nBufferMax);
  232. }
  233. }
  234. return bRet;
  235. }
  236. /* E X T R A C T S E R V E R N A M E */
  237. /*-------------------------------------------------------------------------
  238. %%Function: ExtractServerName
  239. Extract the server name from pcszAddr and copy it into pszServer.
  240. Return a pointer to the remaining data.
  241. Uses the default server name if none is found.
  242. Returns a pointer to the 2nd portion of the name.
  243. -------------------------------------------------------------------------*/
  244. LPCTSTR ExtractServerName(LPCTSTR pcszAddr, LPTSTR pszServer, UINT cchMax)
  245. {
  246. LPCTSTR pchSlash = _StrChr(pcszAddr, _T('/'));
  247. if (NULL == pchSlash)
  248. {
  249. lstrcpyn( pszServer, CDirectoryManager::get_defaultServer(), cchMax );
  250. }
  251. else
  252. {
  253. lstrcpyn(pszServer, pcszAddr, (int)(1 + (pchSlash - pcszAddr)));
  254. pcszAddr = pchSlash+1;
  255. }
  256. return pcszAddr;
  257. }
  258. BOOL FBrowseForFolder(LPTSTR pszFolder, UINT cchMax, LPCTSTR pszTitle, HWND hwndParent)
  259. {
  260. LPITEMIDLIST pidlRoot;
  261. SHGetSpecialFolderLocation(HWND_DESKTOP, CSIDL_DRIVES, &pidlRoot);
  262. BROWSEINFO bi;
  263. ClearStruct(&bi);
  264. bi.hwndOwner = hwndParent;
  265. bi.lpszTitle = pszTitle;
  266. bi.ulFlags = BIF_RETURNONLYFSDIRS;
  267. bi.pidlRoot = pidlRoot;
  268. LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
  269. BOOL fRet = (pidl != NULL);
  270. if (fRet)
  271. {
  272. ASSERT(cchMax >= MAX_PATH);
  273. SHGetPathFromIDList(pidl, pszFolder);
  274. ASSERT(lstrlen(pszFolder) < (int) cchMax);
  275. }
  276. // Get the shell's allocator to free PIDLs
  277. LPMALLOC lpMalloc;
  278. if (!SHGetMalloc(&lpMalloc) && (NULL != lpMalloc))
  279. {
  280. if (NULL != pidlRoot)
  281. {
  282. lpMalloc->Free(pidlRoot);
  283. }
  284. if (pidl)
  285. {
  286. lpMalloc->Free(pidl);
  287. }
  288. lpMalloc->Release();
  289. }
  290. return fRet;
  291. }
  292. /* D I S A B L E C O N T R O L */
  293. /*-------------------------------------------------------------------------
  294. %%Function: DisableControl
  295. -------------------------------------------------------------------------*/
  296. VOID DisableControl(HWND hdlg, int id)
  297. {
  298. if ((NULL != hdlg) && (0 != id))
  299. {
  300. HWND hwndCtrl = GetDlgItem(hdlg, id);
  301. ASSERT(NULL != hwndCtrl);
  302. EnableWindow(hwndCtrl, FALSE);
  303. }
  304. }
  305. BOOL IsWindowActive(HWND hwnd)
  306. {
  307. HWND hwndFocus = GetFocus();
  308. while (NULL != hwndFocus)
  309. {
  310. if (hwndFocus == hwnd)
  311. {
  312. return(TRUE);
  313. }
  314. HWND hwndParent = GetParent(hwndFocus);
  315. if (NULL == hwndParent)
  316. {
  317. hwndFocus = GetWindow(hwndFocus, GW_OWNER);
  318. }
  319. else
  320. {
  321. hwndFocus = hwndParent;
  322. }
  323. }
  324. return(FALSE);
  325. }
  326. class CDialogTranslate : public CTranslateAccel
  327. {
  328. public:
  329. CDialogTranslate(HWND hwnd) : CTranslateAccel(hwnd) {}
  330. HRESULT TranslateAccelerator(
  331. LPMSG pMsg , //Pointer to the structure
  332. DWORD grfModifiers //Flags describing the state of the keys
  333. )
  334. {
  335. HWND hwnd = GetWindow();
  336. return(::IsDialogMessage(hwnd, pMsg) ? S_OK : S_FALSE);
  337. }
  338. } ;
  339. VOID AddTranslateAccelerator(ITranslateAccelerator* pTrans)
  340. {
  341. EnterCriticalSection(&dialogListCriticalSection);
  342. if (g_pDialogList->Add(pTrans))
  343. {
  344. pTrans->AddRef();
  345. }
  346. LeaveCriticalSection(&dialogListCriticalSection);
  347. }
  348. VOID RemoveTranslateAccelerator(ITranslateAccelerator* pTrans)
  349. {
  350. EnterCriticalSection(&dialogListCriticalSection);
  351. if (g_pDialogList->Remove(pTrans))
  352. {
  353. pTrans->Release();
  354. }
  355. LeaveCriticalSection(&dialogListCriticalSection);
  356. }
  357. /* A D D M O D E L E S S D L G */
  358. /*-------------------------------------------------------------------------
  359. %%Function: AddModelessDlg
  360. Add the hwnd to the global dialog list
  361. -------------------------------------------------------------------------*/
  362. VOID AddModelessDlg(HWND hwnd)
  363. {
  364. ASSERT(NULL != g_pDialogList);
  365. CDialogTranslate *pDlgTrans = new CDialogTranslate(hwnd);
  366. if (NULL != pDlgTrans)
  367. {
  368. AddTranslateAccelerator(pDlgTrans);
  369. pDlgTrans->Release();
  370. }
  371. }
  372. /* R E M O V E M O D E L E S S D L G */
  373. /*-------------------------------------------------------------------------
  374. %%Function: RemoveModelessDlg
  375. Remove the hwnd from the global dialog list
  376. -------------------------------------------------------------------------*/
  377. VOID RemoveModelessDlg(HWND hwnd)
  378. {
  379. ASSERT(g_pDialogList);
  380. EnterCriticalSection(&dialogListCriticalSection);
  381. for (int i=g_pDialogList->GetSize()-1; i>=0; --i)
  382. {
  383. ITranslateAccelerator *pTrans = (*g_pDialogList)[i];
  384. ASSERT(NULL != pTrans);
  385. HWND hwndTemp = NULL;
  386. if (S_OK == pTrans->GetWindow(&hwndTemp) && hwndTemp == hwnd)
  387. {
  388. RemoveTranslateAccelerator(pTrans);
  389. break;
  390. }
  391. }
  392. LeaveCriticalSection(&dialogListCriticalSection);
  393. }
  394. /* K I L L S C R N S A V E R */
  395. /*-------------------------------------------------------------------------
  396. %%Function: KillScrnSaver
  397. Remove the screen saver if it is active
  398. -------------------------------------------------------------------------*/
  399. VOID KillScrnSaver(void)
  400. {
  401. if (!IsWindowsNT())
  402. return;
  403. POINT pos;
  404. ::GetCursorPos(&pos);
  405. ::SetCursorPos(0,0);
  406. ::SetCursorPos(pos.x,pos.y);
  407. }
  408. /* D X P S Z */
  409. /*-------------------------------------------------------------------------
  410. %%Function: DxpSz
  411. Get the width of the string in pixels.
  412. -------------------------------------------------------------------------*/
  413. int DxpSz(LPCTSTR pcsz)
  414. {
  415. HWND hwndDesktop = GetDesktopWindow();
  416. if (NULL == hwndDesktop)
  417. return 0;
  418. HDC hdc = GetDC(hwndDesktop);
  419. if (NULL == hdc)
  420. return 0;
  421. HFONT hFontOld = (HFONT) SelectObject(hdc, g_hfontDlg);
  422. SIZE size;
  423. int dxp = ::GetTextExtentPoint32(hdc, pcsz, lstrlen(pcsz), &size)
  424. ? size.cx : 0;
  425. ::SelectObject(hdc, hFontOld);
  426. ::ReleaseDC(hwndDesktop, hdc);
  427. return dxp;
  428. }
  429. /* F A N S I S Z */
  430. /*-------------------------------------------------------------------------
  431. %%Function: FAnsiSz
  432. Return TRUE if the string contains no DBCS characters.
  433. -------------------------------------------------------------------------*/
  434. BOOL FAnsiSz(LPCTSTR psz)
  435. {
  436. if (NULL != psz)
  437. {
  438. char ch;
  439. while (_T('\0') != (ch = *psz++))
  440. {
  441. if (IsDBCSLeadByte(ch))
  442. {
  443. return FALSE;
  444. }
  445. }
  446. }
  447. return TRUE;
  448. }
  449. /////////////////////////////////////////////////////////////////////////////
  450. int g_cBusyOperations = 0;
  451. VOID DecrementBusyOperations(void)
  452. {
  453. g_cBusyOperations--;
  454. POINT pt;
  455. // Wiggle the mouse - force user to send a WM_SETCURSOR
  456. if (::GetCursorPos(&pt))
  457. ::SetCursorPos(pt.x, pt.y);
  458. }
  459. VOID IncrementBusyOperations(void)
  460. {
  461. g_cBusyOperations++;
  462. POINT pt;
  463. // Wiggle the mouse - force user to send a WM_SETCURSOR
  464. if (::GetCursorPos(&pt))
  465. ::SetCursorPos(pt.x, pt.y);
  466. }
  467. /////////////////////////////////////////////////////////////////////////////
  468. // String Utilities
  469. /* P S Z A L L O C */
  470. /*-------------------------------------------------------------------------
  471. %%Function: PszAlloc
  472. -------------------------------------------------------------------------*/
  473. LPTSTR PszAlloc(LPCTSTR pszSrc)
  474. {
  475. if (NULL == pszSrc)
  476. return NULL;
  477. LPTSTR pszDest = new TCHAR[lstrlen(pszSrc) + 1];
  478. if (NULL != pszDest)
  479. {
  480. lstrcpy(pszDest, pszSrc);
  481. }
  482. return pszDest;
  483. }
  484. VOID FreePsz(LPTSTR psz)
  485. {
  486. delete [] psz;
  487. }
  488. /* L P T S T R _ T O _ B S T R */
  489. /*-------------------------------------------------------------------------
  490. %%Function: LPTSTR_to_BSTR
  491. -------------------------------------------------------------------------*/
  492. HRESULT LPTSTR_to_BSTR(BSTR *pbstr, LPCTSTR psz)
  493. {
  494. ASSERT(NULL != pbstr);
  495. if (NULL == psz)
  496. {
  497. psz = TEXT(""); // convert NULL strings to empty strings
  498. }
  499. #ifndef UNICODE
  500. // compute the length of the required BSTR
  501. int cch = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
  502. if (cch <= 0)
  503. return E_FAIL;
  504. // allocate the widestr, +1 for terminating null
  505. BSTR bstr = SysAllocStringLen(NULL, cch-1); // SysAllocStringLen adds 1
  506. if (bstr == NULL)
  507. return E_OUTOFMEMORY;
  508. MultiByteToWideChar(CP_ACP, 0, psz, -1, (LPWSTR)bstr, cch);
  509. ((LPWSTR)bstr)[cch - 1] = 0;
  510. #else
  511. BSTR bstr = SysAllocString(psz);
  512. if (bstr == NULL)
  513. return E_OUTOFMEMORY;
  514. #endif // UNICODE
  515. *pbstr = bstr;
  516. return S_OK;
  517. }
  518. /* B S T R _ T O _ L P T S T R */
  519. /*-------------------------------------------------------------------------
  520. %%Function: BSTR_to_LPTSTR
  521. -------------------------------------------------------------------------*/
  522. HRESULT BSTR_to_LPTSTR(LPTSTR *ppsz, BSTR bstr)
  523. {
  524. #ifndef UNICODE
  525. // compute the length of the required BSTR
  526. int cch = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)bstr, -1, NULL, 0, NULL, NULL);
  527. if (cch <= 0)
  528. return E_FAIL;
  529. // cch is the number of BYTES required, including the null terminator
  530. *ppsz = (LPTSTR) new char[cch];
  531. if (*ppsz == NULL)
  532. return E_OUTOFMEMORY;
  533. WideCharToMultiByte(CP_ACP, 0, (LPWSTR)bstr, -1, *ppsz, cch, NULL, NULL);
  534. return S_OK;
  535. #else
  536. return E_NOTIMPL;
  537. #endif // UNICODE
  538. }
  539. /* P S Z F R O M B S T R */
  540. /*-------------------------------------------------------------------------
  541. %%Function: PszFromBstr
  542. -------------------------------------------------------------------------*/
  543. LPTSTR PszFromBstr(PCWSTR pwStr)
  544. {
  545. #ifdef UNICODE
  546. return PszAlloc(pwStr)
  547. #else
  548. int cch = WideCharToMultiByte(CP_ACP, 0, pwStr, -1, NULL, 0, NULL, NULL);
  549. if (cch <= 0)
  550. return NULL;
  551. // cch is the number of BYTES required, including the null terminator
  552. LPTSTR psz = new char[cch];
  553. if (NULL != psz)
  554. {
  555. WideCharToMultiByte(CP_ACP, 0, pwStr, -1, psz, cch, NULL, NULL);
  556. }
  557. return psz;
  558. #endif /* UNICODE */
  559. }
  560. /////////////////////////////////////////////////////////////////////////////
  561. // Connection Point Helpers
  562. HRESULT NmAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  563. {
  564. IConnectionPointContainer *pCPC;
  565. IConnectionPoint *pCP;
  566. HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  567. if (SUCCEEDED(hRes))
  568. {
  569. hRes = pCPC->FindConnectionPoint(iid, &pCP);
  570. pCPC->Release();
  571. }
  572. if (SUCCEEDED(hRes))
  573. {
  574. hRes = pCP->Advise(pUnk, pdw);
  575. pCP->Release();
  576. }
  577. return hRes;
  578. }
  579. HRESULT NmUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw)
  580. {
  581. IConnectionPointContainer *pCPC;
  582. IConnectionPoint *pCP;
  583. HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  584. if (SUCCEEDED(hRes))
  585. {
  586. hRes = pCPC->FindConnectionPoint(iid, &pCP);
  587. pCPC->Release();
  588. }
  589. if (SUCCEEDED(hRes))
  590. {
  591. hRes = pCP->Unadvise(dw);
  592. pCP->Release();
  593. }
  594. return hRes;
  595. }
  596. extern INmSysInfo2 * g_pNmSysInfo;
  597. ////////////////////////////////////////////////////////////////////////////
  598. // Call into the certificate generation module to generate
  599. // a certificate matching the ULS info for secure calling:
  600. DWORD MakeCertWrap
  601. (
  602. LPCSTR szFirstName,
  603. LPCSTR szLastName,
  604. LPCSTR szEmailName,
  605. DWORD dwFlags
  606. )
  607. {
  608. HMODULE hMakeCertLib = LoadLibrary(SZ_NMMKCERTLIB);
  609. DWORD dwRet = -1;
  610. if ( NULL != hMakeCertLib ) {
  611. PFN_NMMAKECERT pfn_MakeCert =
  612. (PFN_NMMAKECERT)GetProcAddress ( hMakeCertLib,
  613. SZ_NMMAKECERTFUNC );
  614. if ( NULL != pfn_MakeCert ) {
  615. dwRet = pfn_MakeCert( szFirstName,
  616. szLastName,
  617. szEmailName,
  618. NULL,
  619. NULL,
  620. dwFlags );
  621. RefreshSelfIssuedCert();
  622. }
  623. else
  624. {
  625. ERROR_OUT(("GetProcAddress(%s) failed: %x",
  626. SZ_NMMAKECERTFUNC, GetLastError()));
  627. }
  628. FreeLibrary ( hMakeCertLib );
  629. }
  630. else
  631. {
  632. ERROR_OUT(("LoadLibrary(%s) failed: %x", SZ_NMMKCERTLIB,
  633. GetLastError()));
  634. }
  635. return(dwRet);
  636. }
  637. ///////////////////////////////////////////////////////////////////////////
  638. // Icon Utilities
  639. HIMAGELIST g_himlIconSmall = NULL;
  640. VOID LoadIconImages(void)
  641. {
  642. ASSERT(NULL == g_himlIconSmall);
  643. g_himlIconSmall = ImageList_Create(DXP_ICON_SMALL, DYP_ICON_SMALL, ILC_MASK, 1, 0);
  644. if (NULL != g_himlIconSmall)
  645. {
  646. HBITMAP hBmp = ::LoadBitmap(::GetInstanceHandle(), MAKEINTRESOURCE(IDB_ICON_IMAGES));
  647. if (NULL != hBmp)
  648. {
  649. ImageList_AddMasked(g_himlIconSmall, hBmp, TOOLBAR_MASK_COLOR);
  650. ::DeleteObject(hBmp);
  651. }
  652. }
  653. }
  654. VOID FreeIconImages(void)
  655. {
  656. if (NULL != g_himlIconSmall)
  657. {
  658. ImageList_Destroy(g_himlIconSmall);
  659. g_himlIconSmall = NULL;
  660. }
  661. }
  662. VOID DrawIconSmall(HDC hdc, int iIcon, int x, int y)
  663. {
  664. ImageList_DrawEx(g_himlIconSmall, iIcon, hdc,
  665. x, y, DXP_ICON_SMALL, DYP_ICON_SMALL,
  666. CLR_DEFAULT, CLR_DEFAULT, ILD_NORMAL);
  667. }
  668. // Get the default dialog (GUI) font for international
  669. HFONT GetDefaultFont(void)
  670. {
  671. if (NULL == g_hfontDlg)
  672. {
  673. g_hfontDlg = (HFONT) ::GetStockObject(DEFAULT_GUI_FONT);
  674. }
  675. return g_hfontDlg;
  676. }
  677. /* F E M P T Y D L G I T E M */
  678. /*-------------------------------------------------------------------------
  679. %%Function: FEmptyDlgItem
  680. Return TRUE if the dialog control is empty
  681. -------------------------------------------------------------------------*/
  682. BOOL FEmptyDlgItem(HWND hdlg, UINT id)
  683. {
  684. TCHAR sz[MAX_PATH];
  685. return (0 == GetDlgItemTextTrimmed(hdlg, id, sz, CCHMAX(sz)) );
  686. }
  687. /* T R I M D L G I T E M T E X T */
  688. /*-------------------------------------------------------------------------
  689. %%Function: TrimDlgItemText
  690. Trim the text in the edit control and return the length of the string.
  691. -------------------------------------------------------------------------*/
  692. UINT TrimDlgItemText(HWND hdlg, UINT id)
  693. {
  694. TCHAR sz[MAX_PATH];
  695. GetDlgItemTextTrimmed(hdlg, id, sz, CCHMAX(sz));
  696. SetDlgItemText(hdlg, id, sz);
  697. return lstrlen(sz);
  698. }
  699. /* G E T D L G I T E M T E X T T R I M M E D */
  700. /*-------------------------------------------------------------------------
  701. %%Function: GetDlgItemTextTrimmed
  702. -------------------------------------------------------------------------*/
  703. UINT GetDlgItemTextTrimmed(HWND hdlg, int id, PTCHAR psz, int cchMax)
  704. {
  705. UINT cch = GetDlgItemText(hdlg, id, psz, cchMax);
  706. if (0 != cch)
  707. {
  708. cch = TrimSz(psz);
  709. }
  710. return cch;
  711. }
  712. /* F M T D A T E T I M E */
  713. /*-------------------------------------------------------------------------
  714. %%Function: FmtDateTime
  715. Formats the system time using the current setting (MM/DD/YY HH:MM xm)
  716. -------------------------------------------------------------------------*/
  717. int FmtDateTime(LPSYSTEMTIME pst, LPTSTR pszDateTime, int cchMax)
  718. {
  719. pszDateTime[0] = _T('\0');
  720. int cch = ::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE,
  721. pst, NULL, pszDateTime, cchMax);
  722. if ((0 != cch) && ((cchMax - cch) > 0))
  723. {
  724. // Tack on a space and then the time.
  725. // GetDateFormat returns count of chars
  726. // INCLUDING the NULL terminator, hence the - 1
  727. LPTSTR pszTime = pszDateTime + (cch - 1);
  728. pszTime[0] = _T(' ');
  729. pszTime[1] = _T('\0');
  730. cch = ::GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS,
  731. pst, NULL, &(pszTime[1]), (cchMax - cch));
  732. }
  733. return (cch == 0 ? 0 : lstrlen(pszDateTime));
  734. }
  735. /* C O M B I N E N A M E S */
  736. /*-------------------------------------------------------------------------
  737. %%Function: CombineNames
  738. Combine the two names into one string.
  739. The result is a "First Last" (or Intl'd "Last First") string
  740. -------------------------------------------------------------------------*/
  741. VOID CombineNames(LPTSTR pszResult, int cchResult, LPCTSTR pcszFirst, LPCTSTR pcszLast)
  742. {
  743. ASSERT(pszResult);
  744. TCHAR szFmt[32]; // A small value: String is "%1 %2" or "%2 %1"
  745. TCHAR sz[1024]; // The result (before truncating to cchResult chars)
  746. LPCTSTR argw[2];
  747. argw[0] = pcszFirst;
  748. argw[1] = pcszLast;
  749. *pszResult = _T('\0');
  750. if (FLoadString(IDS_NAME_ORDER, szFmt, CCHMAX(szFmt)))
  751. {
  752. if (0 != FormatMessage(FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING,
  753. szFmt, 0, 0, sz, CCHMAX(sz), (va_list *)argw ))
  754. {
  755. lstrcpyn(pszResult, sz, cchResult);
  756. #ifndef _UNICODE
  757. // (see bug 3907 )
  758. // lstrcpyn() can clip a DBCS character in half at the end of the string
  759. // we need to walk the string with ::CharNext() and replace the last byte
  760. // with a NULL if the last byte is half of a DBCS char.
  761. PTSTR pszSource = sz;
  762. while (*pszSource && (pszSource - sz < cchResult))
  763. {
  764. PTSTR pszPrev = pszSource;
  765. pszSource = ::CharNext(pszPrev);
  766. // If we've reached the first character that didn't get copied into
  767. // the destination buffer, and the previous character was a double
  768. // byte character...
  769. if (((pszSource - sz) == cchResult) && ::IsDBCSLeadByte(*pszPrev))
  770. {
  771. // Replace the destination buffer's last character with '\0'
  772. // NOTE: pszResult[cchResult - 1] is '\0' thanks to lstrcpyn()
  773. pszResult[cchResult - 2] = _T('\0');
  774. break;
  775. }
  776. }
  777. #endif // ! _UNICODE
  778. }
  779. }
  780. }
  781. BOOL NMGetSpecialFolderPath(
  782. HWND hwndOwner,
  783. LPTSTR lpszPath,
  784. int nFolder,
  785. BOOL fCreate)
  786. {
  787. LPITEMIDLIST pidl = NULL;
  788. BOOL fRet = FALSE;
  789. if (NOERROR == SHGetSpecialFolderLocation(NULL, nFolder, &pidl))
  790. {
  791. ASSERT(NULL != pidl);
  792. if (SHGetPathFromIDList(pidl, lpszPath))
  793. {
  794. lstrcat(lpszPath, _TEXT("\\"));
  795. fRet = TRUE;
  796. }
  797. LPMALLOC lpMalloc;
  798. if (!SHGetMalloc(&lpMalloc))
  799. {
  800. ASSERT(NULL != lpMalloc);
  801. lpMalloc->Free(pidl);
  802. lpMalloc->Release();
  803. }
  804. }
  805. return fRet;
  806. }
  807. //--------------------------------------------------------------------------//
  808. // CDirectoryManager static data members. //
  809. //--------------------------------------------------------------------------//
  810. bool CDirectoryManager::m_webEnabled = true;
  811. TCHAR CDirectoryManager::m_ils[ MAX_PATH ] = TEXT( "" );
  812. TCHAR CDirectoryManager::m_displayName[ MAX_PATH ] = TEXT( "" );
  813. TCHAR CDirectoryManager::m_displayNameDefault[ MAX_PATH ] = TEXT( "Microsoft Internet Directory" );
  814. TCHAR CDirectoryManager::m_defaultServer[ MAX_PATH ] = TEXT( "" );
  815. TCHAR CDirectoryManager::m_DomainDirectory[ MAX_PATH ] = TEXT( "" );
  816. //--------------------------------------------------------------------------//
  817. // CDirectoryManager::get_defaultServer. //
  818. //--------------------------------------------------------------------------//
  819. const TCHAR * const
  820. CDirectoryManager::get_defaultServer(void)
  821. {
  822. if( m_defaultServer[ 0 ] == '\0' )
  823. {
  824. // defaultServer not yet loaded...
  825. RegEntry re( ISAPI_CLIENT_KEY, HKEY_CURRENT_USER );
  826. lstrcpyn( m_defaultServer, re.GetString( REGVAL_SERVERNAME ), CCHMAX( m_defaultServer ) );
  827. if( (m_defaultServer[ 0 ] == '\0') && (get_DomainDirectory() != NULL) )
  828. {
  829. // When no default ils server has been saved in the registry we first try to default it to the
  830. // server configured for the domain if any...
  831. lstrcpy( m_defaultServer, m_DomainDirectory );
  832. }
  833. if( (m_defaultServer[ 0 ] == '\0') && isWebDirectoryEnabled() )
  834. {
  835. // When no default ils server has been saved in the registry we default it to m_ils...
  836. lstrcpy( m_defaultServer, get_webDirectoryIls() );
  837. }
  838. }
  839. return( m_defaultServer );
  840. } // End of CDirectoryManager::get_defaultServer.
  841. //--------------------------------------------------------------------------//
  842. // CDirectoryManager::set_defaultServer. //
  843. //--------------------------------------------------------------------------//
  844. void
  845. CDirectoryManager::set_defaultServer
  846. (
  847. const TCHAR * const serverName
  848. ){
  849. RegEntry ulsKey( ISAPI_CLIENT_KEY, HKEY_CURRENT_USER );
  850. ulsKey.SetValue( REGVAL_SERVERNAME, serverName );
  851. lstrcpy( m_defaultServer, serverName );
  852. } // End of CDirectoryManager::set_defaultServer.
  853. //--------------------------------------------------------------------------//
  854. // CDirectoryManager::isWebDirectory. //
  855. //--------------------------------------------------------------------------//
  856. bool
  857. CDirectoryManager::isWebDirectory
  858. (
  859. const TCHAR * const directory
  860. ){
  861. TCHAR buffer[ MAX_PATH ];
  862. // If directory is null then the question is "is the default server the web directory?"
  863. return( isWebDirectoryEnabled() && (lstrcmpi( (directory != NULL)? get_dnsName( directory ): get_defaultServer(), get_webDirectoryIls() ) == 0) );
  864. } // End of CDirectoryManager::isWebDirectory.
  865. //--------------------------------------------------------------------------//
  866. // CDirectoryManager::get_dnsName. //
  867. //--------------------------------------------------------------------------//
  868. const TCHAR * const
  869. CDirectoryManager::get_dnsName
  870. (
  871. const TCHAR * const name
  872. ){
  873. // Check to see if the specified name matches m_displayName...
  874. return( (isWebDirectoryEnabled() && (lstrcmpi( name, loadDisplayName() ) == 0))? get_webDirectoryIls() : name );
  875. } // End of CDirectoryManager::get_dnsName.
  876. //--------------------------------------------------------------------------//
  877. // CDirectoryManager::get_displayName. //
  878. //--------------------------------------------------------------------------//
  879. const TCHAR * const
  880. CDirectoryManager::get_displayName
  881. (
  882. const TCHAR * const name
  883. ){
  884. // Check to see if the specified name matches m_ils...
  885. return( (isWebDirectoryEnabled() && (lstrcmpi( name, get_webDirectoryIls() ) == 0))? loadDisplayName(): name );
  886. } // End of CDirectoryManager::get_displayName.
  887. //--------------------------------------------------------------------------//
  888. // CDirectoryManager::loadDisplayName. //
  889. //--------------------------------------------------------------------------//
  890. const TCHAR * const
  891. CDirectoryManager::loadDisplayName(void)
  892. {
  893. using namespace ConfPolicies;
  894. if( m_displayName[ 0 ] == '\0' )
  895. {
  896. GetWebDirInfo( NULL, 0,
  897. NULL, 0,
  898. m_displayName, ARRAY_ELEMENTS(m_displayName) );
  899. if ( '\0' == m_displayName[0] )
  900. {
  901. lstrcpy( m_displayName, RES2T( IDS_MS_INTERNET_DIRECTORY ) );
  902. if( m_displayName[ 0 ] == '\0' )
  903. {
  904. // Loading m_displayName from the resources failed... default to m_displayNameDefault...
  905. lstrcpy( m_displayName, m_displayNameDefault );
  906. }
  907. }
  908. }
  909. return( m_displayName );
  910. } // End of CDirectoryManager::loadDisplayName.
  911. //--------------------------------------------------------------------------//
  912. // CDirectoryManager::get_webDirectoryUrl. //
  913. //--------------------------------------------------------------------------//
  914. void
  915. CDirectoryManager::get_webDirectoryUrl(LPTSTR szWebDir, int cchmax)
  916. {
  917. using namespace ConfPolicies;
  918. if ( !isWebDirectoryEnabled() )
  919. {
  920. szWebDir[0] = '\0';
  921. return;
  922. }
  923. GetWebDirInfo( szWebDir, cchmax );
  924. if ( '\0' != szWebDir[0] )
  925. {
  926. // All done
  927. return;
  928. }
  929. void FormatURL(LPTSTR szURL);
  930. lstrcpyn(szWebDir, RES2T(IDS_WEB_PAGE_FORMAT_WEBVIEW), cchmax);
  931. FormatURL(szWebDir);
  932. } // End of CDirectoryManager::get_webDirectoryUrl.
  933. //--------------------------------------------------------------------------//
  934. // CDirectoryManager::get_webDirectoryIls. //
  935. //--------------------------------------------------------------------------//
  936. const TCHAR * const
  937. CDirectoryManager::get_webDirectoryIls(void)
  938. {
  939. using namespace ConfPolicies;
  940. if (!isWebDirectoryEnabled())
  941. {
  942. return(TEXT(""));
  943. }
  944. if ('\0' == m_ils[0])
  945. {
  946. GetWebDirInfo( NULL, 0,
  947. m_ils, ARRAY_ELEMENTS(m_ils) );
  948. if ('\0' == m_ils[0])
  949. {
  950. lstrcpy(m_ils, TEXT("logon.netmeeting.microsoft.com"));
  951. }
  952. }
  953. return(m_ils);
  954. } // End of CDirectoryManager::get_webDirectoryIls.
  955. //--------------------------------------------------------------------------//
  956. // CDirectoryManager::isWebDirectoryEnabled. //
  957. //--------------------------------------------------------------------------//
  958. bool
  959. CDirectoryManager::isWebDirectoryEnabled(void)
  960. {
  961. static bool policyChecked = false;
  962. if( !policyChecked )
  963. {
  964. policyChecked = true;
  965. m_webEnabled = !ConfPolicies::isWebDirectoryDisabled();
  966. }
  967. return( m_webEnabled );
  968. } // End of CDirectoryManager::isWebDirectoryEnabled.
  969. //--------------------------------------------------------------------------//
  970. // CDirectoryManager::get_DomainDirectory. //
  971. //--------------------------------------------------------------------------//
  972. const TCHAR * const
  973. CDirectoryManager::get_DomainDirectory(void)
  974. {
  975. static bool bAccessAttempted = false; // only read this info once... if it fails once assume it's not available and don't retry until restarted...
  976. if( (!bAccessAttempted) && m_DomainDirectory[ 0 ] == '\0' )
  977. {
  978. bAccessAttempted = true;
  979. // Try to obtain the configured directory for this domain...
  980. ITRendezvous * pRendezvous;
  981. HRESULT hrResult;
  982. hrResult = ::CoCreateInstance( CLSID_Rendezvous, NULL, CLSCTX_ALL, IID_ITRendezvous, (void **) &pRendezvous );
  983. if( (hrResult == S_OK) && (pRendezvous != NULL) )
  984. {
  985. IEnumDirectory * pEnumDirectory;
  986. hrResult = pRendezvous->EnumerateDefaultDirectories( &pEnumDirectory );
  987. if( (hrResult == S_OK) && (pEnumDirectory != NULL) )
  988. {
  989. ITDirectory * pDirectory;
  990. bool bFoundILS = false;
  991. do
  992. {
  993. hrResult = pEnumDirectory->Next( 1, &pDirectory, NULL );
  994. if( (hrResult == S_OK) && (pDirectory != NULL) )
  995. {
  996. LPWSTR * ppServers;
  997. DIRECTORY_TYPE type;
  998. if( pDirectory->get_DirectoryType( &type ) == S_OK )
  999. {
  1000. if( type == DT_ILS ) // Found an ILS server configured on the DS... retrieve the name and port...
  1001. {
  1002. bFoundILS = true;
  1003. BSTR pName;
  1004. if( pDirectory->get_DisplayName( &pName ) == S_OK )
  1005. {
  1006. USES_CONVERSION;
  1007. lstrcpy( m_DomainDirectory, OLE2T( pName ) );
  1008. SysFreeString( pName );
  1009. }
  1010. ITILSConfig * pITILSConfig;
  1011. hrResult = pDirectory->QueryInterface( IID_ITILSConfig, (void **) &pITILSConfig );
  1012. if( (hrResult == S_OK) && (pITILSConfig != NULL) )
  1013. {
  1014. long lPort;
  1015. if( pITILSConfig->get_Port( &lPort ) == S_OK )
  1016. {
  1017. TCHAR pszPort[ 32 ];
  1018. wsprintf( pszPort, TEXT( ":%d" ), lPort );
  1019. lstrcat( m_DomainDirectory, pszPort );
  1020. }
  1021. pITILSConfig->Release();
  1022. }
  1023. }
  1024. }
  1025. pDirectory->Release();
  1026. }
  1027. }
  1028. while( (!bFoundILS) && (hrResult == S_OK) && (pDirectory != NULL) );
  1029. pEnumDirectory->Release();
  1030. }
  1031. pRendezvous->Release();
  1032. }
  1033. }
  1034. return( (m_DomainDirectory[ 0 ] != '\0')? m_DomainDirectory: NULL );
  1035. } // End of CDirectoryManager::get_DomainDirectory.
  1036. // Returns non-empty strings if there is a web dir set by policy
  1037. bool ConfPolicies::GetWebDirInfo(
  1038. LPTSTR szURL, int cchmaxURL,
  1039. LPTSTR szServer, int cchmaxServer,
  1040. LPTSTR szName, int cchmaxName
  1041. )
  1042. {
  1043. // if the string params are messed up, just return false
  1044. ASSERT( (!szURL || ( cchmaxURL > 0 ))
  1045. && (!szServer || ( cchmaxServer > 0 ))
  1046. && (!szName || ( cchmaxName > 0 ))
  1047. );
  1048. bool bSuccess = false;
  1049. // Try to get the registry value
  1050. RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
  1051. LPCTSTR szTemp;
  1052. szTemp = rePol.GetString( REGVAL_POL_INTRANET_WEBDIR_URL );
  1053. if( szTemp[0] )
  1054. {
  1055. if (NULL != szURL)
  1056. {
  1057. lstrcpyn( szURL, szTemp, cchmaxURL );
  1058. }
  1059. szTemp = rePol.GetString( REGVAL_POL_INTRANET_WEBDIR_SERVER );
  1060. if (szTemp[0])
  1061. {
  1062. if (NULL != szServer)
  1063. {
  1064. lstrcpyn( szServer, szTemp, cchmaxServer );
  1065. }
  1066. szTemp = rePol.GetString( REGVAL_POL_INTRANET_WEBDIR_NAME );
  1067. if( szTemp[0] )
  1068. {
  1069. if (NULL != szName)
  1070. {
  1071. lstrcpyn( szName, szTemp, cchmaxName );
  1072. }
  1073. // All three values must be specified for success
  1074. bSuccess = true;
  1075. }
  1076. }
  1077. }
  1078. if (!bSuccess)
  1079. {
  1080. // Empty the strings
  1081. if (NULL != szURL ) szURL [0] = '\0';
  1082. if (NULL != szServer) szServer[0] = '\0';
  1083. if (NULL != szName ) szName [0] = '\0';
  1084. }
  1085. return(bSuccess);
  1086. }
  1087. bool g_bAutoAccept = false;
  1088. bool ConfPolicies::IsAutoAcceptCallsOptionEnabled(void)
  1089. {
  1090. RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
  1091. return !rePol.GetNumber( REGVAL_POL_NO_AUTOACCEPTCALLS, DEFAULT_POL_NO_AUTOACCEPTCALLS );
  1092. }
  1093. bool ConfPolicies::IsAutoAcceptCallsPersisted(void)
  1094. {
  1095. RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
  1096. return 0 != rePol.GetNumber( REGVAL_POL_PERSIST_AUTOACCEPTCALLS, DEFAULT_POL_PERSIST_AUTOACCEPTCALLS );
  1097. }
  1098. bool ConfPolicies::IsAutoAcceptCallsEnabled(void)
  1099. {
  1100. bool bRet = false;
  1101. if( IsAutoAcceptCallsOptionEnabled() )
  1102. {
  1103. bRet = g_bAutoAccept;
  1104. if (IsAutoAcceptCallsPersisted())
  1105. {
  1106. // AutoAccept calls is _not_ disabled by the policy... we should check the AUTO_ACCEPT regval
  1107. RegEntry reConf(CONFERENCING_KEY, HKEY_CURRENT_USER);
  1108. if(reConf.GetNumber(REGVAL_AUTO_ACCEPT, g_bAutoAccept) )
  1109. {
  1110. bRet = true;
  1111. }
  1112. }
  1113. }
  1114. return bRet;
  1115. }
  1116. void ConfPolicies::SetAutoAcceptCallsEnabled(bool bAutoAccept)
  1117. {
  1118. g_bAutoAccept = bAutoAccept;
  1119. RegEntry reConf(CONFERENCING_KEY, HKEY_CURRENT_USER);
  1120. reConf.SetValue(REGVAL_AUTO_ACCEPT, g_bAutoAccept);
  1121. }