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.

770 lines
23 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: surfddi.cxx
  3. *
  4. * Surface DDI callback routines
  5. *
  6. * Created: 23-Aug-1990
  7. * Author: Greg Veres [w-gregv]
  8. *
  9. * Copyright (c) 1990-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.hxx"
  12. /******************************Public*Routine******************************\
  13. * EngMarkBandingSurface
  14. *
  15. * DDI entry point to mark a surface as a banding surface meaning we should
  16. * capture all output to it in a metafile.
  17. *
  18. * History:
  19. * 10-Mar-1993 -by- Patrick Haluptzok patrickh
  20. * Wrote it.
  21. \**************************************************************************/
  22. BOOL EngMarkBandingSurface(HSURF hsurf)
  23. {
  24. SURFREF so;
  25. so.vAltCheckLockIgnoreStockBit(hsurf);
  26. ASSERTGDI(so.bValid(), "ERROR EngMarkBandingSurfae invalid HSURF passed in\n");
  27. so.ps->vSetBanding();
  28. return(TRUE);
  29. }
  30. /******************************Public*Routine******************************\
  31. * hbmCreateDriverSurface
  32. *
  33. * Common entry point for creating DDI surfaces.
  34. *
  35. * History:
  36. * 11-Feb-1991 -by- Patrick Haluptzok patrickh
  37. * Wrote it.
  38. \**************************************************************************/
  39. HBITMAP hbmCreateDriverSurface(ULONG iType, DHSURF dhsurf, SIZEL sizl, LONG lWidth,
  40. ULONG iFormat, FLONG fl, PVOID pvBits)
  41. {
  42. DEVBITMAPINFO dbmi;
  43. ULONG cjWidth = (ULONG) lWidth;
  44. dbmi.iFormat = iFormat & ~UMPD_FLAG;
  45. dbmi.cxBitmap = sizl.cx;
  46. dbmi.cyBitmap = sizl.cy;
  47. dbmi.hpal = (HPALETTE) 0;
  48. dbmi.fl = fl;
  49. //
  50. // convert from bytes to pels if given a buffer and cjWidth. If either
  51. // of these are set to 0 use what DIBMEMOBJ computes.
  52. //
  53. if ((pvBits) && (cjWidth))
  54. {
  55. switch (dbmi.iFormat)
  56. {
  57. case BMF_1BPP:
  58. dbmi.cxBitmap = cjWidth * 8;
  59. break;
  60. case BMF_4BPP:
  61. dbmi.cxBitmap = cjWidth * 2;
  62. break;
  63. case BMF_8BPP:
  64. dbmi.cxBitmap = cjWidth;
  65. break;
  66. case BMF_16BPP:
  67. dbmi.cxBitmap = cjWidth / 2;
  68. break;
  69. case BMF_24BPP:
  70. dbmi.cxBitmap = cjWidth / 3;
  71. break;
  72. case BMF_32BPP:
  73. dbmi.cxBitmap = cjWidth / 4;
  74. break;
  75. }
  76. }
  77. SURFMEM SurfDimo;
  78. SurfDimo.bCreateDIB(&dbmi, pvBits);
  79. if (!SurfDimo.bValid())
  80. {
  81. //
  82. // Constructor logs error code.
  83. //
  84. return((HBITMAP) 0);
  85. }
  86. //
  87. // We have to mark the surface with a special flag indicating it was
  88. // created via EngCreateDeviceBitmap, instead of just looking for
  89. // STYPE_DEVBITMAP, because EngModifySurface can change the type to
  90. // STYPE_BITMAP yet we still want to cleanup the surface by calling
  91. // DrvDeleteDeviceBitmap.
  92. //
  93. if (iType == STYPE_DEVBITMAP)
  94. {
  95. SurfDimo.ps->vSetEngCreateDeviceBitmap();
  96. }
  97. if (iType != STYPE_BITMAP)
  98. {
  99. SurfDimo.ps->lDelta(0);
  100. SurfDimo.ps->pvScan0(NULL);
  101. SurfDimo.ps->pvBits(NULL);
  102. }
  103. SurfDimo.ps->vSetDriverCreated();
  104. SurfDimo.ps->sizl(sizl);
  105. SurfDimo.ps->dhsurf(dhsurf);
  106. SurfDimo.ps->iType(iType);
  107. SurfDimo.vKeepIt();
  108. //
  109. // charge the surface from umpd driver against the process
  110. // so we can clean it up afterwards
  111. //
  112. if (!(iFormat & UMPD_FLAG))
  113. SurfDimo.vSetPID(OBJECT_OWNER_PUBLIC);
  114. else
  115. SurfDimo.ps->vSetUMPD();
  116. return((HBITMAP) SurfDimo.ps->hsurf());
  117. }
  118. /******************************Public*Routine******************************\
  119. * EngCreateBitmap
  120. *
  121. * DDI entry point to create a engine bitmap surface.
  122. *
  123. * History:
  124. * 11-Feb-1991 -by- Patrick Haluptzok patrickh
  125. * Wrote it.
  126. \**************************************************************************/
  127. HBITMAP EngCreateBitmap(SIZEL sizl, LONG lWidth, ULONG iFormat, FLONG fl, PVOID pvBits)
  128. {
  129. return(hbmCreateDriverSurface(STYPE_BITMAP, NULL, sizl, lWidth, iFormat,
  130. fl, pvBits));
  131. }
  132. /******************************Public*Routine******************************\
  133. * EngCreateDeviceBitmap
  134. *
  135. * DDI entry point to create device managed bitmap.
  136. *
  137. * History:
  138. * 10-Mar-1993 -by- Patrick Haluptzok patrickh
  139. * Wrote it.
  140. \**************************************************************************/
  141. HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL sizl, ULONG iFormat)
  142. {
  143. return(hbmCreateDriverSurface(STYPE_DEVBITMAP, dhsurf, sizl, 0, iFormat,
  144. 0, (PVOID)UIntToPtr( 0xdeadbeef )));
  145. }
  146. /******************************Public*Routine******************************\
  147. * EngCreateDeviceSurface
  148. *
  149. * DDI entry point to create device managed bitmap.
  150. *
  151. * History:
  152. * 10-Mar-1993 -by- Patrick Haluptzok patrickh
  153. * Wrote it.
  154. \**************************************************************************/
  155. HSURF EngCreateDeviceSurface(DHSURF dhsurf, SIZEL sizl, ULONG iFormat)
  156. {
  157. //
  158. // [NT 4.0 compatible]
  159. //
  160. // EngCreateDeviceSurface in NT4, does not fail with invalid iFormat
  161. // (especially 0, Adobe Acrobat 3.01 - PDFKD.DLL calls with 0 at least).
  162. // So we replace the wrong data with something valid, here.
  163. //
  164. switch (iFormat & ~UMPD_FLAG)
  165. {
  166. case BMF_1BPP:
  167. case BMF_4BPP:
  168. case BMF_8BPP:
  169. case BMF_16BPP:
  170. case BMF_24BPP:
  171. case BMF_32BPP:
  172. break;
  173. default:
  174. //
  175. // UMPD_FLAG should be preserved.
  176. //
  177. iFormat = (iFormat & UMPD_FLAG) | BMF_1BPP;
  178. }
  179. return((HSURF) hbmCreateDriverSurface(STYPE_DEVICE, dhsurf, sizl, 0,
  180. iFormat, 0, (PVOID)UIntToPtr( 0xdeadbeef )));
  181. }
  182. /******************************Public*Routine******************************\
  183. * EngDeleteSurface
  184. *
  185. * DDI entry point to delete a surface.
  186. *
  187. * History:
  188. * Thu 12-Mar-1992 -by- Patrick Haluptzok [patrickh]
  189. * change to bool return.
  190. *
  191. * 11-Feb-1991 -by- Patrick Haluptzok patrickh
  192. * Wrote it.
  193. \**************************************************************************/
  194. BOOL EngDeleteSurface(HSURF hsurf)
  195. {
  196. BOOL bReturn = TRUE;
  197. if (hsurf != 0)
  198. {
  199. bReturn = bDeleteSurface(hsurf);
  200. }
  201. ASSERTGDI(bReturn, "ERROR EngDeleteSurface failed");
  202. return(bReturn);
  203. }
  204. /******************************Public*Routine******************************\
  205. * EngLockSurface
  206. *
  207. * DDI entry point to lock down a surface handle.
  208. *
  209. * History:
  210. * Thu 27-Aug-1992 -by- Patrick Haluptzok [patrickh]
  211. * Remove SURFOBJ accelerator allocation.
  212. *
  213. * 11-Feb-1991 -by- Patrick Haluptzok patrickh
  214. * Wrote it.
  215. \**************************************************************************/
  216. SURFOBJ *EngLockSurface(HSURF hsurf)
  217. {
  218. SURFREF so;
  219. so.vAltCheckLockIgnoreStockBit(hsurf);
  220. if (so.bValid())
  221. {
  222. so.vKeepIt();
  223. return(so.pSurfobj());
  224. }
  225. else
  226. {
  227. WARNING("EngLockSurface failed to lock handle\n");
  228. return((SURFOBJ *) NULL);
  229. }
  230. }
  231. /******************************Public*Routine******************************\
  232. * EngUnlockSurface
  233. *
  234. * DDI entry point to unlock a surface that has been locked
  235. * with EngLockSurface.
  236. *
  237. * History:
  238. * Thu 27-Aug-1992 -by- Patrick Haluptzok [patrickh]
  239. * Remove SURFOBJ accelerator allocation.
  240. *
  241. * 11-Feb-1991 -by- Patrick Haluptzok patrickh
  242. * Wrote it.
  243. \**************************************************************************/
  244. VOID EngUnlockSurface(SURFOBJ *pso)
  245. {
  246. if (pso != (SURFOBJ *) NULL)
  247. {
  248. SURFACE *ps = SURFOBJ_TO_SURFACE_NOT_NULL(pso);
  249. if (ps == HmgReferenceCheckLock((HOBJ)pso->hsurf,SURF_TYPE,FALSE))
  250. {
  251. SURFREF su(pso);
  252. su.vUnreference();
  253. }
  254. }
  255. }
  256. #if DBG
  257. BOOL PanCopyBits(SURFOBJ*, SURFOBJ*, CLIPOBJ*, XLATEOBJ*, RECTL*, POINTL*);
  258. VOID vAssertValidHookFlags(PDEVOBJ *pdo, SURFREF *pso)
  259. {
  260. FLONG flHooks;
  261. flHooks = pso->ps->flags();
  262. //
  263. // Check to make sure we haven't disabled h/w accelerations and are now
  264. // using the panning driver (unaccelerated driver).
  265. //
  266. if(PPFNDRV(*pdo, CopyBits)!=PanCopyBits) {
  267. //
  268. // Assert that the driver provides a routine entry point to match each
  269. // Hooked flag.
  270. //
  271. // PPFNGET returns the driver routine if the appropriate flag is set.
  272. // if the flag is set and the routine is NULL, we ASSERT.
  273. //
  274. // if the flag is not set, then PPFNGET returns the Eng routine, which
  275. // better not be NULL, so we ASSERT if it is.
  276. //
  277. ASSERTGDI( (PPFNGET(*pdo, BitBlt, flHooks)),
  278. "HOOK_BITBLT specified, but entry is NULL");
  279. ASSERTGDI( (PPFNGET(*pdo, StretchBlt, flHooks)),
  280. "HOOK_STRETCHBLT specified, but entry is NULL");
  281. ASSERTGDI( (PPFNGET(*pdo, PlgBlt, flHooks)),
  282. "HOOK_PLGBLT specified, but entry is NULL");
  283. ASSERTGDI( (PPFNGET(*pdo, TextOut, flHooks)),
  284. "HOOK_TEXTOUT specified, but entry is NULL");
  285. ASSERTGDI( (PPFNGET(*pdo, Paint, flHooks)),
  286. "HOOK_PAINT specified, but entry is NULL");
  287. ASSERTGDI( (PPFNGET(*pdo, StrokePath, flHooks)),
  288. "HOOK_STROKEPATH specified, but entry is NULL");
  289. ASSERTGDI( (PPFNGET(*pdo, FillPath, flHooks)),
  290. "HOOK_FILLPATH specified, but entry is NULL");
  291. ASSERTGDI( (PPFNGET(*pdo, StrokeAndFillPath, flHooks)),
  292. "HOOK_STROKEANDFILLPATH specified, but entry is NULL");
  293. ASSERTGDI( (PPFNGET(*pdo, LineTo, flHooks)),
  294. "HOOK_LINETO specified, but entry is NULL");
  295. ASSERTGDI( (PPFNGET(*pdo, CopyBits, flHooks)),
  296. "HOOK_COPYBITS specified, but entry is NULL");
  297. ASSERTGDI( (PPFNGET(*pdo, StretchBltROP, flHooks)),
  298. "HOOK_STRETCHBLTROP specified, but entry is NULL");
  299. ASSERTGDI( (PPFNGET(*pdo, TransparentBlt, flHooks)),
  300. "HOOK_TRANSPARENTBLT specified, but entry is NULL");
  301. ASSERTGDI( (PPFNGET(*pdo, AlphaBlend, flHooks)),
  302. "HOOK_ALPHABLEND specified, but entry is NULL");
  303. ASSERTGDI( (PPFNGET(*pdo, GradientFill, flHooks)),
  304. "HOOK_GRADIENTFILL specified, but entry is NULL");
  305. ASSERTGDI( ((flHooks & HOOK_SYNCHRONIZE) == 0 ||
  306. pdo->ppfn(INDEX_DrvSynchronize) != NULL ||
  307. pdo->ppfn(INDEX_DrvSynchronizeSurface != NULL)),
  308. "HOOK_SYNCHRONIZE specified, but appropriate driver function"
  309. " (DrvSynchronize or DrvSynchronizeSurface) not available");
  310. }
  311. }
  312. #endif
  313. /******************************Public*Routine******************************\
  314. * EngAssociateSurface *
  315. * *
  316. * DDI entry point for assigning a surface a palette, associating it with *
  317. * a device. *
  318. * *
  319. * History: *
  320. * Mon 27-Apr-1992 16:36:38 -by- Charles Whitmer [chuckwh] *
  321. * Changed HPDEV to HDEV. *
  322. * *
  323. * Thu 12-Mar-1992 -by- Patrick Haluptzok [patrickh] *
  324. * change to bool return *
  325. * *
  326. * Mon 01-Apr-1991 -by- Patrick Haluptzok [patrickh] *
  327. * add pdev, dhpdev init, palette stuff *
  328. * *
  329. * 13-Feb-1991 -by- Patrick Haluptzok patrickh *
  330. * Wrote it. *
  331. \**************************************************************************/
  332. BOOL EngAssociateSurface(HSURF hsurf, HDEV hdev, FLONG flHooks)
  333. {
  334. //
  335. // Remove any obsolete HOOK_ flags, so that we can overload them for
  336. // internal GDI purposes.
  337. //
  338. flHooks &= ~(HOOK_SYNCHRONIZEACCESS | HOOK_MOVEPANNING);
  339. ASSERTGDI((flHooks & (~HOOK_FLAGS)) == 0, "ERROR driver set high flags");
  340. //
  341. // This call needs to associate this surface with the the HDEV given.
  342. // We can't stick the palette in here because for palette managed devices
  343. // the compatible bitmaps have a NULL palette. If we ever try and init
  344. // the palettes here we need to be careful not to do it for compatible
  345. // bitmaps on palette managed devices.
  346. //
  347. PDEVOBJ po(hdev);
  348. if (!po.bValid())
  349. {
  350. WARNING("EngAssociateSurface: invalid PDEV passed in\n");
  351. return FALSE;
  352. }
  353. SURFREF so;
  354. so.vAltCheckLockIgnoreStockBit(hsurf);
  355. if (!so.bValid())
  356. {
  357. WARNING("EngAssociateSurface: invalid SURF passed in\n");
  358. return FALSE;
  359. }
  360. //
  361. // EA Recovery support: If we are hooking the driver entry points for
  362. // EA recovery, we need to store away the surface and associated
  363. // LDEV so that when the DrvDeleteDeviceBitmap comes down, we can hook
  364. // up the "real" driver entry point.
  365. //
  366. // NOTE: We only create this node if EA recovery is currently enabled, and
  367. // DrvCreateDeviceBitmap (which will do the cleanup of the node) is present.
  368. //
  369. if (WatchdogIsFunctionHooked(po.pldev(), INDEX_DrvCreateDeviceBitmap)) {
  370. if (so.ps->bEngCreateDeviceBitmap()) {
  371. if (dhsurfAssociationIsNodeInList(so.ps->dhsurf(), hsurf) == FALSE) {
  372. PDHSURF_ASSOCIATION_NODE Node = dhsurfAssociationCreateNode();
  373. if (Node) {
  374. Node->dhsurf = so.ps->dhsurf();
  375. Node->hsurf = hsurf;
  376. Node->pldev = po.pldev();
  377. dhsurfAssociationInsertNode(Node);
  378. } else {
  379. WARNING("EngAssociateSurface: failed to create association node\n");
  380. return(FALSE);
  381. }
  382. }
  383. }
  384. }
  385. so.ps->pwo((EWNDOBJ *)NULL);
  386. so.ps->hdev(hdev);
  387. so.ps->dhpdev(po.dhpdevNotDynamic()); // Since we're being called from
  388. // the driver, we are implicitly
  389. // holding a dynamic mode change
  390. // lock, and so don't need to
  391. // check it -- hence 'NotDynamic'
  392. so.ps->flags(so.ps->flags() | flHooks);
  393. #if DBG
  394. vAssertValidHookFlags(&po, &so);
  395. #endif
  396. return(TRUE);
  397. }
  398. /******************************Public*Routine******************************\
  399. * EngModifySurface
  400. *
  401. * DDI entry point for changing surface internals such as the type,
  402. * bits pointers, and the hooked flags.
  403. * 27-Apr-1998 -by- J. Andrew Goossen patrickh
  404. * Wrote it.
  405. \**************************************************************************/
  406. BOOL EngModifySurface(
  407. HSURF hsurf,
  408. HDEV hdev,
  409. FLONG flHooks,
  410. FLONG flSurface,
  411. DHSURF dhsurf,
  412. VOID* pvScan0,
  413. LONG lDelta,
  414. VOID* pvReserved)
  415. {
  416. BOOL bRet = TRUE; // Assume success;
  417. SURFREF so;
  418. PDHSURF_ASSOCIATION_NODE Node = NULL;
  419. PDEVOBJ po(hdev);
  420. if (!po.bValid())
  421. {
  422. WARNING("EngModifySurface: invalid PDEV passed in");
  423. return(FALSE);
  424. }
  425. so.vAltLockIgnoreStockBit(hsurf);
  426. if (!so.bValid())
  427. {
  428. WARNING("EngModifySurface: invalid surface handle passed in");
  429. return(FALSE);
  430. }
  431. if (pvReserved != NULL)
  432. {
  433. WARNING("EngModifySurface: pvReserved not NULL");
  434. bRet = FALSE;
  435. }
  436. if (flSurface & ~(MS_NOTSYSTEMMEMORY | MS_SHAREDACCESS))
  437. {
  438. WARNING("EngModifySurface: invalid flSurface flag");
  439. return(FALSE);
  440. }
  441. //
  442. // Only surfaces that were created via EngCreateDeviceBitmap or
  443. // EngCreateDeviceSurface are allowed to be modified. We do this
  444. // primarily for two reasons:
  445. //
  446. // 1. This prevents the driver from modifying willy-nilly
  447. // SURFOBJs that it sees;
  448. // 2. If solves some problems with bDeleteSurface calling
  449. // DrvDeleteDeviceBitmap (it was impossible to allow
  450. // an STYPE_BITMAP surface to have DrvDeleteDeviceBitmap
  451. // called, and still handle the DrvEnableSurface case
  452. // where a driver created its primary surface using
  453. // EngCreateSurface and modified the 'dhsurf' field --
  454. // in this case DrvDeleteDeviceBitmap should not be called!
  455. //
  456. // Note that as a side effect of how we check for STYPE_DEVICE,
  457. // primary surfaces should only ever be called with EngModifySurface
  458. // once. Bitmap surfaces, however, can intentionally be modified by
  459. // EngModifySurface any number times.
  460. //
  461. if (!(so.ps->bEngCreateDeviceBitmap()) && (so.ps->iType() != STYPE_DEVICE))
  462. {
  463. WARNING("EngModifySurface: surface not driver created");
  464. bRet = FALSE;
  465. }
  466. if ((so.ps->hdev() != NULL) && (so.ps->hdev() != hdev))
  467. {
  468. WARNING("EngModifySurface: surface associated with different hdev");
  469. bRet = FALSE;
  470. }
  471. //
  472. // Remove any obsolete HOOK_ flags, so that we can overload them for
  473. // internal GDI purposes.
  474. //
  475. flHooks &= ~(HOOK_SYNCHRONIZEACCESS | HOOK_MOVEPANNING);
  476. ASSERTGDI((flHooks & (~HOOK_FLAGS)) == 0, "ERROR driver set high flags");
  477. //
  478. // WINBUG #254444 bhouse 12-14-2000 Allow drivers to change primary using EngModifySurface
  479. // TODO: Additional code review of this change
  480. // Allow drivers to change primary surface attributes so long as they
  481. // are not changing the hooking flags and the PDEV is disabled.
  482. //
  483. if (so.ps->bPDEVSurface() && ((po.pSpriteState()->flOriginalSurfFlags & HOOK_FLAGS) != flHooks || !po.bDisabled()))
  484. {
  485. WARNING("EngModifySurface: can't modify PDEV surface once created");
  486. bRet = FALSE;
  487. }
  488. //
  489. // EA Recovery support: If we are hooking the driver entry points for
  490. // EA recovery, we need to store away the surface and associated
  491. // LDEV so that when the DrvDeleteDeviceBitmap comes down, we can hook
  492. // up the "real" driver entry point.
  493. //
  494. //
  495. // NOTE: We only create this node if EA recovery is currently enabled, and
  496. // DrvCreateDeviceBitmap (which will do the cleanup of the node) is present.
  497. //
  498. if (WatchdogIsFunctionHooked(po.pldev(), INDEX_DrvCreateDeviceBitmap)) {
  499. if (so.ps->bEngCreateDeviceBitmap()) {
  500. if (dhsurfAssociationIsNodeInList(dhsurf, hsurf) == FALSE) {
  501. Node = dhsurfAssociationCreateNode();
  502. if (Node) {
  503. Node->dhsurf = dhsurf;
  504. Node->hsurf = hsurf;
  505. Node->pldev = po.pldev();
  506. } else {
  507. WARNING("EngAssociateSurface: failed to create association node\n");
  508. bRet = FALSE;
  509. }
  510. }
  511. }
  512. }
  513. //
  514. // First, try changing the surface's type as appropriate:
  515. //
  516. if ((pvScan0 == NULL) || (lDelta == 0))
  517. {
  518. //
  519. // Make the surface opaque, assuming they've hooked the minimum
  520. // number of calls to allow an opaque surface.
  521. //
  522. if ((flHooks & (HOOK_TEXTOUT | HOOK_BITBLT | HOOK_STROKEPATH))
  523. != (HOOK_TEXTOUT | HOOK_BITBLT | HOOK_STROKEPATH))
  524. {
  525. WARNING("EngModifySurface: opaque surfaces must hook textout, bitblt, strokepath");
  526. bRet = FALSE;
  527. }
  528. if (!(flSurface & MS_NOTSYSTEMMEMORY))
  529. {
  530. WARNING("EngModifySurface: why have opaque surface if system memory?");
  531. bRet = FALSE;
  532. }
  533. if (dhsurf == NULL)
  534. {
  535. WARNING("EngModifySurface: opaque types must have a dhsurf");
  536. bRet = FALSE;
  537. }
  538. //
  539. // If all systems are go, convert to an opaque surface:
  540. //
  541. if (bRet)
  542. {
  543. so.ps->pvScan0(NULL);
  544. so.ps->pvBits(NULL);
  545. so.ps->lDelta(0);
  546. //
  547. // We're making the surface opaque, and STYPE_DEVICE surfaces should
  548. // remain STYPE_DEVICE to denote the primary surface, and not become
  549. // STYPE_DEVBITMAP.
  550. //
  551. if (so.ps->iType() != STYPE_DEVICE)
  552. {
  553. so.ps->iType(STYPE_DEVBITMAP);
  554. }
  555. }
  556. }
  557. else
  558. {
  559. if ((flSurface & MS_NOTSYSTEMMEMORY) && !(flHooks & HOOK_SYNCHRONIZE))
  560. {
  561. WARNING("EngModifySurface: VRAM non-opaque surfaces must hook synchronize");
  562. bRet = FALSE;
  563. }
  564. //
  565. // If all systems are go, convert to a GDI-managed surface:
  566. //
  567. if (bRet)
  568. {
  569. so.ps->pvScan0(pvScan0);
  570. so.ps->lDelta(lDelta);
  571. so.ps->iType(STYPE_BITMAP);
  572. if (lDelta > 0)
  573. {
  574. so.ps->pvBits(pvScan0);
  575. so.ps->fjBitmap(so.ps->fjBitmap() | BMF_TOPDOWN);
  576. }
  577. else
  578. {
  579. so.ps->pvBits((VOID*) ((BYTE*) pvScan0
  580. + (so.ps->sizl().cy - 1) * lDelta));
  581. so.ps->fjBitmap(so.ps->fjBitmap() & ~BMF_TOPDOWN);
  582. }
  583. }
  584. }
  585. //
  586. // If we were successful in changing the type, update some common fields:
  587. //
  588. if (bRet)
  589. {
  590. if (flSurface & MS_NOTSYSTEMMEMORY)
  591. {
  592. so.ps->fjBitmap(so.ps->fjBitmap() | BMF_NOTSYSMEM);
  593. }
  594. else
  595. {
  596. so.ps->fjBitmap(so.ps->fjBitmap() & ~BMF_NOTSYSMEM);
  597. }
  598. if (flSurface & MS_SHAREDACCESS)
  599. {
  600. so.ps->vSetShareAccess();
  601. }
  602. else
  603. {
  604. so.ps->vClearShareAccess();
  605. }
  606. so.ps->dhsurf(dhsurf);
  607. so.ps->pwo((EWNDOBJ *)NULL);
  608. so.ps->hdev(hdev);
  609. so.ps->dhpdev(po.dhpdev());
  610. so.ps->flags((so.ps->flags() & ~HOOK_FLAGS) | flHooks);
  611. // Replace the old hooked flags
  612. // with the new ones
  613. #if DBG
  614. vAssertValidHookFlags(&po, &so);
  615. #endif
  616. //
  617. // If we created a Node for EA recovery purposes, then insert the
  618. // node into our list now that we know this function will succeed.
  619. //
  620. if (Node) {
  621. dhsurfAssociationInsertNode(Node);
  622. }
  623. }
  624. else
  625. {
  626. //
  627. // We are failing. Thus if we created an association node above,
  628. // we should clean that up.
  629. //
  630. if (Node) {
  631. AssociationDeleteNode(Node);
  632. Node = NULL;
  633. }
  634. WARNING("EngModifySurface: failed");
  635. }
  636. return(bRet);
  637. }