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.

927 lines
28 KiB

  1. #include "stdafx.h"
  2. #include <objsel.h> // Object picker
  3. #include <dsrole.h>
  4. #include "icwcfg.h"
  5. #pragma hdrstop
  6. // Wait cursor object
  7. CWaitCursor::CWaitCursor() :
  8. _hCursor(NULL)
  9. {
  10. WaitCursor();
  11. }
  12. CWaitCursor::~CWaitCursor()
  13. {
  14. RestoreCursor();
  15. }
  16. void CWaitCursor::WaitCursor()
  17. {
  18. _hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  19. }
  20. void CWaitCursor::RestoreCursor()
  21. {
  22. if (_hCursor)
  23. {
  24. SetCursor(_hCursor);
  25. _hCursor = NULL;
  26. }
  27. }
  28. HRESULT BrowseToPidl(LPCITEMIDLIST pidl)
  29. {
  30. HRESULT hr;
  31. // Use shellexecuteex to open a view on the pidl
  32. SHELLEXECUTEINFO shexinfo = {0};
  33. shexinfo.cbSize = sizeof (shexinfo);
  34. shexinfo.fMask = SEE_MASK_IDLIST | SEE_MASK_FLAG_NO_UI;
  35. shexinfo.nShow = SW_SHOWNORMAL;
  36. shexinfo.lpIDList = (void*) pidl;
  37. shexinfo.lpVerb = TEXT("open");
  38. hr = ShellExecuteEx(&shexinfo) ? S_OK : E_FAIL;
  39. return hr;
  40. }
  41. void FetchText(HWND hWndDlg, UINT uID, LPTSTR lpBuffer, DWORD dwMaxSize)
  42. {
  43. TCHAR* pszTemp;
  44. LPTSTR pszString;
  45. *lpBuffer = L'\0';
  46. HWND hwndCtl = GetDlgItem(hWndDlg, uID);
  47. if (hwndCtl)
  48. {
  49. int iSize = GetWindowTextLength(hwndCtl);
  50. pszTemp = new TCHAR[iSize + 1];
  51. if (pszTemp)
  52. {
  53. GetWindowText(hwndCtl, pszTemp, iSize + 1);
  54. pszString = pszTemp;
  55. while (*pszString == L' ')
  56. {
  57. pszString = CharNext(pszString);
  58. }
  59. if (*pszString )
  60. {
  61. StrCpyN(lpBuffer, pszString, dwMaxSize);
  62. pszString = lpBuffer+(lstrlen(lpBuffer)-1);
  63. while ( (pszString > lpBuffer) && (*pszString == L' ') )
  64. pszString--;
  65. pszString = CharNext(pszString);
  66. *pszString = L'\0';
  67. }
  68. delete [] pszTemp;
  69. }
  70. }
  71. }
  72. INT FetchTextLength(HWND hWndDlg, UINT uID)
  73. {
  74. TCHAR szBuffer[MAX_PATH];
  75. FetchText(hWndDlg, uID, szBuffer, ARRAYSIZE(szBuffer));
  76. return lstrlen(szBuffer);
  77. }
  78. HRESULT AttemptLookupAccountName(LPCTSTR szUsername, PSID* ppsid,
  79. LPTSTR szDomain, DWORD* pcchDomain, SID_NAME_USE* psUse)
  80. {
  81. // First try to find required size of SID
  82. DWORD cbSid = 0;
  83. DWORD cchDomain = *pcchDomain;
  84. BOOL fSuccess = LookupAccountName(NULL, szUsername, *ppsid, &cbSid, szDomain, pcchDomain, psUse);
  85. *ppsid = LocalAlloc(0, cbSid); // Now create the SID buffer and try again
  86. if (!*ppsid )
  87. return E_OUTOFMEMORY;
  88. *pcchDomain = cchDomain;
  89. if (!LookupAccountName(NULL, szUsername, *ppsid, &cbSid, szDomain, pcchDomain, psUse))
  90. {
  91. // Free our allocated SID
  92. LocalFree(*ppsid);
  93. *ppsid = NULL;
  94. return E_FAIL;
  95. }
  96. return S_OK;
  97. }
  98. BOOL FormatMessageTemplate(LPCTSTR pszTemplate, LPTSTR pszStrOut, DWORD cchSize, ...)
  99. {
  100. va_list vaParamList;
  101. va_start(vaParamList, cchSize);
  102. BOOL fResult = FormatMessage(FORMAT_MESSAGE_FROM_STRING, pszTemplate, 0, 0, pszStrOut, cchSize, &vaParamList);
  103. va_end(vaParamList);
  104. return fResult;
  105. }
  106. BOOL FormatMessageString(UINT idTemplate, LPTSTR pszStrOut, DWORD cchSize, ...)
  107. {
  108. BOOL fResult = FALSE;
  109. va_list vaParamList;
  110. TCHAR szFormat[MAX_STATIC + 1];
  111. if (LoadString(g_hinst, idTemplate, szFormat, ARRAYSIZE(szFormat)))
  112. {
  113. va_start(vaParamList, cchSize);
  114. fResult = FormatMessage(FORMAT_MESSAGE_FROM_STRING, szFormat, 0, 0, pszStrOut, cchSize, &vaParamList);
  115. va_end(vaParamList);
  116. }
  117. return fResult;
  118. }
  119. int DisplayFormatMessage(HWND hwnd, UINT idCaption, UINT idFormatString, UINT uType, ...)
  120. {
  121. int iResult = IDCANCEL;
  122. TCHAR szError[MAX_STATIC + 1]; *szError = 0;
  123. TCHAR szCaption[MAX_CAPTION + 1];
  124. TCHAR szFormat[MAX_STATIC + 1]; *szFormat = 0;
  125. // Load and format the error body
  126. if (LoadString(g_hinst, idFormatString, szFormat, ARRAYSIZE(szFormat)))
  127. {
  128. va_list arguments;
  129. va_start(arguments, uType);
  130. if (FormatMessage(FORMAT_MESSAGE_FROM_STRING, szFormat, 0, 0, szError, ARRAYSIZE(szError), &arguments))
  131. {
  132. // Load the caption
  133. if (LoadString(g_hinst, idCaption, szCaption, MAX_CAPTION))
  134. {
  135. iResult = MessageBox(hwnd, szError, szCaption, uType);
  136. }
  137. }
  138. va_end(arguments);
  139. }
  140. return iResult;
  141. }
  142. void EnableControls(HWND hwnd, const UINT* prgIDs, DWORD cIDs, BOOL fEnable)
  143. {
  144. DWORD i;
  145. for (i = 0; i < cIDs; i ++)
  146. {
  147. EnableWindow(GetDlgItem(hwnd, prgIDs[i]), fEnable);
  148. }
  149. }
  150. void MakeDomainUserString(LPCTSTR szDomain, LPCTSTR szUsername, LPTSTR szDomainUser, DWORD cchBuffer)
  151. {
  152. *szDomainUser = 0;
  153. if ((!szDomain) || szDomain[0] == TEXT('\0'))
  154. {
  155. // No domain - just use username
  156. StrCpyN(szDomainUser, szUsername, cchBuffer);
  157. }
  158. else
  159. {
  160. // Otherwise we have to build a DOMAIN\username string
  161. wnsprintf(szDomainUser, cchBuffer, TEXT("%s\\%s"), szDomain, szUsername);
  162. }
  163. }
  164. // From the NT knowledge base
  165. #define MY_BUFSIZE 512 // highly unlikely to exceed 512 bytes
  166. BOOL GetCurrentUserAndDomainName(LPTSTR UserName, LPDWORD cchUserName, LPTSTR DomainName, LPDWORD cchDomainName)
  167. {
  168. HANDLE hToken;
  169. UCHAR InfoBuffer[ MY_BUFSIZE ];
  170. DWORD cbInfoBuffer = MY_BUFSIZE;
  171. SID_NAME_USE snu;
  172. BOOL bSuccess;
  173. if(!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken))
  174. {
  175. if(GetLastError() == ERROR_NO_TOKEN)
  176. {
  177. // attempt to open the process token, since no thread token exists
  178. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  179. return FALSE;
  180. }
  181. else
  182. {
  183. return FALSE;
  184. }
  185. }
  186. bSuccess = GetTokenInformation(hToken, TokenUser, InfoBuffer, cbInfoBuffer, &cbInfoBuffer);
  187. CloseHandle(hToken);
  188. if(!bSuccess)
  189. return FALSE;
  190. return LookupAccountSid(NULL, ((PTOKEN_USER)InfoBuffer)->User.Sid, UserName, cchUserName, DomainName, cchDomainName, &snu);
  191. }
  192. // Pass NULL as TokenHandle to see if thread token is admin
  193. HRESULT IsUserLocalAdmin(HANDLE TokenHandle, BOOL* pfIsAdmin)
  194. {
  195. // First we must check if the current user is a local administrator; if this is
  196. // the case, our dialog doesn't even display
  197. PSID psidAdminGroup = NULL;
  198. SID_IDENTIFIER_AUTHORITY security_nt_authority = SECURITY_NT_AUTHORITY;
  199. BOOL fSuccess = ::AllocateAndInitializeSid(&security_nt_authority, 2,
  200. SECURITY_BUILTIN_DOMAIN_RID,
  201. DOMAIN_ALIAS_RID_ADMINS,
  202. 0, 0, 0, 0, 0, 0,
  203. &psidAdminGroup);
  204. if (fSuccess)
  205. {
  206. // See if the user for this process is a local admin
  207. fSuccess = CheckTokenMembership(TokenHandle, psidAdminGroup, pfIsAdmin);
  208. FreeSid(psidAdminGroup);
  209. }
  210. return fSuccess ? S_OK:E_FAIL;
  211. }
  212. BOOL IsComputerInDomain()
  213. {
  214. static BOOL fInDomain = FALSE;
  215. static BOOL fValid = FALSE;
  216. if (!fValid)
  217. {
  218. fValid = TRUE;
  219. DSROLE_PRIMARY_DOMAIN_INFO_BASIC* pdspdinfb = {0};
  220. DWORD err = DsRoleGetPrimaryDomainInformation(NULL, DsRolePrimaryDomainInfoBasic,
  221. (BYTE**) &pdspdinfb);
  222. if ((err == NO_ERROR) && (pdspdinfb != NULL))
  223. {
  224. if ((pdspdinfb->MachineRole == DsRole_RoleStandaloneWorkstation) ||
  225. (pdspdinfb->MachineRole == DsRole_RoleStandaloneServer))
  226. {
  227. fInDomain = FALSE;
  228. }
  229. else
  230. {
  231. fInDomain = TRUE;
  232. }
  233. DsRoleFreeMemory(pdspdinfb);
  234. }
  235. }
  236. return fInDomain;
  237. }
  238. void OffsetControls(HWND hwnd, const UINT* prgIDs, DWORD cIDs, int dx, int dy)
  239. {
  240. for (DWORD i = 0; i < cIDs; i ++)
  241. OffsetWindow(GetDlgItem(hwnd, prgIDs[i]), dx, dy);
  242. }
  243. void OffsetWindow(HWND hwnd, int dx, int dy)
  244. {
  245. RECT rc;
  246. GetWindowRect(hwnd, &rc);
  247. MapWindowPoints(NULL, GetParent(hwnd), (LPPOINT)&rc, 2);
  248. OffsetRect(&rc, dx, dy);
  249. SetWindowPos(hwnd, NULL, rc.left, rc.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
  250. }
  251. BOOL AddPropSheetPageCallback(HPROPSHEETPAGE hpsp, LPARAM lParam)
  252. {
  253. // lParam is really a ADDPROPSHEETDATA*
  254. ADDPROPSHEETDATA* ppsd = (ADDPROPSHEETDATA*)lParam;
  255. if (ppsd->nPages < ARRAYSIZE(ppsd->rgPages))
  256. {
  257. ppsd->rgPages[ppsd->nPages++] = hpsp;
  258. return TRUE;
  259. }
  260. return FALSE;
  261. }
  262. // Code to ensure only one instance of a particular window is running
  263. CEnsureSingleInstance::CEnsureSingleInstance(LPCTSTR szCaption)
  264. {
  265. // Create an event
  266. m_hEvent = CreateEvent(NULL, TRUE, FALSE, szCaption);
  267. // If any weird errors occur, default to running the instance
  268. m_fShouldExit = FALSE;
  269. if (NULL != m_hEvent)
  270. {
  271. // If our event isn't signaled, we're the first instance
  272. m_fShouldExit = (WAIT_OBJECT_0 == WaitForSingleObject(m_hEvent, 0));
  273. if (m_fShouldExit)
  274. {
  275. // app should exit after calling ShouldExit()
  276. // Find and show the caption'd window
  277. HWND hwndActivate = FindWindow(NULL, szCaption);
  278. if (IsWindow(hwndActivate))
  279. {
  280. SetForegroundWindow(hwndActivate);
  281. }
  282. }
  283. else
  284. {
  285. // Signal that event
  286. SetEvent(m_hEvent);
  287. }
  288. }
  289. }
  290. CEnsureSingleInstance::~CEnsureSingleInstance()
  291. {
  292. if (NULL != m_hEvent)
  293. {
  294. CloseHandle(m_hEvent);
  295. }
  296. }
  297. // Browse for a user
  298. //
  299. // This routine activates the appropriate Object Picker to allow
  300. // the user to select a user
  301. // uiTextLocation -- The resource ID of the Edit control where the selected
  302. // object should be printed
  303. HRESULT BrowseForUser(HWND hwndDlg, TCHAR* pszUser, DWORD cchUser, TCHAR* pszDomain, DWORD cchDomain)
  304. {
  305. DSOP_SCOPE_INIT_INFO scopeInfo = {0};
  306. scopeInfo.cbSize = sizeof (scopeInfo);
  307. scopeInfo.flType =
  308. DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE |
  309. DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE |
  310. DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
  311. DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN |
  312. DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN |
  313. DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
  314. scopeInfo.flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  315. scopeInfo.FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  316. scopeInfo.FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  317. scopeInfo.FilterFlags.Uplevel.flMixedModeOnly = 0;
  318. scopeInfo.FilterFlags.Uplevel.flNativeModeOnly = 0;
  319. scopeInfo.pwzADsPath = NULL;
  320. scopeInfo.pwzDcName = NULL;
  321. scopeInfo.hr = E_FAIL;
  322. DSOP_INIT_INFO initInfo = {0};
  323. initInfo.cbSize = sizeof (initInfo);
  324. initInfo.pwzTargetComputer = NULL;
  325. initInfo.cDsScopeInfos = 1;
  326. initInfo.aDsScopeInfos = &scopeInfo;
  327. initInfo.flOptions = 0;
  328. IDsObjectPicker* pPicker;
  329. HRESULT hr = CoCreateInstance(CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER, IID_IDsObjectPicker, (LPVOID*)&pPicker);
  330. if (SUCCEEDED(hr))
  331. {
  332. hr = pPicker->Initialize(&initInfo);
  333. if (SUCCEEDED(hr))
  334. {
  335. IDataObject* pdo;
  336. hr = pPicker->InvokeDialog(hwndDlg, &pdo); // S_FALSE indicates cancel
  337. if ((S_OK == hr) && (NULL != pdo))
  338. {
  339. // Get the DS_SELECTION_LIST out of the data obj
  340. FORMATETC fmt;
  341. fmt.cfFormat = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  342. fmt.ptd = NULL;
  343. fmt.dwAspect = DVASPECT_CONTENT;
  344. fmt.lindex = -1;
  345. fmt.tymed = TYMED_HGLOBAL;
  346. STGMEDIUM medium = {0};
  347. hr = pdo->GetData(&fmt, &medium);
  348. if (SUCCEEDED(hr))
  349. {
  350. DS_SELECTION_LIST* plist;
  351. plist = (DS_SELECTION_LIST*)
  352. GlobalLock(medium.hGlobal);
  353. if (NULL != plist)
  354. {
  355. if (plist->cItems >= 1)
  356. {
  357. WCHAR szWinNTProviderName[MAX_DOMAIN + MAX_USER + 10];
  358. StrCpyN(szWinNTProviderName, plist->aDsSelection[0].pwzADsPath, ARRAYSIZE(szWinNTProviderName));
  359. // Is the name in the correct format?
  360. if (StrCmpNI(szWinNTProviderName, TEXT("WinNT://"), 8) == 0)
  361. {
  362. // Yes, copy over the user name and password
  363. LPTSTR szDomain = szWinNTProviderName + 8;
  364. LPTSTR szUser = StrChr(szDomain, TEXT('/'));
  365. if (szUser)
  366. {
  367. LPTSTR szTemp = CharNext(szUser);
  368. *szUser = 0;
  369. szUser = szTemp;
  370. // Just in case, remove the trailing slash
  371. LPTSTR szTrailingSlash = StrChr(szUser, TEXT('/'));
  372. if (szTrailingSlash)
  373. *szTrailingSlash = 0;
  374. StrCpyN(pszUser, szUser, cchUser);
  375. StrCpyN(pszDomain, szDomain, cchDomain);
  376. hr = S_OK;
  377. }
  378. }
  379. }
  380. }
  381. else
  382. {
  383. hr = E_UNEXPECTED; // No selection list!
  384. }
  385. GlobalUnlock(medium.hGlobal);
  386. }
  387. pdo->Release();
  388. }
  389. }
  390. pPicker->Release();
  391. }
  392. return hr;
  393. }
  394. //
  395. // create the intro/done large font for wizards
  396. //
  397. static HFONT g_hfontIntro = NULL;
  398. HFONT GetIntroFont(HWND hwnd)
  399. {
  400. if ( !g_hfontIntro )
  401. {
  402. TCHAR szBuffer[64];
  403. NONCLIENTMETRICS ncm = { 0 };
  404. LOGFONT lf;
  405. ncm.cbSize = SIZEOF(ncm);
  406. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  407. lf = ncm.lfMessageFont;
  408. LoadString(g_hinst, IDS_TITLEFONTNAME, lf.lfFaceName, ARRAYSIZE(lf.lfFaceName));
  409. lf.lfWeight = FW_BOLD;
  410. LoadString(g_hinst, IDS_TITLEFONTSIZE, szBuffer, ARRAYSIZE(szBuffer));
  411. lf.lfHeight = 0 - (GetDeviceCaps(NULL, LOGPIXELSY) * StrToInt(szBuffer) / 72);
  412. g_hfontIntro = CreateFontIndirect(&lf);
  413. }
  414. return g_hfontIntro;
  415. }
  416. void CleanUpIntroFont()
  417. {
  418. if (g_hfontIntro)
  419. {
  420. DeleteObject(g_hfontIntro);
  421. g_hfontIntro = NULL;
  422. }
  423. }
  424. void DomainUserString_GetParts(LPCTSTR szDomainUser, LPTSTR szUser, DWORD cchUser, LPTSTR szDomain, DWORD cchDomain)
  425. {
  426. // Check for invalid args
  427. if ((!szUser) ||
  428. (!szDomain) ||
  429. (!cchUser) ||
  430. (!cchDomain))
  431. {
  432. return;
  433. }
  434. else
  435. {
  436. *szUser = 0;
  437. *szDomain = 0;
  438. TCHAR szTemp[MAX_USER + MAX_DOMAIN + 2];
  439. StrCpyN(szTemp, szDomainUser, ARRAYSIZE(szTemp));
  440. LPTSTR szWhack = StrChr(szTemp, TEXT('\\'));
  441. if (!szWhack)
  442. {
  443. // Also check for forward slash to be friendly
  444. szWhack = StrChr(szTemp, TEXT('/'));
  445. }
  446. if (szWhack)
  447. {
  448. LPTSTR szUserPointer = szWhack + 1;
  449. *szWhack = 0;
  450. // Temp now points to domain.
  451. StrCpyN(szDomain, szTemp, cchDomain);
  452. StrCpyN(szUser, szUserPointer, cchUser);
  453. }
  454. else
  455. {
  456. // Don't have a domain name - just a username
  457. StrCpyN(szUser, szTemp, cchUser);
  458. }
  459. }
  460. }
  461. LPITEMIDLIST GetComputerParent()
  462. {
  463. LPITEMIDLIST pidl = NULL;
  464. IShellFolder *psfDesktop;
  465. HRESULT hres = SHGetDesktopFolder(&psfDesktop);
  466. if (SUCCEEDED(hres))
  467. {
  468. TCHAR szName[MAX_PATH];
  469. szName[0] = szName[1] = L'\\';
  470. LPTSTR pszAfterWhacks = szName + 2;
  471. DWORD cchName = ARRAYSIZE(szName) - 2;
  472. if (GetComputerName(pszAfterWhacks, &cchName))
  473. {
  474. hres = psfDesktop->ParseDisplayName(NULL, NULL, szName, NULL, &pidl, NULL);
  475. if (SUCCEEDED(hres))
  476. {
  477. ILRemoveLastID(pidl);
  478. }
  479. }
  480. else
  481. {
  482. hres = E_FAIL;
  483. }
  484. psfDesktop->Release();
  485. }
  486. if (FAILED(hres) && pidl)
  487. {
  488. ILFree(pidl);
  489. pidl = NULL;
  490. }
  491. return pidl;
  492. }
  493. int CALLBACK ShareBrowseCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
  494. {
  495. switch (uMsg)
  496. {
  497. case BFFM_INITIALIZED:
  498. {
  499. // Try to set the selected item according to the path string passed in lpData
  500. LPTSTR pszPath = (LPTSTR) lpData;
  501. if (pszPath && pszPath[0])
  502. {
  503. int i = lstrlen(pszPath) - 1;
  504. if ((pszPath[i] == TEXT('\\')) ||
  505. (pszPath[i] == TEXT('/')))
  506. {
  507. pszPath[i] = 0;
  508. }
  509. SendMessage(hwnd, BFFM_SETSELECTION, (WPARAM) TRUE, (LPARAM) (LPTSTR) pszPath);
  510. }
  511. else
  512. {
  513. // Try to get the computer's container folder
  514. LPITEMIDLIST pidl = GetComputerParent();
  515. if (pidl)
  516. {
  517. SendMessage(hwnd, BFFM_SETSELECTION, (WPARAM) FALSE, (LPARAM) (LPTSTR) pidl);
  518. ILFree(pidl);
  519. }
  520. }
  521. }
  522. break;
  523. case BFFM_SELCHANGED:
  524. // Disable OK if this isn't a UNC path type thing
  525. {
  526. TCHAR szPath[MAX_PATH];
  527. LPITEMIDLIST pidl = (LPITEMIDLIST) lParam;
  528. BOOL fEnableOk = FALSE;
  529. if (SUCCEEDED(SHGetTargetFolderPath(pidl, szPath, ARRAYSIZE(szPath))))
  530. {
  531. SHFILEINFO sfi;
  532. SHGetFileInfo(szPath, 0, &sfi, sizeof(sfi), SHGFI_ATTRIBUTES);
  533. // Enable OK only if this is a file folder
  534. if (sfi.dwAttributes & SFGAO_FILESYSTEM)
  535. {
  536. fEnableOk = PathIsUNC(szPath);
  537. }
  538. }
  539. SendMessage(hwnd, BFFM_ENABLEOK, (WPARAM) 0, (LPARAM) fEnableOk);
  540. }
  541. break;
  542. }
  543. return 0;
  544. }
  545. void RemoveControl(HWND hwnd, UINT idControl, UINT idNextControl, const UINT* prgMoveControls, DWORD cControls, BOOL fShrinkParent)
  546. {
  547. HWND hwndControl = GetDlgItem(hwnd, idControl);
  548. HWND hwndNextControl = GetDlgItem(hwnd, idNextControl);
  549. RECT rcControl;
  550. RECT rcNextControl;
  551. if (hwndControl && GetWindowRect(hwndControl, &rcControl) &&
  552. hwndNextControl && GetWindowRect(hwndNextControl, &rcNextControl))
  553. {
  554. int dx = rcControl.left - rcNextControl.left;
  555. int dy = rcControl.top - rcNextControl.top;
  556. MoveControls(hwnd, prgMoveControls, cControls, dx, dy);
  557. if (fShrinkParent)
  558. {
  559. RECT rcParent;
  560. if (GetWindowRect(hwnd, &rcParent))
  561. {
  562. MapWindowPoints(NULL, GetParent(hwnd), (LPPOINT)&rcParent, 2);
  563. rcParent.right += dx;
  564. rcParent.bottom += dy;
  565. SetWindowPos(hwnd, NULL, 0, 0, RECTWIDTH(rcParent), RECTHEIGHT(rcParent), SWP_NOMOVE | SWP_NOZORDER);
  566. }
  567. }
  568. EnableWindow(hwndControl, FALSE);
  569. ShowWindow(hwndControl, SW_HIDE);
  570. }
  571. }
  572. void MoveControls(HWND hwnd, const UINT* prgControls, DWORD cControls, int dx, int dy)
  573. {
  574. DWORD iControl;
  575. for (iControl = 0; iControl < cControls; iControl ++)
  576. {
  577. HWND hwndControl = GetDlgItem(hwnd, prgControls[iControl]);
  578. RECT rcControl;
  579. if (hwndControl && GetWindowRect(hwndControl, &rcControl))
  580. {
  581. MapWindowPoints(NULL, hwnd, (LPPOINT)&rcControl, 2);
  582. SetWindowPos(hwndControl, NULL, rcControl.left + dx, rcControl.top + dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  583. }
  584. }
  585. }
  586. // compute the size of a control based on the you are going to set into it,
  587. // returning the delta in size.
  588. int SizeControlFromText(HWND hwnd, UINT id, LPTSTR psz)
  589. {
  590. HDC hdc = GetDC(hwnd);
  591. if (hdc)
  592. {
  593. HFONT hfDialog = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
  594. HFONT hfOld = (HFONT)SelectObject(hdc, hfDialog);
  595. RECT rc;
  596. GetClientRect(GetDlgItem(hwnd, id), &rc);
  597. int cy = RECTHEIGHT(rc);
  598. int dy = DrawTextEx(hdc, psz, -1, &rc,
  599. DT_CALCRECT | DT_WORDBREAK | DT_EXPANDTABS |
  600. DT_NOPREFIX | DT_EXTERNALLEADING | DT_EDITCONTROL,
  601. NULL) - cy;
  602. SetWindowPos(GetDlgItem(hwnd, id), NULL, 0, 0, RECTWIDTH(rc), RECTHEIGHT(rc), SWP_NOMOVE|SWP_NOZORDER);
  603. if (hfOld)
  604. SelectObject(hdc, hfOld);
  605. ReleaseDC(hwnd, hdc);
  606. return dy;
  607. }
  608. return 0;
  609. }
  610. void EnableDomainForUPN(HWND hwndUsername, HWND hwndDomain)
  611. {
  612. BOOL fEnable;
  613. // Get the string the user is typing
  614. TCHAR* pszLogonName;
  615. int cchBuffer = (int)SendMessage(hwndUsername, WM_GETTEXTLENGTH, 0, 0) + 1;
  616. pszLogonName = (TCHAR*) LocalAlloc(0, cchBuffer * sizeof(TCHAR));
  617. if (pszLogonName != NULL)
  618. {
  619. SendMessage(hwndUsername, WM_GETTEXT, (WPARAM) cchBuffer, (LPARAM) pszLogonName);
  620. // Disable the domain combo if the user is using a
  621. // UPN (if there is a "@") - ie [email protected]
  622. fEnable = (NULL == StrChr(pszLogonName, TEXT('@')));
  623. EnableWindow(hwndDomain, fEnable);
  624. LocalFree(pszLogonName);
  625. }
  626. }
  627. //
  628. // Set our Alt+Tab icon for the duration of a modal property sheet.
  629. //
  630. int PropertySheetIcon(LPCPROPSHEETHEADER ppsh, LPCTSTR pszIcon)
  631. {
  632. int iResult;
  633. HWND hwnd, hwndT;
  634. BOOL fChangedIcon = FALSE;
  635. HICON hicoPrev;
  636. // This trick doesn't work for modeless property sheets
  637. _ASSERT(!(ppsh->dwFlags & PSH_MODELESS));
  638. // Don't do this if the property sheet itself already has an icon
  639. _ASSERT(ppsh->hIcon == NULL);
  640. // Walk up the parent/owner chain until we find the master owner.
  641. //
  642. // We need to walk the parent chain because sometimes we are given
  643. // a child window as our lpwd->hwnd. And we need to walk the owner
  644. // chain in order to find the owner whose icon will be used for
  645. // Alt+Tab.
  646. //
  647. // GetParent() returns either the parent or owner. Normally this is
  648. // annoying, but we luck out and it's exactly what we want.
  649. hwnd = ppsh->hwndParent;
  650. while ((hwndT = GetParent(hwnd)) != NULL)
  651. {
  652. hwnd = hwndT;
  653. }
  654. // If the master owner isn't visible we can futz his icon without
  655. // screwing up his appearance.
  656. if (!IsWindowVisible(hwnd))
  657. {
  658. HICON hicoNew = LoadIcon(g_hinst, pszIcon);
  659. hicoPrev = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hicoNew);
  660. fChangedIcon = TRUE;
  661. }
  662. iResult = (int)PropertySheet(ppsh);
  663. // Clean up our icon now that we're done
  664. if (fChangedIcon)
  665. {
  666. // Put the old icon back
  667. HICON hicoNew = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hicoPrev);
  668. if (hicoNew)
  669. DestroyIcon(hicoNew);
  670. }
  671. return iResult;
  672. }
  673. // Launch ICW shiznits
  674. BOOL IsICWCompleted()
  675. {
  676. DWORD dwICWCompleted = 0;
  677. DWORD dwICWSize = sizeof(dwICWCompleted);
  678. SHGetValue(HKEY_CURRENT_USER, TEXT(ICW_REGPATHSETTINGS), TEXT(ICW_REGKEYCOMPLETED), NULL, &dwICWCompleted, &dwICWSize);
  679. // 99/01/15 #272829 vtan: This is a horrible hack!!! If ICW has
  680. // not been run but settings have been made manually then values
  681. // in HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections
  682. // exists with the values given. Look for the presence of a key
  683. // to resolve that settings are present but that ICW hasn't been
  684. // launched.
  685. // The ideal solution is to get ICW to make this determination
  686. // for us BUT TO NOT LAUNCH ICWCONN1.EXE IN THE PROCESS.
  687. // Currently it will only launch. There is no way to get the
  688. // desired result without a launch.
  689. // 99/02/01 #280138 vtan: Well the solution put in for #272829
  690. // doesn't work. So peeking at the CheckConnectionWizard()
  691. // source in inetcfg\export.cpp shows that it uses a
  692. // wininet.dll function to determine whether manually configured
  693. // internet settings exist. It also exports this function so
  694. // look for it and bind to it dynamically.
  695. if (dwICWCompleted == 0)
  696. {
  697. #define SMART_RUNICW TRUE
  698. #define SMART_QUITICW FALSE
  699. HINSTANCE hICWInst = LoadLibrary(TEXT("inetcfg.dll"));
  700. if (hICWInst != NULL)
  701. {
  702. typedef DWORD (WINAPI *PFNISSMARTSTART) ();
  703. PFNISSMARTSTART pfnIsSmartStart = reinterpret_cast<PFNISSMARTSTART>(GetProcAddress(hICWInst, "IsSmartStart"));
  704. if (pfnIsSmartStart)
  705. {
  706. dwICWCompleted = BOOLIFY(pfnIsSmartStart() == SMART_QUITICW);
  707. }
  708. FreeLibrary(hICWInst);
  709. }
  710. }
  711. return (dwICWCompleted != 0);
  712. }
  713. void LaunchICW()
  714. {
  715. static BOOL s_fCheckedICW = FALSE;
  716. if (!s_fCheckedICW && !IsICWCompleted())
  717. {
  718. // Prevent an error in finding the ICW from causing this to execute over and over again.
  719. s_fCheckedICW = TRUE;
  720. HINSTANCE hICWInst = LoadLibrary(TEXT("inetcfg.dll"));
  721. if (hICWInst != NULL)
  722. {
  723. PFNCHECKCONNECTIONWIZARD pfnCheckConnectionWizard;
  724. pfnCheckConnectionWizard = reinterpret_cast<PFNCHECKCONNECTIONWIZARD>(GetProcAddress(hICWInst, "CheckConnectionWizard"));
  725. if (pfnCheckConnectionWizard != NULL)
  726. {
  727. // If the user cancels ICW then it needs to be launched again.
  728. s_fCheckedICW = FALSE;
  729. DWORD dwICWResult;
  730. pfnCheckConnectionWizard(ICW_LAUNCHFULL | ICW_LAUNCHMANUAL, &dwICWResult);
  731. }
  732. FreeLibrary(hICWInst);
  733. }
  734. }
  735. }
  736. HRESULT LookupLocalGroupName(DWORD dwRID, LPWSTR pszName, DWORD cchName)
  737. {
  738. HRESULT hr = E_FAIL;
  739. PSID psidGroup = NULL;
  740. SID_IDENTIFIER_AUTHORITY security_nt_authority = SECURITY_NT_AUTHORITY;
  741. BOOL fSuccess = ::AllocateAndInitializeSid(&security_nt_authority, 2,
  742. SECURITY_BUILTIN_DOMAIN_RID,
  743. dwRID,
  744. 0, 0, 0, 0, 0, 0,
  745. &psidGroup);
  746. if (fSuccess)
  747. {
  748. // Get the name
  749. WCHAR szDomain[MAX_GROUP + 1];
  750. DWORD cchDomain = ARRAYSIZE(szDomain);
  751. SID_NAME_USE type;
  752. fSuccess = LookupAccountSid(NULL, psidGroup, pszName, &cchName, szDomain, &cchDomain, &type);
  753. FreeSid(psidGroup);
  754. hr = fSuccess ? S_OK : E_FAIL;
  755. }
  756. return hr;
  757. }