Seite 1 von 1

Directory-Junctions

Verfasst: 27.07.2012 01:01
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).

Re: Directory-Junctions

Verfasst: 27.07.2012 01:14
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"

Re: Directory-Junctions

Verfasst: 27.07.2012 01:17
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...

Re: Directory-Junctions

Verfasst: 27.07.2012 01:22
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

Re: Directory-Junctions

Verfasst: 27.07.2012 01:27
von GPI
jup, tat schon weh der Fehler - ist schon spät.

Jetzt sollte das so gehen wie gedacht :)