DosFindFirst

From EDM2
Jump to: navigation, search

Finds the first file object or group of file objects whose names match the specification. The specification can include extended attributes (EA) associated with a file or directory.

Syntax

DosFindFirst(pszFileSpec, phdir, flAttribute, pfindbuf, cbBuf, pcFileNames, ulInfoLevel)

Parameters

pszFileSpec (PSZ) - input
Address of the ASCIIZ path name of the file or subdirectory to be found. The name component can contain global file name characters.
phdir (PHDIR) - in/out
Address of the handle associated with this DosFindFirst request. The values that can be specified for the handle are shown in the following list:
HDIR_CREATE (0xFFFFFFFF) - The system allocates and returns a handle. Upon return to the caller, phdir contains the handle allocated by the system for use by the process. This is the recommended option to use.
HDIR_SYSTEM (0x00000001) - The system assigns the handle for standard output, which is always available to a process. The DosFindFirst handle is used with subsequent DosFindNext requests. Reuse of this handle in another DosFindFirst request closes the association with the previous DosFindFirst request, and opens a new association with the current DosFindFirst request.
flAttribute (ULONG) - input 
Attribute value that determines the file objects to be searched for.
The bit values are shown in the following list:
31-14 Reserved; must be 0.
13 MUST_HAVE_ARCHIVED (0x00002000) Must-Have Archive bit; excludes files without the archive bit set if bit 13 is set to 1. Files may have the Archive bit set if bit 13 is set to 0.
12 MUST_HAVE_DIRECTORY (0x00001000) Must-Have Subdirectory bit; excludes files that are not subdirectories if bit 12 is set to 1. Files may have the Subdirectory bit set if bit 12 is set to 0.
11 Reserved; must be 0.
10 MUST_HAVE_SYSTEM (0x00000400) Must-Have System File bit; excludes nonsystem files if bit 10 is set to 1. Files may be system files if bit 10 is set to 0.
9 MUST_HAVE_HIDDEN (0x00000200) Must-Have Hidden File bit; excludes nonhidden files if bit 9 is set to 1. Files may be nonhidden if bit 9 is set to 0.
8 MUST_HAVE_READONLY (0x00000100) Must-Have Read-Only File bit; excludes writeable files if bit 8 is set to 1. Files may be read-only if bit 8 is set to 0.
7-6 Reserved; must be 0.
5 FILE_ARCHIVED (0x00000020) May-Have Archive bit; includes files with the Archive bit set if bit 5 is set to 1. Excludes files with the Archive bit set if bit 5 is set to 0.
4 FILE_DIRECTORY (0x00000010) May-Have Subdirectory bit; includes files that are subdirectories if bit 4 is set to 1. Excludes files that are subdirectories if bit 4 is set to 0.
3 Reserved; must be 0.
2 FILE_SYSTEM (0x00000004) May-Have System File bit; includes system files if bit 2 is set to 1. Excludes system files if bit 2 is set to 0.
1 FILE_HIDDEN (0x00000002) May-Have Hidden File bit; includes hidden files if bit 1 is set to 1. Excludes hidden files if bit 1 is set to 0.
0 FILE_READONLY (0x00000001) May-Have Read-Only File bit; includes read-only files if bit 0 is set to 1. Excludes read-only files if bit 0 is set to 0.
These bits may be set individually or in combination. For example, an attribute value of 0x00000024 (bits 5 and 2 set to 1) indicates searching for system files that have been archived.
Bits 8 through 13 are "Must-Have" flags. These allow you to obtain files that definitely have the given attributes. For example, if the Must-Have Subdirectory bit is set to 1, then all returned items are subdirectories.
If a Must-Have bit is set to 1, and the corresponding May-Have bit is set to 0, no items are returned for that attribute.
The attribute FILE_NORMAL (0x00000000) can be used to include files with any of the above bits set.
flAttribute cannot specify the volume label. Volume labels are queried using DosQueryFSInfo.
pfindbuf (PVOID) - in/out
Result buffer.
The result buffer from DosFindFirst should be less than 64KB.
Address of the directory search structures for file object information Levels 1 through 3. The structure required for pfindbuf is dependent on the value specified for ulInfoLevel. The information returned reflects the most recent call to DosClose or DosResetBuffer.
For Level 1 File Information (ulInfoLevel == FIL_STANDARD) :
On output, pfindbuf contains the FILEFINDBUF3 data structure without the last two fields: cchName and achName. This is used without EAs.
The oNextEntryOffset field indicates the number of bytes from the beginning of the current structure to the beginning of the next structure. When this field is 0, the last structure has been reached.
For Level 2 File Information (ulInfoLevel == FIL_QUERYEASIZE) :
On output, pfindbuf contains the FILEFINDBUF4 data structure without the last two fields: cchName and achName. This is used with EAs.
The cbList field contains the size, in bytes, of the file's entire EA set on disk. You can use this field to calculate the maximum size of the buffer needed for Level 3 file information. The size of the buffer required to hold the entire EA set is less than or equal to twice the size of the EA set on disk.
For Level 3 File Information (ulInfoLevel == FIL_QUERYEASFROMLIST) :
On input, pfindbuf contains an EAOP2 data structure. fpGEA2List contains a pointer to a GEA2 list, which defines the attribute names whose values are to be returned. Entries in the GEA2 list must be aligned on a doubleword boundary. Each oNextEntryOffset field must contain the number of bytes from the beginning of the current entry to the beginning of the next entry.
On output, pfindbuf contains a structure with a set of records, each aligned on a doubleword boundary. These records represent the directory entry and associated EAs for the matched file object. pfindbuf has the following format:
  • The EAOP2 data structure, with the fpFEA2List pointer incorrect.
  • The EAOP2 data structure occurs only once in the pfindbuf buffer. The rest of these records are repeated for the remainder of the file objects found.
  • A FILEFINDBUF3 data structure without the last two fields: cchName and achName.
  • A FEA2LIST data structure contained in and related to the FILEFINDBUF3 returned.
  • Length of the name string of the file object (cbName)
  • Name of the file object matched by the input pattern (achName)
Even if there is not enough room to hold all of the requested information, as for return code ERROR_BUFFER_OVERFLOW, the cbList field of the FEA2LIST data structure is valid if there is at least enough space to hold it.
When buffer overflow occurs, cbList contains the size on disk of the entire EA set for the file, even if only a subset of its attributes was requested. The size of the buffer required to hold the EA set is less than or equal to twice the size of the EA set on disk. If no error occurs, cbList includes the pad bytes (for doubleword alignment) between FEA2 structures in the list.
If a particular attribute is not attached to the object, pfindbuf has an FEA2 structure containing the name of the attribute, and the length value is 0.
The GEA2 list contained inside pfindbuf during a Level 3 DosFindFirst and DosFindNext call is not "read-only"; it is used by OS/2. When the function returns, the list is restored to it's original state, but inside the function, the list is manipulated by OS/2. This is of concern to a multithreaded application, where two different threads might use the same GEA2 list as input. If one thread calls DosFindFirst or DosFindNext while another thread is inside DosFindFirst or DosFindNext, the second thread will fail with a return code of ERROR_BAD_FORMAT.
cbBuf (ULONG) - input
The length, in bytes, of pfindbuf.
pcFileNames (PULONG) - in/out
Pointer to the number of entries:
Input - The address of the number of matching entries requested in pfindbuf.
Output - The number of entries placed into pfindbuf.

Return Code

ulrc (APIRET) - returns
DosFindFirst returns one of the following values:
  0 NO_ERROR
  2 ERROR_FILE_NOT_FOUND
  3 ERROR_PATH_NOT_FOUND
  6 ERROR_INVALID_HANDLE
 18 ERROR_NO_MORE_FILES
 26 ERROR_NOT_DOS_DISK
 87 ERROR_INVALID_PARAMETER
108 ERROR_DRIVE_LOCKED
111 ERROR_BUFFER_OVERFLOW
113 ERROR_NO_MORE_SEARCH_HANDLES
206 ERROR_FILENAME_EXCED_RANGE
208 ERROR_META_EXPANSION_TOO_LONG
254 ERROR_INVALID_EA_NAME
255 ERROR_EA_LIST_INCONSISTENT
275 ERROR_EAS_DIDNT_FIT

Remarks

The result buffer from DosFindFirst should be less than 64KB.

DosFindFirst returns directory entries (up to the number requested in pcFileNames) and extended-attribute information for as many files or subdirectories whose names, attributes, and EAs match the specification, and whose information fits in pfindbuf. On output, pcFileNames contains the actual number of directory entries returned.

The file name pointed to by pszFileSpec can contain global file-name characters.

DosFindNext uses the directory handle associated with DosFindFirst to continue the search started by the DosFindFirst request.

Any nonzero return code, except ERROR_EAS_DIDNT_FIT, indicates that no handle has been allocated. This includes such nonerror indicators as ERROR_NO_MORE_FILES.

For ERROR_EAS_DIDNT_FIT, a search handle is returned, and a subsequent call to DosFindNext gets the next matching entry in the directory. You can use DosQueryPathInfo to retrieve the EAs for the matching entry by using the same EA arguments used for the DosFindFirst call, and the name that was returned by DosFindFirst.

For ERROR_EAS_DIDNT_FIT, only information for the first matching entry is returned. This entry is the one whose extended attributes did not fit in the buffer. The information returned is in the format of that returned for information Level 2. No further entries are returned in the buffer, even if they could fit in the remaining space.

The GEA2 list contained inside pfindbuf during a Level 3 DosFindFirst and DosFindNext call is not "read-only", it is used by OS/2. When the function returns, the list is restored to it's original state, but inside the function, the list is manipulated by OS/2. This is of concern to a multithreaded application, where two different threads might use the same GEA2 list as input. If one thread calls DosFindFirst or DosFindNext while another thread is inside DosFindFirst or DosFindNext, the second thread will fail with a return code of ERROR_BAD_FORMAT.

Example Code

This example lists all the normal files that are in the directory from where the example is invoked.

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

 int main (VOID) {
    HDIR          hdirFindHandle = HDIR_CREATE;
    FILEFINDBUF3  FindBuffer     = {0};      /* Returned from FindFirst/Next */
    ULONG         ulResultBufLen = sizeof(FILEFINDBUF3);
    ULONG         ulFindCount    = 1;        /* Look for 1 file at a time    */
    APIRET        rc             = NO_ERROR; /* Return code                  */

    rc = DosFindFirst( "*.*",                /* File pattern - all files     */
                       &hdirFindHandle,      /* Directory search handle      */
                       FILE_NORMAL,          /* Search attribute             */
                       &FindBuffer,          /* Result buffer                */
                       ulResultBufLen,       /* Result buffer length         */
                       &ulFindCount,         /* Number of entries to find    */
                       FIL_STANDARD);        /* Return Level 1 file info     */

    if (rc != NO_ERROR) {
       printf("DosFindFirst error: return code = %u\n",rc);
       return 1;
    } else {
       printf ("%s\n", FindBuffer.achName);   /* Print file name             */
    } /* endif */

    /* Keep finding the next file until there are no more files */
    while (rc != ERROR_NO_MORE_FILES) {
       ulFindCount = 1;                      /* Reset find count.            */

       rc = DosFindNext(hdirFindHandle,      /* Directory handle             */
                        &FindBuffer,         /* Result buffer                */
                        ulResultBufLen,      /* Result buffer length         */
                        &ulFindCount);       /* Number of entries to find    */

       if (rc != NO_ERROR && rc != ERROR_NO_MORE_FILES) {
          printf("DosFindNext error: return code = %u\n",rc);
          return 1;
       } else {
          printf ("%s\n", FindBuffer.achName);    /* Print file name */
       }
    } /* endwhile */

    rc = DosFindClose(hdirFindHandle);    /* Close our directory handle */
    if (rc != NO_ERROR) {
       printf("DosFindClose error: return code = %u\n",rc);
       return 1;
    }
    return NO_ERROR;
 }

Related Functions