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.

1378 lines
35 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. if(FAILED(SHGetSpecialFolderLocation(HWND_DESKTOP, CSIDL_DRIVES, &pidlRoot)))
  262. {
  263. return FALSE;
  264. }
  265. BROWSEINFO bi;
  266. ClearStruct(&bi);
  267. bi.hwndOwner = hwndParent;
  268. bi.lpszTitle = pszTitle;
  269. bi.ulFlags = BIF_RETURNONLYFSDIRS;
  270. bi.pidlRoot = pidlRoot;
  271. LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
  272. BOOL fRet = (pidl != NULL);
  273. if (fRet)
  274. {
  275. ASSERT(cchMax >= MAX_PATH);
  276. SHGetPathFromIDList(pidl, pszFolder);
  277. ASSERT(lstrlen(pszFolder) < (int) cchMax);
  278. }
  279. // Get the shell's allocator to free PIDLs
  280. LPMALLOC lpMalloc;
  281. if (SUCCEEDED(SHGetMalloc(&lpMalloc)) && (NULL != lpMalloc))
  282. {
  283. if (NULL != pidlRoot)
  284. {
  285. lpMalloc->Free(pidlRoot);
  286. }
  287. if (pidl)
  288. {
  289. lpMalloc->Free(pidl);
  290. }
  291. lpMalloc->Release();
  292. }
  293. return fRet;
  294. }
  295. /* D I S A B L E C O N T R O L */
  296. /*-------------------------------------------------------------------------
  297. %%Function: DisableControl
  298. -------------------------------------------------------------------------*/
  299. VOID DisableControl(HWND hdlg, int id)
  300. {
  301. if ((NULL != hdlg) && (0 != id))
  302. {
  303. HWND hwndCtrl = GetDlgItem(hdlg, id);
  304. ASSERT(NULL != hwndCtrl);
  305. EnableWindow(hwndCtrl, FALSE);
  306. }
  307. }
  308. class CDialogTranslate : public CTranslateAccel
  309. {
  310. public:
  311. CDialogTranslate(HWND hwnd) : CTranslateAccel(hwnd) {}
  312. HRESULT TranslateAccelerator(
  313. LPMSG pMsg , //Pointer to the structure
  314. DWORD grfModifiers //Flags describing the state of the keys
  315. )
  316. {
  317. HWND hwnd = GetWindow();
  318. return(::IsDialogMessage(hwnd, pMsg) ? S_OK : S_FALSE);
  319. }
  320. } ;
  321. VOID AddTranslateAccelerator(ITranslateAccelerator* pTrans)
  322. {
  323. EnterCriticalSection(&dialogListCriticalSection);
  324. if (g_pDialogList->Add(pTrans))
  325. {
  326. pTrans->AddRef();
  327. }
  328. LeaveCriticalSection(&dialogListCriticalSection);
  329. }
  330. VOID RemoveTranslateAccelerator(ITranslateAccelerator* pTrans)
  331. {
  332. EnterCriticalSection(&dialogListCriticalSection);
  333. if (g_pDialogList->Remove(pTrans))
  334. {
  335. pTrans->Release();
  336. }
  337. LeaveCriticalSection(&dialogListCriticalSection);
  338. }
  339. /* A D D M O D E L E S S D L G */
  340. /*-------------------------------------------------------------------------
  341. %%Function: AddModelessDlg
  342. Add the hwnd to the global dialog list
  343. -------------------------------------------------------------------------*/
  344. VOID AddModelessDlg(HWND hwnd)
  345. {
  346. ASSERT(NULL != g_pDialogList);
  347. CDialogTranslate *pDlgTrans = new CDialogTranslate(hwnd);
  348. if (NULL != pDlgTrans)
  349. {
  350. AddTranslateAccelerator(pDlgTrans);
  351. pDlgTrans->Release();
  352. }
  353. }
  354. /* R E M O V E M O D E L E S S D L G */
  355. /*-------------------------------------------------------------------------
  356. %%Function: RemoveModelessDlg
  357. Remove the hwnd from the global dialog list
  358. -------------------------------------------------------------------------*/
  359. VOID RemoveModelessDlg(HWND hwnd)
  360. {
  361. ASSERT(g_pDialogList);
  362. EnterCriticalSection(&dialogListCriticalSection);
  363. for (int i=g_pDialogList->GetSize()-1; i>=0; --i)
  364. {
  365. ITranslateAccelerator *pTrans = (*g_pDialogList)[i];
  366. ASSERT(NULL != pTrans);
  367. HWND hwndTemp = NULL;
  368. if (S_OK == pTrans->GetWindow(&hwndTemp) && hwndTemp == hwnd)
  369. {
  370. RemoveTranslateAccelerator(pTrans);
  371. break;
  372. }
  373. }
  374. LeaveCriticalSection(&dialogListCriticalSection);
  375. }
  376. /* K I L L S C R N S A V E R */
  377. /*-------------------------------------------------------------------------
  378. %%Function: KillScrnSaver
  379. Remove the screen saver if it is active
  380. -------------------------------------------------------------------------*/
  381. VOID KillScrnSaver(void)
  382. {
  383. if (!IsWindowsNT())
  384. return;
  385. POINT pos;
  386. ::GetCursorPos(&pos);
  387. ::SetCursorPos(0,0);
  388. ::SetCursorPos(pos.x,pos.y);
  389. }
  390. /* D X P S Z */
  391. /*-------------------------------------------------------------------------
  392. %%Function: DxpSz
  393. Get the width of the string in pixels.
  394. -------------------------------------------------------------------------*/
  395. int DxpSz(LPCTSTR pcsz)
  396. {
  397. HWND hwndDesktop = GetDesktopWindow();
  398. if (NULL == hwndDesktop)
  399. return 0;
  400. HDC hdc = GetDC(hwndDesktop);
  401. if (NULL == hdc)
  402. return 0;
  403. HFONT hFontOld = (HFONT) SelectObject(hdc, g_hfontDlg);
  404. SIZE size;
  405. int dxp = ::GetTextExtentPoint32(hdc, pcsz, lstrlen(pcsz), &size)
  406. ? size.cx : 0;
  407. ::SelectObject(hdc, hFontOld);
  408. ::ReleaseDC(hwndDesktop, hdc);
  409. return dxp;
  410. }
  411. /* F A N S I S Z */
  412. /*-------------------------------------------------------------------------
  413. %%Function: FAnsiSz
  414. Return TRUE if the string contains no DBCS characters.
  415. -------------------------------------------------------------------------*/
  416. BOOL FAnsiSz(LPCTSTR psz)
  417. {
  418. if (NULL != psz)
  419. {
  420. char ch;
  421. while (_T('\0') != (ch = *psz++))
  422. {
  423. if (IsDBCSLeadByte(ch))
  424. {
  425. return FALSE;
  426. }
  427. }
  428. }
  429. return TRUE;
  430. }
  431. /////////////////////////////////////////////////////////////////////////////
  432. int g_cBusyOperations = 0;
  433. VOID DecrementBusyOperations(void)
  434. {
  435. g_cBusyOperations--;
  436. POINT pt;
  437. // Wiggle the mouse - force user to send a WM_SETCURSOR
  438. if (::GetCursorPos(&pt))
  439. ::SetCursorPos(pt.x, pt.y);
  440. }
  441. VOID IncrementBusyOperations(void)
  442. {
  443. g_cBusyOperations++;
  444. POINT pt;
  445. // Wiggle the mouse - force user to send a WM_SETCURSOR
  446. if (::GetCursorPos(&pt))
  447. ::SetCursorPos(pt.x, pt.y);
  448. }
  449. /////////////////////////////////////////////////////////////////////////////
  450. // String Utilities
  451. /* P S Z A L L O C */
  452. /*-------------------------------------------------------------------------
  453. %%Function: PszAlloc
  454. -------------------------------------------------------------------------*/
  455. LPTSTR PszAlloc(LPCTSTR pszSrc)
  456. {
  457. if (NULL == pszSrc)
  458. return NULL;
  459. LPTSTR pszDest = new TCHAR[lstrlen(pszSrc) + 1];
  460. if (NULL != pszDest)
  461. {
  462. lstrcpy(pszDest, pszSrc);
  463. }
  464. return pszDest;
  465. }
  466. VOID FreePsz(LPTSTR psz)
  467. {
  468. delete [] psz;
  469. }
  470. /* L P T S T R _ T O _ B S T R */
  471. /*-------------------------------------------------------------------------
  472. %%Function: LPTSTR_to_BSTR
  473. -------------------------------------------------------------------------*/
  474. HRESULT LPTSTR_to_BSTR(BSTR *pbstr, LPCTSTR psz)
  475. {
  476. ASSERT(NULL != pbstr);
  477. if (NULL == psz)
  478. {
  479. psz = TEXT(""); // convert NULL strings to empty strings
  480. }
  481. #ifndef UNICODE
  482. // compute the length of the required BSTR
  483. int cch = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
  484. if (cch <= 0)
  485. return E_FAIL;
  486. // allocate the widestr, +1 for terminating null
  487. BSTR bstr = SysAllocStringLen(NULL, cch-1); // SysAllocStringLen adds 1
  488. if (bstr == NULL)
  489. return E_OUTOFMEMORY;
  490. MultiByteToWideChar(CP_ACP, 0, psz, -1, (LPWSTR)bstr, cch);
  491. ((LPWSTR)bstr)[cch - 1] = 0;
  492. #else
  493. BSTR bstr = SysAllocString(psz);
  494. if (bstr == NULL)
  495. return E_OUTOFMEMORY;
  496. #endif // UNICODE
  497. *pbstr = bstr;
  498. return S_OK;
  499. }
  500. /* B S T R _ T O _ L P T S T R */
  501. /*-------------------------------------------------------------------------
  502. %%Function: BSTR_to_LPTSTR
  503. -------------------------------------------------------------------------*/
  504. HRESULT BSTR_to_LPTSTR(LPTSTR *ppsz, BSTR bstr)
  505. {
  506. #ifndef UNICODE
  507. // compute the length of the required BSTR
  508. int cch = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)bstr, -1, NULL, 0, NULL, NULL);
  509. if (cch <= 0)
  510. return E_FAIL;
  511. // cch is the number of BYTES required, including the null terminator
  512. *ppsz = (LPTSTR) new char[cch];
  513. if (*ppsz == NULL)
  514. return E_OUTOFMEMORY;
  515. WideCharToMultiByte(CP_ACP, 0, (LPWSTR)bstr, -1, *ppsz, cch, NULL, NULL);
  516. return S_OK;
  517. #else
  518. return E_NOTIMPL;
  519. #endif // UNICODE
  520. }
  521. /* P S Z F R O M B S T R */
  522. /*-------------------------------------------------------------------------
  523. %%Function: PszFromBstr
  524. -------------------------------------------------------------------------*/
  525. LPTSTR PszFromBstr(PCWSTR pwStr)
  526. {
  527. #ifdef UNICODE
  528. return PszAlloc(pwStr)
  529. #else
  530. int cch = WideCharToMultiByte(CP_ACP, 0, pwStr, -1, NULL, 0, NULL, NULL);
  531. if (cch <= 0)
  532. return NULL;
  533. // cch is the number of BYTES required, including the null terminator
  534. LPTSTR psz = new char[cch];
  535. if (NULL != psz)
  536. {
  537. WideCharToMultiByte(CP_ACP, 0, pwStr, -1, psz, cch, NULL, NULL);
  538. }
  539. return psz;
  540. #endif /* UNICODE */
  541. }
  542. /////////////////////////////////////////////////////////////////////////////
  543. // Connection Point Helpers
  544. HRESULT NmAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  545. {
  546. IConnectionPointContainer *pCPC;
  547. IConnectionPoint *pCP;
  548. HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  549. if (SUCCEEDED(hRes))
  550. {
  551. hRes = pCPC->FindConnectionPoint(iid, &pCP);
  552. pCPC->Release();
  553. }
  554. if (SUCCEEDED(hRes))
  555. {
  556. hRes = pCP->Advise(pUnk, pdw);
  557. pCP->Release();
  558. }
  559. return hRes;
  560. }
  561. HRESULT NmUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw)
  562. {
  563. IConnectionPointContainer *pCPC;
  564. IConnectionPoint *pCP;
  565. HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  566. if (SUCCEEDED(hRes))
  567. {
  568. hRes = pCPC->FindConnectionPoint(iid, &pCP);
  569. pCPC->Release();
  570. }
  571. if (SUCCEEDED(hRes))
  572. {
  573. hRes = pCP->Unadvise(dw);
  574. pCP->Release();
  575. }
  576. return hRes;
  577. }
  578. extern INmSysInfo2 * g_pNmSysInfo;
  579. ////////////////////////////////////////////////////////////////////////////
  580. // Call into the certificate generation module to generate
  581. // a certificate matching the ULS info for secure calling:
  582. DWORD MakeCertWrap
  583. (
  584. LPCSTR szFirstName,
  585. LPCSTR szLastName,
  586. LPCSTR szEmailName,
  587. DWORD dwFlags
  588. )
  589. {
  590. HMODULE hMakeCertLib = NmLoadLibrary(SZ_NMMKCERTLIB, TRUE);
  591. DWORD dwRet = -1;
  592. if ( NULL != hMakeCertLib ) {
  593. PFN_NMMAKECERT pfn_MakeCert =
  594. (PFN_NMMAKECERT)GetProcAddress ( hMakeCertLib,
  595. SZ_NMMAKECERTFUNC );
  596. if ( NULL != pfn_MakeCert ) {
  597. dwRet = pfn_MakeCert( szFirstName,
  598. szLastName,
  599. szEmailName,
  600. NULL,
  601. NULL,
  602. dwFlags );
  603. RefreshSelfIssuedCert();
  604. }
  605. else
  606. {
  607. ERROR_OUT(("GetProcAddress(%s) failed: %x",
  608. SZ_NMMAKECERTFUNC, GetLastError()));
  609. }
  610. FreeLibrary ( hMakeCertLib );
  611. }
  612. else
  613. {
  614. ERROR_OUT(("NmLoadLibrary(%s) failed: %x", SZ_NMMKCERTLIB,
  615. GetLastError()));
  616. }
  617. return(dwRet);
  618. }
  619. ///////////////////////////////////////////////////////////////////////////
  620. // Icon Utilities
  621. HIMAGELIST g_himlIconSmall = NULL;
  622. VOID LoadIconImages(void)
  623. {
  624. ASSERT(NULL == g_himlIconSmall);
  625. g_himlIconSmall = ImageList_Create(DXP_ICON_SMALL, DYP_ICON_SMALL, ILC_MASK, 1, 0);
  626. if (NULL != g_himlIconSmall)
  627. {
  628. HBITMAP hBmp = ::LoadBitmap(::GetInstanceHandle(), MAKEINTRESOURCE(IDB_ICON_IMAGES));
  629. if (NULL != hBmp)
  630. {
  631. ImageList_AddMasked(g_himlIconSmall, hBmp, TOOLBAR_MASK_COLOR);
  632. ::DeleteObject(hBmp);
  633. }
  634. }
  635. }
  636. VOID FreeIconImages(void)
  637. {
  638. if (NULL != g_himlIconSmall)
  639. {
  640. ImageList_Destroy(g_himlIconSmall);
  641. g_himlIconSmall = NULL;
  642. }
  643. }
  644. VOID DrawIconSmall(HDC hdc, int iIcon, int x, int y)
  645. {
  646. ImageList_DrawEx(g_himlIconSmall, iIcon, hdc,
  647. x, y, DXP_ICON_SMALL, DYP_ICON_SMALL,
  648. CLR_DEFAULT, CLR_DEFAULT, ILD_NORMAL);
  649. }
  650. // Get the default dialog (GUI) font for international
  651. HFONT GetDefaultFont(void)
  652. {
  653. if (NULL == g_hfontDlg)
  654. {
  655. g_hfontDlg = (HFONT) ::GetStockObject(DEFAULT_GUI_FONT);
  656. }
  657. return g_hfontDlg;
  658. }
  659. /* F E M P T Y D L G I T E M */
  660. /*-------------------------------------------------------------------------
  661. %%Function: FEmptyDlgItem
  662. Return TRUE if the dialog control is empty
  663. -------------------------------------------------------------------------*/
  664. BOOL FEmptyDlgItem(HWND hdlg, UINT id)
  665. {
  666. TCHAR sz[MAX_PATH];
  667. return (0 == GetDlgItemTextTrimmed(hdlg, id, sz, CCHMAX(sz)) );
  668. }
  669. /* T R I M D L G I T E M T E X T */
  670. /*-------------------------------------------------------------------------
  671. %%Function: TrimDlgItemText
  672. Trim the text in the edit control and return the length of the string.
  673. -------------------------------------------------------------------------*/
  674. UINT TrimDlgItemText(HWND hdlg, UINT id)
  675. {
  676. TCHAR sz[MAX_PATH];
  677. GetDlgItemTextTrimmed(hdlg, id, sz, CCHMAX(sz));
  678. SetDlgItemText(hdlg, id, sz);
  679. return lstrlen(sz);
  680. }
  681. /* G E T D L G I T E M T E X T T R I M M E D */
  682. /*-------------------------------------------------------------------------
  683. %%Function: GetDlgItemTextTrimmed
  684. -------------------------------------------------------------------------*/
  685. UINT GetDlgItemTextTrimmed(HWND hdlg, int id, PTCHAR psz, int cchMax)
  686. {
  687. UINT cch = GetDlgItemText(hdlg, id, psz, cchMax);
  688. if (0 != cch)
  689. {
  690. cch = TrimSz(psz);
  691. }
  692. return cch;
  693. }
  694. /* F M T D A T E T I M E */
  695. /*-------------------------------------------------------------------------
  696. %%Function: FmtDateTime
  697. Formats the system time using the current setting (MM/DD/YY HH:MM xm)
  698. -------------------------------------------------------------------------*/
  699. int FmtDateTime(LPSYSTEMTIME pst, LPTSTR pszDateTime, int cchMax)
  700. {
  701. pszDateTime[0] = _T('\0');
  702. int cch = ::GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE,
  703. pst, NULL, pszDateTime, cchMax);
  704. if ((0 != cch) && ((cchMax - cch) > 0))
  705. {
  706. // Tack on a space and then the time.
  707. // GetDateFormat returns count of chars
  708. // INCLUDING the NULL terminator, hence the - 1
  709. LPTSTR pszTime = pszDateTime + (cch - 1);
  710. pszTime[0] = _T(' ');
  711. pszTime[1] = _T('\0');
  712. cch = ::GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS,
  713. pst, NULL, &(pszTime[1]), (cchMax - cch));
  714. }
  715. return (cch == 0 ? 0 : lstrlen(pszDateTime));
  716. }
  717. /* C O M B I N E N A M E S */
  718. /*-------------------------------------------------------------------------
  719. %%Function: CombineNames
  720. Combine the two names into one string.
  721. The result is a "First Last" (or Intl'd "Last First") string
  722. -------------------------------------------------------------------------*/
  723. VOID CombineNames(LPTSTR pszResult, int cchResult, LPCTSTR pcszFirst, LPCTSTR pcszLast)
  724. {
  725. ASSERT(pszResult);
  726. TCHAR szFmt[32]; // A small value: String is "%1 %2" or "%2 %1"
  727. TCHAR sz[1024]; // The result (before truncating to cchResult chars)
  728. LPCTSTR argw[2];
  729. argw[0] = pcszFirst;
  730. argw[1] = pcszLast;
  731. *pszResult = _T('\0');
  732. if (FLoadString(IDS_NAME_ORDER, szFmt, CCHMAX(szFmt)))
  733. {
  734. if (0 != FormatMessage(FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING,
  735. szFmt, 0, 0, sz, CCHMAX(sz), (va_list *)argw ))
  736. {
  737. lstrcpyn(pszResult, sz, cchResult);
  738. #ifndef _UNICODE
  739. // (see bug 3907 )
  740. // lstrcpyn() can clip a DBCS character in half at the end of the string
  741. // we need to walk the string with ::CharNext() and replace the last byte
  742. // with a NULL if the last byte is half of a DBCS char.
  743. PTSTR pszSource = sz;
  744. while (*pszSource && (pszSource - sz < cchResult))
  745. {
  746. PTSTR pszPrev = pszSource;
  747. pszSource = ::CharNext(pszPrev);
  748. // If we've reached the first character that didn't get copied into
  749. // the destination buffer, and the previous character was a double
  750. // byte character...
  751. if (((pszSource - sz) == cchResult) && ::IsDBCSLeadByte(*pszPrev))
  752. {
  753. // Replace the destination buffer's last character with '\0'
  754. // NOTE: pszResult[cchResult - 1] is '\0' thanks to lstrcpyn()
  755. pszResult[cchResult - 2] = _T('\0');
  756. break;
  757. }
  758. }
  759. #endif // ! _UNICODE
  760. }
  761. }
  762. }
  763. BOOL NMGetSpecialFolderPath(
  764. HWND hwndOwner,
  765. LPTSTR lpszPath,
  766. int nFolder,
  767. BOOL fCreate)
  768. {
  769. LPITEMIDLIST pidl = NULL;
  770. BOOL fRet = FALSE;
  771. if (NOERROR == SHGetSpecialFolderLocation(NULL, nFolder, &pidl))
  772. {
  773. ASSERT(NULL != pidl);
  774. if (SHGetPathFromIDList(pidl, lpszPath))
  775. {
  776. lstrcat(lpszPath, _TEXT("\\"));
  777. fRet = TRUE;
  778. }
  779. LPMALLOC lpMalloc;
  780. if (SUCCEEDED(SHGetMalloc(&lpMalloc)))
  781. {
  782. ASSERT(NULL != lpMalloc);
  783. lpMalloc->Free(pidl);
  784. lpMalloc->Release();
  785. }
  786. }
  787. return fRet;
  788. }
  789. //--------------------------------------------------------------------------//
  790. // CDirectoryManager static data members. //
  791. //--------------------------------------------------------------------------//
  792. bool CDirectoryManager::m_webEnabled = true;
  793. TCHAR CDirectoryManager::m_ils[ MAX_PATH ] = TEXT( "" );
  794. TCHAR CDirectoryManager::m_displayName[ MAX_PATH ] = TEXT( "" );
  795. TCHAR CDirectoryManager::m_displayNameDefault[ MAX_PATH ] = TEXT( "Microsoft Internet Directory" );
  796. TCHAR CDirectoryManager::m_defaultServer[ MAX_PATH ] = TEXT( "" );
  797. TCHAR CDirectoryManager::m_DomainDirectory[ MAX_PATH ] = TEXT( "" );
  798. //--------------------------------------------------------------------------//
  799. // CDirectoryManager::get_defaultServer. //
  800. //--------------------------------------------------------------------------//
  801. const TCHAR * const
  802. CDirectoryManager::get_defaultServer(void)
  803. {
  804. if( m_defaultServer[ 0 ] == '\0' )
  805. {
  806. // defaultServer not yet loaded...
  807. RegEntry re( ISAPI_CLIENT_KEY, HKEY_CURRENT_USER );
  808. lstrcpyn( m_defaultServer, re.GetString( REGVAL_SERVERNAME ), CCHMAX( m_defaultServer ) );
  809. if( (m_defaultServer[ 0 ] == '\0') && (get_DomainDirectory() != NULL) )
  810. {
  811. // When no default ils server has been saved in the registry we first try to default it to the
  812. // server configured for the domain if any...
  813. lstrcpy( m_defaultServer, m_DomainDirectory );
  814. }
  815. if( (m_defaultServer[ 0 ] == '\0') && isWebDirectoryEnabled() )
  816. {
  817. // When no default ils server has been saved in the registry we default it to m_ils...
  818. lstrcpy( m_defaultServer, get_webDirectoryIls() );
  819. }
  820. }
  821. return( m_defaultServer );
  822. } // End of CDirectoryManager::get_defaultServer.
  823. //--------------------------------------------------------------------------//
  824. // CDirectoryManager::set_defaultServer. //
  825. //--------------------------------------------------------------------------//
  826. void
  827. CDirectoryManager::set_defaultServer
  828. (
  829. const TCHAR * const serverName
  830. ){
  831. RegEntry ulsKey( ISAPI_CLIENT_KEY, HKEY_CURRENT_USER );
  832. ulsKey.SetValue( REGVAL_SERVERNAME, serverName );
  833. lstrcpy( m_defaultServer, serverName );
  834. } // End of CDirectoryManager::set_defaultServer.
  835. //--------------------------------------------------------------------------//
  836. // CDirectoryManager::isWebDirectory. //
  837. //--------------------------------------------------------------------------//
  838. bool
  839. CDirectoryManager::isWebDirectory
  840. (
  841. const TCHAR * const directory
  842. ){
  843. TCHAR buffer[ MAX_PATH ];
  844. // If directory is null then the question is "is the default server the web directory?"
  845. return( isWebDirectoryEnabled() && (lstrcmpi( (directory != NULL)? get_dnsName( directory ): get_defaultServer(), get_webDirectoryIls() ) == 0) );
  846. } // End of CDirectoryManager::isWebDirectory.
  847. //--------------------------------------------------------------------------//
  848. // CDirectoryManager::get_dnsName. //
  849. //--------------------------------------------------------------------------//
  850. const TCHAR * const
  851. CDirectoryManager::get_dnsName
  852. (
  853. const TCHAR * const name
  854. ){
  855. // Check to see if the specified name matches m_displayName...
  856. return( (isWebDirectoryEnabled() && (lstrcmpi( name, loadDisplayName() ) == 0))? get_webDirectoryIls() : name );
  857. } // End of CDirectoryManager::get_dnsName.
  858. //--------------------------------------------------------------------------//
  859. // CDirectoryManager::get_displayName. //
  860. //--------------------------------------------------------------------------//
  861. const TCHAR * const
  862. CDirectoryManager::get_displayName
  863. (
  864. const TCHAR * const name
  865. ){
  866. // Check to see if the specified name matches m_ils...
  867. return( (isWebDirectoryEnabled() && (lstrcmpi( name, get_webDirectoryIls() ) == 0))? loadDisplayName(): name );
  868. } // End of CDirectoryManager::get_displayName.
  869. //--------------------------------------------------------------------------//
  870. // CDirectoryManager::loadDisplayName. //
  871. //--------------------------------------------------------------------------//
  872. const TCHAR * const
  873. CDirectoryManager::loadDisplayName(void)
  874. {
  875. using namespace ConfPolicies;
  876. if( m_displayName[ 0 ] == '\0' )
  877. {
  878. GetWebDirInfo( NULL, 0,
  879. NULL, 0,
  880. m_displayName, ARRAY_ELEMENTS(m_displayName) );
  881. if ( '\0' == m_displayName[0] )
  882. {
  883. USES_RES2T
  884. lstrcpy( m_displayName, RES2T( IDS_MS_INTERNET_DIRECTORY ) );
  885. if( m_displayName[ 0 ] == '\0' )
  886. {
  887. // Loading m_displayName from the resources failed... default to m_displayNameDefault...
  888. lstrcpy( m_displayName, m_displayNameDefault );
  889. }
  890. }
  891. }
  892. return( m_displayName );
  893. } // End of CDirectoryManager::loadDisplayName.
  894. //--------------------------------------------------------------------------//
  895. // CDirectoryManager::get_webDirectoryUrl. //
  896. //--------------------------------------------------------------------------//
  897. void
  898. CDirectoryManager::get_webDirectoryUrl(LPTSTR szWebDir, int cchmax)
  899. {
  900. using namespace ConfPolicies;
  901. if ( !isWebDirectoryEnabled() )
  902. {
  903. szWebDir[0] = '\0';
  904. return;
  905. }
  906. GetWebDirInfo( szWebDir, cchmax );
  907. if ( '\0' != szWebDir[0] )
  908. {
  909. // All done
  910. return;
  911. }
  912. void FormatURL(LPTSTR szURL);
  913. USES_RES2T
  914. lstrcpyn(szWebDir, RES2T(IDS_WEB_PAGE_FORMAT_WEBVIEW), cchmax);
  915. FormatURL(szWebDir);
  916. } // End of CDirectoryManager::get_webDirectoryUrl.
  917. //--------------------------------------------------------------------------//
  918. // CDirectoryManager::get_webDirectoryIls. //
  919. //--------------------------------------------------------------------------//
  920. const TCHAR * const
  921. CDirectoryManager::get_webDirectoryIls(void)
  922. {
  923. using namespace ConfPolicies;
  924. if (!isWebDirectoryEnabled())
  925. {
  926. return(TEXT(""));
  927. }
  928. if ('\0' == m_ils[0])
  929. {
  930. GetWebDirInfo( NULL, 0,
  931. m_ils, ARRAY_ELEMENTS(m_ils) );
  932. if ('\0' == m_ils[0])
  933. {
  934. lstrcpy(m_ils, TEXT("logon.netmeeting.microsoft.com"));
  935. }
  936. }
  937. return(m_ils);
  938. } // End of CDirectoryManager::get_webDirectoryIls.
  939. //--------------------------------------------------------------------------//
  940. // CDirectoryManager::isWebDirectoryEnabled. //
  941. //--------------------------------------------------------------------------//
  942. bool
  943. CDirectoryManager::isWebDirectoryEnabled(void)
  944. {
  945. static bool policyChecked = false;
  946. if( !policyChecked )
  947. {
  948. policyChecked = true;
  949. m_webEnabled = !ConfPolicies::isWebDirectoryDisabled();
  950. }
  951. return( m_webEnabled );
  952. } // End of CDirectoryManager::isWebDirectoryEnabled.
  953. //--------------------------------------------------------------------------//
  954. // CDirectoryManager::get_DomainDirectory. //
  955. //--------------------------------------------------------------------------//
  956. const TCHAR * const
  957. CDirectoryManager::get_DomainDirectory(void)
  958. {
  959. static bool bAccessAttempted = false; // only read this info once... if it fails once assume it's not available and don't retry until restarted...
  960. if( (!bAccessAttempted) && m_DomainDirectory[ 0 ] == '\0' )
  961. {
  962. bAccessAttempted = true;
  963. // Try to obtain the configured directory for this domain...
  964. ITRendezvous * pRendezvous;
  965. HRESULT hrResult;
  966. hrResult = ::CoCreateInstance( CLSID_Rendezvous, NULL, CLSCTX_ALL, IID_ITRendezvous, (void **) &pRendezvous );
  967. if( (hrResult == S_OK) && (pRendezvous != NULL) )
  968. {
  969. IEnumDirectory * pEnumDirectory;
  970. hrResult = pRendezvous->EnumerateDefaultDirectories( &pEnumDirectory );
  971. if( (hrResult == S_OK) && (pEnumDirectory != NULL) )
  972. {
  973. ITDirectory * pDirectory;
  974. bool bFoundILS = false;
  975. do
  976. {
  977. hrResult = pEnumDirectory->Next( 1, &pDirectory, NULL );
  978. if( (hrResult == S_OK) && (pDirectory != NULL) )
  979. {
  980. LPWSTR * ppServers;
  981. DIRECTORY_TYPE type;
  982. if( pDirectory->get_DirectoryType( &type ) == S_OK )
  983. {
  984. if( type == DT_ILS ) // Found an ILS server configured on the DS... retrieve the name and port...
  985. {
  986. bFoundILS = true;
  987. BSTR pName;
  988. if( pDirectory->get_DisplayName( &pName ) == S_OK )
  989. {
  990. LPTSTR szName;
  991. if (SUCCEEDED(BSTR_to_LPTSTR (&szName, pName)))
  992. {
  993. lstrcpy( m_DomainDirectory, szName );
  994. delete (szName);
  995. }
  996. SysFreeString( pName );
  997. }
  998. ITILSConfig * pITILSConfig;
  999. hrResult = pDirectory->QueryInterface( IID_ITILSConfig, (void **) &pITILSConfig );
  1000. if( (hrResult == S_OK) && (pITILSConfig != NULL) )
  1001. {
  1002. long lPort;
  1003. if( pITILSConfig->get_Port( &lPort ) == S_OK )
  1004. {
  1005. TCHAR pszPort[ 32 ];
  1006. wsprintf( pszPort, TEXT( ":%d" ), lPort );
  1007. lstrcat( m_DomainDirectory, pszPort );
  1008. }
  1009. pITILSConfig->Release();
  1010. }
  1011. }
  1012. }
  1013. pDirectory->Release();
  1014. }
  1015. }
  1016. while( (!bFoundILS) && (hrResult == S_OK) && (pDirectory != NULL) );
  1017. pEnumDirectory->Release();
  1018. }
  1019. pRendezvous->Release();
  1020. }
  1021. }
  1022. return( (m_DomainDirectory[ 0 ] != '\0')? m_DomainDirectory: NULL );
  1023. } // End of CDirectoryManager::get_DomainDirectory.
  1024. // Returns non-empty strings if there is a web dir set by policy
  1025. bool ConfPolicies::GetWebDirInfo(
  1026. LPTSTR szURL, int cchmaxURL,
  1027. LPTSTR szServer, int cchmaxServer,
  1028. LPTSTR szName, int cchmaxName
  1029. )
  1030. {
  1031. // if the string params are messed up, just return false
  1032. ASSERT( (!szURL || ( cchmaxURL > 0 ))
  1033. && (!szServer || ( cchmaxServer > 0 ))
  1034. && (!szName || ( cchmaxName > 0 ))
  1035. );
  1036. bool bSuccess = false;
  1037. // Try to get the registry value
  1038. RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
  1039. LPCTSTR szTemp;
  1040. szTemp = rePol.GetString( REGVAL_POL_INTRANET_WEBDIR_URL );
  1041. if( szTemp[0] )
  1042. {
  1043. if (NULL != szURL)
  1044. {
  1045. lstrcpyn( szURL, szTemp, cchmaxURL );
  1046. }
  1047. szTemp = rePol.GetString( REGVAL_POL_INTRANET_WEBDIR_SERVER );
  1048. if (szTemp[0])
  1049. {
  1050. if (NULL != szServer)
  1051. {
  1052. lstrcpyn( szServer, szTemp, cchmaxServer );
  1053. }
  1054. szTemp = rePol.GetString( REGVAL_POL_INTRANET_WEBDIR_NAME );
  1055. if( szTemp[0] )
  1056. {
  1057. if (NULL != szName)
  1058. {
  1059. lstrcpyn( szName, szTemp, cchmaxName );
  1060. }
  1061. // All three values must be specified for success
  1062. bSuccess = true;
  1063. }
  1064. }
  1065. }
  1066. if (!bSuccess)
  1067. {
  1068. // Empty the strings
  1069. if (NULL != szURL ) szURL [0] = '\0';
  1070. if (NULL != szServer) szServer[0] = '\0';
  1071. if (NULL != szName ) szName [0] = '\0';
  1072. }
  1073. return(bSuccess);
  1074. }
  1075. bool g_bAutoAccept = false;
  1076. bool ConfPolicies::IsAutoAcceptCallsOptionEnabled(void)
  1077. {
  1078. RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
  1079. return !rePol.GetNumber( REGVAL_POL_NO_AUTOACCEPTCALLS, DEFAULT_POL_NO_AUTOACCEPTCALLS );
  1080. }
  1081. bool ConfPolicies::IsAutoAcceptCallsPersisted(void)
  1082. {
  1083. RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
  1084. return 0 != rePol.GetNumber( REGVAL_POL_PERSIST_AUTOACCEPTCALLS, DEFAULT_POL_PERSIST_AUTOACCEPTCALLS );
  1085. }
  1086. bool ConfPolicies::IsAutoAcceptCallsEnabled(void)
  1087. {
  1088. bool bRet = false;
  1089. if( IsAutoAcceptCallsOptionEnabled() )
  1090. {
  1091. bRet = g_bAutoAccept;
  1092. if (IsAutoAcceptCallsPersisted())
  1093. {
  1094. // AutoAccept calls is _not_ disabled by the policy... we should check the AUTO_ACCEPT regval
  1095. RegEntry reConf(CONFERENCING_KEY, HKEY_CURRENT_USER);
  1096. if(reConf.GetNumber(REGVAL_AUTO_ACCEPT, g_bAutoAccept) )
  1097. {
  1098. bRet = true;
  1099. }
  1100. }
  1101. }
  1102. return bRet;
  1103. }
  1104. void ConfPolicies::SetAutoAcceptCallsEnabled(bool bAutoAccept)
  1105. {
  1106. g_bAutoAccept = bAutoAccept;
  1107. RegEntry reConf(CONFERENCING_KEY, HKEY_CURRENT_USER);
  1108. reConf.SetValue(REGVAL_AUTO_ACCEPT, g_bAutoAccept);
  1109. }