private static string ResolveReparsePoint(IntPtr ptr, string path) { NativeMethods.REPARSE_DATA_BUFFER buffer = (NativeMethods.REPARSE_DATA_BUFFER) Marshal.PtrToStructure(ptr, typeof(NativeMethods.REPARSE_DATA_BUFFER)); //Check that this Reparse Point has a Microsoft Tag if (((uint)buffer.ReparseTag & (1 << 31)) == 0) { //We can only handle Microsoft's reparse tags. throw new ArgumentException("Unknown Reparse point type."); } //Then handle the tags switch (buffer.ReparseTag) { case NativeMethods.REPARSE_DATA_TAG.IO_REPARSE_TAG_MOUNT_POINT: return(ResolveReparsePointJunction((IntPtr)(ptr.ToInt64() + Marshal.SizeOf(buffer)))); case NativeMethods.REPARSE_DATA_TAG.IO_REPARSE_TAG_SYMLINK: return(ResolveReparsePointSymlink((IntPtr)(ptr.ToInt64() + Marshal.SizeOf(buffer)), path)); default: throw new ArgumentException("Unsupported Reparse point type."); } }
public void RemoveJunction(string junctionPoint) { if (!Directory.Exists(junctionPoint) && !File.Exists(junctionPoint)) { return; } // Open the junction point. SafeFileHandle fileHandle = OpenReparsePoint(junctionPoint, NativeMethods.EFileAccess.GenericWrite); // Setup reparse structure. NativeMethods.REPARSE_DATA_BUFFER reparseDataBuffer = new NativeMethods.REPARSE_DATA_BUFFER { reparseTag = NativeMethods.IO_REPARSE_TAG_MOUNT_POINT, reparseDataLength = 0, pathBuffer = new byte[0x3FF0] }; // Calculate buffer size and allocate. int inBufferSize = Marshal.SizeOf(reparseDataBuffer); IntPtr inBuffer = Marshal.AllocHGlobal(inBufferSize); try { // Create the pointer. Marshal.StructureToPtr(reparseDataBuffer, inBuffer, false); // Delete the reparse point. bool result = NativeMethods.DeviceIoControl( fileHandle.DangerousGetHandle(), NativeMethods.FSCTL_DELETE_REPARSE_POINT, inBuffer, 8, IntPtr.Zero, 0, out int BytesReturned, IntPtr.Zero); if (!result) { throw new Win32Exception("ERROR: Unable to delete reparse point."); } } finally { fileHandle.Dispose(); Marshal.FreeHGlobal(inBuffer); } }