Search code examples
cheaderzipfile-format

Determine if file is a directory, inside zip archive


I read zip files according to the specification, and get information for each file, from a central directory. From the headers I read:

#define VERSION_NEEDED_OFSSET 6

UINT16 versionNeeded = (UINT16)*(zipFile + VERSION_NEEDED_OFSSET);

So I zipped some files, and also a few directories, and when I got info about the directory, I got versionNeeded = 0x000a

From the documentation I read:

The minimum supported ZIP specification version needed to extract the file, mapped as above. This value is based on the specific format features a ZIP program MUST support to be able to extract the file. If multiple features are applied to a file, the minimum version MUST be set to the feature having the highest value. New features or feature changes affecting the published format specification will be implemented using higher version numbers than the last published value to avoid conflict.

4.4.3.2 Current minimum feature versions are as defined below:

1.0 - Default value

1.1 - File is a volume label

2.0 - File is a folder (directory)

But what is the part of the zip header that is used to determine the file type? I cannot see any types or bits that are responsible for the file type from the documentation.


Solution

  • Ok. If anyone finds this, the right way to do this is to check the offset at central directory start plus 38, a field called external file attributes

    From the documentation:

    4.4.15 external file attributes: (4 bytes) The mapping of the external attributes is host-system dependent (see 'version made by'). For MS-DOS, the low order byte is the MS-DOS directory attribute byte. If input came from standard input, this field is set to zero.

    UINT32 external_attributes = (UINT32)*(zipFile + 38);
    

    Then you match this value against this constants from MSDN.

    To match a directory, compare the external_attributes like so:

    if(external_attributes == 0x10) //FILE_ATTRIBUTE_DIRECTORY