/** 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()); }
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; }