+ block_t self;
+ void *base_addr;
+ size_t length;
+} block_mmap_t;
+
+static void block_mmap_Release (block_t *block)
+{
+ block_mmap_t *p_sys = (block_mmap_t *)block;
+
+ munmap (p_sys->base_addr, p_sys->length);
+ free (p_sys);
+}
+
+/**
+ * Creates a block from a virtual address memory mapping (mmap).
+ * This is provided by LibVLC so that mmap blocks can safely be deallocated
+ * even after the allocating plugin has been unloaded from memory.
+ *
+ * @param addr base address of the mapping (as returned by mmap)
+ * @param length length (bytes) of the mapping (as passed to mmap)
+ * @return NULL if addr is MAP_FAILED, or an error occurred (in the later
+ * case, munmap(addr, length) is invoked before returning).
+ */
+block_t *block_mmap_Alloc (void *addr, size_t length)
+{
+ if (addr == MAP_FAILED)
+ return NULL;
+
+ block_mmap_t *block = malloc (sizeof (*block));
+ if (block == NULL)
+ {
+ munmap (addr, length);
+ return NULL;
+ }
+
+ block_Init (&block->self, (uint8_t *)addr, length);
+ block->self.pf_release = block_mmap_Release;
+ block->base_addr = addr;
+ block->length = length;
+ return &block->self;
+}
+#else
+block_t *block_mmap_Alloc (void *addr, size_t length)
+{
+ (void)addr; (void)length; return NULL;
+}
+#endif
+
+
+#ifdef WIN32
+static
+ssize_t pread (int fd, void *buf, size_t count, off_t offset)
+{
+ HANDLE handle = (HANDLE)(intptr_t)_get_osfhandle (fd);
+ if (handle == INVALID_HANDLE_VALUE)
+ return -1;
+
+ OVERLAPPED olap = { .Offset = offset, .OffsetHigh = (offset >> 32), };
+ DWORD written;
+ /* This braindead API will override the file pointer even if we specify
+ * an explicit read offset... So do not expect this to mix well with
+ * regular read() calls. */
+ if (ReadFile (handle, buf, count, &written, &olap))
+ return written;
+ return -1;