Directory-Junctions

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Directory-Junctions

Beitrag von GPI »

Code: Alles auswählen

;basis http://www.purebasic.fr/english/viewtopic.php?f=7&t=29860&p=220852 - wenn auch ohne funktion...
;Anleitung: http://www.flexhex.com/docs/articles/hard-links.phtml



#FILE_DEVICE_FILE_SYSTEM = 9
#METHOD_BUFFERED = 0
#FILE_ANY_ACCESS = 0

#FILE_LIST_DIRECTORY = 1 
#FILE_SHARE_READ = 1 
#FILE_SHARE_DELETE = 4 
#OPEN_EXISTING = 3 
#FILE_FLAG_BACKUP_SEMANTICS = 33554432; $02000000 
#FILE_SHARE_DELETE = 4 
#FILE_FLAG_OPEN_REPARSE_POINT=2097152 


#IO_REPARSE_TAG_MOUNT_POINT = 2684354563
#IO_REPARSE_TAG_SYMLINK   = 2684354572
#GetFileExInfoStandard=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)

;-ReparseTag values...


Structure REPARSE_MOUNTPOINT_DATA_BUFFER
  ReparseTag.l
  ReparseDataLength.l
  Reserved.w
  ReparseTargetLength.w
  ReparseTargetMaximumLength.w
  Reserved1.w
  ReparseTarget.b[1]
EndStructure
#REPARSE_MOUNTPOINT_HEADER_SIZE=8

;-start
Procedure IsJuction(dirin.s)
  attribute.WIN32_FIND_DATA 
  GetFileAttributesEx_(DirIn ,#GetFileExInfoStandard,@attribute)
  If  attribute\dwFileAttributes & #FILE_ATTRIBUTE_REPARSE_POINT 
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure



DirIn.s="c:\test113"
DirOut.s="\??\c:\empty\"; 

Procedure CreateJunction(dirin.s,dirout.s)
  handle.l=CreateFile_(DirIn, #GENERIC_WRITE | #GENERIC_READ ,#FILE_SHARE_READ, #Null, #OPEN_EXISTING, #FILE_FLAG_BACKUP_SEMANTICS|#FILE_FLAG_OPEN_REPARSE_POINT, #Null) 
  If handle <>#INVALID_HANDLE_VALUE
    *buffer.REPARSE_MOUNTPOINT_DATA_BUFFER=AllocateMemory(SizeOf(REPARSE_MOUNTPOINT_DATA_BUFFER)+Len(dirout)*2+2)
    *buffer\ReparseTag=#IO_REPARSE_TAG_MOUNT_POINT
    PokeS(*buffer+OffsetOf(REPARSE_MOUNTPOINT_DATA_BUFFER\ReparseTarget),dirout,-1,#PB_Unicode)      
    *buffer\ReparseTargetMaximumLength=Len(dirout)*2+2
    *buffer\ReparseTargetLength=Len(dirout)*2
    *buffer\ReparseDataLength=*buffer\ReparseTargetLength+12
    dummy.l=0
    DeviceIoControl_(handle, #FSCTL_SET_REPARSE_POINT,*buffer,*buffer\ReparseDataLength+#REPARSE_MOUNTPOINT_HEADER_SIZE ,#Null,0,@dummy,#Null) 
    CloseHandle_(handle)
    FreeMemory(*buffer)
  EndIf
EndProcedure
Procedure DeleteJunction(dirin.s)  
  handle.l=CreateFile_(DirIn, #GENERIC_WRITE | #GENERIC_READ ,#FILE_SHARE_READ, #Null, #OPEN_EXISTING, #FILE_FLAG_BACKUP_SEMANTICS|#FILE_FLAG_OPEN_REPARSE_POINT, #Null)  
  If handle <>#INVALID_HANDLE_VALUE
    *buffer.REPARSE_MOUNTPOINT_DATA_BUFFER=AllocateMemory(SizeOf(REPARSE_MOUNTPOINT_DATA_BUFFER)+2)
    *buffer\ReparseTag=#IO_REPARSE_TAG_MOUNT_POINT
    dummy.l=0
    DeviceIoControl_(handle, #FSCTL_DELETE_REPARSE_POINT,*buffer,*buffer\ReparseDataLength+#REPARSE_MOUNTPOINT_HEADER_SIZE ,#Null,0,@dummy,#Null) 
    CloseHandle_(handle)
    FreeMemory(*buffer)
  EndIf
EndProcedure

CreateDirectory(dirin)
MessageRequester("Test",Str( IsJuction(dirin)))
createjunction(dirin,dirout)
MessageRequester("Test",Str( IsJuction(dirin)))
deletejunction(dirin)
MessageRequester("Test",Str( IsJuction(dirin)))
DeleteDirectory(dirin,"*.*")

End
Funktioniert hier unter win7 wunderbar - kann das wer auf XP testen?

Es wird ein Verzeichnis-Link "c:\test113" erstellt, das auf "c:\empty" verweist (bitte vorher erstellen und eine dummy-Datei zu Testzwecken reinkopieren).
Zuletzt geändert von GPI am 27.07.2012 01:26, insgesamt 3-mal geändert.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Directory-Junctions

Beitrag von STARGÅTE »

Also der Code an sich hat seine Arbeit scheinbar gemacht, zumindest wurde test113 als Ordner erstellt welcher auch den Inhalt von empty zeigt.
Allerdings bekomme ich im Code einen IMA bei:

Code: Alles auswählen

      Debug Str(ret)+" "+result$
      
      FreeMemory(*buffer) ; Hier ...
    EndIf
IsDir: c:\test113
IsEmpty
hDir: 0
0 Der Vorgang wurde erfolgreich beendet.
Scheinbar wird der Speicher schon woanders freigegeben oder "missbraucht"
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Directory-Junctions

Beitrag von GPI »

STARGÅTE hat geschrieben:Also der Code an sich hat seine Arbeit scheinbar gemacht, zumindest wurde test113 als Ordner erstellt welcher auch den Inhalt von empty zeigt.
Allerdings bekomme ich im Code einen IMA bei:

Code: Alles auswählen

      Debug Str(ret)+" "+result$
      
      FreeMemory(*buffer) ; Hier ...
    EndIf
IsDir: c:\test113
IsEmpty
hDir: 0
0 Der Vorgang wurde erfolgreich beendet.
Scheinbar wird der Speicher schon woanders freigegeben oder "missbraucht"
Ich hab es nochmal umgestellt und umgeschrieben (so ein junction lässt sich leider nicht einfach löschen)

Aber der Buffer darf eigentlich nicht einfach freigegeben werden...
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Directory-Junctions

Beitrag von STARGÅTE »

Hm bekomme auch immer noch:
---------------------------
Test
---------------------------
0
---------------------------
OK
---------------------------
hDir: 0
hDir: 0
aber wie gesagt, funktionieren tut es scheinbar ...
also muss IsJuction() irgendwie ein Problem haben
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Directory-Junctions

Beitrag von GPI »

jup, tat schon weh der Fehler - ist schon spät.

Jetzt sollte das so gehen wie gedacht :)
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Antworten