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.

1043 lines
28 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: util.cxx
  7. //
  8. // Contents: utility functions
  9. //
  10. //
  11. // History: 12-05-1997 SusiA
  12. //
  13. //---------------------------------------------------------------------------
  14. #include "lib.h"
  15. #ifndef SECURITY_WIN32
  16. #define SECURITY_WIN32
  17. #endif
  18. #include "security.h"
  19. CRITICAL_SECTION g_CritSectCommonLib; // initialized by InitCommonLib
  20. void InitCommonLib()
  21. {
  22. InitializeCriticalSection(&g_CritSectCommonLib);
  23. }
  24. void UnInitCommonLib(void)
  25. {
  26. DeleteCriticalSection(&g_CritSectCommonLib);
  27. }
  28. typedef BOOLEAN (APIENTRY *PFNGETUSERNAMEEX) (EXTENDED_NAME_FORMAT NameFormat,
  29. LPWSTR lpNameBuffer, PULONG nSize );
  30. STRING_FILENAME(szSecur32Dll, "SECUR32.DLL");
  31. STRING_INTERFACE(szGetUserNameEx,"GetUserNameExW");
  32. BOOL g_fLoadedSecur32 = FALSE;
  33. HINSTANCE g_hinstSecur32 = NULL;
  34. PFNGETUSERNAMEEX g_pfGetUserNameEx = NULL;
  35. //+---------------------------------------------------------------------------
  36. //
  37. // Function: CenterDialog
  38. //
  39. // Synopsis: Helper to center a dialog on screen.
  40. //
  41. // Arguments: [hDlg] -- Dialog handle.
  42. //
  43. // Returns: None.
  44. //
  45. // Notes: None.
  46. //
  47. //----------------------------------------------------------------------------
  48. void
  49. CenterDialog(HWND hDlg)
  50. {
  51. RECT rc;
  52. GetWindowRect(hDlg, &rc);
  53. SetWindowPos(hDlg,
  54. NULL,
  55. ((GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) / 2),
  56. ((GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) / 2),
  57. 0,
  58. 0,
  59. SWP_NOSIZE | SWP_NOACTIVATE);
  60. }
  61. void LoadSecur32Dll()
  62. {
  63. if (g_fLoadedSecur32)
  64. return;
  65. CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
  66. cCritSect.Enter();
  67. // make sure not loaded again in case someone took lock first
  68. if (!g_fLoadedSecur32)
  69. {
  70. g_hinstSecur32 = LoadLibrary(szSecur32Dll);
  71. if (g_hinstSecur32)
  72. {
  73. g_pfGetUserNameEx = (PFNGETUSERNAMEEX) GetProcAddress(g_hinstSecur32, szGetUserNameEx);
  74. // won't get the export on NT 4.0
  75. }
  76. g_fLoadedSecur32 = TRUE;
  77. }
  78. cCritSect.Leave();
  79. }
  80. //+--------------------------------------------------------------------------
  81. //
  82. // Function: GetDefaultDomainAndUserName
  83. //
  84. // Synopsis: Fill [ptszDomainAndUserName] with "domain\user" string
  85. //
  86. // Arguments: [ptszDomainAndUserName] - buffer to receive string
  87. // [cchBuf] - should be at least UNLEN
  88. //
  89. // Modifies: *[ptszDomainAndUserName].
  90. //
  91. // History: 06-03-1997 DavidMun Created
  92. //
  93. // Notes: If an error occurs while retrieving the domain name, only
  94. // the user name is returned. If even that cannot be
  95. // retrieved, the buffer is set to an empty string.
  96. //
  97. //---------------------------------------------------------------------------
  98. // if output buffer is too small it gets truncated.
  99. VOID
  100. GetDefaultDomainAndUserName(
  101. LPTSTR ptszDomainAndUserName,
  102. LPTSTR ptszSeparator,
  103. ULONG cchBuf)
  104. {
  105. HRESULT hr = E_FAIL;
  106. LONG lr = 0;
  107. LoadSecur32Dll();
  108. if (g_pfGetUserNameEx)
  109. {
  110. ULONG cchTemp = cchBuf;
  111. lr = g_pfGetUserNameEx(NameSamCompatible,ptszDomainAndUserName, &cchTemp);
  112. if (lr)
  113. {
  114. LPTSTR ptszWorker = ptszDomainAndUserName;
  115. while ( (TEXT('\0') != *ptszWorker) && *ptszWorker != TEXT('\\'))
  116. {
  117. ptszWorker++;
  118. }
  119. if ( TEXT('\0') != *ptszWorker)
  120. {
  121. *ptszWorker = ptszSeparator[0];
  122. }
  123. }
  124. }
  125. Assert(NULL != *ptszDomainAndUserName);
  126. return;
  127. }
  128. //+-------------------------------------------------------------------------------
  129. //
  130. // FUNCTION: BOOL ConvertString(LPTSTR pszOut, LPWSTR pwszIn, DWORD dwSize)
  131. //
  132. // PURPOSE: utility function for ANSI/UNICODE conversion
  133. //
  134. // RETURN VALUE: return TRUE if we process it ok.
  135. //
  136. //+-------------------------------------------------------------------------------
  137. BOOL ConvertString(char * pszOut, LPWSTR pwszIn, DWORD dwSize)
  138. {
  139. if(WideCharToMultiByte( CP_ACP,0,pwszIn,-1,pszOut,dwSize,NULL,NULL))
  140. {
  141. return TRUE;
  142. }
  143. return FALSE;
  144. }
  145. //+-------------------------------------------------------------------------------
  146. //
  147. // FUNCTION: BOOL ConvertString(LPWSTR pwszOut, LPTSTR pszIn, DWORD dwSize)
  148. //
  149. // PURPOSE: utility function for ANSI/UNICODE conversion
  150. //
  151. // RETURN VALUE: return TRUE if we process it ok.
  152. //
  153. //+-------------------------------------------------------------------------------
  154. BOOL ConvertString(LPWSTR pwszOut,char * pszIn, DWORD dwSize)
  155. {
  156. if(MultiByteToWideChar( CP_ACP,0,pszIn,-1,pwszOut,dwSize))
  157. {
  158. return TRUE;
  159. }
  160. return FALSE;
  161. }
  162. //+-------------------------------------------------------------------------------
  163. //
  164. // FUNCTION: Bogus function temporary until get transitioned to unicode
  165. // so I don't have to fix up every existing converstring call.
  166. //
  167. // PURPOSE: utility function for ANSI/UNICODE conversion
  168. //
  169. // RETURN VALUE: return TRUE if we process it ok.
  170. //
  171. //+-------------------------------------------------------------------------------
  172. BOOL ConvertString(LPWSTR pszOut, LPWSTR pwszIn, DWORD dwSize)
  173. {
  174. StrCpyN(pszOut, pwszIn, dwSize);
  175. return TRUE;
  176. }
  177. //
  178. // Local constants
  179. //
  180. // DEFAULT_TIME_FORMAT - what to use if there's a problem getting format
  181. // from system.
  182. //
  183. #define DEFAULT_TIME_FORMAT TEXT("hh:mm tt")
  184. #define GET_LOCALE_INFO(lcid) \
  185. { \
  186. cch = GetLocaleInfo(LOCALE_USER_DEFAULT, \
  187. (lcid), \
  188. tszScratch, \
  189. ARRAYLEN(tszScratch)); \
  190. if (!cch) \
  191. { \
  192. break; \
  193. } \
  194. }
  195. //+--------------------------------------------------------------------------
  196. //
  197. // Function: UpdateTimeFormat
  198. //
  199. // Synopsis: Construct a time format containing hour and minute for use
  200. // with the date picker control.
  201. //
  202. // Arguments: [tszTimeFormat] - buffer to fill with time format
  203. // [cchTimeFormat] - size in chars of buffer
  204. //
  205. // Modifies: *[tszTimeFormat]
  206. //
  207. // History: 11-18-1996 DavidMun Created
  208. //
  209. // Notes: This is called on initialization and for wininichange
  210. // processing.
  211. //
  212. //---------------------------------------------------------------------------
  213. void
  214. UpdateTimeFormat(
  215. LPTSTR tszTimeFormat,
  216. ULONG cchTimeFormat)
  217. {
  218. ULONG cch;
  219. TCHAR tszScratch[80] = {0};
  220. BOOL fAmPm = FALSE;
  221. BOOL fAmPmPrefixes = FALSE;
  222. BOOL fLeadingZero = FALSE;
  223. do
  224. {
  225. GET_LOCALE_INFO(LOCALE_ITIME);
  226. fAmPm = (*tszScratch == TEXT('0'));
  227. if (fAmPm)
  228. {
  229. GET_LOCALE_INFO(LOCALE_ITIMEMARKPOSN);
  230. fAmPmPrefixes = (*tszScratch == TEXT('1'));
  231. }
  232. GET_LOCALE_INFO(LOCALE_ITLZERO);
  233. fLeadingZero = (*tszScratch == TEXT('1'));
  234. GET_LOCALE_INFO(LOCALE_STIME);
  235. //
  236. // See if there's enough room in destination string
  237. //
  238. cch = 1 + // terminating nul
  239. 1 + // first hour digit specifier "h"
  240. 2 + // minutes specifier "mm"
  241. (fLeadingZero != 0) + // leading hour digit specifier "h"
  242. lstrlen(tszScratch) + // separator string
  243. (fAmPm ? 3 : 0); // space and "tt" for AM/PM
  244. if (cch > cchTimeFormat)
  245. {
  246. cch = 0; // signal error
  247. }
  248. } while (0);
  249. //
  250. // If there was a problem in getting locale info for building time string
  251. // just use the default and bail.
  252. //
  253. if (!cch)
  254. {
  255. StrCpyN(tszTimeFormat, DEFAULT_TIME_FORMAT, cchTimeFormat);
  256. return;
  257. }
  258. //
  259. // Build a time string that has hours and minutes but no seconds.
  260. //
  261. tszTimeFormat[0] = TEXT('\0');
  262. if (fAmPm)
  263. {
  264. if (fAmPmPrefixes)
  265. {
  266. StrCpyN(tszTimeFormat, TEXT("tt "), cchTimeFormat);
  267. }
  268. StrCatBuff(tszTimeFormat, TEXT("h"), cchTimeFormat);
  269. if (fLeadingZero)
  270. {
  271. StrCatBuff(tszTimeFormat, TEXT("h"), cchTimeFormat);
  272. }
  273. }
  274. else
  275. {
  276. StrCatBuff(tszTimeFormat, TEXT("H"), cchTimeFormat);
  277. if (fLeadingZero)
  278. {
  279. StrCatBuff(tszTimeFormat, TEXT("H"), cchTimeFormat);
  280. }
  281. }
  282. StrCatBuff(tszTimeFormat, tszScratch, cchTimeFormat); // separator
  283. StrCatBuff(tszTimeFormat, TEXT("mm"), cchTimeFormat);
  284. if (fAmPm && !fAmPmPrefixes)
  285. {
  286. StrCatBuff(tszTimeFormat, TEXT(" tt"), cchTimeFormat);
  287. }
  288. }
  289. //+--------------------------------------------------------------------------
  290. //
  291. // Function: FillInStartDateTime
  292. //
  293. // Synopsis: Fill [pTrigger]'s starting date and time values from the
  294. // values in the date/time picker controls.
  295. //
  296. // Arguments: [hwndDatePick] - handle to control with start date
  297. // [hwndTimePick] - handle to control with start time
  298. // [pTrigger] - trigger to init
  299. //
  300. // Modifies: *[pTrigger]
  301. //
  302. // History: 12-08-1997 SusiA Stole from task scheduler
  303. //
  304. //---------------------------------------------------------------------------
  305. VOID FillInStartDateTime( HWND hwndDatePick, HWND hwndTimePick,TASK_TRIGGER *pTrigger)
  306. {
  307. SYSTEMTIME st;
  308. DateTime_GetSystemtime(hwndDatePick, &st);
  309. pTrigger->wBeginYear = st.wYear;
  310. pTrigger->wBeginMonth = st.wMonth;
  311. pTrigger->wBeginDay = st.wDay;
  312. DateTime_GetSystemtime(hwndTimePick, &st);
  313. pTrigger->wStartHour = st.wHour;
  314. pTrigger->wStartMinute = st.wMinute;
  315. }
  316. //+---------------------------------------------------------------------------
  317. //
  318. // function: InsertListViewColumn, private
  319. //
  320. // Synopsis: Inserts a column into the ListView..
  321. //
  322. // Arguments:
  323. //
  324. // Returns:
  325. //
  326. // Modifies:
  327. //
  328. // History: 30-Jul-98 rogerg Created.
  329. //
  330. //----------------------------------------------------------------------------
  331. BOOL InsertListViewColumn(CListView *pListView,int iColumnId,LPWSTR pszText,int fmt,int cx)
  332. {
  333. LV_COLUMN columnInfo;
  334. columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
  335. columnInfo.fmt = fmt;
  336. columnInfo.cx = cx;
  337. columnInfo.pszText = pszText;
  338. columnInfo.iSubItem = 0;
  339. return pListView->InsertColumn(iColumnId,&columnInfo);
  340. }
  341. //+--------------------------------------------------------------------------
  342. //
  343. // Function: InitResizeItem
  344. //
  345. // Synopsis: Setups the ResizeInfo Structure.
  346. //
  347. // !!Can either pass in a ParentScreenRect or
  348. // function will calculate. If passing in
  349. // make sure you don't include the NC area
  350. // of the window. See code below GetClientRect on parent
  351. // then ClientToScreen.
  352. //
  353. // Arguments:
  354. //
  355. // Modifies:
  356. //
  357. // History: 30-07-1998 rogerg
  358. //
  359. //---------------------------------------------------------------------------
  360. BOOL InitResizeItem(int iCtrlId,DWORD dlgResizeFlags,HWND hwndParent,
  361. LPRECT pParentClientRect,DLGRESIZEINFO *pDlgResizeInfo)
  362. {
  363. RECT rectCtrl;
  364. RECT rectLocalParentScreenRect;
  365. Assert(pDlgResizeInfo);
  366. Assert(0 == pParentClientRect->left); // catch any case not handing in ClientRect.
  367. pDlgResizeInfo->iCtrlId = -1; // set ctrlId to -1 so GetDlgItem will fail in resize
  368. // if dont' have parentScreenRect get it ourselves
  369. if (!pParentClientRect)
  370. {
  371. pParentClientRect = &rectLocalParentScreenRect;
  372. if (!GetClientRect(hwndParent,&rectLocalParentScreenRect))
  373. {
  374. AssertSz(0,"Unable to get Parent Rects");
  375. return FALSE;
  376. }
  377. }
  378. Assert(pParentClientRect);
  379. if (!GetWindowRect(GetDlgItem(hwndParent,iCtrlId),&rectCtrl))
  380. {
  381. AssertSz(0,"Failed to GetWindowRect");
  382. return FALSE;
  383. }
  384. MapWindowPoints(NULL,hwndParent,(LPPOINT) &rectCtrl,2);
  385. pDlgResizeInfo->iCtrlId = iCtrlId;
  386. pDlgResizeInfo->hwndParent = hwndParent;
  387. pDlgResizeInfo->dlgResizeFlags = dlgResizeFlags;
  388. // calc the offsets
  389. pDlgResizeInfo->rectParentOffsets.left = rectCtrl.left - pParentClientRect->left;
  390. pDlgResizeInfo->rectParentOffsets.top = rectCtrl.top - pParentClientRect->top;
  391. pDlgResizeInfo->rectParentOffsets.right = pParentClientRect->right - rectCtrl.right;
  392. pDlgResizeInfo->rectParentOffsets.bottom = pParentClientRect->bottom - rectCtrl.bottom;
  393. return TRUE;
  394. }
  395. //+--------------------------------------------------------------------------
  396. //
  397. // Function: ResizeItems
  398. //
  399. // Synopsis: Resizes the Item.
  400. //
  401. //
  402. // Arguments:
  403. //
  404. // Modifies:
  405. //
  406. // History: 30-07-1998 rogerg
  407. //
  408. //---------------------------------------------------------------------------
  409. void ResizeItems(ULONG cbNumItems,DLGRESIZEINFO *pDlgResizeInfo)
  410. {
  411. RECT rectLocalParentClientCoord; // used if caller doesn't pass in parent coords.
  412. DWORD dlgResizeFlags;
  413. LPRECT prectOffsets;
  414. RECT rectClient;
  415. HWND hwndCtrl;
  416. HWND hwndLastParent = NULL;
  417. LPRECT prectParentClientCoords = NULL;
  418. ULONG ulCount;
  419. DLGRESIZEINFO *pCurDlgResizeInfo;
  420. int x,y,cx,cy;
  421. if (!pDlgResizeInfo)
  422. {
  423. Assert(pDlgResizeInfo);
  424. }
  425. for (ulCount = 0; ulCount < cbNumItems; ulCount++)
  426. {
  427. pCurDlgResizeInfo = &(pDlgResizeInfo[ulCount]);
  428. dlgResizeFlags = pCurDlgResizeInfo->dlgResizeFlags;
  429. prectOffsets = &(pCurDlgResizeInfo->rectParentOffsets);
  430. // if not pinright or pin bottom there is nothing
  431. // to do.
  432. if (!(dlgResizeFlags & DLGRESIZEFLAG_PINRIGHT) &&
  433. !(dlgResizeFlags & DLGRESIZEFLAG_PINBOTTOM) )
  434. {
  435. continue;
  436. }
  437. if (NULL == prectParentClientCoords || (hwndLastParent != pCurDlgResizeInfo->hwndParent))
  438. {
  439. prectParentClientCoords = &rectLocalParentClientCoord;
  440. if (!GetClientRect(pCurDlgResizeInfo->hwndParent,&rectLocalParentClientCoord))
  441. {
  442. prectParentClientCoords = NULL; // if GetClientRect failed for a recalc on next item
  443. continue;
  444. }
  445. hwndLastParent = pCurDlgResizeInfo->hwndParent; // set lastparent now that we calc'd the rect.
  446. }
  447. Assert(prectParentClientCoords);
  448. hwndCtrl = GetDlgItem(pCurDlgResizeInfo->hwndParent,pCurDlgResizeInfo->iCtrlId);
  449. if ( (NULL == hwndCtrl) || !(GetWindowRect(hwndCtrl,&rectClient)) )
  450. {
  451. continue;
  452. }
  453. // get current values
  454. x = (prectParentClientCoords->left + prectOffsets->left);
  455. y = (prectParentClientCoords->top + prectOffsets->top);
  456. cx = WIDTH(rectClient);
  457. cy = HEIGHT(rectClient);
  458. // if pinned both right and left adjust the width
  459. if ((dlgResizeFlags & DLGRESIZEFLAG_PINLEFT)
  460. && (dlgResizeFlags & DLGRESIZEFLAG_PINRIGHT))
  461. {
  462. cx = prectParentClientCoords->right - (prectOffsets->right + prectOffsets->left);
  463. }
  464. // if pinned both top and bottom adjust height
  465. if ((dlgResizeFlags & DLGRESIZEFLAG_PINTOP)
  466. && (dlgResizeFlags & DLGRESIZEFLAG_PINBOTTOM))
  467. {
  468. cy = prectParentClientCoords->bottom - (prectOffsets->bottom + prectOffsets->top);
  469. }
  470. // adjust the x position if pin right
  471. if (dlgResizeFlags & DLGRESIZEFLAG_PINRIGHT)
  472. {
  473. x = (prectParentClientCoords->right - prectOffsets->right) - cx;
  474. }
  475. // adjust the y position if pin bottom
  476. if (dlgResizeFlags & DLGRESIZEFLAG_PINBOTTOM)
  477. {
  478. y = (prectParentClientCoords->bottom - prectOffsets->bottom) - cy;
  479. }
  480. SetWindowPos(hwndCtrl, 0,x,y,cx,cy,SWP_NOZORDER | SWP_NOACTIVATE);
  481. }
  482. // now that the items are moved, loop through them again invalidating
  483. // any items with the nocopy bits flag set
  484. for (ulCount = 0; ulCount < cbNumItems; ulCount++)
  485. {
  486. pCurDlgResizeInfo = &(pDlgResizeInfo[ulCount]);
  487. if (pCurDlgResizeInfo->dlgResizeFlags & DLGRESIZEFLAG_NOCOPYBITS)
  488. {
  489. hwndCtrl = GetDlgItem(pCurDlgResizeInfo->hwndParent,pCurDlgResizeInfo->iCtrlId);
  490. if (hwndCtrl && GetClientRect(hwndCtrl,&rectClient))
  491. {
  492. InvalidateRect(hwndCtrl,&rectClient,FALSE);
  493. }
  494. }
  495. }
  496. }
  497. //+--------------------------------------------------------------------------
  498. //
  499. // Function: CalcListViewWidth
  500. //
  501. // Synopsis: Calcs width of listview - scroll bars
  502. //
  503. //
  504. // Arguments:
  505. //
  506. // Modifies:
  507. //
  508. // History: 30-07-1998 rogerg
  509. //
  510. //---------------------------------------------------------------------------
  511. int CalcListViewWidth(HWND hwndList,int iDefault)
  512. {
  513. NONCLIENTMETRICSA metrics;
  514. RECT rcClientRect;
  515. metrics.cbSize = sizeof(metrics);
  516. // explicitly ask for ANSI version of SystemParametersInfo since we just
  517. // care about the ScrollWidth and don't want to conver the LOGFONT info.
  518. if (GetClientRect(hwndList,&rcClientRect)
  519. && SystemParametersInfoA(SPI_GETNONCLIENTMETRICS,sizeof(metrics),(PVOID) &metrics,0))
  520. {
  521. // subtract off scroll bar distance
  522. rcClientRect.right -= (metrics.iScrollWidth);
  523. }
  524. else
  525. {
  526. rcClientRect.right = iDefault; // if fail, use default
  527. }
  528. return rcClientRect.right;
  529. }
  530. //+--------------------------------------------------------------------------
  531. //
  532. // Function: IsHwndRightToLeft
  533. //
  534. // Synopsis: determine if hwnd is right to left.
  535. //
  536. //
  537. // Arguments:
  538. //
  539. // Modifies:
  540. //
  541. // History: 04-02-1999 rogerg
  542. //
  543. //---------------------------------------------------------------------------
  544. BOOL IsHwndRightToLeft(HWND hwnd)
  545. {
  546. LONG_PTR ExStyles;
  547. if (NULL == hwnd)
  548. {
  549. Assert(hwnd);
  550. return FALSE;
  551. }
  552. ExStyles = GetWindowLongPtr(hwnd,GWL_EXSTYLE);
  553. if (WS_EX_LAYOUTRTL & ExStyles)
  554. {
  555. // this is righ to left
  556. return TRUE;
  557. }
  558. return FALSE;
  559. }
  560. //+--------------------------------------------------------------------------
  561. //
  562. // Function: GetDateFormatReadingFlags
  563. //
  564. // Synopsis: returns necessary flags settings for passing proper
  565. // Reading order flags to GetDateFormat()
  566. //
  567. //
  568. // Arguments:
  569. //
  570. // Modifies:
  571. //
  572. // History: 09-07-1999 rogerg
  573. //
  574. //---------------------------------------------------------------------------
  575. DWORD GetDateFormatReadingFlags(HWND hwnd)
  576. {
  577. DWORD dwDateReadingFlags = 0;
  578. LCID locale = GetUserDefaultLCID();
  579. // only set on NT 5.0 or higher.
  580. if ((PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_ARABIC)
  581. || (PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_HEBREW))
  582. {
  583. LONG_PTR dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
  584. if ((!!(dwExStyle & WS_EX_RTLREADING)) != (!!(dwExStyle & WS_EX_LAYOUTRTL)))
  585. {
  586. dwDateReadingFlags = DATE_RTLREADING;
  587. }
  588. else
  589. {
  590. dwDateReadingFlags = DATE_LTRREADING;
  591. }
  592. }
  593. return dwDateReadingFlags;
  594. }
  595. //+--------------------------------------------------------------------------
  596. //
  597. // Function: QueryHandleException
  598. //
  599. // Synopsis: in debug prompts user how to handle the exception
  600. // return always handle.
  601. //
  602. //
  603. // Arguments:
  604. //
  605. // Modifies:
  606. //
  607. // History: 01-04-1999 rogerg
  608. //
  609. //---------------------------------------------------------------------------
  610. extern DWORD g_dwDebugLogAsserts; // conform to logAsserts
  611. BOOL QueryHandleException(void)
  612. {
  613. #ifndef _DEBUG
  614. return EXCEPTION_EXECUTE_HANDLER;
  615. #else // _DEBUG
  616. int iMsgResult = 0;
  617. BOOL fQueryResult = EXCEPTION_EXECUTE_HANDLER;
  618. // if logging asserts just execute the handler
  619. if (g_dwDebugLogAsserts)
  620. {
  621. return EXCEPTION_EXECUTE_HANDLER;
  622. }
  623. iMsgResult = MessageBoxA(NULL,
  624. "An Exception Occured.\nWould you like to Debug this Exception?",
  625. "Exception Failure.",
  626. MB_YESNO | MB_SYSTEMMODAL);
  627. if (iMsgResult == IDYES)
  628. {
  629. fQueryResult = EXCEPTION_CONTINUE_SEARCH;
  630. }
  631. // ask the User what they want to do
  632. return fQueryResult;
  633. #endif // _DEBUG
  634. }
  635. // following are routines for calling sens service directly to write HKLM data
  636. // for us on a locked down machine
  637. #define _SENSCALLS
  638. #define _SENSINTERNAL
  639. #ifdef _SENSCALLS
  640. #include "notify.h"
  641. // may or may not need depending on if in sensapip.h
  642. DWORD SyncMgrExecCmd(DWORD nCmdID, DWORD nCmdOpt);
  643. typedef enum SYNCMGRCMDEXECID
  644. {
  645. SYNCMGRCMDEXECID_UPDATERUNKEY = 1,
  646. SYNCMGRCMDEXECID_RESETREGSECURITY = 2,
  647. } SYNCMGRCMDEXECID;
  648. #ifdef _SENSINTERNAL
  649. // functions for if want to call sens internal without
  650. // dependency on sensapip.lib
  651. // these defines are from Sens common.h
  652. #define SENS_PROTSEQ TEXT("ncalrpc")
  653. #define SENS_ENDPOINT TEXT("senssvc")
  654. RPC_STATUS GetSensNotifyBindHandle(RPC_BINDING_HANDLE *phSensNotify)
  655. {
  656. RPC_STATUS status = RPC_S_OK;
  657. WCHAR * BindingString = NULL;
  658. SID LocalSystem = { 1, 1, SECURITY_NT_AUTHORITY, SECURITY_LOCAL_SYSTEM_RID};
  659. RPC_SECURITY_QOS_V3 RpcSecQos;
  660. status = RpcStringBindingCompose(
  661. NULL, // NULL ObjUuid
  662. SENS_PROTSEQ,
  663. NULL, // Local machine
  664. SENS_ENDPOINT,
  665. NULL, // No Options
  666. &BindingString
  667. );
  668. if (BindingString != NULL)
  669. {
  670. *phSensNotify = NULL;
  671. status = RpcBindingFromStringBinding(BindingString,phSensNotify);
  672. RpcStringFree(&BindingString);
  673. if (RPC_S_OK == status)
  674. {
  675. RpcSecQos.Version= RPC_C_SECURITY_QOS_VERSION_3;
  676. RpcSecQos.ImpersonationType= RPC_C_IMP_LEVEL_IMPERSONATE;
  677. RpcSecQos.IdentityTracking= RPC_C_QOS_IDENTITY_DYNAMIC;
  678. RpcSecQos.Capabilities= RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH;
  679. RpcSecQos.AdditionalSecurityInfoType = 0;
  680. RpcSecQos.u.HttpCredentials = NULL;
  681. RpcSecQos.Sid = (PVOID)&LocalSystem;
  682. status= RpcBindingSetAuthInfoEx(*phSensNotify,
  683. NULL,
  684. RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  685. RPC_C_AUTHN_WINNT,
  686. NULL,
  687. RPC_C_AUTHZ_NONE,
  688. (RPC_SECURITY_QOS *)&RpcSecQos);
  689. if (RPC_S_OK != status)
  690. {
  691. RpcBindingFree(phSensNotify);
  692. *phSensNotify = NULL;
  693. }
  694. }
  695. }
  696. return (status);
  697. }
  698. RPC_STATUS SyncMgrExecCmdInternal(DWORD nCmdID, DWORD nCmdOpt)
  699. {
  700. RPC_STATUS status;
  701. RPC_BINDING_HANDLE hSensNotify;
  702. status = GetSensNotifyBindHandle(&hSensNotify);
  703. if (RPC_S_OK != status)
  704. {
  705. return status;
  706. }
  707. status = RPC_SyncMgrExecCmd(hSensNotify,nCmdID,nCmdOpt);
  708. RpcBindingFree(&hSensNotify);
  709. return status;
  710. }
  711. #endif // _SENSINTERNAL
  712. //+--------------------------------------------------------------------------
  713. //
  714. // Function: SyncMgrExecCmdp
  715. //
  716. // Synopsis: helper function that actually calls into sensapip.lib
  717. //
  718. //
  719. // Arguments:
  720. //
  721. // Modifies:
  722. //
  723. // History: 03-11-99 rogerg created
  724. //
  725. //---------------------------------------------------------------------------
  726. BOOL SyncMgrExecCmdp(DWORD nCmdID, DWORD nCmdOpt)
  727. {
  728. RPC_STATUS RpcStatus;
  729. HRESULT hr;
  730. BOOL fReturn = FALSE;
  731. __try
  732. {
  733. #ifdef _SENSINTERNAL
  734. RpcStatus = SyncMgrExecCmdInternal(nCmdID,nCmdOpt);
  735. #else
  736. RpcStatus = SyncMgrExecCmd(nCmdID,nCmdOpt);
  737. #endif // _SENSINTERNAL
  738. fReturn = (RPC_S_OK == RpcStatus ) ? TRUE: FALSE;
  739. }
  740. __except(QueryHandleException())
  741. {
  742. hr = HRESULT_FROM_WIN32(GetExceptionCode());
  743. AssertSz(0,"Exception Calling SensApip_SyncMgrExecCmd");
  744. }
  745. return fReturn;
  746. }
  747. #endif // _SENSCALLS
  748. //+--------------------------------------------------------------------------
  749. //
  750. // Function: SyncMgrExecCmd_UpdateRunKey
  751. //
  752. // Synopsis: Calls SENS Service to write or remove the run Key
  753. //
  754. //
  755. // Arguments:
  756. //
  757. // Modifies:
  758. //
  759. // History: 03-11-99 rogerg created
  760. //
  761. //---------------------------------------------------------------------------
  762. BOOL SyncMgrExecCmd_UpdateRunKey(BOOL fSet)
  763. {
  764. BOOL fReturn = FALSE;
  765. CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
  766. cCritSect.Enter(); // DoRpcSetup in Sensapip is not thread safe.
  767. #ifdef _SENSCALLS
  768. fReturn = SyncMgrExecCmdp(
  769. SYNCMGRCMDEXECID_UPDATERUNKEY,fSet ? 1 : 0);
  770. #endif // _SENSCALLS
  771. cCritSect.Leave();
  772. return fReturn;
  773. }
  774. //+--------------------------------------------------------------------------
  775. //
  776. // Function: SyncMgrExecCmd_ResetRegSecurity
  777. //
  778. // Synopsis: Calls SENS Service to reset the security on regkeys
  779. // to everyone.
  780. //
  781. //
  782. // Arguments:
  783. //
  784. // Modifies:
  785. //
  786. // History: 03-11-99 rogerg created
  787. //
  788. //---------------------------------------------------------------------------
  789. BOOL SyncMgrExecCmd_ResetRegSecurity(void)
  790. {
  791. BOOL fReturn = FALSE;
  792. CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
  793. cCritSect.Enter(); // DoRpcSetup in Sensapip is not thread safe.
  794. #ifdef _SENSCALLS
  795. fReturn = SyncMgrExecCmdp(SYNCMGRCMDEXECID_RESETREGSECURITY,0);
  796. #endif // _SENSCALLS
  797. cCritSect.Leave();
  798. return fReturn;
  799. }
  800. //+---------------------------------------------------------------------------
  801. //
  802. // Function: GetUserTextualSid
  803. //
  804. // Synopsis: Get a user SID and convert to its string representation
  805. //
  806. //----------------------------------------------------------------------------
  807. BOOL
  808. GetUserTextualSid(
  809. LPTSTR pszSidText, // buffer for Textual representaion of Sid
  810. DWORD cchSidText // provided pszSidText buffersize
  811. )
  812. {
  813. // Get user's SID from current process token
  814. HANDLE hToken;
  815. BOOL bResult = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
  816. if (bResult)
  817. {
  818. BYTE buf[MAX_PATH];
  819. PTOKEN_USER pTokenInfo = (PTOKEN_USER)buf;
  820. DWORD cbTokenInfo = sizeof (buf);
  821. bResult = GetTokenInformation(hToken, TokenUser, pTokenInfo, cbTokenInfo, &cbTokenInfo);
  822. if (bResult)
  823. {
  824. PSID pSid = pTokenInfo->User.Sid;
  825. if (pSid && IsValidSid(pSid))
  826. {
  827. // Convert the SID to a string
  828. LPWSTR pszTempSid;
  829. bResult = ConvertSidToStringSidW(pSid, &pszTempSid);
  830. if (bResult)
  831. {
  832. if (FAILED(StringCchCopy(pszSidText, cchSidText, pszTempSid)))
  833. {
  834. bResult = FALSE;
  835. }
  836. LocalFree(pszTempSid);
  837. }
  838. }
  839. else
  840. {
  841. bResult = FALSE;
  842. }
  843. }
  844. CloseHandle(hToken);
  845. }
  846. return bResult;
  847. }