public static void GetFileProperties(string path, out DateTimeOffset?creationTime, out DateTimeOffset?lastWriteTime, out FileAttributes?fileAttributes
#if DOTNET5_4
                                             , bool isDirectory = false
#endif
                                             )
        {
#if !DOTNET5_4
            path = LongPath.ToUncPath(path);

            if (path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
            {
                path = path.Substring(0, path.Length - 1);
            }

            NativeMethods.WIN32_FIND_DATA findData;
            NativeMethods.SafeFindHandle  findHandle;

            findHandle = NativeMethods.FindFirstFileW(path, out findData);

            if (findHandle.IsInvalid)
            {
                NativeMethods.ThrowExceptionForLastWin32ErrorIfExists();
            }
            else
            {
                findHandle.Dispose();
                findHandle = null;
            }

            long dt = (findData.LastWriteTime.dwLowDateTime & 0xFFFFFFFF);
            dt           |= ((long)findData.LastWriteTime.dwHighDateTime) << 32;
            lastWriteTime = DateTimeOffset.FromFileTime(dt).UtcDateTime;

            dt           = (findData.CreationTime.dwLowDateTime & 0xFFFFFFFF);
            dt          |= ((long)findData.CreationTime.dwHighDateTime) << 32;
            creationTime = DateTimeOffset.FromFileTime(dt).UtcDateTime;

            fileAttributes = (FileAttributes)findData.FileAttributes;
#else
            fileAttributes = File.GetAttributes(path);

            if (isDirectory)
            {
                creationTime  = Directory.GetCreationTimeUtc(path);
                lastWriteTime = Directory.GetLastWriteTimeUtc(path);
            }
            else
            {
                creationTime  = File.GetCreationTimeUtc(path);
                lastWriteTime = File.GetLastWriteTimeUtc(path);
            }
#endif

#if DEBUG
            if (null != TestHookCallbacks.GetFileAttributesCallback)
            {
                fileAttributes = TestHookCallbacks.GetFileAttributesCallback(path);
            }
#endif
        }
        public static void SetAttributes(string path, FileAttributes fileAttributes)
        {
#if DEBUG
            if (null != TestHookCallbacks.SetFileAttributesCallback)
            {
                TestHookCallbacks.SetFileAttributesCallback(path, fileAttributes);
                return;
            }
#endif

#if DOTNET5_4
            File.SetAttributes(path, fileAttributes);
#else
            if (!NativeMethods.SetFileAttributesW(path, (uint)(fileAttributes)))
            {
                NativeMethods.ThrowExceptionForLastWin32ErrorIfExists();
            }
#endif
        }
Пример #3
0
        public static string GetFilePortableSDDL(
            string filePath,
            PreserveSMBPermissions preserveSMBPermissions)
        {
#if DEBUG
            if (null != TestHookCallbacks.GetFilePermissionsCallback)
            {
                return(TestHookCallbacks.GetFilePermissionsCallback(filePath, preserveSMBPermissions));
            }
#endif

            if (preserveSMBPermissions == PreserveSMBPermissions.None)
            {
                return(null);
            }

            string sddl      = GetFileSDDL(filePath, ToSecurityInfo(preserveSMBPermissions));
            string userName  = GetUserName();
            string domainSid = GetDomainSid(userName);
            return(GetPortableSDDL(sddl, domainSid));
        }
Пример #4
0
        public static void SetFileSecurity(string filePath, string portableSDDL, PreserveSMBPermissions preserveSMBPermissions)
        {
#if DEBUG
            if (null != TestHookCallbacks.SetFilePermissionsCallback)
            {
                TestHookCallbacks.SetFilePermissionsCallback(filePath, portableSDDL, preserveSMBPermissions);
                return;
            }
#endif

            filePath = LongPath.ToUncPath(filePath);

            if (PreserveSMBPermissions.None == preserveSMBPermissions)
            {
                return;
            }

            if (string.IsNullOrEmpty(portableSDDL))
            {
                return;
            }

            IntPtr  pSecurityDescriptor      = new IntPtr();
            UIntPtr securityDescriptorLength = new UIntPtr();

            if (!NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptor(portableSDDL,
                                                                                   NativeMethods.SDDL_REVISION_1,
                                                                                   out pSecurityDescriptor,
                                                                                   out securityDescriptorLength))
            {
                throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            try
            {
                NativeMethods.SetFileSecurity(filePath,
                                              (int)(ToSecurityInfo(preserveSMBPermissions)),
                                              pSecurityDescriptor);

                int errorCode = Marshal.GetLastWin32Error();
                int hresult   = Marshal.GetHRForLastWin32Error();

                if ((errorCode == NativeMethods.ERROR_PRIVILEGE_NOT_HELD) ||
                    (errorCode == NativeMethods.ERROR_ACCESS_DENIED) ||
                    (errorCode == NativeMethods.ERROR_INVALID_OWNER))
                {
#if !DMLIB_TEST
                    string privilegeName = null;

                    if ((preserveSMBPermissions & PreserveSMBPermissions.Owner) == PreserveSMBPermissions.Owner)
                    {
                        privilegeName = NativeMethods.OwnerPrivilegeName;
                    }

                    if ((preserveSMBPermissions & PreserveSMBPermissions.SACL) == PreserveSMBPermissions.SACL)
                    {
                        if (null == privilegeName)
                        {
                            privilegeName = NativeMethods.SACLPrivilegeName;
                        }
                        else
                        {
                            privilegeName += " ";
                            privilegeName += NativeMethods.SACLPrivilegeName;
                        }
                    }

                    if (null != privilegeName)
                    {
                        throw new TransferException(
                                  string.Format(
                                      CultureInfo.CurrentCulture,
                                      Resources.PrivilegeRequiredException,
                                      privilegeName));
                    }
#else
                    throw new Win32Exception(errorCode);
#endif
                }

                if (errorCode != 0)
                {
                    Marshal.ThrowExceptionForHR(hresult);
                }
            }
            finally
            {
                NativeMethods.LocalFree(pSecurityDescriptor);
            }
        }