Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Работа с каталогами под DOS


Автор: Cybernetick 20.6.2011, 22:23
Доброго времени суток! Получил лабу- вывести список всех удалённых файлов из заданного каталога и подкаталогов. Посколько WinAPI ещё не изучал, да и предмет требует реализации под DOS, бьюсь со следующим кодом-
Код

#include<stdio.h>
#include<dir.h>
#include<process.h>
#include<dos.h>
int main(void)
 {
  struct ffblk ffb;
  int done;
  printf("local directory\n");
  done = findfirst("*.txt", &ffb, FA_RDONLY);
  while(!done)
   {
   if (ffb.ff_name[1] == 0xE5)
   {
    printf("%13s ", ffb.ff_name);        // File name
    if(ffb.ff_attrib & FA_DIREC) printf("    <DIR>");
     else printf("%9ld", ffb.ff_fsize); // File size
    printf("    %02u-%02u-%4u", ffb.ff_fdate & 0x1F ,
          (ffb.ff_fdate  >> 5) & 0xF,
      ((ffb.ff_fdate >> 9) & 0x7F) + 1980); // Date
    printf("    %02u:%02u\n", (ffb.ff_ftime >> 11) & 0x1F,
       (ffb.ff_ftime >> 5) & 0x3F);      // Time
    done = findnext(&ffb);
    }
    else
    {
    printf("IF SUCKS!");
    done = findnext(&ffb);
    }
   }
   system("pause");
  return 0;
 }



по теории я понял, что нужно ловить из первого байта поля ffb.ff_name код E5h, который и означает, что файл удалён. только проблема в том, что с написанным условием в тело IF'а программа не заходит. вот и прошу совета опытных в этой среде людей- что именно я делаю не так?)
Зараннее благодарен!

Автор: triclosan 20.6.2011, 22:31
имхо это преступление заставлять учить студентов программированию под DOS, где предполагается применять потом эти знания?

Автор: fish9370 20.6.2011, 22:38
Цитата(Cybernetick @  20.6.2011,  22:23 Найти цитируемый пост)
что нужно ловить из первого байта поля ffb.ff_name код E5h


так лови из первого:

Код

 if (ffb.ff_name[0] == 0xE5)

Автор: Cybernetick 20.6.2011, 22:44
Цитата(fish9370 @ 20.6.2011,  22:38)
Цитата(Cybernetick @  20.6.2011,  22:23 Найти цитируемый пост)
что нужно ловить из первого байта поля ffb.ff_name код E5h


так лови из первого:

Код

 if (ffb.ff_name[0] == 0xE5)




попробовал- по прежнему это условие игнорируется... проверял кстати следующим образом-  выводил список всех *.txt-шников в каталоге, потом удалял один из них и ставил это условие... результата никакого.

Автор: fish9370 20.6.2011, 22:50
у printf есть фича %x, сделай так

Код

while(!done) {
   printf("%x\r\n", ffb.ff_name[0]);
   if (ffb.ff_name[0] == 0xE5)

Автор: triclosan 20.6.2011, 22:52
Цитата(fish9370 @  20.6.2011,  22:50 Найти цитируемый пост)
printf("%x\r\n", ffb.ff_name[0]);

не надо

Автор: fish9370 20.6.2011, 22:54
Цитата(triclosan @  20.6.2011,  22:52 Найти цитируемый пост)
не надо


почему?

Автор: Cybernetick 20.6.2011, 22:59
я так понял что новый printf должен будет выдавать первый байт для всех txt-шников? я вставил его и получил только одно значение, значит что у меня проверлся только один файл? 

Автор: triclosan 20.6.2011, 23:02
fish9370, поскольку язык Си растет их Юникс-мира, в текстовом режиме принято конец строки обозначать юниксоидным символов \n - при этом в *nix системах он не меняется, а в этих ваших ДОСах превращается в \r\n

Автор: fish9370 20.6.2011, 23:03
IF SUCKS печатает?

Добавлено через 1 минуту и 30 секунд
Цитата(triclosan @  20.6.2011,  23:02 Найти цитируемый пост)
а в этих ваших ДОСах превращается в \r\n


никогда такого не слышал, где это написанно?

Автор: Cybernetick 20.6.2011, 23:16
предыдущая инфа была не совсем верной- вообщем прога адекватно ловит все файлы и выводит их коды, только после удаление ничего не происходит и просто вместо 6 кодов (по количеству файлов) выводит 5 и 5 раз сообщение IF SUCKS. попробовал уже даже в findfirst завести весь список известных аттрибутов- не помогло... может есть альтернатива этому методу поиска удалённого файла?

Автор: fish9370 20.6.2011, 23:22
Цитата(Cybernetick @  20.6.2011,  23:16 Найти цитируемый пост)
может есть альтернатива этому методу поиска удалённого файла?


да, есть.. только он тебе не понравится.. нужно считывать первый сектор диска (MBR), определять где находится системный раздел, находить таблицу распрределения файлов (FAT, кстати мы имеем дело с FAT32?), пробегаться по ее каталогу и делать тоже самое..


если у тебя есть ДОС, то найди проду diskedit.. с помощью нее можно шастать по диску, и дебажить..

все это у меня лишь воспаминания, десятилетней давности..

Автор: fish9370 21.6.2011, 00:07
ха-ха-ха..  smile 

порылся в исходниках findfirst и вот что я нашел:

Код

/* skip this entry if it is an deleted entry */   
if (*(pBuffer + j) == 0xe5 || *(pBuffer + j) == '.')   
         continue; 


- что не удивительно, это же пользовательская функция..

другими словами он не выдает удаленные файлы.. нужно искать другой метод.. либо тупо переписать функции поиска.. время у нас есть? 

Автор: xvr 21.6.2011, 11:31
Никакие стандартные функции поиска (включая и findfirst) не будут возвращать записи для удаленных файлов (и это сделано уже на уровне ОС, а не в run-time библиотеке)

Так что только напрямую потрошить диск (в DOS), или открывать директорию на чтение (CreateFile с FLAG_BACKUP_SEMANTIC - в Win) и читать. И то и другое требует недюжинных познаний во внутренних структурах файловой системы  smile 

Автор: Cybernetick 21.6.2011, 11:47
думаю топик можно закрывать,всем спасибо за помощь) буду насиловать FAT)

Автор: fish9370 21.6.2011, 12:10
Цитата(xvr @  21.6.2011,  11:31 Найти цитируемый пост)
требует недюжинных познаний во внутренних структурах файловой системы


нет, это требует всего лишь заюзать тот исходник, о котором я писал, и просто убрать эту проверку..  smile 

Автор: xvr 21.6.2011, 12:30
Цитата(fish9370 @  21.6.2011,  12:10 Найти цитируемый пост)
нет, это требует всего лишь заюзать тот исходник, о котором я писал, и просто убрать эту проверку.. 

Увы, не знаю, откуда там эта проверка (может от времен CP/M), но в современных ОС она никогда срабатывать не будет - уже сама ОС не вернет таких записей

Автор: fish9370 21.6.2011, 13:10
Цитата(xvr @  21.6.2011,  12:30 Найти цитируемый пост)
Увы, не знаю, откуда там эта проверка (может от времен CP/M), но в современных ОС она никогда срабатывать не будет - уже сама ОС не вернет таких записей



на самом деле понятие ОС, применительно к DOS - это сильно сказано.. что у нее общего с современной ОС? ни защиты памяти, ни понятия процесс, все программы работают в одном пространстве, все это работает в реальном режиме, обращения напрямую к железу не запрещены.. 
и все вытекающее..

что сможет сделать DOS, если я захочу что-то подправить в файловой системе? - НИ-ЧЕ-ГО..

Автор: xvr 21.6.2011, 19:41
Цитата(fish9370 @  21.6.2011,  13:10 Найти цитируемый пост)
на самом деле понятие ОС, применительно к DOS - это сильно сказано.. что у нее общего с современной ОС?

А какая разница? Удаленные файлы по findfirst (INT 21h, func 4Eh) она тоже не возвращает, каким бы обрезком ОСа она не была  smile 

Цитата(fish9370 @  21.6.2011,  12:10 Найти цитируемый пост)
нет, это требует всего лишь заюзать тот исходник, о котором я писал, и просто убрать эту проверку.. 

Насколько я понял это был совет убрать проверку на E5 из реализации findfirst в C библиотеке? Если так, то это не поможет  smile 

Автор: fish9370 21.6.2011, 20:17
Цитата(xvr @  21.6.2011,  19:41 Найти цитируемый пост)
А какая разница?


ну как тебе сказать, если поставить пропускной пункт посреди пустыни это будет по принципу DOS.. то что он не возвращает что-то через функцию 4Eh не значит, что нельзя написать свою функцию сбоку и сделать то что хочешь..


Цитата(xvr @  21.6.2011,  19:41 Найти цитируемый пост)
Насколько я понял это был совет убрать проверку на E5 из реализации findfirst в C библиотеке? Если так, то это не поможет


перекомпиливать DOS нет никакого желания.. зачем так радикально? просто взять функцию findfirst/findnext, кое-что подправить и спокойно использовать в своей программе.. DOS даже не пикнет..

Автор: xvr 21.6.2011, 22:41
Цитата(fish9370 @  21.6.2011,  20:17 Найти цитируемый пост)
просто взять функцию findfirst/findnext, кое-что подправить

Функции findfirst/findnext из библиотеки С (для DOS) используют функцию 4E прерывания 21 для получения исходных данных. Что в них надо подправить, что бы они начали выдавать то, что к ним не приходит на вход? Или вы предлагаете найти реализацию 4E в int 21 в DOS'е и подправить ее прямо в голых хекс кодах?

Автор: fish9370 22.6.2011, 07:56
Цитата(xvr @  21.6.2011,  22:41 Найти цитируемый пост)
Что в них надо подправить, что бы они начали выдавать то, что к ним не приходит на вход?


xvr,  ты исходники findfirst видел? - после твоего вопроса я вижу, что ты даже представления не имеешь..

ничего никуда не приходит.. эта функция лезет на диск выгребает сама данные и с помощью этой проверки 

Код

/* skip this entry if it an deleted entry or "." or ".." */   
if (*(pBuffer + j) == 0xe5 || *(pBuffer + j) == '.')   
                continue;



отсеивает лишнее

а по-твоему, если к ней "не приходит" список удаленных файлов, зачем она делает эту проверку?  smile 

Автор: xvr 22.6.2011, 09:55
Цитата(fish9370 @  22.6.2011,  07:56 Найти цитируемый пост)
xvr,  ты исходники findfirst видел?

Видел. Вот findfirst от Borland C++ 3.1:
Код

int _CType _FARFUNC findfirst(const char *pathname, struct ffblk *ffblk, int attrib)
{
asm     push    ds

asm     mov     ah,2fh          /* get (and save) DTA */
asm     int     21h
asm     push    es
asm     push    bx

asm     mov     ah, 01Ah
asm     LDS_    dx, ffblk
asm     int     021h            /* Set the disk transfer address */

asm     mov     ah, 04Eh
asm     mov     cx, attrib
asm     LDS_    dx, pathname
asm     int     021h            /* Find first matching file */

asm     pushf                   /* save state of carry flag */
asm     pop     cx
asm     xchg    ax, bx          /* save return code */

asm     mov     ah, 01Ah        /* restore DTA */
asm     pop     dx
asm     pop     ds
asm     int     21h

asm     push    cx
asm     popf
asm     pop     ds

asm     jc      findfirstFailed
        return(0);

findfirstFailed:
        return __IOerror(_BX);
}

Цитата(fish9370 @  22.6.2011,  07:56 Найти цитируемый пост)
ничего никуда не приходит.. эта функция лезет на диск

Да ну? И в каком месте она это делает?  smile 

Вашу findfirst на бочку (и ссылку, откуда такое чудо, с прямым обращением к диску,  взято)

Автор: fish9370 22.6.2011, 10:15
Код

int FAT_findfirst_r(unsigned char *target, struct ffblk *ffres, int attrib)   
{   
  unsigned char *wildName;  /* the wildcard filename part */   
  int i, j;   
  int index = 0;        /* points to the '\\' between the above two parts */   
  int status;   
  unsigned short blkSize;   /* the size of a block (sector in root, cluster in sub-dir) */   
  unsigned short *blkBuffer;    /* a buffer for root sectors */   
  unsigned char *pBuffer;   /* a pointer for reading sector/cluster from disk */   
  struct FAT_FILE *pfile;   /* a temp file handle for sub-dir searching */   
  int availHandler;     /* an available handle for sub-dir searching */   
  unsigned short cluster;   /* the target sub-dir cluster for wildcard name search */   
  unsigned short prevCluster;   /* the previous cluster during wildcard compare */   
  struct FAT_directory pEntry;  /* the dir entry with name matched the wildcard name */   
  unsigned char entryAttr;  /* the attribute of the dir entry */   
  unsigned char *path;      /* the path without drive name */   
  short drive;          /* the target drive */   
  unsigned char *fileName;  /* name part of the sub-dir part */   
  struct FAT_FFInternal *ffInfo;    /* internal information for FAT_findnext */   
#ifdef FAT_LFN   
  struct FAT_LFNinfo longInfo;   
#endif   
   
#ifdef FAT1X_DEBUG   
  SprintStringLn("[FAT_findfirst_r]");   
#endif   
   
  path = FAT_get_drive(target, &drive);   
   
  if (drive == -1)   
  {   
    ffres->ff_reserved = 0;   
    FATErrno = ERROR_INVALID_DRIVE;   
    return -1;   
  }   
   
  /* separate the pathname into sub-dir part and filename part */   
  /* e.g., "\\test1\\test2\\temp\\*.txt"   =>                  */   
  /*       subDirName = "\\test1\\test2\\temp"                 */   
  /*       fileName   = "*.txt"                                */   
  while (path[index] != '\0')   
    index++;   
  while (index > 0 && path[index] != '\\')   
    index--;   
  /* index should now point at the '\\' between the two parts */   
   
  wildName = path + index;   
  if (*wildName == '\\')   
    wildName++;   
   
#ifdef FAT_LFN   
  if ((fileName = (unsigned char *)ap_malloc(FAT_MAX_LFN_LENGTH * 2)) == NULL)   
  {   
    ffres->ff_reserved = 0;   
    FATErrno = ERROR_ALLOC_MEM;   
    return -1;   
  }   
  myMemSet(fileName, 0, FAT_MAX_LFN_LENGTH * 2);   
#else   
  if ((fileName = (unsigned char *)ap_malloc(13)) == NULL)   
  {   
    ffres->ff_reserved = 0;   
    FATErrno = ERROR_ALLOC_MEM;   
    return -1;   
  }   
  myMemSet(fileName, 0, 13);   
#endif   
   
  /* starting comparing attributes and filenames */   
  if (index == 0)   /* find first in the root directory */   
  {   
    /* start searching for the filename in the root directory */   
    /* no need to search for the sub-dir part */   
    blkSize = SECTOR_SIZE;  /* root dir is handled sector by sector */   
    if ((blkBuffer = (unsigned short *)ap_malloc(blkSize)) == NULL)   
    {   
        ap_free(fileName);   
        ffres->ff_reserved = 0;   
        FATErrno = ERROR_ALLOC_MEM;   
        return -1;   
    }   
   
    /* check all root sectors */   
    i = -1;   
    for (;;)   
    {   
        i++;   
        /* if all root sectors have been searched, then no match file is found */   
        if (i == FATSecPerROOT[drive])   
        {   
            ffres->ff_reserved = 0;   
            ap_free(blkBuffer);   
            ap_free(fileName);   
            FATErrno = ERROR_FILE_NOT_EXIST;   
            return -1;   
        }              
        /* read the current root sector */   
        FAT_read_root_sector(drive, FATRootBegin[drive] + i, blkBuffer);   
        pBuffer = (unsigned char *)blkBuffer;   
   
        /* compare entry by entry in the sector */   
        for (j = 0; j  blkSize; j += FAT_DIR_ENTRY_SIZE)   
        {   
            /* this entry and every following entry are empty => not found */   
            if (*(pBuffer + j) == '\0')   
            {   
                ffres->ff_reserved = 0;   
                ap_free(blkBuffer);   
                ap_free(fileName);   
                FATErrno = ERROR_FILE_NOT_EXIST;   
                return -1;   
            }   
   
            /* skip this entry if it is an deleted entry */   
            if (*(pBuffer + j) == 0xe5 || *(pBuffer + j) == '.')   
                continue;   
   
            /* compare the attribute of this entry with the given attribute */   
            entryAttr = *(pBuffer + j + 11);   
   
            // skip long directory entry   
            if ((entryAttr & DA_VFAT) == DA_VFAT)   
                continue;   
   
            /* DA_READONLY and DA_ARCHIVE files can always be seen */   
            /* DA_HIDDEN, DA_SYSTEM, DA_VOLUME, and DA_DIR are not */   
            attrib = attrib | DA_READONLY;   
            attrib = attrib | DA_ARCHIVE;   
   
            /* go to next entry if the attributes unmatch */   
            if ((entryAttr & attrib) != entryAttr)   
                continue;   
   
            /* marked by chilong 03/07/2002  
            // only DIR are shown if DA_DIR is specified by user  
            if ((attrib & DA_DIR) == DA_DIR)  
                if ((entryAttr & DA_DIR) != DA_DIR)  
                    continue;  
               marked by chilong 03/07/2002 */   
               
            /**** modified by MSC 03/07/2002 ****/   
            if ((attrib & FF_DA_DIR_OR) == 0)   
            {   
                // only DIR are shown if DA_DIR is specified by user   
                if ((attrib & DA_DIR) == DA_DIR)   
                    if ((entryAttr & DA_DIR) != DA_DIR)   
                        continue;   
            }   
            /**** modified by MSC 03/07/2002 ****/   
   
            /* attributes match, compare filename with the wildcard name */   
#ifdef FAT_LFN   
            longInfo.startBlock = FATRootBegin[drive] + i;   
            longInfo.startEntry = j;   
            if (i == 0)   
                longInfo.endBlock = 0;   
            else   
                longInfo.endBlock = FATRootBegin[drive] + i - 1;   
            longInfo.endEntry = 0;   
            status = FAT_getLongName(drive, 1, &longInfo, pBuffer + j, fileName);   
            if (status == 1)   
            {   
                if (nameCompare(wildName, fileName, 1) == 1)   
                    status = 1; // the long name (unicode) matches   
                else   
                    status = -1;    // not match   
            }   
            if (status = 0)   
            {   
                getShortName(pBuffer + j, fileName);   
                if (nameCompare(wildName, fileName, 0) == 1)   
                    status = 0; // the short name matches   
                else   
                    status = -1;   
            }      
#else   
            getShortName(pBuffer + j, fileName);   
            if (nameCompare(wildName, fileName, 0) == 1)   
                status = 0;     // the short name matches   
            else   
                status = -1;   
#endif   
   
            if (status != -1)   /* found! */   
            {   
                // allocate the internal findfile structure, used by FAT_findnext()   
                // this structure is deallocated by FAT_findclose()   
                if ((ffInfo = (struct FAT_FFInternal *)ap_malloc(sizeof(struct FAT_FFInternal))) == NULL)   
                {   
                    ffres->ff_reserved = 0;   
                    FATErrno = ERROR_ALLOC_MEM;   
                    ap_free(blkBuffer);   
                    ap_free(fileName);   
                    return -1;   
                }   
                myMemSet(ffInfo, 0, sizeof(struct FAT_FFInternal));   
   
                /* fill in the FAT_FFInternal structure */   
                ffInfo->drive = drive;   
                ffInfo->attrib = attrib;   
                /* the entry number, counting from the 1st root sector */   
                ffInfo->nThEntry = (i * SECTOR_SIZE + j) / FAT_DIR_ENTRY_SIZE;   
                /* the cluster number of the directory, 0 for root */   
                ffInfo->cluster = 0;   
                /* the wildcard name */   
                copyName(wildName, ffInfo->wildname, 0);   
   
                ffres->ff_reserved = (long)ffInfo;   
                /* copy field from dir entry to result */   
//              pEntry = (struct FAT_directory *)(pBuffer + j);   
                FAT_load_dir_info(pBuffer + j, &pEntry);   
                ffres->ff_attrib = pEntry.attribute;   
                ffres->ff_ftime = pEntry.time;   
                ffres->ff_fdate = pEntry.date;   
                ffres->ff_fsize = pEntry.fsize;   
                ffres->ff_drive = FAT_ID;   
                /* copy the name from dir entry to result */   
                // note that if status = 1, the name is in unicode   
                //   otherwise the name is in big5 & ascii   
                if (status == 1)   
                    copyName(fileName, ffres->ff_name, 1);   
                else   
                    copyName(fileName, ffres->ff_name, 0);   
   
                ap_free(blkBuffer);   
                ap_free(fileName);   
                return 0;   
            } /* if loop status */   
            /* not found, try next entry */   
        } /* for loop j */   
        /* not found in this sector, try next sector */   
    } /* for loop infinite */   
  } /* if loop index */   
  else          /* find first in the sub-directory */   
  {   
    /* find the dir entry of the pathname before the wildcard */   
   
    /* create a file handle for FAT_f_search */   
    if ((pfile = (struct FAT_FILE *)ap_malloc(sizeof(struct FAT_FILE))) == NULL)   
    {   
        ffres->ff_reserved = 0;   
        FATErrno = ERROR_ALLOC_MEM;   
        ap_free(fileName);   
        return -1;   
    }   
    myMemSet(pfile, 0, sizeof(struct FAT_FILE));   
   
//  availHandler = FAT_find_free_ftable_entry();   
    availHandler = findFreeHandle();   
    if (availHandler == -1)   
    {   
        ap_free(pfile);   
        ap_free(fileName);   
        ffres->ff_reserved = 0;   
        FATErrno = ERROR_NO_HANDLE_AVAIL;   
        return -1;   
    }   
    pfile->fhandle = availHandler;   
    FATHandleTable[availHandler] = pfile;   
   
    /* start searching */   
    // prepare the pathname where the searching will be done   
    // we want to search only the pathname before the wildcard name   
    //   the last '\\' is temporary replaced by a '\0'   
    //   for example:   
    //  target = "c:\dir1\dir2\dir3\*.txt"   
    //  path = "\dir1\dir2\dir3\*.txt"   
    //  wildName = "*.txt"   
    //  last '\\' to '\0' ==>    path = "\dir1\dir2\dir3"   
    //              target = "c:\dir1\dir2\dir3"   
    //              wildName = "*.txt"   
    //   just remember to put '\\' back when the searching is done or error   
    path[index] = '\0';   
   
//  status = FAT_f_search(pfile, target);   
   
#ifdef FAT_LFN   
    status = FAT_f_search(pfile, target, &longInfo, 0);   
#else   
    status = FAT_f_search(pfile, target, 0);   
#endif   
   
    // reset the last '\\'   
    path[index] = '\\';   
   
    if (status == -1 || (pfile->dirEntry.attribute & DA_DIR) != DA_DIR)   
    {   
        ap_free(pfile);   
        ap_free(fileName);   
        FATHandleTable[availHandler] = NULL;   
        ffres->ff_reserved = 0;   
        FATErrno = ERROR_DIR_NOT_EXIST;   
        return -1;   
    }   
   
    /* the sub-dir is found, start searching for the filename from the 1st entry */   
    blkSize = FATBytesPerCluster[drive];    /* sub-dir is handled cluster by cluster */   
    if ((blkBuffer = (unsigned short *)ap_malloc(blkSize)) == NULL)   
    {   
        ap_free(pfile);   
        ap_free(fileName);   
        FATHandleTable[availHandler] = NULL;   
        ffres->ff_reserved = 0;   
        FATErrno = ERROR_ALLOC_MEM;   
        return -1;   
    }   
   
    /* read the starting cluster of the sub-dir */   
    cluster = pfile->dirEntry.startCluster;   
    prevCluster = 0;   
   
    while (cluster  FATEndOfChain[FATType[drive]])   
    {   
        FAT_read_cluster(drive, cluster, blkBuffer);   
        pBuffer = (unsigned char *)blkBuffer;   
   
        /* compare entry by entry in the sector */   
        for (j = 0; j  blkSize; j += FAT_DIR_ENTRY_SIZE)   
        {   
            /* this entry and every following entry are empty => not found */   
            if (*(pBuffer + j) == '\0')   
            {   
                ap_free(blkBuffer);   
                ap_free(pfile);   
                ap_free(fileName);   
                FATHandleTable[availHandler] = NULL;   
                ffres->ff_reserved = 0;   
                FATErrno = ERROR_FILE_NOT_EXIST;   
                return -1;   
            }   
   
            /* skip this entry if it an deleted entry or "." or ".." */   
            if (*(pBuffer + j) == 0xe5 || *(pBuffer + j) == '.')   
                continue;   
   
            entryAttr = *(pBuffer + j + 11);   
   
            // skip long directory entry   
            if ((entryAttr & DA_VFAT) == DA_VFAT)   
                continue;   
   
            /* compare the attribute of this entry with the given attribute */   
            /* DA_READONLY and DA_ARCHIVE files can always be seen */   
            /* DA_HIDDEN, DA_SYSTEM, DA_VOLUME, and DA_DIR are not */   
            attrib = attrib | DA_READONLY;   
            attrib = attrib | DA_ARCHIVE;   
            /* go to next entry if the attributes unmatch */   
            if ((entryAttr & attrib) != entryAttr)   
                continue;   
            // only DIR are shown if DA_DIR is specified by user   
            if ((attrib & DA_DIR) == DA_DIR)   
                if ((entryAttr & DA_DIR) != DA_DIR)   
                    continue;   
   
            /* attributes match, compare filename with the wildcard name */   
#ifdef FAT_LFN   
            longInfo.startBlock = cluster;   
            longInfo.startEntry = j;   
            longInfo.endBlock = prevCluster;   
            longInfo.endEntry = 0;   
            status = FAT_getLongName(drive, 0, &longInfo, pBuffer + j, fileName);   
            if (status == 1)   
            {   
                if (nameCompare(wildName, fileName, 1) == 1)   
                    status = 1; // the long name (unicode) matches   
                else   
                    status = -1;    // not match   
            }   
            if (status = 0)   
            {   
                getShortName(pBuffer + j, fileName);   
                if (nameCompare(wildName, fileName, 0) == 1)   
                    status = 0; // the short name matches   
                else   
                    status = -1;   
            }      
#else   
            getShortName(pBuffer + j, fileName);   
            if (nameCompare(wildName, fileName, 0) == 1)   
                status = 0;     // the short name matches   
            else   
                status = -1;   
#endif   
   
            if (status != -1)   /* found! */   
            {   
                // allocate the internal findfile structure, used by FAT_findnext()   
                // this structure is deallocated by FAT_findclose()   
                if ((ffInfo = (struct FAT_FFInternal *)ap_malloc(sizeof(struct FAT_FFInternal))) == NULL)   
                {   
                    ap_free(blkBuffer);   
                    ap_free(pfile);   
                    ap_free(fileName);   
                    FATHandleTable[availHandler] = NULL;   
                    ffres->ff_reserved = 0;   
                    FATErrno = ERROR_ALLOC_MEM;   
                    return -1;   
                }   
                myMemSet(ffInfo, 0, sizeof(struct FAT_FFInternal));   
   
                /* fill in the FAT_FFInternal structure */   
                ffInfo->drive = drive;   
                ffInfo->attrib = attrib;   
                /* the entry number, counting from the 1st root sector */   
                ffInfo->nThEntry = j / FAT_DIR_ENTRY_SIZE;   
                /* the cluster number of the directory, 0 for root */   
                ffInfo->cluster = cluster;   
                /* the wildcard name */   
                copyName(wildName, ffInfo->wildname, 0);   
   
                // fill in the ffblk structure   
                ffres->ff_reserved = (long)ffInfo;   
//              pEntry = (struct FAT_directory *)(pBuffer + j);   
                FAT_load_dir_info(pBuffer + j, &pEntry);   
                ffres->ff_attrib = pEntry.attribute;   
                ffres->ff_ftime = pEntry.time;   
                ffres->ff_fdate = pEntry.date;   
                ffres->ff_fsize = pEntry.fsize;   
                ffres->ff_drive = FAT_ID;   
                /* copy the name from dir entry to result */   
                // note that if status = 1, the name is in unicode   
                //   otherwise the name is in big5 & ascii   
                if (status == 1)   
                    copyName(fileName, ffres->ff_name, 1);   
                else   
                    copyName(fileName, ffres->ff_name, 0);   
   
                ap_free(blkBuffer);   
                ap_free(pfile);   
                ap_free(fileName);   
                FATHandleTable[availHandler] = NULL;   
                return 0;   
            } /* if loop status */   
            /* not found, try next entry */   
        } /* for loop j */   
   
        /* not found in this cluster, try next cluster in the chain */   
        prevCluster = cluster;   
        cluster = FAT_read_fat_cluster(drive, cluster);   
    }   
    /* all clusters in the chain have been searched, file not found */   
    ap_free(blkBuffer);   
    ap_free(pfile);   
    ap_free(fileName);   
    FATHandleTable[availHandler] = NULL;   
    ffres->ff_reserved = 0;   
    FATErrno = ERROR_FILE_NOT_EXIST;   
    return -1;   
  }   
}   
   
   
   


Добавлено через 1 минуту и 36 секунд
и только не надо говорить, что функция мол не та, не родная или еще что-то в этом духе..

Автор: xvr 22.6.2011, 14:16
Цитата(fish9370 @  22.6.2011,  10:15 Найти цитируемый пост)
и только не надо говорить, что функция мол не та, не родная или еще что-то в этом духе.. 

Не буду. Эта функция вообще не имеет ничего общего с реализацией findfirst из стандартной С библиотеки для обычного С компилятора.
Очень похожа на кусок реализации FAT для глубокого embedded мира  smile 

Автор: fish9370 22.6.2011, 14:42
Цитата(xvr @  22.6.2011,  14:16 Найти цитируемый пост)
Эта функция вообще не имеет ничего общего с реализацией findfirst из стандартной С библиотеки


т.е. эту функцию использовать религия не позволяет?

Автор: xvr 22.6.2011, 22:12
Цитата(fish9370 @  22.6.2011,  14:42 Найти цитируемый пост)
т.е. эту функцию использовать религия не позволяет? 

Позволяет. Собственно это ТС и собрался делать -
Цитата(Cybernetick @  21.6.2011,  11:47 Найти цитируемый пост)
буду насиловать FAT

Вот только не надо эту функцию называть 'стандартной функцией findfirst' из стандартной С библиотеки.
Эта функция - часть реализации FS.

Собственно ваш совет -
Цитата(fish9370 @  20.6.2011,  23:22 Найти цитируемый пост)
нужно считывать первый сектор диска (MBR), определять где находится системный раздел, находить таблицу распрределения файлов (FAT, кстати мы имеем дело с FAT32?), пробегаться по ее каталогу и делать тоже самое..

был абсолютно правильным, а вот  это
Цитата(fish9370 @  21.6.2011,  00:07 Найти цитируемый пост)
порылся в исходниках findfirst и вот что я нашел:
...
- что не удивительно, это же пользовательская функция..
 и предложение
Цитата(fish9370 @  21.6.2011,  00:07 Найти цитируемый пост)
либо тупо переписать функции поиска.. 

приводят к мысли, что ваша функция findfirst (в том виде, как она была приведена выше) уже содержится в стандартной библиотеке С (для DOS'а), что в корне не верно. 

Функция findfirst, которая есть в CRT компилятора, совершенно другая, и переделать ее в версию без проверки на E5 не получится

Если переформулировать ваше предложение в 'взять низкоуровневую реализацию findfirst из какой нибудь OS-less реализации и оторвать в ней проверку на E5' - то с такой формулировкой я полностью согласен  smile 

Вот только в Win в его DOS box'е это работать не будет - Винда к диску не пустит


Автор: fish9370 23.6.2011, 09:22
Цитата(xvr @  22.6.2011,  22:12 Найти цитируемый пост)
Если переформулировать ваше предложение в 'взять низкоуровневую реализацию findfirst из какой нибудь OS-less реализации и оторвать в ней проверку на E5' - то с такой формулировкой я полностью согласен   


да, это то что я имел ввиду..


Цитата(xvr @  22.6.2011,  22:12 Найти цитируемый пост)
Вот только в Win в его DOS box'е это работать не будет - Винда к диску не пустит


это уже называется виртуальный режим (эмуляция DOS).. здесь действительно ОС перехватывает все запросы к железу..


наверно прекратим этот бесполезный спор..

Автор: xvr 23.6.2011, 10:22
Цитата(fish9370 @  23.6.2011,  09:22 Найти цитируемый пост)
да, это то что я имел ввиду..
наверно прекратим этот бесполезный спор.. 

Угу, консенсус  smile 


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)