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.

552 lines
16 KiB

  1. /***************************************************************************\
  2. *
  3. * File: OSAL.cpp
  4. *
  5. * Description:
  6. * OSAL.cpp implements the process-wide Operating System Abstraction Layer
  7. * that allows DirectUser to run on different platforms.
  8. *
  9. *
  10. * History:
  11. * 1/18/2000: JStall: Created
  12. *
  13. * Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
  14. *
  15. \***************************************************************************/
  16. #include "stdafx.h"
  17. #include "Services.h"
  18. #include "OSAL.h"
  19. #define ENABLE_WINNT 1
  20. /***************************************************************************\
  21. *****************************************************************************
  22. *
  23. * Define OSAL's for different operating systems.
  24. *
  25. *****************************************************************************
  26. \***************************************************************************/
  27. #if ENABLE_WINNT
  28. //------------------------------------------------------------------------------
  29. class WinNT : public OSAL
  30. {
  31. // USER Operations
  32. public:
  33. virtual int DrawText(HDC hDC, LPCWSTR lpString, int nCount, LPRECT lpRect, UINT uFormat);
  34. // GDI Operations
  35. public:
  36. virtual BOOL TextOut(HDC, int, int, LPCWSTR, int);
  37. virtual BOOL ExtTextOut(HDC, int, int, UINT, const RECT *, LPCWSTR, int, const int *);
  38. virtual HFONT CreateFontIndirect(CONST LOGFONTW *);
  39. virtual BOOL GetTextExtentPoint32(HDC, LPCWSTR, int, LPSIZE);
  40. virtual BOOL GetTextExtentExPoint(HDC, LPCWSTR, int, int, LPINT, LPINT, LPSIZE);
  41. // DirectUser/Core
  42. public:
  43. virtual void PushXForm(HDC hdc, XFORM * pxfOld);
  44. virtual void PopXForm(HDC hdc, const XFORM * pxfOld);
  45. virtual void RotateDC(HDC hdc, float flRotationRad);
  46. virtual void ScaleDC(HDC hdc, float flScaleX, float flScaleY);
  47. virtual void TranslateDC(HDC hdc, float flOffsetX, float flOffsetY);
  48. virtual void SetWorldTransform(HDC hdc, const XFORM * pxfOld);
  49. virtual void SetIdentityTransform(HDC hdc);
  50. // DirectUser/Services
  51. public:
  52. virtual BOOL IsInsideLoaderLock();
  53. };
  54. #endif
  55. //------------------------------------------------------------------------------
  56. class Win9x : public OSAL
  57. {
  58. // USER Operations
  59. public:
  60. virtual int DrawText(HDC hDC, LPCWSTR lpString, int nCount, LPRECT lpRect, UINT uFormat);
  61. // GDI Operations
  62. public:
  63. virtual BOOL TextOut(HDC, int, int, LPCWSTR, int);
  64. virtual BOOL ExtTextOut(HDC, int, int, UINT, const RECT *, LPCWSTR, int, const int *);
  65. virtual HFONT CreateFontIndirect(CONST LOGFONTW *);
  66. virtual BOOL GetTextExtentPoint32(HDC, LPCWSTR, int, LPSIZE);
  67. virtual BOOL GetTextExtentExPoint(HDC, LPCWSTR, int, int, LPINT, LPINT, LPSIZE);
  68. // DirectUser/Core
  69. public:
  70. virtual void PushXForm(HDC hdc, XFORM * pxfOld);
  71. virtual void PopXForm(HDC hdc, const XFORM * pxfOld);
  72. virtual void RotateDC(HDC hdc, float flRotationRad);
  73. virtual void ScaleDC(HDC hdc, float flScaleX, float flScaleY);
  74. virtual void TranslateDC(HDC hdc, float flOffsetX, float flOffsetY);
  75. virtual void SetWorldTransform(HDC hdc, const XFORM * pxfOld);
  76. virtual void SetIdentityTransform(HDC hdc);
  77. // DirectUser/Services
  78. public:
  79. virtual BOOL IsInsideLoaderLock();
  80. };
  81. /***************************************************************************\
  82. *****************************************************************************
  83. *
  84. * String Conversion Macros
  85. *
  86. * These macros are extensions of the normal ATLCONV that are designed to
  87. * take the length of the string as a parameter instead of computing it.
  88. * This gives better performance, and gives parity on platforms when the
  89. * string has embedded '\0's.
  90. *
  91. *****************************************************************************
  92. \***************************************************************************/
  93. #ifdef _CONVERSION_USES_THREAD_LOCALE
  94. #define W2AN(lpw, cch) (\
  95. ((_lpw = lpw) == NULL) ? NULL : (\
  96. _convert = (cch+1)*2,\
  97. ATLW2AHELPER((LPSTR) alloca(_convert), _lpw, _convert, _acp)))
  98. #else
  99. #define W2AN(lpw, cch) (\
  100. ((_lpw = lpw) == NULL) ? NULL : (\
  101. _convert = (cch+1)*2,\
  102. ATLW2AHELPER((LPSTR) alloca(_convert), _lpw, _convert)))
  103. #endif
  104. /***************************************************************************\
  105. *****************************************************************************
  106. *
  107. * class OSAL
  108. *
  109. *****************************************************************************
  110. \***************************************************************************/
  111. OSAL * g_pOS = NULL;
  112. OSInfo g_OSI;
  113. PTOP_LEVEL_EXCEPTION_FILTER g_pfnRtlUnhandledExceptionFilter = NULL;
  114. PRTL_IS_THREAD_WITHIN_LOADER_CALLOUT g_pfnRtlIsThreadWithinLoaderCallout = NULL;
  115. class OSALCleanup
  116. {
  117. public:
  118. ~OSALCleanup()
  119. {
  120. ProcessDelete(OSAL, g_pOS);
  121. g_pOS = NULL;
  122. };
  123. } g_OSALCleanup;
  124. //------------------------------------------------------------------------------
  125. HRESULT
  126. OSAL::Init()
  127. {
  128. AssertMsg(g_pOS == NULL, "Only init one time");
  129. OSVERSIONINFO ovi;
  130. ZeroMemory(&ovi, sizeof(ovi));
  131. ovi.dwOSVersionInfoSize = sizeof(ovi);
  132. VerifyMsg(GetVersionEx(&ovi), "Must always be able to get the version");
  133. g_OSI.fQInputAvailableFlag = IsWin98orWin2000(&ovi);
  134. #if ENABLE_WINNT
  135. if (ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
  136. //
  137. // Running on Win9x, so don't have UNICODE
  138. //
  139. g_OSI.fUnicode = FALSE;
  140. g_OSI.fXForm = FALSE;
  141. g_pOS = ProcessNew(Win9x);
  142. } else if (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
  143. //
  144. // Running on NT, so have UNICODE
  145. //
  146. g_OSI.fUnicode = TRUE;
  147. g_OSI.fXForm = TRUE;
  148. g_pOS = ProcessNew(WinNT);
  149. HINSTANCE hinst = LoadLibrary("ntdll.dll");
  150. if (hinst != NULL) {
  151. g_pfnRtlUnhandledExceptionFilter = (PTOP_LEVEL_EXCEPTION_FILTER)
  152. GetProcAddress(hinst, "RtlUnhandledExceptionFilter");
  153. g_pfnRtlIsThreadWithinLoaderCallout =
  154. (PRTL_IS_THREAD_WITHIN_LOADER_CALLOUT)GetProcAddress(hinst, "RtlIsThreadWithinLoaderCallout");
  155. }
  156. } else {
  157. AssertMsg(0, "Unsupported OS");
  158. return E_NOTIMPL;
  159. }
  160. #else // ENABLE_WINNT
  161. g_OSI.fUnicode = FALSE;
  162. g_OSI.fXForm = FALSE;
  163. g_pOS = ProcessNew(Win9x);
  164. #endif // ENABLE_WINNT
  165. return g_pOS != NULL ? S_OK : E_OUTOFMEMORY;
  166. }
  167. //------------------------------------------------------------------------------
  168. LONG WINAPI
  169. StdExceptionFilter(PEXCEPTION_POINTERS pei)
  170. {
  171. AutoTrace("ERROR: Unhandled exception during callback.\n");
  172. AutoTrace("ERROR: This is not a problem with DirectUser.\n");
  173. //
  174. // Output Exception information
  175. //
  176. LONG nResult;
  177. if (g_pfnRtlUnhandledExceptionFilter != NULL) {
  178. nResult = (g_pfnRtlUnhandledExceptionFilter)(pei);
  179. } else {
  180. AutoTrace(" *** enter .exr %p for the exception record\n", pei->ExceptionRecord);
  181. AutoTrace(" *** enter .cxr %p for the context\n", pei->ContextRecord);
  182. nResult = EXCEPTION_CONTINUE_SEARCH;
  183. }
  184. if (nResult == EXCEPTION_CONTINUE_SEARCH) {
  185. return UnhandledExceptionFilter(pei);
  186. } else {
  187. return nResult;
  188. }
  189. }
  190. /***************************************************************************\
  191. *****************************************************************************
  192. *
  193. * class WinNT
  194. *
  195. *****************************************************************************
  196. \***************************************************************************/
  197. #if ENABLE_WINNT
  198. //------------------------------------------------------------------------------
  199. int
  200. WinNT::DrawText(HDC hDC, LPCWSTR lpString, int nCount, LPRECT lpRect, UINT uFormat)
  201. {
  202. return ::DrawTextW(hDC, lpString, nCount, lpRect, uFormat);
  203. }
  204. //------------------------------------------------------------------------------
  205. BOOL
  206. WinNT::TextOut(HDC hdc, int x, int y, LPCWSTR psz, int cch)
  207. {
  208. return ::TextOutW(hdc, x, y, psz, cch);
  209. }
  210. //------------------------------------------------------------------------------
  211. BOOL
  212. WinNT::ExtTextOut(HDC hdc, int x, int y, UINT fuOptions, const RECT * prc, LPCWSTR psz, int cch, const int * pDx)
  213. {
  214. return ::ExtTextOutW(hdc, x, y, fuOptions, prc, psz, cch, pDx);
  215. }
  216. //------------------------------------------------------------------------------
  217. HFONT
  218. WinNT::CreateFontIndirect(CONST LOGFONTW * plf)
  219. {
  220. return ::CreateFontIndirectW(plf);
  221. }
  222. //------------------------------------------------------------------------------
  223. BOOL
  224. WinNT::GetTextExtentPoint32(HDC hdc, LPCWSTR psz, int cch, LPSIZE psize)
  225. {
  226. return ::GetTextExtentPoint32W(hdc, psz, cch, psize);
  227. }
  228. //------------------------------------------------------------------------------
  229. BOOL
  230. WinNT::GetTextExtentExPoint(HDC hdc, LPCWSTR psz, int cch, int nMax,
  231. LPINT pnFit, LPINT apDx, LPSIZE psize)
  232. {
  233. return ::GetTextExtentExPointW(hdc, psz, cch, nMax, pnFit, apDx, psize);
  234. }
  235. //------------------------------------------------------------------------------
  236. void
  237. WinNT::PushXForm(HDC hdc, XFORM * pxfOld)
  238. {
  239. ::GetWorldTransform(hdc, pxfOld);
  240. }
  241. //------------------------------------------------------------------------------
  242. void
  243. WinNT::PopXForm(HDC hdc, const XFORM * pxfOld)
  244. {
  245. ::SetWorldTransform(hdc, pxfOld);
  246. }
  247. //------------------------------------------------------------------------------
  248. void
  249. WinNT::RotateDC(HDC hdc, float flRotationRad)
  250. {
  251. AssertMsg(GetGraphicsMode(hdc) == GM_ADVANCED, "Only can do in advanced mode");
  252. float flCos = (float) cos(flRotationRad);
  253. float flSin = (float) sin(flRotationRad);
  254. XFORM xf;
  255. xf.eM11 = flCos;
  256. xf.eM12 = flSin;
  257. xf.eM21 = - flSin;
  258. xf.eM22 = flCos;
  259. xf.eDx = 0;
  260. xf.eDy = 0;
  261. ::ModifyWorldTransform(hdc, &xf, MWT_LEFTMULTIPLY);
  262. }
  263. //------------------------------------------------------------------------------
  264. void
  265. WinNT::ScaleDC(HDC hdc, float flScaleX, float flScaleY)
  266. {
  267. AssertMsg(GetGraphicsMode(hdc) == GM_ADVANCED, "Only can do in advanced mode");
  268. XFORM xf;
  269. xf.eM11 = flScaleX;
  270. xf.eM12 = 0;
  271. xf.eM21 = 0;
  272. xf.eM22 = flScaleY;
  273. xf.eDx = 0;
  274. xf.eDy = 0;
  275. ::ModifyWorldTransform(hdc, &xf, MWT_LEFTMULTIPLY);
  276. }
  277. //------------------------------------------------------------------------------
  278. void
  279. WinNT::TranslateDC(HDC hdc, float flOffsetX, float flOffsetY)
  280. {
  281. AssertMsg(GetGraphicsMode(hdc) == GM_ADVANCED, "Only can do in advanced mode");
  282. XFORM xf;
  283. xf.eM11 = 1.0;
  284. xf.eM12 = 0;
  285. xf.eM21 = 0;
  286. xf.eM22 = 1.0;
  287. xf.eDx = flOffsetX;
  288. xf.eDy = flOffsetY;
  289. ::ModifyWorldTransform(hdc, &xf, MWT_LEFTMULTIPLY);
  290. }
  291. //------------------------------------------------------------------------------
  292. void
  293. WinNT::SetWorldTransform(HDC hdc, const XFORM * pxf)
  294. {
  295. ::SetWorldTransform(hdc, pxf);
  296. }
  297. //------------------------------------------------------------------------------
  298. void
  299. WinNT::SetIdentityTransform(HDC hdc)
  300. {
  301. ModifyWorldTransform(hdc, NULL, MWT_IDENTITY);
  302. }
  303. //------------------------------------------------------------------------------
  304. BOOL
  305. WinNT::IsInsideLoaderLock()
  306. {
  307. if (g_pfnRtlIsThreadWithinLoaderCallout != NULL) {
  308. return (*g_pfnRtlIsThreadWithinLoaderCallout)() ? TRUE : FALSE;
  309. } else {
  310. PRTL_CRITICAL_SECTION pCS;
  311. /*
  312. * If we failed to find this export, then fallback to our bogus, XP
  313. * behavior where we explicitly check the loader lock.
  314. */
  315. pCS = reinterpret_cast<PRTL_CRITICAL_SECTION>(NtCurrentPeb()->LoaderLock);
  316. return (HandleToUlong(pCS->OwningThread) == GetCurrentThreadId());
  317. }
  318. }
  319. #endif // ENABLE_WINNT
  320. /***************************************************************************\
  321. *****************************************************************************
  322. *
  323. * class Win9x
  324. *
  325. *****************************************************************************
  326. \***************************************************************************/
  327. //------------------------------------------------------------------------------
  328. int
  329. Win9x::DrawText(HDC hDC, LPCWSTR lpString, int nCount, LPRECT lpRect, UINT uFormat)
  330. {
  331. USES_CONVERSION;
  332. return ::DrawTextA(hDC, W2AN(lpString, nCount), nCount, lpRect, uFormat);
  333. }
  334. //------------------------------------------------------------------------------
  335. BOOL
  336. Win9x::TextOut(HDC hdc, int x, int y, LPCWSTR psz, int cch)
  337. {
  338. return ::TextOutW(hdc, x, y, psz, cch);
  339. }
  340. //------------------------------------------------------------------------------
  341. BOOL
  342. Win9x::ExtTextOut(HDC hdc, int x, int y, UINT fuOptions, const RECT * prc, LPCWSTR psz, int cch, const int * pDx)
  343. {
  344. return ::ExtTextOutW(hdc, x, y, fuOptions, prc, psz, cch, pDx);
  345. }
  346. //------------------------------------------------------------------------------
  347. HFONT
  348. Win9x::CreateFontIndirect(CONST LOGFONTW * plf)
  349. {
  350. USES_CONVERSION;
  351. LOGFONT lf;
  352. lf.lfHeight = plf->lfHeight;
  353. lf.lfWidth = plf->lfWidth;
  354. lf.lfEscapement = plf->lfEscapement;
  355. lf.lfOrientation = plf->lfOrientation;
  356. lf.lfWeight = plf->lfWeight;
  357. lf.lfItalic = plf->lfItalic;
  358. lf.lfUnderline = plf->lfUnderline;
  359. lf.lfStrikeOut = plf->lfStrikeOut;
  360. lf.lfCharSet = plf->lfCharSet;
  361. lf.lfOutPrecision = plf->lfOutPrecision;
  362. lf.lfClipPrecision = plf->lfClipPrecision;
  363. lf.lfQuality = plf->lfQuality;
  364. lf.lfPitchAndFamily = plf->lfPitchAndFamily;
  365. AtlW2AHelper(lf.lfFaceName, plf->lfFaceName, lstrlenW(plf->lfFaceName) + 1);
  366. return ::CreateFontIndirectA(&lf);
  367. }
  368. //------------------------------------------------------------------------------
  369. BOOL
  370. Win9x::GetTextExtentPoint32(HDC hdc, LPCWSTR psz, int cch, LPSIZE psize)
  371. {
  372. USES_CONVERSION;
  373. return ::GetTextExtentPoint32A(hdc, W2AN(psz, cch), cch, psize);
  374. }
  375. //------------------------------------------------------------------------------
  376. BOOL
  377. Win9x::GetTextExtentExPoint(HDC hdc, LPCWSTR psz, int cch, int nMax,
  378. LPINT pnFit, LPINT apDx, LPSIZE psize)
  379. {
  380. USES_CONVERSION;
  381. return ::GetTextExtentExPointA(hdc, W2AN(psz, cch), cch, nMax, pnFit, apDx, psize);
  382. }
  383. //------------------------------------------------------------------------------
  384. void
  385. Win9x::PushXForm(HDC hdc, XFORM * pxfOld)
  386. {
  387. POINT pt;
  388. ::GetWindowOrgEx(hdc, &pt);
  389. pxfOld->eM11 = 1.0f;
  390. pxfOld->eM12 = 0.0f;
  391. pxfOld->eM21 = 0.0f;
  392. pxfOld->eM22 = 1.0f;
  393. pxfOld->eDx = (float) pt.x;
  394. pxfOld->eDy = (float) pt.y;
  395. }
  396. //------------------------------------------------------------------------------
  397. void
  398. Win9x::PopXForm(HDC hdc, const XFORM * pxfOld)
  399. {
  400. POINT pt;
  401. pt.x = (long) pxfOld->eDx;
  402. pt.y = (long) pxfOld->eDy;
  403. ::SetWindowOrgEx(hdc, pt.x, pt.y, NULL);
  404. }
  405. //------------------------------------------------------------------------------
  406. void
  407. Win9x::RotateDC(HDC hdc, float flRotationRad)
  408. {
  409. UNREFERENCED_PARAMETER(hdc);
  410. UNREFERENCED_PARAMETER(flRotationRad);
  411. }
  412. //------------------------------------------------------------------------------
  413. void
  414. Win9x::ScaleDC(HDC hdc, float flScaleX, float flScaleY)
  415. {
  416. UNREFERENCED_PARAMETER(hdc);
  417. UNREFERENCED_PARAMETER(flScaleX);
  418. UNREFERENCED_PARAMETER(flScaleY);
  419. }
  420. //------------------------------------------------------------------------------
  421. void
  422. Win9x::TranslateDC(HDC hdc, float flOffsetX, float flOffsetY)
  423. {
  424. ::OffsetWindowOrgEx(hdc, -(int) flOffsetX, -(int) flOffsetY, NULL);
  425. }
  426. //------------------------------------------------------------------------------
  427. void
  428. Win9x::SetWorldTransform(HDC hdc, const XFORM * pxf)
  429. {
  430. ::SetWindowOrgEx(hdc, -(int) pxf->eDx, -(int) pxf->eDy, NULL);
  431. }
  432. //------------------------------------------------------------------------------
  433. void
  434. Win9x::SetIdentityTransform(HDC hdc)
  435. {
  436. ::SetWindowOrgEx(hdc, 0, 0, NULL);
  437. }
  438. //------------------------------------------------------------------------------
  439. BOOL
  440. Win9x::IsInsideLoaderLock()
  441. {
  442. return FALSE;
  443. }