public static string GetTarget(string path) { using (var fileHandle = getFileHandle(path)) { if (fileHandle.IsInvalid) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } int outBufferSize = Marshal.SizeOf(typeof(SymbolicLinkReparseData)); IntPtr outBuffer = IntPtr.Zero; SymbolicLinkReparseData reparseDataBuffer; try { outBuffer = Marshal.AllocHGlobal(outBufferSize); int bytesReturned; bool success = Win32SafeNativeMethods.DeviceIoControl( fileHandle.DangerousGetHandle(), ioctlCommandGetReparsePoint, IntPtr.Zero, 0, outBuffer, outBufferSize, out bytesReturned, IntPtr.Zero); fileHandle.Close(); if (!success || bytesReturned <= 0) { if (((uint)Marshal.GetHRForLastWin32Error()) == PathNotAReparsePointError) { return(null); } Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } reparseDataBuffer = (SymbolicLinkReparseData)Marshal.PtrToStructure( outBuffer, typeof(SymbolicLinkReparseData)); } finally { Marshal.FreeHGlobal(outBuffer); } return(reparseDataBuffer.ReparseTag != SymLinkTag ? null : Encoding.Unicode.GetString(reparseDataBuffer.PathBuffer, reparseDataBuffer.PrintNameOffset, reparseDataBuffer.PrintNameLength)); } }