Why does following code always returns FALSE in area commented?

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
The following code, a conversion from C# to Visual Basic works in the C# version but always returns FALSE in the area I commented. This code is beyond my scope. Any help would be greatly appreciated. The purpose of this code is to show all folders but represent
folders that are mount points, junction points or symbolic links in different colors.
<span style="text-decoration:underline Control and Name
Form (Form1)
Treeview (RPTreeView)
RadioButton (targetRadioButton)
RadioButton (linkRadioButton)
Label (NormalisedTargetLabel)
Label (ActualTargetLabel)
<pre class="prettyprint lang-vb Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports System.IO
Imports WindowsApplication1.ReparsePoints
Imports System.Runtime.InteropServices
Imports System.Diagnostics


Public Class Form1


Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim drives As DriveInfo() = DriveInfo.GetDrives()
For Each drive As DriveInfo In drives
RPTreeView.Nodes.Add(drive.Name.Substring(0, 2))
targetRadioButton.Checked = True
Next
End Sub

Private Sub fillNode(node As TreeNode)
node.Nodes.Clear()
Dim fullpath As String = ""
Dim nextNode As TreeNode = node
Do
If targetRadioButton.Checked AndAlso nextNode.Tag IsNot Nothing AndAlso DirectCast(nextNode.Tag, ReparsePoint).Tag <> ReparsePoint.TagType.None AndAlso DirectCast(nextNode.Tag, ReparsePoint).Tag <> ReparsePoint.TagType.MountPoint Then
fullpath = DirectCast(nextNode.Tag, ReparsePoint).ToString() + "" + fullpath
Exit Do
Else
fullpath = nextNode.Text + "" + fullpath
nextNode = nextNode.Parent
End If
Loop While nextNode IsNot Nothing
Try
For Each directory1 As String In Directory.GetDirectories(fullpath)
Dim reparsePoint2 As New ReparsePoint(directory1)
Dim newNode As TreeNode = node.Nodes.Add(directory1.Substring(directory1.LastIndexOf(""c) + 1))
newNode.Tag = reparsePoint2
If reparsePoint2.Tag = ReparsePoint.TagType.MountPoint Then
newNode.ForeColor = Color.Red
MessageBox.Show("Red")
ElseIf reparsePoint2.Tag = ReparsePoint.TagType.JunctionPoint Then
newNode.ForeColor = Color.Blue
MessageBox.Show("Blue")
ElseIf reparsePoint2.Tag = ReparsePoint.TagType.SymbolicLink Then
newNode.ForeColor = Color.Green
MessageBox.Show("Green")
End If
Next
Catch exception As Exception
MessageBox.Show(exception.Message, exception.[GetType]().ToString())
End Try
node.Expand()
End Sub


Private Sub RPTreeView_AfterExpand(sender As Object, e As TreeViewEventArgs) Handles RPTreeView.AfterExpand
If e.Action = TreeViewAction.ByKeyboard OrElse e.Action = TreeViewAction.ByMouse Then
fillNode(e.Node)
End If
End Sub


Private Sub RPTreeView_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles RPTreeView.AfterSelect
If e.Action <> TreeViewAction.Collapse And e.Action <> TreeViewAction.Unknown Then
fillNode(e.Node)
If DirectCast(e.Node.Tag, ReparsePoint) Is Nothing OrElse DirectCast(e.Node.Tag, ReparsePoint).Tag = ReparsePoint.TagType.None Then
NormalisedTargetLabel.Text = ""
ActualTargetLabel.Text = ""
Else
NormalisedTargetLabel.Text = "" + DirectCast(e.Node.Tag, ReparsePoint).ToString() + ""
ActualTargetLabel.Text = "" + DirectCast(e.Node.Tag, ReparsePoint).Target + ""
End If
End If
End Sub


End Class

Namespace ReparsePoints
Public Class ReparsePoint

Private Const IO_REPARSE_TAG_MOUNT_POINT As UInteger = &HA0000003UI
Private Const IO_REPARSE_TAG_SYMLINK As UInteger = &HA000000CUI
Private Const SE_PRIVILEGE_ENABLED As UInt32 = &H2
Private Const SE_BACKUP_NAME As String = "SeBackupPrivilege"
Private Const FILE_FLAG_BACKUP_SEMANTICS As UInteger = &H2000000
Private Const FILE_FLAG_OPEN_REPARSE_POINT As UInteger = &H200000
Private Const FILE_DEVICE_FILE_SYSTEM As UInteger = 9
Private Const FILE_ANY_ACCESS As UInteger = 0
Private Const METHOD_BUFFERED As UInteger = 0
Private Const MAXIMUM_REPARSE_DATA_BUFFER_SIZE As Integer = 16 * 1024
Private Const TOKEN_ADJUST_PRIVILEGES As UInteger = &H20
Private Const FSCTL_GET_REPARSE_POINT As Integer = 42

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Private Structure REPARSE_DATA_BUFFER
Public ReparseTag As UInteger
Public ReparseDataLength As Short
Public Reserved As Short
Public SubsNameOffset As Short
Public SubsNameLength As Short
Public PrintNameOffset As Short
Public PrintNameLength As Short
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=MAXIMUM_REPARSE_DATA_BUFFER_SIZE)> _
Public ReparseTarget As Char()
End Structure

<StructLayout(LayoutKind.Sequential)> _
Private Structure LUID
Public LowPart As UInt32
Public HighPart As Int32
End Structure

<StructLayout(LayoutKind.Sequential)> _
Private Structure LUID_AND_ATTRIBUTES
Public Luid As LUID
Public Attributes As UInt32
End Structure

Private Structure TOKEN_PRIVILEGES
Public PrivilegeCount As UInt32
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> _
Public Privileges As LUID_AND_ATTRIBUTES()
End Structure

Private Declare Auto Function DeviceIoControl Lib "kernel32.dll" (hDevice As IntPtr, dwIoControlCode As UInteger, lpInBuffer As IntPtr, nInBufferSize As UInteger, outBuffer As REPARSE_DATA_BUFFER, nOutBufferSize As UInteger, _
lpBytesReturned As UInteger, lpOverlapped As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean

<DllImport("Kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function CreateFile(fileName As String, <MarshalAs(UnmanagedType.U4)> fileAccess As FileAccess, <MarshalAs(UnmanagedType.U4)> fileShare As FileShare, securityAttributes As Integer, <MarshalAs(UnmanagedType.U4)> creationDisposition As FileMode, flags As UInteger, _
template As IntPtr) As IntPtr
End Function

<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function OpenProcessToken(ProcessHandle As IntPtr, DesiredAccess As UInt32, TokenHandle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

<DllImport("kernel32.dll")> _
Private Shared Function GetCurrentProcess() As IntPtr
End Function

<DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function LookupPrivilegeValue(lpSystemName As String, lpName As String, lpLuid As LUID) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function AdjustTokenPrivileges(TokenHandle As IntPtr, <MarshalAs(UnmanagedType.Bool)> DisableAllPrivileges As Boolean, ByRef NewState As TOKEN_PRIVILEGES, BufferLength As Int32, PreviousState As IntPtr, ReturnLength As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function CloseHandle(hObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

Public Enum TagType
None = 0
MountPoint = 1
SymbolicLink = 2
JunctionPoint = 3
End Enum

Private normalisedTarget As String
Private actualTarget As String
Private m_tag As TagType

Public Sub New(path As String)
Debug.Assert(Not String.IsNullOrEmpty(path) AndAlso path.Length > 2 AndAlso path(1) = ":"c AndAlso path(2) = ""c)
normalisedTarget = ""
m_tag = TagType.None
Dim success As Boolean
Dim lastError As Integer
Dim token As IntPtr
Dim tokenPrivileges As New TOKEN_PRIVILEGES()
tokenPrivileges.Privileges = New LUID_AND_ATTRIBUTES(0) {}
success = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, token)


SUCCESS RETURNS FALSE HERE BUT WORKS IN C# VERSION


lastError = Marshal.GetLastWin32Error()
If success Then
success = LookupPrivilegeValue(Nothing, SE_BACKUP_NAME, tokenPrivileges.Privileges(0).Luid)
lastError = Marshal.GetLastWin32Error()
If success Then
tokenPrivileges.PrivilegeCount = 1
tokenPrivileges.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED
success = AdjustTokenPrivileges(token, False, tokenPrivileges, Marshal.SizeOf(tokenPrivileges), IntPtr.Zero, IntPtr.Zero)
lastError = Marshal.GetLastWin32Error()
End If
CloseHandle(token)
End If

If success Then
Dim handle As IntPtr = CreateFile(path, FileAccess.Read, FileShare.None, 0, FileMode.Open, FILE_FLAG_OPEN_REPARSE_POINT Or FILE_FLAG_BACKUP_SEMANTICS, _
IntPtr.Zero)
lastError = Marshal.GetLastWin32Error()
If handle.ToInt32() >= 0 Then
Dim buffer As New REPARSE_DATA_BUFFER()
Dim controlCode As UInteger = (FILE_DEVICE_FILE_SYSTEM << 16) Or (FILE_ANY_ACCESS << 14) Or (FSCTL_GET_REPARSE_POINT << 2) Or METHOD_BUFFERED
Dim bytesReturned As UInteger
success = DeviceIoControl(handle, controlCode, IntPtr.Zero, 0, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, _
bytesReturned, IntPtr.Zero)
lastError = Marshal.GetLastWin32Error()
If success Then
Dim subsString As String = ""
Dim printString As String = ""
Debug.Assert(buffer.ReparseTag = IO_REPARSE_TAG_SYMLINK OrElse buffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT, "Unrecognised reparse tag")
If buffer.ReparseTag = IO_REPARSE_TAG_SYMLINK Then
subsString = New String(buffer.ReparseTarget, (buffer.SubsNameOffset / 2 + 2), buffer.SubsNameLength / 2)
printString = New String(buffer.ReparseTarget, (buffer.PrintNameOffset / 2 + 2), buffer.PrintNameLength / 2)
m_tag = TagType.SymbolicLink
ElseIf buffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT Then
subsString = New String(buffer.ReparseTarget, buffer.SubsNameOffset / 2, buffer.SubsNameLength / 2)
printString = New String(buffer.ReparseTarget, buffer.PrintNameOffset / 2, buffer.PrintNameLength / 2)
m_tag = If(subsString.StartsWith("??Volume"), TagType.MountPoint, TagType.JunctionPoint)
End If
Debug.Assert(Not (String.IsNullOrEmpty(subsString) AndAlso String.IsNullOrEmpty(printString)), "Failed to retrieve parse point")
If Not String.IsNullOrEmpty(printString) Then
normalisedTarget = printString
Else
normalisedTarget = subsString
Debug.Assert(normalisedTarget.Length > 2, "Target string too short")
Debug.Assert((normalisedTarget.StartsWith("??") AndAlso (normalisedTarget(5) = ":"c OrElse normalisedTarget.StartsWith("??Volume")) OrElse (Not normalisedTarget.StartsWith("??") AndAlso normalisedTarget(1) <> ":"c)), "Malformed subsString")
Debug.Assert(buffer.ReparseTag = IO_REPARSE_TAG_SYMLINK OrElse normalisedTarget.StartsWith("??Volume") OrElse normalisedTarget(1) = ":"c, "Relative junction point")
If normalisedTarget.StartsWith("??") Then
normalisedTarget = normalisedTarget.Substring(4)
End If
End If
actualTarget = normalisedTarget
If buffer.ReparseTag = IO_REPARSE_TAG_SYMLINK AndAlso (normalisedTarget.Length < 2 OrElse normalisedTarget(1) <> ":"c) Then
If normalisedTarget(0) = ""c Then
normalisedTarget = normalisedTarget.Substring(1)
End If
If path.EndsWith("") Then
path = path.Substring(0, path.Length - 1)
End If
normalisedTarget = path.Substring(0, path.LastIndexOf(""c)) + "" + normalisedTarget
End If
If normalisedTarget.EndsWith("") Then
normalisedTarget = normalisedTarget.Substring(0, normalisedTarget.Length - 1)
End If
End If
CloseHandle(handle)
Else
success = False
End If
End If
End Sub

Public Overrides Function ToString() As String
Return normalisedTarget
End Function

Public ReadOnly Property Target() As String
Get
Return actualTarget
End Get
End Property

Public ReadOnly Property Tag() As TagType
Get
Return m_tag
End Get
End Property

End Class

End Namespace

[/code]
<img alt="" src="http://social.msdn.microsoft.com/Forums/getfile/221655 <br/>

<
Youve taught me everything I know but not everything you know.

View the full article
 
Back
Top