Jump to content

Script works correctly if compiled as 32 bit, but not if compiled as 64 bit (NtQuerySymbolicLinkObject)


Recommended Posts

If script is compiled as 64 bit it doesnt return all devices that it returns when compiled as 32 bit:

32 bit.png

64 bit.png

Could someone help me find what error is causing this?

; www.autoitscript.com/forum/topic/170417-help-getting-drive-letter-from-an-arc-path

#NoTrayIcon
#RequireAdmin
#include <Array.au3>
#include <WinAPI.au3>

Global Const $DIRECTORY_QUERY = 0x0001
Global Const $DIRECTORY_TRAVERSE = 0x0002
Global Const $sTagUNICODESTRING = "USHORT Length;USHORT MaximumLength;PTR Buffer;"
Global Const $sTagOBJECT_ATTRIBUTES = "ULONG Length;HANDLE RootDirectory;PTR ObjectName;ULONG Attributes;PTR SecurityDescriptor;PTR SecurityQualityOfService"

Global $aObjects = _GetPartitionPaths()
_ArrayDelete($aObjects, 0)
_ArrayDisplay($aObjects, "Partition Paths", Default, Default, Default, "Name|Type|SymLink")
Exit

Func _GetPartitionPaths()
   Local $Paths[1][3] = [[1]]
   $tNameSource = DllStructCreate("wchar String[512]")
   DllStructSetData($tNameSource, 1, "\GLOBAL??")
   $tUnicodeString = _RtlInitUnicodeString($tNameSource)
   $tObject_Attributes = _InitializeObjectAttributes(DllStructGetPtr($tUnicodeString))
   $hDirectory = _NtOpenDirectoryObject(DllStructGetPtr($tObject_Attributes), BitOR($DIRECTORY_TRAVERSE, $DIRECTORY_QUERY))
   $tBuffer = DllStructCreate("byte Data[32767]")
   $aRet = DllCall("Ntdll.dll", "LONG", "NtQueryDirectoryObject", "HANDLE", $hDirectory, "ptr", DllStructGetPtr($tBuffer), "ULONG", 32767, "BOOL", False, "BOOL", True, "ULONG*", 0, "ULONG*", 0)
   If @error Or $aRet[0] < 0 Then Return SetError(1, 0, '')
   $index = $aRet[6]
   For $i = 0 To $index - 1
      $tData = DllStructCreate($sTagUNICODESTRING & $sTagUNICODESTRING, DllStructGetPtr($tBuffer) + ($i * 16))
      $tName = DllStructCreate("wchar wNameString[" & DllStructGetData($tData, 1) & "]", DllStructGetData($tData, 3))
      $tType = DllStructCreate("wChar wTypeString[" & DllStructGetData($tData, 4) & "]", DllStructGetData($tData, 6))
      $taName = DllStructCreate("wchar String[512]")
      DllStructSetData($taName, 1, DllStructGetData($tName, 'wNameString'))
      $tStr = _RtlInitUnicodeString($taName)
      $tAttr = _InitializeObjectAttributes(DllStructGetPtr($tStr), 0, $hDirectory)
      $hLink = _NtOpenSymbolicLinkObject(DllStructGetPtr($tAttr), $GENERIC_READ)
      $taTarget = DllStructCreate("wchar String[512]")
      DllStructSetData($taTarget, 1, "")
      $tTarget = _RtlInitUnicodeString($taTarget)
      DllStructSetData($tTarget, 'MaximumLength', 512)
      _NtQuerySymbolicLinkObject($hLink, $tTarget)
      $tSTarget = DllStructCreate("wchar wString[" & DllStructGetData($tTarget, 1) & "]", DllStructGetData($tTarget, 3))
      $NameString = DllStructGetData($tName, 'wNameString')
      If (StringInStr($NameString, 'Harddisk') and StringInStr($NameString, 'Partition')) or (StringInStr($NameString, 'Volume') and not StringInStr($NameString, 'Harddisk') and not StringInStr($NameString, 'STORAGE')) Then
         $Paths[0][0] += 1
         ReDim $Paths[$Paths[0][0]][3]
         $Paths[$Paths[0][0] - 1][0] = DllStructGetData($tName, 'wNameString')
         $Paths[$Paths[0][0] - 1][1] = DllStructGetData($tType, 'wTypeString')
         If IsDllStruct($tSTarget) Then
            $Paths[$Paths[0][0] - 1][2] = DllStructGetData($tSTarget, 'wString')
         Else
            $Paths[$Paths[0][0] - 1][2] = ''
         EndIf
      EndIf
      _WinAPI_CloseHandle($hLink)
   Next
   Return $Paths
EndFunc

Func _RtlInitUnicodeString($tSourceString)
   Local $tUnicodeString = DllStructCreate($sTagUNICODESTRING)
   DllCall("Ntdll.dll", "NONE", "RtlInitUnicodeString", "struct*", $tUnicodeString, "struct*", $tSourceString)
   If @error Then SetError(@error, 0, 0)
   Return $tUnicodeString
EndFunc

Func _InitializeObjectAttributes($pObjectName, $ulAttributes = 0, $hRootDirectory = Null, $pSecurityDescriptor = Null)
   Local $tObject_Attributes = DllStructCreate($sTagOBJECT_ATTRIBUTES)
   DllStructSetData($tObject_Attributes, 1, DllStructGetSize($tObject_Attributes))
   DllStructSetData($tObject_Attributes, 2, $hRootDirectory)
   DllStructSetData($tObject_Attributes, 3, $pObjectName)
   Return $tObject_Attributes
EndFunc

Func _NtQuerySymbolicLinkObject($hLinkHandle, $tLinkTarget)
   Local $aRet = DllCall("Ntdll.dll", "LONG", "NtQuerySymbolicLinkObject", "HANDLE", $hLinkHandle, "struct*", $tLinkTarget, "ULONG*", 0)
   If @error Then SetError(@error, 0, 0)
   If $aRet[0] <> 0 Then SetError(1, 0, 0)
EndFunc

Func _NtOpenDirectoryObject($pObjectAttr, $AccessMask)
   Local $aRet = DllCall("Ntdll.dll", "LONG", "NtOpenDirectoryObject", "HANDLE*", 0, "ULONG", $AccessMask, "PTR", $pObjectAttr)
   If @error Then SetError(@error, 0, 0)
   If $aRet[0] < 0 Or $aRet[1] = 0 Then SetError(1, 0, 0)
   Return $aRet[1]
EndFunc

Func _NtOpenSymbolicLinkObject($pObjectAttr, $AccessMask)
   Local $aRet = DllCall("Ntdll.dll", "LONG", "NtOpenSymbolicLinkObject", "HANDLE*", 0, "ULONG", $AccessMask, "PTR", $pObjectAttr)
   If @error Then Return SetError(@error, 0, 0)
   If $aRet[0] < 0 Or $aRet[1] = 0 Then Return SetError(1, 0, 0)
   Return $aRet[1]
EndFunc

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...