home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / ramfs102.zip / src / find.c < prev    next >
C/C++ Source or Header  |  2002-10-21  |  6KB  |  234 lines

  1. #include "includes.h"
  2.  
  3.  
  4.  
  5. /* all info levels start with these fields */
  6. struct common1
  7. {
  8.   ULONG  datiCreate;
  9.   ULONG  datiAccess;
  10.   ULONG  datiWrite;
  11.   ULONG  cbFile;
  12.   ULONG  cbFileAlloc;
  13.   USHORT fDOSattr;
  14. };
  15.  
  16.  
  17. /* all info levels end with these fields */
  18. struct common2
  19. {
  20.   UCHAR  cbName;
  21.   UCHAR     szName[1];
  22. };
  23.  
  24.  
  25. /* in FIL_QUERYEASIZE, these fields are between common1 and common2 */
  26. struct easize
  27. {
  28.   ULONG cbList;
  29. };
  30.  
  31.  
  32.  
  33.  
  34. int FindStoreEntry (
  35.     PCHAR   _ss *ppData,
  36.     USHORT  _ss *pcbData,
  37.     int          level,
  38.     int          flag,
  39.     USHORT       usAttrPattern,
  40.     PEAOP        pEAOP,
  41.     PDIRENTRY    pEntry )
  42. {
  43.   struct common1 *pCommon1;
  44.   struct common2 *pCommon2;
  45.   struct easize  *pEasize;
  46.   PFEALIST pFEAList;
  47.   int      cbRequired;
  48.   int      rc;
  49.  
  50.   /* reserve space for all information except level-specific stuff - this
  51.      is a preliminary buffer size check */
  52.   if (flag == 0)
  53.   {
  54.     /* we shouldn't store ulPosition in front of returned data */
  55.     cbRequired = sizeof(struct common1) +
  56.          sizeof(struct common2) + pEntry->cbName;
  57.  
  58.     if (*pcbData < cbRequired)
  59.       return ERROR_BUFFER_OVERFLOW;
  60.     *pcbData -= cbRequired;
  61.   }
  62.   else
  63.   {
  64.     /* we should store ulPosition in front of returned data */
  65.     cbRequired = sizeof(ULONG) +
  66.          sizeof(struct common1) +
  67.          sizeof(struct common2) + pEntry->cbName;
  68.     if (*pcbData < cbRequired)
  69.       return ERROR_BUFFER_OVERFLOW;
  70.     *pcbData -= cbRequired;
  71.  
  72.     /* we don't actually store ulPosition since we won't use it later anyway */
  73.     *ppData += sizeof(ULONG);
  74.   }
  75.  
  76.   /* store common file info */
  77.   pCommon1 = (struct common1 *) *ppData;
  78.   pCommon1->datiCreate  = pEntry->datiCreate;
  79.   pCommon1->datiAccess  = pEntry->datiAccess;
  80.   pCommon1->datiWrite   = pEntry->datiWrite;
  81.   pCommon1->cbFile      = pEntry->fblkFile.fSize;
  82.   /* BUGBUG: this isn't true anymore because the clusters != 4K and for large
  83.      clusters, it's questionable whether the whole memory has been committed
  84.      */
  85.   pCommon1->cbFileAlloc = ROUNDUP (pEntry->fblkFile.fSize);
  86.   if (pEntry->fDOSattr & DOSATTR_DIRECTORY)
  87.   {
  88.     pCommon1->cbFile = 0;
  89.     pCommon1->cbFileAlloc = 0;
  90.   }
  91.   pCommon1->fDOSattr = pEntry->fDOSattr & ~(DOSATTR_NON83 | DOSATTR_NEEDEA);
  92.   *ppData += sizeof(struct common1);
  93.  
  94.   switch (level)
  95.   {
  96.     case FIL_STANDARD:
  97.         /* level 1 only consists of common1 + common2 */
  98.         break;
  99.  
  100.     case FIL_QUERYEASIZE:
  101.         /* insert special level 2 stuff */
  102.         if (*pcbData < sizeof(struct easize))
  103.           return ERROR_BUFFER_OVERFLOW;
  104.         pEasize = (struct easize *) *ppData;
  105.         pEasize->cbList = 0;
  106.         if (pEntry->blkEA.cbSize)
  107.           pEasize->cbList = pEntry->blkEA.cbSize + 4;
  108.         *ppData  += sizeof(struct easize);
  109.         *pcbData -= sizeof(struct easize);
  110.         break;
  111.  
  112.     case FIL_QUERYEASFROMLIST:
  113.         /* insert special level 3 stuff using pEAOP */
  114.         if (*pcbData < 4)
  115.           return ERROR_BUFFER_OVERFLOW;
  116.         pFEAList = (PFEALIST) *ppData;
  117.         pFEAList->cbList = *pcbData;
  118.         rc = EaGetList (pFEAList, pEAOP, &pEntry->blkEA);
  119.         if (rc)
  120.           return rc;
  121.         *ppData  += (USHORT) pFEAList->cbList;
  122.         *pcbData -= (USHORT) pFEAList->cbList;
  123.         break;
  124.   }
  125.  
  126.   /* store file name */
  127.   pCommon2 = (struct common2 *) *ppData;
  128.   pCommon2->cbName = pEntry->cbName;
  129.   if (usAttrPattern & DOSATTR_NON83)
  130.   {
  131.     /* caller can cope with mixed-case names */
  132.     memcpy (pCommon2->szName, pEntry->achName, pEntry->cbName+1);
  133.   }
  134.   else
  135.   {
  136.     /* MAYHAVE_NON83 wasn't set. DOS requires uppercased names. */
  137.     FSH_UPPERCASE (pEntry->achName, pEntry->cbName+1, pCommon2->szName);
  138.   }
  139.   *ppData += sizeof(struct common2) + pEntry->cbName;
  140.  
  141.   return NO_ERROR;
  142. }
  143.  
  144.  
  145.  
  146.  
  147. int FindEntries (
  148.     PSEARCH   pSearch,
  149.     PDIRENTRY pEntry,
  150.     PCHAR     pData,
  151.     USHORT    cbData,
  152.     PUSHORT   pcMatch,
  153.     USHORT    level,
  154.     USHORT    flags )
  155. {
  156.   USHORT cMatch;
  157.   BLOCK     blkDir;
  158.   PEAOP  pEAOP;
  159.   int    cbCurName;
  160.   int    cbCurEntry;
  161.   int    rc;
  162.  
  163.   if (pSearch->flatEntry == SEARCH_END)
  164.     return ERROR_NO_MORE_FILES;
  165.  
  166.   pEAOP = NULL;
  167.   if (level == FIL_QUERYEASFROMLIST)
  168.   {
  169.     /* buffer starts with an EAOP specifying EA names to return - skip it,
  170.        remembering pEAOP */
  171.     if (cbData < sizeof(EAOP))
  172.       return ERROR_BUFFER_OVERFLOW;
  173.     pEAOP   = (PEAOP)pData;
  174.     pData  += sizeof(EAOP);
  175.     cbData -= sizeof(EAOP);
  176.   }
  177.  
  178.   VMReadBlk (&blkDir, pSearch->flatBlkDir);
  179.  
  180.   cMatch = 0;
  181.   while (pSearch->flatEntry < blkDir.flatAddr + blkDir.cbSize)
  182.   {
  183.     cbCurName = VMReadUChar (pSearch->flatEntry);
  184.     cbCurEntry = sizeof(DIRENTRY)-sizeof(pEntry->achName) + cbCurName;
  185.     VMRead (pEntry, pSearch->flatEntry, cbCurEntry);
  186.     pEntry->achName [cbCurName] = '\0';
  187.     if (UtilAttrMatch (pSearch->usAttr, pEntry->fDOSattr) == NO_ERROR)
  188.     {
  189.       /* attribute is ok, check if name also matches */
  190.       char szCurUpName[256];
  191.  
  192.       FSH_UPPERCASE (pEntry->achName, sizeof(szCurUpName), szCurUpName);
  193.       if (FSH_WILDMATCH (pSearch->szPattern, szCurUpName) == NO_ERROR)
  194.       {
  195.     /* name also matches */
  196.     if (cMatch == *pcMatch)
  197.       return NO_ERROR;    /* we aren't allowed to store more entries */
  198.  
  199.     rc = FindStoreEntry (&pData, &cbData, level, flags, pSearch->usAttr,
  200.                  pEAOP, pEntry);
  201.     if (rc == NO_ERROR)
  202.       cMatch++;
  203.     else if (rc == ERROR_BUFFER_OVERFLOW  &&  cMatch != 0)
  204.     {
  205.       /* found some entries, but not room to store this one */
  206.       *pcMatch = cMatch;
  207.       return NO_ERROR;
  208.     }
  209.     else
  210.       /* not room to store first entry, or other error */
  211.       return rc;
  212.       }
  213.     }
  214.     pSearch->flatEntry += cbCurEntry;
  215.   }
  216.  
  217. #ifdef DEBUG
  218.   if (pSearch->flatEntry != blkDir.flatAddr + blkDir.cbSize)
  219.   {
  220.     debugging = TRUE;
  221.     DEBUG_PRINTF3 ("\r\n!!! Find flatEntry=0x%08lX, blkDir.flatAddr=0x%08lX, cbSize=0x%08lX\r\n",
  222.            pSearch->flatEntry, blkDir.flatAddr, blkDir.cbSize);
  223.     INT3;
  224.   }
  225. #endif
  226.  
  227.   pSearch->flatEntry = SEARCH_END;
  228.   if (cMatch == 0)
  229.     return ERROR_NO_MORE_FILES;
  230.  
  231.   *pcMatch = cMatch;
  232.   return NO_ERROR;
  233. }
  234.