LoadDLLfunc (VirtualAlloc2, KernelBase)
LoadDLLfunc (NtMapViewOfSectionEx, ntdll)
+LoadDLLfuncEx (RtlSetProcessPlaceholderCompatibilityMode, ntdll, 1)
LoadDLLfunc (ldap_bind_s, wldap32)
LoadDLLfunc (ldap_count_entries, wldap32)
if (dynamically_loaded)
sigproc_init ();
+ /* Call this before accessing any files. */
+ RtlSetProcessPlaceholderCompatibilityMode (PHCM_EXPOSE_PLACEHOLDERS);
+
check_sanity_and_sync (user_data);
/* Initialize malloc and then call user_shared_initialize since it relies
bool ret = false;
status = NtOpenFile (&reph, READ_CONTROL, attr, &io, FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
+ FILE_OPEN_NO_RECALL
+ | FILE_OPEN_FOR_BACKUP_INTENT
+ | FILE_OPEN_REPARSE_POINT);
if (NT_SUCCESS (status))
{
PREPARSE_DATA_BUFFER rp = (PREPARSE_DATA_BUFFER) tp.c_get ();
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
&attr, &io, FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT
+ | FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_DIRECTORY_FILE);
if (!NT_SUCCESS (status))
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL,
pc.get_object_attr (attr, sec_none_nih),
&io, FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT));
+ FILE_OPEN_NO_RECALL
+ | FILE_OPEN_FOR_BACKUP_INTENT));
if (!opened)
{
/* Can't open file. Try again with parent dir. */
attr.ObjectName = &dirname;
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL, &attr, &io,
FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT));
+ FILE_OPEN_NO_RECALL
+ | FILE_OPEN_FOR_BACKUP_INTENT));
if (!opened)
goto out;
}
|| NT_SUCCESS (NtOpenFile (&hdl, READ_CONTROL,
pc.get_object_attr (attr, sec_none_nih),
&io, FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT
+ FILE_OPEN_NO_RECALL
+ | FILE_OPEN_FOR_BACKUP_INTENT
| (pc.is_known_reparse_point ()
? FILE_OPEN_REPARSE_POINT : 0)))
)
Mountpoints and unknown or unhandled reparse points will be treated
as normal file/directory/unknown. In all cases, returning the INO of
the reparse point (not of the target) matches behavior of posix systems.
+ Unless the file is OFFLINE. *.
*/
- if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
+ if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) && !isoffline (attr))
{
OBJECT_ATTRIBUTES oattr;
&nfs_aol_ffei, sizeof nfs_aol_ffei)
: NtOpenFile (&hdl, READ_CONTROL, &attr, &io,
FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT
+ FILE_OPEN_NO_RECALL
+ | FILE_OPEN_FOR_BACKUP_INTENT
| FILE_OPEN_REPARSE_POINT);
if (NT_SUCCESS (f_status))
{
#define FILE_VC_QUOTAS_REBUILDING 0x00000200
#define FILE_VC_VALID_MASK 0x000003ff
+#define PHCM_APPLICATION_DEFAULT 0
+#define PHCM_DISGUISE_PLACEHOLDER 1
+#define PHCM_EXPOSE_PLACEHOLDERS 2
+#define PHCM_MAX 2
+#define PHCM_ERROR_INVALID_PARAMETER -1
+#define PHCM_ERROR_NO_TEB -2
+
/* IOCTL code to impersonate client of named pipe. */
#define FSCTL_PIPE_DISCONNECT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 1, \
BOOLEAN);
NTSTATUS RtlSetGroupSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID, BOOLEAN);
NTSTATUS RtlSetOwnerSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID, BOOLEAN);
+ CHAR RtlSetProcessPlaceholderCompatibilityMode (CHAR);
PUCHAR RtlSubAuthorityCountSid (PSID);
PULONG RtlSubAuthoritySid (PSID, ULONG);
ULONG RtlUnicodeStringToAnsiSize (PUNICODE_STRING);
&& (attributes & attribs_to_test);
}
+extern inline bool
+isoffline (DWORD attributes)
+{
+ return has_attribute (attributes, FILE_ATTRIBUTE_OFFLINE
+ | FILE_ATTRIBUTE_RECALL_ON_OPEN
+ | FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS);
+}
+
enum executable_states
{
is_executable,
bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
+ bool isoffline () const
+ {
+ return has_attribute (FILE_ATTRIBUTE_OFFLINE
+ | FILE_ATTRIBUTE_RECALL_ON_OPEN
+ | FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS);
+ }
executable_states exec_state ()
{
extern int _check_for_executable;
return is_executable;
if (mount_flags & MOUNT_NOTEXEC)
return not_executable;
- if (!_check_for_executable)
+ if (isoffline () || !_check_for_executable)
return dont_care_if_executable;
return dont_know_if_executable;
}
#define FILE_SUPPORTS_GHOSTING 0x40000000
#endif
+#ifndef FILE_ATTRIBUTE_RECALL_ON_OPEN
+#define FILE_ATTRIBUTE_RECALL_ON_OPEN 0x00040000
+#endif
+#ifndef FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS
+#define FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000
+#endif
+
/* So-called "Microsoft Account" SIDs (S-1-11-...) have a netbios domain name
"MicrosoftAccounts". The new "Application Container SIDs" (S-1-15-...)
have a netbios domain name "APPLICATION PACKAGE AUTHORITY"
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
&attr, &io, FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT
+ | FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_DIRECTORY_FILE);
if (NT_SUCCESS (status))
}
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES,
&attr, &io, FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_REPARSE_POINT
+ FILE_OPEN_NO_RECALL
+ | FILE_OPEN_REPARSE_POINT
| FILE_OPEN_FOR_BACKUP_INTENT);
debug_printf ("%y = NtOpenFile (no-EAs %S)", status, &upath);
}
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
&dattr, &io, FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT
+ | FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_DIRECTORY_FILE);
if (!NT_SUCCESS (status))
directory using a relative path, symlink evaluation goes totally
awry. We never want a virtual drive evaluated as symlink. */
if (upath.Length <= 14)
- goto file_not_symlink;
+ goto file_not_symlink;
+
+ /* Offline files, even if reparse points, are not symlinks. */
+ if (isoffline (fileattr ()))
+ goto file_not_symlink;
/* Reparse points are potentially symlinks. This check must be
performed before checking the SYSTEM attribute for sysfile
symlinks, since reparse points can have this flag set, too. */
- if ((fileattr () & FILE_ATTRIBUTE_REPARSE_POINT))
+ if (fileattr () & FILE_ATTRIBUTE_REPARSE_POINT)
{
res = check_reparse_point (h, fs.is_remote_drive ());
if (res > 0)
status = NtOpenFile (&sym_h, SYNCHRONIZE | GENERIC_READ, &attr, &io,
FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT
+ FILE_OPEN_NO_RECALL
+ | FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS (status))
res = 0;
status = NtOpenFile (&sym_h, SYNCHRONIZE | GENERIC_READ, &attr, &io,
FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT
+ FILE_OPEN_NO_RECALL
+ | FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS (status))