Softlinks von Verzeichnissen unter Vista
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Softlinks von Verzeichnissen unter Vista
Wie kann ich zu so einem Verzeichnis den echten Pfad ermitteln?
Das sind unter Vista z.B. Verzeichnisse wie: "Documents and Settings" oder
"Programme", die es als solche ja nicht mehr gibt.
Anhand der Namen kann ich nicht vorgehen, da es je nach Ländereinstellung
andere solcher Verzeichnisse geben kann.
Wäre schön wenn jemand da was weiß, ich selber habe bisher nichts
passendes gefunden
Gruß
Thomas
Das sind unter Vista z.B. Verzeichnisse wie: "Documents and Settings" oder
"Programme", die es als solche ja nicht mehr gibt.
Anhand der Namen kann ich nicht vorgehen, da es je nach Ländereinstellung
andere solcher Verzeichnisse geben kann.
Wäre schön wenn jemand da was weiß, ich selber habe bisher nichts
passendes gefunden
Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Nein, specialfolder nützt mir nichts, hab ja keine #CSIDL_bla zur Verfügung,
sondern nur den Pfad, dem ich folgen muß, leider funktioniert das nicht
autom., sondern es wird ein leeres Verzeichnis angezeigt
Ich erkenne die Ordner eigentlich nur am Attribut: #FILE_ATTRIBUTE_REPARSE_POINT
Jetzt muß ich irgendwie per API das zugehörige Verzeichnis ermitteln.
Ohne Vista wirste das auch nicht verstehen können. Selbst das
ExplorerListGadget kommt damit nicht klar, sondern zeigt darin nur eine
leere an
sondern nur den Pfad, dem ich folgen muß, leider funktioniert das nicht
autom., sondern es wird ein leeres Verzeichnis angezeigt

Ich erkenne die Ordner eigentlich nur am Attribut: #FILE_ATTRIBUTE_REPARSE_POINT
Jetzt muß ich irgendwie per API das zugehörige Verzeichnis ermitteln.
Ohne Vista wirste das auch nicht verstehen können. Selbst das
ExplorerListGadget kommt damit nicht klar, sondern zeigt darin nur eine
leere an

PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Das ExplorerListGadget zeigt ein leeres Verzeichnis an, nicht weil es dem link nicht folgen kann sondern weil der Prozess nicht die Rechte dazu hat auf "C:\Documents and Settings" direkt zuzugreifen. Mit einem Unterordner wie "C:\Documents and Settings\<Username>" geht es wieder. Der Explorer lässt das browsen des Ordners auch nicht zu, desshalb ist es schon korrekt das das ExplorerListGadget nicht versucht selbst den link aufzulösen.
Der Code funktioniert auch mit 64bit:
Der Code funktioniert auch mit 64bit:
Code: Alles auswählen
; WinIoCtl.h
;
#FILE_DEVICE_FILE_SYSTEM = $00000009
#METHOD_BUFFERED = 0
#FILE_ANY_ACCESS = 0
#FILE_SPECIAL_ACCESS = (#FILE_ANY_ACCESS)
Macro CTL_CODE( DeviceType, Function, Method, Access )
(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
EndMacro
#FSCTL_SET_REPARSE_POINT = CTL_CODE(#FILE_DEVICE_FILE_SYSTEM, 41, #METHOD_BUFFERED, #FILE_SPECIAL_ACCESS)
#FSCTL_GET_REPARSE_POINT = CTL_CODE(#FILE_DEVICE_FILE_SYSTEM, 42, #METHOD_BUFFERED, #FILE_ANY_ACCESS)
#FSCTL_DELETE_REPARSE_POINT = CTL_CODE(#FILE_DEVICE_FILE_SYSTEM, 43, #METHOD_BUFFERED, #FILE_SPECIAL_ACCESS)
; Winbase.h
;
#FILE_FLAG_OPEN_REPARSE_POINT = $00200000
; WinNT.h
;
#IO_REPARSE_TAG_MOUNT_POINT = $A0000003
#IO_REPARSE_TAG_HSM = $C0000004
#IO_REPARSE_TAG_HSM2 = $80000006
#IO_REPARSE_TAG_SIS = $80000007
#IO_REPARSE_TAG_DFS = $8000000A
#IO_REPARSE_TAG_SYMLINK = $A000000C
#IO_REPARSE_TAG_DFSR = $80000012
; From Windows Driver Kit.
; http://msdn.microsoft.com/en-us/library/ms791514.aspx
;
Structure SymbolicLinkReparseBuffer
SubstituteNameOffset.w
SubstituteNameLength.w
PrintNameOffset.w
PrintNameLength.w
Flags.l
PathBuffer.w[1]
EndStructure
Structure MountPointReparseBuffer
SubstituteNameOffset.w
SubstituteNameLength.w
PrintNameOffset.w
PrintNameLength.w
PathBuffer.w[1]
EndStructure
Structure GenericReparseBuffer
DataBuffer.b[1]
EndStructure
Structure REPARSE_DATA_BUFFER
ReparseTag.l
ReparseDataLength.w
Reserved.w
StructureUnion
SymbolicLinkReparseBuffer.SymbolicLinkReparseBuffer
MountPointReparseBuffer.MountPointReparseBuffer
GenericReparseBuffer.GenericReparseBuffer
EndStructureUnion
EndStructure
; Tries to follow a directory link on Windows Vista (should also work for files)
;
; - If the directory is no link, the result is the original directory
; - If the target cannot be read, the result is ""
;
Procedure.s GetDirectoryTarget(Directory$)
Protected TokenHandle, BufferSize, hDirectory, BytesReturned.l
Protected Privileges.TOKEN_PRIVILEGES
Protected *Buffer.REPARSE_DATA_BUFFER
Protected Result$ = ""
; Check if the directory is a reparse point (link or mount point)
;
If GetFileAttributes_(@Directory$) & #FILE_ATTRIBUTE_REPARSE_POINT
; The backup privilege is required to open a directory for io queries
; So try to set it on our process token. (usually it should be set already)
;
If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES, @TokenHandle)
Privileges\PrivilegeCount = 1
Privileges\Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
If LookupPrivilegeValue_(#Null, @"SeBackupPrivilege", @Privileges\Privileges[0]\Luid)
AdjustTokenPrivileges_(TokenHandle, #False, @Privileges, SizeOf(TOKEN_PRIVILEGES), #Null, #Null)
EndIf
CloseHandle_(TokenHandle)
EndIf
; Open the directory
; Have to pass 0 as access right (not #GENERIC_READ), as it fails otherwise
; http://www.codeproject.com/KB/vista/Windows_Vista.aspx
;
hDirectory = CreateFile_(@Directory$, 0, #FILE_SHARE_READ|#FILE_SHARE_WRITE, #Null, #OPEN_EXISTING, #FILE_FLAG_OPEN_REPARSE_POINT | #FILE_FLAG_BACKUP_SEMANTICS, #Null)
If hDirectory <> #INVALID_HANDLE_VALUE
; Allocate a buffer for the io query. 1000 bytes should be enough for the real path (in unicode)
;
BufferSize = SizeOf(REPARSE_DATA_BUFFER) + 1000
*Buffer = AllocateMemory(BufferSize)
If *Buffer
; Query the directory for reparse point information
;
If DeviceIoControl_(hDirectory, #FSCTL_GET_REPARSE_POINT, #Null, 0, *Buffer, BufferSize, @BytesReturned, #Null) <> 0
; Check the kind of reparse point (device drivers can create their own tags, so this is important)
; The "& $FFFFFFFF" is for 64bit, as the tags are negative when interpreted as quads
;
If *Buffer\ReparseTag & $FFFFFFFF = #IO_REPARSE_TAG_MOUNT_POINT
; Read the result. The offset and length are in bytes. PeekS needs length in characters
;
Result$ = PeekS(@*Buffer\MountPointReparseBuffer\PathBuffer[0] + *Buffer\MountPointReparseBuffer\SubstituteNameOffset, *Buffer\MountPointReparseBuffer\SubstituteNameLength / 2, #PB_Unicode)
ElseIf *Buffer\ReparseTag & $FFFFFFFF = #IO_REPARSE_TAG_SYMLINK
Result$ = PeekS(@*Buffer\SymbolicLinkReparseBuffer\PathBuffer[0] + *Buffer\SymbolicLinkReparseBuffer\SubstituteNameOffset, *Buffer\SymbolicLinkReparseBuffer\SubstituteNameLength / 2, #PB_Unicode)
EndIf
EndIf
FreeMemory(*Buffer)
EndIf
CloseHandle_(hDirectory)
EndIf
Else
; It is not a reparse point, so return the original path
;
Result$ = Directory$
EndIf
; Since the result is a unicode directory name, it can have the "\??\" prefix which allows a length of 32767 characters.
;
If Left(Result$, 4) = "\??\"
Result$ = Right(Result$, Len(Result$)-4)
EndIf
ProcedureReturn Result$
EndProcedure
; ----------------------------------------------------------------------------
Directory$ = "C:\Documents and Settings\"
Debug "Testing: " + Directory$
Debug "Target: " + GetDirectoryTarget(Directory$)
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin

Genau was ich gesucht habe. Hatte eigentlich keine grosse Hoffnung, hier
Hilfe zu finden, aber versuch macht Klug.
Danke und Grüße
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Schon gelöst für michfreak hat geschrieben:Das ExplorerListGadget zeigt ein leeres Verzeichnis an, nicht weil es dem link nicht folgen kann sondern weil der Prozess nicht die Rechte dazu hat auf "C:\Documents and Settings" direkt zuzugreifen. Mit einem Unterordner wie "C:\Documents and Settings\<Username>" geht es wieder. Der Explorer lässt das browsen des Ordners auch nicht zu, desshalb ist es schon korrekt das das ExplorerListGadget nicht versucht selbst den link aufzulösen.

Ich löse immer nur den ersten auf und öffne das Resultat mit dem richtigen
Namen, schon komme ich weiter, wie in anderen Dateimanagern auch.
Lediglich der Explorer macht es anders, der erzeugt noch ein virtuelles
Verzeichnis Benutzer, das ein bissel irritiert

PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Hallo ts-soft,
ich habe auch einiger zeit her mit HardLink,Symboliclink,
ADS experimentiert..
der Source ist nicht so richtig übersichtig (total chaotisch)
aber für ein geübter programmierer wie du sollte es kein problem sein
anbei den Link:
Link Manager + source
Ciao
jpd
ich habe auch einiger zeit her mit HardLink,Symboliclink,
ADS experimentiert..
der Source ist nicht so richtig übersichtig (total chaotisch)
aber für ein geübter programmierer wie du sollte es kein problem sein

anbei den Link:
Link Manager + source
Ciao
jpd
PB 5.10 Windows 7 x64
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Sehr interessanter Code, werde ich wohl das eine oder anderen vonjpd hat geschrieben:ich habe auch einiger zeit her mit HardLink,Symboliclink,
ADS experimentiert..
Ciao
jpd
entwenden müssen

Die Phase, wo ich auch sowas in mein Projekt einbaue, wird kommen.

Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

das habe ich auch damals gedacht,ts-soft hat geschrieben:Die Phase, wo ich auch sowas in mein Projekt einbaue, wird kommen.
![]()
Thomas
aber leider die zeit ist immer so knapp

irgendwann werde ich das auch integrieren können.
aber erstmal wurde der code 4.30 kompatibel gemacht ...
die version ist über den gleichen Link erreichbar.
Ciao
jpd
PB 5.10 Windows 7 x64