Use a different magic for memory DCs and get rid of the DC_MEMORY
flag.

diff --git a/dlls/gdi/enhmfdrv/init.c b/dlls/gdi/enhmfdrv/init.c
index e91a813..3c445ae 100644
--- a/dlls/gdi/enhmfdrv/init.c
+++ b/dlls/gdi/enhmfdrv/init.c
@@ -284,8 +284,7 @@
 
     TRACE("%s\n", debugstr_w(filename) );
 
-    if (!(dc = DC_AllocDC( &EMFDRV_Funcs ))) return 0;
-    dc->header.wMagic = ENHMETAFILE_DC_MAGIC;
+    if (!(dc = DC_AllocDC( &EMFDRV_Funcs, ENHMETAFILE_DC_MAGIC ))) return 0;
 
     physDev = (EMFDRV_PDEVICE *)HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
     if (!physDev) {
diff --git a/dlls/gdi/mfdrv/init.c b/dlls/gdi/mfdrv/init.c
index feee4fe..8126a1e 100644
--- a/dlls/gdi/mfdrv/init.c
+++ b/dlls/gdi/mfdrv/init.c
@@ -154,8 +154,7 @@
     DC *dc;
     METAFILEDRV_PDEVICE *physDev;
 
-    if (!(dc = DC_AllocDC( &MFDRV_Funcs ))) return NULL;
-    dc->header.wMagic = METAFILE_DC_MAGIC;
+    if (!(dc = DC_AllocDC( &MFDRV_Funcs, METAFILE_DC_MAGIC ))) return NULL;
 
     physDev = (METAFILEDRV_PDEVICE *)HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
     if (!physDev)
diff --git a/dlls/ttydrv/dc.c b/dlls/ttydrv/dc.c
index 9c6fbce..66af253 100644
--- a/dlls/ttydrv/dc.c
+++ b/dlls/ttydrv/dc.c
@@ -57,7 +57,7 @@
   physDev->hdc = dc->hSelf;
   physDev->org.x = physDev->org.y = 0;
 
-  if(dc->flags & DC_MEMORY){
+  if(GetObjectType(dc->hSelf) == OBJ_MEMDC) {
     physDev->window = NULL;
     physDev->cellWidth = 1;
     physDev->cellHeight = 1;
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index 06700aa..e81d184 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -953,7 +953,7 @@
         }
         else  /* color -> color */
         {
-            if (dcSrc->flags & DC_MEMORY)
+            if (GetObjectType(physDevSrc->hdc) == OBJ_MEMDC)
                 imageSrc = XGetImage( gdi_display, physDevSrc->drawable,
                                       physDevSrc->org.x + visRectSrc->left,
                                       physDevSrc->org.y + visRectSrc->top,
@@ -1047,7 +1047,7 @@
         register INT x, y;
         XImage *image;
 
-        if (physDev->dc->flags & DC_MEMORY)
+        if (GetObjectType( physDev->hdc ) == OBJ_MEMDC)
             image = XGetImage( gdi_display, physDev->drawable,
                                physDev->org.x + visRectDst->left,
                                physDev->org.y + visRectDst->top,
diff --git a/graphics/x11drv/dib.c b/graphics/x11drv/dib.c
index 84d4cb7..4a3db48 100644
--- a/graphics/x11drv/dib.c
+++ b/graphics/x11drv/dib.c
@@ -5209,7 +5209,7 @@
     xSrc, ySrc, xDest, yDest, width, height);
   /* this function is meant as an optimization for BitBlt,
    * not to be called otherwise */
-  if (!(dcSrc->flags & DC_MEMORY)) {
+  if (GetObjectType( physDevSrc->hdc ) != OBJ_MEMDC) {
     ERR("called for non-memory source DC!?\n");
     return;
   }
@@ -5621,7 +5621,7 @@
 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
 {
   if (!physDev) return DIB_Status_None;
-  if (!(physDev->dc->flags & DC_MEMORY)) return DIB_Status_None;
+  if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return DIB_Status_None;
 
   return X11DRV_LockDIBSection2( physDev->dc->hBitmap, req, lossy );
 }
@@ -5632,7 +5632,7 @@
 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
 {
   if (!physDev) return;
-  if (!(physDev->dc->flags & DC_MEMORY)) return;
+  if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return;
 
   X11DRV_UnlockDIBSection2( physDev->dc->hBitmap, commit );
 }
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index b3273a6..7b7729c 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -898,6 +898,7 @@
     XImage * image;
     int pixel;
     POINT pt;
+    BOOL memdc = (GetObjectType(physDev->hdc) == OBJ_MEMDC);
     DC *dc = physDev->dc;
 
     pt.x = x;
@@ -908,7 +909,7 @@
     X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
 
     wine_tsx11_lock();
-    if (dc->flags & DC_MEMORY)
+    if (memdc)
     {
         image = XGetImage( gdi_display, physDev->drawable,
                            physDev->org.x + pt.x, physDev->org.y + pt.y,
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index 7577582..944ec4c 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -103,7 +103,7 @@
     physDev->hdc = dc->hSelf;
     physDev->dc  = dc;  /* FIXME */
 
-    if (dc->flags & DC_MEMORY)
+    if (GetObjectType( dc->hSelf ) == OBJ_MEMDC)
     {
         physDev->drawable  = BITMAP_stock_pixmap;
     }
diff --git a/graphics/x11drv/palette.c b/graphics/x11drv/palette.c
index 22b4b19..212dd8d 100644
--- a/graphics/x11drv/palette.c
+++ b/graphics/x11drv/palette.c
@@ -1233,10 +1233,9 @@
  */
 UINT X11DRV_RealizeDefaultPalette( X11DRV_PDEVICE *physDev )
 {
-    DC *dc = physDev->dc;
     UINT ret = 0;
 
-    if (palette_size && !(dc->flags & DC_MEMORY))
+    if (palette_size && GetObjectType(physDev->hdc) != OBJ_MEMDC)
     {
         PALETTEOBJ*  palPtr = GDI_GetObjPtr( GetStockObject(DEFAULT_PALETTE), PALETTE_MAGIC );
         if (palPtr)
diff --git a/include/gdi.h b/include/gdi.h
index 7a190ee..cf2b282 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -41,7 +41,8 @@
 #define METAFILE_DC_MAGIC     0x4f51
 #define ENHMETAFILE_MAGIC     0x4f52
 #define ENHMETAFILE_DC_MAGIC  0x4f53
-#define LAST_MAGIC            0x4f53
+#define MEMORY_DC_MAGIC       0x4f54
+#define LAST_MAGIC            0x4f54
 
 #define MAGIC_DONTCARE	      0xffff
 
@@ -296,7 +297,6 @@
 #define DCHF_VALIDATEVISRGN     0x0002
 
   /* DC flags */
-#define DC_MEMORY     0x0001   /* It is a memory DC */
 #define DC_SAVED      0x0002   /* It is a saved DC */
 #define DC_DIRTY      0x0004   /* hVisRgn has to be updated */
 #define DC_THUNKHOOK  0x0008   /* DC hook is in the 16-bit code */
@@ -455,7 +455,7 @@
 
 extern POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut );
 
-extern DC * DC_AllocDC( const DC_FUNCTIONS *funcs );
+extern DC * DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic );
 extern DC * DC_GetDCPtr( HDC hdc );
 extern DC * DC_GetDCUpdate( HDC hdc );
 extern void DC_InitDC( DC * dc );
diff --git a/objects/bitmap.c b/objects/bitmap.c
index a78d192..e617c81 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -407,7 +407,7 @@
     DC *dc = DC_GetDCPtr( hdc );
 
     if (!dc) return 0;
-    if (!(dc->flags & DC_MEMORY))
+    if (GetObjectType( hdc ) != OBJ_MEMDC)
     {
         GDI_ReleaseObj( hdc );
         return 0;
diff --git a/objects/dc.c b/objects/dc.c
index f352c46..d8bc999 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -48,12 +48,12 @@
 /***********************************************************************
  *           DC_AllocDC
  */
-DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
+DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
 {
     HDC hdc;
     DC *dc;
 
-    if (!(dc = GDI_AllocObject( sizeof(*dc), DC_MAGIC, (HGDIOBJ*)&hdc, &dc_funcs ))) return NULL;
+    if (!(dc = GDI_AllocObject( sizeof(*dc), magic, (HGDIOBJ*)&hdc, &dc_funcs ))) return NULL;
 
     dc->hSelf               = hdc;
     dc->funcs               = funcs;
@@ -130,8 +130,9 @@
     GDIOBJHDR *ptr = GDI_GetObjPtr( hdc, MAGIC_DONTCARE );
     if (!ptr) return NULL;
     if ((GDIMAGIC(ptr->wMagic) == DC_MAGIC) ||
-	(GDIMAGIC(ptr->wMagic) == METAFILE_DC_MAGIC) ||
-	(GDIMAGIC(ptr->wMagic) == ENHMETAFILE_DC_MAGIC))
+        (GDIMAGIC(ptr->wMagic) == MEMORY_DC_MAGIC) ||
+        (GDIMAGIC(ptr->wMagic) == METAFILE_DC_MAGIC) ||
+        (GDIMAGIC(ptr->wMagic) == ENHMETAFILE_DC_MAGIC))
         return (DC *)ptr;
     GDI_ReleaseObj( hdc );
     SetLastError( ERROR_INVALID_HANDLE );
@@ -151,18 +152,15 @@
     if (!dc) return NULL;
     while (dc->flags & DC_DIRTY)
     {
+        DCHOOKPROC proc = dc->hookThunk;
         dc->flags &= ~DC_DIRTY;
-        if (!(dc->flags & (DC_SAVED | DC_MEMORY)))
+        if (proc)
         {
-            DCHOOKPROC proc = dc->hookThunk;
-            if (proc)
-            {
-                DWORD data = dc->dwHookData;
-                GDI_ReleaseObj( hdc );
-                proc( HDC_16(hdc), DCHC_INVALIDVISRGN, data, 0 );
-                if (!(dc = DC_GetDCPtr( hdc ))) break;
-                /* otherwise restart the loop in case it became dirty again in the meantime */
-            }
+            DWORD data = dc->dwHookData;
+            GDI_ReleaseObj( hdc );
+            proc( HDC_16(hdc), DCHC_INVALIDVISRGN, data, 0 );
+            if (!(dc = DC_GetDCPtr( hdc ))) break;
+            /* otherwise restart the loop in case it became dirty again in the meantime */
         }
     }
     return dc;
@@ -271,7 +269,7 @@
     HGDIOBJ handle;
 
     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
-    if (!(newdc = GDI_AllocObject( sizeof(DC), DC_MAGIC, &handle, &dc_funcs )))
+    if (!(newdc = GDI_AllocObject( sizeof(DC), GDIMAGIC(dc->header.wMagic), &handle, &dc_funcs )))
     {
       GDI_ReleaseObj( hdc );
       return 0;
@@ -409,7 +407,7 @@
     dc->vportExtX        = dcs->vportExtX;
     dc->vportExtY        = dcs->vportExtY;
 
-    if (!(dc->flags & DC_MEMORY)) dc->bitsPerPixel = dcs->bitsPerPixel;
+    if (GDIMAGIC(dc->header.wMagic) != MEMORY_DC_MAGIC) dc->bitsPerPixel = dcs->bitsPerPixel;
 
     if (dcs->hClipRgn)
     {
@@ -586,13 +584,12 @@
         ERR( "no driver found for %s\n", buf );
         return 0;
     }
-    if (!(dc = DC_AllocDC( funcs )))
+    if (!(dc = DC_AllocDC( funcs, DC_MAGIC )))
     {
         DRIVER_release_driver( funcs );
         return 0;
     }
 
-    dc->flags   = 0;
     dc->hBitmap = GetStockObject( DEFAULT_BITMAP );
 
     TRACE("(driver=%s, device=%s, output=%s): returning %p\n",
@@ -667,20 +664,26 @@
 {
     DC *dc, *origDC;
     const DC_FUNCTIONS *funcs;
+    PHYSDEV physDev;
 
     GDI_CheckNotLock();
 
     if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC )))
     {
         funcs = origDC->funcs;
+        physDev = origDC->physDev;
         GDI_ReleaseObj( hdc ); /* can't hold the lock while loading the driver */
         funcs = DRIVER_get_driver( funcs );
     }
-    else funcs = DRIVER_load_driver( "DISPLAY" );
+    else
+    {
+        funcs = DRIVER_load_driver( "DISPLAY" );
+        physDev = NULL;
+    }
 
     if (!funcs) return 0;
 
-    if (!(dc = DC_AllocDC( funcs )))
+    if (!(dc = DC_AllocDC( funcs, MEMORY_DC_MAGIC )))
     {
         DRIVER_release_driver( funcs );
         return 0;
@@ -688,21 +691,19 @@
 
     TRACE("(%p): returning %p\n", hdc, dc->hSelf );
 
-    dc->flags        = DC_MEMORY;
     dc->bitsPerPixel = 1;
     dc->hBitmap      = GetStockObject( DEFAULT_BITMAP );
 
     /* Copy the driver-specific physical device info into
      * the new DC. The driver may use this read-only info
      * while creating the compatible DC below. */
-    if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC ))) dc->physDev = origDC->physDev;
+    dc->physDev = physDev;
 
     if (dc->funcs->pCreateDC &&
         !dc->funcs->pCreateDC( dc, &dc->physDev, NULL, NULL, NULL, NULL ))
     {
         WARN("creation aborted by device\n");
         GDI_FreeObject( dc->hSelf, dc );
-        if (origDC) GDI_ReleaseObj( hdc );
         DRIVER_release_driver( funcs );
         return 0;
     }
@@ -715,7 +716,6 @@
 
     DC_InitDC( dc );
     GDI_ReleaseObj( dc->hSelf );
-    if (origDC) GDI_ReleaseObj( hdc );
     return dc->hSelf;
 }
 
@@ -732,19 +732,16 @@
 
     GDI_CheckNotLock();
 
-    if (!(dc = GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
+    if (!(dc = DC_GetDCPtr( hdc ))) return FALSE;
 
     /* Call hook procedure to check whether is it OK to delete this DC */
-    if (dc->hookThunk && !(dc->flags & (DC_SAVED | DC_MEMORY)))
+    if (dc->hookThunk)
     {
         DCHOOKPROC proc = dc->hookThunk;
-        if (proc)
-        {
-            DWORD data = dc->dwHookData;
-            GDI_ReleaseObj( hdc );
-            if (!proc( HDC_16(hdc), DCHC_DELETEDC, data, 0 )) return FALSE;
-            if (!(dc = DC_GetDCPtr( hdc ))) return TRUE;  /* deleted by the hook */
-        }
+        DWORD data = dc->dwHookData;
+        GDI_ReleaseObj( hdc );
+        if (!proc( HDC_16(hdc), DCHC_DELETEDC, data, 0 )) return FALSE;
+        if (!(dc = DC_GetDCPtr( hdc ))) return TRUE;  /* deleted by the hook */
     }
 
     while (dc->saveLevel)
@@ -1141,11 +1138,15 @@
  */
 BOOL WINAPI SetDCHook( HDC hdc, DCHOOKPROC hookProc, DWORD dwHookData )
 {
-    DC *dc = DC_GetDCPtr( hdc );
+    DC *dc = GDI_GetObjPtr( hdc, DC_MAGIC );
 
     if (!dc) return FALSE;
-    dc->dwHookData = dwHookData;
-    dc->hookThunk = hookProc;
+
+    if (!(dc->flags & DC_SAVED))
+    {
+        dc->dwHookData = dwHookData;
+        dc->hookThunk = hookProc;
+    }
     GDI_ReleaseObj( hdc );
     return TRUE;
 }
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 85d6779..6e2d483 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -692,6 +692,7 @@
     case METAFILE_DC_MAGIC:
     case ENHMETAFILE_MAGIC:
     case ENHMETAFILE_DC_MAGIC:
+    case MEMORY_DC_MAGIC:
     case BITMAP_MAGIC:
     case PALETTE_MAGIC:
         if (!(obj = alloc_large_heap( size, handle ))) goto error;
@@ -1023,6 +1024,9 @@
       case ENHMETAFILE_DC_MAGIC:
 	  result = OBJ_ENHMETADC;
 	  break;
+      case MEMORY_DC_MAGIC:
+	  result = OBJ_MEMDC;
+	  break;
       default:
 	  FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
 	  break;