public long Skip(long bytes)
        {
            uint lowSought, highSought;

            if (!NativeMethods.BackupSeek(mFileHandle, NativeMethods.GetLowOrderDword(bytes), NativeMethods.GetHighOrderDword(bytes),
                                          out lowSought, out highSought, ref mContext))
            {
                int errorCode = Marshal.GetLastWin32Error();

                // Error Code 25 indicates a seek error, we just skip that here.
                if (errorCode != 0 && errorCode != 25)
                {
                    Console.WriteLine("Error code = {0}", errorCode);
                    NativeError.ThrowException(errorCode);
                }
            }
            return(((long)lowSought & 0xFFFFFFFF) | ((long)highSought << 32));
        }
        public virtual void Lock(long position, long length)
        {
            if (position < 0)
            {
                throw new ArgumentOutOfRangeException("position", position, "Position must not be negative.");
            }

            if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length", length, "Length must not be negative.");
            }

            if (!NativeMethods.LockFile(mFileHandle,
                                        NativeMethods.GetLowOrderDword(position),
                                        NativeMethods.GetHighOrderDword(position),
                                        NativeMethods.GetLowOrderDword(length),
                                        NativeMethods.GetHighOrderDword(length)))
            {
                NativeError.ThrowException();
            }
        }
        public int Read(byte[] buffer, int offset, int count, bool processSecurity)
        {
            if (!CanRead)
            {
                throw new NotSupportedException("Stream does not support reading");
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (offset + count > buffer.Length)
            {
                throw new ArgumentException("The sum of offset and count is larger than the size of the buffer.");
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", Resources.OffsetMustNotBeNegative);
            }

            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", Resources.CountMustNotBeNegative);
            }

            using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(count))
            {
                uint numberOfBytesRead;
                if (!NativeMethods.BackupRead(mFileHandle, hBuf, (uint)hBuf.Capacity, out numberOfBytesRead, false, processSecurity, ref mContext))
                {
                    NativeError.ThrowException();
                }

                hBuf.CopyTo(buffer, offset, count);

                return((int)numberOfBytesRead);
            }
        }
Beispiel #4
0
        private static NativeMethods.RemoteNameInfo GetMappedInfoInternal(string path)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path", "The specified path cannot be NULL.");
            }

            if (IsLongPath(path))
            {
                throw new ArgumentException("Long paths are not supported but this method.");
            }

            if (path.Length > NativeMethods.MAX_PATH)
            {
                throw new System.IO.PathTooLongException();
            }

            int bufferSize = 0;
            SafeGlobalMemoryBufferHandle safeBuffer = new SafeGlobalMemoryBufferHandle(bufferSize);

            uint retVal;

            // first call is to get correct buffer size to store results.
            if ((retVal = NativeMethods.WNetGetUniversalName(path, NativeMethods.REMOTE_NAME_INFO_LEVEL, safeBuffer, ref bufferSize)) != Win32Errors.ERROR_MORE_DATA)
            {
                NativeError.ThrowException(retVal);
            }

            safeBuffer = new SafeGlobalMemoryBufferHandle(bufferSize);

            if ((retVal = NativeMethods.WNetGetUniversalName(path, NativeMethods.REMOTE_NAME_INFO_LEVEL, safeBuffer, ref bufferSize)) != Win32Errors.NO_ERROR)
            {
                NativeError.ThrowException(retVal);
            }

            return((NativeMethods.RemoteNameInfo)Marshal.PtrToStructure(safeBuffer.DangerousGetHandle(), typeof(NativeMethods.RemoteNameInfo)));
        }
        public FileSecurity GetAccessControl()
        {
            IntPtr pSidOwner, pSidGroup, pDacl, pSacl;
            SafeLocalMemoryBufferHandle pSecurityDescriptor;
            uint errorCode = SecurityNativeMethods.GetSecurityInfo(mFileHandle, SecurityNativeMethods.SE_OBJECT_TYPE.SE_FILE_OBJECT,
                                                                   SecInfo.DACL_SECURITY_INFORMATION | SecInfo.GROUP_SECURITY_INFORMATION | SecInfo.OWNER_SECURITY_INFORMATION |
                                                                   SecInfo.LABEL_SECURITY_INFORMATION | SecInfo.SACL_SECURITY_INFORMATION,
                                                                   out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor);

            try
            {
                if (errorCode != 0)
                {
                    NativeError.ThrowException(errorCode);
                }

                if (!SecurityNativeMethods.IsValidSecurityDescriptor(pSecurityDescriptor))
                {
                    throw new System.IO.IOException(Resources.InvalidSecurityDescriptorReturnedFromSystem);
                }

                uint length = SecurityNativeMethods.GetSecurityDescriptorLength(pSecurityDescriptor);

                byte[] managedBuffer = new byte[length];

                pSecurityDescriptor.CopyTo(managedBuffer, 0, (int)length);

                FileSecurity fs = new FileSecurity();
                fs.SetSecurityDescriptorBinaryForm(managedBuffer);
                return(fs);
            }
            finally
            {
                pSecurityDescriptor.Dispose();
            }
        }
        public static LinkTargetInfo GetLinkTargetInfo(SafeHandle device)
        {
            UInt32 bytesReturned;

            int       lastError   = 0;
            const int maxCapacity = 0x3FF0;

            SafeGlobalMemoryBufferHandle buffer = new SafeGlobalMemoryBufferHandle(512);

            try
            {
                do
                {
                    if (!NativeMethods.DeviceIoControl(device, IoControlCode.FsctlGetReparsePoint, new SafeGlobalMemoryBufferHandle(), 0, buffer, (uint)buffer.Capacity, out bytesReturned, IntPtr.Zero))
                    {
                        lastError = Marshal.GetLastWin32Error();
                        if (lastError == Win32Errors.ERROR_INSUFFICIENT_BUFFER && buffer.Capacity < maxCapacity)
                        {
                            buffer.Dispose();
                            buffer = null;
                            buffer = new SafeGlobalMemoryBufferHandle(maxCapacity);
                            continue;
                        }
                        NativeError.ThrowException(lastError);
                    }
                    else
                    {
                        break;
                    }
                }while (true);

                IntPtr bufPtr = buffer.DangerousGetHandle();
                ReparseDataBufferHeader header = (ReparseDataBufferHeader)Marshal.PtrToStructure(bufPtr, typeof(ReparseDataBufferHeader));

                if (header.ReparseTag == ReparsePointTag.MountPoint)
                {
                    MountPointReparseBuffer mpBuf = (MountPointReparseBuffer)Marshal.PtrToStructure(AddPtr(bufPtr, Marshal.OffsetOf(typeof(ReparseDataBufferHeader), "data")), typeof(MountPointReparseBuffer));
                    IntPtr dataPos    = AddPtr(Marshal.OffsetOf(typeof(ReparseDataBufferHeader), "data"), Marshal.OffsetOf(typeof(MountPointReparseBuffer), "data"));
                    byte[] dataBuffer = new byte[bytesReturned - dataPos.ToInt64()];
                    Marshal.Copy(AddPtr(bufPtr, dataPos), dataBuffer, 0, dataBuffer.Length);
                    return(new LinkTargetInfo(
                               Encoding.Unicode.GetString(dataBuffer, mpBuf.SubstituteNameOffset, mpBuf.SubstituteNameLength),
                               Encoding.Unicode.GetString(dataBuffer, mpBuf.PrintNameOffset, mpBuf.PrintNameLength)
                               ));
                }
                else if (header.ReparseTag == ReparsePointTag.SymLink)
                {
                    SymbolicLinkReparseBuffer mpBuf = (SymbolicLinkReparseBuffer)Marshal.PtrToStructure(AddPtr(bufPtr, Marshal.OffsetOf(typeof(ReparseDataBufferHeader), "data")), typeof(SymbolicLinkReparseBuffer));
                    IntPtr dataPos    = AddPtr(Marshal.OffsetOf(typeof(ReparseDataBufferHeader), "data"), Marshal.OffsetOf(typeof(SymbolicLinkReparseBuffer), "data"));
                    byte[] dataBuffer = new byte[bytesReturned - dataPos.ToInt64()];
                    Marshal.Copy(AddPtr(bufPtr, dataPos), dataBuffer, 0, dataBuffer.Length);
                    return(new SymbolicLinkTargetInfo(
                               Encoding.Unicode.GetString(dataBuffer, mpBuf.SubstituteNameOffset, mpBuf.SubstituteNameLength),
                               Encoding.Unicode.GetString(dataBuffer, mpBuf.PrintNameOffset, mpBuf.PrintNameLength),
                               (SymbolicLinkType)mpBuf.Flags
                               ));
                }
                else
                {
                    throw new UnrecognizedReparsePointException();
                }
            }
            finally
            {
                if (buffer != null)
                {
                    buffer.Dispose();
                }
            }
        }
        internal static void SetSecurityInfo(SafeHandle handle, NativeMethods.SE_OBJECT_TYPE objectType, NativeObjectSecurity fileSecurity)
        {
            byte[] managedDescriptor = fileSecurity.GetSecurityDescriptorBinaryForm();
            using (SafeGlobalMemoryBufferHandle hDescriptor = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length))
            {
                hDescriptor.CopyFrom(managedDescriptor, 0, managedDescriptor.Length);


                NativeMethods.SECURITY_DESCRIPTOR_CONTROL control;
                uint revision;
                if (!NativeMethods.GetSecurityDescriptorControl(hDescriptor, out control, out revision))
                {
                    NativeError.ThrowException();
                }

                IntPtr pDacl;
                bool   daclDefaulted, daclPresent;
                if (!NativeMethods.GetSecurityDescriptorDacl(hDescriptor, out daclPresent, out pDacl, out daclDefaulted))
                {
                    NativeError.ThrowException();
                }

                IntPtr pSacl;
                bool   saclDefaulted, saclPresent;
                if (!NativeMethods.GetSecurityDescriptorSacl(hDescriptor, out saclPresent, out pSacl, out saclDefaulted))
                {
                    NativeError.ThrowException();
                }

                IntPtr pOwner;
                bool   ownerDefaulted;
                if (!NativeMethods.GetSecurityDescriptorOwner(hDescriptor, out pOwner, out ownerDefaulted))
                {
                    NativeError.ThrowException();
                }

                IntPtr pGroup;
                bool   GroupDefaulted;
                if (!NativeMethods.GetSecurityDescriptorGroup(hDescriptor, out pGroup, out GroupDefaulted))
                {
                    NativeError.ThrowException();
                }

                PrivilegeEnabler privilegeEnabler = null;

                NativeMethods.SECURITY_INFORMATION info = 0;

                if (daclPresent)
                {
                    info |= NativeMethods.SECURITY_INFORMATION.DACL_SECURITY_INFORMATION;

                    if ((control & NativeMethods.SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PROTECTED) != 0)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.PROTECTED_DACL_SECURITY_INFORMATION;
                    }
                    else
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION;
                    }
                }

                if (saclPresent)
                {
                    info |= NativeMethods.SECURITY_INFORMATION.SACL_SECURITY_INFORMATION;
                    if ((control & NativeMethods.SECURITY_DESCRIPTOR_CONTROL.SE_SACL_PROTECTED) != 0)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.PROTECTED_SACL_SECURITY_INFORMATION;
                    }
                    else
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION;
                    }

                    privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
                }

                if (pOwner != IntPtr.Zero)
                {
                    info |= NativeMethods.SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION;
                }

                if (pGroup != IntPtr.Zero)
                {
                    info |= NativeMethods.SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION;
                }

                try
                {
                    uint errorCode = NativeMethods.SetSecurityInfo(handle, objectType, info, pOwner, pGroup, pDacl, pSacl);

                    if (errorCode != 0)
                    {
                        NativeError.ThrowException((int)errorCode);
                    }
                }
                finally
                {
                    if (privilegeEnabler != null)
                    {
                        privilegeEnabler.Dispose();
                    }
                }
            }
        }
        public bool MoveNext()
        {
            mInfo = new FileSystemEntryInfo();
            if (mHandle == null)
            {
                if (mTransaction == null)
                {
                    mHandle = NativeMethods.FindFirstFileExW(mPath,
                                                             NativeMethods.FINDEX_INFO_LEVELS.FindExInfoStandard,
                                                             mInfo, mFindexSearchOptions,
                                                             IntPtr.Zero, NativeMethods.FINDEX_FLAGS.FIND_FIRST_EX_NONE);
                }
                else
                {
                    mHandle = NativeMethods.FindFirstFileTransactedW(mPath,
                                                                     NativeMethods.FINDEX_INFO_LEVELS.FindExInfoStandard, mInfo,
                                                                     mFindexSearchOptions, IntPtr.Zero,
                                                                     NativeMethods.FINDEX_FLAGS.FIND_FIRST_EX_NONE, mTransaction.SafeHandle);
                }

                if (mHandle.IsInvalid)
                {
                    uint error = (uint)Marshal.GetLastWin32Error();
                    if (error == Win32Errors.ERROR_FILE_NOT_FOUND)
                    {
                        return(false);
                    }
                    else
                    {
                        NativeError.ThrowException(error, mPath, mPath);
                    }
                }
                return(Filter());
            }
            else if (mHandle.IsInvalid)
            {
                return(false);
            }
            else
            {
                if (!NativeMethods.FindNextFileW(mHandle, mInfo))
                {
                    uint error = (uint)Marshal.GetLastWin32Error();
                    if (error == Win32Errors.ERROR_NO_MORE_FILES)
                    {
                        mHandle.Close();
                        return(false);
                    }
                    else
                    {
                        NativeError.ThrowException(error);
                    }
                }
                else
                {
                    return(Filter());
                }
            }
            // Actually unreachable code, but seems to be neccessary.
            return(false);
        }