DosEnumAttribute

From EDM2
Jump to: navigation, search

Identifies names and lengths of extended attributes for a specific file or subdirectory.

Syntax

DosEnumAttribute(ulRefType, pvFile, ulEntry, pvBuf, cbBuf, pulCount, ulInfoLevel)

Parameters

ulRefType (ULONG) - input 
A value that indicates whether pvFile points to a handle or to an ASCIIZ name.
Possible values are shown in the following list:
0 ENUMEA_REFTYPE_FHANDLE - Handle of a file.
1 ENUMEA_REFTYPE_PATH - ASCIIZ name of a file or subdirectory.
pvFile (PVOID) - input 
Address of the handle of a file returned by DosOpen; or the ASCIIZ name of a file or subdirectory.
ulEntry (ULONG) - input 
Ordinal of an entry in the file object's EA list, which indicates where in the list to begin the return of EA information.
The value 0 is reserved. A value of 1 indicates the file object's first EA; a value of 2, the second; and so on.
pvBuf (PVOID) - output 
Address of the buffer where EA information is returned.
Level 1 information (ulInfoLevel == ENUMEA_LEVEL_NO_VALUE) is returned in a data structure of type DENA2.
cbBuf (ULONG) - input 
The length, in bytes, of the buffer pointed to by pvBuf.
pulCount (PULONG) - in/out 
Pointer to number of EAs.
Input
A pointer to the ULONG containing the number of EAs for which information is requested. A value of -1 requests that information be returned for as many EAs whose information fits in pvBuf.
Output
A pointer to the ULONG containing the actual number of EAs for which information is returned. When this value is greater than 1, enumerated information is returned in a series of DENA2 data structures. Each data structure is aligned on a doubleword (or 32-bit) boundary. The first field of the data structure (oNextEntryOffset) contains the number of bytes to the beginning of the next data structure. A value of zero for oNextEntryOffset indicates that this is the last data structure.
ulInfoLevel (ULONG) - input 
Level of information required.
Only the value 1 (ENUMEA_LEVEL_NO_VALUE) can be specified, indicating return of level 1 information.

Return Code

ulrc (APIRET) - returns
DosEnumAttribute returns one of the following values:
  • 9 NO_ERROR
  • 2 ERROR_FILE_NOT_FOUND
  • 3 ERROR_PATH_NOT_FOUND
  • 5 ERROR_ACCESS_DENIED
  • 6 ERROR_INVALID_HANDLE
  • 8 ERROR_NOT_ENOUGH_MEMORY
  • 87 ERROR_INVALID_PARAMETER
  • 111 ERROR_BUFFER_OVERFLOW
  • 124 ERROR_INVALID_LEVEL
  • 206 ERROR_FILENAME_EXCED_RANGE

Remarks

The structure that DosEnumAttribute returns is used to calculate the size of the buffer needed to hold the full extended attribute (FEA2) information for a DosQueryPathInfo or DosQueryFileInfo call that actually gets the FEA2. The buffer size is calculated as follows:

Four bytes (for oNextEntryOffset) +
One byte (for fEA) +
One byte (for cbName) +
Two bytes (for cbValue) +
Value of cbName (for the name of the EA) +
One byte (for terminating NULL in cbName) +
Value of cbValue (for the value of the EA) 

Each entry must start on a doubleword boundary.

A process can continue through a file's EA list by reissuing DosEnumAttribute with ulEntry set to the value specified in the previous call, plus the value returned in pulCount.

DosEnumAttribute does not control the specific ordering of EAs; it merely identifies them. Extended attributes can have multiple readers and writers, just as the files they are associated with can. If a file is open in a sharing mode that allows other processes to modify the file's EA list, repetitively calling DosEnumAttribute to back up to an EA's position may return inconsistent results. For example with DosSetFileInfo or DosSetPathInfo, another process can edit the EA list between calls by your process to DosEnumAttribute. Therefore, the EA returned when ulEntry is 11 for the first call might not be the same EA returned when ulEntry is 11 for the next call.

To prevent EAs from being modified between calls to DosEnumAttribute for a specified file handle or file name, the calling function must open the file in deny-write sharing mode before it calls DosEnumAttribute. If a subdirectory name is specified, modification by other processes is not a concern, because no sharing is possible.

When a value of 1 (ENUMEA_REFTYPE_PATH) is specified for ulRefType, the EAs returned are current only when the call was made, and may have been changed by another thread or process since then.

Example Code

This example gets all the possible extended attributes (EAs) from the file "ATTRIB.EXE" in the OS2 directory, and then displays the names.

 #define INCL_DOSFILEMGR   /* File Manager values */
 #define INCL_DOSERRORS    /* DOS error values    */
 #include <os2.h>
 #include <stdio.h>

int main(VOID) {
   UCHAR    EnumBuf[200] = {0};      /* Data Buffer */
   ULONG    ulEnumCnt    = 0;        /* Count of entries to return */
   FEA2     *ptr         = NULL;     /* Pointer to data items returned */
   ULONG    ulTemp       = 0;
   APIRET   rc           = NO_ERROR; /* Return code  */
   ULONG    i            = 0;        /* Loop index */

   ulEnumCnt = (ULONG)-1; /* Request as many attributes as will fit in buffer */

   rc = DosEnumAttribute(ENUMEA_REFTYPE_PATH,   /* ASCIIZ string to be used   */
                         "c:\\os2\\attrib.exe", /* Name of file               */
                         1L,                    /* Start with first attribute */
                         (PVOID)&EnumBuf,       /* Buffer for information     */
                         sizeof(EnumBuf),
                         &ulEnumCnt,
                         ENUMEA_LEVEL_NO_VALUE); /* Request level 1 info      */

   if (rc != NO_ERROR) {
      printf("DosEnumAttribute error: return code = %u\n", rc);
      return 1;
   }

   ptr = (FEA2 *)EnumBuf; /* Mask the buffer pointer to an FEA2 structure */

   printf ("Attributes found = %u\n", ulEnumCnt);

   for (i = 0; i < ulEnumCnt; i++) {
      printf ("name = %s\n", ptr->szName);         /* increment the ptr     */
      ulTemp = ptr->oNextEntryOffset + (ULONG)ptr; /* with the value in     */
      ptr = (FEA2 *)ulTemp;                        /* oNextEntryOffset      */
   } /* endfor */                                  /* to access next record */

   return NO_ERROR;
}

Related Functions