+static void
+print_security_descriptor(const void *desc, size_t size, FILE *fp)
+{
+ print_byte_field(desc, size, fp);
+#ifdef _WIN32
+ wchar_t *str = NULL;
+ ConvertSecurityDescriptorToStringSecurityDescriptorW(
+ (void *)desc,
+ SDDL_REVISION_1,
+ OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION |
+ SACL_SECURITY_INFORMATION,
+ &str,
+ NULL);
+ if (str) {
+ fprintf(fp, " [ %ls ]", str);
+ LocalFree(str);
+ }
+#endif /* _WIN32 */
+}
+
+static int
+cmp_security(const struct wim_inode *inode1, const struct wim_inode *inode2,
+ const struct wim_image_metadata *imd1,
+ const struct wim_image_metadata *imd2, int cmp_flags)
+{
+ /*
+ * Unfortunately this has to be disabled on Windows for now, since
+ * Windows changes security descriptors upon backup/restore in ways that
+ * are difficult to replicate...
+ */
+ if (cmp_flags & WIMLIB_CMP_FLAG_WINDOWS_MODE)
+ return 0;
+
+ if (inode_has_security_descriptor(inode1)) {
+ if (inode_has_security_descriptor(inode2)) {
+ const void *desc1 = imd1->security_data->descriptors[inode1->i_security_id];
+ const void *desc2 = imd2->security_data->descriptors[inode2->i_security_id];
+ size_t size1 = imd1->security_data->sizes[inode1->i_security_id];
+ size_t size2 = imd2->security_data->sizes[inode2->i_security_id];
+
+ if (size1 != size2 || memcmp(desc1, desc2, size1)) {
+ ERROR("Security descriptor of %"TS" differs!",
+ inode_any_full_path(inode1));
+ fprintf(stderr, "desc1=");
+ print_security_descriptor(desc1, size1, stderr);
+ fprintf(stderr, "\ndesc2=");
+ print_security_descriptor(desc2, size2, stderr);
+ fprintf(stderr, "\n");
+ return WIMLIB_ERR_IMAGES_ARE_DIFFERENT;
+ }
+ } else if (!(cmp_flags & WIMLIB_CMP_FLAG_UNIX_MODE)) {
+ ERROR("%"TS" has a security descriptor in the first image but "
+ "not in the second image!", inode_any_full_path(inode1));
+ return WIMLIB_ERR_IMAGES_ARE_DIFFERENT;
+ }
+ } else if (inode_has_security_descriptor(inode2)) {
+ /* okay --- consider it acceptable if a default security
+ * descriptor was assigned */
+ /*ERROR("%"TS" has a security descriptor in the second image but "*/
+ /*"not in the first image!", inode_any_full_path(inode1));*/
+ /*return WIMLIB_ERR_IMAGES_ARE_DIFFERENT;*/
+ }
+ return 0;
+}
+