Index: file.inc.1.90.2.3
===================================================================
--- file.inc.1.90.2.3   (revision 12)
+++ file.inc.1.90.2.3   (working copy)
@@ -575,9 +575,10 @@

 /**
  * Call modules that implement hook_file_download() to find out if a file is
- * accessible and what headers it should be transferred with. If a module
- * returns -1 drupal_access_denied() will be returned. If one or more modules
- * returned headers the download will start with the returned headers. If no
+ * accessible and what headers it should be transferred with, taking these modules' hooks'
+ * relative weight into account. If the hook with the lowest weight
+ * returns -1 drupal_access_denied() will be returned. If it returned headers
+ * the download will start with the returned headers. If no
  * modules respond drupal_not_found() will be returned.
  */

@@ -592,7 +593,47 @@
   }

   if (file_exists(file_create_path($filepath))) {
-    $headers = module_invoke_all('file_download', $filepath);
+    // Are there modules that want their hook_file_download() to take precedence?
+    if (count(module_implements('file_download_weight'))) {
+      // Get list of modules that implement hook_file_download()
+      $modules = module_implements('file_download');
+      $list = array();
+      if (count($modules)) {
+        // There are modules that implement hook_file_download()
+        foreach ($modules as $module) {
+          // Try to retrieve their relative weight by calling hook_file_download_weight(),
+          // with $filepath as argument; if hook_file_download_weight() is not implemented
+          // for this module, default to 0
+          $function = $module.'_file_download_weight';
+          if (function_exists($function)) {
+            $weight = call_user_func($function, $filepath);
+          }
+          else {
+            $weight = 0;
+          }
+          $list[$weight][] = $module; // Put module name in list sorted by weight
+        }
+        // Sort modules by weight
+        ksort($list, SORT_NUMERIC);
+        // Get all modules with lowest weight and iterate through them until
+        // one returns a set of headers or -1
+        $modules = reset($list);
+        foreach ($modules as $module) {
+          $headers = module_invoke($module, 'file_download', $filepath);
+          if (count($headers)) {
+            $headers = (array)$headers;
+            break;
+          }
+        }
+        if (!is_array($headers)) {
+          $headers = array();
+        }
+      }
+    }
+    else {
+      // Use default method of invoking all hooks indiscriminately
+      $headers = module_invoke_all('file_download', $filepath);
+    }
     if (in_array(-1, $headers)) {
         return drupal_access_denied();
     }