Announcement

Collapse
No announcement yet.

Getattr - win7

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Getattr - win7

    GETATTR delivers under Windows7 following values:

    GETATTR("C:\Users\All Users") = 9238
    GETATTR("C:\ProgramData") = 73746

    #2
    w7 as added at least one attrubute. That one being letter 'I'. Don't have a clue what that means and if there are other attributes. Haven't run across them, yet.

    However, I've run across this situation in xp. File attribute numbers > 255.
    Last edited by Mel Bishop; 1 Nov 2009, 08:11 AM.
    There are no atheists in a fox hole or the morning of a math test.
    If my flag offends you, I'll help you pack.

    Comment


      #3
      C:\Users\All Users and C:\ProgramData

      Both folders contain the same files.

      If the C: is scanned (with FindFirstFile, FindNextFile),
      then corresponding files are counted twice.

      How can I prevent this?

      Comment


        #4
        Since you haven't posted an example of how you are finding these files, a couple of thoughts comes to mind.

        1. DIR$
        2. Check the path(s) for unwanted files.
        There are no atheists in a fox hole or the morning of a math test.
        If my flag offends you, I'll help you pack.

        Comment


          #5
          GetAttr() returns styles, you should use them accordingly

          If GetAttr(...) AND ... style then...

          And thus not by some 'total' number!
          hellobasic

          Comment


            #6
            FindFirstFileEX?

            Per doc allows you to filter the attributes of files returned.
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


              #7
              Originally posted by Edwin Knoppert View Post
              GetAttr() returns styles, you should use them accordingly

              If GetAttr(...) AND ... style then...

              And thus not by some 'total' number!
              I found the following attributes:

              %FILE_ATTRIBUTE_READONLY = &H00000001
              %FILE_ATTRIBUTE_HIDDEN = &H00000002
              %FILE_ATTRIBUTE_SYSTEM = &H00000004
              %FILE_ATTRIBUTE_DIRECTORY = &H00000010
              %FILE_ATTRIBUTE_ARCHIVE = &H00000020
              %FILE_ATTRIBUTE_DEVICE = &H00000040
              %FILE_ATTRIBUTE_NORMAL = &H00000080
              %FILE_ATTRIBUTE_TEMPORARY = &H00000100
              %FILE_ATTRIBUTE_SPARSE_FILE = &H00000200
              %FILE_ATTRIBUTE_REPARSE_POINT = &H00000400
              %FILE_ATTRIBUTE_COMPRESSED = &H00000800
              %FILE_ATTRIBUTE_OFFLINE = &H00001000
              %FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = &H00002000
              %FILE_ATTRIBUTE_ENCRYPTED = &H00004000

              Thus:
              GETATTR("C:\Users\All Users") = 9238 = &h2416 = HIDDEN or SYSTEM or DIRECTORY or REPARSE_POINT or NOT_CONTENT_INDEXED

              But what is:
              GETATTR("C:\ProgramData") = 73746 = &h00012012 =

              Comment


                #8
                The answer is right here. It took me close to forty(40) seconds to find it.

                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                  #9
                  Originally posted by Michael Mattias View Post
                  The answer is right here. It took me close to forty(40) seconds to find it.

                  http://msdn.microsoft.com/en-us/libr...30(VS.85).aspx
                  Thanks for you help.
                  And, what is FILE_ATTRIBUTE_VIRTUAL?

                  Comment


                    #10
                    >And, what is FILE_ATTRIBUTE_VIRTUAL?

                    What part of "This value is reserved for system use" don't you understand?
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                      #11
                      C:\Users\All Users and C:\ProgramData

                      Both folders point to the same content.
                      How can I find out if included in the collection duplicate file objects?
                      I probably must to look (open) at the linking of the virtual folders (FILE_ATTRIBUTE_VIRTUAL).
                      But how?

                      Code:
                      #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

                      Comment


                        #12
                        FILE_ATTRIBUTE_REPARSE_POINT 1024 0x0400 A file or directory that has an associated reparse point, or a file that is a symbolic link.

                        One of your two folders has this attribute. Skip it.

                        Or, perhaps better still, skip the file with the "Virtual" attribute. Even though the attribute is "reserved for system use" and not further documented, "virtual" sounds like "not real" and therefore not worthy of inclusion in your list of "real" files.

                        Sometimes you just have to make a guess.
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                          #13
                          It would be better if I had a API function that shows me which folders are linked (hard-, soft-, symbolic link, etc.).

                          Comment


                            #14
                            I think I could use DeviceIoControl and WinIOCtl.inc -> %FSCTL_GET_REPARSE_POINT

                            Please help me translate the C-structure.
                            REPARSE_DATA_BUFFER

                            Comment


                              #15
                              I have three dollars sixty-two cents says simply skipping files/folders with attribute FILE_ATTRIBUTE_VIRTUAL solves your problem.. whatever that problem is.

                              You have not described the application, so darned if I know what you are trying to accomplish here... what is this, some kind of 'backup' application?
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                                #16
                                Originally posted by Michael Mattias View Post
                                I have three dollars sixty-two cents says simply skipping files/folders with attribute FILE_ATTRIBUTE_VIRTUAL solves your problem.. whatever that problem is.

                                You have not described the application, so darned if I know what you are trying to accomplish here... what is this, some kind of 'backup' application?
                                I will collect all the files in a folder or drive. After this, the files are processed. However, no duplicate files to be processed further.

                                I think I could use DeviceIoControl and WinIOCtl.inc -> %FSCTL_GET_REPARSE_POINT

                                Please help me translate the C-structure.
                                REPARSE_DATA_BUFFER

                                Code:
                                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;

                                Comment


                                  #17
                                  With the following code corresponding links can be read.
                                  In the program I do not understand one point:
                                  Why is counted once Buffer.SubstituteNameOffset-4 ?
                                  (See red marker.)
                                  Is the code really properly? Or I made a bug?

                                  Code:
                                  #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

                                  Comment


                                    #18
                                    When it comes to directories, MS refers to those "redirects" as Junction Points.

                                    See

                                    In Windows Vista and Windows Server 2008, the default locations for user data and system data have changed.

                                    Comment


                                      #19
                                      Thanks for the links.

                                      I hope that someone look at my example code...
                                      Is everything programmed correctly?

                                      Comment


                                        #20
                                        Originally posted by Bernhard Fomm View Post
                                        Thanks for the links.

                                        I hope that someone look at my example code...
                                        Is everything programmed correctly?
                                        Bernhard,

                                        On my compiter I get "C:\Documents and Settings is not a mount point or symlink" and then nothing for "C:\Users\All Users" (program ends).

                                        I don't have a "C:\Users\All Users" folder on my hard drive.

                                        Hope that helps.

                                        =============================
                                        That's cool beyond cold, Man.
                                        Swede
                                        =============================
                                        It's a pretty day. I hope you enjoy it.

                                        Gösta

                                        JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                                        LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                                        Comment

                                        Working...
                                        X
                                        😀
                                        🥰
                                        🤢
                                        😎
                                        😡
                                        👍
                                        👎