예제 #1
0
static NTSTATUS
VfatMarkVolumeDirty(PVFAT_IRP_CONTEXT IrpContext)
{
   ULONG eocMark;
   PDEVICE_EXTENSION DeviceExt;
   NTSTATUS Status = STATUS_SUCCESS;

   DPRINT("VfatMarkVolumeDirty(IrpContext %p)\n", IrpContext);
   DeviceExt = IrpContext->DeviceExt;

   if (!(DeviceExt->VolumeFcb->Flags & VCB_IS_DIRTY))
   {
      Status = GetNextCluster(DeviceExt, 1, &eocMark);
      if (NT_SUCCESS(Status))
      {
         /* unset clean shutdown bit */
         eocMark &= ~DeviceExt->CleanShutBitMask;
         Status = WriteCluster(DeviceExt, 1, eocMark);
      }
   }

   DeviceExt->VolumeFcb->Flags &= ~VCB_CLEAR_DIRTY;

   return Status;
}
예제 #2
0
//Release one cluster chain,the cluster chain starts from dwStartCluster.
BOOL ReleaseClusterChain(__FAT32_FS* pFat32Fs,DWORD dwStartCluster)
{
	DWORD   dwNextCluster = 0;
	DWORD   dwCurrCluster = 0;
	BOOL    bResult       = FALSE;

	if((NULL == pFat32Fs) || (dwStartCluster < 2) || IS_EOC(dwStartCluster))
	{
		goto __TERMINAL;
	}
	dwNextCluster = dwStartCluster;
	while(!IS_EOC(dwNextCluster))
	{
		dwCurrCluster = dwNextCluster;
		if(!GetNextCluster(pFat32Fs,&dwNextCluster))
		{
			goto __TERMINAL;
		}
		ReleaseCluster(pFat32Fs,dwCurrCluster);  //Release current one.
	}
	bResult = TRUE;

__TERMINAL:
	return bResult;
}
예제 #3
0
BOOL GetCluster(PVOLINFO pVolInfo, PFINDINFO pFindInfo, USHORT usClusterIndex)
{
USHORT usIndex;

   if (usClusterIndex >= pFindInfo->usTotalClusters)
      return FALSE;

   if (!pFindInfo->pInfo->rgClusters[usClusterIndex])
      {
      for (usIndex = pFindInfo->usClusterIndex; usIndex < usClusterIndex; usIndex++)
         {
         pFindInfo->pInfo->rgClusters[usIndex + 1] =
            GetNextCluster( pVolInfo, pFindInfo->pInfo->rgClusters[usIndex]);

         if (!pFindInfo->pInfo->rgClusters[usIndex + 1])
            pFindInfo->pInfo->rgClusters[usIndex + 1] = FAT_EOF;

         if (pFindInfo->pInfo->rgClusters[usIndex + 1] == FAT_EOF)
            return FALSE;
         }
      }

   if (pFindInfo->pInfo->rgClusters[usClusterIndex] == FAT_EOF)
      return FALSE;

   if (ReadCluster( pVolInfo,
      pFindInfo->pInfo->rgClusters[usClusterIndex], pFindInfo->pInfo->pDirEntries, 0))
      return FALSE;

   pFindInfo->usClusterIndex = usClusterIndex;
   return TRUE;
}
예제 #4
0
void Clust::DeleteMetric(unsigned uIndex)
	{
	for (unsigned uNodeIndex = GetFirstCluster(); uNodeIndex != uInsane;
	  uNodeIndex = GetNextCluster(uNodeIndex))
		{
		if (uIndex == uNodeIndex)
			continue;
		DeleteMetric(uIndex, uNodeIndex);
		}
	}
예제 #5
0
파일: rw.c 프로젝트: hoangduit/reactos
NTSTATUS
OffsetToCluster(
    PDEVICE_EXTENSION DeviceExt,
    ULONG FirstCluster,
    ULONG FileOffset,
    PULONG Cluster,
    BOOLEAN Extend)
{
    ULONG CurrentCluster;
    ULONG i;
    NTSTATUS Status;
/*
    DPRINT("OffsetToCluster(DeviceExt %x, Fcb %x, FirstCluster %x,"
           " FileOffset %x, Cluster %x, Extend %d)\n", DeviceExt,
           Fcb, FirstCluster, FileOffset, Cluster, Extend);
*/
    if (FirstCluster == 0)
    {
        DbgPrint("OffsetToCluster is called with FirstCluster = 0!\n");
        ASSERT(FALSE);
    }

    if (FirstCluster == 1)
    {
        /* root of FAT16 or FAT12 */
        *Cluster = DeviceExt->FatInfo.rootStart + FileOffset
            / (DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.SectorsPerCluster;
        return STATUS_SUCCESS;
    }
    else
    {
        CurrentCluster = FirstCluster;
        if (Extend)
        {
            for (i = 0; i < FileOffset / DeviceExt->FatInfo.BytesPerCluster; i++)
            {
                Status = GetNextClusterExtend (DeviceExt, CurrentCluster, &CurrentCluster);
                if (!NT_SUCCESS(Status))
                    return Status;
            }
            *Cluster = CurrentCluster;
        }
        else
        {
            for (i = 0; i < FileOffset / DeviceExt->FatInfo.BytesPerCluster; i++)
            {
                Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster);
                if (!NT_SUCCESS(Status))
                    return Status;
            }
            *Cluster = CurrentCluster;
       }
       return STATUS_SUCCESS;
   }
}
예제 #6
0
파일: rw.c 프로젝트: hoangduit/reactos
/*
 * Return the next cluster in a FAT chain, possibly extending the chain if
 * necessary
 */
NTSTATUS
NextCluster(
    PDEVICE_EXTENSION DeviceExt,
    ULONG FirstCluster,
    PULONG CurrentCluster,
    BOOLEAN Extend)
{
    if (FirstCluster == 1)
    {
        (*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster;
        return STATUS_SUCCESS;
    }
    else
    {
        if (Extend)
            return GetNextClusterExtend(DeviceExt, (*CurrentCluster), CurrentCluster);
        else
            return GetNextCluster(DeviceExt, (*CurrentCluster), CurrentCluster);
    }
}
예제 #7
0
VOID CheckSpace(PDRIVEINFO pDrive)
{
ULONG ulCluster;

   printf("\nChecking for lost clusters\n");

   ulTotalFree = 0;
   for (ulCluster = 2; ulCluster < pDrive->ulTotalClusters + 2; ulCluster++)
      {
      ULONG ulNext = GetNextCluster(pDrive, ulCluster);
      if (!(ulNext & FAT_EOF))
         {
         MarkCluster(pDrive, ulCluster);
         ulTotalFree++;
         }
      else
         {
         if (!ClusterInUse(pDrive, ulCluster))
            printf("Cluster %lu is lost (%8.8lX)\n", ulCluster, ulNext);
         }
      }
}
예제 #8
0
ULONG NextSector(ULONG Sector)
{
    Sector += 1;

    //
    // This may look confusing, but it saves us 16 bytes over a % operation.
    //      if( Sector % ( 1 << pBPB->SectorsPerCluster) == 0 )
    // Just checking to see if we've used all the sectors in the current cluster.
    //
    if( (Sector & ((1 << pBPB->SectorsPerCluster)-1)) == 0 )
    {
        ULONG Cluster = LBA2Cluster( Sector - 1 );
        ULONG NewCluster = GetNextCluster( Cluster );
        if( IsDataCluster( NewCluster ) && Cluster != NewCluster )
        {
            return Cluster2LBA( NewCluster );
        }

        Sector = 0;
    }

    return Sector;
}
예제 #9
0
파일: IFSEA.C 프로젝트: OS2World/DRV-FAT32
USHORT usReadEAS(PVOLINFO pVolInfo, ULONG ulDirCluster, PSZ pszFileName, PFEALIST * ppFEAL, BOOL fCreate)
{
    PFEALIST pFEAL;
    ULONG ulCluster;
    PBYTE  pszEAName;
    PBYTE pRead;
    USHORT rc;
    USHORT usClustersUsed;

    *ppFEAL = NULL;

    rc = GetEASName(pVolInfo, ulDirCluster, pszFileName, &pszEAName);
    if (rc)
        return rc;

    ulCluster = FindPathCluster(pVolInfo, ulDirCluster, pszEAName, NULL, NULL);
    free(pszEAName);

    if ((ulCluster && ulCluster != FAT_EOF) || fCreate)
    {
        pFEAL = gdtAlloc(MAX_EA_SIZE, FALSE);
        if (!pFEAL)
            return ERROR_NOT_ENOUGH_MEMORY;
        memset(pFEAL, 0, (size_t) MAX_EA_SIZE);
        pFEAL->cbList = sizeof (ULONG);
    }
    else
        pFEAL = NULL;

    if (!ulCluster || ulCluster == FAT_EOF)
    {
        *ppFEAL = pFEAL;
        return 0;
    }

    pRead = (PBYTE)pFEAL;
    if (f32Parms.fMessageActive & LOG_EAS)
        Message("usReadEAS: Reading (1) cluster %lu", ulCluster);

    rc = ReadCluster(pVolInfo, ulCluster, pRead, 0);
    if (rc)
    {
        freeseg(pFEAL);
        return rc;
    }
    if (pFEAL->cbList > MAX_EA_SIZE)
    {
        freeseg(pFEAL);
        return ERROR_EAS_DIDNT_FIT;
    }

    usClustersUsed = (USHORT)(pFEAL->cbList / pVolInfo->usClusterSize);
    if (pFEAL->cbList % pVolInfo->usClusterSize)
        usClustersUsed++;

    /*
       vreemd: zonder deze Messages lijkt deze routine mis te gaan.
       Optimalisatie?
    */
    if (f32Parms.fMessageActive & LOG_EAS)
        Message("usReadEAS: %u clusters used", usClustersUsed);

    usClustersUsed--;
    pRead += pVolInfo->usClusterSize;

    while (usClustersUsed)
    {
        ulCluster = GetNextCluster(pVolInfo, ulCluster);
        if (!ulCluster)
            ulCluster = FAT_EOF;
        if (ulCluster == FAT_EOF)
        {
            freeseg(pFEAL);
            return ERROR_EA_FILE_CORRUPT;
        }
        /*
           vreemd: zonder deze Messages lijkt deze routine mis te gaan.
           Optimalisatie?
        */
        if (f32Parms.fMessageActive & LOG_EAS)
            Message("usReadEAS: Reading (2) cluster %lu", ulCluster);

        rc = ReadCluster(pVolInfo, ulCluster, pRead, 0);
        if (rc)
        {
            freeseg(pFEAL);
            return rc;
        }
        usClustersUsed--;
        pRead += pVolInfo->usClusterSize;
    }
    *ppFEAL = pFEAL;

    return 0;
}
예제 #10
0
//Append one free cluster to the tail of a cluster chain.
//The pdwCurrCluster contains the laster cluster of a cluster chain,if this routine
//executes successfully,it will return TRUE and pdwCurrCluster contains the cluster
//number value appended to chain right now.Else FALSE will be returned and the pdwCurrCluster
//keep unchanged.
BOOL AppendClusterToChain(__FAT32_FS* pFat32Fs,DWORD* pdwCurrCluster)
{
	DWORD         dwCurrCluster   = 0;
	DWORD         dwNextCluster   = 0;
	DWORD         dwSector        = 0;
	DWORD         dwOffset        = 0;
	BOOL          bResult         = FALSE;
	BYTE*         pBuffer         = NULL;
	DWORD         dwEndCluster    = 0;


	if((NULL == pFat32Fs) || (NULL == pdwCurrCluster))
	{
		goto __TERMINAL;
	}
	dwCurrCluster = *pdwCurrCluster;
	if((2 > dwCurrCluster) || IS_EOC(dwCurrCluster))
	{
		goto __TERMINAL;
	}

	dwSector = dwCurrCluster / 128;
	if(dwSector > pFat32Fs->dwFatSectorNum)  //Exceed the FAT size.
	{
		goto __TERMINAL;
	}
	dwSector += pFat32Fs->dwFatBeginSector;  //Now dwSector is the physical sector number of dwCurrCluster in fat.
	dwOffset  = (dwCurrCluster - (dwCurrCluster / 128) * 128) * sizeof(DWORD); //Get sector offset.

	pBuffer = (BYTE*)LocalAlloc(LPTR,pFat32Fs->dwBytePerSector);
	if(NULL == pBuffer)
	{
		goto __TERMINAL;
	}
	//Try to get a free cluster.
	if(!GetFreeCluster(pFat32Fs,0,&dwNextCluster))
	{
		goto __TERMINAL;
	}
	//The following operation must behind GetFreeCluster routine above,because
	//GetFreeCluster routine will modify the content of FAT,and this change must
	//be taken before the following read.
	//One complicated problem has been caused by this reason.
	if(!ReadDeviceSector(pFat32Fs->pPartition,pFat32Fs->dwPartitionSatrt+ dwSector,1,pBuffer))
	{		
		goto __TERMINAL;
	}
	//Save the next cluster to chain.
	*(DWORD*)(pBuffer + dwOffset) &= 0xF0000000;  //Keep the leading 4 bits.
	*(DWORD*)(pBuffer + dwOffset) += (dwNextCluster & 0x0FFFFFFF);
	if(!WriteDeviceSector(pFat32Fs->pPartition,	pFat32Fs->dwPartitionSatrt+ dwSector,1,pBuffer))
	{
		ReleaseCluster(pFat32Fs,dwNextCluster);   //Release this cluster.		
		goto __TERMINAL;
	}

	dwEndCluster = *(DWORD*)(pBuffer + dwOffset);
	if(!GetNextCluster(pFat32Fs,&dwEndCluster))
	{
		
	}

	bResult = TRUE;  //Anything is in place.

__TERMINAL:
	if(pBuffer)  //Should release it.
	{
		LocalFree(pBuffer);
	}

	if(bResult)
	{
		*pdwCurrCluster = (dwNextCluster & 0x0FFFFFFF);
	}

	return bResult;
}
예제 #11
0
파일: FAT32.C 프로젝트: bladely/HelloX_OS
//Implementation of SetFilePointer.
static DWORD FatDeviceSeek(__COMMON_OBJECT* lpDrv, __COMMON_OBJECT* lpDev,__DRCB* lpDrcb)
{
    __FAT32_FILE*    pFatFile  = NULL;
    DWORD	         dwSeekRet = -1;

    if((NULL == lpDrv) || (NULL == lpDev) || (NULL == lpDrcb))
    {
        return dwSeekRet;
    }

    pFatFile = (__FAT32_FILE*)(((__DEVICE_OBJECT*)lpDev)->lpDevExtension);
    if( NULL != pFatFile)
    {
        __FAT32_FS* pFatFs       = pFatFile->pFileSystem;
        DWORD       dwWhereBegin = (DWORD)lpDrcb->lpInputBuffer;//((DWORD*)lpDrcb->lpInputBuffer);
        DWORD       dwOffsetPos  = *((INT*)lpDrcb->dwExtraParam1);
        DWORD       dwClusterNum = 0;
        DWORD       i            = 0;

        //_hx_printf("FatDeviceSeek: where=%d,pos=%d\r\n",dwWhereBegin,dwOffsetPos);

        switch(dwWhereBegin)
        {
        case FILE_FROM_BEGIN:
        {
            pFatFile->dwCurrPos = dwOffsetPos;
        }
        break;
        case FILE_FROM_CURRENT:
        {
            pFatFile->dwCurrPos += dwOffsetPos;
        }
        break;
        case FILE_FROM_END:
        {
            pFatFile->dwCurrPos = pFatFile->dwFileSize;
        }
        break;
        default:
        {
            return dwSeekRet;
        }
        }

        if(pFatFile->dwCurrPos > pFatFile->dwFileSize)
        {
            pFatFile->dwCurrPos = pFatFile->dwFileSize;
        }

        if(pFatFile->dwCurrPos < pFatFs->dwClusterSize )
        {
            dwClusterNum = 1;
        }
        else
        {
            dwClusterNum = pFatFile->dwCurrPos/pFatFs->dwClusterSize;
            if((pFatFile->dwCurrPos+1)%pFatFs->dwClusterSize)
            {
                dwClusterNum ++;
            }
        }

        pFatFile->dwCurrClusNum = pFatFile->dwStartClusNum;
        for(i=0; i< (dwClusterNum-1); i++)
        {
            DWORD dwNextNum = pFatFile->dwCurrClusNum;

            if(!GetNextCluster(pFatFs,&dwNextNum))
            {
                return dwSeekRet;
            }

            pFatFile->dwCurrClusNum = dwNextNum;
        }

        pFatFile->dwClusOffset = pFatFile->dwCurrPos % pFatFs->dwClusterSize;
        dwSeekRet              = pFatFile->dwCurrPos;
    }

    return dwSeekRet;
}
예제 #12
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;
}
예제 #13
0
파일: FAT32.C 프로젝트: bladely/HelloX_OS
//Helper routine used to build the directory cluster list given a name.
//The appropriate find handle is returned if all successfully.
static __FAT32_FIND_HANDLE* BuildFindHandle(__FAT32_FS* pFat32Fs,CHAR* pszDirName)
{
    __FAT32_FIND_HANDLE*    pFindHandle     = NULL;
    __FAT32_DIR_CLUSTER*    pDirCluster     = NULL;
    __FAT32_SHORTENTRY      ShortEntry      = {0};     //Short entry of target dir.
    DWORD                   dwCurrClus      = 0;
    DWORD                   dwSector        = 0;
    BOOL                    bResult         = FALSE;

    if(!GetDirEntry(pFat32Fs,&pszDirName[0],&ShortEntry,NULL,NULL))
    {
        goto __TERMINAL;
    }
    if(!(ShortEntry.FileAttributes & FILE_ATTR_DIRECTORY))  //Not a directory.
    {
        goto __TERMINAL;
    }
    pFindHandle = (__FAT32_FIND_HANDLE*)CREATE_OBJECT(__FAT32_FIND_HANDLE);
    if(NULL == pFindHandle)
    {
        goto __TERMINAL;
    }
    //Initialize the find hanlde object.
    pFindHandle->dwClusterOffset = 0;
    pFindHandle->dwClusterSize   = pFat32Fs->dwClusterSize;
    pFindHandle->pClusterRoot    = NULL;
    pFindHandle->pCurrCluster    = NULL;
    dwCurrClus = ((DWORD)ShortEntry.wFirstClusHi << 16) + (DWORD)ShortEntry.wFirstClusLow;
    while(!IS_EOC(dwCurrClus))
    {
        pDirCluster = (__FAT32_DIR_CLUSTER*)CREATE_OBJECT(__FAT32_DIR_CLUSTER);
        if(NULL == pDirCluster)  //Can not allocate memory.
        {
            goto __TERMINAL;
        }
        pDirCluster->pCluster = (BYTE*)FatMem_Alloc(pFat32Fs->dwClusterSize);
        if(NULL == pDirCluster->pCluster)
        {
            goto __TERMINAL;
        }
        pDirCluster->pNext = NULL;
        //Now try to read the directory cluster data.
        dwSector = GetClusterSector(pFat32Fs,dwCurrClus);
        if(0 == dwSector)
        {
            goto __TERMINAL;
        }
        if(!ReadDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition,
                             dwSector,
                             pFat32Fs->SectorPerClus,
                             pDirCluster->pCluster))  //Can not read directory cluster.
        {
            goto __TERMINAL;
        }
        //Attach this cluster into directory cluster list.
        if(NULL == pFindHandle->pClusterRoot)  //First cluster now.
        {
            pFindHandle->pClusterRoot = pDirCluster;
            pFindHandle->pCurrCluster = pDirCluster;
        }
        else  //Not the first cluster,pCurrCluster pointing to the last node.
        {
            pFindHandle->pCurrCluster->pNext = pDirCluster;
            pFindHandle->pCurrCluster        = pDirCluster;
        }
        if(!GetNextCluster(pFat32Fs,&dwCurrClus))
        {
            goto __TERMINAL;
        }
    }
    pFindHandle->pCurrCluster = pFindHandle->pClusterRoot;
    pDirCluster = NULL;  //Indicate the successful execution of above while block.
    bResult = TRUE;  //Mark the successful flag.

__TERMINAL:
    if(bResult)  //Successful.
    {
        return pFindHandle;
    }
    else  //Failed,should release the allocated resource.
    {
        if(pDirCluster)  //Directory cluster object has been allocated.
        {
            if(pDirCluster->pCluster)
            {
                FatMem_Free(pDirCluster->pCluster);
            }
            FatMem_Free(pDirCluster);
        }
        //Release the directory cluster object in list.
        if(NULL == pFindHandle)
        {
            goto __RETURN;
        }
        while(pFindHandle->pClusterRoot)
        {
            pFindHandle->pCurrCluster = pFindHandle->pClusterRoot;
            pFindHandle->pClusterRoot = pFindHandle->pClusterRoot->pNext;
            if(pFindHandle->pCurrCluster->pCluster)
            {
                FatMem_Free(pFindHandle->pCurrCluster->pCluster);
            }
            FatMem_Free(pFindHandle->pCurrCluster);
        }

        //Release the find handle object.
        FatMem_Free(pFindHandle);

__RETURN:

        return NULL;
    }
}
예제 #14
0
파일: FAT32.C 프로젝트: bladely/HelloX_OS
//Helper routine to obtain volume lable.
static BOOL GetVolumeLbl(__FAT32_FS* pFat32Fs,CHAR* pVolumeLbl)
{
    BOOL                bResult      = FALSE;
    __FAT32_SHORTENTRY* pfse         = NULL;
    BYTE*               pBuffer      = NULL;
    DWORD               dwCurrClus   = 0;
    DWORD               dwSector     = 0;
    CHAR                Buffer[128]  = {0};
    INT                 i,j;

    if((NULL == pFat32Fs) || (NULL == pVolumeLbl))
    {
        goto __TERMINAL;
    }
    //Create local buffer to contain one cluster.
    pBuffer = (BYTE*)FatMem_Alloc(pFat32Fs->SectorPerClus * pFat32Fs->dwBytePerSector);
    if(NULL == pBuffer)
    {
        PrintLine("Can not allocate memory from heap.");
        goto __TERMINAL;
    }
    dwCurrClus = pFat32Fs->dwRootDirClusStart;
    while(!IS_EOC(dwCurrClus))  //Main loop to check the root directory.
    {
        dwSector = GetClusterSector(pFat32Fs,dwCurrClus);
        if(0 == dwSector)  //Fatal error.
        {
            goto __TERMINAL;
        }
        if(!ReadDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition,
                             dwSector,
                             pFat32Fs->SectorPerClus,
                             pBuffer))  //Can not read the appropriate sector(s).
        {
            _hx_sprintf(Buffer," Read sector failed in GetVolumeLbl,Info: %d %d %d %d %d %d %d ",
                        dwCurrClus,
                        dwSector,
                        pFat32Fs->dwClusterSize,
                        pFat32Fs->dwDataSectorStart,
                        pFat32Fs->dwFatSectorNum,
                        pFat32Fs->dwFatBeginSector,
                        pFat32Fs->SectorPerClus);
            PrintLine(Buffer);  //Only used for debugging.
            goto __TERMINAL;
        }
        //Now check the root directory to seek the volume ID entry.
        pfse = (__FAT32_SHORTENTRY*)pBuffer;
        for(i = 0; i < pFat32Fs->SectorPerClus * 16; i ++)
        {
            if(0xE5 == (BYTE)pfse->FileName[0])  //Empty entry.
            {
                pfse += 1;  //Seek to the next entry.
                continue;
            }
            if(0 == pfse->FileName[0])     //All rest part is zero,no need to check futher.
            {
                break;
            }
            if(FILE_ATTR_LONGNAME == pfse->FileAttributes)  //Long file name entry.
            {
                pfse += 1;
                continue;
            }
            if(FILE_ATTR_VOLUMEID & pfse->FileAttributes)   //Volume label entry.
            {
                for(j = 0; j < 11; j ++)
                {
                    pVolumeLbl[j] = pfse->FileName[j];
                }
                pVolumeLbl[j] = 0;  //Set the terminator.
                bResult = TRUE;
                goto __TERMINAL;
            }
            pfse += 1;
        }
        if(!GetNextCluster(pFat32Fs,&dwCurrClus))
        {
            _hx_printf(Buffer,"Current cluster number is %d\n",dwCurrClus);
            break;
        }
    }

__TERMINAL:
    FatMem_Free(pBuffer);

    return bResult;
}
예제 #15
0
static NTSTATUS
VfatMount (PVFAT_IRP_CONTEXT IrpContext)
/*
 * FUNCTION: Mount the filesystem
 */
{
   PDEVICE_OBJECT DeviceObject = NULL;
   PDEVICE_EXTENSION DeviceExt = NULL;
   BOOLEAN RecognizedFS;
   NTSTATUS Status;
   PVFATFCB Fcb = NULL;
   PVFATFCB VolumeFcb = NULL;
   PVFATCCB Ccb = NULL;
   PDEVICE_OBJECT DeviceToMount;
   PVPB Vpb;
   UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\$$Fat$$");
   UNICODE_STRING VolumeNameU = RTL_CONSTANT_STRING(L"\\$$Volume$$");
   ULONG HashTableSize;
   ULONG eocMark;
   FATINFO FatInfo;

   DPRINT("VfatMount(IrpContext %p)\n", IrpContext);

   ASSERT(IrpContext);

   if (IrpContext->DeviceObject != VfatGlobalData->DeviceObject)
   {
      Status = STATUS_INVALID_DEVICE_REQUEST;
      goto ByeBye;
   }

   DeviceToMount = IrpContext->Stack->Parameters.MountVolume.DeviceObject;
   Vpb = IrpContext->Stack->Parameters.MountVolume.Vpb;

   Status = VfatHasFileSystem (DeviceToMount, &RecognizedFS, &FatInfo);
   if (!NT_SUCCESS(Status))
   {
      goto ByeBye;
   }

   if (RecognizedFS == FALSE)
   {
      DPRINT("VFAT: Unrecognized Volume\n");
      Status = STATUS_UNRECOGNIZED_VOLUME;
      goto ByeBye;
   }

   /* Use prime numbers for the table size */
   if (FatInfo.FatType == FAT12)
   {
      HashTableSize = 4099; // 4096 = 4 * 1024
   }
   else if (FatInfo.FatType == FAT16 ||
            FatInfo.FatType == FATX16)
   {
      HashTableSize = 16411; // 16384 = 16 * 1024
   }
   else
   {
      HashTableSize = 65537; // 65536 = 64 * 1024;
   }
   HashTableSize = FCB_HASH_TABLE_SIZE;
   DPRINT("VFAT: Recognized volume\n");
   Status = IoCreateDevice(VfatGlobalData->DriverObject,
                           ROUND_UP(sizeof (DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize,
                           NULL,
                           FILE_DEVICE_DISK_FILE_SYSTEM,
                           DeviceToMount->Characteristics,
                           FALSE,
                           &DeviceObject);
   if (!NT_SUCCESS(Status))
   {
      goto ByeBye;
   }

   DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
   DeviceExt = (PVOID) DeviceObject->DeviceExtension;
   RtlZeroMemory(DeviceExt, ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize);
   DeviceExt->FcbHashTable = (HASHENTRY**)((ULONG_PTR)DeviceExt + ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)));
   DeviceExt->HashTableSize = HashTableSize;

   /* use same vpb as device disk */
   DeviceObject->Vpb = Vpb;
   DeviceToMount->Vpb = Vpb;

   Status = VfatMountDevice(DeviceExt, DeviceToMount);
   if (!NT_SUCCESS(Status))
   {
      /* FIXME: delete device object */
      goto ByeBye;
   }

   DPRINT("BytesPerSector:     %d\n", DeviceExt->FatInfo.BytesPerSector);
   DPRINT("SectorsPerCluster:  %d\n", DeviceExt->FatInfo.SectorsPerCluster);
   DPRINT("FATCount:           %d\n", DeviceExt->FatInfo.FATCount);
   DPRINT("FATSectors:         %d\n", DeviceExt->FatInfo.FATSectors);
   DPRINT("RootStart:          %d\n", DeviceExt->FatInfo.rootStart);
   DPRINT("DataStart:          %d\n", DeviceExt->FatInfo.dataStart);
   if (DeviceExt->FatInfo.FatType == FAT32)
   {
      DPRINT("RootCluster:        %d\n", DeviceExt->FatInfo.RootCluster);
   }

   switch (DeviceExt->FatInfo.FatType)
   {
      case FAT12:
         DeviceExt->GetNextCluster = FAT12GetNextCluster;
         DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
         DeviceExt->WriteCluster = FAT12WriteCluster;
         DeviceExt->CleanShutBitMask = 0;
         break;

      case FAT16:
      case FATX16:
         DeviceExt->GetNextCluster = FAT16GetNextCluster;
         DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
         DeviceExt->WriteCluster = FAT16WriteCluster;
         DeviceExt->CleanShutBitMask = 0x8000;
         break;

      case FAT32:
      case FATX32:
         DeviceExt->GetNextCluster = FAT32GetNextCluster;
         DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
         DeviceExt->WriteCluster = FAT32WriteCluster;
         DeviceExt->CleanShutBitMask = 0x80000000;
         break;
   }

   if (DeviceExt->FatInfo.FatType == FATX16
      || DeviceExt->FatInfo.FatType == FATX32)
   {
      DeviceExt->Flags |= VCB_IS_FATX;
      DeviceExt->GetNextDirEntry = FATXGetNextDirEntry;
      DeviceExt->BaseDateYear = 2000;
   }
   else
   {
      DeviceExt->GetNextDirEntry = FATGetNextDirEntry;
      DeviceExt->BaseDateYear = 1980;
   }

   DeviceExt->StorageDevice = DeviceToMount;
   DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
   DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
   DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
   DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
   DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

   DPRINT("FsDeviceObject %p\n", DeviceObject);

   /* Initialize this resource early ... it's used in VfatCleanup */
   ExInitializeResourceLite(&DeviceExt->DirResource);

   DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
   Fcb = vfatNewFCB(DeviceExt, &NameU);
   if (Fcb == NULL)
   {
      Status = STATUS_INSUFFICIENT_RESOURCES;
      goto ByeBye;
   }
   Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
   if (Ccb == NULL)
   {
      Status =  STATUS_INSUFFICIENT_RESOURCES;
      goto ByeBye;
   }

   RtlZeroMemory(Ccb, sizeof (VFATCCB));
   DeviceExt->FATFileObject->FsContext = Fcb;
   DeviceExt->FATFileObject->FsContext2 = Ccb;
   DeviceExt->FATFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
   DeviceExt->FATFileObject->PrivateCacheMap = NULL;
   DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;
   Fcb->FileObject = DeviceExt->FATFileObject;

   Fcb->Flags |= FCB_IS_FAT;

   Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector;
   Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize;
   Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;

   CcInitializeCacheMap(DeviceExt->FATFileObject,
                        (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
                        TRUE,
                        &VfatGlobalData->CacheMgrCallbacks,
                        Fcb);

   DeviceExt->LastAvailableCluster = 2;
   ExInitializeResourceLite(&DeviceExt->FatResource);

   InitializeListHead(&DeviceExt->FcbListHead);

   VolumeFcb = vfatNewFCB(DeviceExt, &VolumeNameU);
   if (VolumeFcb == NULL)
   {
      Status = STATUS_INSUFFICIENT_RESOURCES;
      goto ByeBye;
   }
   VolumeFcb->Flags = FCB_IS_VOLUME;
   VolumeFcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.Sectors * DeviceExt->FatInfo.BytesPerSector;
   VolumeFcb->RFCB.ValidDataLength = VolumeFcb->RFCB.FileSize;
   VolumeFcb->RFCB.AllocationSize = VolumeFcb->RFCB.FileSize;
   DeviceExt->VolumeFcb = VolumeFcb;

   ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
   InsertHeadList(&VfatGlobalData->VolumeListHead, &DeviceExt->VolumeListEntry);
   ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);

   /* read serial number */
   DeviceObject->Vpb->SerialNumber = DeviceExt->FatInfo.VolumeID;

   /* read volume label */
   ReadVolumeLabel(DeviceExt,  DeviceObject->Vpb);

   /* read clean shutdown bit status */
   Status = GetNextCluster(DeviceExt, 1, &eocMark);
   if (NT_SUCCESS(Status))
   {
      if (eocMark & DeviceExt->CleanShutBitMask)
      {
         /* unset clean shutdown bit */
         eocMark &= ~DeviceExt->CleanShutBitMask;
         WriteCluster(DeviceExt, 1, eocMark);
         VolumeFcb->Flags |= VCB_CLEAR_DIRTY;
      }
   }
   VolumeFcb->Flags |= VCB_IS_DIRTY;

   FsRtlNotifyVolumeEvent(DeviceExt->FATFileObject, FSRTL_VOLUME_MOUNT);

   Status = STATUS_SUCCESS;
ByeBye:

  if (!NT_SUCCESS(Status))
  {
     // cleanup
     if (DeviceExt && DeviceExt->FATFileObject)
        ObDereferenceObject (DeviceExt->FATFileObject);
     if (Fcb)
        vfatDestroyFCB(Fcb);
     if (Ccb)
        vfatDestroyCCB(Ccb);
     if (DeviceObject)
       IoDeleteDevice(DeviceObject);
     if (VolumeFcb)
        vfatDestroyFCB(VolumeFcb);
  }
  return Status;
}
예제 #16
0
파일: IFSEA.C 프로젝트: OS2World/DRV-FAT32
USHORT usWriteEAS(PVOLINFO pVolInfo, ULONG ulDirCluster, PSZ pszFileName, PFEALIST pFEAL)
{
    ULONG ulCluster, ulNextCluster;
    PBYTE  pszEAName;
    PBYTE pWrite;
    USHORT rc;
    USHORT usClustersNeeded;
    DIRENTRY DirEntry;
    DIRENTRY DirNew;
    BOOL     fCritical;
    PFEA     pFea, pFeaEnd;

    if (pFEAL->cbList > MAX_EA_SIZE)
        return ERROR_EA_LIST_TOO_LONG;

    rc = GetEASName(pVolInfo, ulDirCluster, pszFileName, &pszEAName);
    if (rc)
        return rc;

    usClustersNeeded = (USHORT)pFEAL->cbList / pVolInfo->usClusterSize;
    if (pFEAL->cbList % pVolInfo->usClusterSize)
        usClustersNeeded++;

    ulCluster = FindPathCluster(pVolInfo, ulDirCluster, pszEAName, &DirEntry, NULL);
    if (!ulCluster || ulCluster == FAT_EOF)
    {
        BOOL fNew = FALSE;

        if (ulCluster == FAT_EOF)
        {
            fNew = TRUE;
            memset(&DirNew, 0, sizeof DirNew);
            DirNew.bAttr  = FILE_HIDDEN | FILE_SYSTEM | FILE_READONLY;
            DirNew.ulFileSize = pFEAL->cbList;
        }
        else
            memcpy(&DirNew, &DirEntry, sizeof DirEntry);

        ulCluster = MakeFatChain(pVolInfo, FAT_EOF, (ULONG)usClustersNeeded, NULL);
        if (ulCluster == FAT_EOF)
        {
            free(pszEAName);
            return ERROR_DISK_FULL;
        }

        DirNew.wCluster = LOUSHORT(ulCluster);
        DirNew.wClusterHigh = HIUSHORT(ulCluster);

        if (fNew)
            rc = MakeDirEntry(pVolInfo, ulDirCluster, &DirNew, pszEAName);
        else
            rc = ModifyDirectory(pVolInfo, ulDirCluster,
                                 MODIFY_DIR_UPDATE, &DirEntry, &DirNew, NULL, 0);
        if (rc)
        {
            free(pszEAName);
            return rc;
        }
    }
    else
    {
        memcpy(&DirNew, &DirEntry, sizeof (DIRENTRY));
        DirNew.ulFileSize = pFEAL->cbList;
        rc = ModifyDirectory(pVolInfo, ulDirCluster, MODIFY_DIR_UPDATE,
                             &DirEntry, &DirNew, NULL, 0);
        if (rc)
        {
            free(pszEAName);
            return rc;
        }
    }

    free(pszEAName);

    pWrite = (PBYTE)pFEAL;
    ulNextCluster = FAT_EOF;
    while (usClustersNeeded)
    {
        ulNextCluster = GetNextCluster(pVolInfo, ulCluster);
        if (!ulNextCluster)
            ulNextCluster = FAT_EOF;
        rc = WriteCluster(pVolInfo, ulCluster, pWrite, 0);
        if (rc)
            return rc;
        usClustersNeeded --;
        pWrite += pVolInfo->usClusterSize;

        if (usClustersNeeded)
        {
            if (ulNextCluster == FAT_EOF)
                ulCluster = MakeFatChain(pVolInfo, ulCluster, (ULONG)usClustersNeeded, NULL);
            else
                ulCluster = ulNextCluster;
            if (ulCluster == FAT_EOF)
                return ERROR_DISK_FULL;
        }
    }
    if (ulNextCluster != FAT_EOF)
    {
        SetNextCluster(pVolInfo, ulCluster, FAT_EOF);
        DeleteFatChain(pVolInfo, ulNextCluster);
    }

    pFea = pFEAL->list;
    pFeaEnd = (PFEA)((PBYTE)pFEAL + pFEAL->cbList);
    fCritical = FALSE;
    while (pFea < pFeaEnd)
    {
        if (pFea->fEA & FEA_NEEDEA)
            fCritical = TRUE;
        pFea = (PFEA)((PBYTE)pFea + sizeof (FEA) + (USHORT)pFea->cbName + 1 + pFea->cbValue);
    }


    if (fCritical)
        rc = MarkFileEAS(pVolInfo, ulDirCluster, pszFileName, FILE_HAS_CRITICAL_EAS);
    else
        rc = MarkFileEAS(pVolInfo, ulDirCluster, pszFileName, FILE_HAS_EAS);

    return rc;
}
예제 #17
0
//Find one empty short directory entry in a cluster chain start from dwStartCluster,
//and save the short entry pointed by pfse into this entry.If can not find a free one
//in the whole cluster chain,then append a free cluster in the chain and save it.
BOOL CreateDirEntry(__FAT32_FS* pFat32Fs,DWORD dwStartCluster,__FAT32_SHORTENTRY* pDirEntry)
{
	__FAT32_SHORTENTRY     DirEntry;
	__FAT32_SHORTENTRY*    pfse       = NULL;
	DWORD                  dwSector   = 0;
	DWORD                  dwCurrCluster = 0;
	DWORD                  dwNextCluster = 0;
	BYTE*                  pBuffer       = NULL;
	CHAR                   DirName[13]   = {0};
	DWORD                  i;
	BOOL                   bFind      = FALSE;
	BOOL                   bResult    = FALSE;

	if((NULL == pFat32Fs) || (dwStartCluster < 2) || IS_EOC(dwStartCluster) || (NULL == pDirEntry))
	{
		goto __TERMINAL;
	}
	if(!ConvertName(pDirEntry,(BYTE*)&DirName[0]))
	{
		goto __TERMINAL;
	}
	//Check if the directory to be created has already in directory.
	if(GetShortEntry(pFat32Fs,dwStartCluster,DirName,&DirEntry,NULL,NULL))  //Directory already exists.
	{
		goto __TERMINAL;
	}
	pBuffer = (BYTE*)LocalAlloc(LPTR,pFat32Fs->dwClusterSize);
	if(NULL == pBuffer)
	{
		goto __TERMINAL;
	}
	//Try to find a free directory entry in the given directory,if can not find,then
	//allocate a free cluster,append it to the given directory.
	dwNextCluster = dwStartCluster;
	while(!IS_EOC(dwNextCluster))
	{
		dwCurrCluster = dwNextCluster;
		dwSector = GetClusterSector(pFat32Fs,dwCurrCluster);
		if(0 == dwSector)
		{
			//PrintLine("  In CreateDirEntry,Condition 2");
			goto __TERMINAL;
		}
		if(!ReadDeviceSector(pFat32Fs->pPartition,pFat32Fs->dwPartitionSatrt+dwSector, pFat32Fs->SectorPerClus,pBuffer))
		{			//PrintLine("  In CreateDirEntry,Condition 3");
			goto __TERMINAL;
		}
		//Search this cluster from begin.
		pfse = (__FAT32_SHORTENTRY*)pBuffer;
		for(i = 0;i < pFat32Fs->dwClusterSize / sizeof(__FAT32_SHORTENTRY);i++)
		{
			if((0 == pfse->FileName[0]) || (0xE5 == (BYTE)pfse->FileName[0]))  //Find a free slot.
			{
				bFind = TRUE;
				break;
			}
			pfse ++;
		}
		if(bFind) //Find a free directory entry,no need to check further.
		{
			break;
		}
		//Can not find a free directory slot,try to search next cluster.
		if(!GetNextCluster(pFat32Fs,&dwNextCluster))
		{
			//PrintLine("  In CreateDirEntry,Condition 4");
			goto __TERMINAL;
		}
	}

	if(bFind)  //Has found a free directory slot.
	{
		memcpy((char*)pfse,(const char*)pDirEntry,sizeof(__FAT32_SHORTENTRY));
		if(!WriteDeviceSector(pFat32Fs->pPartition,pFat32Fs->dwPartitionSatrt+dwSector,pFat32Fs->SectorPerClus,pBuffer))
		{			
			goto __TERMINAL;
		}
	}
	else       //Can not find a free slot,allocate a new cluster for parent directory.
	{
		if(!AppendClusterToChain(pFat32Fs,&dwCurrCluster))
		{			
			goto __TERMINAL;
		}
		ZeroMemory(pBuffer,pFat32Fs->dwClusterSize);
		memcpy((char*)pBuffer,(const char*)pDirEntry,sizeof(__FAT32_SHORTENTRY));
		dwSector = GetClusterSector(pFat32Fs,dwCurrCluster);
		if(!WriteDeviceSector(pFat32Fs->pPartition,pFat32Fs->dwPartitionSatrt+dwSector,pFat32Fs->SectorPerClus,pBuffer))
		{			
			goto __TERMINAL;
		}
	}

	bResult = TRUE;

__TERMINAL:
	if(pBuffer)
	{
		LocalFree(pBuffer);
	}

	return bResult;
}
예제 #18
0
파일: shutdown.c 프로젝트: RareHare/reactos
NTSTATUS NTAPI
VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
   NTSTATUS Status;
   PLIST_ENTRY ListEntry;
   PDEVICE_EXTENSION DeviceExt;
   ULONG eocMark;

   DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp);

   FsRtlEnterFileSystem();

   /* FIXME: block new mount requests */

   if (DeviceObject == VfatGlobalData->DeviceObject)
   {
      Irp->IoStatus.Status = STATUS_SUCCESS;
      ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
      ListEntry = VfatGlobalData->VolumeListHead.Flink;
      while (ListEntry != &VfatGlobalData->VolumeListHead)
      {
         DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry);
         ListEntry = ListEntry->Flink;

	 ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
         if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
         {
            /* set clean shutdown bit */
            Status = GetNextCluster(DeviceExt, 1, &eocMark);
            if (NT_SUCCESS(Status))
            {
               eocMark |= DeviceExt->CleanShutBitMask;
               if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark)))
                  DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
            }
         }
         Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
         if (NT_SUCCESS(Status))
         {
            Status = VfatDiskShutDown(DeviceExt);
            if (!NT_SUCCESS(Status))
	       DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
         }
         else
         {
	    DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
	 }
         ExReleaseResourceLite(&DeviceExt->DirResource);

         /* FIXME: Unmount the logical volume */

         if (!NT_SUCCESS(Status))
            Irp->IoStatus.Status = Status;
      }
      ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);

      /* FIXME: Free all global acquired resources */

      Status = Irp->IoStatus.Status;
   }
   else
   {
      Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
      Status = STATUS_INVALID_DEVICE_REQUEST;
   }

   Irp->IoStatus.Information = 0;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);

   FsRtlExitFileSystem();

   return(Status);
}
예제 #19
0
BOOL DumpDirectory(PDRIVEINFO pDrive, ULONG ulDirCluster, PSZ pszPath)
{
static BYTE szLongName[512];
int iIndex;
PDIRENTRY pDir;
PBYTE pbCluster;
PBYTE pbPath;
USHORT usClusters;
ULONG ulCluster;
ULONG ulBytesNeeded;
BYTE _huge * p;
PDIRENTRY pEnd;
BYTE bCheckSum, bCheck;
ULONG ulClustersNeeded;
ULONG ulClustersUsed;
ULONG ulEntries;
static BYTE szShortName[13];


   if (!ulDirCluster)
      {
      printf("ERROR: Cluster for %s is 0!\n", pszPath);
      return TRUE;
      }

   if (ulDirCluster == pDrive->bpb.RootDirStrtClus)
      {
      PULONG pulCluster;
      ReadFATSector(pDrive, 0);
      pulCluster = (PULONG)pDrive->pbFATSector;
      printf("MEDIA BYTES in FAT: %8.8lX\n",
         *pulCluster);

      pulCluster = (PULONG)pDrive->pbFATSector + 1;
      printf("DiskStatus: %8.8lX\n",
         *pulCluster);
//      vDumpSector(pDrive->pbFATSector);
      }

   //pDrive->ulTotalDirs++;

   pbPath = malloc(512);
   usClusters = GetClusterCount(pDrive, ulDirCluster);
   ulTotalClusters += usClusters;

   if (fDetailed > 2)
      printf("\n\nDirectory of %s (%u clusters)\n\n", pszPath, usClusters);

   ulBytesNeeded = (ULONG)pDrive->bpb.SectorsPerCluster * (ULONG)pDrive->bpb.BytesPerSector * usClusters;
   pbCluster = calloc(usClusters, pDrive->bpb.SectorsPerCluster * pDrive->bpb.BytesPerSector);
   if (!pbCluster)
      {
      printf("ERROR:Not enough memory!\n");
      return FALSE;
      }

   ulCluster = ulDirCluster;
   p = pbCluster;
   while (ulCluster != FAT_EOF)
      {
      ReadCluster(pDrive, ulCluster);
      memcpy(p, pDrive->pbCluster, pDrive->bpb.SectorsPerCluster * pDrive->bpb.BytesPerSector);
      ulCluster = GetNextCluster(pDrive, ulCluster);
      p += pDrive->bpb.SectorsPerCluster * pDrive->bpb.BytesPerSector;
      }

   memset(szLongName, 0, sizeof szLongName);
   pDir = (PDIRENTRY)pbCluster;
   pEnd = (PDIRENTRY)(pbCluster + ulBytesNeeded - sizeof (DIRENTRY));
   ulEntries = 0;
   bCheck = 0;
   while (pDir <= pEnd)
      {
      if (fDetailed > 3)
         {
         ULONG ulOffset = (PBYTE)pDir - pbCluster;
         if (ulOffset && !(ulOffset % 4096))
            printf("-------- NEXT CLUSTER ----------\n");
         }
      if (pDir->bFileName[0] && pDir->bFileName[0] != 0xE5)
         {
         if (pDir->bAttr == FILE_LONGNAME)
            {
            if (fDetailed > 3)
               {
               printf("(longname)\n");
               vDumpDirEntry(pDir);
               }
            if (strlen(szLongName) && bCheck != pDir->bReserved)
               {
               printf("A lost long filename was found: %s\n",
                  szLongName);
               memset(szLongName, 0, sizeof szLongName);
               }
            bCheck = pDir->bReserved;
            fGetLongName(pDir, szLongName, sizeof szLongName);
            }
         else 
            {
            bCheckSum = 0;
            for (iIndex = 0; iIndex < 11; iIndex++)
               {
               if (bCheckSum & 0x01)
                  {
                  bCheckSum >>=1;
                  bCheckSum |= 0x80;
                  }
               else
                  bCheckSum >>=1;
               bCheckSum += pDir->bFileName[iIndex];
               }
            if (strlen(szLongName) && bCheck != bCheckSum)
               {
               printf("The longname %s does not belong to %s\\%s\n",
                  szLongName, pszPath, MakeName(pDir, szShortName, sizeof szShortName));
               memset(szLongName, 0, sizeof szLongName);
               }

            if (fDetailed > 2)
               {
               printf("%-8.8s.%-3.3s %2.2X ",
                  pDir->bFileName,
                  pDir->bExtention,
                  pDir->bAttr);
               if (pDir->bAttr & FILE_DIRECTORY)
                  printf("<DIR>      ");
               else
                  printf("%10lu ", pDir->ulFileSize);

               printf("%8.8lX ", MAKEP(pDir->wClusterHigh, pDir->wCluster));
               if (pDir->fEAS)
                  printf("%2.2X ", pDir->fEAS);
               else
                  printf("   ");

               printf("%s\n", szLongName);
               }
            if (!(pDir->bAttr & FILE_DIRECTORY))
               {

               ulClustersNeeded = pDir->ulFileSize / pDrive->usClusterSize +
                  (pDir->ulFileSize % pDrive->usClusterSize ? 1:0);
               ulClustersUsed = GetClusterCount(pDrive,(ULONG)pDir->wClusterHigh * 0x10000 + pDir->wCluster);
               ulTotalClusters += ulClustersUsed;
               if (ulClustersNeeded != ulClustersUsed)
                  {
                  printf("File allocation error detected for %s\\%s\n",
                     pszPath, MakeName(pDir, szShortName, sizeof szShortName));
                  printf("%lu clusters needed, %lu clusters allocated\n",
                     ulClustersNeeded, ulClustersUsed);
                  }
               }
            memset(szLongName, 0, sizeof szLongName);
            }
         ulEntries++;
         }
예제 #20
0
DWORD WriteFileToVhd(__FAT32_FS*  pFat32Fs,__FAT32_FILE*   pFat32File,LPCSTR pSrcFile)
{
	__FAT32_SHORTENTRY*     pFat32Entry    = NULL;
	HANDLE                  hSrcFile       = NULL;	
	BYTE*                   pClusBuffer    = NULL;	
	BYTE*                   pStart         = NULL;
	DWORD                   dwCurrPos      = 0;
	DWORD                   dwSector       = 0;
	DWORD                   dwNextClus     = 0;
	DWORD                   dwWriteSize    = 0;
	DWORD                   dwFirstCluster = 0;	
	DWORD                   dwOnceSize     = 0;
	DWORD                   dwWritten      = 0;    //Record the written size.
	
	
	
	hSrcFile     = CreateFileA(pSrcFile,GENERIC_READ,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,OPEN_EXISTING,0,0);
	if(hSrcFile == INVALID_HANDLE_VALUE)
	{
		return S_OK;
	}
	dwWriteSize   = GetFileSize(hSrcFile,NULL);
	
	pClusBuffer  = (BYTE*)LocalAlloc(LPTR,pFat32Fs->dwClusterSize);
	if(NULL == pClusBuffer)  //Can not allocate buffer.
	{
		goto __TERMINAL;
	}

	dwCurrPos  = pFat32File->dwCurrPos;
	dwNextClus = pFat32File->dwCurrClusNum;

	//if file null,first alloc a Cluster
	if(dwNextClus == 0 && GetFreeCluster(pFat32Fs,0,&dwNextClus))
	{
		pFat32File->dwCurrClusNum  = dwNextClus;
		pFat32File->dwStartClusNum = dwNextClus;
		dwFirstCluster             = dwNextClus;
	}

	dwSector   = GetClusterSector(pFat32Fs,dwNextClus);		
	if(0 == dwSector)
	{		
		goto __TERMINAL;
	}
	//Read the current cluster.
	if(!ReadDeviceSector(pFat32Fs->pPartition,pFat32Fs->dwPartitionSatrt+ dwSector,pFat32Fs->SectorPerClus,	pClusBuffer))
	{
		goto __TERMINAL;
	}

	while(dwWriteSize > 0)
	{
		DWORD      dwRead = 0;
		pStart     = pClusBuffer + pFat32File->dwClusOffset;
		dwOnceSize = pFat32Fs->dwClusterSize - pFat32File->dwClusOffset;

		if(dwOnceSize > dwWriteSize)
		{
			dwOnceSize = dwWriteSize;
		}
		//memcpy(pStart,pBuffer,dwOnceSize);
		ReadFile(hSrcFile,pStart,dwOnceSize,&dwRead,NULL);

		//Now write the cluster into memory.
		if(!WriteDeviceSector(pFat32Fs->pPartition,pFat32Fs->dwPartitionSatrt+dwSector,pFat32Fs->SectorPerClus,pClusBuffer))
		{
			
			goto __TERMINAL;
		}

		//Adjust file object's status.
		pFat32File->dwClusOffset += dwOnceSize;
		pFat32File->dwCurrPos    += dwOnceSize;

		//2014.9.28 modified by tywind
		if(pFat32File->dwCurrPos >= pFat32File->dwFileSize)
		{
			pFat32File->dwFileSize = pFat32File->dwCurrPos;
		}

		if(0 == (pFat32File->dwClusOffset % pFat32Fs->dwClusterSize))
		{
			dwNextClus = pFat32File->dwCurrClusNum;
			if(!GetNextCluster(pFat32Fs,&dwNextClus))
			{				
				goto __TERMINAL;
			}
			if(IS_EOC(dwNextClus))  //Reach the end of file,so extend file.
			{
				if(!AppendClusterToChain(pFat32Fs,&pFat32File->dwCurrClusNum))
				{
					goto __TERMINAL;
				}
				dwNextClus = pFat32File->dwCurrClusNum;
			}
			pFat32File->dwCurrClusNum = dwNextClus;
			pFat32File->dwClusOffset  = 0;

			//Update dwSector to corespond current cluster.
			dwSector = GetClusterSector(pFat32Fs,dwNextClus);
			if(0 == dwSector)
			{				
				goto __TERMINAL;
			}
		}
		//Adjust the buffer position and local control variables.		
		dwWritten    += dwOnceSize;
		dwWriteSize  -= dwOnceSize;

		if(0 == dwWriteSize)  //Write over.
		{
			break;
		}
	}
	//Now update the file's directory entry.
	dwSector = GetClusterSector(pFat32Fs,pFat32File->dwParentClus);
	if(0 == dwSector)
	{		
		goto __TERMINAL;
	}

	if(!ReadDeviceSector(pFat32Fs->pPartition,pFat32Fs->dwPartitionSatrt+dwSector,pFat32Fs->SectorPerClus,pClusBuffer))
	{
		goto __TERMINAL;
	}

	pFat32Entry = (__FAT32_SHORTENTRY*)(pClusBuffer + pFat32File->dwParentOffset);

	//modify file First Cluster index 
	if(dwFirstCluster > 0 )
	{
		pFat32Entry->wFirstClusHi   = (WORD)(dwFirstCluster >> 16);
		pFat32Entry->wFirstClusLow  = (WORD)(dwFirstCluster&0x0000FFFF);
	}
예제 #21
0
//Find one empty short directory entry in a cluster chain start from dwStartCluster,
//and save the short entry pointed by pfse into this entry.If can not find a free one
//in the whole cluster chain,then append a free cluster in the chain and save it.
BOOL CreateDirEntry(__FAT32_FS* pFat32Fs,DWORD dwStartCluster,__FAT32_SHORTENTRY* pDirEntry)
{
	__FAT32_SHORTENTRY     DirEntry;
	__FAT32_SHORTENTRY*    pfse       = NULL;
	DWORD                  dwSector   = 0;
	DWORD                  dwCurrCluster = 0;
	DWORD                  dwNextCluster = 0;
	BYTE*                  pBuffer       = NULL;
	CHAR                   DirName[13]   = {0};
	DWORD                  i;
	BOOL                   bFind      = FALSE;
	BOOL                   bResult    = FALSE;

	if((NULL == pFat32Fs) || (dwStartCluster < 2) || IS_EOC(dwStartCluster) || (NULL == pDirEntry))
	{
		PrintLine("  In CreateDirEntry,Condition 0");
		goto __TERMINAL;
	}
	if(!ConvertName(pDirEntry,(BYTE*)&DirName[0]))
	{
		PrintLine("  In CreateDirEntry,Condition 1");
		goto __TERMINAL;
	}
	//Check if the directory to be created has already in directory.
	if(GetShortEntry(pFat32Fs,dwStartCluster,DirName,&DirEntry,NULL,NULL))  //Directory already exists.
	{
		PrintLine("  In CreateDirEntry: The specified directory already exist.");
		goto __TERMINAL;
	}
	pBuffer = (BYTE*)KMemAlloc(pFat32Fs->dwClusterSize,KMEM_SIZE_TYPE_ANY);
	if(NULL == pBuffer)
	{
		PrintLine("  In CreateDirEntry,can not allocate memory for temporary buffer.");
		goto __TERMINAL;
	}
	//Try to find a free directory entry in the given directory,if can not find,then
	//allocate a free cluster,append it to the given directory.
	dwNextCluster = dwStartCluster;
	while(!IS_EOC(dwNextCluster))
	{
		dwCurrCluster = dwNextCluster;
		dwSector = GetClusterSector(pFat32Fs,dwCurrCluster);
		if(0 == dwSector)
		{
			PrintLine("  In CreateDirEntry,Condition 2");
			goto __TERMINAL;
		}
		if(!ReadDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition,
			dwSector,
			pFat32Fs->SectorPerClus,
			pBuffer))
		{
			PrintLine("  In CreateDirEntry,Condition 3");
			goto __TERMINAL;
		}
		//Search this cluster from begin.
		pfse = (__FAT32_SHORTENTRY*)pBuffer;
		for(i = 0;i < pFat32Fs->dwClusterSize / sizeof(__FAT32_SHORTENTRY);i++)
		{
			if((0 == pfse->FileName[0]) || ((BYTE)0xE5 == pfse->FileName[0]))  //Find a free slot.
			{
				bFind = TRUE;
				break;
			}
			pfse ++;
		}
		if(bFind) //Find a free directory entry,no need to check further.
		{
			break;
		}
		//Can not find a free directory slot,try to search next cluster.
		if(!GetNextCluster(pFat32Fs,&dwNextCluster))
		{
			PrintLine("  In CreateDirEntry,Condition 4");
			goto __TERMINAL;
		}
	}
	if(bFind)  //Has found a free directory slot.
	{
		memcpy((char*)pfse,(const char*)pDirEntry,sizeof(__FAT32_SHORTENTRY));
		if(!WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition,
			dwSector,
			pFat32Fs->SectorPerClus,
			pBuffer))
		{
			PrintLine("  In CreateDirEntry,Condition 5");
			goto __TERMINAL;
		}
	}
	else       //Can not find a free slot,allocate a new cluster for parent directory.
	{
		if(!AppendClusterToChain(pFat32Fs,&dwCurrCluster))
		{
			PrintLine("  In CreateDirEntry: Can not append a free cluster to this dir.");
			goto __TERMINAL;
		}
		memzero(pBuffer,pFat32Fs->dwClusterSize);
		memcpy((char*)pBuffer,(const char*)pDirEntry,sizeof(__FAT32_SHORTENTRY));
		dwSector = GetClusterSector(pFat32Fs,dwCurrCluster);
		if(!WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition,
			dwSector,
			pFat32Fs->SectorPerClus,
			pBuffer))
		{
			PrintLine("  In CreateDirEntry,Condition 6");
			goto __TERMINAL;
		}
	}
	/*
	_hx_sprintf(pBuffer,"In CreateDirEntry: dwSector = %d,dwCurrCluster = %d,offset = %d",
		dwSector,
		dwCurrCluster,
		(BYTE*)pfse - pBuffer);
	PrintLine(pBuffer);*/

	bResult = TRUE;
__TERMINAL:
	if(pBuffer)
	{
		KMemFree(pBuffer,KMEM_SIZE_TYPE_ANY,0);
	}
	return bResult;
}
예제 #22
0
BOOL GetShortEntry(__FAT32_FS* pFat32Fs,DWORD dwStartCluster,CHAR* pFileName,__FAT32_SHORTENTRY* pShortEntry, DWORD* pDirClus,DWORD* pDirOffset)
{
	BOOL                bResult      = FALSE;
	__FAT32_SHORTENTRY* pfse         = NULL;
	BYTE*               pBuffer      = NULL;
	DWORD               dwCurrClus   = 0;
	DWORD               dwSector     = 0;
	BYTE                FileName[13];
	int                 i;

	if((NULL == pFat32Fs) || (NULL == pFileName) || (pShortEntry == pfse))
	{
		goto __TERMINAL;
	}
	//Create local buffer to contain one cluster.
	pBuffer = (BYTE*)LocalAlloc(LPTR,pFat32Fs->SectorPerClus * pFat32Fs->dwBytePerSector);
	if(NULL == pBuffer)
	{
		
		goto __TERMINAL;
	}
	dwCurrClus = dwStartCluster;
	while(!IS_EOC(dwCurrClus))  //Main loop to check the root directory.
	{
		dwSector = GetClusterSector(pFat32Fs,dwCurrClus);
		if(0 == dwSector)  //Fatal error.
		{
			//PrintLine("  In GetShortEntry: Can not get cluster sector.");
			goto __TERMINAL;
		}
		if(!ReadDeviceSector(pFat32Fs->pPartition,
			pFat32Fs->dwPartitionSatrt+dwSector,
			pFat32Fs->SectorPerClus,
			pBuffer))  //Can not read the appropriate sector(s).
		{
			//PrintLine("  In GetShortEntry: Can not read sector from device.");
			goto __TERMINAL;
		}
		//Now check the root directory to seek the volume ID entry.
		pfse = (__FAT32_SHORTENTRY*)pBuffer;
		for(i = 0;i < pFat32Fs->SectorPerClus * 16;i ++)
		{
			if(0xE5 == (BYTE)pfse->FileName[0])  //Empty entry.
			{
				pfse += 1;  //Seek to the next entry.
				continue;
			}
			if(0 == pfse->FileName[0])     //All rest part is zero,no need to check futher.
			{
				break;
			}
			if(FILE_ATTR_LONGNAME == pfse->FileAttributes)  //Long file name entry.
			{
				pfse += 1;
				continue;
			}
			if(FILE_ATTR_VOLUMEID & pfse->FileAttributes)   //Volume label entry.
			{
				pfse += 1;
				continue;
			}
			if(ConvertName(pfse,FileName))  //Can not convert to regular file name string.
			{
				if(strcmpi((CHAR*)pFileName,(CHAR*)&FileName[0]) == 0)  //Found.
				{
					memcpy((char*)pShortEntry,(const char*)pfse,sizeof(__FAT32_SHORTENTRY));
					if(pDirClus)
					{
						*pDirClus = dwCurrClus;
					}
					if(pDirOffset)
					{
						*pDirOffset = (BYTE*)pfse - pBuffer;
					}
					bResult = TRUE;
					goto __TERMINAL;
				}
			}
			pfse += 1;
		}
		if(!GetNextCluster(pFat32Fs,&dwCurrClus))
		{
			break;
		}
	}
__TERMINAL:
	if(pBuffer)
	{
		LocalFree(pBuffer);
	}

	return bResult;
}
예제 #23
0
파일: fsctl.c 프로젝트: RPG-7/reactos
static
NTSTATUS
VfatDismountVolume(
    PVFAT_IRP_CONTEXT IrpContext)
{
    PDEVICE_EXTENSION DeviceExt;
    PLIST_ENTRY NextEntry;
    PVFATFCB Fcb;
    PFILE_OBJECT FileObject;
    ULONG eocMark;
    NTSTATUS Status;

    DPRINT("VfatDismountVolume(%p)\n", IrpContext);

    DeviceExt = IrpContext->DeviceExt;
    FileObject = IrpContext->FileObject;

    /* We HAVE to be locked. Windows also allows dismount with no lock
     * but we're here mainly for 1st stage, so KISS
     */
    if (!(DeviceExt->Flags & VCB_VOLUME_LOCKED))
    {
        return STATUS_ACCESS_DENIED;
    }

    /* Race condition? */
    if (DeviceExt->Flags & VCB_DISMOUNT_PENDING)
    {
        return STATUS_VOLUME_DISMOUNTED;
    }

    /* Notify we'll dismount. Pass that point there's no reason we fail */
    FsRtlNotifyVolumeEvent(IrpContext->Stack->FileObject, FSRTL_VOLUME_DISMOUNT);

    ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);

    if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
    {
        /* Set clean shutdown bit */
        Status = GetNextCluster(DeviceExt, 1, &eocMark);
        if (NT_SUCCESS(Status))
        {
            eocMark |= DeviceExt->CleanShutBitMask;
            if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark)))
                DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
        }
    }

    /* Flush volume & files */
    VfatFlushVolume(DeviceExt, (PVFATFCB)FileObject->FsContext);

    /* Rebrowse the FCB in order to free them now */
    while (!IsListEmpty(&DeviceExt->FcbListHead))
    {
        NextEntry = RemoveHeadList(&DeviceExt->FcbListHead);
        Fcb = CONTAINING_RECORD(NextEntry, VFATFCB, FcbListEntry);
        vfatDestroyFCB(Fcb);
    }

    /* Mark we're being dismounted */
    DeviceExt->Flags |= VCB_DISMOUNT_PENDING;
#ifndef ENABLE_SWAPOUT
    IrpContext->DeviceObject->Vpb->Flags &= ~VPB_MOUNTED;
#endif

    ExReleaseResourceLite(&DeviceExt->FatResource);

    /* Release a few resources and quit, we're done */
    ExDeleteResourceLite(&DeviceExt->DirResource);
    ExDeleteResourceLite(&DeviceExt->FatResource);
    ObDereferenceObject(DeviceExt->FATFileObject);

    return STATUS_SUCCESS;
}