Example #1
0
File: Path.cs Project: CDEApp/CDE
        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();
                }
            }
        }
Example #2
0
        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();
                }
            }
        }