public void Dispose() { if (lpSecurityDescriptor != null) { lpSecurityDescriptor.Close(); } }
public void Dispose() { if (null != _securityDescriptor && !_securityDescriptor.IsClosed) { _securityDescriptor.Close(); } }
private static SafeGlobalMemoryBufferHandle GetLinkTargetData(SafeFileHandle safeHandle, string reparsePath) { var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE); while (true) { uint bytesReturned; var success = NativeMethods.DeviceIoControl(safeHandle, NativeMethods.FSCTL_GET_REPARSE_POINT, IntPtr.Zero, 0, safeBuffer, (uint)safeBuffer.Capacity, out bytesReturned, IntPtr.Zero); var lastError = Marshal.GetLastWin32Error(); if (!success) { switch ((uint)lastError) { case Win32Errors.ERROR_MORE_DATA: case Win32Errors.ERROR_INSUFFICIENT_BUFFER: // Should not happen since we already use the maximum size. if (safeBuffer.Capacity < bytesReturned) { safeBuffer.Close(); } break; default: if (lastError != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException(lastError, reparsePath); } break; } } else { break; } } return(safeBuffer); }
private static SafeGlobalMemoryBufferHandle ToUnmanagedSecurityAttributes(ObjectSecurity securityDescriptor) { if (securityDescriptor == null) return new SafeGlobalMemoryBufferHandle(); byte[] src = securityDescriptor.GetSecurityDescriptorBinaryForm(); var safeBuffer = new SafeGlobalMemoryBufferHandle(src.Length); try { safeBuffer.CopyFrom(src, 0, src.Length); return safeBuffer; } catch { safeBuffer.Close(); throw; } }
private static SafeGlobalMemoryBufferHandle ToUnmanagedSecurityAttributes(ObjectSecurity securityDescriptor) { if (securityDescriptor == null) { return(new SafeGlobalMemoryBufferHandle()); } byte[] src = securityDescriptor.GetSecurityDescriptorBinaryForm(); var safeBuffer = new SafeGlobalMemoryBufferHandle(src.Length); try { safeBuffer.CopyFrom(src, 0, src.Length); return(safeBuffer); } catch { safeBuffer.Close(); throw; } }
internal static LinkTargetInfo GetLinkTargetInfoCore(SafeFileHandle safeHandle) { // Start with a large buffer to prevent a 2nd call. uint bytesReturned = NativeMethods.DefaultFileBufferSize; using (var safeBuffer = new SafeGlobalMemoryBufferHandle((int)bytesReturned)) { while (true) { // DeviceIoControlMethod.Buffered = 0, // DeviceIoControlFileDevice.FileSystem = 9 // FsctlGetReparsePoint = (DeviceIoControlFileDevice.FileSystem << 16) | (42 << 2) | DeviceIoControlMethod.Buffered | (0 << 14) if (!NativeMethods.DeviceIoControl(safeHandle, ((9 << 16) | (42 << 2) | 0 | (0 << 14)), IntPtr.Zero, 0, safeBuffer, (uint)safeBuffer.Capacity, out bytesReturned, IntPtr.Zero)) { int lastError = Marshal.GetLastWin32Error(); switch ((uint)lastError) { case Win32Errors.ERROR_MORE_DATA: case Win32Errors.ERROR_INSUFFICIENT_BUFFER: if (safeBuffer.Capacity < bytesReturned) { safeBuffer.Close(); break; } NativeError.ThrowException(lastError); break; } } else { break; } } int marshalReparseBuffer = (int)Marshal.OffsetOf(typeof(NativeMethods.ReparseDataBufferHeader), "data"); var header = safeBuffer.PtrToStructure <NativeMethods.ReparseDataBufferHeader>(0); int dataOffset = (int)(marshalReparseBuffer + (header.ReparseTag == ReparsePointTag.MountPoint ? Marshal.OffsetOf(typeof(NativeMethods.MountPointReparseBuffer), "data") : Marshal.OffsetOf(typeof(NativeMethods.SymbolicLinkReparseBuffer), "data")).ToInt64()); var dataBuffer = new byte[bytesReturned - dataOffset]; switch (header.ReparseTag) { case ReparsePointTag.MountPoint: var mountPoint = safeBuffer.PtrToStructure <NativeMethods.MountPointReparseBuffer>(marshalReparseBuffer); safeBuffer.CopyTo(dataOffset, dataBuffer, 0, dataBuffer.Length); return(new LinkTargetInfo( Encoding.Unicode.GetString(dataBuffer, mountPoint.SubstituteNameOffset, mountPoint.SubstituteNameLength), Encoding.Unicode.GetString(dataBuffer, mountPoint.PrintNameOffset, mountPoint.PrintNameLength))); case ReparsePointTag.SymLink: var symLink = safeBuffer.PtrToStructure <NativeMethods.SymbolicLinkReparseBuffer>(marshalReparseBuffer); safeBuffer.CopyTo(dataOffset, dataBuffer, 0, dataBuffer.Length); return(new SymbolicLinkTargetInfo( Encoding.Unicode.GetString(dataBuffer, symLink.SubstituteNameOffset, symLink.SubstituteNameLength), Encoding.Unicode.GetString(dataBuffer, symLink.PrintNameOffset, symLink.PrintNameLength), symLink.Flags)); default: throw new UnrecognizedReparsePointException(); } } }
internal static LinkTargetInfo GetLinkTargetInfoInternal(SafeFileHandle safeHandle) { // Start with a large buffer to prevent a 2nd call. uint bytesReturned = NativeMethods.MaxPathUnicode; using (SafeGlobalMemoryBufferHandle safeBuffer = new SafeGlobalMemoryBufferHandle((int)bytesReturned)) { do { // Possible PInvoke signature bug: safeBuffer.Capacity and bytesReturned are always the same. // Since a large buffer is used, we are not affected. // DeviceIoControlMethod.Buffered = 0, // DeviceIoControlFileDevice.FileSystem = 9 // FsctlGetReparsePoint = (DeviceIoControlFileDevice.FileSystem << 16) | (42 << 2) | DeviceIoControlMethod.Buffered | (0 << 14) if (!NativeMethods.DeviceIoControl(safeHandle, ((9 << 16) | (42 << 2) | 0 | (0 << 14)), IntPtr.Zero, 0, safeBuffer, (uint)safeBuffer.Capacity, out bytesReturned, IntPtr.Zero)) { int lastError = Marshal.GetLastWin32Error(); switch ((uint)lastError) { case Win32Errors.ERROR_MORE_DATA: case Win32Errors.ERROR_INSUFFICIENT_BUFFER: if (safeBuffer.Capacity < bytesReturned) { safeBuffer.Close(); break; } // Throws IOException. NativeError.ThrowException(lastError, true); break; } } else { break; } } while (true); // CA2001:AvoidCallingProblematicMethods IntPtr buffer = IntPtr.Zero; bool successRef = false; safeBuffer.DangerousAddRef(ref successRef); // MSDN: The DangerousGetHandle method poses a security risk because it can return a handle that is not valid. if (successRef) { buffer = safeBuffer.DangerousGetHandle(); } safeBuffer.DangerousRelease(); if (buffer == IntPtr.Zero) { NativeError.ThrowException(Resources.HandleDangerousRef); } // CA2001:AvoidCallingProblematicMethods Type toMountPointReparseBuffer = typeof(NativeMethods.MountPointReparseBuffer); Type toReparseDataBufferHeader = typeof(NativeMethods.ReparseDataBufferHeader); Type toSymbolicLinkReparseBuffer = typeof(NativeMethods.SymbolicLinkReparseBuffer); IntPtr marshalReparseBuffer = Marshal.OffsetOf(toReparseDataBufferHeader, "data"); NativeMethods.ReparseDataBufferHeader header = Utils.MarshalPtrToStructure <NativeMethods.ReparseDataBufferHeader>(0, buffer); IntPtr dataPos; byte[] dataBuffer; switch (header.ReparseTag) { case ReparsePointTag.MountPoint: NativeMethods.MountPointReparseBuffer mprb = Utils.MarshalPtrToStructure <NativeMethods.MountPointReparseBuffer>(0, new IntPtr(buffer.ToInt64() + marshalReparseBuffer.ToInt64())); dataPos = new IntPtr(marshalReparseBuffer.ToInt64() + Marshal.OffsetOf(toMountPointReparseBuffer, "data").ToInt64()); dataBuffer = new byte[bytesReturned - dataPos.ToInt64()]; Marshal.Copy(new IntPtr(buffer.ToInt64() + dataPos.ToInt64()), dataBuffer, 0, dataBuffer.Length); return(new LinkTargetInfo( Encoding.Unicode.GetString(dataBuffer, mprb.SubstituteNameOffset, mprb.SubstituteNameLength), Encoding.Unicode.GetString(dataBuffer, mprb.PrintNameOffset, mprb.PrintNameLength))); case ReparsePointTag.SymLink: NativeMethods.SymbolicLinkReparseBuffer slrb = Utils.MarshalPtrToStructure <NativeMethods.SymbolicLinkReparseBuffer>(0, new IntPtr(buffer.ToInt64() + marshalReparseBuffer.ToInt64())); dataPos = new IntPtr(marshalReparseBuffer.ToInt64() + Marshal.OffsetOf(toSymbolicLinkReparseBuffer, "data").ToInt64()); dataBuffer = new byte[bytesReturned - dataPos.ToInt64()]; Marshal.Copy(new IntPtr(buffer.ToInt64() + dataPos.ToInt64()), dataBuffer, 0, dataBuffer.Length); return(new SymbolicLinkTargetInfo( Encoding.Unicode.GetString(dataBuffer, slrb.SubstituteNameOffset, slrb.SubstituteNameLength), Encoding.Unicode.GetString(dataBuffer, slrb.PrintNameOffset, slrb.PrintNameLength), slrb.Flags)); default: throw new UnrecognizedReparsePointException(); } } }