/* * higher level interfaces for findfirst/findnext (DOS) */ #include #include #include /* * OS/2 allows you to have multiple finds operating at the same * time, like dos does, but it doesn't give you anything more * than a directory descriptor to point at the DTA's with. * * We set up a local dta array that we reference with descriptors. * To support HDIR_SYSTEM, we also keep a global dta which HDIR_SYSTEM * magically references. */ static struct dirstack { /* local dta array, referenced by handles */ struct find_t dta; short inuse; } *dirs; static int dircount=0; /* # dta's allocated at this moment */ #define MAX_OPEN_DIR 400 /* only allow 400 open hdirs at a whack */ #define USE_SYSTEM 0x7fff /* magic handle to reference global dta */ static struct find_t sysdta; /* ... global dta ... */ /* * Fill a filefindbuf structure with the information found by dos_find...() */ static _fillfindbuf(PUSHORT pcSearch, PFILEFINDBUF pffb, struct find_t *p) { *pcSearch = 1; /* we found a single item */ pffb->attrFile = p->attrib; pffb->cbFileAlloc = pffb->cbFile = p->size; strcpy(pffb->achName, p->name); memcpy(&pffb->fdateCreation, &p->wr_date, sizeof p->wr_date); memcpy(&pffb->ftimeCreation, &p->wr_time, sizeof p->wr_time); memcpy(&pffb->fdateLastWrite, &p->wr_date, sizeof p->wr_date); memcpy(&pffb->ftimeLastWrite, &p->wr_time, sizeof p->wr_time); memcpy(&pffb->fdateLastAccess, &p->wr_date, sizeof p->wr_date); memcpy(&pffb->ftimeLastAccess, &p->wr_time, sizeof p->wr_time); } /* _fillfindbuf */ /* * DosFindFirst() sets up a dta and tries to do a find against it */ USHORT APIENTRY DosFindFirst(PSZ pszFSpec, PHDIR phdir, USHORT usAttr, PFILEFINDBUF pffb, USHORT cbBuf, PUSHORT pcSearch, ULONG ulReserved) { struct find_t *p; register st; if (cbBuf != sizeof *pffb) /* have to use the correct size */ return 87/*invalid parameter*/; if (*phdir == HDIR_CREATE) { /* do we need to build a hdir? */ register i; for (i=0; i MAX_OPEN_DIR) return 4/*too many open files*/; if (new = malloc((1+dircount)* sizeof new[0])) { /* we're doing an explicit malloc/memcpy/free so we don't * have to specialcase the first allocation on a realloc() */ if (dircount > 0) { memcpy(new, dirs, dircount * sizeof new[0]); free(dirs); } dirs = new; dirs[dircount].inuse = 1; p = &dirs[*phdir = dircount].dta; dircount++; } else return 8/*not enough memory*/; } else if (*phdir == HDIR_SYSTEM) { /* use our scratch dta */ *phdir = USE_SYSTEM; p = &sysdta; } else return 87/*invalid parameter*/; } /* finally, look up the dratted thing */ if (_dos_findfirst(pszFSpec, usAttr, p) == 0) { _fillfindbuf(pcSearch, pffb, p); return 0; } return 2/*file not found*/; } /* fsFindfirst */ /* * DosFindNext() gives you another, like you asked for */ USHORT APIENTRY DosFindNext(HDIR hdir, PFILEFINDBUF pffb, USHORT cbBuf, PUSHORT pcSearch) { struct find_t *p; if (cbBuf != sizeof *pffb) return 87/*invalid parameter*/; if (hdir == USE_SYSTEM) p = &sysdta; else if (hdir >= 0 && hdir < dircount && dirs[hdir].inuse) p = &dirs[hdir].dta; else return 87/*invalid parameter*/; if (_dos_findnext(p) == 0) { _fillfindbuf(pcSearch, pffb, p); return 0; } return 2/*file not found*/; } /* fsFindnext */ /* * free a hdir so we can reuse it sometime in the distant * future */ USHORT APIENTRY DosFindClose(HDIR hdir) { if (hdir >= 0 && hdir < dircount && dirs[hdir].inuse) { dirs[hdir].inuse = 0; return 0; } return 87/*invalid parameter*/; } /* fsFindend */