GETATTR delivers under Windows7 following values:
GETATTR("C:\Users\All Users") = 9238
GETATTR("C:\ProgramData") = 73746
GETATTR("C:\Users\All Users") = 9238
GETATTR("C:\ProgramData") = 73746
#COMPILE EXE #DIM ALL #INCLUDE "WIN32API.INC" GLOBAL gcFiles AS LONG GLOBAL gcFolders AS LONG GLOBAL glFileAtt() AS LONG GLOBAL glFoldAtt() AS LONG GLOBAL gsFiles() AS STRING GLOBAL gsFolders() AS STRING SUB GetAllFiles (BYVAL sStartFolder AS STRING) LOCAL hSearch AS DWORD LOCAL WFD AS WIN32_FIND_DATA sStartFolder = RTRIM$(sStartFolder, "\") hSearch = FindFirstFile(BUILD$(sStartFolder,"\*"), WFD) IF hSearch <> %INVALID_HANDLE_VALUE THEN DO IF (WFD.dwFileAttributes AND %FILE_ATTRIBUTE_DIRECTORY) = %FILE_ATTRIBUTE_DIRECTORY THEN IF ASC(WFD.cFileName) <> 46 THEN ' 46 = "." REDIM PRESERVE gsFolders (gcFolders) AS STRING REDIM PRESERVE glFoldAtt (gcFolders) AS LONG gsFolders (gcFolders) = sStartFolder + "\" + WFD.cFileName glFoldAtt (gcFolders) = WFD.dwFileAttributes INCR gcFolders CALL GetAllFiles (sStartFolder + "\" + WFD.cFileName) END IF ELSE REDIM PRESERVE gsFiles (gcFiles) AS STRING REDIM PRESERVE glFileAtt (gcFiles) AS LONG gsFiles (gcFiles) = sStartFolder + "\" + WFD.cFileName glFileAtt (gcFiles) = WFD.dwFileAttributes INCR gcFiles END IF LOOP WHILE FindNextFile(hSearch, WFD) FindClose hSearch END IF END SUB SUB PB_DeleteFile(BYVAL pFile AS STRING) ON ERROR RESUME NEXT KILL pFile END SUB SUB PB_WriteFile (BYVAL pFile AS STRING, pFiles() AS STRING, pAttr() AS LONG) ON ERROR GOTO FN_ERR LOCAL f AS LONG LOCAL i AS LONG f = FREEFILE OPEN pFile FOR OUTPUT ACCESS WRITE AS #f FOR i = LBOUND(pFiles) TO UBOUND(pFiles) PRINT #f, FORMAT$(pAttr(i)) + $TAB + pFiles(i) NEXT i CLOSE #f FN_EXIT: EXIT SUB FN_ERR: MSGBOX ERROR$,,FUNCNAME$ RESUME FN_EXIT END SUB FUNCTION PBMAIN () AS LONG LOCAL StartFolder AS STRING LOCAL tmp AS STRING LOCAL i AS LONG StartFolder = "C:\" tmp = "CALL GetAllFiles (" + $DQ + StartFolder + $DQ + ")" #IF %DEF(%PB_CC32) STDOUT tmp #ELSE MSGBOX tmp #ENDIF DIM gsFiles(0) AS STRING CALL GetAllFiles (StartFolder) ' sort and write log-file... ARRAY SORT gsFiles(), TAGARRAY glFileAtt() ARRAY SORT gsFolders(), TAGARRAY glFoldAtt() CALL PB_DeleteFile (EXE.FULL$+".files.txt") CALL PB_DeleteFile (EXE.FULL$+".folders.txt") CALL PB_WriteFile (EXE.FULL$+".files.txt", gsFiles(), glFileAtt()) CALL PB_WriteFile (EXE.FULL$+".folders.txt", gsFolders(), glFoldAtt()) ' -------------------------------------------------------- tmp = FORMAT$(gcFiles) + " files in " + StartFolder tmp = tmp + $CRLF + $CRLF + "Log files:" + $CRLF + EXE.FULL$+".files.txt" + $CRLF + EXE.FULL$+".folders.txt" #IF %DEF(%PB_CC32) STDOUT tmp WAITKEY$ #ELSE MSGBOX tmp #ENDIF END FUNCTION
typedef struct _REPARSE_DATA_BUFFER { ULONG ReparseTag; USHORT ReparseDataLength; USHORT Reserved; union { struct { USHORT SubstituteNameOffset; USHORT SubstituteNameLength; USHORT PrintNameOffset; USHORT PrintNameLength; ULONG Flags; WCHAR PathBuffer[1]; } SymbolicLinkReparseBuffer; struct { USHORT SubstituteNameOffset; USHORT SubstituteNameLength; USHORT PrintNameOffset; USHORT PrintNameLength; WCHAR PathBuffer[1]; } MountPointReparseBuffer; struct { UCHAR DataBuffer[1]; } GenericReparseBuffer; }; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
#COMPILE EXE #DIM ALL #INCLUDE "win32api.inc" #INCLUDE "winioctl.inc" [COLOR="SeaGreen"]' Constant is missing in Win32API.inc[/COLOR] %IO_REPARSE_TAG_SYMLINK = &hA000000C [COLOR="SeaGreen"]' http://msdn.microsoft.com/en-us/library/ms791514.aspx[/COLOR] TYPE REPARSE_DATA_BUFFER ReparseTag AS LONG ReparseDataLength AS WORD Reserved AS WORD SubstituteNameOffset AS WORD SubstituteNameLength AS WORD PrintNameOffset AS WORD PrintNameLength AS WORD Flags AS LONG PathBuffer(%MAXIMUM_REPARSE_DATA_BUFFER_SIZE) AS WORD [COLOR="SeaGreen"]' Unicode[/COLOR] END TYPE FUNCTION GetDirectoryTarget (BYVAL pDir AS STRING) AS STRING LOCAL mDir AS ASCIIZ * %MAX_PATH LOCAL TokenHandle AS LONG LOCAL TokenPrivilleges AS TOKEN_PRIVILEGES LOCAL hDirectory AS LONG LOCAL BufferSize AS LONG LOCAL Buffer AS REPARSE_DATA_BUFFER LOCAL BytesReturned AS LONG LOCAL lRet AS LONG LOCAL ResultW AS STRING LOCAL ResultA AS STRING mDir = pDir [COLOR="SeaGreen"]' Check if the directory is a reparse point (link or mount point)[/COLOR] IF (GetFileAttributes(mDir) AND %FILE_ATTRIBUTE_REPARSE_POINT) = %FILE_ATTRIBUTE_REPARSE_POINT THEN [COLOR="SeaGreen"]' 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)[/COLOR] IF OpenProcessToken(GetCurrentProcess(), %TOKEN_ADJUST_PRIVILEGES, TokenHandle) THEN TokenPrivilleges.PrivilegeCount = 1 TokenPrivilleges.Privileges(0).Attributes = %SE_PRIVILEGE_ENABLED IF LookupPrivilegeValue($NUL, $SE_BACKUP_NAME, TokenPrivilleges.Privileges(0).pLuid) THEN AdjustTokenPrivileges(TokenHandle, %FALSE, TokenPrivilleges, SIZEOF(TokenPrivilleges), BYVAL 0, BYVAL 0) END IF CloseHandle (TokenHandle) END IF [COLOR="SeaGreen"]' Open directory[/COLOR] hDirectory = CreateFile(mDir, BYVAL 0, %FILE_SHARE_READ OR %FILE_SHARE_WRITE, BYVAL 0, %OPEN_EXISTING, %FILE_FLAG_OPEN_REPARSE_POINT OR %FILE_FLAG_BACKUP_SEMANTICS, BYVAL 0) IF hDirectory <> %INVALID_HANDLE_VALUE THEN [COLOR="SeaGreen"]' Query the directory for reparse point information[/COLOR] BufferSize = SIZEOF(Buffer) lRet = DeviceIoControl(hDirectory, %FSCTL_GET_REPARSE_POINT, BYVAL %NULL, 0, Buffer, BufferSize, BytesReturned, BYVAL %NULL) IF lRet <> 0 THEN [COLOR="SeaGreen"]' Check the kind of reparse point (device drivers can create their own tags, so this is important)[/COLOR] IF (Buffer.ReparseTag AND &hFFFFFFFF) = %IO_REPARSE_TAG_[COLOR="Red"][B]MOUNT_POINT[/B][/COLOR] THEN [COLOR="SeaGreen"]' Read the result. The offset and length are in bytes. Peek$ needs length in characters[/COLOR] ResultW = PEEK$(VARPTR(Buffer.PathBuffer(0)) + [COLOR="Red"][B]Buffer.SubstituteNameOffset - 4[/B][/COLOR], Buffer.SubstituteNameLength) ResultA = ACODE$(ResultW) MSGBOX "Reparse: " + pDir + $CR + "Target: " + ResultA,,"IO_REPARSE_TAG_MOUNT_POINT" END IF IF (Buffer.ReparseTag AND &hFFFFFFFF) = %IO_REPARSE_[COLOR="DarkOrange"][B]TAG_SYMLINK[/B][/COLOR] THEN [COLOR="SeaGreen"]' Read the result. The offset and length are in bytes. Peek$ needs length in characters[/COLOR] ResultW = PEEK$(VARPTR(Buffer.PathBuffer(0)) + [COLOR="DarkOrange"][B]Buffer.SubstituteNameOffset[/B][/COLOR], Buffer.SubstituteNameLength) ResultA = ACODE$(ResultW) MSGBOX "Reparse: " + pDir + $CR + "Target: " + ResultA,,"IO_REPARSE_TAG_SYMLINK" END IF END IF END IF CloseHandle(hDirectory) ELSE MSGBOX pDir + " is not a mount point or symlink" END IF FUNCTION = ResultA END FUNCTION FUNCTION PBMAIN () AS LONG CALL GetDirectoryTarget("C:\Documents and Settings") CALL GetDirectoryTarget("C:\Users\All Users") END FUNCTION
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Comment