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); try { 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.Dispose(); safeBuffer = null; 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))); } finally { if (safeBuffer != null) { safeBuffer.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(); } } }