12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139 |
- #include "ff.h"
- #include "diskio.h"
- #if _FATFS != 4004
- #error Wrong include file (ff.h).
- #endif
- #if _MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096
- #error Wrong sector size.
- #endif
- #if _MAX_SS != 512
- #define SS(fs) ((fs)->ssize)
- #else
- #define SS(fs) 512U
- #endif
- #if _FS_REENTRANT
- #if _USE_LFN == 1
- #error Static LFN work area must not be used in re-entrant configuration.
- #endif
- #define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; }
- #define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; }
- #else
- #define ENTER_FF(fs)
- #define LEAVE_FF(fs, res) return res
- #endif
- #define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); }
- #if _FS_LOCK
- #if _FS_READONLY
- #error _FS_LOCK must be 0 on read-only cfg.
- #endif
- typedef struct {
- FATFS *fs;
- DWORD clu;
- WORD idx;
- WORD ctr;
- } FILESEM;
- #endif
- #if _CODE_PAGE == 932
- #define _DF1S 0x81
- #define _DF1E 0x9F
- #define _DF2S 0xE0
- #define _DF2E 0xFC
- #define _DS1S 0x40
- #define _DS1E 0x7E
- #define _DS2S 0x80
- #define _DS2E 0xFC
- #elif _CODE_PAGE == 936
- #define _DF1S 0x81
- #define _DF1E 0xFE
- #define _DS1S 0x40
- #define _DS1E 0x7E
- #define _DS2S 0x80
- #define _DS2E 0xFE
- #elif _CODE_PAGE == 949
- #define _DF1S 0x81
- #define _DF1E 0xFE
- #define _DS1S 0x41
- #define _DS1E 0x5A
- #define _DS2S 0x61
- #define _DS2E 0x7A
- #define _DS3S 0x81
- #define _DS3E 0xFE
- #elif _CODE_PAGE == 950
- #define _DF1S 0x81
- #define _DF1E 0xFE
- #define _DS1S 0x40
- #define _DS1E 0x7E
- #define _DS2S 0xA1
- #define _DS2E 0xFE
- #elif _CODE_PAGE == 437
- #define _DF1S 0
- #define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 720
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 737
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
- 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 775
- #define _DF1S 0
- #define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 850
- #define _DF1S 0
- #define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
- 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 852
- #define _DF1S 0
- #define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
- 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
- #elif _CODE_PAGE == 855
- #define _DF1S 0
- #define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
- 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
- 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 857
- #define _DF1S 0
- #define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
- 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 858
- #define _DF1S 0
- #define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
- 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 862
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 866
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 874
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 1250
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
- #elif _CODE_PAGE == 1251
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
- 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
- #elif _CODE_PAGE == 1252
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
- 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
- #elif _CODE_PAGE == 1253
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
- 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
- #elif _CODE_PAGE == 1254
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
- 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
- #elif _CODE_PAGE == 1255
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 1256
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
- #elif _CODE_PAGE == 1257
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
- #elif _CODE_PAGE == 1258
- #define _DF1S 0
- #define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
- 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
- #elif _CODE_PAGE == 1
- #if _USE_LFN
- #error Cannot use LFN feature without valid code page.
- #endif
- #define _DF1S 0
- #else
- #error Unknown code page
- #endif
- #define IsUpper(c) (((c)>='A')&&((c)<='Z'))
- #define IsLower(c) (((c)>='a')&&((c)<='z'))
- #define IsDigit(c) (((c)>='0')&&((c)<='9'))
- #if _DF1S
- #ifdef _DF2S
- #define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
- #else
- #define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
- #endif
- #ifdef _DS3S
- #define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
- #else
- #define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
- #endif
- #else
- #define IsDBCS1(c) 0
- #define IsDBCS2(c) 0
- #endif
- #define NS 11
- #define NS_LOSS 0x01
- #define NS_LFN 0x02
- #define NS_LAST 0x04
- #define NS_BODY 0x08
- #define NS_EXT 0x10
- #define NS_DOT 0x20
- #define MIN_FAT16 4086
- #define MIN_FAT32 65526
- #define BS_jmpBoot 0
- #define BS_OEMName 3
- #define BPB_BytsPerSec 11
- #define BPB_SecPerClus 13
- #define BPB_RsvdSecCnt 14
- #define BPB_NumFATs 16
- #define BPB_RootEntCnt 17
- #define BPB_TotSec16 19
- #define BPB_Media 21
- #define BPB_FATSz16 22
- #define BPB_SecPerTrk 24
- #define BPB_NumHeads 26
- #define BPB_HiddSec 28
- #define BPB_TotSec32 32
- #define BS_DrvNum 36
- #define BS_BootSig 38
- #define BS_VolID 39
- #define BS_VolLab 43
- #define BS_FilSysType 54
- #define BPB_FATSz32 36
- #define BPB_ExtFlags 40
- #define BPB_FSVer 42
- #define BPB_RootClus 44
- #define BPB_FSInfo 48
- #define BPB_BkBootSec 50
- #define BS_DrvNum32 64
- #define BS_BootSig32 66
- #define BS_VolID32 67
- #define BS_VolLab32 71
- #define BS_FilSysType32 82
- #define FSI_LeadSig 0
- #define FSI_StrucSig 484
- #define FSI_Free_Count 488
- #define FSI_Nxt_Free 492
- #define MBR_Table 446
- #define SZ_PTE 16
- #define BS_55AA 510
- #define DIR_Name 0
- #define DIR_Attr 11
- #define DIR_NTres 12
- #define DIR_CrtTimeTenth 13
- #define DIR_CrtTime 14
- #define DIR_CrtDate 16
- #define DIR_LstAccDate 18
- #define DIR_FstClusHI 20
- #define DIR_WrtTime 22
- #define DIR_WrtDate 24
- #define DIR_FstClusLO 26
- #define DIR_FileSize 28
- #define LDIR_Ord 0
- #define LDIR_Attr 11
- #define LDIR_Type 12
- #define LDIR_Chksum 13
- #define LDIR_FstClusLO 26
- #define SZ_DIR 32
- #define LLE 0x40
- #define DDE 0xE5
- #define NDDE 0x05
- #if _VOLUMES
- static
- FATFS *FatFs[_VOLUMES];
- #else
- #error Number of volumes must not be 0.
- #endif
- static
- WORD Fsid;
- #if _FS_RPATH
- static
- BYTE CurrVol;
- #endif
- #if _FS_LOCK
- static
- FILESEM Files[_FS_LOCK];
- #endif
- #if _USE_LFN == 0
- #define DEF_NAMEBUF BYTE sfn[12]
- #define INIT_BUF(dobj) (dobj).fn = sfn
- #define FREE_BUF()
- #elif _USE_LFN == 1
- static WCHAR LfnBuf[_MAX_LFN+1];
- #define DEF_NAMEBUF BYTE sfn[12]
- #define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; }
- #define FREE_BUF()
- #elif _USE_LFN == 2
- #define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN+1]
- #define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; }
- #define FREE_BUF()
- #elif _USE_LFN == 3
- #define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn
- #define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \
- if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \
- (dobj).lfn = lfn; (dobj).fn = sfn; }
- #define FREE_BUF() ff_memfree(lfn)
- #else
- #error Wrong LFN configuration.
- #endif
- static
- void mem_cpy (void* dst, const void* src, UINT cnt) {
- BYTE *d = (BYTE*)dst;
- const BYTE *s = (const BYTE*)src;
- #if _WORD_ACCESS == 1
- while (cnt >= sizeof (int)) {
- *(int*)d = *(int*)s;
- d += sizeof (int); s += sizeof (int);
- cnt -= sizeof (int);
- }
- #endif
- while (cnt--)
- *d++ = *s++;
- }
- static
- void mem_set (void* dst, int val, UINT cnt) {
- BYTE *d = (BYTE*)dst;
- while (cnt--)
- *d++ = (BYTE)val;
- }
- static
- int mem_cmp (const void* dst, const void* src, UINT cnt) {
- const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src;
- int r = 0;
- while (cnt-- && (r = *d++ - *s++) == 0) ;
- return r;
- }
- static
- int chk_chr (const char* str, int chr) {
- while (*str && *str != chr) str++;
- return *str;
- }
- #if _FS_REENTRANT
- static
- int lock_fs (
- FATFS *fs
- )
- {
- return ff_req_grant(fs->sobj);
- }
- static
- void unlock_fs (
- FATFS *fs,
- FRESULT res
- )
- {
- if (fs &&
- res != FR_NOT_ENABLED &&
- res != FR_INVALID_DRIVE &&
- res != FR_INVALID_OBJECT &&
- res != FR_TIMEOUT) {
- ff_rel_grant(fs->sobj);
- }
- }
- #endif
- #if _FS_LOCK
- static
- FRESULT chk_lock (
- DIR* dj,
- int acc
- )
- {
- UINT i, be;
-
- for (i = be = 0; i < _FS_LOCK; i++) {
- if (Files[i].fs) {
- if (Files[i].fs == dj->fs &&
- Files[i].clu == dj->sclust &&
- Files[i].idx == dj->index) break;
- } else {
- be++;
- }
- }
- if (i == _FS_LOCK)
- return (be || acc == 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES;
-
- return (acc || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK;
- }
- static
- int enq_lock (void)
- {
- UINT i;
- for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ;
- return (i == _FS_LOCK) ? 0 : 1;
- }
- static
- UINT inc_lock (
- DIR* dj,
- int acc
- )
- {
- UINT i;
- for (i = 0; i < _FS_LOCK; i++) {
- if (Files[i].fs == dj->fs &&
- Files[i].clu == dj->sclust &&
- Files[i].idx == dj->index) break;
- }
- if (i == _FS_LOCK) {
- for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ;
- if (i == _FS_LOCK) return 0;
- Files[i].fs = dj->fs;
- Files[i].clu = dj->sclust;
- Files[i].idx = dj->index;
- Files[i].ctr = 0;
- }
- if (acc && Files[i].ctr) return 0;
- Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1;
- return i + 1;
- }
- static
- FRESULT dec_lock (
- UINT i
- )
- {
- WORD n;
- FRESULT res;
- if (--i < _FS_LOCK) {
- n = Files[i].ctr;
- if (n == 0x100) n = 0;
- if (n) n--;
- Files[i].ctr = n;
- if (!n) Files[i].fs = 0;
- res = FR_OK;
- } else {
- res = FR_INT_ERR;
- }
- return res;
- }
- static
- void clear_lock (
- FATFS *fs
- )
- {
- UINT i;
- for (i = 0; i < _FS_LOCK; i++) {
- if (Files[i].fs == fs) Files[i].fs = 0;
- }
- }
- #endif
- static
- FRESULT move_window (
- FATFS *fs,
- DWORD sector
- )
- {
- DWORD wsect;
- wsect = fs->winsect;
- if (wsect != sector) {
- #if !_FS_READONLY
- if (fs->wflag) {
- if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK)
- return FR_DISK_ERR;
- fs->wflag = 0;
- if (wsect < (fs->fatbase + fs->fsize)) {
- BYTE nf;
- for (nf = fs->n_fats; nf > 1; nf--) {
- wsect += fs->fsize;
- disk_write(fs->drv, fs->win, wsect, 1);
- }
- }
- }
- #endif
- if (sector) {
- if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK)
- return FR_DISK_ERR;
- fs->winsect = sector;
- }
- }
- return FR_OK;
- }
- #if !_FS_READONLY
- static
- FRESULT sync (
- FATFS *fs
- )
- {
- FRESULT res;
- res = move_window(fs, 0);
- if (res == FR_OK) {
-
- if (fs->fs_type == FS_FAT32 && fs->fsi_flag) {
- fs->winsect = 0;
-
- mem_set(fs->win, 0, 512);
- ST_WORD(fs->win+BS_55AA, 0xAA55);
- ST_DWORD(fs->win+FSI_LeadSig, 0x41615252);
- ST_DWORD(fs->win+FSI_StrucSig, 0x61417272);
- ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust);
- ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust);
-
- disk_write(fs->drv, fs->win, fs->fsi_sector, 1);
- fs->fsi_flag = 0;
- }
-
- if (disk_ioctl(fs->drv, CTRL_SYNC, 0) != RES_OK)
- res = FR_DISK_ERR;
- }
- return res;
- }
- #endif
- DWORD clust2sect (
- FATFS *fs,
- DWORD clst
- )
- {
- clst -= 2;
- if (clst >= (fs->n_fatent - 2)) return 0;
- return clst * fs->csize + fs->database;
- }
- DWORD get_fat (
- FATFS *fs,
- DWORD clst
- )
- {
- UINT wc, bc;
- BYTE *p;
- if (clst < 2 || clst >= fs->n_fatent)
- return 1;
- switch (fs->fs_type) {
- case FS_FAT12 :
- bc = (UINT)clst; bc += bc / 2;
- if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
- wc = fs->win[bc % SS(fs)]; bc++;
- if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
- wc |= fs->win[bc % SS(fs)] << 8;
- return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
- case FS_FAT16 :
- if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;
- p = &fs->win[clst * 2 % SS(fs)];
- return LD_WORD(p);
- case FS_FAT32 :
- if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;
- p = &fs->win[clst * 4 % SS(fs)];
- return LD_DWORD(p) & 0x0FFFFFFF;
- }
- return 0xFFFFFFFF;
- }
- #if !_FS_READONLY
- FRESULT put_fat (
- FATFS *fs,
- DWORD clst,
- DWORD val
- )
- {
- UINT bc;
- BYTE *p;
- FRESULT res;
- if (clst < 2 || clst >= fs->n_fatent) {
- res = FR_INT_ERR;
- } else {
- switch (fs->fs_type) {
- case FS_FAT12 :
- bc = (UINT)clst; bc += bc / 2;
- res = move_window(fs, fs->fatbase + (bc / SS(fs)));
- if (res != FR_OK) break;
- p = &fs->win[bc % SS(fs)];
- *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
- bc++;
- fs->wflag = 1;
- res = move_window(fs, fs->fatbase + (bc / SS(fs)));
- if (res != FR_OK) break;
- p = &fs->win[bc % SS(fs)];
- *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
- break;
- case FS_FAT16 :
- res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
- if (res != FR_OK) break;
- p = &fs->win[clst * 2 % SS(fs)];
- ST_WORD(p, (WORD)val);
- break;
- case FS_FAT32 :
- res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
- if (res != FR_OK) break;
- p = &fs->win[clst * 4 % SS(fs)];
- val |= LD_DWORD(p) & 0xF0000000;
- ST_DWORD(p, val);
- break;
- default :
- res = FR_INT_ERR;
- }
- fs->wflag = 1;
- }
- return res;
- }
- #endif
- #if !_FS_READONLY
- static
- FRESULT remove_chain (
- FATFS *fs,
- DWORD clst
- )
- {
- FRESULT res;
- DWORD nxt;
- #if _USE_ERASE
- DWORD scl = clst, ecl = clst, rt[2];
- #endif
- if (clst < 2 || clst >= fs->n_fatent) {
- res = FR_INT_ERR;
- } else {
- res = FR_OK;
- while (clst < fs->n_fatent) {
- nxt = get_fat(fs, clst);
- if (nxt == 0) break;
- if (nxt == 1) { res = FR_INT_ERR; break; }
- if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }
- res = put_fat(fs, clst, 0);
- if (res != FR_OK) break;
- if (fs->free_clust != 0xFFFFFFFF) {
- fs->free_clust++;
- fs->fsi_flag = 1;
- }
- #if _USE_ERASE
- if (ecl + 1 == nxt) {
- ecl = nxt;
- } else {
- rt[0] = clust2sect(fs, scl);
- rt[1] = clust2sect(fs, ecl) + fs->csize - 1;
- disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, rt);
- scl = ecl = nxt;
- }
- #endif
- clst = nxt;
- }
- }
- return res;
- }
- #endif
- #if !_FS_READONLY
- static
- DWORD create_chain (
- FATFS *fs,
- DWORD clst
- )
- {
- DWORD cs, ncl, scl;
- FRESULT res;
- if (clst == 0) {
- scl = fs->last_clust;
- if (!scl || scl >= fs->n_fatent) scl = 1;
- }
- else {
- cs = get_fat(fs, clst);
- if (cs < 2) return 1;
- if (cs < fs->n_fatent) return cs;
- scl = clst;
- }
- ncl = scl;
- for (;;) {
- ncl++;
- if (ncl >= fs->n_fatent) {
- ncl = 2;
- if (ncl > scl) return 0;
- }
- cs = get_fat(fs, ncl);
- if (cs == 0) break;
- if (cs == 0xFFFFFFFF || cs == 1)
- return cs;
- if (ncl == scl) return 0;
- }
- res = put_fat(fs, ncl, 0x0FFFFFFF);
- if (res == FR_OK && clst != 0) {
- res = put_fat(fs, clst, ncl);
- }
- if (res == FR_OK) {
- fs->last_clust = ncl;
- if (fs->free_clust != 0xFFFFFFFF) {
- fs->free_clust--;
- fs->fsi_flag = 1;
- }
- } else {
- ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1;
- }
- return ncl;
- }
- #endif
- #if _USE_FASTSEEK
- static
- DWORD clmt_clust (
- FIL* fp,
- DWORD ofs
- )
- {
- DWORD cl, ncl, *tbl;
- tbl = fp->cltbl + 1;
- cl = ofs / SS(fp->fs) / fp->fs->csize;
- for (;;) {
- ncl = *tbl++;
- if (!ncl) return 0;
- if (cl < ncl) break;
- cl -= ncl; tbl++;
- }
- return cl + *tbl;
- }
- #endif
- static
- FRESULT dir_sdi (
- DIR *dj,
- WORD idx
- )
- {
- DWORD clst;
- WORD ic;
- dj->index = idx;
- clst = dj->sclust;
- if (clst == 1 || clst >= dj->fs->n_fatent)
- return FR_INT_ERR;
- if (!clst && dj->fs->fs_type == FS_FAT32)
- clst = dj->fs->dirbase;
- if (clst == 0) {
- dj->clust = clst;
- if (idx >= dj->fs->n_rootdir)
- return FR_INT_ERR;
- dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / SZ_DIR);
- }
- else {
- ic = SS(dj->fs) / SZ_DIR * dj->fs->csize;
- while (idx >= ic) {
- clst = get_fat(dj->fs, clst);
- if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
- if (clst < 2 || clst >= dj->fs->n_fatent)
- return FR_INT_ERR;
- idx -= ic;
- }
- dj->clust = clst;
- dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / SZ_DIR);
- }
- dj->dir = dj->fs->win + (idx % (SS(dj->fs) / SZ_DIR)) * SZ_DIR;
- return FR_OK;
- }
- static
- FRESULT dir_next (
- DIR *dj,
- int stretch
- )
- {
- DWORD clst;
- WORD i;
- stretch = stretch;
- i = dj->index + 1;
- if (!i || !dj->sect)
- return FR_NO_FILE;
- if (!(i % (SS(dj->fs) / SZ_DIR))) {
- dj->sect++;
- if (dj->clust == 0) {
- if (i >= dj->fs->n_rootdir)
- return FR_NO_FILE;
- }
- else {
- if (((i / (SS(dj->fs) / SZ_DIR)) & (dj->fs->csize - 1)) == 0) {
- clst = get_fat(dj->fs, dj->clust);
- if (clst <= 1) return FR_INT_ERR;
- if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
- if (clst >= dj->fs->n_fatent) {
- #if !_FS_READONLY
- BYTE c;
- if (!stretch) return FR_NO_FILE;
- clst = create_chain(dj->fs, dj->clust);
- if (clst == 0) return FR_DENIED;
- if (clst == 1) return FR_INT_ERR;
- if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
-
- if (move_window(dj->fs, 0)) return FR_DISK_ERR;
- mem_set(dj->fs->win, 0, SS(dj->fs));
- dj->fs->winsect = clust2sect(dj->fs, clst);
- for (c = 0; c < dj->fs->csize; c++) {
- dj->fs->wflag = 1;
- if (move_window(dj->fs, 0)) return FR_DISK_ERR;
- dj->fs->winsect++;
- }
- dj->fs->winsect -= c;
- #else
- return FR_NO_FILE;
- #endif
- }
- dj->clust = clst;
- dj->sect = clust2sect(dj->fs, clst);
- }
- }
- }
- dj->index = i;
- dj->dir = dj->fs->win + (i % (SS(dj->fs) / SZ_DIR)) * SZ_DIR;
- return FR_OK;
- }
- static
- DWORD ld_clust (
- FATFS *fs,
- BYTE *dir
- )
- {
- DWORD cl;
- cl = LD_WORD(dir+DIR_FstClusLO);
- if (fs->fs_type == FS_FAT32)
- cl |= (DWORD)LD_WORD(dir+DIR_FstClusHI) << 16;
- return cl;
- }
- #if !_FS_READONLY
- static
- void st_clust (
- BYTE *dir,
- DWORD cl
- )
- {
- ST_WORD(dir+DIR_FstClusLO, cl);
- ST_WORD(dir+DIR_FstClusHI, cl >> 16);
- }
- #endif
- #if _USE_LFN
- static
- const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30};
- static
- int cmp_lfn (
- WCHAR *lfnbuf,
- BYTE *dir
- )
- {
- UINT i, s;
- WCHAR wc, uc;
- i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13;
- s = 0; wc = 1;
- do {
- uc = LD_WORD(dir+LfnOfs[s]);
- if (wc) {
- wc = ff_wtoupper(uc);
- if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++]))
- return 0;
- } else {
- if (uc != 0xFFFF) return 0;
- }
- } while (++s < 13);
- if ((dir[LDIR_Ord] & LLE) && wc && lfnbuf[i])
- return 0;
- return 1;
- }
- static
- int pick_lfn (
- WCHAR *lfnbuf,
- BYTE *dir
- )
- {
- UINT i, s;
- WCHAR wc, uc;
- i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;
- s = 0; wc = 1;
- do {
- uc = LD_WORD(dir+LfnOfs[s]);
- if (wc) {
- if (i >= _MAX_LFN) return 0;
- lfnbuf[i++] = wc = uc;
- } else {
- if (uc != 0xFFFF) return 0;
- }
- } while (++s < 13);
- if (dir[LDIR_Ord] & LLE) {
- if (i >= _MAX_LFN) return 0;
- lfnbuf[i] = 0;
- }
- return 1;
- }
- #if !_FS_READONLY
- static
- void fit_lfn (
- const WCHAR *lfnbuf,
- BYTE *dir,
- BYTE ord,
- BYTE sum
- )
- {
- UINT i, s;
- WCHAR wc;
- dir[LDIR_Chksum] = sum;
- dir[LDIR_Attr] = AM_LFN;
- dir[LDIR_Type] = 0;
- ST_WORD(dir+LDIR_FstClusLO, 0);
- i = (ord - 1) * 13;
- s = wc = 0;
- do {
- if (wc != 0xFFFF) wc = lfnbuf[i++];
- ST_WORD(dir+LfnOfs[s], wc);
- if (!wc) wc = 0xFFFF;
- } while (++s < 13);
- if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE;
- dir[LDIR_Ord] = ord;
- }
- #endif
- #endif
- #if _USE_LFN
- void gen_numname (
- BYTE *dst,
- const BYTE *src,
- const WCHAR *lfn,
- WORD seq
- )
- {
- BYTE ns[8], c;
- UINT i, j;
- mem_cpy(dst, src, 11);
- if (seq > 5) {
- do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn);
- }
-
- i = 7;
- do {
- c = (seq % 16) + '0';
- if (c > '9') c += 7;
- ns[i--] = c;
- seq /= 16;
- } while (seq);
- ns[i] = '~';
-
- for (j = 0; j < i && dst[j] != ' '; j++) {
- if (IsDBCS1(dst[j])) {
- if (j == i - 1) break;
- j++;
- }
- }
- do {
- dst[j++] = (i < 8) ? ns[i++] : ' ';
- } while (j < 8);
- }
- #endif
- #if _USE_LFN
- static
- BYTE sum_sfn (
- const BYTE *dir
- )
- {
- BYTE sum = 0;
- UINT n = 11;
- do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n);
- return sum;
- }
- #endif
- static
- FRESULT dir_find (
- DIR *dj
- )
- {
- FRESULT res;
- BYTE c, *dir;
- #if _USE_LFN
- BYTE a, ord, sum;
- #endif
- res = dir_sdi(dj, 0);
- if (res != FR_OK) return res;
- #if _USE_LFN
- ord = sum = 0xFF;
- #endif
- do {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- dir = dj->dir;
- c = dir[DIR_Name];
- if (c == 0) { res = FR_NO_FILE; break; }
- #if _USE_LFN
- a = dir[DIR_Attr] & AM_MASK;
- if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) {
- ord = 0xFF;
- } else {
- if (a == AM_LFN) {
- if (dj->lfn) {
- if (c & LLE) {
- sum = dir[LDIR_Chksum];
- c &= ~LLE; ord = c;
- dj->lfn_idx = dj->index;
- }
-
- ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
- }
- } else {
- if (!ord && sum == sum_sfn(dir)) break;
- ord = 0xFF; dj->lfn_idx = 0xFFFF;
- if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break;
- }
- }
- #else
- if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11))
- break;
- #endif
- res = dir_next(dj, 0);
- } while (res == FR_OK);
- return res;
- }
- #if _FS_MINIMIZE <= 1
- static
- FRESULT dir_read (
- DIR *dj
- )
- {
- FRESULT res;
- BYTE c, *dir;
- #if _USE_LFN
- BYTE a, ord = 0xFF, sum = 0xFF;
- #endif
- res = FR_NO_FILE;
- while (dj->sect) {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- dir = dj->dir;
- c = dir[DIR_Name];
- if (c == 0) { res = FR_NO_FILE; break; }
- #if _USE_LFN
- a = dir[DIR_Attr] & AM_MASK;
- if (c == DDE || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) {
- ord = 0xFF;
- } else {
- if (a == AM_LFN) {
- if (c & LLE) {
- sum = dir[LDIR_Chksum];
- c &= ~LLE; ord = c;
- dj->lfn_idx = dj->index;
- }
-
- ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
- } else {
- if (ord || sum != sum_sfn(dir))
- dj->lfn_idx = 0xFFFF;
- break;
- }
- }
- #else
- if (c != DDE && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL))
- break;
- #endif
- res = dir_next(dj, 0);
- if (res != FR_OK) break;
- }
- if (res != FR_OK) dj->sect = 0;
- return res;
- }
- #endif
- #if !_FS_READONLY
- static
- FRESULT dir_register (
- DIR *dj
- )
- {
- FRESULT res;
- BYTE c, *dir;
- #if _USE_LFN
- WORD n, ne, is;
- BYTE sn[12], *fn, sum;
- WCHAR *lfn;
- fn = dj->fn; lfn = dj->lfn;
- mem_cpy(sn, fn, 12);
- if (_FS_RPATH && (sn[NS] & NS_DOT))
- return FR_INVALID_NAME;
- if (sn[NS] & NS_LOSS) {
- fn[NS] = 0; dj->lfn = 0;
- for (n = 1; n < 100; n++) {
- gen_numname(fn, sn, lfn, n);
- res = dir_find(dj);
- if (res != FR_OK) break;
- }
- if (n == 100) return FR_DENIED;
- if (res != FR_NO_FILE) return res;
- fn[NS] = sn[NS]; dj->lfn = lfn;
- }
- if (sn[NS] & NS_LFN) {
- for (ne = 0; lfn[ne]; ne++) ;
- ne = (ne + 25) / 13;
- } else {
- ne = 1;
- }
-
- res = dir_sdi(dj, 0);
- if (res != FR_OK) return res;
- n = is = 0;
- do {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- c = *dj->dir;
- if (c == DDE || c == 0) {
- if (n == 0) is = dj->index;
- if (++n == ne) break;
- } else {
- n = 0;
- }
- res = dir_next(dj, 1);
- } while (res == FR_OK);
- if (res == FR_OK && ne > 1) {
- res = dir_sdi(dj, is);
- if (res == FR_OK) {
- sum = sum_sfn(dj->fn);
- ne--;
- do {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum);
- dj->fs->wflag = 1;
- res = dir_next(dj, 0);
- } while (res == FR_OK && --ne);
- }
- }
- #else
- res = dir_sdi(dj, 0);
- if (res == FR_OK) {
- do {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- c = *dj->dir;
- if (c == DDE || c == 0) break;
- res = dir_next(dj, 1);
- } while (res == FR_OK);
- }
- #endif
- if (res == FR_OK) {
- res = move_window(dj->fs, dj->sect);
- if (res == FR_OK) {
- dir = dj->dir;
- mem_set(dir, 0, SZ_DIR);
- mem_cpy(dir, dj->fn, 11);
- #if _USE_LFN
- dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT);
- #endif
- dj->fs->wflag = 1;
- }
- }
- return res;
- }
- #endif
- #if !_FS_READONLY && !_FS_MINIMIZE
- static
- FRESULT dir_remove (
- DIR *dj
- )
- {
- FRESULT res;
- #if _USE_LFN
- WORD i;
- i = dj->index;
- res = dir_sdi(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx));
- if (res == FR_OK) {
- do {
- res = move_window(dj->fs, dj->sect);
- if (res != FR_OK) break;
- *dj->dir = DDE;
- dj->fs->wflag = 1;
- if (dj->index >= i) break;
- res = dir_next(dj, 0);
- } while (res == FR_OK);
- if (res == FR_NO_FILE) res = FR_INT_ERR;
- }
- #else
- res = dir_sdi(dj, dj->index);
- if (res == FR_OK) {
- res = move_window(dj->fs, dj->sect);
- if (res == FR_OK) {
- *dj->dir = DDE;
- dj->fs->wflag = 1;
- }
- }
- #endif
- return res;
- }
- #endif
- static
- FRESULT create_name (
- DIR *dj,
- const TCHAR **path
- )
- {
- #ifdef _EXCVT
- static const BYTE excvt[] = _EXCVT;
- #endif
- #if _USE_LFN
- BYTE b, cf;
- WCHAR w, *lfn;
- UINT i, ni, si, di;
- const TCHAR *p;
-
- for (p = *path; *p == '/' || *p == '\\'; p++) ;
- lfn = dj->lfn;
- si = di = 0;
- for (;;) {
- w = p[si++];
- if (w < ' ' || w == '/' || w == '\\') break;
- if (di >= _MAX_LFN)
- return FR_INVALID_NAME;
- #if !_LFN_UNICODE
- w &= 0xFF;
- if (IsDBCS1(w)) {
- b = (BYTE)p[si++];
- if (!IsDBCS2(b))
- return FR_INVALID_NAME;
- w = (w << 8) + b;
- }
- w = ff_convert(w, 1);
- if (!w) return FR_INVALID_NAME;
- #endif
- if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w))
- return FR_INVALID_NAME;
- lfn[di++] = w;
- }
- *path = &p[si];
- cf = (w < ' ') ? NS_LAST : 0;
- #if _FS_RPATH
- if ((di == 1 && lfn[di-1] == '.') ||
- (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) {
- lfn[di] = 0;
- for (i = 0; i < 11; i++)
- dj->fn[i] = (i < di) ? '.' : ' ';
- dj->fn[i] = cf | NS_DOT;
- return FR_OK;
- }
- #endif
- while (di) {
- w = lfn[di-1];
- if (w != ' ' && w != '.') break;
- di--;
- }
- if (!di) return FR_INVALID_NAME;
- lfn[di] = 0;
-
- mem_set(dj->fn, ' ', 11);
- for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ;
- if (si) cf |= NS_LOSS | NS_LFN;
- while (di && lfn[di - 1] != '.') di--;
- b = i = 0; ni = 8;
- for (;;) {
- w = lfn[si++];
- if (!w) break;
- if (w == ' ' || (w == '.' && si != di)) {
- cf |= NS_LOSS | NS_LFN; continue;
- }
- if (i >= ni || si == di) {
- if (ni == 11) {
- cf |= NS_LOSS | NS_LFN; break;
- }
- if (si != di) cf |= NS_LOSS | NS_LFN;
- if (si > di) break;
- si = di; i = 8; ni = 11;
- b <<= 2; continue;
- }
- if (w >= 0x80) {
- #ifdef _EXCVT
- w = ff_convert(w, 0);
- if (w) w = excvt[w - 0x80];
- #else
- w = ff_convert(ff_wtoupper(w), 0);
- #endif
- cf |= NS_LFN;
- }
- if (_DF1S && w >= 0x100) {
- if (i >= ni - 1) {
- cf |= NS_LOSS | NS_LFN; i = ni; continue;
- }
- dj->fn[i++] = (BYTE)(w >> 8);
- } else {
- if (!w || chk_chr("+,;=[]", w)) {
- w = '_'; cf |= NS_LOSS | NS_LFN;
- } else {
- if (IsUpper(w)) {
- b |= 2;
- } else {
- if (IsLower(w)) {
- b |= 1; w -= 0x20;
- }
- }
- }
- }
- dj->fn[i++] = (BYTE)w;
- }
- if (dj->fn[0] == DDE) dj->fn[0] = NDDE;
- if (ni == 8) b <<= 2;
- if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03)
- cf |= NS_LFN;
- if (!(cf & NS_LFN)) {
- if ((b & 0x03) == 0x01) cf |= NS_EXT;
- if ((b & 0x0C) == 0x04) cf |= NS_BODY;
- }
- dj->fn[NS] = cf;
- return FR_OK;
- #else
- BYTE b, c, d, *sfn;
- UINT ni, si, i;
- const char *p;
-
- for (p = *path; *p == '/' || *p == '\\'; p++) ;
- sfn = dj->fn;
- mem_set(sfn, ' ', 11);
- si = i = b = 0; ni = 8;
- #if _FS_RPATH
- if (p[si] == '.') {
- for (;;) {
- c = (BYTE)p[si++];
- if (c != '.' || si >= 3) break;
- sfn[i++] = c;
- }
- if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME;
- *path = &p[si];
- sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT;
- return FR_OK;
- }
- #endif
- for (;;) {
- c = (BYTE)p[si++];
- if (c <= ' ' || c == '/' || c == '\\') break;
- if (c == '.' || i >= ni) {
- if (ni != 8 || c != '.') return FR_INVALID_NAME;
- i = 8; ni = 11;
- b <<= 2; continue;
- }
- if (c >= 0x80) {
- b |= 3;
- #ifdef _EXCVT
- c = excvt[c - 0x80];
- #else
- #if !_DF1S
- return FR_INVALID_NAME;
- #endif
- #endif
- }
- if (IsDBCS1(c)) {
- d = (BYTE)p[si++];
- if (!IsDBCS2(d) || i >= ni - 1)
- return FR_INVALID_NAME;
- sfn[i++] = c;
- sfn[i++] = d;
- } else {
- if (chk_chr("\"*+,:;<=>\?[]|\x7F", c))
- return FR_INVALID_NAME;
- if (IsUpper(c)) {
- b |= 2;
- } else {
- if (IsLower(c)) {
- b |= 1; c -= 0x20;
- }
- }
- sfn[i++] = c;
- }
- }
- *path = &p[si];
- c = (c <= ' ') ? NS_LAST : 0;
- if (!i) return FR_INVALID_NAME;
- if (sfn[0] == DDE) sfn[0] = NDDE;
- if (ni == 8) b <<= 2;
- if ((b & 0x03) == 0x01) c |= NS_EXT;
- if ((b & 0x0C) == 0x04) c |= NS_BODY;
- sfn[NS] = c;
- return FR_OK;
- #endif
- }
- #if _FS_MINIMIZE <= 1
- static
- void get_fileinfo (
- DIR *dj,
- FILINFO *fno
- )
- {
- UINT i;
- BYTE nt, *dir;
- TCHAR *p, c;
- p = fno->fname;
- if (dj->sect) {
- dir = dj->dir;
- nt = dir[DIR_NTres];
- for (i = 0; i < 8; i++) {
- c = dir[i];
- if (c == ' ') break;
- if (c == NDDE) c = (TCHAR)DDE;
- if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20;
- #if _LFN_UNICODE
- if (IsDBCS1(c) && i < 7 && IsDBCS2(dir[i+1]))
- c = (c << 8) | dir[++i];
- c = ff_convert(c, 1);
- if (!c) c = '?';
- #endif
- *p++ = c;
- }
- if (dir[8] != ' ') {
- *p++ = '.';
- for (i = 8; i < 11; i++) {
- c = dir[i];
- if (c == ' ') break;
- if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20;
- #if _LFN_UNICODE
- if (IsDBCS1(c) && i < 10 && IsDBCS2(dir[i+1]))
- c = (c << 8) | dir[++i];
- c = ff_convert(c, 1);
- if (!c) c = '?';
- #endif
- *p++ = c;
- }
- }
- fno->fattrib = dir[DIR_Attr];
- fno->fsize = LD_DWORD(dir+DIR_FileSize);
- fno->fdate = LD_WORD(dir+DIR_WrtDate);
- fno->ftime = LD_WORD(dir+DIR_WrtTime);
- }
- *p = 0;
- #if _USE_LFN
- if (fno->lfname && fno->lfsize) {
- TCHAR *tp = fno->lfname;
- WCHAR w, *lfn;
- i = 0;
- if (dj->sect && dj->lfn_idx != 0xFFFF) {
- lfn = dj->lfn;
- while ((w = *lfn++) != 0) {
- #if !_LFN_UNICODE
- w = ff_convert(w, 0);
- if (!w) { i = 0; break; }
- if (_DF1S && w >= 0x100)
- tp[i++] = (TCHAR)(w >> 8);
- #endif
- if (i >= fno->lfsize - 1) { i = 0; break; }
- tp[i++] = (TCHAR)w;
- }
- }
- tp[i] = 0;
- }
- #endif
- }
- #endif
- static
- FRESULT follow_path (
- DIR *dj,
- const TCHAR *path
- )
- {
- FRESULT res;
- BYTE *dir, ns;
- #if _FS_RPATH
- if (*path == '/' || *path == '\\') {
- path++; dj->sclust = 0;
- } else {
- dj->sclust = dj->fs->cdir;
- }
- #else
- if (*path == '/' || *path == '\\')
- path++;
- dj->sclust = 0;
- #endif
- if ((UINT)*path < ' ') {
- res = dir_sdi(dj, 0);
- dj->dir = 0;
- } else {
- for (;;) {
- res = create_name(dj, &path);
- if (res != FR_OK) break;
- res = dir_find(dj);
- ns = *(dj->fn+NS);
- if (res != FR_OK) {
- if (res != FR_NO_FILE) break;
-
- if (_FS_RPATH && (ns & NS_DOT)) {
- dj->sclust = 0; dj->dir = 0;
- res = FR_OK;
- if (!(ns & NS_LAST)) continue;
- } else {
- if (!(ns & NS_LAST)) res = FR_NO_PATH;
- }
- break;
- }
- if (ns & NS_LAST) break;
- dir = dj->dir;
- if (!(dir[DIR_Attr] & AM_DIR)) {
- res = FR_NO_PATH; break;
- }
- dj->sclust = ld_clust(dj->fs, dir);
- }
- }
- return res;
- }
- static
- BYTE check_fs (
- FATFS *fs,
- DWORD sect
- )
- {
- if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK)
- return 3;
- if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55)
- return 2;
- if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146)
- return 0;
- if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)
- return 0;
- return 1;
- }
- static
- FRESULT chk_mounted (
- const TCHAR **path,
- FATFS **rfs,
- BYTE wmode
- )
- {
- BYTE fmt, b, pi, *tbl;
- UINT vol;
- DSTATUS stat;
- DWORD bsect, fasize, tsect, sysect, nclst, szbfat;
- WORD nrsv;
- const TCHAR *p = *path;
- FATFS *fs;
-
- vol = p[0] - '0';
- if (vol <= 9 && p[1] == ':') {
- p += 2; *path = p;
- } else {
- #if _FS_RPATH
- vol = CurrVol;
- #else
- vol = 0;
- #endif
- }
-
- *rfs = 0;
- if (vol >= _VOLUMES)
- return FR_INVALID_DRIVE;
- fs = FatFs[vol];
- if (!fs) return FR_NOT_ENABLED;
- ENTER_FF(fs);
- *rfs = fs;
- if (fs->fs_type) {
- stat = disk_status(fs->drv);
- if (!(stat & STA_NOINIT)) {
- if (!_FS_READONLY && wmode && (stat & STA_PROTECT))
- return FR_WRITE_PROTECTED;
- return FR_OK;
- }
- }
-
-
- fs->fs_type = 0;
- fs->drv = LD2PD(vol);
- stat = disk_initialize(fs->drv);
- if (stat & STA_NOINIT)
- return FR_NOT_READY;
- if (!_FS_READONLY && wmode && (stat & STA_PROTECT))
- return FR_WRITE_PROTECTED;
- #if _MAX_SS != 512
- if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &fs->ssize) != RES_OK)
- return FR_DISK_ERR;
- #endif
-
- fmt = check_fs(fs, bsect = 0);
- if (LD2PT(vol) && !fmt) fmt = 1;
- if (fmt == 1) {
-
- pi = LD2PT(vol);
- if (pi) pi--;
- tbl = &fs->win[MBR_Table + pi * SZ_PTE];
- if (tbl[4]) {
- bsect = LD_DWORD(&tbl[8]);
- fmt = check_fs(fs, bsect);
- }
- }
- if (fmt == 3) return FR_DISK_ERR;
- if (fmt) return FR_NO_FILESYSTEM;
-
- if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs))
- return FR_NO_FILESYSTEM;
- fasize = LD_WORD(fs->win+BPB_FATSz16);
- if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32);
- fs->fsize = fasize;
- fs->n_fats = b = fs->win[BPB_NumFATs];
- if (b != 1 && b != 2) return FR_NO_FILESYSTEM;
- fasize *= b;
- fs->csize = b = fs->win[BPB_SecPerClus];
- if (!b || (b & (b - 1))) return FR_NO_FILESYSTEM;
- fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt);
- if (fs->n_rootdir % (SS(fs) / SZ_DIR)) return FR_NO_FILESYSTEM;
- tsect = LD_WORD(fs->win+BPB_TotSec16);
- if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32);
- nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt);
- if (!nrsv) return FR_NO_FILESYSTEM;
-
- sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIR);
- if (tsect < sysect) return FR_NO_FILESYSTEM;
- nclst = (tsect - sysect) / fs->csize;
- if (!nclst) return FR_NO_FILESYSTEM;
- fmt = FS_FAT12;
- if (nclst >= MIN_FAT16) fmt = FS_FAT16;
- if (nclst >= MIN_FAT32) fmt = FS_FAT32;
-
- fs->n_fatent = nclst + 2;
- fs->database = bsect + sysect;
- fs->fatbase = bsect + nrsv;
- if (fmt == FS_FAT32) {
- if (fs->n_rootdir) return FR_NO_FILESYSTEM;
- fs->dirbase = LD_DWORD(fs->win+BPB_RootClus);
- szbfat = fs->n_fatent * 4;
- } else {
- if (!fs->n_rootdir) return FR_NO_FILESYSTEM;
- fs->dirbase = fs->fatbase + fasize;
- szbfat = (fmt == FS_FAT16) ?
- fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
- }
- if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs))
- return FR_NO_FILESYSTEM;
- #if !_FS_READONLY
-
- fs->free_clust = 0xFFFFFFFF;
- fs->last_clust = 0;
-
- if (fmt == FS_FAT32) {
- fs->fsi_flag = 0;
- fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo);
- if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK &&
- LD_WORD(fs->win+BS_55AA) == 0xAA55 &&
- LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&
- LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {
- fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
- fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
- }
- }
- #endif
- fs->fs_type = fmt;
- fs->id = ++Fsid;
- fs->winsect = 0;
- fs->wflag = 0;
- #if _FS_RPATH
- fs->cdir = 0;
- #endif
- #if _FS_LOCK
- clear_lock(fs);
- #endif
- return FR_OK;
- }
- static
- FRESULT validate (
- void* obj
- )
- {
- FIL *fil;
- fil = (FIL*)obj;
- if (!fil->fs || !fil->fs->fs_type || fil->fs->id != fil->id)
- return FR_INVALID_OBJECT;
- ENTER_FF(fil->fs);
- if (disk_status(fil->fs->drv) & STA_NOINIT)
- return FR_NOT_READY;
- return FR_OK;
- }
- FRESULT f_mount (
- BYTE vol,
- FATFS *fs
- )
- {
- FATFS *rfs;
- if (vol >= _VOLUMES)
- return FR_INVALID_DRIVE;
- rfs = FatFs[vol];
- if (rfs) {
- #if _FS_LOCK
- clear_lock(rfs);
- #endif
- #if _FS_REENTRANT
- if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR;
- #endif
- rfs->fs_type = 0;
- }
- if (fs) {
- fs->fs_type = 0;
- #if _FS_REENTRANT
- if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR;
- #endif
- }
- FatFs[vol] = fs;
- return FR_OK;
- }
- FRESULT f_open (
- FIL *fp,
- const TCHAR *path,
- BYTE mode
- )
- {
- FRESULT res;
- DIR dj;
- BYTE *dir;
- DEF_NAMEBUF;
- if (!fp) return FR_INVALID_OBJECT;
- fp->fs = 0;
- #if !_FS_READONLY
- mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;
- res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ));
- #else
- mode &= FA_READ;
- res = chk_mounted(&path, &dj.fs, 0);
- #endif
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path);
- dir = dj.dir;
- #if !_FS_READONLY
- if (res == FR_OK) {
- if (!dir)
- res = FR_INVALID_NAME;
- #if _FS_LOCK
- else
- res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
- #endif
- }
-
- if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {
- DWORD dw, cl;
- if (res != FR_OK) {
- if (res == FR_NO_FILE)
- #if _FS_LOCK
- res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;
- #else
- res = dir_register(&dj);
- #endif
- mode |= FA_CREATE_ALWAYS;
- dir = dj.dir;
- }
- else {
- if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) {
- res = FR_DENIED;
- } else {
- if (mode & FA_CREATE_NEW)
- res = FR_EXIST;
- }
- }
- if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) {
- dw = get_fattime();
- ST_DWORD(dir+DIR_CrtTime, dw);
- dir[DIR_Attr] = 0;
- ST_DWORD(dir+DIR_FileSize, 0);
- cl = ld_clust(dj.fs, dir);
- st_clust(dir, 0);
- dj.fs->wflag = 1;
- if (cl) {
- dw = dj.fs->winsect;
- res = remove_chain(dj.fs, cl);
- if (res == FR_OK) {
- dj.fs->last_clust = cl - 1;
- res = move_window(dj.fs, dw);
- }
- }
- }
- }
- else {
- if (res == FR_OK) {
- if (dir[DIR_Attr] & AM_DIR) {
- res = FR_NO_FILE;
- } else {
- if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO))
- res = FR_DENIED;
- }
- }
- }
- if (res == FR_OK) {
- if (mode & FA_CREATE_ALWAYS)
- mode |= FA__WRITTEN;
- fp->dir_sect = dj.fs->winsect;
- fp->dir_ptr = dir;
- #if _FS_LOCK
- fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
- if (!fp->lockid) res = FR_INT_ERR;
- #endif
- }
- #else
- if (res == FR_OK) {
- dir = dj.dir;
- if (!dir) {
- res = FR_INVALID_NAME;
- } else {
- if (dir[DIR_Attr] & AM_DIR)
- res = FR_NO_FILE;
- }
- }
- #endif
- FREE_BUF();
- if (res == FR_OK) {
- fp->flag = mode;
- fp->sclust = ld_clust(dj.fs, dir);
- fp->fsize = LD_DWORD(dir+DIR_FileSize);
- fp->fptr = 0;
- fp->dsect = 0;
- #if _USE_FASTSEEK
- fp->cltbl = 0;
- #endif
- fp->fs = dj.fs; fp->id = dj.fs->id;
- }
- }
- LEAVE_FF(dj.fs, res);
- }
- FRESULT f_read (
- FIL *fp,
- void *buff,
- UINT btr,
- UINT *br
- )
- {
- FRESULT res;
- DWORD clst, sect, remain;
- UINT rcnt, cc;
- BYTE csect, *rbuff = buff;
- *br = 0;
- res = validate(fp);
- if (res != FR_OK) LEAVE_FF(fp->fs, res);
- if (fp->flag & FA__ERROR)
- LEAVE_FF(fp->fs, FR_INT_ERR);
- if (!(fp->flag & FA_READ))
- LEAVE_FF(fp->fs, FR_DENIED);
- remain = fp->fsize - fp->fptr;
- if (btr > remain) btr = (UINT)remain;
- for ( ; btr;
- rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
- if ((fp->fptr % SS(fp->fs)) == 0) {
- csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));
- if (!csect) {
- if (fp->fptr == 0) {
- clst = fp->sclust;
- } else {
- #if _USE_FASTSEEK
- if (fp->cltbl)
- clst = clmt_clust(fp, fp->fptr);
- else
- #endif
- clst = get_fat(fp->fs, fp->clust);
- }
- if (clst < 2) ABORT(fp->fs, FR_INT_ERR);
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- fp->clust = clst;
- }
- sect = clust2sect(fp->fs, fp->clust);
- if (!sect) ABORT(fp->fs, FR_INT_ERR);
- sect += csect;
- cc = btr / SS(fp->fs);
- if (cc) {
- if (csect + cc > fp->fs->csize)
- cc = fp->fs->csize - csect;
- if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- #if !_FS_READONLY && _FS_MINIMIZE <= 2
- #if _FS_TINY
- if (fp->fs->wflag && fp->fs->winsect - sect < cc)
- mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));
- #else
- if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc)
- mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));
- #endif
- #endif
- rcnt = SS(fp->fs) * cc;
- continue;
- }
- #if !_FS_TINY
- if (fp->dsect != sect) {
- #if !_FS_READONLY
- if (fp->flag & FA__DIRTY) {
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
- #endif
- if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- }
- #endif
- fp->dsect = sect;
- }
- rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));
- if (rcnt > btr) rcnt = btr;
- #if _FS_TINY
- if (move_window(fp->fs, fp->dsect))
- ABORT(fp->fs, FR_DISK_ERR);
- mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt);
- #else
- mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt);
- #endif
- }
- LEAVE_FF(fp->fs, FR_OK);
- }
- #if !_FS_READONLY
- FRESULT f_write (
- FIL *fp,
- const void *buff,
- UINT btw,
- UINT *bw
- )
- {
- FRESULT res;
- DWORD clst, sect;
- UINT wcnt, cc;
- const BYTE *wbuff = buff;
- BYTE csect;
- *bw = 0;
- res = validate(fp);
- if (res != FR_OK) LEAVE_FF(fp->fs, res);
- if (fp->flag & FA__ERROR)
- LEAVE_FF(fp->fs, FR_INT_ERR);
- if (!(fp->flag & FA_WRITE))
- LEAVE_FF(fp->fs, FR_DENIED);
- if ((DWORD)(fp->fsize + btw) < fp->fsize) btw = 0;
- for ( ; btw;
- wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
- if ((fp->fptr % SS(fp->fs)) == 0) {
- csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));
- if (!csect) {
- if (fp->fptr == 0) {
- clst = fp->sclust;
- if (clst == 0)
- fp->sclust = clst = create_chain(fp->fs, 0);
- } else {
- #if _USE_FASTSEEK
- if (fp->cltbl)
- clst = clmt_clust(fp, fp->fptr);
- else
- #endif
- clst = create_chain(fp->fs, fp->clust);
- }
- if (clst == 0) break;
- if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- fp->clust = clst;
- }
- #if _FS_TINY
- if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0))
- ABORT(fp->fs, FR_DISK_ERR);
- #else
- if (fp->flag & FA__DIRTY) {
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
- #endif
- sect = clust2sect(fp->fs, fp->clust);
- if (!sect) ABORT(fp->fs, FR_INT_ERR);
- sect += csect;
- cc = btw / SS(fp->fs);
- if (cc) {
- if (csect + cc > fp->fs->csize)
- cc = fp->fs->csize - csect;
- if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- #if _FS_TINY
- if (fp->fs->winsect - sect < cc) {
- mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs));
- fp->fs->wflag = 0;
- }
- #else
- if (fp->dsect - sect < cc) {
- mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs));
- fp->flag &= ~FA__DIRTY;
- }
- #endif
- wcnt = SS(fp->fs) * cc;
- continue;
- }
- #if _FS_TINY
- if (fp->fptr >= fp->fsize) {
- if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR);
- fp->fs->winsect = sect;
- }
- #else
- if (fp->dsect != sect) {
- if (fp->fptr < fp->fsize &&
- disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- }
- #endif
- fp->dsect = sect;
- }
- wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));
- if (wcnt > btw) wcnt = btw;
- #if _FS_TINY
- if (move_window(fp->fs, fp->dsect))
- ABORT(fp->fs, FR_DISK_ERR);
- mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt);
- fp->fs->wflag = 1;
- #else
- mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt);
- fp->flag |= FA__DIRTY;
- #endif
- }
- if (fp->fptr > fp->fsize) fp->fsize = fp->fptr;
- fp->flag |= FA__WRITTEN;
- LEAVE_FF(fp->fs, FR_OK);
- }
- FRESULT f_sync (
- FIL *fp
- )
- {
- FRESULT res;
- DWORD tim;
- BYTE *dir;
- res = validate(fp);
- if (res == FR_OK) {
- if (fp->flag & FA__WRITTEN) {
- #if !_FS_TINY
- if (fp->flag & FA__DIRTY) {
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- LEAVE_FF(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
- #endif
-
- res = move_window(fp->fs, fp->dir_sect);
- if (res == FR_OK) {
- dir = fp->dir_ptr;
- dir[DIR_Attr] |= AM_ARC;
- ST_DWORD(dir+DIR_FileSize, fp->fsize);
- st_clust(dir, fp->sclust);
- tim = get_fattime();
- ST_DWORD(dir+DIR_WrtTime, tim);
- ST_WORD(dir+DIR_LstAccDate, 0);
- fp->flag &= ~FA__WRITTEN;
- fp->fs->wflag = 1;
- res = sync(fp->fs);
- }
- }
- }
- LEAVE_FF(fp->fs, res);
- }
- #endif
- FRESULT f_close (
- FIL *fp
- )
- {
- FRESULT res;
- #if _FS_READONLY
- res = validate(fp);
- {
- #if _FS_REENTRANT
- FATFS *fs = fp->fs;
- #endif
- if (res == FR_OK) fp->fs = 0;
- LEAVE_FF(fs, res);
- }
- #else
- res = f_sync(fp);
- #if _FS_LOCK
- if (res == FR_OK) {
- #if _FS_REENTRANT
- FATFS *fs = fp->fs;;
- res = validate(fp);
- if (res == FR_OK) {
- res = dec_lock(fp->lockid);
- unlock_fs(fs, FR_OK);
- }
- #else
- res = dec_lock(fp->lockid);
- #endif
- }
- #endif
- if (res == FR_OK) fp->fs = 0;
- return res;
- #endif
- }
- #if _FS_RPATH >= 1
- FRESULT f_chdrive (
- BYTE drv
- )
- {
- if (drv >= _VOLUMES) return FR_INVALID_DRIVE;
- CurrVol = drv;
- return FR_OK;
- }
- FRESULT f_chdir (
- const TCHAR *path
- )
- {
- FRESULT res;
- DIR dj;
- DEF_NAMEBUF;
- res = chk_mounted(&path, &dj.fs, 0);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path);
- FREE_BUF();
- if (res == FR_OK) {
- if (!dj.dir) {
- dj.fs->cdir = dj.sclust;
- } else {
- if (dj.dir[DIR_Attr] & AM_DIR)
- dj.fs->cdir = ld_clust(dj.fs, dj.dir);
- else
- res = FR_NO_PATH;
- }
- }
- if (res == FR_NO_FILE) res = FR_NO_PATH;
- }
- LEAVE_FF(dj.fs, res);
- }
- #if _FS_RPATH >= 2
- FRESULT f_getcwd (
- TCHAR *path,
- UINT sz_path
- )
- {
- FRESULT res;
- DIR dj;
- UINT i, n;
- DWORD ccl;
- TCHAR *tp;
- FILINFO fno;
- DEF_NAMEBUF;
- *path = 0;
- res = chk_mounted((const TCHAR**)&path, &dj.fs, 0);
- if (res == FR_OK) {
- INIT_BUF(dj);
- i = sz_path;
- dj.sclust = dj.fs->cdir;
- while ((ccl = dj.sclust) != 0) {
- res = dir_sdi(&dj, 1);
- if (res != FR_OK) break;
- res = dir_read(&dj);
- if (res != FR_OK) break;
- dj.sclust = ld_clust(dj.fs, dj.dir);
- res = dir_sdi(&dj, 0);
- if (res != FR_OK) break;
- do {
- res = dir_read(&dj);
- if (res != FR_OK) break;
- if (ccl == ld_clust(dj.fs, dj.dir)) break;
- res = dir_next(&dj, 0);
- } while (res == FR_OK);
- if (res == FR_NO_FILE) res = FR_INT_ERR;
- if (res != FR_OK) break;
- #if _USE_LFN
- fno.lfname = path;
- fno.lfsize = i;
- #endif
- get_fileinfo(&dj, &fno);
- tp = fno.fname;
- if (_USE_LFN && *path) tp = path;
- for (n = 0; tp[n]; n++) ;
- if (i < n + 3) {
- res = FR_NOT_ENOUGH_CORE; break;
- }
- while (n) path[--i] = tp[--n];
- path[--i] = '/';
- }
- tp = path;
- if (res == FR_OK) {
- *tp++ = '0' + CurrVol;
- *tp++ = ':';
- if (i == sz_path) {
- *tp++ = '/';
- } else {
- do
- *tp++ = path[i++];
- while (i < sz_path);
- }
- }
- *tp = 0;
- FREE_BUF();
- }
- LEAVE_FF(dj.fs, res);
- }
- #endif
- #endif
- #if _FS_MINIMIZE <= 2
- FRESULT f_lseek (
- FIL *fp,
- DWORD ofs
- )
- {
- FRESULT res;
- res = validate(fp);
- if (res != FR_OK) LEAVE_FF(fp->fs, res);
- if (fp->flag & FA__ERROR)
- LEAVE_FF(fp->fs, FR_INT_ERR);
- #if _USE_FASTSEEK
- if (fp->cltbl) {
- DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;
- if (ofs == CREATE_LINKMAP) {
- tbl = fp->cltbl;
- tlen = *tbl++; ulen = 2;
- cl = fp->sclust;
- if (cl) {
- do {
-
- tcl = cl; ncl = 0; ulen += 2;
- do {
- pcl = cl; ncl++;
- cl = get_fat(fp->fs, cl);
- if (cl <= 1) ABORT(fp->fs, FR_INT_ERR);
- if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- } while (cl == pcl + 1);
- if (ulen <= tlen) {
- *tbl++ = ncl; *tbl++ = tcl;
- }
- } while (cl < fp->fs->n_fatent);
- }
- *fp->cltbl = ulen;
- if (ulen <= tlen)
- *tbl = 0;
- else
- res = FR_NOT_ENOUGH_CORE;
- } else {
- if (ofs > fp->fsize)
- ofs = fp->fsize;
- fp->fptr = ofs;
- if (ofs) {
- fp->clust = clmt_clust(fp, ofs - 1);
- dsc = clust2sect(fp->fs, fp->clust);
- if (!dsc) ABORT(fp->fs, FR_INT_ERR);
- dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1);
- if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) {
- #if !_FS_TINY
- #if !_FS_READONLY
- if (fp->flag & FA__DIRTY) {
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
- #endif
- if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- #endif
- fp->dsect = dsc;
- }
- }
- }
- } else
- #endif
-
- {
- DWORD clst, bcs, nsect, ifptr;
- if (ofs > fp->fsize
- #if !_FS_READONLY
- && !(fp->flag & FA_WRITE)
- #endif
- ) ofs = fp->fsize;
- ifptr = fp->fptr;
- fp->fptr = nsect = 0;
- if (ofs) {
- bcs = (DWORD)fp->fs->csize * SS(fp->fs);
- if (ifptr > 0 &&
- (ofs - 1) / bcs >= (ifptr - 1) / bcs) {
- fp->fptr = (ifptr - 1) & ~(bcs - 1);
- ofs -= fp->fptr;
- clst = fp->clust;
- } else {
- clst = fp->sclust;
- #if !_FS_READONLY
- if (clst == 0) {
- clst = create_chain(fp->fs, 0);
- if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- fp->sclust = clst;
- }
- #endif
- fp->clust = clst;
- }
- if (clst != 0) {
- while (ofs > bcs) {
- #if !_FS_READONLY
- if (fp->flag & FA_WRITE) {
- clst = create_chain(fp->fs, clst);
- if (clst == 0) {
- ofs = bcs; break;
- }
- } else
- #endif
- clst = get_fat(fp->fs, clst);
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR);
- fp->clust = clst;
- fp->fptr += bcs;
- ofs -= bcs;
- }
- fp->fptr += ofs;
- if (ofs % SS(fp->fs)) {
- nsect = clust2sect(fp->fs, clst);
- if (!nsect) ABORT(fp->fs, FR_INT_ERR);
- nsect += ofs / SS(fp->fs);
- }
- }
- }
- if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) {
- #if !_FS_TINY
- #if !_FS_READONLY
- if (fp->flag & FA__DIRTY) {
- if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- fp->flag &= ~FA__DIRTY;
- }
- #endif
- if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK)
- ABORT(fp->fs, FR_DISK_ERR);
- #endif
- fp->dsect = nsect;
- }
- #if !_FS_READONLY
- if (fp->fptr > fp->fsize) {
- fp->fsize = fp->fptr;
- fp->flag |= FA__WRITTEN;
- }
- #endif
- }
- LEAVE_FF(fp->fs, res);
- }
- #if _FS_MINIMIZE <= 1
- FRESULT f_opendir (
- DIR *dj,
- const TCHAR *path
- )
- {
- FRESULT res;
- FATFS *fs;
- DEF_NAMEBUF;
- if (!dj) return FR_INVALID_OBJECT;
- res = chk_mounted(&path, &dj->fs, 0);
- fs = dj->fs;
- if (res == FR_OK) {
- INIT_BUF(*dj);
- res = follow_path(dj, path);
- FREE_BUF();
- if (res == FR_OK) {
- if (dj->dir) {
- if (dj->dir[DIR_Attr] & AM_DIR) {
- dj->sclust = ld_clust(fs, dj->dir);
- } else {
- res = FR_NO_PATH;
- }
- }
- if (res == FR_OK) {
- dj->id = fs->id;
- res = dir_sdi(dj, 0);
- }
- }
- if (res == FR_NO_FILE) res = FR_NO_PATH;
- if (res != FR_OK) dj->fs = 0;
- } else {
- dj->fs = 0;
- }
- LEAVE_FF(fs, res);
- }
- FRESULT f_readdir (
- DIR *dj,
- FILINFO *fno
- )
- {
- FRESULT res;
- DEF_NAMEBUF;
- res = validate(dj);
- if (res == FR_OK) {
- if (!fno) {
- res = dir_sdi(dj, 0);
- } else {
- INIT_BUF(*dj);
- res = dir_read(dj);
- if (res == FR_NO_FILE) {
- dj->sect = 0;
- res = FR_OK;
- }
- if (res == FR_OK) {
- get_fileinfo(dj, fno);
- res = dir_next(dj, 0);
- if (res == FR_NO_FILE) {
- dj->sect = 0;
- res = FR_OK;
- }
- }
- FREE_BUF();
- }
- }
- LEAVE_FF(dj->fs, res);
- }
- #if _FS_MINIMIZE == 0
- FRESULT f_stat (
- const TCHAR *path,
- FILINFO *fno
- )
- {
- FRESULT res;
- DIR dj;
- DEF_NAMEBUF;
- res = chk_mounted(&path, &dj.fs, 0);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path);
- if (res == FR_OK) {
- if (dj.dir)
- get_fileinfo(&dj, fno);
- else
- res = FR_INVALID_NAME;
- }
- FREE_BUF();
- }
- LEAVE_FF(dj.fs, res);
- }
- #if !_FS_READONLY
- FRESULT f_getfree (
- const TCHAR *path,
- DWORD *nclst,
- FATFS **fatfs
- )
- {
- FRESULT res;
- FATFS *fs;
- DWORD n, clst, sect, stat;
- UINT i;
- BYTE fat, *p;
-
- res = chk_mounted(&path, fatfs, 0);
- fs = *fatfs;
- if (res == FR_OK) {
-
- if (fs->free_clust <= fs->n_fatent - 2) {
- *nclst = fs->free_clust;
- } else {
-
- fat = fs->fs_type;
- n = 0;
- if (fat == FS_FAT12) {
- clst = 2;
- do {
- stat = get_fat(fs, clst);
- if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }
- if (stat == 1) { res = FR_INT_ERR; break; }
- if (stat == 0) n++;
- } while (++clst < fs->n_fatent);
- } else {
- clst = fs->n_fatent;
- sect = fs->fatbase;
- i = 0; p = 0;
- do {
- if (!i) {
- res = move_window(fs, sect++);
- if (res != FR_OK) break;
- p = fs->win;
- i = SS(fs);
- }
- if (fat == FS_FAT16) {
- if (LD_WORD(p) == 0) n++;
- p += 2; i -= 2;
- } else {
- if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++;
- p += 4; i -= 4;
- }
- } while (--clst);
- }
- fs->free_clust = n;
- if (fat == FS_FAT32) fs->fsi_flag = 1;
- *nclst = n;
- }
- }
- LEAVE_FF(fs, res);
- }
- FRESULT f_truncate (
- FIL *fp
- )
- {
- FRESULT res;
- DWORD ncl;
- if (!fp) return FR_INVALID_OBJECT;
- res = validate(fp);
- if (res == FR_OK) {
- if (fp->flag & FA__ERROR) {
- res = FR_INT_ERR;
- } else {
- if (!(fp->flag & FA_WRITE))
- res = FR_DENIED;
- }
- }
- if (res == FR_OK) {
- if (fp->fsize > fp->fptr) {
- fp->fsize = fp->fptr;
- fp->flag |= FA__WRITTEN;
- if (fp->fptr == 0) {
- res = remove_chain(fp->fs, fp->sclust);
- fp->sclust = 0;
- } else {
- ncl = get_fat(fp->fs, fp->clust);
- res = FR_OK;
- if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;
- if (ncl == 1) res = FR_INT_ERR;
- if (res == FR_OK && ncl < fp->fs->n_fatent) {
- res = put_fat(fp->fs, fp->clust, 0x0FFFFFFF);
- if (res == FR_OK) res = remove_chain(fp->fs, ncl);
- }
- }
- }
- if (res != FR_OK) fp->flag |= FA__ERROR;
- }
- LEAVE_FF(fp->fs, res);
- }
- FRESULT f_unlink (
- const TCHAR *path
- )
- {
- FRESULT res;
- DIR dj, sdj;
- BYTE *dir;
- DWORD dclst;
- DEF_NAMEBUF;
- res = chk_mounted(&path, &dj.fs, 1);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path);
- if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME;
- #if _FS_LOCK
- if (res == FR_OK) res = chk_lock(&dj, 2);
- #endif
- if (res == FR_OK) {
- dir = dj.dir;
- if (!dir) {
- res = FR_INVALID_NAME;
- } else {
- if (dir[DIR_Attr] & AM_RDO)
- res = FR_DENIED;
- }
- dclst = ld_clust(dj.fs, dir);
- if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) {
- if (dclst < 2) {
- res = FR_INT_ERR;
- } else {
- mem_cpy(&sdj, &dj, sizeof (DIR));
- sdj.sclust = dclst;
- res = dir_sdi(&sdj, 2);
- if (res == FR_OK) {
- res = dir_read(&sdj);
- if (res == FR_OK
- #if _FS_RPATH
- || dclst == dj.fs->cdir
- #endif
- ) res = FR_DENIED;
- if (res == FR_NO_FILE) res = FR_OK;
- }
- }
- }
- if (res == FR_OK) {
- res = dir_remove(&dj);
- if (res == FR_OK) {
- if (dclst)
- res = remove_chain(dj.fs, dclst);
- if (res == FR_OK) res = sync(dj.fs);
- }
- }
- }
- FREE_BUF();
- }
- LEAVE_FF(dj.fs, res);
- }
- FRESULT f_mkdir (
- const TCHAR *path
- )
- {
- FRESULT res;
- DIR dj;
- BYTE *dir, n;
- DWORD dsc, dcl, pcl, tim = get_fattime();
- DEF_NAMEBUF;
- res = chk_mounted(&path, &dj.fs, 1);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path);
- if (res == FR_OK) res = FR_EXIST;
- if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME;
- if (res == FR_NO_FILE) {
- dcl = create_chain(dj.fs, 0);
- res = FR_OK;
- if (dcl == 0) res = FR_DENIED;
- if (dcl == 1) res = FR_INT_ERR;
- if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR;
- if (res == FR_OK)
- res = move_window(dj.fs, 0);
- if (res == FR_OK) {
- dsc = clust2sect(dj.fs, dcl);
- dir = dj.fs->win;
- mem_set(dir, 0, SS(dj.fs));
- mem_set(dir+DIR_Name, ' ', 8+3);
- dir[DIR_Name] = '.';
- dir[DIR_Attr] = AM_DIR;
- ST_DWORD(dir+DIR_WrtTime, tim);
- st_clust(dir, dcl);
- mem_cpy(dir+SZ_DIR, dir, SZ_DIR);
- dir[33] = '.'; pcl = dj.sclust;
- if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase)
- pcl = 0;
- st_clust(dir+SZ_DIR, pcl);
- for (n = dj.fs->csize; n; n--) {
- dj.fs->winsect = dsc++;
- dj.fs->wflag = 1;
- res = move_window(dj.fs, 0);
- if (res != FR_OK) break;
- mem_set(dir, 0, SS(dj.fs));
- }
- }
- if (res == FR_OK) res = dir_register(&dj);
- if (res != FR_OK) {
- remove_chain(dj.fs, dcl);
- } else {
- dir = dj.dir;
- dir[DIR_Attr] = AM_DIR;
- ST_DWORD(dir+DIR_WrtTime, tim);
- st_clust(dir, dcl);
- dj.fs->wflag = 1;
- res = sync(dj.fs);
- }
- }
- FREE_BUF();
- }
- LEAVE_FF(dj.fs, res);
- }
- FRESULT f_chmod (
- const TCHAR *path,
- BYTE value,
- BYTE mask
- )
- {
- FRESULT res;
- DIR dj;
- BYTE *dir;
- DEF_NAMEBUF;
- res = chk_mounted(&path, &dj.fs, 1);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path);
- FREE_BUF();
- if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME;
- if (res == FR_OK) {
- dir = dj.dir;
- if (!dir) {
- res = FR_INVALID_NAME;
- } else {
- mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC;
- dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask);
- dj.fs->wflag = 1;
- res = sync(dj.fs);
- }
- }
- }
- LEAVE_FF(dj.fs, res);
- }
- FRESULT f_utime (
- const TCHAR *path,
- const FILINFO *fno
- )
- {
- FRESULT res;
- DIR dj;
- BYTE *dir;
- DEF_NAMEBUF;
- res = chk_mounted(&path, &dj.fs, 1);
- if (res == FR_OK) {
- INIT_BUF(dj);
- res = follow_path(&dj, path);
- FREE_BUF();
- if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME;
- if (res == FR_OK) {
- dir = dj.dir;
- if (!dir) {
- res = FR_INVALID_NAME;
- } else {
- ST_WORD(dir+DIR_WrtTime, fno->ftime);
- ST_WORD(dir+DIR_WrtDate, fno->fdate);
- dj.fs->wflag = 1;
- res = sync(dj.fs);
- }
- }
- }
- LEAVE_FF(dj.fs, res);
- }
- FRESULT f_rename (
- const TCHAR *path_old,
- const TCHAR *path_new
- )
- {
- FRESULT res;
- DIR djo, djn;
- BYTE buf[21], *dir;
- DWORD dw;
- DEF_NAMEBUF;
- res = chk_mounted(&path_old, &djo.fs, 1);
- if (res == FR_OK) {
- djn.fs = djo.fs;
- INIT_BUF(djo);
- res = follow_path(&djo, path_old);
- if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT))
- res = FR_INVALID_NAME;
- #if _FS_LOCK
- if (res == FR_OK) res = chk_lock(&djo, 2);
- #endif
- if (res == FR_OK) {
- if (!djo.dir) {
- res = FR_NO_FILE;
- } else {
- mem_cpy(buf, djo.dir+DIR_Attr, 21);
- mem_cpy(&djn, &djo, sizeof (DIR));
- res = follow_path(&djn, path_new);
- if (res == FR_OK) res = FR_EXIST;
- if (res == FR_NO_FILE) {
- res = dir_register(&djn);
- if (res == FR_OK) {
- dir = djn.dir;
- mem_cpy(dir+13, buf+2, 19);
- dir[DIR_Attr] = buf[0] | AM_ARC;
- djo.fs->wflag = 1;
- if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) {
- dw = clust2sect(djo.fs, ld_clust(djo.fs, dir));
- if (!dw) {
- res = FR_INT_ERR;
- } else {
- res = move_window(djo.fs, dw);
- dir = djo.fs->win+SZ_DIR;
- if (res == FR_OK && dir[1] == '.') {
- dw = (djo.fs->fs_type == FS_FAT32 && djn.sclust == djo.fs->dirbase) ? 0 : djn.sclust;
- st_clust(dir, dw);
- djo.fs->wflag = 1;
- }
- }
- }
- if (res == FR_OK) {
- res = dir_remove(&djo);
- if (res == FR_OK)
- res = sync(djo.fs);
- }
- }
- }
- }
- }
- FREE_BUF();
- }
- LEAVE_FF(djo.fs, res);
- }
- #endif
- #endif
- #endif
- #endif
- #if _USE_FORWARD && _FS_TINY
- FRESULT f_forward (
- FIL *fp,
- UINT (*func)(const BYTE*,UINT),
- UINT btr,
- UINT *bf
- )
- {
- FRESULT res;
- DWORD remain, clst, sect;
- UINT rcnt;
- BYTE csect;
- *bf = 0;
- if (!fp) return FR_INVALID_OBJECT;
- res = validate(fp);
- if (res != FR_OK) LEAVE_FF(fp->fs, res);
- if (fp->flag & FA__ERROR)
- LEAVE_FF(fp->fs, FR_INT_ERR);
- if (!(fp->flag & FA_READ))
- LEAVE_FF(fp->fs, FR_DENIED);
- remain = fp->fsize - fp->fptr;
- if (btr > remain) btr = (UINT)remain;
- for ( ; btr && (*func)(0, 0);
- fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {
- csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));
- if ((fp->fptr % SS(fp->fs)) == 0) {
- if (!csect) {
- clst = (fp->fptr == 0) ?
- fp->sclust : get_fat(fp->fs, fp->clust);
- if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
- if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
- fp->clust = clst;
- }
- }
- sect = clust2sect(fp->fs, fp->clust);
- if (!sect) ABORT(fp->fs, FR_INT_ERR);
- sect += csect;
- if (move_window(fp->fs, sect))
- ABORT(fp->fs, FR_DISK_ERR);
- fp->dsect = sect;
- rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs));
- if (rcnt > btr) rcnt = btr;
- rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt);
- if (!rcnt) ABORT(fp->fs, FR_INT_ERR);
- }
- LEAVE_FF(fp->fs, FR_OK);
- }
- #endif
- #if _USE_MKFS && !_FS_READONLY
- #define N_ROOTDIR 512
- #define N_FATS 1
- FRESULT f_mkfs (
- BYTE drv,
- BYTE sfd,
- UINT au
- )
- {
- static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0};
- static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512};
- BYTE fmt, md, sys, *tbl, pdrv, part;
- DWORD n_clst, vs, n, wsect;
- UINT i;
- DWORD b_vol, b_fat, b_dir, b_data;
- DWORD n_vol, n_rsv, n_fat, n_dir;
- FATFS *fs;
- DSTATUS stat;
-
- if (drv >= _VOLUMES) return FR_INVALID_DRIVE;
- if (sfd > 1) return FR_INVALID_PARAMETER;
- if (au & (au - 1)) return FR_INVALID_PARAMETER;
- fs = FatFs[drv];
- if (!fs) return FR_NOT_ENABLED;
- fs->fs_type = 0;
- pdrv = LD2PD(drv);
- part = LD2PT(drv);
-
- stat = disk_initialize(pdrv);
- if (stat & STA_NOINIT) return FR_NOT_READY;
- if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
- #if _MAX_SS != 512
- if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS)
- return FR_DISK_ERR;
- #endif
- if (_MULTI_PARTITION && part) {
-
- if (disk_read(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;
- if (LD_WORD(fs->win+BS_55AA) != 0xAA55) return FR_MKFS_ABORTED;
- tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
- if (!tbl[4]) return FR_MKFS_ABORTED;
- b_vol = LD_DWORD(tbl+8);
- n_vol = LD_DWORD(tbl+12);
- } else {
-
- if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128)
- return FR_DISK_ERR;
- b_vol = (sfd) ? 0 : 63;
- n_vol -= b_vol;
- }
- if (!au) {
- vs = n_vol / (2000 / (SS(fs) / 512));
- for (i = 0; vs < vst[i]; i++) ;
- au = cst[i];
- }
- au /= SS(fs);
- if (au == 0) au = 1;
- if (au > 128) au = 128;
-
- n_clst = n_vol / au;
- fmt = FS_FAT12;
- if (n_clst >= MIN_FAT16) fmt = FS_FAT16;
- if (n_clst >= MIN_FAT32) fmt = FS_FAT32;
-
- if (fmt == FS_FAT32) {
- n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs);
- n_rsv = 32;
- n_dir = 0;
- } else {
- n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4;
- n_fat = (n_fat + SS(fs) - 1) / SS(fs);
- n_rsv = 1;
- n_dir = (DWORD)N_ROOTDIR * SZ_DIR / SS(fs);
- }
- b_fat = b_vol + n_rsv;
- b_dir = b_fat + n_fat * N_FATS;
- b_data = b_dir + n_dir;
- if (n_vol < b_data + au - b_vol) return FR_MKFS_ABORTED;
-
- if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &n) != RES_OK || !n || n > 32768) n = 1;
- n = (b_data + n - 1) & ~(n - 1);
- n = (n - b_data) / N_FATS;
- if (fmt == FS_FAT32) {
- n_rsv += n;
- b_fat += n;
- } else {
- n_fat += n;
- }
-
- n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au;
- if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16)
- || (fmt == FS_FAT32 && n_clst < MIN_FAT32))
- return FR_MKFS_ABORTED;
- switch (fmt) {
- case FS_FAT12: sys = 0x01; break;
- case FS_FAT16: sys = (n_vol < 0x10000) ? 0x04 : 0x06; break;
- default: sys = 0x0C;
- }
- if (_MULTI_PARTITION && part) {
-
- tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
- tbl[4] = sys;
- if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;
- md = 0xF8;
- } else {
- if (sfd) {
- md = 0xF0;
- } else {
- mem_set(fs->win, 0, SS(fs));
- tbl = fs->win+MBR_Table;
- tbl[1] = 1;
- tbl[2] = 1;
- tbl[3] = 0;
- tbl[4] = sys;
- tbl[5] = 254;
- n = (b_vol + n_vol) / 63 / 255;
- tbl[6] = (BYTE)((n >> 2) | 63);
- tbl[7] = (BYTE)n;
- ST_DWORD(tbl+8, 63);
- ST_DWORD(tbl+12, n_vol);
- ST_WORD(fs->win+BS_55AA, 0xAA55);
- if (disk_write(pdrv, fs->win, 0, 1) != RES_OK)
- return FR_DISK_ERR;
- md = 0xF8;
- }
- }
-
- tbl = fs->win;
- mem_set(tbl, 0, SS(fs));
- mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);
- i = SS(fs);
- ST_WORD(tbl+BPB_BytsPerSec, i);
- tbl[BPB_SecPerClus] = (BYTE)au;
- ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv);
- tbl[BPB_NumFATs] = N_FATS;
- i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR;
- ST_WORD(tbl+BPB_RootEntCnt, i);
- if (n_vol < 0x10000) {
- ST_WORD(tbl+BPB_TotSec16, n_vol);
- } else {
- ST_DWORD(tbl+BPB_TotSec32, n_vol);
- }
- tbl[BPB_Media] = md;
- ST_WORD(tbl+BPB_SecPerTrk, 63);
- ST_WORD(tbl+BPB_NumHeads, 255);
- ST_DWORD(tbl+BPB_HiddSec, b_vol);
- n = get_fattime();
- if (fmt == FS_FAT32) {
- ST_DWORD(tbl+BS_VolID32, n);
- ST_DWORD(tbl+BPB_FATSz32, n_fat);
- ST_DWORD(tbl+BPB_RootClus, 2);
- ST_WORD(tbl+BPB_FSInfo, 1);
- ST_WORD(tbl+BPB_BkBootSec, 6);
- tbl[BS_DrvNum32] = 0x80;
- tbl[BS_BootSig32] = 0x29;
- mem_cpy(tbl+BS_VolLab32, "NO NAME " "FAT32 ", 19);
- } else {
- ST_DWORD(tbl+BS_VolID, n);
- ST_WORD(tbl+BPB_FATSz16, n_fat);
- tbl[BS_DrvNum] = 0x80;
- tbl[BS_BootSig] = 0x29;
- mem_cpy(tbl+BS_VolLab, "NO NAME " "FAT ", 19);
- }
- ST_WORD(tbl+BS_55AA, 0xAA55);
- if (disk_write(pdrv, tbl, b_vol, 1) != RES_OK)
- return FR_DISK_ERR;
- if (fmt == FS_FAT32)
- disk_write(pdrv, tbl, b_vol + 6, 1);
-
- wsect = b_fat;
- for (i = 0; i < N_FATS; i++) {
- mem_set(tbl, 0, SS(fs));
- n = md;
- if (fmt != FS_FAT32) {
- n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00;
- ST_DWORD(tbl+0, n);
- } else {
- n |= 0xFFFFFF00;
- ST_DWORD(tbl+0, n);
- ST_DWORD(tbl+4, 0xFFFFFFFF);
- ST_DWORD(tbl+8, 0x0FFFFFFF);
- }
- if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
- return FR_DISK_ERR;
- mem_set(tbl, 0, SS(fs));
- for (n = 1; n < n_fat; n++) {
- if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
- return FR_DISK_ERR;
- }
- }
-
- i = (fmt == FS_FAT32) ? au : n_dir;
- do {
- if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
- return FR_DISK_ERR;
- } while (--i);
- #if _USE_ERASE
- {
- DWORD eb[2];
- eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
- disk_ioctl(pdrv, CTRL_ERASE_SECTOR, eb);
- }
- #endif
-
- if (fmt == FS_FAT32) {
- ST_DWORD(tbl+FSI_LeadSig, 0x41615252);
- ST_DWORD(tbl+FSI_StrucSig, 0x61417272);
- ST_DWORD(tbl+FSI_Free_Count, n_clst - 1);
- ST_DWORD(tbl+FSI_Nxt_Free, 2);
- ST_WORD(tbl+BS_55AA, 0xAA55);
- disk_write(pdrv, tbl, b_vol + 1, 1);
- disk_write(pdrv, tbl, b_vol + 7, 1);
- }
- return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
- }
- #if _MULTI_PARTITION == 2
- FRESULT f_fdisk (
- BYTE pdrv,
- const DWORD szt[],
- void* work
- )
- {
- UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl;
- BYTE s_hd, e_hd, *p, *buf = (BYTE*)work;
- DSTATUS stat;
- DWORD sz_disk, sz_part, s_part;
- stat = disk_initialize(pdrv);
- if (stat & STA_NOINIT) return FR_NOT_READY;
- if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
- if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR;
-
- for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ;
- if (n == 256) n--;
- e_hd = n - 1;
- sz_cyl = 63 * n;
- tot_cyl = sz_disk / sz_cyl;
-
- mem_set(buf, 0, _MAX_SS);
- p = buf + MBR_Table; b_cyl = 0;
- for (i = 0; i < 4; i++, p += SZ_PTE) {
- p_cyl = (szt[i] <= 100) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl;
- if (!p_cyl) continue;
- s_part = (DWORD)sz_cyl * b_cyl;
- sz_part = (DWORD)sz_cyl * p_cyl;
- if (i == 0) {
- s_hd = 1;
- s_part += 63; sz_part -= 63;
- } else {
- s_hd = 0;
- }
- e_cyl = b_cyl + p_cyl - 1;
- if (e_cyl >= tot_cyl) return FR_INVALID_PARAMETER;
-
- p[1] = s_hd;
- p[2] = (BYTE)((b_cyl >> 2) + 1);
- p[3] = (BYTE)b_cyl;
- p[4] = 0x06;
- p[5] = e_hd;
- p[6] = (BYTE)((e_cyl >> 2) + 63);
- p[7] = (BYTE)e_cyl;
- ST_DWORD(p + 8, s_part);
- ST_DWORD(p + 12, sz_part);
-
- b_cyl += p_cyl;
- }
- ST_WORD(p, 0xAA55);
-
- return (disk_write(pdrv, buf, 0, 1) || disk_ioctl(pdrv, CTRL_SYNC, 0)) ? FR_DISK_ERR : FR_OK;
- }
- #endif
- #endif
- #if _USE_STRFUNC
- TCHAR* f_gets (
- TCHAR* buff,
- int len,
- FIL* fil
- )
- {
- int n = 0;
- TCHAR c, *p = buff;
- BYTE s[2];
- UINT rc;
- while (n < len - 1) {
- f_read(fil, s, 1, &rc);
- if (rc != 1) break;
- c = s[0];
- #if _LFN_UNICODE
- if (c >= 0x80) {
- if (c < 0xC0) continue;
- if (c < 0xE0) {
- f_read(fil, s, 1, &rc);
- if (rc != 1) break;
- c = ((c & 0x1F) << 6) | (s[0] & 0x3F);
- if (c < 0x80) c = '?';
- } else {
- if (c < 0xF0) {
- f_read(fil, s, 2, &rc);
- if (rc != 2) break;
- c = (c << 12) | ((s[0] & 0x3F) << 6) | (s[1] & 0x3F);
- if (c < 0x800) c = '?';
- } else {
- c = '?';
- }
- }
- }
- #endif
- #if _USE_STRFUNC >= 2
- if (c == '\r') continue;
- #endif
- *p++ = c;
- n++;
- if (c == '\n') break;
- }
- *p = 0;
- return n ? buff : 0;
- }
- #if !_FS_READONLY
- #include <stdarg.h>
- int f_putc (
- TCHAR c,
- FIL* fil
- )
- {
- UINT bw, btw;
- BYTE s[3];
- #if _USE_STRFUNC >= 2
- if (c == '\n') f_putc ('\r', fil);
- #endif
- #if _LFN_UNICODE
- if (c < 0x80) {
- s[0] = (BYTE)c;
- btw = 1;
- } else {
- if (c < 0x800) {
- s[0] = (BYTE)(0xC0 | (c >> 6));
- s[1] = (BYTE)(0x80 | (c & 0x3F));
- btw = 2;
- } else {
- s[0] = (BYTE)(0xE0 | (c >> 12));
- s[1] = (BYTE)(0x80 | ((c >> 6) & 0x3F));
- s[2] = (BYTE)(0x80 | (c & 0x3F));
- btw = 3;
- }
- }
- #else
- s[0] = (BYTE)c;
- btw = 1;
- #endif
- f_write(fil, s, btw, &bw);
- return (bw == btw) ? 1 : EOF;
- }
- int f_puts (
- const TCHAR* str,
- FIL* fil
- )
- {
- int n;
- for (n = 0; *str; str++, n++) {
- if (f_putc(*str, fil) == EOF) return EOF;
- }
- return n;
- }
- int f_printf (
- FIL* fil,
- const TCHAR* str,
- ...
- )
- {
- va_list arp;
- BYTE f, r;
- UINT i, j, w;
- ULONG v;
- TCHAR c, d, s[16], *p;
- int res, chc, cc;
- va_start(arp, str);
- for (cc = res = 0; cc != EOF; res += cc) {
- c = *str++;
- if (c == 0) break;
- if (c != '%') {
- cc = f_putc(c, fil);
- if (cc != EOF) cc = 1;
- continue;
- }
- w = f = 0;
- c = *str++;
- if (c == '0') {
- f = 1; c = *str++;
- } else {
- if (c == '-') {
- f = 2; c = *str++;
- }
- }
- while (IsDigit(c)) {
- w = w * 10 + c - '0';
- c = *str++;
- }
- if (c == 'l' || c == 'L') {
- f |= 4; c = *str++;
- }
- if (!c) break;
- d = c;
- if (IsLower(d)) d -= 0x20;
- switch (d) {
- case 'S' :
- p = va_arg(arp, TCHAR*);
- for (j = 0; p[j]; j++) ;
- chc = 0;
- if (!(f & 2)) {
- while (j++ < w) chc += (cc = f_putc(' ', fil));
- }
- chc += (cc = f_puts(p, fil));
- while (j++ < w) chc += (cc = f_putc(' ', fil));
- if (cc != EOF) cc = chc;
- continue;
- case 'C' :
- cc = f_putc((TCHAR)va_arg(arp, int), fil); continue;
- case 'B' :
- r = 2; break;
- case 'O' :
- r = 8; break;
- case 'D' :
- case 'U' :
- r = 10; break;
- case 'X' :
- r = 16; break;
- default:
- cc = f_putc(c, fil); continue;
- }
-
- v = (f & 4) ? (ULONG)va_arg(arp, long) : ((d == 'D') ? (ULONG)(long)va_arg(arp, int) : (ULONG)va_arg(arp, unsigned int));
- if (d == 'D' && (v & 0x80000000)) {
- v = 0 - v;
- f |= 8;
- }
- i = 0;
- do {
- d = (TCHAR)(v % r); v /= r;
- if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
- s[i++] = d + '0';
- } while (v && i < sizeof s / sizeof s[0]);
- if (f & 8) s[i++] = '-';
- j = i; d = (f & 1) ? '0' : ' ';
- res = 0;
- while (!(f & 2) && j++ < w) res += (cc = f_putc(d, fil));
- do res += (cc = f_putc(s[--i], fil)); while(i);
- while (j++ < w) res += (cc = f_putc(' ', fil));
- if (cc != EOF) cc = res;
- }
- va_end(arp);
- return (cc == EOF) ? cc : res;
- }
- #endif
- #endif
|