Beispiel #1
0
VOID CheckHeap(VOID)
{
USHORT usSel;
BYTE _huge * pHeapStart;
BYTE _huge * pHeapEnd;
BYTE _huge * pWork;
USHORT rc;

   for (usSel = 0; usSel < MAX_SELECTORS; usSel++)
      {
      pHeapStart = rgpSegment[usSel];
      if (!pHeapStart || pHeapStart == RESERVED_SEGMENT)
         continue;
      rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pHeapStart, HEAP_SIZE);
      if (rc)
         {
         CritMessage("FAT32: Protection VIOLATION in CheckHeap (SYS%d)", rc);
         Message("FAT32: Protection VIOLATION in CheckHeap (SYS%d)", rc);
         return;
         }
      pHeapEnd = pHeapStart + HEAP_SIZE;
      pWork = pHeapStart;
      while (pWork < pHeapEnd)
         pWork += BlockSize(pWork) + sizeof (ULONG);
      if (pWork != pHeapEnd)
         CritMessage("FAT32: Heap corruption found!");
      }
}
Beispiel #2
0
static BOOL RemoveVolume(PVOLINFO pVolInfo)
{
PVOLINFO pNext;
USHORT rc;

   if (pGlobVolInfo == pVolInfo)
      {
      pGlobVolInfo = pVolInfo->pNextVolInfo;
      return TRUE;
      }

   pNext = (PVOLINFO)pGlobVolInfo;
   while (pNext)
      {
      rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pNext, sizeof (VOLINFO));
      if (rc)
         {
         FatalMessage("FAT32: Protection VIOLATION in RemoveVolume!\n");
         return FALSE;
         }

      if (pNext->pNextVolInfo == pVolInfo)
         {
         pNext->pNextVolInfo = pVolInfo->pNextVolInfo;
         return TRUE;
         }
      pNext = (PVOLINFO)pNext->pNextVolInfo;
      }
   return FALSE;
}
Beispiel #3
0
USHORT GetLogBuffer(PBYTE pData, USHORT cbData, ULONG ulTimeOut)
{
USHORT rc;

   if (f32Parms.fInShutDown)
      return ERROR_ALREADY_SHUTDOWN;

   rc = MY_PROBEBUF(PB_OPWRITE, pData, cbData);
   if (rc)
      {
      Message("FAT32: Protection VIOLATION in GetLogBuffer! (SYS%d)", rc);
      return rc;
      }

   _disable();
   while (!fData && !f32Parms.fInShutDown)
      {
      rc = DevHelp_ProcBlock((ULONG)GetLogBuffer, ulTimeOut, WAIT_IS_INTERRUPTABLE);
      if (rc)
         {
         _enable();
         return rc;
         }
      _disable();
      }
   _enable();

   if (f32Parms.fInShutDown)
      return ERROR_ALREADY_SHUTDOWN;

   strncpy(pData, szLogBuf, cbData);
   if (strlen(szLogBuf) > cbData)
      {
      memmove(szLogBuf, szLogBuf + cbData, strlen(szLogBuf + cbData) + 1);
      rc = ERROR_BUFFER_OVERFLOW;
      }
   else
      {
      *szLogBuf = 0;
      fData = FALSE;
      rc = 0;
      }

   return rc;
}
Beispiel #4
0
/*********************************************************************
* FindFreeSpace
*********************************************************************/
void * FindFreeSpace(void * pStart, size_t tSize)
{
BYTE _huge * pHeapStart;
BYTE _huge * pHeapEnd;
BYTE _huge * pWork;
BYTE _huge * pNext;
USHORT rc;

   pHeapStart = pStart;
   pHeapEnd = pHeapStart + HEAP_SIZE;

   rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pHeapStart, HEAP_SIZE);
   if (rc)
      {
      CritMessage("FAT32: Protection VIOLATION in FindFreeSpace (SYS%d)", rc);
      Message("FAT32: Protection VIOLATION in FindFreeSpace (SYS%d)", rc);
      return NULL;
      }

   pWork = pHeapStart;
   while (pWork < pHeapEnd)
      {
      if (BlockSize(pWork) >= tSize && IsBlockFree(pWork))
         {
         ULONG ulRemaining = BlockSize(pWork) - tSize;
         if (ulRemaining > sizeof (ULONG))
            {
            pNext = pWork + sizeof (ULONG) + tSize;
            SetBlockSize(pNext, BlockSize(pWork) - tSize - sizeof (ULONG));
            SetFree(pNext);
            SetBlockSize(pWork, tSize);
            }

         SetInUse(pWork);
         return pWork + sizeof (ULONG);
         }
      pWork += BlockSize(pWork) + sizeof (ULONG);
      }
   return NULL;
}
Beispiel #5
0
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;
}
Beispiel #6
0
int far pascal __loadds FS_FINDNEXT(
    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      /* flag     */
)
{
PVOLINFO pVolInfo;
PFINDINFO pFindInfo = (PFINDINFO)pfsfsd;
USHORT rc;
USHORT usIndex;
USHORT usNeededLen;
USHORT usEntriesWanted;

   if (f32Parms.fMessageActive & LOG_FS)
      Message("FS_FINDNEXT, level %u, cbData %u, MaxEntries %u", usLevel, cbData, *pcMatch);

   usEntriesWanted = *pcMatch;
   *pcMatch = 0;

   pVolInfo = GetVolInfo(pfsfsi->fsi_hVPB);
   if (IsDriveLocked(pVolInfo))
      {
      rc = ERROR_DRIVE_LOCKED;
      goto FS_FINDNEXTEXIT;
      }

   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_FINDNEXTEXIT;
      }

   if (usFlags == FF_GETPOS)
      usNeededLen += sizeof (ULONG);

   if (cbData < usNeededLen)
      {
      rc = ERROR_BUFFER_OVERFLOW;
      goto FS_FINDNEXTEXIT;
      }

   rc = MY_PROBEBUF(PB_OPWRITE, pData, cbData);
   if (rc)
      {
      Message("FAT32: Protection VIOLATION in FS_FINDNEXT!");
      return rc;
      }

   if (usLevel == FIL_QUERYEASFROMLIST)
      {
      memcpy(&pFindInfo->pInfo->EAOP, pData, sizeof (EAOP));
      rc = MY_PROBEBUF(PB_OPREAD,
         (PBYTE)pFindInfo->pInfo->EAOP.fpGEAList,
         (USHORT)pFindInfo->pInfo->EAOP.fpGEAList->cbList);
      if (rc)
         goto FS_FINDNEXTEXIT;
      }

   memset(pData, 0, cbData);

   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 = NULL;

      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_FINDNEXTEXIT:

   if (f32Parms.fMessageActive & LOG_FS)
      Message("FS_FINDNEXT returned %d (%d entries)",
         rc, *pcMatch);
   return rc;
}
Beispiel #7
0
void cdecl free(void * pntr)
#endif
{
USHORT usSel;
BYTE _huge * pHeapStart;
BYTE _huge * pHeapEnd;
BYTE _huge * pWork;
BYTE _huge * pToFree = pntr;
BYTE _huge * pPrev;
BYTE _huge * pNext;
USHORT rc;

   if (f32Parms.fMessageActive & LOG_MEM)
      Message("free %lX", pntr);

//   CheckHeap();

   if (OFFSETOF(pntr) == 0)
      {
      freeseg(pntr);
      return;
      }


   GetMemAccess();

   for (usSel = 0; usSel < MAX_SELECTORS; usSel++)
      {
      if (SELECTOROF(pntr) == SELECTOROF(rgpSegment[usSel]))
         break;
      }
   if (usSel == MAX_SELECTORS)
      {
      CritMessage("FAT32: %lX not found in free!", pntr);
      Message("FAT32: %lX not found in free!", pntr);
      ReleaseMemAccess();
      return;
      }

   pHeapStart = rgpSegment[usSel];
   pHeapEnd = pHeapStart + HEAP_SIZE;

   rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pHeapStart, HEAP_SIZE);
   if (rc)
      {
      CritMessage("FAT32: Protection VIOLATION in free (SYS%d)", rc);
      Message("FAT32: Protection VIOLATION in free (SYS%d)", rc);
      ReleaseMemAccess();
      return;
      }

   pWork = pHeapStart;
   pPrev = NULL;
   while (pWork < pHeapEnd)
      {
      if (pWork + sizeof (ULONG) == pToFree)
         {
         if (pPrev && IsBlockFree(pPrev))
            {
            SetBlockSize(pPrev,
               BlockSize(pPrev) + BlockSize(pWork) + sizeof (ULONG));
            pWork = pPrev;
            }

         pNext = pWork + BlockSize(pWork) + sizeof (ULONG);
         if (pNext < pHeapEnd && IsBlockFree(pNext))
            SetBlockSize(pWork, BlockSize(pWork) + BlockSize(pNext) + sizeof (ULONG));

         SetFree(pWork);
         break;
         }
      else
         pPrev = pWork;

      pWork += BlockSize(pWork) + sizeof (ULONG);
      }
   if (pWork >= pHeapEnd)
      {
      CritMessage("FAT32: ERROR: Address not found in free");
      Message("ERROR: Address not found in free");
      ReleaseMemAccess();
      return;
      }

   /*
      free selector if no longer needed
   */
   if (usSel > 0 &&
      BlockSize(rgpSegment[usSel]) == (HEAP_SIZE - sizeof (ULONG)) &&
      IsBlockFree(rgpSegment[usSel]))
      {
      PBYTE p = rgpSegment[usSel];
      rgpSegment[usSel] = NULL;
      freeseg(p);
      }
   ReleaseMemAccess();
}
Beispiel #8
0
USHORT usModifyEAS(PVOLINFO pVolInfo, ULONG ulDirCluster, PSZ pszFileName, PEAOP pEAOP)
{
    USHORT rc;
    PFEALIST pTarFeal;
    PFEALIST pSrcFeal;
    PBYTE    pSrcMax;
    PFEA pSrcFea;
    PFEA pTarFea;

    if (f32Parms.fMessageActive & LOG_EAS)
        Message("usModifyEAS for %s", pszFileName);


    /*
       Do not allow ea's file files with no filename (root)
    */
    if (!strlen(pszFileName))
        return 284;

    rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pEAOP, sizeof (EAOP));
    if (rc)
    {
        Message("Protection violation in usModifyEAS (1) at %lX", pEAOP);
        return rc;
    }

    pSrcFeal = pEAOP->fpFEAList;
    if (pSrcFeal->cbList > MAX_EA_SIZE)
        return ERROR_EA_LIST_TOO_LONG;

    rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pSrcFeal, (USHORT)pSrcFeal->cbList);
    if (rc)
    {
        Message("Protection violation in usModifyEAS (2) at %lX", pSrcFeal);
        return rc;
    }

    if (pSrcFeal->cbList <= sizeof (ULONG))
        return 0;

    rc = usReadEAS(pVolInfo, ulDirCluster, pszFileName, &pTarFeal, TRUE);
    if (rc)
        return rc;

    if (f32Parms.fMessageActive & LOG_EAS)
        Message("cbList before = %lu", pTarFeal->cbList);


    pSrcMax = (PBYTE)pSrcFeal + pSrcFeal->cbList;
    pSrcFea = pSrcFeal->list;
    while ((PBYTE)pSrcFea + sizeof (FEA) < pSrcMax)
    {
        PBYTE pName;
        USHORT usNewSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue;

        if ((PBYTE)pSrcFea + usNewSize > pSrcMax)
        {
            pEAOP->oError = (PBYTE)pSrcFea - (PBYTE)pEAOP;
            rc = ERROR_EA_LIST_INCONSISTENT;
            goto usStoreEASExit;
        }
        pName  = (PBYTE)(pSrcFea + 1);

        rc = FSH_CHECKEANAME(0x0001, pSrcFea->cbName, pName);
        if (rc && pSrcFea->cbValue)
        {
            pEAOP->oError = (PBYTE)pSrcFea - (PBYTE)pEAOP;
            goto usStoreEASExit;
        }

        if (!pSrcFea->cbValue || !pSrcFea->cbName)
            usNewSize = 0;
        else
            usNewSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue;

        pTarFea = FindEA(pTarFeal, pName, pSrcFea->cbName);
        if (!pTarFea)
        {
            pTarFea = (PFEA)((PBYTE)pTarFeal + pTarFeal->cbList);
            if (MAX_EA_SIZE - pTarFeal->cbList < (ULONG)usNewSize)
            {
                rc = ERROR_EAS_DIDNT_FIT;
                goto usStoreEASExit;
            }
            memcpy(pTarFea, pSrcFea, usNewSize);
            pTarFeal->cbList += usNewSize;

            if (f32Parms.fMessageActive & LOG_EAS)
                Message("Inserting EA '%s' (%u,%u)", pName,
                        pSrcFea->cbName, pSrcFea->cbValue);
        }
        else
        {
            USHORT usOldSize  = sizeof (FEA) + (USHORT)pTarFea->cbName + 1 + pTarFea->cbValue;
            USHORT usMoveSize = (USHORT)pTarFeal->cbList -
                                ((PBYTE)pTarFea - (PBYTE)pTarFeal);
            usMoveSize -= usOldSize;

            if (usOldSize < usNewSize)
            {
                if (MAX_EA_SIZE - pTarFeal->cbList < (ULONG)(usNewSize - usOldSize))
                {
                    rc = ERROR_EAS_DIDNT_FIT;
                    goto usStoreEASExit;
                }
            }
            memmove((PBYTE)pTarFea + usNewSize,
                    (PBYTE)pTarFea + usOldSize, usMoveSize);
            memcpy(pTarFea, pSrcFea, usNewSize);
            pTarFeal->cbList -= usOldSize;
            pTarFeal->cbList += usNewSize;

            if (f32Parms.fMessageActive & LOG_EAS)
                Message("Updating EA '%s' (%u,%u)", pName,
                        pSrcFea->cbName, pSrcFea->cbValue);
        }

        usNewSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue;
        pSrcFea = (PFEA)((PBYTE)pSrcFea + usNewSize);
    }

    if (f32Parms.fMessageActive & LOG_EAS)
        Message("cbList after = %lu", pTarFeal->cbList);

    if (pTarFeal->cbList > 4)
        rc = usWriteEAS(pVolInfo, ulDirCluster, pszFileName, pTarFeal);
    else
        rc = usDeleteEAS(pVolInfo, ulDirCluster, pszFileName);

usStoreEASExit:
    freeseg(pTarFeal);

    if (f32Parms.fMessageActive & LOG_EAS)
        Message("usModifyEAS for %s returned %d",
                pszFileName, rc);

    return rc;
}
Beispiel #9
0
USHORT usGetEAS(PVOLINFO pVolInfo, USHORT usLevel, ULONG ulDirCluster, PSZ pszFileName, PEAOP pEAOP)
{
    USHORT rc;
    PFEALIST pTarFeal;
    PFEALIST pSrcFeal;
    PFEA     pSrcFea;
    PFEA     pTarFea;
    PGEALIST pGeaList;
    USHORT   usMaxSize;

    if (f32Parms.fMessageActive & LOG_EAS)
        Message("usGetEAS for %s Level %d", pszFileName, usLevel);

    /*
       Checking all the arguments
    */

    rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pEAOP, sizeof (EAOP));
    if (rc)
    {
        Message("Protection violation in usGetEAS (1) at %lX", pEAOP);
        return rc;
    }

    pTarFeal = pEAOP->fpFEAList;
    rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pTarFeal, sizeof (ULONG));
    if (rc)
    {
        Message("Protection violation in usGetEAS (2) at %lX", pTarFeal);
        return rc;
    }
    if (pTarFeal->cbList > MAX_EA_SIZE)
        usMaxSize = (USHORT)MAX_EA_SIZE;
    else
        usMaxSize = (USHORT)pTarFeal->cbList;

    if (usMaxSize < sizeof (ULONG))
        return ERROR_BUFFER_OVERFLOW;

    rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pTarFeal, (USHORT)usMaxSize);
    if (rc)
        return rc;

    if (usLevel == FIL_QUERYEASFROMLIST)
    {
        pGeaList = pEAOP->fpGEAList;
        rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pGeaList, sizeof (ULONG));
        if (rc)
            return rc;
        if (pGeaList->cbList > MAX_EA_SIZE)
            return ERROR_EA_LIST_TOO_LONG;
        rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pGeaList, (USHORT)pGeaList->cbList);
        if (rc)
            return rc;
    }
    else
        pGeaList = NULL;

    /*
       Initialize the FEALIST
    */
    memset(pTarFeal, 0, usMaxSize);
    pTarFeal->cbList = sizeof (ULONG);
    usMaxSize -= sizeof (ULONG);
    pTarFea = pTarFeal->list;

    /*
       Does the EA Exist?
    */

    rc = usReadEAS(pVolInfo, ulDirCluster, pszFileName, &pSrcFeal, FALSE);
    if (rc)
        goto usGetEASExit;

    /*
       If not, return
    */
    if (usLevel == FIL_QUERYEASFROMLIST)
    {
        PBYTE    pGeaMax;
        PGEA     pGea;

        pGeaMax = (PBYTE)pGeaList + pGeaList->cbList;
        pGea    = pGeaList->list;
        while ((PBYTE)pGea + sizeof (GEA) < pGeaMax)
        {
            USHORT usGeaSize = sizeof (GEA) + (USHORT)pGea->cbName;
            USHORT usFeaSize;

            if (pGea->szName + (USHORT)pGea->cbName > pGeaMax)
            {
                rc = ERROR_EA_LIST_INCONSISTENT;
                goto usGetEASExit;
            }

            pSrcFea = FindEA(pSrcFeal, pGea->szName, pGea->cbName);
            if (pSrcFea)
            {
                usFeaSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue;
                if (usFeaSize > usMaxSize)
                {
                    rc = ERROR_BUFFER_OVERFLOW;
                    pTarFeal->cbList = pSrcFeal->cbList;
                    goto usGetEASExit;
                }
                if (f32Parms.fMessageActive & LOG_EAS)
                    Message("Found %s", pSrcFea + 1);
                memcpy(pTarFea, pSrcFea, usFeaSize);
            }
            else
            {
                usFeaSize = sizeof (FEA) + (USHORT)pGea->cbName + 1;
                if (usFeaSize > usMaxSize)
                {
                    rc = ERROR_BUFFER_OVERFLOW;
                    if (pSrcFeal)
                        pTarFeal->cbList = pSrcFeal->cbList;
                    else
                        pTarFeal->cbList = 4;
                    goto usGetEASExit;
                }

                if (f32Parms.fMessageActive & LOG_EAS)
                    Message("usGetEAS: %s not found!", pGea->szName);

                pTarFea->fEA = 0x00;
                pTarFea->cbName = pGea->cbName;
                pTarFea->cbValue = 0;
                strcpy((PBYTE)(pTarFea + 1), pGea->szName);
            }

            pTarFea = (PFEA)((PBYTE)pTarFea + usFeaSize);
            pTarFeal->cbList += usFeaSize;
            usMaxSize -= usFeaSize;

            pGea = (PGEA)((PBYTE)pGea + usGeaSize);
        }
    }
    else if (pSrcFeal)
    {
        PBYTE     pSrcMax = (PBYTE)pSrcFeal + pSrcFeal->cbList;
        pSrcFea = pSrcFeal->list;

        while ((PBYTE)pSrcFea + sizeof (FEA) < pSrcMax)
        {
            USHORT usFeaSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue;
            if (usFeaSize > usMaxSize)
            {
                rc = ERROR_BUFFER_OVERFLOW;
                pTarFeal->cbList = pSrcFeal->cbList;
                goto usGetEASExit;
            }
            if (f32Parms.fMessageActive & LOG_EAS)
                Message("Found %s (%u,%u)", pSrcFea + 1, (USHORT)pSrcFea->cbName, pSrcFea->cbValue);
            memcpy(pTarFea, pSrcFea, usFeaSize);
            pTarFea = (PFEA)((PBYTE)pTarFea + usFeaSize);
            pTarFeal->cbList += usFeaSize;
            pSrcFea = (PFEA)((PBYTE)pSrcFea + usFeaSize);
            usMaxSize -= usFeaSize;
        }
    }

    rc = 0;

usGetEASExit:

    if (pSrcFeal)
        freeseg(pSrcFeal);

    if (f32Parms.fMessageActive & LOG_EAS)
        Message("usGetEAS for %s returned %d (%lu bytes in EAS)",
                pszFileName, rc, pTarFeal->cbList);

    return rc;
}