[gdk-pixbuf] Link directly to GDI+ API avoiding LoadLibrary



commit 0f01668251d7d9344f2130e128c230ad332ebf42
Author: Tor Lillqvist <tml iki fi>
Date:   Fri Sep 3 02:10:43 2010 +0300

    Link directly to GDI+ API avoiding LoadLibrary
    
    Avoid potential DLL hijacking risks by not calling LoadLibrary() to
    load gdiplus.dll. As gdiplus.dll is a WinSxS (side-by-side) DLL we
    couldn't use the full path anyway as we don't know it.
    
    So just link to the GDI+ functions directly. Gdiplus.dll should be
    present on all Windows versions we support anyway. Some complexity
    added as MinGW doesn't come with an import library for gdiplus.dll, so
    we have to create one ourselves. But we call relatively few functions
    from gdiplus.dll so that is not a big deal.

 gdk-pixbuf/Makefile.am      |   56 ++++++++++++++++++++++++-----
 gdk-pixbuf/io-gdip-native.h |   63 ++++++++++++++------------------
 gdk-pixbuf/io-gdip-utils.c  |   84 ++-----------------------------------------
 3 files changed, 77 insertions(+), 126 deletions(-)
---
diff --git a/gdk-pixbuf/Makefile.am b/gdk-pixbuf/Makefile.am
index b121157..f5173b8 100644
--- a/gdk-pixbuf/Makefile.am
+++ b/gdk-pixbuf/Makefile.am
@@ -199,6 +199,43 @@ libpixbufloader_qtif_la_LIBADD = $(module_libs)
 
 if BUILD_GDIPLUS_LOADERS
 
+# MinGW doesn't come with any import library for gdiplus.dll, so
+# create a partial one that's enough for our use.
+
+libgdiplus = libgdiplus.dll.a
+gdiplus_ldflag = -Wl,$(libgdiplus)
+
+libgdiplus.dll.a: Makefile
+	(echo EXPORTS; \
+	 for F in GdiplusStartup 12 \
+		  GdipCreateBitmapFromStream 8 \
+		  GdipBitmapGetPixel 16 \
+		  GdipGetImageWidth 8 \
+		  GdipGetImageHeight 8 \
+		  GdipDisposeImage 4 \
+		  GdipGetImageFlags 8 \
+		  GdipImageGetFrameCount 12 \
+		  GdipImageSelectActiveFrame 12 \
+		  GdipGetPropertyItemSize 12 \
+		  GdipGetPropertyItem 16 \
+		  GdipCreateBitmapFromScan0 24 \
+		  GdipSaveImageToStream 16 \
+		  GdipGetImageEncoders 12 \
+		  GdipGetImageEncodersSize 8 \
+		  GdipBitmapSetPixel 16 \
+		  GdipDrawImageI 16 \
+		  GdipGetImageGraphicsContext 8 \
+		  GdipFlush 8 \
+		  GdipGraphicsClear 8 \
+		  GdipBitmapSetResolution 12 \
+		  GdipGetImageHorizontalResolution 8 \
+		  GdipGetImageVerticalResolution 8 \
+		  GdipLoadImageFromStream 8 \
+		  GdipDeleteGraphics 4 ; do echo $$F; \
+	 done) >gdiplus.def
+	$(DLLTOOL) --kill-at --dllname gdiplus.dll --input-def gdiplus.def --output-lib $@
+	rm gdiplus.def
+
 if INCLUDE_GDIPLUS
 
 # When building the GDI+ loader statically, we put the "common" objects
@@ -251,7 +288,7 @@ GDIPLUS_LIBS = \
 	libpixbufloader-gdip-jpeg.la \
 	libpixbufloader-gdip-tiff.la
 
-libpixbufloader_gdip_ico_la_LDFLAGS = -avoid-version -module -no-undefined
+libpixbufloader_gdip_ico_la_LDFLAGS = -avoid-version -module -no-undefined $(gdiplus_ldflag)
 libpixbufloader_gdip_ico_la_SOURCES = 	\
 	io-gdip-native.h		\
 	io-gdip-propertytags.h		\
@@ -262,7 +299,7 @@ libpixbufloader_gdip_ico_la_SOURCES = 	\
 	io-gdip-ico.c
 libpixbufloader_gdip_ico_la_LIBADD = $(module_libs) $(libole32)
 
-libpixbufloader_gdip_wmf_la_LDFLAGS = -avoid-version -module -no-undefined
+libpixbufloader_gdip_wmf_la_LDFLAGS = -avoid-version -module -no-undefined $(gdiplus_ldflag)
 libpixbufloader_gdip_wmf_la_SOURCES = 	\
 	io-gdip-native.h		\
 	io-gdip-propertytags.h		\
@@ -273,7 +310,7 @@ libpixbufloader_gdip_wmf_la_SOURCES = 	\
 	io-gdip-wmf.c
 libpixbufloader_gdip_wmf_la_LIBADD = $(module_libs) $(libole32)
 
-libpixbufloader_gdip_emf_la_LDFLAGS = -avoid-version -module -no-undefined
+libpixbufloader_gdip_emf_la_LDFLAGS = -avoid-version -module -no-undefined $(gdiplus_ldflag)
 libpixbufloader_gdip_emf_la_SOURCES = 	\
 	io-gdip-native.h		\
 	io-gdip-propertytags.h		\
@@ -284,7 +321,7 @@ libpixbufloader_gdip_emf_la_SOURCES = 	\
 	io-gdip-emf.c
 libpixbufloader_gdip_emf_la_LIBADD = $(module_libs) $(libole32)
 
-libpixbufloader_gdip_bmp_la_LDFLAGS = -avoid-version -module -no-undefined
+libpixbufloader_gdip_bmp_la_LDFLAGS = -avoid-version -module -no-undefined $(gdiplus_ldflag)
 libpixbufloader_gdip_bmp_la_SOURCES = 	\
 	io-gdip-native.h		\
 	io-gdip-propertytags.h		\
@@ -295,7 +332,7 @@ libpixbufloader_gdip_bmp_la_SOURCES = 	\
 	io-gdip-bmp.c
 libpixbufloader_gdip_bmp_la_LIBADD = $(module_libs) $(libole32)
 
-libpixbufloader_gdip_gif_la_LDFLAGS = -avoid-version -module -no-undefined
+libpixbufloader_gdip_gif_la_LDFLAGS = -avoid-version -module -no-undefined $(gdiplus_ldflag)
 libpixbufloader_gdip_gif_la_SOURCES = 	\
 	io-gdip-native.h		\
 	io-gdip-propertytags.h		\
@@ -306,7 +343,7 @@ libpixbufloader_gdip_gif_la_SOURCES = 	\
 	io-gdip-gif.c
 libpixbufloader_gdip_gif_la_LIBADD = $(module_libs) $(libole32)
 
-libpixbufloader_gdip_jpeg_la_LDFLAGS = -avoid-version -module -no-undefined
+libpixbufloader_gdip_jpeg_la_LDFLAGS = -avoid-version -module -no-undefined $(gdiplus_ldflag)
 libpixbufloader_gdip_jpeg_la_SOURCES = 	\
 	io-gdip-native.h		\
 	io-gdip-propertytags.h		\
@@ -317,7 +354,7 @@ libpixbufloader_gdip_jpeg_la_SOURCES = 	\
 	io-gdip-jpeg.c
 libpixbufloader_gdip_jpeg_la_LIBADD = $(module_libs) $(libole32)
 
-libpixbufloader_gdip_tiff_la_LDFLAGS = -avoid-version -module -no-undefined
+libpixbufloader_gdip_tiff_la_LDFLAGS = -avoid-version -module -no-undefined $(gdiplus_ldflag)
 libpixbufloader_gdip_tiff_la_SOURCES = 	\
 	io-gdip-native.h		\
 	io-gdip-propertytags.h		\
@@ -551,11 +588,12 @@ libgdk_pixbuf_2_0_la_LDFLAGS = \
 	-version-info $(LT_VERSION_INFO)	\
 	$(LIBTOOL_EXPORT_OPTIONS)		\
 	$(no_undefined)				\
-	$(gdk_pixbuf_symbols)
+	$(gdk_pixbuf_symbols)			\
+	$(gdiplus_ldflag)
 
 
 libgdk_pixbuf_2_0_la_LIBADD = pixops/libpixops.la $(builtin_objs) $(GDK_PIXBUF_DEP_LIBS) $(libole32)
-libgdk_pixbuf_2_0_la_DEPENDENCIES = pixops/libpixops.la $(builtin_objs) $(gdk_pixbuf_def) $(gdk_pixbuf_win32_res)
+libgdk_pixbuf_2_0_la_DEPENDENCIES = pixops/libpixops.la $(builtin_objs) $(gdk_pixbuf_def) $(gdk_pixbuf_win32_res) $(libgdiplus)
 
 gdk_pixbuf_headers = 			\
 	gdk-pixbuf.h			\
diff --git a/gdk-pixbuf/io-gdip-native.h b/gdk-pixbuf/io-gdip-native.h
index 24ea824..417a747 100644
--- a/gdk-pixbuf/io-gdip-native.h
+++ b/gdk-pixbuf/io-gdip-native.h
@@ -224,41 +224,32 @@ typedef struct _GpRect GpRect;
 #define IStream_SetSize(This,size) (This)->lpVtbl->SetSize(This,size)
 #endif
 
-typedef GpStatus (WINGDIPAPI* GdiplusStartupFunc) (gpointer, const gpointer, gpointer);
-typedef GpStatus (WINGDIPAPI* GdipCreateBitmapFromStreamFunc) (gpointer, GpBitmap**);
-typedef GpStatus (WINGDIPAPI* GdipBitmapGetPixelFunc) (GpBitmap*, gint x, gint y, ARGB*);
-typedef GpStatus (WINGDIPAPI* GdipGetImageWidthFunc) (GpImage*, guint*);
-typedef GpStatus (WINGDIPAPI* GdipGetImageHeightFunc) (GpImage*, guint*);
-typedef GpStatus (WINGDIPAPI* GdipDisposeImageFunc) (GpImage*);
-typedef GpStatus (WINGDIPAPI* GdipGetImageFlagsFunc) (GpImage *, guint*);
-typedef GpStatus (WINGDIPAPI* GdipImageGetFrameCountFunc) (GpImage *image, const GUID* dimensionID, UINT* count);
-typedef GpStatus (WINGDIPAPI* GdipImageSelectActiveFrameFunc) (GpImage *image, const GUID* dimensionID, UINT frameIndex);
-typedef GpStatus (WINGDIPAPI* GdipGetPropertyItemSizeFunc) (GpImage *image, int propId, guint* size);
-typedef GpStatus (WINGDIPAPI* GdipGetPropertyItemFunc) (GpImage *image, int propId, guint propSize, PropertyItem* buffer);
-typedef GpStatus (WINGDIPAPI* GdipGetPropertyCountFunc) (GpImage *image, guint* numOfProperty);
-typedef GpStatus (WINGDIPAPI* GdipGetPropertyIdListFunc) (GpImage *image, guint numOfProperty, PROPID* list);
-typedef GpStatus (WINGDIPAPI* GdipCreateBitmapFromScan0Func) (INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, 
-                                                              GpBitmap** bitmap);
-typedef GpStatus (WINGDIPAPI* GdipSaveImageToStreamFunc) (GpImage *image, IStream* stream, const CLSID* clsidEncoder, 
-                                                          const EncoderParameters* encoderParams);
-
-typedef GpStatus (WINGDIPAPI* GdipGetImageEncodersFunc) (UINT numEncoders, UINT size, ImageCodecInfo *encoders);
-typedef GpStatus (WINGDIPAPI* GdipGetImageEncodersSizeFunc) (UINT *numEncoders, UINT *size);
-typedef GpStatus (WINGDIPAPI* GdipBitmapSetPixelFunc) (GpBitmap* bitmap, INT x, INT y, ARGB color);
-
-typedef GpStatus (WINGDIPAPI* GdipDrawImageIFunc) (GpGraphics *graphics, GpImage *image, INT x, INT y);
-typedef GpStatus (WINGDIPAPI* GdipGetImageGraphicsContextFunc) (GpImage *image, GpGraphics **graphics);
-typedef GpStatus (WINGDIPAPI* GdipFlushFunc) (GpGraphics *graphics, INT intention);
-typedef GpStatus (WINGDIPAPI* GdipGraphicsClearFunc) (GpGraphics *graphics, ARGB color);
-typedef GpStatus (WINGDIPAPI* GdipBitmapSetResolutionFunc) (GpBitmap* bitmap, float xdpi, float ydpi);
-typedef GpStatus (WINGDIPAPI* GdipGetImageHorizontalResolutionFunc) (GpImage *image, float *resolution);
-typedef GpStatus (WINGDIPAPI* GdipGetImageVerticalResolutionFunc) (GpImage *image, float *resolution);
-typedef GpStatus (WINGDIPAPI* GdipLoadImageFromStreamFunc) (IStream* stream, GpImage **image);
-typedef GpStatus (WINGDIPAPI* GdipDeleteGraphicsFunc) (GpGraphics *graphics);
-
-typedef GpStatus (WINGDIPAPI* GdipBitmapLockBitsFunc) (GpBitmap* bitmap, const GpRect* rect, UINT flags, PixelFormat format, BitmapData* lockedBitmapData);
-typedef GpStatus (WINGDIPAPI* GdipBitmapUnlockBitsFunc) (GpBitmap* bitmap, BitmapData* lockedBitmapData);
-typedef GpStatus (WINGDIPAPI* GdipGetImagePixelFormatFunc) (GpImage *image, PixelFormat *format);
-typedef GpStatus (WINGDIPAPI* GdipCloneBitmapAreaIFunc) (INT x, INT y, INT width, INT height, PixelFormat format, GpBitmap *srcBitmap, GpBitmap **dstBitmap);
+GpStatus WINGDIPAPI GdiplusStartup (gpointer, const gpointer, gpointer);
+GpStatus WINGDIPAPI GdipCreateBitmapFromStream (gpointer, GpBitmap**);
+GpStatus WINGDIPAPI GdipBitmapGetPixel (GpBitmap*, gint x, gint y, ARGB*);
+GpStatus WINGDIPAPI GdipGetImageWidth (GpImage*, guint*);
+GpStatus WINGDIPAPI GdipGetImageHeight (GpImage*, guint*);
+GpStatus WINGDIPAPI GdipDisposeImage (GpImage*);
+GpStatus WINGDIPAPI GdipGetImageFlags (GpImage *, guint*);
+GpStatus WINGDIPAPI GdipImageGetFrameCount (GpImage *image, const GUID* dimensionID, UINT* count);
+GpStatus WINGDIPAPI GdipImageSelectActiveFrame (GpImage *image, const GUID* dimensionID, UINT frameIndex);
+GpStatus WINGDIPAPI GdipGetPropertyItemSize (GpImage *image, int propId, guint* size);
+GpStatus WINGDIPAPI GdipGetPropertyItem (GpImage *image, int propId, guint propSize, PropertyItem* buffer);
+GpStatus WINGDIPAPI GdipCreateBitmapFromScan0 (INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, 
+                                               GpBitmap** bitmap);
+GpStatus WINGDIPAPI GdipSaveImageToStream (GpImage *image, IStream* stream, const CLSID* clsidEncoder, 
+                                           const EncoderParameters* encoderParams);
+GpStatus WINGDIPAPI GdipGetImageEncoders (UINT numEncoders, UINT size, ImageCodecInfo *encoders);
+GpStatus WINGDIPAPI GdipGetImageEncodersSize (UINT *numEncoders, UINT *size);
+GpStatus WINGDIPAPI GdipBitmapSetPixel (GpBitmap* bitmap, INT x, INT y, ARGB color);
+GpStatus WINGDIPAPI GdipDrawImageI (GpGraphics *graphics, GpImage *image, INT x, INT y);
+GpStatus WINGDIPAPI GdipGetImageGraphicsContext (GpImage *image, GpGraphics **graphics);
+GpStatus WINGDIPAPI GdipFlush (GpGraphics *graphics, INT intention);
+GpStatus WINGDIPAPI GdipGraphicsClear (GpGraphics *graphics, ARGB color);
+GpStatus WINGDIPAPI GdipBitmapSetResolution (GpBitmap* bitmap, float xdpi, float ydpi);
+GpStatus WINGDIPAPI GdipGetImageHorizontalResolution (GpImage *image, float *resolution);
+GpStatus WINGDIPAPI GdipGetImageVerticalResolution (GpImage *image, float *resolution);
+GpStatus WINGDIPAPI GdipLoadImageFromStream (IStream* stream, GpImage **image);
+GpStatus WINGDIPAPI GdipDeleteGraphics (GpGraphics *graphics);
 
 #endif
diff --git a/gdk-pixbuf/io-gdip-utils.c b/gdk-pixbuf/io-gdip-utils.c
index b8fa72b..8f62d75 100644
--- a/gdk-pixbuf/io-gdip-utils.c
+++ b/gdk-pixbuf/io-gdip-utils.c
@@ -43,38 +43,6 @@ struct _GdipContext {
 };
 typedef struct _GdipContext GdipContext;
 
-static GdiplusStartupFunc GdiplusStartup;
-static GdipCreateBitmapFromStreamFunc GdipCreateBitmapFromStream;
-static GdipBitmapGetPixelFunc GdipBitmapGetPixel;
-static GdipGetImageHeightFunc GdipGetImageHeight;
-static GdipDisposeImageFunc GdipDisposeImage;
-static GdipGetImageFlagsFunc GdipGetImageFlags;
-static GdipGetImageWidthFunc GdipGetImageWidth;
-static GdipImageGetFrameCountFunc GdipImageGetFrameCount;
-static GdipImageSelectActiveFrameFunc GdipImageSelectActiveFrame;
-static GdipGetPropertyItemSizeFunc GdipGetPropertyItemSize;
-static GdipGetPropertyItemFunc GdipGetPropertyItem;
-static GdipGetPropertyCountFunc GdipGetPropertyCount;
-static GdipGetPropertyIdListFunc GdipGetPropertyIdList;
-static GdipCreateBitmapFromScan0Func GdipCreateBitmapFromScan0;
-static GdipSaveImageToStreamFunc GdipSaveImageToStream;
-static GdipBitmapSetPixelFunc GdipBitmapSetPixel;
-static GdipDrawImageIFunc GdipDrawImageI;
-static GdipGetImageGraphicsContextFunc GdipGetImageGraphicsContext;
-static GdipFlushFunc GdipFlush;
-static GdipGraphicsClearFunc GdipGraphicsClear;
-static GdipBitmapSetResolutionFunc GdipBitmapSetResolution;
-static GdipGetImageHorizontalResolutionFunc GdipGetImageHorizontalResolution;
-static GdipGetImageVerticalResolutionFunc GdipGetImageVerticalResolution;
-static GdipLoadImageFromStreamFunc GdipLoadImageFromStream;
-static GdipDeleteGraphicsFunc GdipDeleteGraphics;
-static GdipGetImageEncodersFunc GdipGetImageEncoders;
-static GdipGetImageEncodersSizeFunc GdipGetImageEncodersSize;
-static GdipBitmapLockBitsFunc GdipBitmapLockBits;
-static GdipBitmapUnlockBitsFunc GdipBitmapUnlockBits;
-static GdipGetImagePixelFormatFunc GdipGetImagePixelFormat;
-static GdipCloneBitmapAreaIFunc GdipCloneBitmapAreaI;
-
 DEFINE_GUID(FrameDimensionTime, 0x6aedbd6d,0x3fb5,0x418a,0x83,0xa6,0x7f,0x45,0x22,0x9d,0xc8,0x72);
 DEFINE_GUID(FrameDimensionPage, 0x7462dc86,0x6180,0x4c7e,0x8e,0x3f,0xee,0x73,0x33,0xa7,0xa4,0x83);
 
@@ -131,58 +99,12 @@ gdip_init (void)
 {
   GdiplusStartupInput input;
   ULONG_PTR gdiplusToken = 0;
-  static HINSTANCE gdipluslib = NULL;
+  static gboolean beenhere = FALSE;
 
-  if (!gdipluslib)
-    gdipluslib = LoadLibrary ("gdiplus.dll");
-  else
+  if (beenhere)
     return TRUE; /* gdip_init() is idempotent */
 
-  if (!gdipluslib)
-    return FALSE;
-
-#define LOOKUP(func) \
-  G_STMT_START { \
-    func = (func##Func) GetProcAddress (gdipluslib, #func); \
-    if (!func) {\
-      g_warning ("Couldn't find GDI+ function %s\n", #func); \
-      return FALSE; \
-    } \
-  } G_STMT_END
-
-  LOOKUP (GdiplusStartup);
-  LOOKUP (GdipCreateBitmapFromStream);
-  LOOKUP (GdipBitmapGetPixel);
-  LOOKUP (GdipGetImageHeight);
-  LOOKUP (GdipDisposeImage);
-  LOOKUP (GdipGetImageFlags);
-  LOOKUP (GdipGetImageWidth);
-  LOOKUP (GdipImageGetFrameCount);
-  LOOKUP (GdipImageSelectActiveFrame);
-  LOOKUP (GdipGetPropertyItemSize);
-  LOOKUP (GdipGetPropertyItem);
-  LOOKUP (GdipGetPropertyCount);
-  LOOKUP (GdipGetPropertyIdList);
-  LOOKUP (GdipCreateBitmapFromScan0);
-  LOOKUP (GdipSaveImageToStream);
-  LOOKUP (GdipBitmapSetPixel);
-  LOOKUP (GdipDrawImageI);
-  LOOKUP (GdipGetImageGraphicsContext);
-  LOOKUP (GdipFlush);
-  LOOKUP (GdipGraphicsClear);
-  LOOKUP (GdipBitmapSetResolution);
-  LOOKUP (GdipGetImageHorizontalResolution);
-  LOOKUP (GdipGetImageVerticalResolution);
-  LOOKUP (GdipLoadImageFromStream);
-  LOOKUP (GdipDeleteGraphics);
-  LOOKUP (GdipGetImageEncoders);
-  LOOKUP (GdipGetImageEncodersSize);
-  LOOKUP (GdipBitmapLockBits);
-  LOOKUP (GdipBitmapUnlockBits);
-  LOOKUP (GdipGetImagePixelFormat);
-  LOOKUP (GdipCloneBitmapAreaI);
-
-#undef LOOKUP
+  beenhere = TRUE;
 
   input.GdiplusVersion = 1;
   input.DebugEventCallback = NULL;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]