diff -ur xine-lib-1.1.18.orig/src/input/libdvdnav/dvd_udf.c xine-lib-1.1.18/src/input/libdvdnav/dvd_udf.c
--- xine-lib-1.1.18.orig/src/input/libdvdnav/dvd_udf.c	2009-11-30 21:57:20.000000000 +0100
+++ xine-lib-1.1.18/src/input/libdvdnav/dvd_udf.c	2010-02-24 21:12:36.032882913 +0100
@@ -38,10 +38,16 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <inttypes.h>
+#ifndef __WIN32__
+#include <fnmatch.h>
+#endif
 
 #include "dvd_reader.h"
 #include "dvd_udf.h"
 
+#include "ifo_types.h"
+#include "ifo_read.h"
+
 /* Private but located in/shared with dvd_reader.c */
 extern int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
 				size_t block_count, unsigned char *data, 
@@ -774,7 +780,9 @@
     return part->valid;
 }
 
-uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
+
+
+static uint32_t UDFFindFileReal( dvd_reader_t *device, char *filename,
 		      uint32_t *filesize )
 {
     uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ];
@@ -856,6 +864,84 @@
       return partition.Start + File.Location;
 }
 
+/**
+ * Get the offset from the ifo files to allow playback of DVDs
+ * with a deliberately broken UDF file system (aka DVD-Movie-Protect).
+ * When the file is not an IFO or VOB, it calls the real UDF routine.
+ */
+uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
+		      uint32_t *filesize )
+{
+#ifndef __WIN32__
+  if (!fnmatch("/VIDEO_TS/VTS_[0-9][0-9]_[0-9].???", filename, FNM_PATHNAME)) {
+#else
+  if (strlen("/VIDEO_TS/VTS_01_1.VOB") == strlen(filename)
+      && !strncmp(filename, "/VIDEO_TS/VTS_", strlen("/VIDEO_TS/VTS_"))	) {
+#endif
+		size_t len = strlen(filename);
+		char *extension = &filename[len-3];
+		if (!strcmp(extension, "IFO") || !strcmp(extension, "VOB")) {
+			int title = atoi(&filename[len-8]);
+			int part = atoi(&filename[len-5]);
+
+			ifo_handle_t *ifo_handle = ifoOpen(device, 0);
+			if (0 == ifo_handle)
+				return 0;
+
+			uint32_t tmp_filesize;
+			uint32_t offset = UDFFindFileReal(device, "/VIDEO_TS/VIDEO_TS.IFO", &tmp_filesize);
+
+			int i;
+			for (i=0; i<ifo_handle->tt_srpt->nr_of_srpts; i++)
+				if (title == ifo_handle->tt_srpt->title[i].title_set_nr)
+					break;
+
+			if (i == ifo_handle->tt_srpt->nr_of_srpts) {
+				/* not found */
+				ifoClose(ifo_handle);
+				return 0;
+			}
+			offset += ifo_handle->tt_srpt->title[i].title_set_sector;
+			ifoClose(ifo_handle);
+
+			if (!strcmp(extension, "VOB")) {
+				ifo_handle = ifoOpen(device, title);
+				if (0 == ifo_handle)
+					return 0;
+
+				switch(part) {
+					case 0:
+						if (0 == ifo_handle->vtsi_mat->vtsm_vobs) {
+							ifoClose(ifo_handle);
+							return 0;
+						}
+						offset += ifo_handle->vtsi_mat->vtsm_vobs;
+						break;
+					case 1:
+						if (0 == ifo_handle->vtsi_mat->vtstt_vobs) {
+							ifoClose(ifo_handle);
+							return 0;
+						}
+						offset += ifo_handle->vtsi_mat->vtstt_vobs;
+						break;
+					default: /* can't get other parts (also no need to) */
+						offset = 0;
+						break;
+				}
+
+				ifoClose(ifo_handle);
+			}
+
+
+			*filesize = 1000000; /* File size unknown */
+			if (offset != 0)
+				return offset;
+		}
+	}
+
+	return UDFFindFileReal( device, filename, filesize);
+}
+
 
 
 /**