コード例 #1
0
        internal static bool DeleteJunction(string junctionPath)
        {
            bool result = false;

            if (!String.IsNullOrEmpty(junctionPath))
            {
                if (!Platform.IsWindows)
                {
                    // For non-Windows platform, treat it as a file.  Just delete it.
                    try
                    {
                        File.Delete(junctionPath);
                        return true;
                    }
                    catch
                    {
                        return false;
                    }
                }

                using (SafeHandle handle = OpenReparsePoint(junctionPath, FileDesiredAccess.GenericWrite))
                {
                    bool success = false;
                    int inOutBufferSize = ClrFacade.SizeOf<REPARSE_GUID_DATA_BUFFER>();
                    IntPtr outBuffer = Marshal.AllocHGlobal(inOutBufferSize);
                    IntPtr inBuffer = Marshal.AllocHGlobal(inOutBufferSize);

                    try
                    {
                        handle.DangerousAddRef(ref success);
                        IntPtr dangerousHandle = handle.DangerousGetHandle();
                        int bytesReturned;

                        // Do a FSCTL_GET_REPARSE_POINT first because the ReparseTag could be 
                        // IO_REPARSE_TAG_MOUNT_POINT or IO_REPARSE_TAG_SYMLINK.
                        // Using the wrong one results in mismatched-tag error.

                        REPARSE_GUID_DATA_BUFFER junctionData = new REPARSE_GUID_DATA_BUFFER();
                        ClrFacade.StructureToPtr<REPARSE_GUID_DATA_BUFFER>(junctionData, outBuffer, false);

                        result = DeviceIoControl(dangerousHandle, FSCTL_GET_REPARSE_POINT, IntPtr.Zero, 0,
                            outBuffer, inOutBufferSize, out bytesReturned, IntPtr.Zero);
                        if (!result)
                        {
                            int lastError = Marshal.GetLastWin32Error();
                            throw new Win32Exception(lastError);
                        }

                        junctionData = ClrFacade.PtrToStructure<REPARSE_GUID_DATA_BUFFER>(outBuffer);
                        junctionData.ReparseDataLength = 0;
                        junctionData.DataBuffer = new char[MAX_REPARSE_SIZE];

                        ClrFacade.StructureToPtr<REPARSE_GUID_DATA_BUFFER>(junctionData, inBuffer, false);

                        // To delete a reparse point: 
                        // ReparseDataLength must be 0
                        // inBufferSize must be REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
                        result = DeviceIoControl(dangerousHandle, FSCTL_DELETE_REPARSE_POINT, inBuffer, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);
                        if (!result)
                        {
                            int lastError = Marshal.GetLastWin32Error();
                            throw new Win32Exception(lastError);
                        }
                    }
                    finally
                    {
                        if (success)
                        {
                            handle.DangerousRelease();
                        }

                        Marshal.FreeHGlobal(outBuffer);
                        Marshal.FreeHGlobal(inBuffer);
                    }
                }
            }
            else
            {
                throw new ArgumentNullException("junctionPath");
            }

            return result;
        }
コード例 #2
0
ファイル: ReparsePoint.cs プロジェクト: meziantou/exportsrc
        /// <summary>
        /// Gets the target directory from a directory link in Windows Vista.
        /// </summary>
        /// <param name="directoryInfo">The directory info of this directory
        /// link</param>
        /// <returns>the target directory, if it was read,
        /// otherwise an empty string.</returns>
        public static String GetTargetDir(FileSystemInfo directoryInfo)
        {
            String targetDir = string.Empty;

            try
            {
                // Is it a directory link?
                if ((directoryInfo.Attributes
                     & FileAttributes.ReparsePoint) != 0)
                {
                    // Open the directory link:
                    IntPtr hFile = CreateFile(directoryInfo.FullName,
                                              0,
                                              0,
                                              IntPtr.Zero,
                                              OPEN_EXISTING,
                                              FILE_FLAG_BACKUP_SEMANTICS |
                                              FILE_FLAG_OPEN_REPARSE_POINT,
                                              IntPtr.Zero);
                    if (hFile.ToInt32() != INVALID_HANDLE_VALUE)
                    {
                        // Allocate a buffer for the reparse point data:
                        Int32  outBufferSize = Marshal.SizeOf(typeof(REPARSE_GUID_DATA_BUFFER));
                        IntPtr outBuffer     = Marshal.AllocHGlobal(outBufferSize);

                        try
                        {
                            // Read the reparse point data:
                            Int32 bytesReturned;
                            Int32 readOK = DeviceIoControl(hFile,
                                                           FSCTL_GET_REPARSE_POINT,
                                                           IntPtr.Zero,
                                                           0,
                                                           outBuffer,
                                                           outBufferSize,
                                                           out bytesReturned,
                                                           IntPtr.Zero);
                            if (readOK != 0)
                            {
                                // Get the target directory from the reparse
                                // point data:
                                REPARSE_GUID_DATA_BUFFER rgdBuffer =
                                    (REPARSE_GUID_DATA_BUFFER)
                                    Marshal.PtrToStructure
                                        (outBuffer, typeof(REPARSE_GUID_DATA_BUFFER));
                                targetDir = Encoding.Unicode.GetString
                                                (rgdBuffer.PathBuffer,
                                                rgdBuffer.SubstituteNameOffset,
                                                rgdBuffer.SubstituteNameLength);
                                if (targetDir.StartsWith
                                        (NonInterpretedPathPrefix))
                                {
                                    targetDir = targetDir.Substring
                                                    (NonInterpretedPathPrefix.Length);
                                }
                            }
                        }
                        catch (Exception)
                        {
                        }

                        // Free the buffer for the reparse point data:
                        Marshal.FreeHGlobal(outBuffer);

                        // Close the directory link:
                        CloseHandle(hFile);
                    }
                }
            }
            catch (Exception)
            {
            }

            return(targetDir);
        }
コード例 #3
0
        /// <summary>
        /// Gets the target directory from a directory link in Windows.
        /// </summary>
        /// <param name="directoryInfo">The directory info of the directory link</param>
        /// <returns>The target directory, if link exists, otherwise the FullName</returns>
        /// <exception cref="ReparsePointException">Thrown if an error occurs</exception>
        public static string GetTargetDirectory(FileSystemInfo directoryInfo)
        {
            try
            {
                string targetDir = directoryInfo.FullName;

                // Is it a directory link?
                if ((directoryInfo.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
                {
                    // Open the directory link:
                    IntPtr hFile = SafeNativeMethods.CreateFile(
                        directoryInfo.FullName,
                        0,
                        0,
                        IntPtr.Zero,
                        OPEN_EXISTING,
                        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
                        IntPtr.Zero);

                    if (hFile.ToInt32() != INVALID_HANDLE_VALUE)
                    {
                        // Allocate a buffer for the reparse point data:
                        int    outBufferSize = Marshal.SizeOf(typeof(REPARSE_GUID_DATA_BUFFER));
                        IntPtr outBuffer     = Marshal.AllocHGlobal(outBufferSize);

                        try
                        {
                            // Read the reparse point data:
                            int bytesReturned;
                            int readOK = SafeNativeMethods.DeviceIoControl(
                                hFile,
                                FSCTL_GET_REPARSE_POINT,
                                IntPtr.Zero,
                                0,
                                outBuffer,
                                outBufferSize,
                                out bytesReturned,
                                IntPtr.Zero);

                            if (readOK != 0)
                            {
                                // Get the target directory from the reparse point data:
                                REPARSE_GUID_DATA_BUFFER rgdBuffer = (REPARSE_GUID_DATA_BUFFER)Marshal.PtrToStructure(outBuffer, typeof(REPARSE_GUID_DATA_BUFFER));
                                targetDir = Encoding.Unicode.GetString(
                                    rgdBuffer.PathBuffer,
                                    rgdBuffer.SubstituteNameOffset,
                                    rgdBuffer.SubstituteNameLength);

                                if (targetDir.StartsWith(NonInterpretedPathPrefix, StringComparison.OrdinalIgnoreCase))
                                {
                                    targetDir = targetDir.Substring(NonInterpretedPathPrefix.Length);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            throw new ReparsePointException("Failed to access ReparsePoint.", ex);
                        }
                        finally
                        {
                            // Free the buffer for the reparse point data:
                            Marshal.FreeHGlobal(outBuffer);

                            // Close the directory link:
                            SafeNativeMethods.CloseHandle(hFile);
                        }
                    }
                }

                return(targetDir);
            }
            catch (Exception ex)
            {
                throw new ReparsePointException("Failed to access ReparsePoint.", ex);
            }
        }