Please have a look at that code:
NtGdiCreateCompatibleDC @ 192: ... hNewDC = DC_AllocDC http://www.reactos.org/generated/doxygen/de/dcc/dc_8h.html#a12(&OrigDC->DriverName http://www.reactos.org/generated/doxygen/d9/de9/struct__DC.html#o8);
if (NULL == hNewDC) { DC_UnlockDc(OrigDC); if (NULL != DisplayDC) { NtGdiDeleteObjectApp http://www.reactos.org/generated/doxygen/d7/de8/subsystems_2win32_2win32k_2objects_2dc_8c.html#a21(DisplayDC); } return NULL; } NewDC = DC_LockDc( hNewDC );
...
I am not completely sure (GreatLord said it was fine) but i think it might not be. Let's think of a condition when process x, thread 0 does try call NtGdiCreateCompatibleDC and Allocates the DC. Wouldn't there be the chance of thread 1 to get a lock on the DC (by guessing it's handle) just after it was created and make DC_LockDC return NULL? GDIOBJ_LockObj checks if the ProcessID is the same as PsGetCurrentProcessId() , but not more. So I think a second thread might do a timed attack and get a lock on the just created DC.