diff --git a/Makefile.in b/Makefile.in
index 67373b59..e6cdb357 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1100,10 +1100,14 @@ all-dist:
 ## make deploy
 ##
 
+STEAMPIPE_FIXUPS_PY := $(SRCDIR)/steampipe_fixups.py
+
 .PHONY: deploy
 deploy: all
 	mkdir -p $(DEPLOY_DIR) && \
 	rsync --delete --exclude compatibilitytool.vdf -arx $(DST_BASE)/ $(DEPLOY_DIR)
+	cp -a $(STEAMPIPE_FIXUPS_PY) $(DEPLOY_DIR)
+	python3 $(STEAMPIPE_FIXUPS_PY) process $(DEPLOY_DIR)
 
 
 ##
diff --git a/proton b/proton
index 87cba9ba..7afd9ba7 100755
--- a/proton
+++ b/proton
@@ -435,6 +435,28 @@ class Proton:
                 if file_exists(old_dist_dir, follow_symlinks=True):
                     shutil.rmtree(old_dist_dir)
 
+    def do_steampipe_fixups(self):
+        fixups_json = self.path("steampipe_fixups.json")
+        fixups_mtime = self.path("files/steampipe_fixups_mtime")
+
+        if file_exists(fixups_json, follow_symlinks=True):
+            with self.dist_lock:
+                import steampipe_fixups
+
+                current_fixup_mtime = None
+                if file_exists(fixups_mtime, follow_symlinks=True):
+                    with open(fixups_mtime, "r") as f:
+                        current_fixup_mtime = f.readline().strip()
+
+                new_fixup_mtime = getmtimestr(fixups_json)
+
+                if current_fixup_mtime != new_fixup_mtime:
+                    result_code = steampipe_fixups.do_restore(self.base_dir, fixups_json)
+
+                    if result_code == 0:
+                        with open(fixups_mtime, "w") as f:
+                            f.write(new_fixup_mtime + "\n")
+
     def missing_default_prefix(self):
         '''Check if the default prefix dir is missing. Returns true if missing, false if present'''
         return not os.path.isdir(self.default_pfx_dir)
@@ -769,10 +791,10 @@ class CompatData:
 
             self.migrate_user_paths()
 
-            if not os.path.lexists(self.prefix_dir + "/dosdevices/c:"):
+            if not file_exists(self.prefix_dir + "/dosdevices/c:", follow_symlinks=False):
                 os.symlink("../drive_c", self.prefix_dir + "/dosdevices/c:")
 
-            if not os.path.lexists(self.prefix_dir + "/dosdevices/z:"):
+            if not file_exists(self.prefix_dir + "/dosdevices/z:", follow_symlinks=False):
                 os.symlink("/", self.prefix_dir + "/dosdevices/z:")
 
             # collect configuration info
@@ -1680,6 +1702,7 @@ if __name__ == "__main__":
     g_proton = Proton(os.path.dirname(sys.argv[0]))
 
     g_proton.cleanup_legacy_dist()
+    g_proton.do_steampipe_fixups()
 
     g_compatdata = CompatData(os.environ["STEAM_COMPAT_DATA_PATH"])
 
diff --git a/steampipe_fixups.py b/steampipe_fixups.py
new file mode 100755
index 00000000..e5646ebe
--- /dev/null
+++ b/steampipe_fixups.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+
+#Steampipe doesn't support certain unix-y things which may be required by
+#native Linux applications. This file will process a directory of Linux files
+#and store the file properties into a manifest file. After a round trip through
+#Steampipe, the original file properties can be restored using this same
+#script.
+
+import json
+import os
+import secrets
+import stat
+
+DEFAULT_MANIFEST_NAME = "steampipe_fixups.json"
+
+def usage():
+    print("Usage:")
+    print("\t" + sys.argv[0] + "\tprepare\t<path to directory to process>\t[manifest output file]")
+    print("\t\tProcess the given path and output the manifest file to the given path, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
+    print("")
+    print("\t" + sys.argv[0] + "\trestore\t<path to directory to process>\t[manifest file]")
+    print("\t\tRestore the given path using the manifest file, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
+
+empty_dirs = []
+no_write_paths = []
+
+def canonicalize(path, prefix):
+    return path.replace(prefix, "", 1).lstrip('/')
+
+def process_dir(path):
+    for root, subdirs, files in os.walk(path):
+        if len(subdirs) == 0 and len(files) == 0:
+            empty_dirs.append(canonicalize(root, path))
+
+        for file_ in files:
+            this_file = os.path.join(root, file_)
+            stat_result = os.lstat(this_file)
+            if (stat_result.st_mode & stat.S_IWUSR) == 0:
+                no_write_paths.append(canonicalize(this_file, path))
+
+    return 0
+
+def write_manifest(manifest):
+    out = open(manifest, "w")
+    json.dump(
+        {
+            "id": str(secrets.randbits(32)), #we need steampipe to update this file for every build
+            "empty_dirs": empty_dirs,
+            "no_write_paths": no_write_paths,
+        },
+        out,
+        indent = 4,
+        sort_keys = True
+    )
+    return 0
+
+def do_process(path, manifest):
+    if os.path.exists(manifest):
+        os.remove(manifest)
+
+    ret = process_dir(path)
+    if ret != 0:
+        return ret
+
+    #output should be deterministic
+    empty_dirs.sort()
+    no_write_paths.sort()
+
+    ret = write_manifest(manifest)
+    if ret != 0:
+        return ret
+
+    return 0
+
+def do_restore(path, manifest):
+    loaded = json.load(open(manifest, "r"))
+
+    empty_dirs = loaded["empty_dirs"]
+    no_write_paths = loaded["no_write_paths"]
+
+    for empty_dir in empty_dirs:
+        try:
+            os.makedirs(os.path.join(path, empty_dir))
+        except OSError:
+            #already exists
+            pass
+
+    for file_ in no_write_paths:
+        this_file = os.path.join(path, file_)
+        stat_result = os.lstat(this_file)
+        os.chmod(this_file,
+                stat_result.st_mode & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
+
+    return 0
+
+if __name__ == '__main__':
+    import sys
+    if len(sys.argv) < 3 or len(sys.argv) > 4:
+        usage()
+        sys.exit(1)
+
+    verb = sys.argv[1]
+    path = sys.argv[2]
+    if len(sys.argv) >= 4:
+        manifest = sys.argv[3]
+    else:
+        manifest = os.path.join(path, DEFAULT_MANIFEST_NAME)
+
+    if verb == "process":
+        sys.exit(do_process(path, manifest))
+
+    if verb == "restore":
+        sys.exit(do_restore(path, manifest))
+
+    usage()
+    sys.exit(1)