/**
Format a disk section, called iteratively to erase whole of media, on last iteration
creates an empty volume. If called with quick formatonly erases the Fat leaving the
rest of the volume intact.

@leave System wide error code
*/
void CFatFormatCB::DoFormatStepL()
	{
	if (iFormatInfo.iFormatIsCurrent==EFalse)
		{ // Only done first time through
		if (iMode & EForceErase)
			{
			TInt r = FatMount().ErasePassword();
			User::LeaveIfError(r);
			// CFatMountCB::ErasePassword() calls TBusLocalDrive::ForceRemount(),
			// so need to stop a remount from occurring in next call to :
			// TFsFormatNext::DoRequestL((), TDrive::CheckMount().
			FatMount().Drive().SetChanged(EFalse);
			}

        RecordOldInfoL();
		InitializeFormatDataL();
		FatMount().DoDismount();
		if (iVariableSize)
			FatMount().ReduceSizeL(0,I64LOW(FatMount().iSize));
		}
    //
    // Blank disk if not EQuickFormat
    //
	if (!iVariableSize && !(iMode & EQuickFormat) && iCurrentStep)
		{
		if (iFormatInfo.iFormatIsCurrent == EFalse)
			{//-- firstly invalidate sectors 0-6 inclusive, they may contain main boot sector, backup boot sector and FSInfo sector.
	        DoZeroFillMediaL(0, (KBkBootSectorNum+1)*iBytesPerSector);
            }
		TInt ret=FatMount().LocalDrive()->Format(iFormatInfo);
		if (ret!=KErrNone && ret!=KErrEof) // Handle format error
            ret = HandleCorrupt(ret);

        if (ret!=KErrNone && ret!=KErrEof) // KErrEof could be set by LocalDrive()->Format()
		    User::Leave(ret);

		if (ret==KErrNone)
			{
			iCurrentStep = I64LOW( 100 - (100 * TInt64(iFormatInfo.i512ByteSectorsFormatted)) / iMaxDiskSectors );
			if (iCurrentStep<=0)
				iCurrentStep=1;
			return;
			}
		}

	// ReMount since MBR may have been rewritten and partition may have moved / changed size
	TInt ret = LocalDrive()->ForceRemount(0);
	if (ret != KErrNone && ret != KErrNotSupported)
		User::Leave(ret);

	// MBR may have changed, so need to re-read iHiddenSectors etc.before BPB is written
	InitializeFormatDataL();

    // Translate bad sector number to cluster number which contains that sector
    // This only happens in full format, in quick format they are already cluster numbers
    if (!iVariableSize && !(iMode & EQuickFormat))
        User::LeaveIfError(BadSectorToCluster());

	//Check if root cluster is bad and update as required
	if(Is32BitFat() && !iVariableSize && (iMode & EQuickFormat))
		{
		if(iBadClusters.Find(iRootClusterNum) !=  KErrNotFound)
			{
			iRootClusterNum++;
            while(iBadClusters.Find(iRootClusterNum) != KErrNotFound)
				{
				iRootClusterNum++;
				}
			}
		}

    //
    // Do the rest of the disk in one lump
    //
	iCurrentStep=0;

    //-- zero-fill media from position 0 to the FAT end, i.e main & backup boot sector, FSInfo and its copy and all FATs
    const TUint32 posFatEnd = ((iSectorsPerFat*iNumberOfFats) + iReservedSectors) * iBytesPerSector; //-- last FAT end position
	
    if (iVariableSize)
		FatMount().EnlargeL(posFatEnd); 

    DoZeroFillMediaL(0, posFatEnd);
    
    if(Is32BitFat())
		{//create an empty root directory entry here
		
        const TUint KFat32EntrySz = 4; //-- FAT32 entry size, bytes
        const TInt  startFAT1   = iReservedSectors;              //-- FAT1 start sector
        const TInt  entryOffset = iRootClusterNum*KFat32EntrySz; //-- Root dir entry offset in the FAT, bytes

		TBuf8<KFat32EntrySz> EOF(KFat32EntrySz);
		EOF[0]=0xFF;		
		EOF[1]=0xFF;
		EOF[2]=0xFF;
		EOF[3]=0x0F;

        //-- write EOF mark to the every FAT copy
    	for(TInt i=0; i<iNumberOfFats; i++)
            {
		    const TInt rootDirEntryPos = iBytesPerSector*(startFAT1 + i*iSectorsPerFat) + entryOffset;
            User::LeaveIfError(LocalDrive()->Write(rootDirEntryPos, EOF));
            }

        //-- zero-fill FAT32 root directory (just 1 cluster)
		const TInt firstDataSector = iReservedSectors + (iNumberOfFats * iSectorsPerFat); //+RootDirSectors (not required for fat32)
        const TInt firstSectorOfCluster = ((iRootClusterNum - KFatFirstSearchCluster) * iSectorsPerCluster) + firstDataSector;
	
        const TUint32 posRootDirStart = firstSectorOfCluster * iBytesPerSector;
        const TUint32 posRootDirEnd = posRootDirStart + iSectorsPerCluster*iBytesPerSector;

        DoZeroFillMediaL(posRootDirStart, posRootDirEnd);
        }
	else
		{//-- FAT12/16
		    //-- Zero fill root directory
            const TInt rootDirSector = iReservedSectors + (iNumberOfFats * iSectorsPerFat); 
            const TInt rootDirSize   = iRootDirEntries * KSizeOfFatDirEntry; //-- size in bytes
            
            const TUint32 posRootDirStart = rootDirSector * iBytesPerSector;
            const TUint32 posRootDirEnd   = posRootDirStart + rootDirSize;

            const TInt numOfRootSectors=(rootDirSize%iBytesPerSector) ? (rootDirSize/iBytesPerSector+1) : (rootDirSize/iBytesPerSector);
		    if (iVariableSize)
			    FatMount().EnlargeL(iBytesPerSector*numOfRootSectors);

            DoZeroFillMediaL(posRootDirStart, posRootDirEnd);

		// Enlarge ram drive to take into account rounding of
		// data start to cluster boundary
		if(iVariableSize && iSectorsPerCluster!=1)
			{
			const TInt firstFreeSector=rootDirSector+numOfRootSectors;
			const TInt firstFreeCluster=firstFreeSector%iSectorsPerCluster ? firstFreeSector/iSectorsPerCluster+1 : firstFreeSector/iSectorsPerCluster;
			const TInt alignedSector=firstFreeCluster*iSectorsPerCluster;
			if(alignedSector!=firstFreeSector)
				FatMount().EnlargeL((alignedSector-firstFreeSector)*iBytesPerSector);
			}
		}

    //-- FAT[0] must contain media descriptor in the low byte, FAT[1] for fat16/32 may contain some flags
	TBuf8<8> startFat(8);
    startFat.Fill(0xFF);
   
    if(Is32BitFat()) //-- FAT32
        {//-- FAT32 uses only low 28 bits in FAT entry. 
        startFat[3] = 0x0F;
        startFat[7] = 0x0F;
        } 
    else if(iVariableSize||Is16BitFat()) //-- FAT16 or RAM drive which is always FAT16
        {
        startFat.SetLength(4);
        }
    else //-- FAT12
        {
        startFat.SetLength(3);
        }

    startFat[0]=KBootSectorMediaDescriptor;

    //-- write FAT[0] and FAT[1] entries to all copies of FAT
	for(TInt i=0;i<iNumberOfFats;i++)
        {
		User::LeaveIfError(LocalDrive()->Write(iBytesPerSector*(iReservedSectors+(iSectorsPerFat*i)),startFat));
        }

	//-- create boot sectors
    CreateBootSectorL();

    //-- create FSInfo sectors
    if (Is32BitFat())
		{
		CreateReservedBootSectorL();
        CreateFSInfoSectorL();
		}

    //-- here we have bad clusters numbers saved by the quick format
    //-- Interpret old bad cluster number to new cluster number and mark new bad clusters
    if (!iVariableSize && iBadClusters.Count()>0)
        {
 	
        //-- Here we need fully mounted volume, so mount it normally.
	    FatMount().MountL(EFalse);

        iBadClusters.Sort();
        TranslateL();
        const TInt mark = FatMount().Is32BitFat() ? KBad_32Bit : (FatMount().Is16BitFat() ? KBad_16Bit : KBad_12Bit);
        
        for (TInt i=0; i<iBadClusters.Count(); ++i)
            FatMount().FAT().WriteL(iBadClusters[i], mark);
        
        FatMount().FAT().FlushL();
        
        //-- indicate that the volume is "dirty" in order to the next Mount evend not to use FSInfo, which
        //-- contains incorrect value of free clusters because we already have bad ones saved.  
        //-- This is a very rare condition.
        FatMount().SetVolumeCleanL(EFalse); 

#if defined(_DEBUG)
	TInt r=FatMount().CheckDisk();
	__PRINT1(_L("CFatFormatCB::DoFormatStepL() CheckDisk res: %d"),r);
#endif
        }
        else
        {
        //-- We do not need to perform full mount in this case, the TDrive object will be marked as changed in ~CFormatCB and the
        //-- mount will be closed. Therefore on the first access to it it will be mounted normally.
        FatMount().MountL(ETrue); //-- force mount
        }

    __PRINT1(_L("CFatFormatCB::DoFormatStepL() Format complete drv:%d"), DriveNumber());
	}
Exemple #2
0
static IDCOffer_clp UnixLoginMod_New_m (
    UnixLoginMod_cl     *self,
    IDCOffer_clp    fs      /* IN */,
    string_t        passwd  /* IN */,
    string_t        group   /* IN */ )
{
    UnixLoginMod_st     *lst;
    Login_st        *st;
    FSClient_clp     fsclient;
    Type_Any         any, *dirany;
    FSTypes_RC       rc;
    FSDir_clp        dir;
    FileIO_clp       fileio;
    Rd_clp           rd;
    FSUtil_clp       fsutil;
    StringTblMod_clp strtbl;
    IDCTransport_clp shmt;
    IDCOffer_clp     offer;
    IDCService_clp   service;
    char buff[124];

    TRC(printf("UnixLoginMod_New_m(%p, %s, %s)\n",fs,passwd,group));

    fsutil=NAME_FIND("modules>FSUtil", FSUtil_clp);
    strtbl=NAME_FIND("modules>StringTblMod", StringTblMod_clp);
    shmt=NAME_FIND("modules>ShmTransport", IDCTransport_clp);

    lst=Heap$Malloc(Pvs(heap), sizeof(*lst));
    lst->heap=Pvs(heap);

    /* Bind to security service */
    TRC(printf(" + binding to security service\n"));
    lst->sec=IDC_OPEN("sys>SecurityOffer", Security_clp);

    /* Bind to FS */
    TRC(printf(" + binding to filesystem\n"));
    fsclient=IDC_BIND(fs, FSClient_clp);
    
    rc=FSClient$GetDir(fsclient, "", True, &dirany);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't get directory\n");
	FREE(lst);
	return NULL;
    }

    dir=NARROW(dirany, FSDir_clp);
    FREE(dirany);

    /* Create tables */
    TRC(printf(" + creating tables\n"));
    lst->users=StringTblMod$New(strtbl, lst->heap);
    lst->groups=StringTblMod$New(strtbl, lst->heap);
    lst->certificate_tbl=StringTblMod$New(strtbl, lst->heap);
    lst->certificate_id = 1;

    /* Read in passwd file */
    TRC(printf(" + reading password file\n"));
    rc=FSDir$Lookup(dir, passwd, True);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't lookup passwd file\n");
	FREE(lst);
	return NULL;
    }

    rc=FSDir$Open(dir, 0, FSTypes_Mode_Read, 0, &fileio);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't open passwd file\n");
	FREE(lst);
	return NULL;
    }

    rd=FSUtil$GetRd(fsutil, fileio, lst->heap, True);
    
    while (!Rd$EOF(rd))
    {
	uint32_t l;
	l=Rd$GetLine(rd, buff, 120);
	buff[l]=0;
	/* TRC(printf("->%s\n",buff)); */
	add_passwd_line(lst, buff);
    }

    Rd$Close(rd);

    /* Read in group file */
    TRC(printf(" + reading group file\n"));
    rc=FSDir$Lookup(dir, group, True);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't lookup group file\n");
	FREE(lst);
	return NULL;
    }

    rc=FSDir$Open(dir, 0, FSTypes_Mode_Read, 0, &fileio);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't open group file\n");
	FREE(lst);
	return NULL;
    }

    rd=FSUtil$GetRd(fsutil, fileio, lst->heap, True);

    while (!Rd$EOF(rd))
    {
	uint32_t l;
	l=Rd$GetLine(rd, buff, 120);
	buff[l]=0;
	/* TRC(printf("=>%s\n",buff)); */
	add_group_line(lst, buff);
    }

    Rd$Close(rd);

    /* We don't need the filesystem any more */
    FSDir$Close(dir);

    LINK_INITIALISE(&lst->certificate_list);

    MU_INIT(&lst->mu);

    /* Closure for local access to the server */

    st=Heap$Malloc(lst->heap, sizeof(*st));
    CL_INIT(st->cl, &login_ms, st);
    st->id=VP$DomainID(Pvs(vp));
    st->lst=lst;

    /* Export */
    TRC(printf(" + exporting Login service\n"));
    ANY_INIT(&any, Login_clp, &st->cl);
    CL_INIT(lst->callback, &callback_ms, lst);
    offer=IDCTransport$Offer(shmt, &any, &lst->callback, lst->heap,
			     Pvs(gkpr), Pvs(entry), &service);

    return offer;
}