int far pascal __loadds FS_FINDFIRST(struct cdfsi far * pcdfsi, /* pcdfsi */ struct cdfsd far * pcdfsd, /* pcdfsd */ char far * pName, /* pName */ unsigned short usCurDirEnd, /* iCurDirEnd */ unsigned short usAttr, /* attr */ struct fsfsi far * pfsfsi, /* pfsfsi */ struct fsfsd far * pfsfsd, /* pfsfsd */ char far * pData, /* pData */ unsigned short cbData, /* cbData */ unsigned short far * pcMatch, /* pcMatch */ unsigned short usLevel, /* level */ unsigned short usFlags) /* flags */ { PVOLINFO pVolInfo; PFINDINFO pFindInfo = (PFINDINFO)pfsfsd; USHORT rc; USHORT usIndex; USHORT usNeededLen; USHORT usNumClusters; ULONG ulCluster; ULONG ulDirCluster; PSZ pSearch; PFINFO pNext; ULONG ulNeededSpace; USHORT usEntriesWanted; EAOP EAOP; PROCINFO ProcInfo; if (f32Parms.fMessageActive & LOG_FS) Message("FS_FINDFIRST for %s attr %X, Level %d, cbData %u, MaxEntries %u", pName, usAttr, usLevel, cbData, *pcMatch); usEntriesWanted = *pcMatch; *pcMatch = 0; if (strlen(pName) > FAT32MAXPATH) { rc = ERROR_FILENAME_EXCED_RANGE; goto FS_FINDFIRSTEXIT; } memset(pfsfsd, 0, sizeof (struct fsfsd)); pVolInfo = GetVolInfo(pfsfsi->fsi_hVPB); if (IsDriveLocked(pVolInfo)) { rc = ERROR_DRIVE_LOCKED; goto FS_FINDFIRSTEXIT; } switch (usLevel) { case FIL_STANDARD : usNeededLen = sizeof (FILEFNDBUF) - CCHMAXPATHCOMP; break; case FIL_QUERYEASIZE : usNeededLen = sizeof (FILEFNDBUF2) - CCHMAXPATHCOMP; break; case FIL_QUERYEASFROMLIST : usNeededLen = sizeof (EAOP) + sizeof (FILEFNDBUF3) + sizeof (ULONG); break; default : rc = ERROR_NOT_SUPPORTED; goto FS_FINDFIRSTEXIT; } if (usFlags == FF_GETPOS) usNeededLen += sizeof (ULONG); if (cbData < usNeededLen) { rc = ERROR_BUFFER_OVERFLOW; goto FS_FINDFIRSTEXIT; } rc = MY_PROBEBUF(PB_OPWRITE, pData, cbData); if (rc) { Message("FAT32: Protection VIOLATION in FS_FINDFIRST! (SYS%d)", rc); return rc; } if (usLevel == FIL_QUERYEASFROMLIST) { memcpy(&EAOP, pData, sizeof (EAOP)); rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)EAOP.fpGEAList, (USHORT)EAOP.fpGEAList->cbList); if (rc) goto FS_FINDFIRSTEXIT; } memset(pData, 0, cbData); usNumClusters = 0; ulDirCluster = FindDirCluster(pVolInfo, pcdfsi, pcdfsd, pName, usCurDirEnd, RETURN_PARENT_DIR, &pSearch); if (ulDirCluster == FAT_EOF) { rc = ERROR_PATH_NOT_FOUND; goto FS_FINDFIRSTEXIT; } ulCluster = ulDirCluster; while (ulCluster && ulCluster != FAT_EOF) { usNumClusters++; ulCluster = GetNextCluster( pVolInfo, ulCluster); } ulNeededSpace = sizeof (FINFO) + (usNumClusters - 1) * sizeof (ULONG); ulNeededSpace += pVolInfo->usClusterSize; GetProcInfo(&ProcInfo, sizeof ProcInfo); pFindInfo->pInfo = (PFINFO)malloc((size_t)ulNeededSpace); if (!pFindInfo->pInfo) { rc = ERROR_NOT_ENOUGH_MEMORY; goto FS_FINDFIRSTEXIT; } memset(pFindInfo->pInfo, 0, (size_t)ulNeededSpace); if (!pVolInfo->pFindInfo) pVolInfo->pFindInfo = pFindInfo->pInfo; else { pNext = (PFINFO)pVolInfo->pFindInfo; while (pNext->pNextEntry) pNext = (PFINFO)pNext->pNextEntry; pNext->pNextEntry = pFindInfo->pInfo; } memcpy(&pFindInfo->pInfo->EAOP, &EAOP, sizeof (EAOP)); pFindInfo->usEntriesPerCluster = pVolInfo->usClusterSize / sizeof (DIRENTRY); pFindInfo->usClusterIndex = 0; pFindInfo->pInfo->rgClusters[0] = ulDirCluster; pFindInfo->usTotalClusters = usNumClusters; pFindInfo->pInfo->pDirEntries = (PDIRENTRY)(&pFindInfo->pInfo->rgClusters[usNumClusters]); if (f32Parms.fMessageActive & LOG_FIND) Message("pInfo at %lX, pDirEntries at %lX", pFindInfo->pInfo, pFindInfo->pInfo->pDirEntries); pFindInfo->pInfo->pNextEntry = NULL; memcpy(&pFindInfo->pInfo->ProcInfo, &ProcInfo, sizeof (PROCINFO)); strcpy(pFindInfo->pInfo->szSearch, pSearch); FSH_UPPERCASE(pFindInfo->pInfo->szSearch, sizeof pFindInfo->pInfo->szSearch, pFindInfo->pInfo->szSearch); pFindInfo->ulMaxEntry = ((ULONG)pVolInfo->usClusterSize / sizeof (DIRENTRY)) * usNumClusters; if (!GetCluster(pVolInfo, pFindInfo, 0)) { rc = ERROR_SYS_INTERNAL; goto FS_FINDFIRSTEXIT; } pFindInfo->ulCurEntry = 0; if (usAttr & 0x0040) { pFindInfo->fLongNames = TRUE; usAttr &= ~0x0040; } else pFindInfo->fLongNames = FALSE; pFindInfo->bMustAttr = (BYTE)(usAttr >> 8); usAttr |= (FILE_READONLY | FILE_ARCHIVED); usAttr &= (FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED); pFindInfo->bAttr = (BYTE)~usAttr; if (usLevel == FIL_QUERYEASFROMLIST) { memcpy(pData, &pFindInfo->pInfo->EAOP, sizeof (EAOP)); pData += sizeof (EAOP); cbData -= sizeof (EAOP); } rc = 0; for (usIndex = 0; usIndex < usEntriesWanted; usIndex++) { PULONG pulOrdinal; if (usFlags == FF_GETPOS) { if (cbData < sizeof (ULONG)) { rc = ERROR_BUFFER_OVERFLOW; break; } pulOrdinal = (PULONG)pData; pData += sizeof (ULONG); cbData -= sizeof (ULONG); } rc = FillDirEntry(pVolInfo, &pData, &cbData, pFindInfo, usLevel); if (!rc || (rc == ERROR_EAS_DIDNT_FIT && usIndex == 0)) { if (usFlags == FF_GETPOS) *pulOrdinal = pFindInfo->ulCurEntry - 1; } if (rc) break; } if ((rc == ERROR_NO_MORE_FILES || rc == ERROR_BUFFER_OVERFLOW || rc == ERROR_EAS_DIDNT_FIT) && usIndex > 0) rc = 0; if (rc == ERROR_EAS_DIDNT_FIT && usIndex == 0) usIndex = 1; *pcMatch = usIndex; FS_FINDFIRSTEXIT: if (f32Parms.fMessageActive & LOG_FS) Message("FS_FINDFIRST returned %d (%d entries)", rc, *pcMatch); if (rc && rc != ERROR_EAS_DIDNT_FIT) { FS_FINDCLOSE(pfsfsi, pfsfsd); } return rc; }
int myfindnext( struct super_block *p_volume, struct file *p_file, unsigned short attr, struct fsfsi32 *pfsfsi, struct fsfsd32 *pfsfsd, char *pData, unsigned short cbData, unsigned short *pcMatch, unsigned short level, unsigned short flags, UINT32 index_dir, int is_findfirst, int caseRetensive ) { char *left; char *right; UINT32 cur_size; int rc; char *pName; UINT32 len; struct inode *ino; UINT16 nb_found; struct dirent Dir; int fn_flag; pName = ((p_hfind) pfsfsd)->pName; nb_found = 0; if (level == FIL_QUERYEASFROMLIST) { cur_size = sizeof(EAOP); } else { cur_size = 0; } while (nb_found < *pcMatch) { /***********************************************************/ /*** If we are at the end of the parent dir : stop ***/ /***********************************************************/ if (VFS_readdir(p_file, __StackToFlat(&Dir)) != NO_ERROR) { ((p_hfind) pfsfsd)->last = index_dir; *pcMatch = nb_found; if (nb_found > 0) { #ifdef FS_TRACE kernel_printf("myfindnext() - EOD - found %d entries", nb_found); #endif return NO_ERROR; } else { #if 1 if (is_findfirst) { /************************************************************************/ /*** Lib‚ration du buffer stockant les noms de recherche ***/ /************************************************************************/ if ((rc = DevHlp32_VMFree(((p_hfind) pfsfsd)->pName)) != NO_ERROR) { fs_err(FUNC_FS_FINDFIRST, FUNC_G_free, rc, THISFILE, __LINE__); return rc; } /* end if */ /************************************************************************/ if ((rc = vfs_close(p_file)) != NO_ERROR) { fs_err(FUNC_FS_FINDFIRST, FUNC_CLOSE, rc, THISFILE, __LINE__); return rc; } // ((p_hfind)pfsfsd)->FS_CLOSEd = SEARCH_ALREADY_CLOSED; } #else FS_FINDCLOSE(pfsfsi, pfsfsd); ((p_hfind) pfsfsd)->FS_CLOSEd = SEARCH_ALREADY_CLOSED; #endif return ERROR_NO_MORE_FILES; } } /* end if */ /***********************************************************/ /***********************************************************/ /*** If we found an entry, see if it matches ***/ /***********************************************************/ if (caseRetensive) { fn_flag = _FNM_OS2 | _FNM_IGNORECASE; } else { fn_flag = _FNM_OS2; } if (fnmatch(pName, __StackToFlat(Dir.d_name), fn_flag) == 0) { if (p_file->f_inode->i_ino != Dir.d_ino) { if ((ino = iget(p_volume, Dir.d_ino)) == NULL) { fs_err(FUNC_FS_FINDFIRST, FUNC_GET_VINODE, rc, THISFILE, __LINE__); return ERROR_NO_MORE_FILES; } /* endif */ } else { ino = p_file->f_inode; } if (filter_with_attrs(ino, attr | FILE_READONLY, __StackToFlat(Dir.d_name))) { if ((rc = ino_to_fileinfo( ino, pData + cur_size, cbData - cur_size, __StackToFlat(&len), level, flags, attr, __StackToFlat(&Dir), index_dir, TYPEOP_FILEFIND)) != NO_ERROR) { *pcMatch = nb_found; ((p_hfind) pfsfsd)->last = index_dir; fs_log("====> FS_FINDFIRST : erreur ino_to_fileinfo()"); if (p_file->f_inode->i_ino != Dir.d_ino) { iput(ino); } return rc; } nb_found++; cur_size += len; } if (p_file->f_inode->i_ino != Dir.d_ino) { iput(ino); } } /* end if */ /***********************************************************/ index_dir++; } /* end while */ *pcMatch = nb_found; ((p_hfind) pfsfsd)->last = index_dir; #ifdef FS_TRACE kernel_printf("myfindnext() - found %d entries", nb_found); #endif return NO_ERROR; }