+static noinline_for_stack int
+load_object_id(ntfs_inode *ni, struct wim_inode *inode)
+{
+ OBJECT_ID_ATTR attr;
+ int len;
+
+ len = ntfs_get_ntfs_object_id(ni, (char *)&attr, sizeof(attr));
+ if (likely(len == -ENODATA || len == 0))
+ return 0;
+ if (len < 0)
+ return WIMLIB_ERR_NTFS_3G;
+ if (!inode_set_object_id(inode, &attr, len))
+ return WIMLIB_ERR_NOMEM;
+ return 0;
+}
+
+/* Load the security descriptor of an NTFS inode into the corresponding WIM
+ * inode and the WIM image's security descriptor set. */
+static noinline_for_stack int
+get_security_descriptor(ntfs_inode *ni, struct wim_inode *inode,
+ ntfs_volume *vol, struct wim_sd_set *sd_set)
+{
+ struct SECURITY_CONTEXT scx = {.vol = vol};
+ char _buf[4096];
+ char *buf = _buf;
+ size_t avail_size = sizeof(_buf);
+ int ret;
+
+retry:
+ ret = ntfs_get_ntfs_acl(&scx, ni, buf, avail_size);
+ if (unlikely(ret < 0)) {
+ ret = WIMLIB_ERR_NTFS_3G;
+ goto out;
+ }
+
+ if (unlikely(ret > avail_size)) {
+ if (unlikely(buf != _buf))
+ FREE(buf);
+ buf = MALLOC(ret);
+ if (!buf) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out;
+ }
+ avail_size = ret;
+ goto retry;
+ }
+
+ if (likely(ret > 0)) {
+ inode->i_security_id = sd_set_add_sd(sd_set, buf, ret);
+ if (unlikely(inode->i_security_id < 0)) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out;
+ }
+ }
+
+ ret = 0;
+out:
+ if (unlikely(buf != _buf))
+ FREE(buf);
+ return ret;
+}
+