| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987 | 
							- {**************************************************************************************************}
 
- {                                                                                                  }
 
- { Project JEDI Code Library (JCL)                                                                  }
 
- {                                                                                                  }
 
- { The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
 
- { you may not use this file except in compliance with the License. You may obtain a copy of the    }
 
- { License at http://www.mozilla.org/MPL/                                                           }
 
- {                                                                                                  }
 
- { Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF   }
 
- { ANY KIND, either express or implied. See the License for the specific language governing rights  }
 
- { and limitations under the License.                                                               }
 
- {                                                                                                  }
 
- { The Original Code is JclPeImage.pas.                                                             }
 
- {                                                                                                  }
 
- { The Initial Developer of the Original Code is Petr Vones. Portions created by Petr Vones are     }
 
- { Copyright (C) Petr Vones. All Rights Reserved.                                                   }
 
- {                                                                                                  }
 
- { Contributor(s):                                                                                  }
 
- {   Marcel van Brakel                                                                              }
 
- {   Robert Marquardt (marquardt)                                                                   }
 
- {   Uwe Schuster (uschuster)                                                                       }
 
- {   Matthias Thoma (mthoma)                                                                        }
 
- {   Petr Vones (pvones)                                                                            }
 
- {   Hallvard Vassbotn                                                                              }
 
- {   Jean-Fabien Connault (cycocrew)                                                                }
 
- {                                                                                                  }
 
- {**************************************************************************************************}
 
- {                                                                                                  }
 
- { This unit contains various classes and support routines to read the contents of portable         }
 
- { executable (PE) files. You can use these classes to, for example examine the contents of the     }
 
- { imports section of an executable. In addition the unit contains support for Borland specific     }
 
- { structures and name unmangling.                                                                  }
 
- {                                                                                                  }
 
- {**************************************************************************************************}
 
- {                                                                                                  }
 
- { Last modified: $Date::                                                                         $ }
 
- { Revision:      $Rev::                                                                          $ }
 
- { Author:        $Author::                                                                       $ }
 
- {                                                                                                  }
 
- {**************************************************************************************************}
 
- unit JclPeImage;
 
- {$I jcl.inc}
 
- {$I windowsonly.inc}
 
- interface
 
- uses
 
-   {$IFDEF UNITVERSIONING}
 
-   JclUnitVersioning,
 
-   {$ENDIF UNITVERSIONING}
 
-   {$IFDEF HAS_UNITSCOPE}
 
-   Winapi.Windows, System.Classes, System.SysUtils, System.TypInfo, System.Contnrs,
 
-   {$ELSE ~HAS_UNITSCOPE}
 
-   Windows, Classes, SysUtils, TypInfo, Contnrs,
 
-   {$ENDIF ~HAS_UNITSCOPE}
 
-   JclBase, {$IFNDEF WINSCP}JclDateTime,{$ENDIF ~WINSCP} JclFileUtils, JclWin32;
 
- type
 
-   // Smart name compare function
 
-   TJclSmartCompOption = (scSimpleCompare, scIgnoreCase);
 
-   TJclSmartCompOptions = set of TJclSmartCompOption;
 
- function PeStripFunctionAW(const FunctionName: string): string;
 
- function PeSmartFunctionNameSame(const ComparedName, FunctionName: string;
 
-   Options: TJclSmartCompOptions = []): Boolean;
 
- type
 
-   // Base list
 
-   EJclPeImageError = class(EJclError);
 
-   TJclPeImage = class;
 
-   TJclPeImageClass = class of TJclPeImage;
 
-   TJclPeImageBaseList = class(TObjectList)
 
-   private
 
-     FImage: TJclPeImage;
 
-   public
 
-     constructor Create(AImage: TJclPeImage);
 
-     property Image: TJclPeImage read FImage;
 
-   end;
 
-   // Images cache
 
-   TJclPeImagesCache = class(TObject)
 
-   private
 
-     FList: TStringList;
 
-     function GetCount: Integer;
 
-     function GetImages(const FileName: TFileName): TJclPeImage;
 
-   protected
 
-     function GetPeImageClass: TJclPeImageClass; virtual;
 
-   public
 
-     constructor Create;
 
-     destructor Destroy; override;
 
-     procedure Clear;
 
-     property Images[const FileName: TFileName]: TJclPeImage read GetImages; default;
 
-     property Count: Integer read GetCount;
 
-   end;
 
-   // Import section related classes
 
-   TJclPeImportSort = (isName, isOrdinal, isHint, isLibImport);
 
-   TJclPeImportLibSort = (ilName, ilIndex);
 
-   TJclPeImportKind = (ikImport, ikDelayImport, ikBoundImport);
 
-   TJclPeResolveCheck = (icNotChecked, icResolved, icUnresolved);
 
-   TJclPeLinkerProducer = (lrBorland, lrMicrosoft);
 
-   // lrBorland   -> Delphi PE files
 
-   // lrMicrosoft -> MSVC and BCB PE files
 
-   TJclPeImportLibItem = class;
 
-   // Created from a IMAGE_THUNK_DATA64 or IMAGE_THUNK_DATA32 record
 
-   TJclPeImportFuncItem = class(TObject)
 
-   private
 
-     FOrdinal: Word;  // word in 32/64
 
-     FHint: Word;
 
-     FImportLib: TJclPeImportLibItem;
 
-     FIndirectImportName: Boolean;
 
-     FName: string;
 
-     FResolveCheck: TJclPeResolveCheck;
 
-     function GetIsByOrdinal: Boolean;
 
-   protected
 
-     procedure SetName(const Value: string);
 
-     procedure SetIndirectImportName(const Value: string);
 
-     procedure SetResolveCheck(Value: TJclPeResolveCheck);
 
-   public
 
-     constructor Create(AImportLib: TJclPeImportLibItem; AOrdinal: Word;
 
-       AHint: Word; const AName: string);
 
-     property Ordinal: Word read FOrdinal;
 
-     property Hint: Word read FHint;
 
-     property ImportLib: TJclPeImportLibItem read FImportLib;
 
-     property IndirectImportName: Boolean read FIndirectImportName;
 
-     property IsByOrdinal: Boolean read GetIsByOrdinal;
 
-     property Name: string read FName;
 
-     property ResolveCheck: TJclPeResolveCheck read FResolveCheck;
 
-   end;
 
-   // Created from a IMAGE_IMPORT_DESCRIPTOR
 
-   TJclPeImportLibItem = class(TJclPeImageBaseList)
 
-   private
 
-     FImportDescriptor: Pointer;
 
-     FImportDirectoryIndex: Integer;
 
-     FImportKind: TJclPeImportKind;
 
-     FLastSortType: TJclPeImportSort;
 
-     FLastSortDescending: Boolean;
 
-     FName: string;
 
-     FSorted: Boolean;
 
-     FTotalResolveCheck: TJclPeResolveCheck;
 
-     FThunk: Pointer;
 
-     FThunkData: Pointer;
 
-     function GetCount: Integer;
 
-     function GetFileName: TFileName;
 
-     function GetItems(Index: Integer): TJclPeImportFuncItem;
 
-     function GetName: string;
 
-     function GetThunkData32: PImageThunkData32;
 
-     function GetThunkData64: PImageThunkData64;
 
-   protected
 
-     procedure CheckImports(ExportImage: TJclPeImage);
 
-     procedure CreateList;
 
-     procedure SetImportDirectoryIndex(Value: Integer);
 
-     procedure SetImportKind(Value: TJclPeImportKind);
 
-     procedure SetSorted(Value: Boolean);
 
-     procedure SetThunk(Value: Pointer);
 
-   public
 
-     constructor Create(AImage: TJclPeImage; AImportDescriptor: Pointer;
 
-       AImportKind: TJclPeImportKind; const AName: string; AThunk: Pointer);
 
-     procedure SortList(SortType: TJclPeImportSort; Descending: Boolean = False);
 
-     property Count: Integer read GetCount;
 
-     property FileName: TFileName read GetFileName;
 
-     property ImportDescriptor: Pointer read FImportDescriptor;
 
-     property ImportDirectoryIndex: Integer read FImportDirectoryIndex;
 
-     property ImportKind: TJclPeImportKind read FImportKind;
 
-     property Items[Index: Integer]: TJclPeImportFuncItem read GetItems; default;
 
-     property Name: string read GetName;
 
-     property OriginalName: string read FName;
 
-     // use the following properties
 
-     // property ThunkData: PImageThunkData
 
-     property ThunkData32: PImageThunkData32 read GetThunkData32;
 
-     property ThunkData64: PImageThunkData64 read GetThunkData64;
 
-     property TotalResolveCheck: TJclPeResolveCheck read FTotalResolveCheck;
 
-   end;
 
-   TJclPeImportList = class(TJclPeImageBaseList)
 
-   private
 
-     FAllItemsList: TList;
 
-     FFilterModuleName: string;
 
-     FLastAllSortType: TJclPeImportSort;
 
-     FLastAllSortDescending: Boolean;
 
-     FLinkerProducer: TJclPeLinkerProducer;
 
-     FParallelImportTable: array of Pointer;
 
-     FUniqueNamesList: TStringList;
 
-     function GetAllItemCount: Integer;
 
-     function GetAllItems(Index: Integer): TJclPeImportFuncItem;
 
-     function GetItems(Index: Integer): TJclPeImportLibItem;
 
-     function GetUniqueLibItemCount: Integer;
 
-     function GetUniqueLibItems(Index: Integer): TJclPeImportLibItem;
 
-     function GetUniqueLibNames(Index: Integer): string;
 
-     function GetUniqueLibItemFromName(const Name: string): TJclPeImportLibItem;
 
-     procedure SetFilterModuleName(const Value: string);
 
-   protected
 
-     procedure CreateList;
 
-     procedure RefreshAllItems;
 
-   public
 
-     constructor Create(AImage: TJclPeImage);
 
-     destructor Destroy; override;
 
-     procedure CheckImports(PeImageCache: TJclPeImagesCache = nil);
 
-     function MakeBorlandImportTableForMappedImage: Boolean;
 
-     function SmartFindName(const CompareName, LibName: string; Options: TJclSmartCompOptions = []): TJclPeImportFuncItem;
 
-     procedure SortAllItemsList(SortType: TJclPeImportSort; Descending: Boolean = False);
 
-     procedure SortList(SortType: TJclPeImportLibSort);
 
-     procedure TryGetNamesForOrdinalImports;
 
-     property AllItems[Index: Integer]: TJclPeImportFuncItem read GetAllItems;
 
-     property AllItemCount: Integer read GetAllItemCount;
 
-     property FilterModuleName: string read FFilterModuleName write SetFilterModuleName;
 
-     property Items[Index: Integer]: TJclPeImportLibItem read GetItems; default;
 
-     property LinkerProducer: TJclPeLinkerProducer read FLinkerProducer;
 
-     property UniqueLibItemCount: Integer read GetUniqueLibItemCount;
 
-     property UniqueLibItemFromName[const Name: string]: TJclPeImportLibItem read GetUniqueLibItemFromName;
 
-     property UniqueLibItems[Index: Integer]: TJclPeImportLibItem read GetUniqueLibItems;
 
-     property UniqueLibNames[Index: Integer]: string read GetUniqueLibNames;
 
-   end;
 
-   // Export section related classes
 
-   TJclPeExportSort = (esName, esOrdinal, esHint, esAddress, esForwarded,  esAddrOrFwd, esSection);
 
-   TJclPeExportFuncList = class;
 
-   // Created from a IMAGE_EXPORT_DIRECTORY
 
-   TJclPeExportFuncItem = class(TObject)
 
-   private
 
-     FAddress: DWORD;
 
-     FExportList: TJclPeExportFuncList;
 
-     FForwardedName: string;
 
-     FForwardedDotPos: string;
 
-     FHint: Word;
 
-     FName: string;
 
-     FOrdinal: Word;
 
-     FResolveCheck: TJclPeResolveCheck;
 
-     function GetAddressOrForwardStr: string;
 
-     function GetForwardedFuncName: string;
 
-     function GetForwardedLibName: string;
 
-     function GetForwardedFuncOrdinal: DWORD;
 
-     function GetIsExportedVariable: Boolean;
 
-     function GetIsForwarded: Boolean;
 
-     function GetSectionName: string;
 
-     function GetMappedAddress: Pointer;
 
-   protected
 
-     procedure SetResolveCheck(Value: TJclPeResolveCheck);
 
-   public
 
-     constructor Create(AExportList: TJclPeExportFuncList; const AName, AForwardedName: string;
 
-       AAddress: DWORD; AHint: Word; AOrdinal: Word; AResolveCheck: TJclPeResolveCheck);
 
-     property Address: DWORD read FAddress;
 
-     property AddressOrForwardStr: string read GetAddressOrForwardStr;
 
-     property IsExportedVariable: Boolean read GetIsExportedVariable;
 
-     property IsForwarded: Boolean read GetIsForwarded;
 
-     property ForwardedName: string read FForwardedName;
 
-     property ForwardedLibName: string read GetForwardedLibName;
 
-     property ForwardedFuncOrdinal: DWORD read GetForwardedFuncOrdinal;
 
-     property ForwardedFuncName: string read GetForwardedFuncName;
 
-     property Hint: Word read FHint;
 
-     property MappedAddress: Pointer read GetMappedAddress;
 
-     property Name: string read FName;
 
-     property Ordinal: Word read FOrdinal;
 
-     property ResolveCheck: TJclPeResolveCheck read FResolveCheck;
 
-     property SectionName: string read GetSectionName;
 
-   end;
 
-   TJclPeExportFuncList = class(TJclPeImageBaseList)
 
-   private
 
-     FAnyForwards: Boolean;
 
-     FBase: DWORD;
 
-     FExportDir: PImageExportDirectory;
 
-     FForwardedLibsList: TStringList;
 
-     FFunctionCount: DWORD;
 
-     FLastSortType: TJclPeExportSort;
 
-     FLastSortDescending: Boolean;
 
-     FSorted: Boolean;
 
-     FTotalResolveCheck: TJclPeResolveCheck;
 
-     function GetForwardedLibsList: TStrings;
 
-     function GetItems(Index: Integer): TJclPeExportFuncItem;
 
-     function GetItemFromAddress(Address: DWORD): TJclPeExportFuncItem;
 
-     function GetItemFromOrdinal(Ordinal: DWORD): TJclPeExportFuncItem;
 
-     function GetItemFromName(const Name: string): TJclPeExportFuncItem;
 
-     function GetName: string;
 
-   protected
 
-     function CanPerformFastNameSearch: Boolean;
 
-     procedure CreateList;
 
-     property LastSortType: TJclPeExportSort read FLastSortType;
 
-     property LastSortDescending: Boolean read FLastSortDescending;
 
-     property Sorted: Boolean read FSorted;
 
-   public
 
-     constructor Create(AImage: TJclPeImage);
 
-     destructor Destroy; override;
 
-     procedure CheckForwards(PeImageCache: TJclPeImagesCache = nil);
 
-     class function ItemName(Item: TJclPeExportFuncItem): string;
 
-     function OrdinalValid(Ordinal: DWORD): Boolean;
 
-     procedure PrepareForFastNameSearch;
 
-     function SmartFindName(const CompareName: string; Options: TJclSmartCompOptions = []): TJclPeExportFuncItem;
 
-     procedure SortList(SortType: TJclPeExportSort; Descending: Boolean = False);
 
-     property AnyForwards: Boolean read FAnyForwards;
 
-     property Base: DWORD read FBase;
 
-     property ExportDir: PImageExportDirectory read FExportDir;
 
-     property ForwardedLibsList: TStrings read GetForwardedLibsList;
 
-     property FunctionCount: DWORD read FFunctionCount;
 
-     property Items[Index: Integer]: TJclPeExportFuncItem read GetItems; default;
 
-     property ItemFromAddress[Address: DWORD]: TJclPeExportFuncItem read GetItemFromAddress;
 
-     property ItemFromName[const Name: string]: TJclPeExportFuncItem read GetItemFromName;
 
-     property ItemFromOrdinal[Ordinal: DWORD]: TJclPeExportFuncItem read GetItemFromOrdinal;
 
-     property Name: string read GetName;
 
-     property TotalResolveCheck: TJclPeResolveCheck read FTotalResolveCheck;
 
-   end;
 
-   // Resource section related classes
 
-   TJclPeResourceKind = (
 
-     rtUnknown0,
 
-     rtCursorEntry,
 
-     rtBitmap,
 
-     rtIconEntry,
 
-     rtMenu,
 
-     rtDialog,
 
-     rtString,
 
-     rtFontDir,
 
-     rtFont,
 
-     rtAccelerators,
 
-     rtRCData,
 
-     rtMessageTable,
 
-     rtCursor,
 
-     rtUnknown13,
 
-     rtIcon,
 
-     rtUnknown15,
 
-     rtVersion,
 
-     rtDlgInclude,
 
-     rtUnknown18,
 
-     rtPlugPlay,
 
-     rtVxd,
 
-     rtAniCursor,
 
-     rtAniIcon,
 
-     rtHmtl,
 
-     rtManifest,
 
-     rtUserDefined);
 
-   TJclPeResourceList = class;
 
-   TJclPeResourceItem = class;
 
-   TJclPeResourceRawStream = class(TCustomMemoryStream)
 
-   public
 
-     constructor Create(AResourceItem: TJclPeResourceItem);
 
-     function Write(const Buffer; Count: Longint): Longint; override;
 
-   end;
 
-   TJclPeResourceItem = class(TObject)
 
-   private
 
-     FEntry: PImageResourceDirectoryEntry;
 
-     FImage: TJclPeImage;
 
-     FList: TJclPeResourceList;
 
-     FLevel: Byte;
 
-     FParentItem: TJclPeResourceItem;
 
-     FNameCache: string;
 
-     function GetDataEntry: PImageResourceDataEntry;
 
-     function GetIsDirectory: Boolean;
 
-     function GetIsName: Boolean;
 
-     function GetLangID: LANGID;
 
-     function GetList: TJclPeResourceList;
 
-     function GetName: string;
 
-     function GetParameterName: string;
 
-     function GetRawEntryData: Pointer;
 
-     function GetRawEntryDataSize: Integer;
 
-     function GetResourceType: TJclPeResourceKind;
 
-     function GetResourceTypeStr: string;
 
-   protected
 
-     function OffsetToRawData(Ofs: DWORD): TJclAddr;
 
-     function Level1Item: TJclPeResourceItem;
 
-     function SubDirData: PImageResourceDirectory;
 
-   public
 
-     constructor Create(AImage: TJclPeImage; AParentItem: TJclPeResourceItem;
 
-       AEntry: PImageResourceDirectoryEntry);
 
-     destructor Destroy; override;
 
-     function CompareName(AName: PChar): Boolean;
 
-     property DataEntry: PImageResourceDataEntry read GetDataEntry;
 
-     property Entry: PImageResourceDirectoryEntry read FEntry;
 
-     property Image: TJclPeImage read FImage;
 
-     property IsDirectory: Boolean read GetIsDirectory;
 
-     property IsName: Boolean read GetIsName;
 
-     property LangID: LANGID read GetLangID;
 
-     property List: TJclPeResourceList read GetList;
 
-     property Level: Byte read FLevel;
 
-     property Name: string read GetName;
 
-     property ParameterName: string read GetParameterName;
 
-     property ParentItem: TJclPeResourceItem read FParentItem;
 
-     property RawEntryData: Pointer read GetRawEntryData;
 
-     property RawEntryDataSize: Integer read GetRawEntryDataSize;
 
-     property ResourceType: TJclPeResourceKind read GetResourceType;
 
-     property ResourceTypeStr: string read GetResourceTypeStr;
 
-   end;
 
-   TJclPeResourceList = class(TJclPeImageBaseList)
 
-   private
 
-     FDirectory: PImageResourceDirectory;
 
-     FParentItem: TJclPeResourceItem;
 
-     function GetItems(Index: Integer): TJclPeResourceItem;
 
-   protected
 
-     procedure CreateList(AParentItem: TJclPeResourceItem);
 
-   public
 
-     constructor Create(AImage: TJclPeImage; AParentItem: TJclPeResourceItem;
 
-       ADirectory: PImageResourceDirectory);
 
-     function FindName(const Name: string): TJclPeResourceItem;
 
-     property Directory: PImageResourceDirectory read FDirectory;
 
-     property Items[Index: Integer]: TJclPeResourceItem read GetItems; default;
 
-     property ParentItem: TJclPeResourceItem read FParentItem;
 
-   end;
 
-   TJclPeRootResourceList = class(TJclPeResourceList)
 
-   private
 
-     FManifestContent: TStringList;
 
-     function GetManifestContent: TStrings;
 
-   public
 
-     destructor Destroy; override;
 
-     function FindResource(ResourceType: TJclPeResourceKind;
 
-       const ResourceName: string = ''): TJclPeResourceItem; overload;
 
-     function FindResource(const ResourceType: PChar;
 
-       const ResourceName: PChar = nil): TJclPeResourceItem; overload;
 
-     function ListResourceNames(ResourceType: TJclPeResourceKind; const Strings: TStrings): Boolean;
 
-     property ManifestContent: TStrings read GetManifestContent;
 
-   end;
 
-   // Relocation section related classes
 
-   TJclPeRelocation = record
 
-     Address: Word;
 
-     RelocType: Byte;
 
-     VirtualAddress: DWORD;
 
-   end;
 
-   TJclPeRelocEntry = class(TObject)
 
-   private
 
-     FChunk: PImageBaseRelocation;
 
-     FCount: Integer;
 
-     function GetRelocations(Index: Integer): TJclPeRelocation;
 
-     function GetSize: DWORD;
 
-     function GetVirtualAddress: DWORD;
 
-   public
 
-     constructor Create(AChunk: PImageBaseRelocation; ACount: Integer);
 
-     property Count: Integer read FCount;
 
-     property Relocations[Index: Integer]: TJclPeRelocation read GetRelocations; default;
 
-     property Size: DWORD read GetSize;
 
-     property VirtualAddress: DWORD read GetVirtualAddress;
 
-   end;
 
-   TJclPeRelocList = class(TJclPeImageBaseList)
 
-   private
 
-     FAllItemCount: Integer;
 
-     function GetItems(Index: Integer): TJclPeRelocEntry;
 
-     function GetAllItems(Index: Integer): TJclPeRelocation;
 
-   protected
 
-     procedure CreateList;
 
-   public
 
-     constructor Create(AImage: TJclPeImage);
 
-     property AllItems[Index: Integer]: TJclPeRelocation read GetAllItems;
 
-     property AllItemCount: Integer read FAllItemCount;
 
-     property Items[Index: Integer]: TJclPeRelocEntry read GetItems; default;
 
-   end;
 
-   // Debug section related classes
 
-   TJclPeDebugList = class(TJclPeImageBaseList)
 
-   private
 
-     function GetItems(Index: Integer): TImageDebugDirectory;
 
-   protected
 
-     procedure CreateList;
 
-   public
 
-     constructor Create(AImage: TJclPeImage);
 
-     property Items[Index: Integer]: TImageDebugDirectory read GetItems; default;
 
-   end;
 
-   // Certificates section related classes
 
-   TJclPeCertificate = class(TObject)
 
-   private
 
-     FData: Pointer;
 
-     FHeader: TWinCertificate;
 
-   public
 
-     constructor Create(AHeader: TWinCertificate; AData: Pointer);
 
-     property Data: Pointer read FData;
 
-     property Header: TWinCertificate read FHeader;
 
-   end;
 
-   TJclPeCertificateList = class(TJclPeImageBaseList)
 
-   private
 
-     function GetItems(Index: Integer): TJclPeCertificate;
 
-   protected
 
-     procedure CreateList;
 
-   public
 
-     constructor Create(AImage: TJclPeImage);
 
-     property Items[Index: Integer]: TJclPeCertificate read GetItems; default;
 
-   end;
 
-   // Common Language Runtime section related classes
 
-   TJclPeCLRHeader = class(TObject)
 
-   private
 
-     FHeader: TImageCor20Header;
 
-     FImage: TJclPeImage;
 
-     function GetVersionString: string;
 
-     function GetHasMetadata: Boolean;
 
-   protected
 
-     procedure ReadHeader;
 
-   public
 
-     constructor Create(AImage: TJclPeImage);
 
-     property HasMetadata: Boolean read GetHasMetadata;
 
-     property Header: TImageCor20Header read FHeader;
 
-     property VersionString: string read GetVersionString;
 
-     property Image: TJclPeImage read FImage;
 
-   end;
 
-   // PE Image
 
-   TJclPeHeader = (
 
-     JclPeHeader_Signature,
 
-     JclPeHeader_Machine,
 
-     JclPeHeader_NumberOfSections,
 
-     JclPeHeader_TimeDateStamp,
 
-     JclPeHeader_PointerToSymbolTable,
 
-     JclPeHeader_NumberOfSymbols,
 
-     JclPeHeader_SizeOfOptionalHeader,
 
-     JclPeHeader_Characteristics,
 
-     JclPeHeader_Magic,
 
-     JclPeHeader_LinkerVersion,
 
-     JclPeHeader_SizeOfCode,
 
-     JclPeHeader_SizeOfInitializedData,
 
-     JclPeHeader_SizeOfUninitializedData,
 
-     JclPeHeader_AddressOfEntryPoint,
 
-     JclPeHeader_BaseOfCode,
 
-     JclPeHeader_BaseOfData,
 
-     JclPeHeader_ImageBase,
 
-     JclPeHeader_SectionAlignment,
 
-     JclPeHeader_FileAlignment,
 
-     JclPeHeader_OperatingSystemVersion,
 
-     JclPeHeader_ImageVersion,
 
-     JclPeHeader_SubsystemVersion,
 
-     JclPeHeader_Win32VersionValue,
 
-     JclPeHeader_SizeOfImage,
 
-     JclPeHeader_SizeOfHeaders,
 
-     JclPeHeader_CheckSum,
 
-     JclPeHeader_Subsystem,
 
-     JclPeHeader_DllCharacteristics,
 
-     JclPeHeader_SizeOfStackReserve,
 
-     JclPeHeader_SizeOfStackCommit,
 
-     JclPeHeader_SizeOfHeapReserve,
 
-     JclPeHeader_SizeOfHeapCommit,
 
-     JclPeHeader_LoaderFlags,
 
-     JclPeHeader_NumberOfRvaAndSizes);
 
-   TJclLoadConfig = (
 
-     JclLoadConfig_Characteristics,   { TODO : rename to Size? }
 
-     JclLoadConfig_TimeDateStamp,
 
-     JclLoadConfig_Version,
 
-     JclLoadConfig_GlobalFlagsClear,
 
-     JclLoadConfig_GlobalFlagsSet,
 
-     JclLoadConfig_CriticalSectionDefaultTimeout,
 
-     JclLoadConfig_DeCommitFreeBlockThreshold,
 
-     JclLoadConfig_DeCommitTotalFreeThreshold,
 
-     JclLoadConfig_LockPrefixTable,
 
-     JclLoadConfig_MaximumAllocationSize,
 
-     JclLoadConfig_VirtualMemoryThreshold,
 
-     JclLoadConfig_ProcessHeapFlags,
 
-     JclLoadConfig_ProcessAffinityMask,
 
-     JclLoadConfig_CSDVersion,
 
-     JclLoadConfig_Reserved1,
 
-     JclLoadConfig_EditList,
 
-     JclLoadConfig_Reserved           { TODO : extend to the new fields? }
 
-   );
 
-   TJclPeFileProperties = record
 
-     Size: DWORD;
 
-     CreationTime: TDateTime;
 
-     LastAccessTime: TDateTime;
 
-     LastWriteTime: TDateTime;
 
-     Attributes: Integer;
 
-   end;
 
-   TJclPeImageStatus = (stNotLoaded, stOk, stNotPE, stNotSupported, stNotFound, stError);
 
-   TJclPeTarget = (taUnknown, taWin32, taWin64);
 
-   TJclPeImage = class(TObject)
 
-   private
 
-     FAttachedImage: Boolean;
 
-     FCertificateList: TJclPeCertificateList;
 
-     FCLRHeader: TJclPeCLRHeader;
 
-     FDebugList: TJclPeDebugList;
 
-     FFileName: TFileName;
 
-     FImageSections: TStringList;
 
-     FLoadedImage: TLoadedImage;
 
-     FExportList: TJclPeExportFuncList;
 
-     FImportList: TJclPeImportList;
 
-     FNoExceptions: Boolean;
 
-     FReadOnlyAccess: Boolean;
 
-     FRelocationList: TJclPeRelocList;
 
-     FResourceList: TJclPeRootResourceList;
 
-     FResourceVA: TJclAddr;
 
-     FStatus: TJclPeImageStatus;
 
-     FTarget: TJclPeTarget;
 
-     FVersionInfo: TJclFileVersionInfo;
 
-     FStringTable: TStringList;
 
-     function GetCertificateList: TJclPeCertificateList;
 
-     function GetCLRHeader: TJclPeCLRHeader;
 
-     function GetDebugList: TJclPeDebugList;
 
-     function GetDescription: string;
 
-     function GetDirectories(Directory: Word): TImageDataDirectory;
 
-     function GetDirectoryExists(Directory: Word): Boolean;
 
-     function GetExportList: TJclPeExportFuncList;
 
-     {$IFNDEF WINSCP}
 
-     function GetFileProperties: TJclPeFileProperties;
 
-     {$ENDIF ~WINSCP}
 
-     function GetImageSectionCount: Integer;
 
-     function GetImageSectionHeaders(Index: Integer): TImageSectionHeader;
 
-     function GetImageSectionNames(Index: Integer): string;
 
-     function GetImageSectionNameFromRva(const Rva: DWORD): string;
 
-     function GetImportList: TJclPeImportList;
 
-     function GetHeaderValues(Index: TJclPeHeader): string;
 
-     function GetLoadConfigValues(Index: TJclLoadConfig): string;
 
-     function GetMappedAddress: TJclAddr;
 
-     function GetOptionalHeader32: TImageOptionalHeader32;
 
-     function GetOptionalHeader64: TImageOptionalHeader64;
 
-     function GetRelocationList: TJclPeRelocList;
 
-     function GetResourceList: TJclPeRootResourceList;
 
-     function GetUnusedHeaderBytes: TImageDataDirectory;
 
-     function GetVersionInfo: TJclFileVersionInfo;
 
-     function GetVersionInfoAvailable: Boolean;
 
-     procedure ReadImageSections;
 
-     procedure ReadStringTable;
 
-     procedure SetFileName(const Value: TFileName);
 
-     function GetStringTableCount: Integer;
 
-     function GetStringTableItem(Index: Integer): string;
 
-     function GetImageSectionFullNames(Index: Integer): string;
 
-   protected
 
-     procedure AfterOpen; dynamic;
 
-     procedure CheckNotAttached;
 
-     procedure Clear; dynamic;
 
-     function ExpandModuleName(const ModuleName: string): TFileName;
 
-     procedure RaiseStatusException;
 
-     function ResourceItemCreate(AEntry: PImageResourceDirectoryEntry;
 
-       AParentItem: TJclPeResourceItem): TJclPeResourceItem; virtual;
 
-     function ResourceListCreate(ADirectory: PImageResourceDirectory;
 
-       AParentItem: TJclPeResourceItem): TJclPeResourceList; virtual;
 
-     property NoExceptions: Boolean read FNoExceptions;
 
-   public
 
-     constructor Create(ANoExceptions: Boolean = False); virtual;
 
-     destructor Destroy; override;
 
-     procedure AttachLoadedModule(const Handle: HMODULE);
 
-     function CalculateCheckSum: DWORD;
 
-     function DirectoryEntryToData(Directory: Word): Pointer;
 
-     function GetSectionHeader(const SectionName: string; out Header: PImageSectionHeader): Boolean;
 
-     function GetSectionName(Header: PImageSectionHeader): string;
 
-     function GetNameInStringTable(Offset: ULONG): string;
 
-     function IsBrokenFormat: Boolean;
 
-     function IsCLR: Boolean;
 
-     function IsSystemImage: Boolean;
 
-     // RVA are always DWORD
 
-     function RawToVa(Raw: DWORD): Pointer; overload;
 
-     function RvaToSection(Rva: DWORD): PImageSectionHeader; overload;
 
-     function RvaToVa(Rva: DWORD): Pointer; overload;
 
-     function RvaToVaEx(Rva: DWORD): Pointer; overload;
 
-     function StatusOK: Boolean;
 
-     procedure TryGetNamesForOrdinalImports;
 
-     function VerifyCheckSum: Boolean;
 
-     class function DebugTypeNames(DebugType: DWORD): string;
 
-     class function DirectoryNames(Directory: Word): string;
 
-     class function ExpandBySearchPath(const ModuleName, BasePath: string): TFileName;
 
-     class function HeaderNames(Index: TJclPeHeader): string;
 
-     class function LoadConfigNames(Index: TJclLoadConfig): string;
 
-     class function ShortSectionInfo(Characteristics: DWORD): string;
 
-     class function DateTimeToStamp(const DateTime: TDateTime): DWORD;
 
-     class function StampToDateTime(TimeDateStamp: DWORD): TDateTime;
 
-     property AttachedImage: Boolean read FAttachedImage;
 
-     property CertificateList: TJclPeCertificateList read GetCertificateList;
 
-     property CLRHeader: TJclPeCLRHeader read GetCLRHeader;
 
-     property DebugList: TJclPeDebugList read GetDebugList;
 
-     property Description: string read GetDescription;
 
-     property Directories[Directory: Word]: TImageDataDirectory read GetDirectories;
 
-     property DirectoryExists[Directory: Word]: Boolean read GetDirectoryExists;
 
-     property ExportList: TJclPeExportFuncList read GetExportList;
 
-     property FileName: TFileName read FFileName write SetFileName;
 
-     {$IFNDEF WINSCP}
 
-     property FileProperties: TJclPeFileProperties read GetFileProperties;
 
-     {$ENDIF ~WINSCP}
 
-     property HeaderValues[Index: TJclPeHeader]: string read GetHeaderValues;
 
-     property ImageSectionCount: Integer read GetImageSectionCount;
 
-     property ImageSectionHeaders[Index: Integer]: TImageSectionHeader read GetImageSectionHeaders;
 
-     property ImageSectionNames[Index: Integer]: string read GetImageSectionNames;
 
-     property ImageSectionFullNames[Index: Integer]: string read GetImageSectionFullNames;
 
-     property ImageSectionNameFromRva[const Rva: DWORD]: string read GetImageSectionNameFromRva;
 
-     property ImportList: TJclPeImportList read GetImportList;
 
-     property LoadConfigValues[Index: TJclLoadConfig]: string read GetLoadConfigValues;
 
-     property LoadedImage: TLoadedImage read FLoadedImage;
 
-     property MappedAddress: TJclAddr read GetMappedAddress;
 
-     property StringTableCount: Integer read GetStringTableCount;
 
-     property StringTable[Index: Integer]: string read GetStringTableItem;
 
-     // use the following properties
 
-     // property OptionalHeader: TImageOptionalHeader
 
-     property OptionalHeader32: TImageOptionalHeader32 read GetOptionalHeader32;
 
-     property OptionalHeader64: TImageOptionalHeader64 read GetOptionalHeader64;
 
-     property ReadOnlyAccess: Boolean read FReadOnlyAccess write FReadOnlyAccess;
 
-     property RelocationList: TJclPeRelocList read GetRelocationList;
 
-     property ResourceVA: TJclAddr read FResourceVA;
 
-     property ResourceList: TJclPeRootResourceList read GetResourceList;
 
-     property Status: TJclPeImageStatus read FStatus;
 
-     property Target: TJclPeTarget read FTarget;
 
-     property UnusedHeaderBytes: TImageDataDirectory read GetUnusedHeaderBytes;
 
-     property VersionInfo: TJclFileVersionInfo read GetVersionInfo;
 
-     property VersionInfoAvailable: Boolean read GetVersionInfoAvailable;
 
-   end;
 
-   {$IFDEF BORLAND}
 
-   TJclPeBorImage = class;
 
-   TJclPeBorImagesCache = class(TJclPeImagesCache)
 
-   private
 
-     function GetImages(const FileName: TFileName): TJclPeBorImage;
 
-   protected
 
-     function GetPeImageClass: TJclPeImageClass; override;
 
-   public
 
-     property Images[const FileName: TFileName]: TJclPeBorImage read GetImages; default;
 
-   end;
 
-   // Borland Delphi PE Image specific information
 
-   TJclPePackageInfo = class(TObject)
 
-   private
 
-     FAvailable: Boolean;
 
-     FContains: TStringList;
 
-     FDcpName: string;
 
-     FRequires: TStringList;
 
-     FFlags: Integer;
 
-     FDescription: string;
 
-     FEnsureExtension: Boolean;
 
-     FSorted: Boolean;
 
-     function GetContains: TStrings;
 
-     function GetContainsCount: Integer;
 
-     function GetContainsFlags(Index: Integer): Byte;
 
-     function GetContainsNames(Index: Integer): string;
 
-     function GetRequires: TStrings;
 
-     function GetRequiresCount: Integer;
 
-     function GetRequiresNames(Index: Integer): string;
 
-   protected
 
-     procedure ReadPackageInfo(ALibHandle: THandle);
 
-     procedure SetDcpName(const Value: string);
 
-   public
 
-     constructor Create(ALibHandle: THandle);
 
-     destructor Destroy; override;
 
-     class function PackageModuleTypeToString(Flags: Cardinal): string;
 
-     class function PackageOptionsToString(Flags: Cardinal): string;
 
-     class function ProducerToString(Flags: Cardinal): string;
 
-     class function UnitInfoFlagsToString(UnitFlags: Byte): string;
 
-     property Available: Boolean read FAvailable;
 
-     property Contains: TStrings read GetContains;
 
-     property ContainsCount: Integer read GetContainsCount;
 
-     property ContainsNames[Index: Integer]: string read GetContainsNames;
 
-     property ContainsFlags[Index: Integer]: Byte read GetContainsFlags;
 
-     property Description: string read FDescription;
 
-     property DcpName: string read FDcpName;
 
-     property EnsureExtension: Boolean read FEnsureExtension write FEnsureExtension;
 
-     property Flags: Integer read FFlags;
 
-     property Requires: TStrings read GetRequires;
 
-     property RequiresCount: Integer read GetRequiresCount;
 
-     property RequiresNames[Index: Integer]: string read GetRequiresNames;
 
-     property Sorted: Boolean read FSorted write FSorted;
 
-   end;
 
-   TJclPeBorForm = class(TObject)
 
-   private
 
-     FFormFlags: TFilerFlags;
 
-     FFormClassName: string;
 
-     FFormObjectName: string;
 
-     FFormPosition: Integer;
 
-     FResItem: TJclPeResourceItem;
 
-     function GetDisplayName: string;
 
-   public
 
-     constructor Create(AResItem: TJclPeResourceItem; AFormFlags: TFilerFlags;
 
-       AFormPosition: Integer; const AFormClassName, AFormObjectName: string);
 
-     procedure ConvertFormToText(const Stream: TStream); overload;
 
-     procedure ConvertFormToText(const Strings: TStrings); overload;
 
-     property FormClassName: string read FFormClassName;
 
-     property FormFlags: TFilerFlags read FFormFlags;
 
-     property FormObjectName: string read FFormObjectName;
 
-     property FormPosition: Integer read FFormPosition;
 
-     property DisplayName: string read GetDisplayName;
 
-     property ResItem: TJclPeResourceItem read FResItem;
 
-   end;
 
-   TJclPeBorImage = class(TJclPeImage)
 
-   private
 
-     FForms: TObjectList;
 
-     FIsPackage: Boolean;
 
-     FIsBorlandImage: Boolean;
 
-     FLibHandle: THandle;
 
-     FPackageInfo: TJclPePackageInfo;
 
-     FPackageInfoSorted: Boolean;
 
-     FPackageCompilerVersion: Integer;
 
-     function GetFormCount: Integer;
 
-     function GetForms(Index: Integer): TJclPeBorForm;
 
-     function GetFormFromName(const FormClassName: string): TJclPeBorForm;
 
-     function GetLibHandle: THandle;
 
-     function GetPackageCompilerVersion: Integer;
 
-     function GetPackageInfo: TJclPePackageInfo;
 
-   protected
 
-     procedure AfterOpen; override;
 
-     procedure Clear; override;
 
-     procedure CreateFormsList;
 
-   public
 
-     constructor Create(ANoExceptions: Boolean = False); override;
 
-     destructor Destroy; override;
 
-     function DependedPackages(List: TStrings; FullPathName, Descriptions: Boolean): Boolean;
 
-     function FreeLibHandle: Boolean;
 
-     property Forms[Index: Integer]: TJclPeBorForm read GetForms;
 
-     property FormCount: Integer read GetFormCount;
 
-     property FormFromName[const FormClassName: string]: TJclPeBorForm read GetFormFromName;
 
-     property IsBorlandImage: Boolean read FIsBorlandImage;
 
-     property IsPackage: Boolean read FIsPackage;
 
-     property LibHandle: THandle read GetLibHandle;
 
-     property PackageCompilerVersion: Integer read GetPackageCompilerVersion;
 
-     property PackageInfo: TJclPePackageInfo read GetPackageInfo;
 
-     property PackageInfoSorted: Boolean read FPackageInfoSorted write FPackageInfoSorted;
 
-   end;
 
-   {$ENDIF BORLAND}
 
-   // Threaded function search
 
-   TJclPeNameSearchOption = (seImports, seDelayImports, seBoundImports, seExports);
 
-   TJclPeNameSearchOptions = set of TJclPeNameSearchOption;
 
-   TJclPeNameSearchNotifyEvent = procedure (Sender: TObject; PeImage: TJclPeImage;
 
-     var Process: Boolean) of object;
 
-   TJclPeNameSearchFoundEvent = procedure (Sender: TObject; const FileName: TFileName;
 
-     const FunctionName: string; Option: TJclPeNameSearchOption) of object;
 
-   TJclPeNameSearch = class(TThread)
 
-   private
 
-     F_FileName: TFileName;
 
-     F_FunctionName: string;
 
-     F_Option: TJclPeNameSearchOption;
 
-     F_Process: Boolean;
 
-     FFunctionName: string;
 
-     FOptions: TJclPeNameSearchOptions;
 
-     FPath: string;
 
-     FPeImage: TJclPeImage;
 
-     FOnFound: TJclPeNameSearchFoundEvent;
 
-     FOnProcessFile: TJclPeNameSearchNotifyEvent;
 
-   protected
 
-     function CompareName(const FunctionName, ComparedName: string): Boolean; virtual;
 
-     procedure DoFound;
 
-     procedure DoProcessFile;
 
-     procedure Execute; override;
 
-   public
 
-     constructor Create(const FunctionName, Path: string; Options: TJclPeNameSearchOptions = [seImports, seExports]);
 
-     procedure Start;
 
-     property OnFound: TJclPeNameSearchFoundEvent read FOnFound write FOnFound;
 
-     property OnProcessFile: TJclPeNameSearchNotifyEvent read FOnProcessFile write FOnProcessFile;
 
-   end;
 
- // PE Image miscellaneous functions
 
- type
 
-   TJclRebaseImageInfo32 = record
 
-     OldImageSize: DWORD;
 
-     OldImageBase: TJclAddr32;
 
-     NewImageSize: DWORD;
 
-     NewImageBase: TJclAddr32;
 
-   end;
 
-   TJclRebaseImageInfo64 = record
 
-     OldImageSize: DWORD;
 
-     OldImageBase: TJclAddr64;
 
-     NewImageSize: DWORD;
 
-     NewImageBase: TJclAddr64;
 
-   end;
 
-   // renamed
 
-   // TJclRebaseImageInfo = TJclRebaseImageInfo32;
 
- { Image validity }
 
- function IsValidPeFile(const FileName: TFileName): Boolean;
 
- // use PeGetNtHeaders32 for backward compatibility
 
- // function PeGetNtHeaders(const FileName: TFileName; out NtHeaders: TImageNtHeaders): Boolean;
 
- function PeGetNtHeaders32(const FileName: TFileName; out NtHeaders: TImageNtHeaders32): Boolean;
 
- function PeGetNtHeaders64(const FileName: TFileName; out NtHeaders: TImageNtHeaders64): Boolean;
 
- { Image modifications }
 
- function PeCreateNameHintTable(const FileName: TFileName): Boolean;
 
- // use PeRebaseImage32
 
- //function PeRebaseImage(const ImageName: TFileName; NewBase: DWORD = 0; TimeStamp: DWORD = 0;
 
- //  MaxNewSize: DWORD = 0): TJclRebaseImageInfo;
 
- function PeRebaseImage32(const ImageName: TFileName; NewBase: TJclAddr32 = 0; TimeStamp: DWORD = 0;
 
-   MaxNewSize: DWORD = 0): TJclRebaseImageInfo32;
 
- function PeRebaseImage64(const ImageName: TFileName; NewBase: TJclAddr64 = 0; TimeStamp: DWORD = 0;
 
-   MaxNewSize: DWORD = 0): TJclRebaseImageInfo64;
 
- function PeUpdateLinkerTimeStamp(const FileName: TFileName; const Time: TDateTime): Boolean;
 
- function PeReadLinkerTimeStamp(const FileName: TFileName): TDateTime;
 
- function PeInsertSection(const FileName: TFileName; SectionStream: TStream; SectionName: string): Boolean;
 
- { Image Checksum }
 
- function PeVerifyCheckSum(const FileName: TFileName): Boolean;
 
- function PeClearCheckSum(const FileName: TFileName): Boolean;
 
- function PeUpdateCheckSum(const FileName: TFileName): Boolean;
 
- // Various simple PE Image searching and listing routines
 
- { Exports searching }
 
- function PeDoesExportFunction(const FileName: TFileName; const FunctionName: string;
 
-   Options: TJclSmartCompOptions = []): Boolean;
 
- function PeIsExportFunctionForwardedEx(const FileName: TFileName; const FunctionName: string;
 
-   out ForwardedName: string; Options: TJclSmartCompOptions = []): Boolean;
 
- function PeIsExportFunctionForwarded(const FileName: TFileName; const FunctionName: string;
 
-   Options: TJclSmartCompOptions = []): Boolean;
 
- { Imports searching }
 
- function PeDoesImportFunction(const FileName: TFileName; const FunctionName: string;
 
-   const LibraryName: string = ''; Options: TJclSmartCompOptions = []): Boolean;
 
- function PeDoesImportLibrary(const FileName: TFileName; const LibraryName: string;
 
-   Recursive: Boolean = False): Boolean;
 
- { Imports listing }
 
- function PeImportedLibraries(const FileName: TFileName; const LibrariesList: TStrings;
 
-   Recursive: Boolean = False; FullPathName: Boolean = False): Boolean;
 
- function PeImportedFunctions(const FileName: TFileName; const FunctionsList: TStrings;
 
-   const LibraryName: string = ''; IncludeLibNames: Boolean = False): Boolean;
 
- { Exports listing }
 
- function PeExportedFunctions(const FileName: TFileName; const FunctionsList: TStrings): Boolean;
 
- function PeExportedNames(const FileName: TFileName; const FunctionsList: TStrings): Boolean;
 
- function PeExportedVariables(const FileName: TFileName; const FunctionsList: TStrings): Boolean;
 
- { Resources listing }
 
- function PeResourceKindNames(const FileName: TFileName; ResourceType: TJclPeResourceKind;
 
-   const NamesList: TStrings): Boolean;
 
- { Borland packages specific }
 
- {$IFDEF BORLAND}
 
- function PeBorFormNames(const FileName: TFileName; const NamesList: TStrings): Boolean;
 
- function PeBorDependedPackages(const FileName: TFileName; PackagesList: TStrings;
 
-   FullPathName, Descriptions: Boolean): Boolean;
 
- {$ENDIF BORLAND}
 
- // Missing imports checking routines
 
- function PeFindMissingImports(const FileName: TFileName; MissingImportsList: TStrings): Boolean; overload;
 
- function PeFindMissingImports(RequiredImportsList, MissingImportsList: TStrings): Boolean; overload;
 
- function PeCreateRequiredImportList(const FileName: TFileName; RequiredImportsList: TStrings): Boolean;
 
- // Mapped or loaded image related routines
 
- // use PeMapImgNtHeaders32
 
- // function PeMapImgNtHeaders(const BaseAddress: Pointer): PImageNtHeaders;
 
- function PeMapImgNtHeaders32(const BaseAddress: Pointer): PImageNtHeaders32; overload;
 
- function PeMapImgNtHeaders32(Stream: TStream; const BasePosition: Int64; out NtHeaders32: TImageNtHeaders32): Int64; overload;
 
- function PeMapImgNtHeaders64(const BaseAddress: Pointer): PImageNtHeaders64; overload;
 
- function PeMapImgNtHeaders64(Stream: TStream; const BasePosition: Int64; out NtHeaders64: TImageNtHeaders64): Int64; overload;
 
- function PeMapImgLibraryName(const BaseAddress: Pointer): string;
 
- function PeMapImgLibraryName32(const BaseAddress: Pointer): string;
 
- function PeMapImgLibraryName64(const BaseAddress: Pointer): string;
 
- function PeMapImgSize(const BaseAddress: Pointer): DWORD; overload;
 
- function PeMapImgSize(Stream: TStream; const BasePosition: Int64): DWORD; overload;
 
- function PeMapImgSize32(const BaseAddress: Pointer): DWORD; overload;
 
- function PeMapImgSize32(Stream: TStream; const BasePosition: Int64): DWORD; overload;
 
- function PeMapImgSize64(const BaseAddress: Pointer): DWORD; overload;
 
- function PeMapImgSize64(Stream: TStream; const BasePosition: Int64): DWORD; overload;
 
- function PeMapImgTarget(const BaseAddress: Pointer): TJclPeTarget; overload;
 
- function PeMapImgTarget(Stream: TStream; const BasePosition: Int64): TJclPeTarget; overload;
 
- type
 
-   TImageSectionHeaderArray = array of TImageSectionHeader;
 
- // use PeMapImgSections32
 
- // function PeMapImgSections(NtHeaders: PImageNtHeaders): PImageSectionHeader;
 
- function PeMapImgSections32(NtHeaders: PImageNtHeaders32): PImageSectionHeader; overload;
 
- function PeMapImgSections32(Stream: TStream; const NtHeaders32Position: Int64; const NtHeaders32: TImageNtHeaders32;
 
-   out ImageSectionHeaders: TImageSectionHeaderArray): Int64; overload;
 
- function PeMapImgSections64(NtHeaders: PImageNtHeaders64): PImageSectionHeader; overload;
 
- function PeMapImgSections64(Stream: TStream; const NtHeaders64Position: Int64; const NtHeaders64: TImageNtHeaders64;
 
-   out ImageSectionHeaders: TImageSectionHeaderArray): Int64; overload;
 
- // use PeMapImgFindSection32
 
- // function PeMapImgFindSection(NtHeaders: PImageNtHeaders;
 
- //   const SectionName: string): PImageSectionHeader;
 
- function PeMapImgFindSection32(NtHeaders: PImageNtHeaders32;
 
-   const SectionName: string): PImageSectionHeader;
 
- function PeMapImgFindSection64(NtHeaders: PImageNtHeaders64;
 
-   const SectionName: string): PImageSectionHeader;
 
- function PeMapImgFindSection(const ImageSectionHeaders: TImageSectionHeaderArray;
 
-   const SectionName: string): SizeInt;
 
- function PeMapImgFindSectionFromModule(const BaseAddress: Pointer;
 
-   const SectionName: string): PImageSectionHeader;
 
- function PeMapImgExportedVariables(const Module: HMODULE; const VariablesList: TStrings): Boolean;
 
- function PeMapImgResolvePackageThunk(Address: Pointer): Pointer;
 
- function PeMapFindResource(const Module: HMODULE; const ResourceType: PChar;
 
-   const ResourceName: string): Pointer;
 
- type
 
-   TJclPeSectionStream = class(TCustomMemoryStream)
 
-   private
 
-     FInstance: HMODULE;
 
-     FSectionHeader: TImageSectionHeader;
 
-     procedure Initialize(Instance: HMODULE; const ASectionName: string);
 
-   public
 
-     constructor Create(Instance: HMODULE; const ASectionName: string);
 
-     function Write(const Buffer; Count: Longint): Longint; override;
 
-     property Instance: HMODULE read FInstance;
 
-     property SectionHeader: TImageSectionHeader read FSectionHeader;
 
-   end;
 
- // API hooking classes
 
- type
 
-   TJclPeMapImgHookItem = class(TObject)
 
-   private
 
-     FBaseAddress: Pointer;
 
-     FFunctionName: string;
 
-     FModuleName: string;
 
-     FNewAddress: Pointer;
 
-     FOriginalAddress: Pointer;
 
-     FList: TObjectList;
 
-   protected
 
-     function InternalUnhook: Boolean;
 
-   public
 
-     constructor Create(AList: TObjectList; const AFunctionName: string;
 
-       const AModuleName: string; ABaseAddress, ANewAddress, AOriginalAddress: Pointer);
 
-     destructor Destroy; override;
 
-     function Unhook: Boolean;
 
-     property BaseAddress: Pointer read FBaseAddress;
 
-     property FunctionName: string read FFunctionName;
 
-     property ModuleName: string read FModuleName;
 
-     property NewAddress: Pointer read FNewAddress;
 
-     property OriginalAddress: Pointer read FOriginalAddress;
 
-   end;
 
-   TJclPeMapImgHooks = class(TObjectList)
 
-   private
 
-     function GetItems(Index: Integer): TJclPeMapImgHookItem;
 
-     function GetItemFromOriginalAddress(OriginalAddress: Pointer): TJclPeMapImgHookItem;
 
-     function GetItemFromNewAddress(NewAddress: Pointer): TJclPeMapImgHookItem;
 
-   public
 
-     function HookImport(Base: Pointer; const ModuleName: string;
 
-       const FunctionName: string; NewAddress: Pointer; var OriginalAddress: Pointer): Boolean;
 
-     class function IsWin9xDebugThunk(P: Pointer): Boolean;
 
-     class function ReplaceImport(Base: Pointer; const ModuleName: string; FromProc, ToProc: Pointer): Boolean;
 
-     class function SystemBase: Pointer;
 
-     procedure UnhookAll;
 
-     function UnhookByNewAddress(NewAddress: Pointer): Boolean;
 
-     procedure UnhookByBaseAddress(BaseAddress: Pointer);
 
-     property Items[Index: Integer]: TJclPeMapImgHookItem read GetItems; default;
 
-     property ItemFromOriginalAddress[OriginalAddress: Pointer]: TJclPeMapImgHookItem read GetItemFromOriginalAddress;
 
-     property ItemFromNewAddress[NewAddress: Pointer]: TJclPeMapImgHookItem read GetItemFromNewAddress;
 
-   end;
 
- // Image access under a debbuger
 
- function PeDbgImgNtHeaders32(ProcessHandle: THandle; BaseAddress: TJclAddr32;
 
-   var NtHeaders: TImageNtHeaders32): Boolean;
 
- // TODO 64 bit version
 
- //function PeDbgImgNtHeaders64(ProcessHandle: THandle; BaseAddress: TJclAddr64;
 
- //  var NtHeaders: TImageNtHeaders64): Boolean;
 
- function PeDbgImgLibraryName32(ProcessHandle: THandle; BaseAddress: TJclAddr32;
 
-   var Name: string): Boolean;
 
- //function PeDbgImgLibraryName64(ProcessHandle: THandle; BaseAddress: TJclAddr64;
 
- //  var Name: string): Boolean;
 
- // Borland BPL packages name unmangling
 
- type
 
-   TJclBorUmSymbolKind = (skData, skFunction, skConstructor, skDestructor, skRTTI, skVTable);
 
-   TJclBorUmSymbolModifier = (smQualified, smLinkProc);
 
-   TJclBorUmSymbolModifiers = set of TJclBorUmSymbolModifier;
 
-   TJclBorUmDescription = record
 
-     Kind: TJclBorUmSymbolKind;
 
-     Modifiers: TJclBorUmSymbolModifiers;
 
-   end;
 
-   TJclBorUmResult = (urOk, urNotMangled, urMicrosoft, urError);
 
-   TJclPeUmResult = (umNotMangled, umBorland, umMicrosoft);
 
- function PeBorUnmangleName(const Name: string; out Unmangled: string;
 
-   out Description: TJclBorUmDescription; out BasePos: Integer): TJclBorUmResult; overload;
 
- function PeBorUnmangleName(const Name: string; out Unmangled: string;
 
-   out Description: TJclBorUmDescription): TJclBorUmResult; overload;
 
- function PeBorUnmangleName(const Name: string; out Unmangled: string): TJclBorUmResult; overload;
 
- function PeBorUnmangleName(const Name: string): string; overload;
 
- function PeIsNameMangled(const Name: string): TJclPeUmResult;
 
- function UndecorateSymbolName(const DecoratedName: string; out UnMangled: string; Flags: DWORD): Boolean;
 
- function PeUnmangleName(const Name: string; out Unmangled: string): TJclPeUmResult;
 
- {$IFDEF UNITVERSIONING}
 
- const
 
-   UnitVersioning: TUnitVersionInfo = (
 
-     RCSfile: '$URL$';
 
-     Revision: '$Revision$';
 
-     Date: '$Date$';
 
-     LogPath: 'JCL\source\windows';
 
-     Extra: '';
 
-     Data: nil
 
-     );
 
- {$ENDIF UNITVERSIONING}
 
- implementation
 
- uses
 
-   {$IFDEF HAS_UNITSCOPE}
 
-   System.RTLConsts,
 
-   System.Types, // for inlining TList.Remove
 
-   {$IFDEF HAS_UNIT_CHARACTER}
 
-   System.Character,
 
-   {$ENDIF HAS_UNIT_CHARACTER}
 
-   {$ELSE ~HAS_UNITSCOPE}
 
-   RTLConsts,
 
-   {$IFDEF HAS_UNIT_CHARACTER}
 
-   Character,
 
-   {$ENDIF HAS_UNIT_CHARACTER}
 
-   {$ENDIF ~HAS_UNITSCOPE}
 
-   {$IFNDEF WINSCP}JclLogic,{$ELSE}Math, System.AnsiStrings, {$ENDIF ~WINSCP} JclResources, JclSysUtils, {$IFNDEF WINSCP}JclAnsiStrings,{$ENDIF ~WINSCP} JclStrings{$IFNDEF WINSCP}, JclStringConversions{$ENDIF ~WINSCP};
 
- const
 
-   MANIFESTExtension = '.manifest';
 
-   DebugSectionName    = '.debug';
 
-   ReadOnlySectionName = '.rdata';
 
-   BinaryExtensionLibrary = '.dll';
 
-   {$IFDEF BORLAND}
 
-   CompilerExtensionDCP   = '.dcp';
 
-   BinaryExtensionPackage = '.bpl';
 
-   PackageInfoResName    = 'PACKAGEINFO';
 
-   DescriptionResName    = 'DESCRIPTION';
 
-   PackageOptionsResName = 'PACKAGEOPTIONS';
 
-   DVclAlResName         = 'DVCLAL';
 
-   {$ENDIF BORLAND}
 
- {$IFDEF WINSCP}
 
- // Stubs for JclStringConversions functions
 
- function TryUTF8ToString(const S: TUTF8String; out D: string): Boolean;
 
- begin
 
-   Result := False;
 
- end;
 
- function TryStringToUTF8(const S: string; out D: TUTF8String): Boolean;
 
- begin
 
-   Result := False;
 
- end;
 
- // stub for JclDateTime constant
 
- const
 
-   UnixTimeStart = UnixDateDelta;
 
- // from JclAnsiStrings.pas
 
- function StrLCompA(const Str1, Str2: PAnsiChar; MaxLen: Cardinal): Integer;
 
- begin
 
-   Result := {$IFDEF DEPRECATED_SYSUTILS_ANSISTRINGS}System.AnsiStrings.{$ENDIF}StrLComp(Str1, Str2, MaxLen);
 
- end;
 
- function StrPLCopyA(Dest: PAnsiChar; const Source: AnsiString; MaxLen: Cardinal): PAnsiChar;
 
- begin
 
-   Result := {$IFDEF DEPRECATED_SYSUTILS_ANSISTRINGS}System.AnsiStrings.{$ENDIF}StrPLCopy(Dest, Source, MaxLen);
 
- end;
 
- function StrICompA(const Str1, Str2: PAnsiChar): Integer;
 
- begin
 
-   Result := {$IFDEF DEPRECATED_SYSUTILS_ANSISTRINGS}System.AnsiStrings.{$ENDIF}StrIComp(Str1, Str2);
 
- end;
 
- function StrLenA(S: PAnsiChar): Integer;
 
- begin
 
-   Result := {$IFDEF DEPRECATED_SYSUTILS_ANSISTRINGS}System.AnsiStrings.{$ENDIF}StrLen(S);
 
- end;
 
- {$ENDIF}
 
- // Helper routines
 
- function AddFlagTextRes(var Text: string; const FlagText: PResStringRec; const Value, Mask: Cardinal): Boolean;
 
- begin
 
-   Result := (Value and Mask <> 0);
 
-   if Result then
 
-   begin
 
-     if Length(Text) > 0 then
 
-       Text := Text + ', ';
 
-     Text := Text + LoadResString(FlagText);
 
-   end;
 
- end;
 
- function CompareResourceName(T1, T2: PChar): Boolean;
 
- var
 
-   Long1, Long2: LongRec;
 
- begin
 
-   {$IFDEF CPU64}
 
-   Long1 := LongRec(Int64Rec(T1).Lo);
 
-   Long2 := LongRec(Int64Rec(T2).Lo);
 
-   if (Int64Rec(T1).Hi = 0) and (Int64Rec(T2).Hi = 0) and (Long1.Hi = 0) and (Long2.Hi = 0) then
 
-   {$ENDIF CPU64}
 
-   {$IFDEF CPU32}
 
-   Long1 := LongRec(T1);
 
-   Long2 := LongRec(T2);
 
-   if (Long1.Hi = 0) or (Long2.Hi = 0) then
 
-   {$ENDIF CPU32}
 
-     Result := Long1.Lo = Long2.Lo
 
-   else
 
-     Result := (StrIComp(T1, T2) = 0);
 
- end;
 
- function CreatePeImage(const FileName: TFileName): TJclPeImage;
 
- begin
 
-   Result := TJclPeImage.Create(True);
 
-   Result.FileName := FileName;
 
- end;
 
- function InternalImportedLibraries(const FileName: TFileName;
 
-   Recursive, FullPathName: Boolean; ExternalCache: TJclPeImagesCache): TStringList;
 
- var
 
-   Cache: TJclPeImagesCache;
 
-   procedure ProcessLibraries(const AFileName: TFileName);
 
-   var
 
-     I: Integer;
 
-     S: TFileName;
 
-     ImportLib: TJclPeImportLibItem;
 
-   begin
 
-     with Cache[AFileName].ImportList do
 
-       for I := 0 to Count - 1 do
 
-       begin
 
-         ImportLib := Items[I];
 
-         if FullPathName then
 
-           S := ImportLib.FileName
 
-         else
 
-           S := TFileName(ImportLib.Name);
 
-         if Result.IndexOf(S) = -1 then
 
-         begin
 
-           Result.Add(S);
 
-           if Recursive then
 
-             ProcessLibraries(ImportLib.FileName);
 
-         end;
 
-       end;
 
-   end;
 
- begin
 
-   if ExternalCache = nil then
 
-     Cache := TJclPeImagesCache.Create
 
-   else
 
-     Cache := ExternalCache;
 
-   try
 
-     Result := TStringList.Create;
 
-     try
 
-       Result.Sorted := True;
 
-       Result.Duplicates := dupIgnore;
 
-       ProcessLibraries(FileName);
 
-     except
 
-       FreeAndNil(Result);
 
-       raise;
 
-     end;
 
-   finally
 
-     if ExternalCache = nil then
 
-       Cache.Free;
 
-   end;
 
- end;
 
- // Smart name compare function
 
- function PeStripFunctionAW(const FunctionName: string): string;
 
- var
 
-   L: Integer;
 
- begin
 
-   Result := FunctionName;
 
-   L := Length(Result);
 
-   if (L > 1) then
 
-     case Result[L] of
 
-       'A', 'W':
 
-         if CharIsValidIdentifierLetter(Result[L - 1]) then
 
-           Delete(Result, L, 1);
 
-     end;
 
- end;
 
- function PeSmartFunctionNameSame(const ComparedName, FunctionName: string;
 
-   Options: TJclSmartCompOptions): Boolean;
 
- var
 
-   S: string;
 
- begin
 
-   if scIgnoreCase in Options then
 
-     Result := CompareText(FunctionName, ComparedName) = 0
 
-   else
 
-     Result := (FunctionName = ComparedName);
 
-   if (not Result) and not (scSimpleCompare in Options) then
 
-   begin
 
-     if Length(FunctionName) > 0 then
 
-     begin
 
-       S := PeStripFunctionAW(FunctionName);
 
-       if scIgnoreCase in Options then
 
-         Result := CompareText(S, ComparedName) = 0
 
-       else
 
-         Result := (S = ComparedName);
 
-     end
 
-     else
 
-       Result := False;
 
-   end;
 
- end;
 
- //=== { TJclPeImagesCache } ==================================================
 
- constructor TJclPeImagesCache.Create;
 
- begin
 
-   inherited Create;
 
-   FList := TStringList.Create;
 
-   FList.Sorted := True;
 
-   FList.Duplicates := dupIgnore;
 
- end;
 
- destructor TJclPeImagesCache.Destroy;
 
- begin
 
-   Clear;
 
-   FreeAndNil(FList);
 
-   inherited Destroy;
 
- end;
 
- procedure TJclPeImagesCache.Clear;
 
- var
 
-   I: Integer;
 
- begin
 
-   with FList do
 
-     for I := 0 to Count - 1 do
 
-       Objects[I].Free;
 
-   FList.Clear;
 
- end;
 
- function TJclPeImagesCache.GetCount: Integer;
 
- begin
 
-   Result := FList.Count;
 
- end;
 
- function TJclPeImagesCache.GetImages(const FileName: TFileName): TJclPeImage;
 
- var
 
-   I: Integer;
 
- begin
 
-   I := FList.IndexOf(FileName);
 
-   if I = -1 then
 
-   begin
 
-     Result := GetPeImageClass.Create(True);
 
-     Result.FileName := FileName;
 
-     FList.AddObject(FileName, Result);
 
-   end
 
-   else
 
-     Result := TJclPeImage(FList.Objects[I]);
 
- end;
 
- function TJclPeImagesCache.GetPeImageClass: TJclPeImageClass;
 
- begin
 
-   Result := TJclPeImage;
 
- end;
 
- //=== { TJclPeImageBaseList } ================================================
 
- constructor TJclPeImageBaseList.Create(AImage: TJclPeImage);
 
- begin
 
-   inherited Create(True);
 
-   FImage := AImage;
 
- end;
 
- // Import sort functions
 
- function ImportSortByName(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := CompareStr(TJclPeImportFuncItem(Item1).Name, TJclPeImportFuncItem(Item2).Name);
 
-   if Result = 0 then
 
-     Result := CompareStr(TJclPeImportFuncItem(Item1).ImportLib.Name, TJclPeImportFuncItem(Item2).ImportLib.Name);
 
-   if Result = 0 then
 
-     Result := TJclPeImportFuncItem(Item1).Ordinal - TJclPeImportFuncItem(Item2).Ordinal;
 
- end;
 
- function ImportSortByNameDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ImportSortByName(Item2, Item1);
 
- end;
 
- function ImportSortByHint(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := TJclPeImportFuncItem(Item1).Hint - TJclPeImportFuncItem(Item2).Hint;
 
- end;
 
- function ImportSortByHintDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ImportSortByHint(Item2, Item1);
 
- end;
 
- function ImportSortByDll(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := CompareStr(TJclPeImportFuncItem(Item1).ImportLib.Name,
 
-     TJclPeImportFuncItem(Item2).ImportLib.Name);
 
-   if Result = 0 then
 
-     Result := ImportSortByName(Item1, Item2);
 
- end;
 
- function ImportSortByDllDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ImportSortByDll(Item2, Item1);
 
- end;
 
- function ImportSortByOrdinal(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := CompareStr(TJclPeImportFuncItem(Item1).ImportLib.Name,
 
-     TJclPeImportFuncItem(Item2).ImportLib.Name);
 
-   if Result = 0 then
 
-     Result := TJclPeImportFuncItem(Item1).Ordinal -  TJclPeImportFuncItem(Item2).Ordinal;
 
- end;
 
- function ImportSortByOrdinalDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ImportSortByOrdinal(Item2, Item1);
 
- end;
 
- function GetImportSortFunction(SortType: TJclPeImportSort; Descending: Boolean): TListSortCompare;
 
- const
 
-   SortFunctions: array [TJclPeImportSort, Boolean] of TListSortCompare =
 
-     ((ImportSortByName, ImportSortByNameDESC),
 
-      (ImportSortByOrdinal, ImportSortByOrdinalDESC),
 
-      (ImportSortByHint, ImportSortByHintDESC),
 
-      (ImportSortByDll, ImportSortByDllDESC)
 
-     );
 
- begin
 
-   Result := SortFunctions[SortType, Descending];
 
- end;
 
- function ImportLibSortByIndex(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := TJclPeImportLibItem(Item1).ImportDirectoryIndex -
 
-     TJclPeImportLibItem(Item2).ImportDirectoryIndex;
 
- end;
 
- function ImportLibSortByName(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := AnsiCompareStr(TJclPeImportLibItem(Item1).Name, TJclPeImportLibItem(Item2).Name);
 
-   if Result = 0 then
 
-     Result := ImportLibSortByIndex(Item1, Item2);
 
- end;
 
- function GetImportLibSortFunction(SortType: TJclPeImportLibSort): TListSortCompare;
 
- const
 
-   SortFunctions: array [TJclPeImportLibSort] of TListSortCompare =
 
-     (ImportLibSortByName, ImportLibSortByIndex);
 
- begin
 
-   Result := SortFunctions[SortType];
 
- end;
 
- //=== { TJclPeImportFuncItem } ===============================================
 
- constructor TJclPeImportFuncItem.Create(AImportLib: TJclPeImportLibItem;
 
-   AOrdinal: Word; AHint: Word; const AName: string);
 
- begin
 
-   inherited Create;
 
-   FImportLib := AImportLib;
 
-   FOrdinal := AOrdinal;
 
-   FHint := AHint;
 
-   FName := AName;
 
-   FResolveCheck := icNotChecked;
 
-   FIndirectImportName := False;
 
- end;
 
- function TJclPeImportFuncItem.GetIsByOrdinal: Boolean;
 
- begin
 
-   Result := FOrdinal <> 0;
 
- end;
 
- procedure TJclPeImportFuncItem.SetIndirectImportName(const Value: string);
 
- begin
 
-   FName := Value;
 
-   FIndirectImportName := True;
 
- end;
 
- procedure TJclPeImportFuncItem.SetName(const Value: string);
 
- begin
 
-   FName := Value;
 
-   FIndirectImportName := False;
 
- end;
 
- procedure TJclPeImportFuncItem.SetResolveCheck(Value: TJclPeResolveCheck);
 
- begin
 
-   FResolveCheck := Value;
 
- end;
 
- //=== { TJclPeImportLibItem } ================================================
 
- constructor TJclPeImportLibItem.Create(AImage: TJclPeImage;
 
-   AImportDescriptor: Pointer; AImportKind: TJclPeImportKind; const AName: string;
 
-   AThunk: Pointer);
 
- begin
 
-   inherited Create(AImage);
 
-   FTotalResolveCheck := icNotChecked;
 
-   FImportDescriptor := AImportDescriptor;
 
-   FImportKind := AImportKind;
 
-   FName := AName;
 
-   FThunk := AThunk;
 
-   FThunkData := AThunk;
 
- end;
 
- procedure TJclPeImportLibItem.CheckImports(ExportImage: TJclPeImage);
 
- var
 
-   I: Integer;
 
-   ExportList: TJclPeExportFuncList;
 
- begin
 
-   if ExportImage.StatusOK then
 
-   begin
 
-     FTotalResolveCheck := icResolved;
 
-     ExportList := ExportImage.ExportList;
 
-     for I := 0 to Count - 1 do
 
-     begin
 
-       with Items[I] do
 
-         if IsByOrdinal then
 
-         begin
 
-           if ExportList.OrdinalValid(Ordinal) then
 
-             SetResolveCheck(icResolved)
 
-           else
 
-           begin
 
-             SetResolveCheck(icUnresolved);
 
-             Self.FTotalResolveCheck := icUnresolved;
 
-           end;
 
-         end
 
-         else
 
-         begin
 
-           if ExportList.ItemFromName[Items[I].Name] <> nil then
 
-             SetResolveCheck(icResolved)
 
-           else
 
-           begin
 
-             SetResolveCheck(icUnresolved);
 
-             Self.FTotalResolveCheck := icUnresolved;
 
-           end;
 
-         end;
 
-     end;
 
-   end
 
-   else
 
-   begin
 
-     FTotalResolveCheck := icUnresolved;
 
-     for I := 0 to Count - 1 do
 
-       Items[I].SetResolveCheck(icUnresolved);
 
-   end;
 
- end;
 
- procedure TJclPeImportLibItem.CreateList;
 
-   procedure CreateList32;
 
-   var
 
-     Thunk32: PImageThunkData32;
 
-     OrdinalName: PImageImportByName;
 
-     Ordinal, Hint: Word;
 
-     Name: PAnsiChar;
 
-     ImportName: string;
 
-   begin
 
-     Thunk32 := PImageThunkData32(FThunk);
 
-     while Thunk32^.Function_ <> 0 do
 
-     begin
 
-       Ordinal := 0;
 
-       Hint := 0;
 
-       Name := nil;
 
-       if Thunk32^.Ordinal and IMAGE_ORDINAL_FLAG32 = 0 then
 
-       begin
 
-         case ImportKind of
 
-           ikImport, ikBoundImport:
 
-             begin
 
-               OrdinalName := PImageImportByName(Image.RvaToVa(Thunk32^.AddressOfData));
 
-               Hint := OrdinalName.Hint;
 
-               Name := OrdinalName.Name;
 
-             end;
 
-           ikDelayImport:
 
-             begin
 
-               OrdinalName := PImageImportByName(Image.RvaToVaEx(Thunk32^.AddressOfData));
 
-               Hint := OrdinalName.Hint;
 
-               Name := OrdinalName.Name;
 
-             end;
 
-         end;
 
-       end
 
-       else
 
-         Ordinal := IMAGE_ORDINAL32(Thunk32^.Ordinal);
 
-       if not TryUTF8ToString(Name, ImportName) then
 
-         ImportName := string(Name);
 
-       Add(TJclPeImportFuncItem.Create(Self, Ordinal, Hint, ImportName));
 
-       Inc(Thunk32);
 
-     end;
 
-   end;
 
-   procedure CreateList64;
 
-   var
 
-     Thunk64: PImageThunkData64;
 
-     OrdinalName: PImageImportByName;
 
-     Ordinal, Hint: Word;
 
-     Name: PAnsiChar;
 
-     ImportName: string;
 
-   begin
 
-     Thunk64 := PImageThunkData64(FThunk);
 
-     while Thunk64^.Function_ <> 0 do
 
-     begin
 
-       Ordinal := 0;
 
-       Hint := 0;
 
-       Name := nil;
 
-       if Thunk64^.Ordinal and IMAGE_ORDINAL_FLAG64 = 0 then
 
-       begin
 
-         case ImportKind of
 
-           ikImport, ikBoundImport:
 
-             begin
 
-               OrdinalName := PImageImportByName(Image.RvaToVa(Thunk64^.AddressOfData));
 
-               Hint := OrdinalName.Hint;
 
-               Name := OrdinalName.Name;
 
-             end;
 
-           ikDelayImport:
 
-             begin
 
-               OrdinalName := PImageImportByName(Image.RvaToVaEx(Thunk64^.AddressOfData));
 
-               Hint := OrdinalName.Hint;
 
-               Name := OrdinalName.Name;
 
-             end;
 
-         end;
 
-       end
 
-       else
 
-         Ordinal := IMAGE_ORDINAL64(Thunk64^.Ordinal);
 
-       if not TryUTF8ToString(Name, ImportName) then
 
-         ImportName := string(Name);
 
-       Add(TJclPeImportFuncItem.Create(Self, Ordinal, Hint, ImportName));
 
-       Inc(Thunk64);
 
-     end;
 
-   end;
 
- begin
 
-   if FThunk = nil then
 
-     Exit;
 
-   case Image.Target of
 
-     taWin32:
 
-       CreateList32;
 
-     taWin64:
 
-       CreateList64;
 
-   end;
 
-   FThunk := nil;
 
- end;
 
- function TJclPeImportLibItem.GetCount: Integer;
 
- begin
 
-   if FThunk <> nil then
 
-     CreateList;
 
-   Result := inherited Count;
 
- end;
 
- function TJclPeImportLibItem.GetFileName: TFileName;
 
- begin
 
-   Result := Image.ExpandModuleName(Name);
 
- end;
 
- function TJclPeImportLibItem.GetItems(Index: Integer): TJclPeImportFuncItem;
 
- begin
 
-   Result := TJclPeImportFuncItem(Get(Index));
 
- end;
 
- function TJclPeImportLibItem.GetName: string;
 
- begin
 
-   Result := AnsiLowerCase(OriginalName);
 
- end;
 
- function TJclPeImportLibItem.GetThunkData32: PImageThunkData32;
 
- begin
 
-   if Image.Target = taWin32 then
 
-     Result := FThunkData
 
-   else
 
-     Result := nil;
 
- end;
 
- function TJclPeImportLibItem.GetThunkData64: PImageThunkData64;
 
- begin
 
-   if Image.Target = taWin64 then
 
-     Result := FThunkData
 
-   else
 
-     Result := nil;
 
- end;
 
- procedure TJclPeImportLibItem.SetImportDirectoryIndex(Value: Integer);
 
- begin
 
-   FImportDirectoryIndex := Value;
 
- end;
 
- procedure TJclPeImportLibItem.SetImportKind(Value: TJclPeImportKind);
 
- begin
 
-   FImportKind := Value;
 
- end;
 
- procedure TJclPeImportLibItem.SetSorted(Value: Boolean);
 
- begin
 
-   FSorted := Value;
 
- end;
 
- procedure TJclPeImportLibItem.SetThunk(Value: Pointer);
 
- begin
 
-   FThunk := Value;
 
-   FThunkData := Value;
 
- end;
 
- procedure TJclPeImportLibItem.SortList(SortType: TJclPeImportSort; Descending: Boolean);
 
- begin
 
-   if not FSorted or (SortType <> FLastSortType) or (Descending <> FLastSortDescending) then
 
-   begin
 
-     GetCount; // create list if it wasn't created
 
-     Sort(GetImportSortFunction(SortType, Descending));
 
-     FLastSortType := SortType;
 
-     FLastSortDescending := Descending;
 
-     FSorted := True;
 
-   end;
 
- end;
 
- //=== { TJclPeImportList } ===================================================
 
- constructor TJclPeImportList.Create(AImage: TJclPeImage);
 
- begin
 
-   inherited Create(AImage);
 
-   FAllItemsList := TList.Create;
 
-   FAllItemsList.Capacity := 256;
 
-   FUniqueNamesList := TStringList.Create;
 
-   FUniqueNamesList.Sorted := True;
 
-   FUniqueNamesList.Duplicates := dupIgnore;
 
-   FLastAllSortType := isName;
 
-   FLastAllSortDescending := False;
 
-   CreateList;
 
- end;
 
- destructor TJclPeImportList.Destroy;
 
- var
 
-   I: Integer;
 
- begin
 
-   FreeAndNil(FAllItemsList);
 
-   FreeAndNil(FUniqueNamesList);
 
-   for I := 0 to Length(FparallelImportTable) - 1 do
 
-     FreeMem(FparallelImportTable[I]);
 
-   inherited Destroy;
 
- end;
 
- procedure TJclPeImportList.CheckImports(PeImageCache: TJclPeImagesCache);
 
- var
 
-   I: Integer;
 
-   ExportPeImage: TJclPeImage;
 
- begin
 
-   Image.CheckNotAttached;
 
-   if PeImageCache <> nil then
 
-     ExportPeImage := nil // to make the compiler happy
 
-   else
 
-     ExportPeImage := TJclPeImage.Create(True);
 
-   try
 
-     for I := 0 to Count - 1 do
 
-       if Items[I].TotalResolveCheck = icNotChecked then
 
-       begin
 
-         if PeImageCache <> nil then
 
-           ExportPeImage := PeImageCache[Items[I].FileName]
 
-         else
 
-           ExportPeImage.FileName := Items[I].FileName;
 
-         ExportPeImage.ExportList.PrepareForFastNameSearch;
 
-         Items[I].CheckImports(ExportPeImage);
 
-       end;
 
-   finally
 
-     if PeImageCache = nil then
 
-       ExportPeImage.Free;
 
-   end;
 
- end;
 
- procedure TJclPeImportList.CreateList;
 
-   procedure CreateDelayImportList32(DelayImportDesc: PImgDelayDescrV1);
 
-   var
 
-     LibItem: TJclPeImportLibItem;
 
-     UTF8Name: TUTF8String;
 
-     LibName: string;
 
-   begin
 
-     while DelayImportDesc^.szName <> nil do
 
-     begin
 
-       UTF8Name := PAnsiChar(Image.RvaToVaEx(DWORD(DelayImportDesc^.szName)));
 
-       if not TryUTF8ToString(UTF8Name, LibName) then
 
-         LibName := string(UTF8Name);
 
-       LibItem := TJclPeImportLibItem.Create(Image, DelayImportDesc, ikDelayImport,
 
-         LibName, Image.RvaToVaEx(DWORD(DelayImportDesc^.pINT)));
 
-       Add(LibItem);
 
-       FUniqueNamesList.AddObject(AnsiLowerCase(LibItem.Name), LibItem);
 
-       Inc(DelayImportDesc);
 
-     end;
 
-   end;
 
-   procedure CreateDelayImportList64(DelayImportDesc: PImgDelayDescrV2);
 
-   var
 
-     LibItem: TJclPeImportLibItem;
 
-     UTF8Name: TUTF8String;
 
-     LibName: string;
 
-   begin
 
-     while DelayImportDesc^.rvaDLLName <> 0 do
 
-     begin
 
-       UTF8Name := PAnsiChar(Image.RvaToVa(DelayImportDesc^.rvaDLLName));
 
-       if not TryUTF8ToString(UTF8Name, LibName) then
 
-         LibName := string(UTF8Name);
 
-       LibItem := TJclPeImportLibItem.Create(Image, DelayImportDesc, ikDelayImport,
 
-         LibName, Image.RvaToVa(DelayImportDesc^.rvaINT));
 
-       Add(LibItem);
 
-       FUniqueNamesList.AddObject(AnsiLowerCase(LibItem.Name), LibItem);
 
-       Inc(DelayImportDesc);
 
-     end;
 
-   end;
 
- var
 
-   ImportDesc: PImageImportDescriptor;
 
-   LibItem: TJclPeImportLibItem;
 
-   UTF8Name: TUTF8String;
 
-   LibName, ModuleName: string;
 
-   DelayImportDesc: Pointer;
 
-   BoundImports, BoundImport: PImageBoundImportDescriptor;
 
-   S: string;
 
-   I: Integer;
 
-   Thunk: Pointer;
 
- begin
 
-   SetCapacity(100);
 
-   with Image do
 
-   begin
 
-     if not StatusOK then
 
-       Exit;
 
-     ImportDesc := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_IMPORT);
 
-     if ImportDesc <> nil then
 
-       while ImportDesc^.Name <> 0 do
 
-       begin
 
-         if ImportDesc^.Union.Characteristics = 0 then
 
-         begin
 
-           if AttachedImage then  // Borland images doesn't have two parallel arrays
 
-             Thunk := nil // see MakeBorlandImportTableForMappedImage method
 
-           else
 
-             Thunk := RvaToVa(ImportDesc^.FirstThunk);
 
-           FLinkerProducer := lrBorland;
 
-         end
 
-         else
 
-         begin
 
-           Thunk := RvaToVa(ImportDesc^.Union.Characteristics);
 
-           FLinkerProducer := lrMicrosoft;
 
-         end;
 
-         UTF8Name := PAnsiChar(RvaToVa(ImportDesc^.Name));
 
-         if not TryUTF8ToString(UTF8Name, LibName) then
 
-           LibName := string(UTF8Name);
 
-         LibItem := TJclPeImportLibItem.Create(Image, ImportDesc, ikImport, LibName, Thunk);
 
-         Add(LibItem);
 
-         FUniqueNamesList.AddObject(AnsiLowerCase(LibItem.Name), LibItem);
 
-         Inc(ImportDesc);
 
-       end;
 
-     DelayImportDesc := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
 
-     if DelayImportDesc <> nil then
 
-     begin
 
-       case Target of
 
-         taWin32:
 
-           CreateDelayImportList32(DelayImportDesc);
 
-         taWin64:
 
-           CreateDelayImportList64(DelayImportDesc);
 
-       end;
 
-     end;
 
-     BoundImports := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT);
 
-     if BoundImports <> nil then
 
-     begin
 
-       BoundImport := BoundImports;
 
-       while BoundImport^.OffsetModuleName <> 0 do
 
-       begin
 
-         UTF8Name := PAnsiChar(TJclAddr(BoundImports) + BoundImport^.OffsetModuleName);
 
-         if not TryUTF8ToString(UTF8Name, ModuleName) then
 
-           ModuleName := string(UTF8Name);
 
-         S := AnsiLowerCase(ModuleName);
 
-         I := FUniqueNamesList.IndexOf(S);
 
-         if I >= 0 then
 
-           TJclPeImportLibItem(FUniqueNamesList.Objects[I]).SetImportKind(ikBoundImport);
 
-         for I := 1 to BoundImport^.NumberOfModuleForwarderRefs do
 
-           Inc(PImageBoundForwarderRef(BoundImport)); // skip forward information
 
-         Inc(BoundImport);
 
-       end;
 
-     end;
 
-   end;
 
-   for I := 0 to Count - 1 do
 
-     Items[I].SetImportDirectoryIndex(I);
 
- end;
 
- function TJclPeImportList.GetAllItemCount: Integer;
 
- begin
 
-   Result := FAllItemsList.Count;
 
-   if Result = 0 then // we haven't created the list yet -> create unsorted list
 
-   begin
 
-     RefreshAllItems;
 
-     Result := FAllItemsList.Count;
 
-   end;
 
- end;
 
- function TJclPeImportList.GetAllItems(Index: Integer): TJclPeImportFuncItem;
 
- begin
 
-   Result := TJclPeImportFuncItem(FAllItemsList[Index]);
 
- end;
 
- function TJclPeImportList.GetItems(Index: Integer): TJclPeImportLibItem;
 
- begin
 
-   Result := TJclPeImportLibItem(Get(Index));
 
- end;
 
- function TJclPeImportList.GetUniqueLibItemCount: Integer;
 
- begin
 
-   Result := FUniqueNamesList.Count;
 
- end;
 
- function TJclPeImportList.GetUniqueLibItemFromName(const Name: string): TJclPeImportLibItem;
 
- var
 
-   I: Integer;
 
- begin
 
-   I := FUniqueNamesList.IndexOf(Name);
 
-   if I = -1 then
 
-     Result := nil
 
-   else
 
-     Result := TJclPeImportLibItem(FUniqueNamesList.Objects[I]);
 
- end;
 
- function TJclPeImportList.GetUniqueLibItems(Index: Integer): TJclPeImportLibItem;
 
- begin
 
-   Result := TJclPeImportLibItem(FUniqueNamesList.Objects[Index]);
 
- end;
 
- function TJclPeImportList.GetUniqueLibNames(Index: Integer): string;
 
- begin
 
-   Result := FUniqueNamesList[Index];
 
- end;
 
- function TJclPeImportList.MakeBorlandImportTableForMappedImage: Boolean;
 
- var
 
-   FileImage: TJclPeImage;
 
-   I, TableSize: Integer;
 
- begin
 
-   if Image.AttachedImage and (LinkerProducer = lrBorland) and
 
-     (Length(FParallelImportTable) = 0) then
 
-   begin
 
-     FileImage := TJclPeImage.Create(True);
 
-     try
 
-       FileImage.FileName := Image.FileName;
 
-       Result := FileImage.StatusOK;
 
-       if Result then
 
-       begin
 
-         SetLength(FParallelImportTable, FileImage.ImportList.Count);
 
-         for I := 0 to FileImage.ImportList.Count - 1 do
 
-         begin
 
-           Assert(Items[I].ImportKind = ikImport); // Borland doesn't have Delay load or Bound imports
 
-           TableSize := (FileImage.ImportList[I].Count + 1);
 
-           case Image.Target of
 
-             taWin32:
 
-               begin
 
-                 TableSize := TableSize * SizeOf(TImageThunkData32);
 
-                 GetMem(FParallelImportTable[I], TableSize);
 
-                 System.Move(FileImage.ImportList[I].ThunkData32^, FParallelImportTable[I]^, TableSize);
 
-                 Items[I].SetThunk(FParallelImportTable[I]);
 
-               end;
 
-             taWin64:
 
-               begin
 
-                 TableSize := TableSize * SizeOf(TImageThunkData64);
 
-                 GetMem(FParallelImportTable[I], TableSize);
 
-                 System.Move(FileImage.ImportList[I].ThunkData64^, FParallelImportTable[I]^, TableSize);
 
-                 Items[I].SetThunk(FParallelImportTable[I]);
 
-               end;
 
-           end;
 
-         end;
 
-       end;
 
-     finally
 
-       FileImage.Free;
 
-     end;
 
-   end
 
-   else
 
-     Result := True;
 
- end;
 
- procedure TJclPeImportList.RefreshAllItems;
 
- var
 
-   L, I: Integer;
 
-   LibItem: TJclPeImportLibItem;
 
- begin
 
-   FAllItemsList.Clear;
 
-   for L := 0 to Count - 1 do
 
-   begin
 
-     LibItem := Items[L];
 
-     if (Length(FFilterModuleName) = 0) or (AnsiCompareText(LibItem.Name, FFilterModuleName) = 0) then
 
-       for I := 0 to LibItem.Count - 1 do
 
-         FAllItemsList.Add(LibItem[I]);
 
-   end;
 
- end;
 
- procedure TJclPeImportList.SetFilterModuleName(const Value: string);
 
- begin
 
-   if (FFilterModuleName <> Value) or (FAllItemsList.Count = 0) then
 
-   begin
 
-     FFilterModuleName := Value;
 
-     RefreshAllItems;
 
-     FAllItemsList.Sort(GetImportSortFunction(FLastAllSortType, FLastAllSortDescending));
 
-   end;
 
- end;
 
- function TJclPeImportList.SmartFindName(const CompareName, LibName: string;
 
-   Options: TJclSmartCompOptions): TJclPeImportFuncItem;
 
- var
 
-   L, I: Integer;
 
-   LibItem: TJclPeImportLibItem;
 
- begin
 
-   Result := nil;
 
-   for L := 0 to Count - 1 do
 
-   begin
 
-     LibItem := Items[L];
 
-     if (Length(LibName) = 0) or (AnsiCompareText(LibItem.Name, LibName) = 0) then
 
-       for I := 0 to LibItem.Count - 1 do
 
-         if PeSmartFunctionNameSame(CompareName, LibItem[I].Name, Options) then
 
-         begin
 
-           Result := LibItem[I];
 
-           Break;
 
-         end;
 
-   end;
 
- end;
 
- procedure TJclPeImportList.SortAllItemsList(SortType: TJclPeImportSort; Descending: Boolean);
 
- begin
 
-   GetAllItemCount; // create list if it wasn't created
 
-   FAllItemsList.Sort(GetImportSortFunction(SortType, Descending));
 
-   FLastAllSortType := SortType;
 
-   FLastAllSortDescending := Descending;
 
- end;
 
- procedure TJclPeImportList.SortList(SortType: TJclPeImportLibSort);
 
- begin
 
-   Sort(GetImportLibSortFunction(SortType));
 
- end;
 
- procedure TJclPeImportList.TryGetNamesForOrdinalImports;
 
- var
 
-   LibNamesList: TStringList;
 
-   L, I: Integer;
 
-   LibPeDump: TJclPeImage;
 
-   procedure TryGetNames(const ModuleName: string);
 
-   var
 
-     Item: TJclPeImportFuncItem;
 
-     I, L: Integer;
 
-     ImportLibItem: TJclPeImportLibItem;
 
-     ExportItem: TJclPeExportFuncItem;
 
-     ExportList: TJclPeExportFuncList;
 
-   begin
 
-     if Image.AttachedImage then
 
-       LibPeDump.AttachLoadedModule(GetModuleHandle(PChar(ModuleName)))
 
-     else
 
-       LibPeDump.FileName := Image.ExpandModuleName(ModuleName);
 
-     if not LibPeDump.StatusOK then
 
-       Exit;
 
-     ExportList := LibPeDump.ExportList;
 
-     for L := 0 to Count - 1 do
 
-     begin
 
-       ImportLibItem := Items[L];
 
-       if AnsiCompareText(ImportLibItem.Name, ModuleName) = 0 then
 
-       begin
 
-         for I := 0 to ImportLibItem.Count - 1 do
 
-         begin
 
-           Item := ImportLibItem[I];
 
-           if Item.IsByOrdinal then
 
-           begin
 
-             ExportItem := ExportList.ItemFromOrdinal[Item.Ordinal];
 
-             if (ExportItem <> nil) and (ExportItem.Name <> '') then
 
-               Item.SetIndirectImportName(ExportItem.Name);
 
-           end;
 
-         end;
 
-         ImportLibItem.SetSorted(False);
 
-       end;
 
-     end;
 
-   end;
 
- begin
 
-   LibNamesList := TStringList.Create;
 
-   try
 
-     LibNamesList.Sorted := True;
 
-     LibNamesList.Duplicates := dupIgnore;
 
-     for L := 0 to Count - 1 do
 
-       with Items[L] do
 
-         for I := 0 to Count - 1 do
 
-           if Items[I].IsByOrdinal then
 
-             LibNamesList.Add(AnsiUpperCase(Name));
 
-     LibPeDump := TJclPeImage.Create(True);
 
-     try
 
-       for I := 0 to LibNamesList.Count - 1 do
 
-         TryGetNames(LibNamesList[I]);
 
-     finally
 
-       LibPeDump.Free;
 
-     end;
 
-     SortAllItemsList(FLastAllSortType, FLastAllSortDescending);
 
-   finally
 
-     LibNamesList.Free;
 
-   end;
 
- end;
 
- //=== { TJclPeExportFuncItem } ===============================================
 
- constructor TJclPeExportFuncItem.Create(AExportList: TJclPeExportFuncList;
 
-   const AName, AForwardedName: string; AAddress: DWORD; AHint: Word;
 
-   AOrdinal: Word; AResolveCheck: TJclPeResolveCheck);
 
- var
 
-   DotPos: Integer;
 
- begin
 
-   inherited Create;
 
-   FExportList := AExportList;
 
-   FName := AName;
 
-   FForwardedName := AForwardedName;
 
-   FAddress := AAddress;
 
-   FHint := AHint;
 
-   FOrdinal := AOrdinal;
 
-   FResolveCheck := AResolveCheck;
 
-   DotPos := AnsiPos('.', ForwardedName);
 
-   if DotPos > 0 then
 
-     FForwardedDotPos := Copy(ForwardedName, DotPos + 1, Length(ForwardedName) - DotPos)
 
-   else
 
-     FForwardedDotPos := '';
 
- end;
 
- function TJclPeExportFuncItem.GetAddressOrForwardStr: string;
 
- begin
 
-   if IsForwarded then
 
-     Result := ForwardedName
 
-   else
 
-     FmtStr(Result, '%.8x', [Address]);
 
- end;
 
- function TJclPeExportFuncItem.GetForwardedFuncName: string;
 
- begin
 
-   if (Length(FForwardedDotPos) > 0) and (FForwardedDotPos[1] <> '#') then
 
-     Result := FForwardedDotPos
 
-   else
 
-     Result := '';
 
- end;
 
- function TJclPeExportFuncItem.GetForwardedFuncOrdinal: DWORD;
 
- begin
 
-   if (Length(FForwardedDotPos) > 0) and (FForwardedDotPos[1] = '#') then
 
-     Result := StrToIntDef(FForwardedDotPos, 0)
 
-   else
 
-     Result := 0;
 
- end;
 
- function TJclPeExportFuncItem.GetForwardedLibName: string;
 
- begin
 
-   if Length(FForwardedDotPos) = 0 then
 
-     Result := ''
 
-   else
 
-     Result := AnsiLowerCase(Copy(FForwardedName, 1, Length(FForwardedName) - Length(FForwardedDotPos) - 1)) + BinaryExtensionLibrary;
 
- end;
 
- function TJclPeExportFuncItem.GetIsExportedVariable: Boolean;
 
- begin
 
-   case FExportList.Image.Target of
 
-     taWin32:
 
-     begin
 
-       {$IFDEF DELPHI64_TEMPORARY}
 
-       System.Error(rePlatformNotImplemented);//there is no BaseOfData in the 32-bit header for Win64
 
-       Result := False;
 
-       {$ELSE ~DELPHI64_TEMPORARY}
 
-       Result := (Address >= FExportList.Image.OptionalHeader32.BaseOfData);
 
-       {$ENDIF ~DELPHI64_TEMPORARY}
 
-     end;
 
-     taWin64:
 
-       Result := False;
 
-       // TODO equivalent for 64-bit modules
 
-       //Result := (Address >= FExportList.Image.OptionalHeader64.BaseOfData);
 
-   else
 
-     Result := False;
 
-   end;
 
- end;
 
- function TJclPeExportFuncItem.GetIsForwarded: Boolean;
 
- begin
 
-   Result := Length(FForwardedName) <> 0;
 
- end;
 
- function TJclPeExportFuncItem.GetMappedAddress: Pointer;
 
- begin
 
-   Result := FExportList.Image.RvaToVa(FAddress);
 
- end;
 
- function TJclPeExportFuncItem.GetSectionName: string;
 
- begin
 
-   if IsForwarded then
 
-     Result := ''
 
-   else
 
-     with FExportList.Image do
 
-       Result := ImageSectionNameFromRva[Address];
 
- end;
 
- procedure TJclPeExportFuncItem.SetResolveCheck(Value: TJclPeResolveCheck);
 
- begin
 
-   FResolveCheck := Value;
 
- end;
 
- // Export sort functions
 
- function ExportSortByName(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := CompareStr(TJclPeExportFuncItem(Item1).Name, TJclPeExportFuncItem(Item2).Name);
 
- end;
 
- function ExportSortByNameDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ExportSortByName(Item2, Item1);
 
- end;
 
- function ExportSortByOrdinal(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := TJclPeExportFuncItem(Item1).Ordinal - TJclPeExportFuncItem(Item2).Ordinal;
 
- end;
 
- function ExportSortByOrdinalDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ExportSortByOrdinal(Item2, Item1);
 
- end;
 
- function ExportSortByHint(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := TJclPeExportFuncItem(Item1).Hint - TJclPeExportFuncItem(Item2).Hint;
 
- end;
 
- function ExportSortByHintDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ExportSortByHint(Item2, Item1);
 
- end;
 
- function ExportSortByAddress(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := INT_PTR(TJclPeExportFuncItem(Item1).Address) - INT_PTR(TJclPeExportFuncItem(Item2).Address);
 
-   if Result = 0 then
 
-     Result := ExportSortByName(Item1, Item2);
 
- end;
 
- function ExportSortByAddressDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ExportSortByAddress(Item2, Item1);
 
- end;
 
- function ExportSortByForwarded(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := CompareStr(TJclPeExportFuncItem(Item1).ForwardedName, TJclPeExportFuncItem(Item2).ForwardedName);
 
-   if Result = 0 then
 
-     Result := ExportSortByName(Item1, Item2);
 
- end;
 
- function ExportSortByForwardedDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ExportSortByForwarded(Item2, Item1);
 
- end;
 
- function ExportSortByAddrOrFwd(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := CompareStr(TJclPeExportFuncItem(Item1).AddressOrForwardStr, TJclPeExportFuncItem(Item2).AddressOrForwardStr);
 
- end;
 
- function ExportSortByAddrOrFwdDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ExportSortByAddrOrFwd(Item2, Item1);
 
- end;
 
- function ExportSortBySection(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := CompareStr(TJclPeExportFuncItem(Item1).SectionName, TJclPeExportFuncItem(Item2).SectionName);
 
-   if Result = 0 then
 
-     Result := ExportSortByName(Item1, Item2);
 
- end;
 
- function ExportSortBySectionDESC(Item1, Item2: Pointer): Integer;
 
- begin
 
-   Result := ExportSortBySection(Item2, Item1);
 
- end;
 
- //=== { TJclPeExportFuncList } ===============================================
 
- constructor TJclPeExportFuncList.Create(AImage: TJclPeImage);
 
- begin
 
-   inherited Create(AImage);
 
-   FTotalResolveCheck := icNotChecked;
 
-   CreateList;
 
- end;
 
- destructor TJclPeExportFuncList.Destroy;
 
- begin
 
-   FreeAndNil(FForwardedLibsList);
 
-   inherited Destroy;
 
- end;
 
- function TJclPeExportFuncList.CanPerformFastNameSearch: Boolean;
 
- begin
 
-   Result := FSorted and (FLastSortType = esName) and not FLastSortDescending;
 
- end;
 
- procedure TJclPeExportFuncList.CheckForwards(PeImageCache: TJclPeImagesCache);
 
- var
 
-   I: Integer;
 
-   FullFileName: TFileName;
 
-   ForwardPeImage: TJclPeImage;
 
-   ModuleResolveCheck: TJclPeResolveCheck;
 
-   procedure PerformCheck(const ModuleName: string);
 
-   var
 
-     I: Integer;
 
-     Item: TJclPeExportFuncItem;
 
-     EL: TJclPeExportFuncList;
 
-   begin
 
-     EL := ForwardPeImage.ExportList;
 
-     EL.PrepareForFastNameSearch;
 
-     ModuleResolveCheck := icResolved;
 
-     for I := 0 to Count - 1 do
 
-     begin
 
-       Item := Items[I];
 
-       if (not Item.IsForwarded) or (Item.ResolveCheck <> icNotChecked) or
 
-         (Item.ForwardedLibName <> ModuleName) then
 
-         Continue;
 
-       if EL.ItemFromName[Item.ForwardedFuncName] = nil then
 
-       begin
 
-         Item.SetResolveCheck(icUnresolved);
 
-         ModuleResolveCheck := icUnresolved;
 
-       end
 
-       else
 
-         Item.SetResolveCheck(icResolved);
 
-     end;
 
-   end;
 
- begin
 
-   if not AnyForwards then
 
-     Exit;
 
-   FTotalResolveCheck := icResolved;
 
-   if PeImageCache <> nil then
 
-     ForwardPeImage := nil // to make the compiler happy
 
-   else
 
-     ForwardPeImage := TJclPeImage.Create(True);
 
-   try
 
-     for I := 0 to ForwardedLibsList.Count - 1 do
 
-     begin
 
-       FullFileName := Image.ExpandModuleName(ForwardedLibsList[I]);
 
-       if PeImageCache <> nil then
 
-         ForwardPeImage := PeImageCache[FullFileName]
 
-       else
 
-         ForwardPeImage.FileName := FullFileName;
 
-       if ForwardPeImage.StatusOK then
 
-         PerformCheck(ForwardedLibsList[I])
 
-       else
 
-         ModuleResolveCheck := icUnresolved;
 
-       FForwardedLibsList.Objects[I] := Pointer(ModuleResolveCheck);
 
-       if ModuleResolveCheck = icUnresolved then
 
-         FTotalResolveCheck := icUnresolved;
 
-     end;
 
-   finally
 
-     if PeImageCache = nil then
 
-       ForwardPeImage.Free;
 
-   end;
 
- end;
 
- procedure TJclPeExportFuncList.CreateList;
 
- var
 
-   Functions: Pointer;
 
-   Address, NameCount: DWORD;
 
-   NameOrdinals: PWORD;
 
-   Names: PDWORD;
 
-   I: Integer;
 
-   ExportItem: TJclPeExportFuncItem;
 
-   ExportVABegin, ExportVAEnd: DWORD;
 
-   UTF8Name: TUTF8String;
 
-   ForwardedName, ExportName: string;
 
- begin
 
-   with Image do
 
-   begin
 
-     if not StatusOK then
 
-       Exit;
 
-     with Directories[IMAGE_DIRECTORY_ENTRY_EXPORT] do
 
-     begin
 
-       ExportVABegin := VirtualAddress;
 
-       ExportVAEnd := VirtualAddress + TJclAddr(Size);
 
-     end;
 
-     FExportDir := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_EXPORT);
 
-     if FExportDir <> nil then
 
-     begin
 
-       FBase := FExportDir^.Base;
 
-       FFunctionCount := FExportDir^.NumberOfFunctions;
 
-       Functions := RvaToVa(FExportDir^.AddressOfFunctions);
 
-       NameOrdinals := RvaToVa(FExportDir^.AddressOfNameOrdinals);
 
-       Names := RvaToVa(FExportDir^.AddressOfNames);
 
-       NameCount := FExportDir^.NumberOfNames;
 
-       Count := FExportDir^.NumberOfFunctions;
 
-       for I := 0 to Count - 1 do
 
-       begin
 
-         Address := PDWORD(TJclAddr(Functions) + TJclAddr(I) * SizeOf(DWORD))^;
 
-         if (Address >= ExportVABegin) and (Address <= ExportVAEnd) then
 
-         begin
 
-           FAnyForwards := True;
 
-           UTF8Name := PAnsiChar(RvaToVa(Address));
 
-           if not TryUTF8ToString(UTF8Name, ForwardedName) then
 
-             ForwardedName := string(UTF8Name);
 
-         end
 
-         else
 
-           ForwardedName := '';
 
-         ExportItem := TJclPeExportFuncItem.Create(Self, '',
 
-           ForwardedName, Address, $FFFF, TJclAddr(I) + FBase, icNotChecked);
 
-         List{$IFNDEF RTL230_UP}^{$ENDIF !RTL230_UP}[I] := ExportItem;
 
-       end;
 
-       for I := 0 to NameCount - 1 do
 
-       begin
 
-           // named function
 
-         UTF8Name := PAnsiChar(RvaToVa(Names^));
 
-         if not TryUTF8ToString(UTF8Name, ExportName) then
 
-           ExportName := string(UTF8Name);
 
-         ExportItem := TJclPeExportFuncItem(List{$IFNDEF RTL230_UP}^{$ENDIF !RTL230_UP}[NameOrdinals^]);
 
-         ExportItem.FName := ExportName;
 
-         ExportItem.FHint := I;
 
-         Inc(NameOrdinals);
 
-         Inc(Names);
 
-       end;
 
-     end;
 
-   end;
 
- end;
 
- function TJclPeExportFuncList.GetForwardedLibsList: TStrings;
 
- var
 
-   I: Integer;
 
- begin
 
-   if FForwardedLibsList = nil then
 
-   begin
 
-     FForwardedLibsList := TStringList.Create;
 
-     FForwardedLibsList.Sorted := True;
 
-     FForwardedLibsList.Duplicates := dupIgnore;
 
-     if FAnyForwards then
 
-       for I := 0 to Count - 1 do
 
-         with Items[I] do
 
-           if IsForwarded then
 
-             FForwardedLibsList.AddObject(ForwardedLibName, Pointer(icNotChecked));
 
-   end;
 
-   Result := FForwardedLibsList;
 
- end;
 
- function TJclPeExportFuncList.GetItemFromAddress(Address: DWORD): TJclPeExportFuncItem;
 
- var
 
-   I: Integer;
 
- begin
 
-   Result := nil;
 
-   for I := 0 to Count - 1 do
 
-     if Items[I].Address = Address then
 
-     begin
 
-       Result := Items[I];
 
-       Break;
 
-     end;
 
- end;
 
- function TJclPeExportFuncList.GetItemFromName(const Name: string): TJclPeExportFuncItem;
 
- var
 
-   L, H, I, C: Integer;
 
-   B: Boolean;
 
- begin
 
-   Result := nil;
 
-   if CanPerformFastNameSearch then
 
-   begin
 
-     L := 0;
 
-     H := Count - 1;
 
-     B := False;
 
-     while L <= H do
 
-     begin
 
-       I := (L + H) shr 1;
 
-       C := CompareStr(Items[I].Name, Name);
 
-       if C < 0 then
 
-         L := I + 1
 
-       else
 
-       begin
 
-         H := I - 1;
 
-         if C = 0 then
 
-         begin
 
-           B := True;
 
-           L := I;
 
-         end;
 
-       end;
 
-     end;
 
-     if B then
 
-       Result := Items[L];
 
-   end
 
-   else
 
-     for I := 0 to Count - 1 do
 
-       if Items[I].Name = Name then
 
-       begin
 
-         Result := Items[I];
 
-         Break;
 
-       end;
 
- end;
 
- function TJclPeExportFuncList.GetItemFromOrdinal(Ordinal: DWORD): TJclPeExportFuncItem;
 
- var
 
-   I: Integer;
 
- begin
 
-   Result := nil;
 
-   for I := 0 to Count - 1 do
 
-     if Items[I].Ordinal = Ordinal then
 
-     begin
 
-       Result := Items[I];
 
-       Break;
 
-     end;
 
- end;
 
- function TJclPeExportFuncList.GetItems(Index: Integer): TJclPeExportFuncItem;
 
- begin
 
-   Result := TJclPeExportFuncItem(Get(Index));
 
- end;
 
- function TJclPeExportFuncList.GetName: string;
 
- var
 
-   UTF8ExportName: TUTF8String;
 
- begin
 
-   if (FExportDir = nil) or (FExportDir^.Name = 0) then
 
-     Result := ''
 
-   else
 
-   begin
 
-     UTF8ExportName := PAnsiChar(Image.RvaToVa(FExportDir^.Name));
 
-     if not TryUTF8ToString(UTF8ExportName, Result) then
 
-       Result := string(UTF8ExportName);
 
-   end;
 
- end;
 
- class function TJclPeExportFuncList.ItemName(Item: TJclPeExportFuncItem): string;
 
- begin
 
-   if Item = nil then
 
-     Result := ''
 
-   else
 
-     Result := Item.Name;
 
- end;
 
- function TJclPeExportFuncList.OrdinalValid(Ordinal: DWORD): Boolean;
 
- begin
 
-   Result := (FExportDir <> nil) and (Ordinal >= Base) and
 
-     (Ordinal < FunctionCount + Base);
 
- end;
 
- procedure TJclPeExportFuncList.PrepareForFastNameSearch;
 
- begin
 
-   if not CanPerformFastNameSearch then
 
-     SortList(esName, False);
 
- end;
 
- function TJclPeExportFuncList.SmartFindName(const CompareName: string;
 
-   Options: TJclSmartCompOptions): TJclPeExportFuncItem;
 
- var
 
-   I: Integer;
 
- begin
 
-   Result := nil;
 
-   for I := 0 to Count - 1 do
 
-   begin
 
-     if PeSmartFunctionNameSame(CompareName, Items[I].Name, Options) then
 
-     begin
 
-       Result := Items[I];
 
-       Break;
 
-     end;
 
-   end;
 
- end;
 
- procedure TJclPeExportFuncList.SortList(SortType: TJclPeExportSort; Descending: Boolean);
 
- const
 
-   SortFunctions: array [TJclPeExportSort, Boolean] of TListSortCompare =
 
-     ((ExportSortByName, ExportSortByNameDESC),
 
-      (ExportSortByOrdinal, ExportSortByOrdinalDESC),
 
-      (ExportSortByHint, ExportSortByHintDESC),
 
-      (ExportSortByAddress, ExportSortByAddressDESC),
 
-      (ExportSortByForwarded, ExportSortByForwardedDESC),
 
-      (ExportSortByAddrOrFwd, ExportSortByAddrOrFwdDESC),
 
-      (ExportSortBySection, ExportSortBySectionDESC)
 
-     );
 
- begin
 
-   if not FSorted or (SortType <> FLastSortType) or (Descending <> FLastSortDescending) then
 
-   begin
 
-     Sort(SortFunctions[SortType, Descending]);
 
-     FLastSortType := SortType;
 
-     FLastSortDescending := Descending;
 
-     FSorted := True;
 
-   end;
 
- end;
 
- //=== { TJclPeResourceRawStream } ============================================
 
- constructor TJclPeResourceRawStream.Create(AResourceItem: TJclPeResourceItem);
 
- begin
 
-   Assert(not AResourceItem.IsDirectory);
 
-   inherited Create;
 
-   SetPointer(AResourceItem.RawEntryData, AResourceItem.RawEntryDataSize);
 
- end;
 
- function TJclPeResourceRawStream.Write(const Buffer; Count: Integer): Longint;
 
- begin
 
-   raise EJclPeImageError.CreateRes(@RsPeReadOnlyStream);
 
- end;
 
- //=== { TJclPeResourceItem } =================================================
 
- constructor TJclPeResourceItem.Create(AImage: TJclPeImage;
 
-   AParentItem: TJclPeResourceItem; AEntry: PImageResourceDirectoryEntry);
 
- begin
 
-   inherited Create;
 
-   FImage := AImage;
 
-   FEntry := AEntry;
 
-   FParentItem := AParentItem;
 
-   if AParentItem = nil then
 
-     FLevel := 1
 
-   else
 
-     FLevel := AParentItem.Level + 1;
 
- end;
 
- destructor TJclPeResourceItem.Destroy;
 
- begin
 
-   FreeAndNil(FList);
 
-   inherited Destroy;
 
- end;
 
- function TJclPeResourceItem.CompareName(AName: PChar): Boolean;
 
- var
 
-   P: PChar;
 
- begin
 
-   if IsName then
 
-     P := PChar(Name)
 
-   else
 
-     P := PChar(FEntry^.Name and $FFFF); // Integer encoded in a PChar
 
-   Result := CompareResourceName(AName, P);
 
- end;
 
- function TJclPeResourceItem.GetDataEntry: PImageResourceDataEntry;
 
- begin
 
-   if GetIsDirectory then
 
-     Result := nil
 
-   else
 
-     Result := PImageResourceDataEntry(OffsetToRawData(FEntry^.OffsetToData));
 
- end;
 
- function TJclPeResourceItem.GetIsDirectory: Boolean;
 
- begin
 
-   Result := FEntry^.OffsetToData and IMAGE_RESOURCE_DATA_IS_DIRECTORY <> 0;
 
- end;
 
- function TJclPeResourceItem.GetIsName: Boolean;
 
- begin
 
-   Result := FEntry^.Name and IMAGE_RESOURCE_NAME_IS_STRING <> 0;
 
- end;
 
- function TJclPeResourceItem.GetLangID: LANGID;
 
- begin
 
-   if IsDirectory then
 
-   begin
 
-     GetList;
 
-     if FList.Count = 1 then
 
-       Result := StrToIntDef(FList[0].Name, 0)
 
-     else
 
-       Result := 0;
 
-   end
 
-   else
 
-     Result := StrToIntDef(Name, 0);
 
- end;
 
- function TJclPeResourceItem.GetList: TJclPeResourceList;
 
- begin
 
-   if not IsDirectory then
 
-   begin
 
-     if Image.NoExceptions then
 
-     begin
 
-       Result := nil;
 
-       Exit;
 
-     end
 
-     else
 
-       raise EJclPeImageError.CreateRes(@RsPeNotResDir);
 
-   end;
 
-   if FList = nil then
 
-     FList := FImage.ResourceListCreate(SubDirData, Self);
 
-   Result := FList;
 
- end;
 
- function TJclPeResourceItem.GetName: string;
 
- begin
 
-   if IsName then
 
-   begin
 
-     if FNameCache = '' then
 
-     begin
 
-       with PImageResourceDirStringU(OffsetToRawData(FEntry^.Name))^ do
 
-         FNameCache := WideCharLenToString(NameString, Length);
 
-       StrResetLength(FNameCache);
 
-     end;
 
-     Result := FNameCache;
 
-   end
 
-   else
 
-     Result := IntToStr(FEntry^.Name and $FFFF);
 
- end;
 
- function TJclPeResourceItem.GetParameterName: string;
 
- begin
 
-   if IsName then
 
-     Result := Name
 
-   else
 
-     Result := Format('#%d', [FEntry^.Name and $FFFF]);
 
- end;
 
- function TJclPeResourceItem.GetRawEntryData: Pointer;
 
- begin
 
-   if GetIsDirectory then
 
-     Result := nil
 
-   else
 
-     Result := FImage.RvaToVa(GetDataEntry^.OffsetToData);
 
- end;
 
- function TJclPeResourceItem.GetRawEntryDataSize: Integer;
 
- begin
 
-   if GetIsDirectory then
 
-     Result := -1
 
-   else
 
-     Result := PImageResourceDataEntry(OffsetToRawData(FEntry^.OffsetToData))^.Size;
 
- end;
 
- function TJclPeResourceItem.GetResourceType: TJclPeResourceKind;
 
- begin
 
-   with Level1Item do
 
-   begin
 
-     if FEntry^.Name < Cardinal(High(TJclPeResourceKind)) then
 
-       Result := TJclPeResourceKind(FEntry^.Name)
 
-     else
 
-       Result := rtUserDefined
 
-   end;
 
- end;
 
- function TJclPeResourceItem.GetResourceTypeStr: string;
 
- begin
 
-   with Level1Item do
 
-   begin
 
-     if FEntry^.Name < Cardinal(High(TJclPeResourceKind)) then
 
-       Result := Copy(GetEnumName(TypeInfo(TJclPeResourceKind), Ord(FEntry^.Name)), 3, 30)
 
-     else
 
-       Result := Name;
 
-   end;
 
- end;
 
- function TJclPeResourceItem.Level1Item: TJclPeResourceItem;
 
- begin
 
-   Result := Self;
 
-   while Result.FParentItem <> nil do
 
-     Result := Result.FParentItem;
 
- end;
 
- function TJclPeResourceItem.OffsetToRawData(Ofs: DWORD): TJclAddr;
 
- begin
 
-   Result := (Ofs and $7FFFFFFF) + Image.ResourceVA;
 
- end;
 
- function TJclPeResourceItem.SubDirData: PImageResourceDirectory;
 
- begin
 
-   Result := Pointer(OffsetToRawData(FEntry^.OffsetToData));
 
- end;
 
- //=== { TJclPeResourceList } =================================================
 
- constructor TJclPeResourceList.Create(AImage: TJclPeImage;
 
-   AParentItem: TJclPeResourceItem; ADirectory: PImageResourceDirectory);
 
- begin
 
-   inherited Create(AImage);
 
-   FDirectory := ADirectory;
 
-   FParentItem := AParentItem;
 
-   CreateList(AParentItem);
 
- end;
 
- procedure TJclPeResourceList.CreateList(AParentItem: TJclPeResourceItem);
 
- var
 
-   Entry: PImageResourceDirectoryEntry;
 
-   DirItem: TJclPeResourceItem;
 
-   I: Integer;
 
- begin
 
-   if FDirectory = nil then
 
-     Exit;
 
-   Entry := Pointer(TJclAddr(FDirectory) + SizeOf(TImageResourceDirectory));
 
-   for I := 1 to DWORD(FDirectory^.NumberOfNamedEntries) + DWORD(FDirectory^.NumberOfIdEntries) do
 
-   begin
 
-     DirItem := Image.ResourceItemCreate(Entry, AParentItem);
 
-     Add(DirItem);
 
-     Inc(Entry);
 
-   end;
 
- end;
 
- function TJclPeResourceList.FindName(const Name: string): TJclPeResourceItem;
 
- var
 
-   I: Integer;
 
- begin
 
-   Result := nil;
 
-   for I := 0 to Count - 1 do
 
-     if StrSame(Items[I].Name, Name) then
 
-     begin
 
-       Result := Items[I];
 
-       Break;
 
-     end;
 
- end;
 
- function TJclPeResourceList.GetItems(Index: Integer): TJclPeResourceItem;
 
- begin
 
-   Result := TJclPeResourceItem(Get(Index));
 
- end;
 
- //=== { TJclPeRootResourceList } =============================================
 
- destructor TJclPeRootResourceList.Destroy;
 
- begin
 
-   FreeAndNil(FManifestContent);
 
-   inherited Destroy;
 
- end;
 
- function TJclPeRootResourceList.FindResource(ResourceType: TJclPeResourceKind;
 
-   const ResourceName: string): TJclPeResourceItem;
 
- var
 
-   I: Integer;
 
-   TypeItem: TJclPeResourceItem;
 
- begin
 
-   Result := nil;
 
-   TypeItem := nil;
 
-   for I := 0 to Count - 1 do
 
-   begin
 
-     if Items[I].ResourceType = ResourceType then
 
-     begin
 
-       TypeItem := Items[I];
 
-       Break;
 
-     end;
 
-   end;
 
-   if TypeItem <> nil then
 
-     if ResourceName = '' then
 
-       Result := TypeItem
 
-     else
 
-       with TypeItem.List do
 
-         for I := 0 to Count - 1 do
 
-           if Items[I].Name = ResourceName then
 
-           begin
 
-             Result := Items[I];
 
-             Break;
 
-           end;
 
- end;
 
- function TJclPeRootResourceList.FindResource(const ResourceType: PChar;
 
-   const ResourceName: PChar): TJclPeResourceItem;
 
- var
 
-   I: Integer;
 
-   TypeItem: TJclPeResourceItem;
 
- begin
 
-   Result := nil;
 
-   TypeItem := nil;
 
-   for I := 0 to Count - 1 do
 
-     if Items[I].CompareName(ResourceType) then
 
-     begin
 
-       TypeItem := Items[I];
 
-       Break;
 
-     end;
 
-   if TypeItem <> nil then
 
-     if ResourceName = nil then
 
-       Result := TypeItem
 
-     else
 
-       with TypeItem.List do
 
-         for I := 0 to Count - 1 do
 
-           if Items[I].CompareName(ResourceName) then
 
-           begin
 
-             Result := Items[I];
 
-             Break;
 
-           end;
 
- end;
 
- function TJclPeRootResourceList.GetManifestContent: TStrings;
 
- var
 
-   ManifestFileName: string;
 
-   ResItem: TJclPeResourceItem;
 
-   ResStream: TJclPeResourceRawStream;
 
- begin
 
-   if FManifestContent = nil then
 
-   begin
 
-     FManifestContent := TStringList.Create;
 
-     ResItem := FindResource(RT_MANIFEST, CREATEPROCESS_MANIFEST_RESOURCE_ID);
 
-     if ResItem = nil then
 
-     begin
 
-       ManifestFileName := Image.FileName + MANIFESTExtension;
 
-       if FileExists(ManifestFileName) then
 
-         FManifestContent.LoadFromFile(ManifestFileName);
 
-     end
 
-     else
 
-     begin
 
-       ResStream := TJclPeResourceRawStream.Create(ResItem.List[0]);
 
-       try
 
-         FManifestContent.LoadFromStream(ResStream);
 
-       finally
 
-         ResStream.Free;
 
-       end;
 
-     end;
 
-   end;
 
-   Result := FManifestContent;
 
- end;
 
- function TJclPeRootResourceList.ListResourceNames(ResourceType: TJclPeResourceKind;
 
-   const Strings: TStrings): Boolean;
 
- var
 
-   ResTypeItem, TempItem: TJclPeResourceItem;
 
-   I: Integer;
 
- begin
 
-   ResTypeItem := FindResource(ResourceType, '');
 
-   Result := (ResTypeItem <> nil);
 
-   if Result then
 
-   begin
 
-     Strings.BeginUpdate;
 
-     try
 
-       with ResTypeItem.List do
 
-         for I := 0 to Count - 1 do
 
-         begin
 
-           TempItem := Items[I];
 
-           Strings.AddObject(TempItem.Name, Pointer(TempItem.IsName));
 
-         end;
 
-     finally
 
-       Strings.EndUpdate;
 
-     end;
 
-   end;
 
- end;
 
- //=== { TJclPeRelocEntry } ===================================================
 
- constructor TJclPeRelocEntry.Create(AChunk: PImageBaseRelocation; ACount: Integer);
 
- begin
 
-   inherited Create;
 
-   FChunk := AChunk;
 
-   FCount := ACount;
 
- end;
 
- function TJclPeRelocEntry.GetRelocations(Index: Integer): TJclPeRelocation;
 
- var
 
-   Temp: Word;
 
- begin
 
-   Temp := PWord(TJclAddr(FChunk) + SizeOf(TImageBaseRelocation) + DWORD(Index) * SizeOf(Word))^;
 
-   Result.Address := Temp and $0FFF;
 
-   Result.RelocType := (Temp and $F000) shr 12;
 
-   Result.VirtualAddress := TJclAddr(Result.Address) + VirtualAddress;
 
- end;
 
- function TJclPeRelocEntry.GetSize: DWORD;
 
- begin
 
-   Result := FChunk^.SizeOfBlock;
 
- end;
 
- function TJclPeRelocEntry.GetVirtualAddress: DWORD;
 
- begin
 
-   Result := FChunk^.VirtualAddress;
 
- end;
 
- //=== { TJclPeRelocList } ====================================================
 
- constructor TJclPeRelocList.Create(AImage: TJclPeImage);
 
- begin
 
-   inherited Create(AImage);
 
-   CreateList;
 
- end;
 
- procedure TJclPeRelocList.CreateList;
 
- var
 
-   Chunk: PImageBaseRelocation;
 
-   Item: TJclPeRelocEntry;
 
-   RelocCount: Integer;
 
- begin
 
-   with Image do
 
-   begin
 
-     if not StatusOK then
 
-       Exit;
 
-     Chunk := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_BASERELOC);
 
-     if Chunk = nil then
 
-       Exit;
 
-     FAllItemCount := 0;
 
-     while Chunk^.SizeOfBlock <> 0 do
 
-     begin
 
-       RelocCount := (Chunk^.SizeOfBlock - SizeOf(TImageBaseRelocation)) div SizeOf(Word);
 
-       Item := TJclPeRelocEntry.Create(Chunk, RelocCount);
 
-       Inc(FAllItemCount, RelocCount);
 
-       Add(Item);
 
-       Chunk := Pointer(TJclAddr(Chunk) + Chunk^.SizeOfBlock);
 
-     end;
 
-   end;
 
- end;
 
- function TJclPeRelocList.GetAllItems(Index: Integer): TJclPeRelocation;
 
- var
 
-   I, N, C: Integer;
 
- begin
 
-   N := Index;
 
-   for I := 0 to Count - 1 do
 
-   begin
 
-     C := Items[I].Count;
 
-     Dec(N, C);
 
-     if N < 0 then
 
-     begin
 
-       Result := Items[I][N + C];
 
-       Break;
 
-     end;
 
-   end;
 
- end;
 
- function TJclPeRelocList.GetItems(Index: Integer): TJclPeRelocEntry;
 
- begin
 
-   Result := TJclPeRelocEntry(Get(Index));
 
- end;
 
- //=== { TJclPeDebugList } ====================================================
 
- constructor TJclPeDebugList.Create(AImage: TJclPeImage);
 
- begin
 
-   inherited Create(AImage);
 
-   OwnsObjects := False;
 
-   CreateList;
 
- end;
 
- procedure TJclPeDebugList.CreateList;
 
- var
 
-   DebugImageDir: TImageDataDirectory;
 
-   DebugDir: PImageDebugDirectory;
 
-   Header: PImageSectionHeader;
 
-   FormatCount, I: Integer;
 
- begin
 
-   with Image do
 
-   begin
 
-     if not StatusOK then
 
-       Exit;
 
-     DebugImageDir := Directories[IMAGE_DIRECTORY_ENTRY_DEBUG];
 
-     if DebugImageDir.VirtualAddress = 0 then
 
-       Exit;
 
-     if GetSectionHeader(DebugSectionName, Header) and
 
-       (Header^.VirtualAddress = DebugImageDir.VirtualAddress) then
 
-     begin
 
-       FormatCount := DebugImageDir.Size;
 
-       DebugDir := RvaToVa(Header^.VirtualAddress);
 
-     end
 
-     else
 
-     begin
 
-       if not GetSectionHeader(ReadOnlySectionName, Header) then
 
-         Exit;
 
-       FormatCount := DebugImageDir.Size div SizeOf(TImageDebugDirectory);
 
-       DebugDir := Pointer(MappedAddress + DebugImageDir.VirtualAddress -
 
-         Header^.VirtualAddress + Header^.PointerToRawData);
 
-     end;
 
-     for I := 1 to FormatCount do
 
-     begin
 
-       Add(TObject(DebugDir));
 
-       Inc(DebugDir);
 
-     end;
 
-   end;
 
- end;
 
- function TJclPeDebugList.GetItems(Index: Integer): TImageDebugDirectory;
 
- begin
 
-   Result := PImageDebugDirectory(Get(Index))^;
 
- end;
 
- //=== { TJclPeCertificate } ==================================================
 
- constructor TJclPeCertificate.Create(AHeader: TWinCertificate; AData: Pointer);
 
- begin
 
-   inherited Create;
 
-   FHeader := AHeader;
 
-   FData := AData;
 
- end;
 
- //=== { TJclPeCertificateList } ==============================================
 
- constructor TJclPeCertificateList.Create(AImage: TJclPeImage);
 
- begin
 
-   inherited Create(AImage);
 
-   CreateList;
 
- end;
 
- procedure TJclPeCertificateList.CreateList;
 
- var
 
-   Directory: TImageDataDirectory;
 
-   CertPtr: PChar;
 
-   TotalSize: Integer;
 
-   Item: TJclPeCertificate;
 
- begin
 
-   Directory := Image.Directories[IMAGE_DIRECTORY_ENTRY_SECURITY];
 
-   if Directory.VirtualAddress = 0 then
 
-     Exit;
 
-   CertPtr := Image.RawToVa(Directory.VirtualAddress); // Security directory is a raw offset
 
-   TotalSize := Directory.Size;
 
-   while TotalSize >= SizeOf(TWinCertificate) do
 
-   begin
 
-     Item := TJclPeCertificate.Create(PWinCertificate(CertPtr)^, CertPtr + SizeOf(TWinCertificate));
 
-     Dec(TotalSize, Item.Header.dwLength);
 
-     Add(Item);
 
-   end;
 
- end;
 
- function TJclPeCertificateList.GetItems(Index: Integer): TJclPeCertificate;
 
- begin
 
-   Result := TJclPeCertificate(Get(Index));
 
- end;
 
- //=== { TJclPeCLRHeader } ====================================================
 
- constructor TJclPeCLRHeader.Create(AImage: TJclPeImage);
 
- begin
 
-   FImage := AImage;
 
-   ReadHeader;
 
- end;
 
- function TJclPeCLRHeader.GetHasMetadata: Boolean;
 
- const
 
-   METADATA_SIGNATURE = $424A5342; // Reference: Partition II Metadata.doc - 23.2.1 Metadata root
 
- begin
 
-   with Header.MetaData do
 
-     Result := (VirtualAddress <> 0) and (PDWORD(FImage.RvaToVa(VirtualAddress))^ = METADATA_SIGNATURE);
 
- end;
 
- { TODO -cDOC : "Flier Lu" <flier_lu att yahoo dott com dott cn> }
 
- function TJclPeCLRHeader.GetVersionString: string;
 
- begin
 
-   Result := FormatVersionString(Header.MajorRuntimeVersion, Header.MinorRuntimeVersion);
 
- end;
 
- procedure TJclPeCLRHeader.ReadHeader;
 
- var
 
-   HeaderPtr: PImageCor20Header;
 
- begin
 
-   HeaderPtr := Image.DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR);
 
-   if (HeaderPtr <> nil) and (HeaderPtr^.cb >= SizeOf(TImageCor20Header)) then
 
-     FHeader := HeaderPtr^;
 
- end;
 
- //=== { TJclPeImage } ========================================================
 
- constructor TJclPeImage.Create(ANoExceptions: Boolean);
 
- begin
 
-   FNoExceptions := ANoExceptions;
 
-   FReadOnlyAccess := True;
 
-   FImageSections := TStringList.Create;
 
-   FStringTable := TStringList.Create;
 
- end;
 
- destructor TJclPeImage.Destroy;
 
- begin
 
-   Clear;
 
-   FreeAndNil(FImageSections);
 
-   FStringTable.Free;
 
-   inherited Destroy;
 
- end;
 
- procedure TJclPeImage.AfterOpen;
 
- begin
 
- end;
 
- procedure TJclPeImage.AttachLoadedModule(const Handle: HMODULE);
 
-   procedure AttachLoadedModule32;
 
-   var
 
-     NtHeaders: PImageNtHeaders32;
 
-   begin
 
-     NtHeaders := PeMapImgNtHeaders32(Pointer(Handle));
 
-     if NtHeaders = nil then
 
-       FStatus := stNotPE
 
-     else
 
-     begin
 
-       FStatus := stOk;
 
-       FAttachedImage := True;
 
-       FFileName := GetModulePath(Handle);
 
-       // OF: possible loss of data
 
-       FLoadedImage.ModuleName := PAnsiChar(AnsiString(FFileName));
 
-       FLoadedImage.hFile := INVALID_HANDLE_VALUE;
 
-       FLoadedImage.MappedAddress := Pointer(Handle);
 
-       FLoadedImage.FileHeader := PImageNtHeaders(NtHeaders);
 
-       FLoadedImage.NumberOfSections := NtHeaders^.FileHeader.NumberOfSections;
 
-       FLoadedImage.Sections := PeMapImgSections32(NtHeaders);
 
-       FLoadedImage.LastRvaSection := FLoadedImage.Sections;
 
-       FLoadedImage.Characteristics := NtHeaders^.FileHeader.Characteristics;
 
-       FLoadedImage.fSystemImage := (FLoadedImage.Characteristics and IMAGE_FILE_SYSTEM <> 0);
 
-       FLoadedImage.fDOSImage := False;
 
-       FLoadedImage.SizeOfImage := NtHeaders^.OptionalHeader.SizeOfImage;
 
-       ReadImageSections;
 
-       ReadStringTable;
 
-       AfterOpen;
 
-     end;
 
-     RaiseStatusException;
 
-   end;
 
-   procedure AttachLoadedModule64;
 
-    var
 
-     NtHeaders: PImageNtHeaders64;
 
-   begin
 
-     NtHeaders := PeMapImgNtHeaders64(Pointer(Handle));
 
-     if NtHeaders = nil then
 
-       FStatus := stNotPE
 
-     else
 
-     begin
 
-       FStatus := stOk;
 
-       FAttachedImage := True;
 
-       FFileName := GetModulePath(Handle);
 
-       // OF: possible loss of data
 
-       FLoadedImage.ModuleName := PAnsiChar(AnsiString(FFileName));
 
-       FLoadedImage.hFile := INVALID_HANDLE_VALUE;
 
-       FLoadedImage.MappedAddress := Pointer(Handle);
 
-       FLoadedImage.FileHeader := PImageNtHeaders(NtHeaders);
 
-       FLoadedImage.NumberOfSections := NtHeaders^.FileHeader.NumberOfSections;
 
-       FLoadedImage.Sections := PeMapImgSections64(NtHeaders);
 
-       FLoadedImage.LastRvaSection := FLoadedImage.Sections;
 
-       FLoadedImage.Characteristics := NtHeaders^.FileHeader.Characteristics;
 
-       FLoadedImage.fSystemImage := (FLoadedImage.Characteristics and IMAGE_FILE_SYSTEM <> 0);
 
-       FLoadedImage.fDOSImage := False;
 
-       FLoadedImage.SizeOfImage := NtHeaders^.OptionalHeader.SizeOfImage;
 
-       ReadImageSections;
 
-       ReadStringTable;
 
-       AfterOpen;
 
-     end;
 
-     RaiseStatusException;
 
-   end;
 
- begin
 
-   Clear;
 
-   if Handle = 0 then
 
-     Exit;
 
-   FTarget := PeMapImgTarget(Pointer(Handle));
 
-   case Target of
 
-     taWin32:
 
-       AttachLoadedModule32;
 
-     taWin64:
 
-       AttachLoadedModule64;
 
-     taUnknown:
 
-       FStatus := stNotSupported;
 
-   end;
 
- end;
 
- function TJclPeImage.CalculateCheckSum: DWORD;
 
- var
 
-   C: DWORD;
 
- begin
 
-   if StatusOK then
 
-   begin
 
-     CheckNotAttached;
 
-     if CheckSumMappedFile(FLoadedImage.MappedAddress, FLoadedImage.SizeOfImage,
 
-       C, Result) = nil then
 
-         RaiseLastOSError;
 
-   end
 
-   else
 
-     Result := 0;
 
- end;
 
- procedure TJclPeImage.CheckNotAttached;
 
- begin
 
-   if FAttachedImage then
 
-     raise EJclPeImageError.CreateRes(@RsPeNotAvailableForAttached);
 
- end;
 
- procedure TJclPeImage.Clear;
 
- begin
 
-   FImageSections.Clear;
 
-   FStringTable.Clear;
 
-   FreeAndNil(FCertificateList);
 
-   FreeAndNil(FCLRHeader);
 
-   FreeAndNil(FDebugList);
 
-   FreeAndNil(FImportList);
 
-   FreeAndNil(FExportList);
 
-   FreeAndNil(FRelocationList);
 
-   FreeAndNil(FResourceList);
 
-   FreeAndNil(FVersionInfo);
 
-   if not FAttachedImage and StatusOK then
 
-     UnMapAndLoad(FLoadedImage);
 
-   ResetMemory(FLoadedImage, SizeOf(FLoadedImage));
 
-   FStatus := stNotLoaded;
 
-   FAttachedImage := False;
 
- end;
 
- class function TJclPeImage.DateTimeToStamp(const DateTime: TDateTime): DWORD;
 
- begin
 
-   Result := Round((DateTime - UnixTimeStart) * SecsPerDay);
 
- end;
 
- class function TJclPeImage.DebugTypeNames(DebugType: DWORD): string;
 
- begin
 
-   case DebugType of
 
-     IMAGE_DEBUG_TYPE_UNKNOWN:
 
-       Result := LoadResString(@RsPeDEBUG_UNKNOWN);
 
-     IMAGE_DEBUG_TYPE_COFF:
 
-       Result := LoadResString(@RsPeDEBUG_COFF);
 
-     IMAGE_DEBUG_TYPE_CODEVIEW:
 
-       Result := LoadResString(@RsPeDEBUG_CODEVIEW);
 
-     IMAGE_DEBUG_TYPE_FPO:
 
-       Result := LoadResString(@RsPeDEBUG_FPO);
 
-     IMAGE_DEBUG_TYPE_MISC:
 
-       Result := LoadResString(@RsPeDEBUG_MISC);
 
-     IMAGE_DEBUG_TYPE_EXCEPTION:
 
-       Result := LoadResString(@RsPeDEBUG_EXCEPTION);
 
-     IMAGE_DEBUG_TYPE_FIXUP:
 
-       Result := LoadResString(@RsPeDEBUG_FIXUP);
 
-     IMAGE_DEBUG_TYPE_OMAP_TO_SRC:
 
-       Result := LoadResString(@RsPeDEBUG_OMAP_TO_SRC);
 
-     IMAGE_DEBUG_TYPE_OMAP_FROM_SRC:
 
-       Result := LoadResString(@RsPeDEBUG_OMAP_FROM_SRC);
 
-   else
 
-     Result := LoadResString(@RsPeDEBUG_UNKNOWN);
 
-   end;
 
- end;
 
- function TJclPeImage.DirectoryEntryToData(Directory: Word): Pointer;
 
- var
 
-   Size: DWORD;
 
- begin
 
-   Size := 0;
 
-   Result := ImageDirectoryEntryToData(FLoadedImage.MappedAddress, FAttachedImage, Directory, Size);
 
- end;
 
- class function TJclPeImage.DirectoryNames(Directory: Word): string;
 
- begin
 
-   case Directory of
 
-     IMAGE_DIRECTORY_ENTRY_EXPORT:
 
-       Result := LoadResString(@RsPeImg_00);
 
-     IMAGE_DIRECTORY_ENTRY_IMPORT:
 
-       Result := LoadResString(@RsPeImg_01);
 
-     IMAGE_DIRECTORY_ENTRY_RESOURCE:
 
-       Result := LoadResString(@RsPeImg_02);
 
-     IMAGE_DIRECTORY_ENTRY_EXCEPTION:
 
-       Result := LoadResString(@RsPeImg_03);
 
-     IMAGE_DIRECTORY_ENTRY_SECURITY:
 
-       Result := LoadResString(@RsPeImg_04);
 
-     IMAGE_DIRECTORY_ENTRY_BASERELOC:
 
-       Result := LoadResString(@RsPeImg_05);
 
-     IMAGE_DIRECTORY_ENTRY_DEBUG:
 
-       Result := LoadResString(@RsPeImg_06);
 
-     IMAGE_DIRECTORY_ENTRY_COPYRIGHT:
 
-       Result := LoadResString(@RsPeImg_07);
 
-     IMAGE_DIRECTORY_ENTRY_GLOBALPTR:
 
-       Result := LoadResString(@RsPeImg_08);
 
-     IMAGE_DIRECTORY_ENTRY_TLS:
 
-       Result := LoadResString(@RsPeImg_09);
 
-     IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:
 
-       Result := LoadResString(@RsPeImg_10);
 
-     IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:
 
-       Result := LoadResString(@RsPeImg_11);
 
-     IMAGE_DIRECTORY_ENTRY_IAT:
 
-       Result := LoadResString(@RsPeImg_12);
 
-     IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
 
-       Result := LoadResString(@RsPeImg_13);
 
-     IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:
 
-       Result := LoadResString(@RsPeImg_14);
 
-   else
 
-     Result := Format(LoadResString(@RsPeImg_Reserved), [Directory]);
 
-   end;
 
- end;
 
- class function TJclPeImage.ExpandBySearchPath(const ModuleName, BasePath: string): TFileName;
 
- var
 
-   FullName: array [0..MAX_PATH] of Char;
 
-   FilePart: PChar;
 
- begin
 
-   Result := PathAddSeparator(ExtractFilePath(BasePath)) + ModuleName;
 
-   if FileExists(Result) then
 
-     Exit;
 
-   FilePart := nil;
 
-   if SearchPath(nil, PChar(ModuleName), nil, Length(FullName), FullName, FilePart) = 0 then
 
-     Result := ModuleName
 
-   else
 
-     Result := FullName;
 
- end;
 
- function TJclPeImage.ExpandModuleName(const ModuleName: string): TFileName;
 
- begin
 
-   Result := ExpandBySearchPath(ModuleName, ExtractFilePath(FFileName));
 
- end;
 
- function TJclPeImage.GetCertificateList: TJclPeCertificateList;
 
- begin
 
-   if FCertificateList = nil then
 
-     FCertificateList := TJclPeCertificateList.Create(Self);
 
-   Result := FCertificateList;
 
- end;
 
- function TJclPeImage.GetCLRHeader: TJclPeCLRHeader;
 
- begin
 
-   if FCLRHeader = nil then
 
-     FCLRHeader := TJclPeCLRHeader.Create(Self);
 
-   Result := FCLRHeader;
 
- end;
 
- function TJclPeImage.GetDebugList: TJclPeDebugList;
 
- begin
 
-   if FDebugList = nil then
 
-     FDebugList := TJclPeDebugList.Create(Self);
 
-   Result := FDebugList;
 
- end;
 
- function TJclPeImage.GetDescription: string;
 
- var
 
-   UTF8DescriptionName: TUTF8String;
 
- begin
 
-   if DirectoryExists[IMAGE_DIRECTORY_ENTRY_COPYRIGHT] then
 
-   begin
 
-     UTF8DescriptionName := PAnsiChar(DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_COPYRIGHT));
 
-     if not TryUTF8ToString(UTF8DescriptionName, Result) then
 
-       Result := string(UTF8DescriptionName);
 
-   end
 
-   else
 
-     Result := '';
 
- end;
 
- function TJclPeImage.GetDirectories(Directory: Word): TImageDataDirectory;
 
- begin
 
-   if StatusOK then
 
-   begin
 
-     case Target of
 
-       taWin32:
 
-         Result := PImageNtHeaders32(FLoadedImage.FileHeader)^.OptionalHeader.DataDirectory[Directory];
 
-       taWin64:
 
-         Result := PImageNtHeaders64(FLoadedImage.FileHeader)^.OptionalHeader.DataDirectory[Directory];
 
-     else
 
-       Result.VirtualAddress := 0;
 
-       Result.Size := 0;
 
-     end
 
-   end
 
-   else
 
-   begin
 
-     Result.VirtualAddress := 0;
 
-     Result.Size := 0;
 
-   end;
 
- end;
 
- function TJclPeImage.GetDirectoryExists(Directory: Word): Boolean;
 
- begin
 
-   Result := (Directories[Directory].VirtualAddress <> 0);
 
- end;
 
- function TJclPeImage.GetExportList: TJclPeExportFuncList;
 
- begin
 
-   if FExportList = nil then
 
-     FExportList := TJclPeExportFuncList.Create(Self);
 
-   Result := FExportList;
 
- end;
 
- {$IFNDEF WINSCP}
 
- function TJclPeImage.GetFileProperties: TJclPeFileProperties;
 
- var
 
-   FileAttributesEx: WIN32_FILE_ATTRIBUTE_DATA;
 
-   Size: TJclULargeInteger;
 
- begin
 
-   ResetMemory(Result, SizeOf(Result));
 
-   if GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @FileAttributesEx) then
 
-   begin
 
-     Size.LowPart := FileAttributesEx.nFileSizeLow;
 
-     Size.HighPart := FileAttributesEx.nFileSizeHigh;
 
-     Result.Size := Size.QuadPart;
 
-     Result.CreationTime := FileTimeToLocalDateTime(FileAttributesEx.ftCreationTime);
 
-     Result.LastAccessTime := FileTimeToLocalDateTime(FileAttributesEx.ftLastAccessTime);
 
-     Result.LastWriteTime := FileTimeToLocalDateTime(FileAttributesEx.ftLastWriteTime);
 
-     Result.Attributes := FileAttributesEx.dwFileAttributes;
 
-   end;
 
- end;
 
- {$ENDIF ~WINSCP}
 
- function TJclPeImage.GetHeaderValues(Index: TJclPeHeader): string;
 
-   function GetMachineString(Value: DWORD): string;
 
-   begin
 
-     case Value of
 
-       IMAGE_FILE_MACHINE_UNKNOWN:
 
-         Result := LoadResString(@RsPeMACHINE_UNKNOWN);
 
-       IMAGE_FILE_MACHINE_I386:
 
-         Result := LoadResString(@RsPeMACHINE_I386);
 
-       IMAGE_FILE_MACHINE_R3000:
 
-         Result := LoadResString(@RsPeMACHINE_R3000);
 
-       IMAGE_FILE_MACHINE_R4000:
 
-         Result := LoadResString(@RsPeMACHINE_R4000);
 
-       IMAGE_FILE_MACHINE_R10000:
 
-         Result := LoadResString(@RsPeMACHINE_R10000);
 
-       IMAGE_FILE_MACHINE_WCEMIPSV2:
 
-         Result := LoadResString(@RsPeMACHINE_WCEMIPSV2);
 
-       IMAGE_FILE_MACHINE_ALPHA:
 
-         Result := LoadResString(@RsPeMACHINE_ALPHA);
 
-       IMAGE_FILE_MACHINE_SH3:
 
-         Result := LoadResString(@RsPeMACHINE_SH3);        // SH3 little-endian
 
-       IMAGE_FILE_MACHINE_SH3DSP:
 
-         Result := LoadResString(@RsPeMACHINE_SH3DSP);
 
-       IMAGE_FILE_MACHINE_SH3E:
 
-         Result := LoadResString(@RsPeMACHINE_SH3E);       // SH3E little-endian
 
-       IMAGE_FILE_MACHINE_SH4:
 
-         Result := LoadResString(@RsPeMACHINE_SH4);        // SH4 little-endian
 
-       IMAGE_FILE_MACHINE_SH5:
 
-         Result := LoadResString(@RsPeMACHINE_SH5);        // SH5
 
-       IMAGE_FILE_MACHINE_ARM:
 
-         Result := LoadResString(@RsPeMACHINE_ARM);        // ARM Little-Endian
 
-       IMAGE_FILE_MACHINE_THUMB:
 
-         Result := LoadResString(@RsPeMACHINE_THUMB);
 
-       IMAGE_FILE_MACHINE_AM33:
 
-         Result := LoadResString(@RsPeMACHINE_AM33);
 
-       IMAGE_FILE_MACHINE_POWERPC:
 
-         Result := LoadResString(@RsPeMACHINE_POWERPC);
 
-       IMAGE_FILE_MACHINE_POWERPCFP:
 
-         Result := LoadResString(@RsPeMACHINE_POWERPCFP);
 
-       IMAGE_FILE_MACHINE_IA64:
 
-         Result := LoadResString(@RsPeMACHINE_IA64);       // Intel 64
 
-       IMAGE_FILE_MACHINE_MIPS16:
 
-         Result := LoadResString(@RsPeMACHINE_MIPS16);     // MIPS
 
-       IMAGE_FILE_MACHINE_ALPHA64:
 
-         Result := LoadResString(@RsPeMACHINE_AMPHA64);    // ALPHA64
 
-       //IMAGE_FILE_MACHINE_AXP64
 
-       IMAGE_FILE_MACHINE_MIPSFPU:
 
-         Result := LoadResString(@RsPeMACHINE_MIPSFPU);    // MIPS
 
-       IMAGE_FILE_MACHINE_MIPSFPU16:
 
-         Result := LoadResString(@RsPeMACHINE_MIPSFPU16);  // MIPS
 
-       IMAGE_FILE_MACHINE_TRICORE:
 
-         Result := LoadResString(@RsPeMACHINE_TRICORE);    // Infineon
 
-       IMAGE_FILE_MACHINE_CEF:
 
-         Result := LoadResString(@RsPeMACHINE_CEF);
 
-       IMAGE_FILE_MACHINE_EBC:
 
-         Result := LoadResString(@RsPeMACHINE_EBC);        // EFI Byte Code
 
-       IMAGE_FILE_MACHINE_AMD64:
 
-         Result := LoadResString(@RsPeMACHINE_AMD64);      // AMD64 (K8)
 
-       IMAGE_FILE_MACHINE_M32R:
 
-         Result := LoadResString(@RsPeMACHINE_M32R);       // M32R little-endian
 
-       IMAGE_FILE_MACHINE_CEE:
 
-         Result := LoadResString(@RsPeMACHINE_CEE);
 
-     else
 
-       Result := Format('[%.8x]', [Value]);
 
-     end;
 
-   end;
 
-   function GetSubsystemString(Value: DWORD): string;
 
-   begin
 
-     case Value of
 
-       IMAGE_SUBSYSTEM_UNKNOWN:
 
-         Result := LoadResString(@RsPeSUBSYSTEM_UNKNOWN);
 
-       IMAGE_SUBSYSTEM_NATIVE:
 
-         Result := LoadResString(@RsPeSUBSYSTEM_NATIVE);
 
-       IMAGE_SUBSYSTEM_WINDOWS_GUI:
 
-         Result := LoadResString(@RsPeSUBSYSTEM_WINDOWS_GUI);
 
-       IMAGE_SUBSYSTEM_WINDOWS_CUI:
 
-         Result := LoadResString(@RsPeSUBSYSTEM_WINDOWS_CUI);
 
-       IMAGE_SUBSYSTEM_OS2_CUI:
 
-         Result := LoadResString(@RsPeSUBSYSTEM_OS2_CUI);
 
-       IMAGE_SUBSYSTEM_POSIX_CUI:
 
-         Result := LoadResString(@RsPeSUBSYSTEM_POSIX_CUI);
 
-       IMAGE_SUBSYSTEM_RESERVED8:
 
-         Result := LoadResString(@RsPeSUBSYSTEM_RESERVED8);
 
-     else
 
-       Result := Format('[%.8x]', [Value]);
 
-     end;
 
-   end;
 
-   function GetHeaderValues32(Index: TJclPeHeader): string;
 
-   var
 
-     OptionalHeader: TImageOptionalHeader32;
 
-   begin
 
-     OptionalHeader := OptionalHeader32;
 
-     case Index of
 
-       JclPeHeader_Magic:
 
-         Result := IntToHex(OptionalHeader.Magic, 4);
 
-       JclPeHeader_LinkerVersion:
 
-         Result := FormatVersionString(OptionalHeader.MajorLinkerVersion, OptionalHeader.MinorLinkerVersion);
 
-       JclPeHeader_SizeOfCode:
 
-         Result := IntToHex(OptionalHeader.SizeOfCode, 8);
 
-       JclPeHeader_SizeOfInitializedData:
 
-         Result := IntToHex(OptionalHeader.SizeOfInitializedData, 8);
 
-       JclPeHeader_SizeOfUninitializedData:
 
-         Result := IntToHex(OptionalHeader.SizeOfUninitializedData, 8);
 
-       JclPeHeader_AddressOfEntryPoint:
 
-         Result := IntToHex(OptionalHeader.AddressOfEntryPoint, 8);
 
-       JclPeHeader_BaseOfCode:
 
-         Result := IntToHex(OptionalHeader.BaseOfCode, 8);
 
-       JclPeHeader_BaseOfData:
 
-         {$IFDEF DELPHI64_TEMPORARY}
 
-         System.Error(rePlatformNotImplemented);
 
-         {$ELSE ~DELPHI64_TEMPORARY}
 
-         Result := IntToHex(OptionalHeader.BaseOfData, 8);
 
-         {$ENDIF ~DELPHI64_TEMPORARY}
 
-       JclPeHeader_ImageBase:
 
-         Result := IntToHex(OptionalHeader.ImageBase, 8);
 
-       JclPeHeader_SectionAlignment:
 
-         Result := IntToHex(OptionalHeader.SectionAlignment, 8);
 
-       JclPeHeader_FileAlignment:
 
-         Result := IntToHex(OptionalHeader.FileAlignment, 8);
 
-       JclPeHeader_OperatingSystemVersion:
 
-         Result := FormatVersionString(OptionalHeader.MajorOperatingSystemVersion, OptionalHeader.MinorOperatingSystemVersion);
 
-       JclPeHeader_ImageVersion:
 
-         Result := FormatVersionString(OptionalHeader.MajorImageVersion, OptionalHeader.MinorImageVersion);
 
-       JclPeHeader_SubsystemVersion:
 
-         Result := FormatVersionString(OptionalHeader.MajorSubsystemVersion, OptionalHeader.MinorSubsystemVersion);
 
-       JclPeHeader_Win32VersionValue:
 
-         Result := IntToHex(OptionalHeader.Win32VersionValue, 8);
 
-       JclPeHeader_SizeOfImage:
 
-         Result := IntToHex(OptionalHeader.SizeOfImage, 8);
 
-       JclPeHeader_SizeOfHeaders:
 
-         Result := IntToHex(OptionalHeader.SizeOfHeaders, 8);
 
-       JclPeHeader_CheckSum:
 
-         Result := IntToHex(OptionalHeader.CheckSum, 8);
 
-       JclPeHeader_Subsystem:
 
-         Result := GetSubsystemString(OptionalHeader.Subsystem);
 
-       JclPeHeader_DllCharacteristics:
 
-         Result := IntToHex(OptionalHeader.DllCharacteristics, 4);
 
-       JclPeHeader_SizeOfStackReserve:
 
-         Result := IntToHex(OptionalHeader.SizeOfStackReserve, 8);
 
-       JclPeHeader_SizeOfStackCommit:
 
-         Result := IntToHex(OptionalHeader.SizeOfStackCommit, 8);
 
-       JclPeHeader_SizeOfHeapReserve:
 
-         Result := IntToHex(OptionalHeader.SizeOfHeapReserve, 8);
 
-       JclPeHeader_SizeOfHeapCommit:
 
-         Result := IntToHex(OptionalHeader.SizeOfHeapCommit, 8);
 
-       JclPeHeader_LoaderFlags:
 
-         Result := IntToHex(OptionalHeader.LoaderFlags, 8);
 
-       JclPeHeader_NumberOfRvaAndSizes:
 
-         Result := IntToHex(OptionalHeader.NumberOfRvaAndSizes, 8);
 
-     end;
 
-   end;
 
-   function GetHeaderValues64(Index: TJclPeHeader): string;
 
-   var
 
-     OptionalHeader: TImageOptionalHeader64;
 
-   begin
 
-     OptionalHeader := OptionalHeader64;
 
-     case Index of
 
-       JclPeHeader_Magic:
 
-         Result := IntToHex(OptionalHeader.Magic, 4);
 
-       JclPeHeader_LinkerVersion:
 
-         Result := FormatVersionString(OptionalHeader.MajorLinkerVersion, OptionalHeader.MinorLinkerVersion);
 
-       JclPeHeader_SizeOfCode:
 
-         Result := IntToHex(OptionalHeader.SizeOfCode, 8);
 
-       JclPeHeader_SizeOfInitializedData:
 
-         Result := IntToHex(OptionalHeader.SizeOfInitializedData, 8);
 
-       JclPeHeader_SizeOfUninitializedData:
 
-         Result := IntToHex(OptionalHeader.SizeOfUninitializedData, 8);
 
-       JclPeHeader_AddressOfEntryPoint:
 
-         Result := IntToHex(OptionalHeader.AddressOfEntryPoint, 8);
 
-       JclPeHeader_BaseOfCode:
 
-         Result := IntToHex(OptionalHeader.BaseOfCode, 8);
 
-       JclPeHeader_BaseOfData:
 
-         Result := ''; // IntToHex(OptionalHeader.BaseOfData, 8);
 
-       JclPeHeader_ImageBase:
 
-         Result := IntToHex(OptionalHeader.ImageBase, 16);
 
-       JclPeHeader_SectionAlignment:
 
-         Result := IntToHex(OptionalHeader.SectionAlignment, 8);
 
-       JclPeHeader_FileAlignment:
 
-         Result := IntToHex(OptionalHeader.FileAlignment, 8);
 
-       JclPeHeader_OperatingSystemVersion:
 
-         Result := FormatVersionString(OptionalHeader.MajorOperatingSystemVersion, OptionalHeader.MinorOperatingSystemVersion);
 
-       JclPeHeader_ImageVersion:
 
-         Result := FormatVersionString(OptionalHeader.MajorImageVersion, OptionalHeader.MinorImageVersion);
 
-       JclPeHeader_SubsystemVersion:
 
-         Result := FormatVersionString(OptionalHeader.MajorSubsystemVersion, OptionalHeader.MinorSubsystemVersion);
 
-       JclPeHeader_Win32VersionValue:
 
-         Result := IntToHex(OptionalHeader.Win32VersionValue, 8);
 
-       JclPeHeader_SizeOfImage:
 
-         Result := IntToHex(OptionalHeader.SizeOfImage, 8);
 
-       JclPeHeader_SizeOfHeaders:
 
-         Result := IntToHex(OptionalHeader.SizeOfHeaders, 8);
 
-       JclPeHeader_CheckSum:
 
-         Result := IntToHex(OptionalHeader.CheckSum, 8);
 
-       JclPeHeader_Subsystem:
 
-         Result := GetSubsystemString(OptionalHeader.Subsystem);
 
-       JclPeHeader_DllCharacteristics:
 
-         Result := IntToHex(OptionalHeader.DllCharacteristics, 4);
 
-       JclPeHeader_SizeOfStackReserve:
 
-         Result := IntToHex(OptionalHeader.SizeOfStackReserve, 16);
 
-       JclPeHeader_SizeOfStackCommit:
 
-         Result := IntToHex(OptionalHeader.SizeOfStackCommit, 16);
 
-       JclPeHeader_SizeOfHeapReserve:
 
-         Result := IntToHex(OptionalHeader.SizeOfHeapReserve, 16);
 
-       JclPeHeader_SizeOfHeapCommit:
 
-         Result := IntToHex(OptionalHeader.SizeOfHeapCommit, 16);
 
-       JclPeHeader_LoaderFlags:
 
-         Result := IntToHex(OptionalHeader.LoaderFlags, 8);
 
-       JclPeHeader_NumberOfRvaAndSizes:
 
-         Result := IntToHex(OptionalHeader.NumberOfRvaAndSizes, 8);
 
-     end;
 
-   end;
 
- begin
 
-   if StatusOK then
 
-     with FLoadedImage.FileHeader^ do
 
-       case Index of
 
-         JclPeHeader_Signature:
 
-           Result := IntToHex(Signature, 8);
 
-         JclPeHeader_Machine:
 
-           Result := GetMachineString(FileHeader.Machine);
 
-         JclPeHeader_NumberOfSections:
 
-           Result := IntToHex(FileHeader.NumberOfSections, 4);
 
-         JclPeHeader_TimeDateStamp:
 
-           Result := IntToHex(FileHeader.TimeDateStamp, 8);
 
-         JclPeHeader_PointerToSymbolTable:
 
-           Result := IntToHex(FileHeader.PointerToSymbolTable, 8);
 
-         JclPeHeader_NumberOfSymbols:
 
-           Result := IntToHex(FileHeader.NumberOfSymbols, 8);
 
-         JclPeHeader_SizeOfOptionalHeader:
 
-           Result := IntToHex(FileHeader.SizeOfOptionalHeader, 4);
 
-         JclPeHeader_Characteristics:
 
-           Result := IntToHex(FileHeader.Characteristics, 4);
 
-         JclPeHeader_Magic..JclPeHeader_NumberOfRvaAndSizes:
 
-           case Target of
 
-             taWin32:
 
-               Result := GetHeaderValues32(Index);
 
-             taWin64:
 
-               Result := GetHeaderValues64(Index);
 
-             //taUnknown:
 
-           else
 
-             Result := '';
 
-           end;
 
-       else
 
-         Result := '';
 
-       end
 
-   else
 
-     Result := '';
 
- end;
 
- function TJclPeImage.GetImageSectionCount: Integer;
 
- begin
 
-   Result := FImageSections.Count;
 
- end;
 
- function TJclPeImage.GetImageSectionFullNames(Index: Integer): string;
 
- var
 
-   Offset: Integer;
 
- begin
 
-   Result := ImageSectionNames[Index];
 
-   if (Length(Result) > 0) and (Result[1] = '/') and TryStrToInt(Copy(Result, 2, MaxInt), Offset) then
 
-     Result := GetNameInStringTable(Offset);
 
- end;
 
- function TJclPeImage.GetImageSectionHeaders(Index: Integer): TImageSectionHeader;
 
- begin
 
-   Result := PImageSectionHeader(FImageSections.Objects[Index])^;
 
- end;
 
- function TJclPeImage.GetImageSectionNameFromRva(const Rva: DWORD): string;
 
- begin
 
-   Result := GetSectionName(RvaToSection(Rva));
 
- end;
 
- function TJclPeImage.GetImageSectionNames(Index: Integer): string;
 
- begin
 
-   Result := FImageSections[Index];
 
- end;
 
- function TJclPeImage.GetImportList: TJclPeImportList;
 
- begin
 
-   if FImportList = nil then
 
-     FImportList := TJclPeImportList.Create(Self);
 
-   Result := FImportList;
 
- end;
 
- function TJclPeImage.GetLoadConfigValues(Index: TJclLoadConfig): string;
 
-   function GetLoadConfigValues32(Index: TJclLoadConfig): string;
 
-   var
 
-     LoadConfig: PIMAGE_LOAD_CONFIG_DIRECTORY32;
 
-   begin
 
-     LoadConfig := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG);
 
-     if LoadConfig <> nil then
 
-       with LoadConfig^ do
 
-         case Index of
 
-           JclLoadConfig_Characteristics:
 
-             Result := IntToHex(Size, 8);
 
-           JclLoadConfig_TimeDateStamp:
 
-             Result := IntToHex(TimeDateStamp, 8);
 
-           JclLoadConfig_Version:
 
-             Result := FormatVersionString(MajorVersion, MinorVersion);
 
-           JclLoadConfig_GlobalFlagsClear:
 
-             Result := IntToHex(GlobalFlagsClear, 8);
 
-           JclLoadConfig_GlobalFlagsSet:
 
-             Result := IntToHex(GlobalFlagsSet, 8);
 
-           JclLoadConfig_CriticalSectionDefaultTimeout:
 
-             Result := IntToHex(CriticalSectionDefaultTimeout, 8);
 
-           JclLoadConfig_DeCommitFreeBlockThreshold:
 
-             Result := IntToHex(DeCommitFreeBlockThreshold, 8);
 
-           JclLoadConfig_DeCommitTotalFreeThreshold:
 
-             Result := IntToHex(DeCommitTotalFreeThreshold, 8);
 
-           JclLoadConfig_LockPrefixTable:
 
-             Result := IntToHex(LockPrefixTable, 8);
 
-           JclLoadConfig_MaximumAllocationSize:
 
-             Result := IntToHex(MaximumAllocationSize, 8);
 
-           JclLoadConfig_VirtualMemoryThreshold:
 
-             Result := IntToHex(VirtualMemoryThreshold, 8);
 
-           JclLoadConfig_ProcessHeapFlags:
 
-             Result := IntToHex(ProcessHeapFlags, 8);
 
-           JclLoadConfig_ProcessAffinityMask:
 
-             Result := IntToHex(ProcessAffinityMask, 8);
 
-           JclLoadConfig_CSDVersion:
 
-             Result := IntToHex(CSDVersion, 4);
 
-           JclLoadConfig_Reserved1:
 
-             Result := IntToHex(Reserved1, 4);
 
-           JclLoadConfig_EditList:
 
-             Result := IntToHex(EditList, 8);
 
-           JclLoadConfig_Reserved:
 
-             Result := LoadResString(@RsPeReserved);
 
-         end;
 
-   end;
 
-   function GetLoadConfigValues64(Index: TJclLoadConfig): string;
 
-   var
 
-     LoadConfig: PIMAGE_LOAD_CONFIG_DIRECTORY64;
 
-   begin
 
-     LoadConfig := DirectoryEntryToData(IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG);
 
-     if LoadConfig <> nil then
 
-       with LoadConfig^ do
 
-         case Index of
 
-           JclLoadConfig_Characteristics:
 
-             Result := IntToHex(Size, 8);
 
-           JclLoadConfig_TimeDateStamp:
 
-             Result := IntToHex(TimeDateStamp, 8);
 
-           JclLoadConfig_Version:
 
-             Result := FormatVersionString(MajorVersion, MinorVersion);
 
-           JclLoadConfig_GlobalFlagsClear:
 
-             Result := IntToHex(GlobalFlagsClear, 8);
 
-           JclLoadConfig_GlobalFlagsSet:
 
-             Result := IntToHex(GlobalFlagsSet, 8);
 
-           JclLoadConfig_CriticalSectionDefaultTimeout:
 
-             Result := IntToHex(CriticalSectionDefaultTimeout, 8);
 
-           JclLoadConfig_DeCommitFreeBlockThreshold:
 
-             Result := IntToHex(DeCommitFreeBlockThreshold, 16);
 
-           JclLoadConfig_DeCommitTotalFreeThreshold:
 
-             Result := IntToHex(DeCommitTotalFreeThreshold, 16);
 
-           JclLoadConfig_LockPrefixTable:
 
-             Result := IntToHex(LockPrefixTable, 16);
 
-           JclLoadConfig_MaximumAllocationSize:
 
-             Result := IntToHex(MaximumAllocationSize, 16);
 
-           JclLoadConfig_VirtualMemoryThreshold:
 
-             Result := IntToHex(VirtualMemoryThreshold, 16);
 
-           JclLoadConfig_ProcessHeapFlags:
 
-             Result := IntToHex(ProcessHeapFlags, 8);
 
-           JclLoadConfig_ProcessAffinityMask:
 
-             Result := IntToHex(ProcessAffinityMask, 16);
 
-           JclLoadConfig_CSDVersion:
 
-             Result := IntToHex(CSDVersion, 4);
 
-           JclLoadConfig_Reserved1:
 
-             Result := IntToHex(Reserved1, 4);
 
-           JclLoadConfig_EditList:
 
-             Result := IntToHex(EditList, 16);
 
-           JclLoadConfig_Reserved:
 
-             Result := LoadResString(@RsPeReserved);
 
-         end;
 
-   end;
 
- begin
 
-   Result := '';
 
-   case Target of
 
-     taWin32:
 
-       Result := GetLoadConfigValues32(Index);
 
-     taWin64:
 
-       Result := GetLoadConfigValues64(Index);
 
-   end;
 
- end;
 
- function TJclPeImage.GetMappedAddress: TJclAddr;
 
- begin
 
-   if StatusOK then
 
-     Result := TJclAddr(LoadedImage.MappedAddress)
 
-   else
 
-     Result := 0;
 
- end;
 
- function TJclPeImage.GetNameInStringTable(Offset: ULONG): string;
 
- var
 
-   Index: Integer;
 
- begin
 
-   Dec(Offset, SizeOf(ULONG));
 
-   Index := 0;
 
-   while (Offset > 0) and (Index < FStringTable.Count) do
 
-   begin
 
-     Dec(Offset, Length(FStringTable[Index]) + 1);
 
-     if Offset > 0 then
 
-       Inc(Index);
 
-   end;
 
-   if Offset = 0 then
 
-     Result := FStringTable[Index]
 
-   else
 
-     Result := '';
 
- end;
 
- function TJclPeImage.GetOptionalHeader32: TImageOptionalHeader32;
 
- begin
 
-   if Target = taWin32 then
 
-     Result := PImageNtHeaders32(FLoadedImage.FileHeader)^.OptionalHeader
 
-   else
 
-     ZeroMemory(@Result, SizeOf(Result));
 
- end;
 
- function TJclPeImage.GetOptionalHeader64: TImageOptionalHeader64;
 
- begin
 
-   if Target = taWin64 then
 
-     Result := PImageNtHeaders64(FLoadedImage.FileHeader)^.OptionalHeader
 
-   else
 
-     ZeroMemory(@Result, SizeOf(Result));
 
- end;
 
- function TJclPeImage.GetRelocationList: TJclPeRelocList;
 
- begin
 
-   if FRelocationList = nil then
 
-     FRelocationList := TJclPeRelocList.Create(Self);
 
-   Result := FRelocationList;
 
- end;
 
- function TJclPeImage.GetResourceList: TJclPeRootResourceList;
 
- begin
 
-   if FResourceList = nil then
 
-   begin
 
-     FResourceVA := Directories[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
 
-     if FResourceVA <> 0 then
 
-       FResourceVA := TJclAddr(RvaToVa(FResourceVA));
 
-     FResourceList := TJclPeRootResourceList.Create(Self, nil, PImageResourceDirectory(FResourceVA));
 
-   end;
 
-   Result := FResourceList;
 
- end;
 
- function TJclPeImage.GetSectionHeader(const SectionName: string;
 
-   out Header: PImageSectionHeader): Boolean;
 
- var
 
-   I: Integer;
 
- begin
 
-   I := FImageSections.IndexOf(SectionName);
 
-   if I = -1 then
 
-   begin
 
-     Header := nil;
 
-     Result := False;
 
-   end
 
-   else
 
-   begin
 
-     Header := PImageSectionHeader(FImageSections.Objects[I]);
 
-     Result := True;
 
-   end;
 
- end;
 
- function TJclPeImage.GetSectionName(Header: PImageSectionHeader): string;
 
- var
 
-   I: Integer;
 
- begin
 
-   I := FImageSections.IndexOfObject(TObject(Header));
 
-   if I = -1 then
 
-     Result := ''
 
-   else
 
-     Result := FImageSections[I];
 
- end;
 
- function TJclPeImage.GetStringTableCount: Integer;
 
- begin
 
-   Result := FStringTable.Count;
 
- end;
 
- function TJclPeImage.GetStringTableItem(Index: Integer): string;
 
- begin
 
-   Result := FStringTable[Index];
 
- end;
 
- function TJclPeImage.GetUnusedHeaderBytes: TImageDataDirectory;
 
- begin
 
-   CheckNotAttached;
 
-   Result.Size := 0;
 
-   Result.VirtualAddress := GetImageUnusedHeaderBytes(FLoadedImage, Result.Size);
 
-   if Result.VirtualAddress = 0 then
 
-     RaiseLastOSError;
 
- end;
 
- function TJclPeImage.GetVersionInfo: TJclFileVersionInfo;
 
- var
 
-   VersionInfoResource: TJclPeResourceItem;
 
- begin
 
-   if (FVersionInfo = nil) and VersionInfoAvailable then
 
-   begin
 
-     VersionInfoResource := ResourceList.FindResource(rtVersion, '1').List[0];
 
-     with VersionInfoResource do
 
-       try
 
-         FVersionInfo := TJclFileVersionInfo.Attach(RawEntryData, RawEntryDataSize);
 
-       except
 
-         FreeAndNil(FVersionInfo);
 
-       end;
 
-   end;
 
-   Result := FVersionInfo;
 
- end;
 
- function TJclPeImage.GetVersionInfoAvailable: Boolean;
 
- begin
 
-   Result := StatusOK and (ResourceList.FindResource(rtVersion, '1') <> nil);
 
- end;
 
- class function TJclPeImage.HeaderNames(Index: TJclPeHeader): string;
 
- begin
 
-   case Index of
 
-     JclPeHeader_Signature:
 
-       Result := LoadResString(@RsPeSignature);
 
-     JclPeHeader_Machine:
 
-       Result := LoadResString(@RsPeMachine);
 
-     JclPeHeader_NumberOfSections:
 
-       Result := LoadResString(@RsPeNumberOfSections);
 
-     JclPeHeader_TimeDateStamp:
 
-       Result := LoadResString(@RsPeTimeDateStamp);
 
-     JclPeHeader_PointerToSymbolTable:
 
-       Result := LoadResString(@RsPePointerToSymbolTable);
 
-     JclPeHeader_NumberOfSymbols:
 
-       Result := LoadResString(@RsPeNumberOfSymbols);
 
-     JclPeHeader_SizeOfOptionalHeader:
 
-       Result := LoadResString(@RsPeSizeOfOptionalHeader);
 
-     JclPeHeader_Characteristics:
 
-       Result := LoadResString(@RsPeCharacteristics);
 
-     JclPeHeader_Magic:
 
-       Result := LoadResString(@RsPeMagic);
 
-     JclPeHeader_LinkerVersion:
 
-       Result := LoadResString(@RsPeLinkerVersion);
 
-     JclPeHeader_SizeOfCode:
 
-       Result := LoadResString(@RsPeSizeOfCode);
 
-     JclPeHeader_SizeOfInitializedData:
 
-       Result := LoadResString(@RsPeSizeOfInitializedData);
 
-     JclPeHeader_SizeOfUninitializedData:
 
-       Result := LoadResString(@RsPeSizeOfUninitializedData);
 
-     JclPeHeader_AddressOfEntryPoint:
 
-       Result := LoadResString(@RsPeAddressOfEntryPoint);
 
-     JclPeHeader_BaseOfCode:
 
-       Result := LoadResString(@RsPeBaseOfCode);
 
-     JclPeHeader_BaseOfData:
 
-       Result := LoadResString(@RsPeBaseOfData);
 
-     JclPeHeader_ImageBase:
 
-       Result := LoadResString(@RsPeImageBase);
 
-     JclPeHeader_SectionAlignment:
 
-       Result := LoadResString(@RsPeSectionAlignment);
 
-     JclPeHeader_FileAlignment:
 
-       Result := LoadResString(@RsPeFileAlignment);
 
-     JclPeHeader_OperatingSystemVersion:
 
-       Result := LoadResString(@RsPeOperatingSystemVersion);
 
-     JclPeHeader_ImageVersion:
 
-       Result := LoadResString(@RsPeImageVersion);
 
-     JclPeHeader_SubsystemVersion:
 
-       Result := LoadResString(@RsPeSubsystemVersion);
 
-     JclPeHeader_Win32VersionValue:
 
-       Result := LoadResString(@RsPeWin32VersionValue);
 
-     JclPeHeader_SizeOfImage:
 
-       Result := LoadResString(@RsPeSizeOfImage);
 
-     JclPeHeader_SizeOfHeaders:
 
-       Result := LoadResString(@RsPeSizeOfHeaders);
 
-     JclPeHeader_CheckSum:
 
-       Result := LoadResString(@RsPeCheckSum);
 
-     JclPeHeader_Subsystem:
 
-       Result := LoadResString(@RsPeSubsystem);
 
-     JclPeHeader_DllCharacteristics:
 
-       Result := LoadResString(@RsPeDllCharacteristics);
 
-     JclPeHeader_SizeOfStackReserve:
 
-       Result := LoadResString(@RsPeSizeOfStackReserve);
 
-     JclPeHeader_SizeOfStackCommit:
 
-       Result := LoadResString(@RsPeSizeOfStackCommit);
 
-     JclPeHeader_SizeOfHeapReserve:
 
-       Result := LoadResString(@RsPeSizeOfHeapReserve);
 
-     JclPeHeader_SizeOfHeapCommit:
 
-       Result := LoadResString(@RsPeSizeOfHeapCommit);
 
-     JclPeHeader_LoaderFlags:
 
-       Result := LoadResString(@RsPeLoaderFlags);
 
-     JclPeHeader_NumberOfRvaAndSizes:
 
-       Result := LoadResString(@RsPeNumberOfRvaAndSizes);
 
-   else
 
-     Result := '';
 
-   end;
 
- end;
 
- function TJclPeImage.IsBrokenFormat: Boolean;
 
-   function IsBrokenFormat32: Boolean;
 
-   var
 
-     OptionalHeader: TImageOptionalHeader32;
 
-   begin
 
-     OptionalHeader := OptionalHeader32;
 
-     Result := not ((OptionalHeader.AddressOfEntryPoint = 0) or IsCLR);
 
-     if Result then
 
-     begin
 
-       Result := (ImageSectionCount = 0);
 
-       if not Result then
 
-         with ImageSectionHeaders[0] do
 
-           Result := (VirtualAddress <> OptionalHeader.BaseOfCode) or (SizeOfRawData = 0) or
 
-             (OptionalHeader.AddressOfEntryPoint > VirtualAddress + Misc.VirtualSize) or
 
-             (Characteristics and (IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_WRITE) <> IMAGE_SCN_CNT_CODE);
 
-     end;
 
-   end;
 
-   function IsBrokenFormat64: Boolean;
 
-   var
 
-     OptionalHeader: TImageOptionalHeader64;
 
-   begin
 
-     OptionalHeader := OptionalHeader64;
 
-     Result := not ((OptionalHeader.AddressOfEntryPoint = 0) or IsCLR);
 
-     if Result then
 
-     begin
 
-       Result := (ImageSectionCount = 0);
 
-       if not Result then
 
-         with ImageSectionHeaders[0] do
 
-           Result := (VirtualAddress <> OptionalHeader.BaseOfCode) or (SizeOfRawData = 0) or
 
-             (OptionalHeader.AddressOfEntryPoint > VirtualAddress + Misc.VirtualSize) or
 
-             (Characteristics and (IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_WRITE) <> IMAGE_SCN_CNT_CODE);
 
-     end;
 
-   end;
 
- begin
 
-   case Target of
 
-     taWin32:
 
-       Result := IsBrokenFormat32;
 
-     taWin64:
 
-       Result := IsBrokenFormat64;
 
-     //taUnknown:
 
-   else
 
-     Result := False; // don't know how to check it
 
-   end;
 
- end;
 
- function TJclPeImage.IsCLR: Boolean;
 
- begin
 
-   Result := DirectoryExists[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] and CLRHeader.HasMetadata;
 
- end;
 
- function TJclPeImage.IsSystemImage: Boolean;
 
- begin
 
-   Result := StatusOK and FLoadedImage.fSystemImage;
 
- end;
 
- class function TJclPeImage.LoadConfigNames(Index: TJclLoadConfig): string;
 
- begin
 
-   case Index of
 
-     JclLoadConfig_Characteristics:
 
-       Result := LoadResString(@RsPeCharacteristics);
 
-     JclLoadConfig_TimeDateStamp:
 
-       Result := LoadResString(@RsPeTimeDateStamp);
 
-     JclLoadConfig_Version:
 
-       Result := LoadResString(@RsPeVersion);
 
-     JclLoadConfig_GlobalFlagsClear:
 
-       Result := LoadResString(@RsPeGlobalFlagsClear);
 
-     JclLoadConfig_GlobalFlagsSet:
 
-       Result := LoadResString(@RsPeGlobalFlagsSet);
 
-     JclLoadConfig_CriticalSectionDefaultTimeout:
 
-       Result := LoadResString(@RsPeCriticalSectionDefaultTimeout);
 
-     JclLoadConfig_DeCommitFreeBlockThreshold:
 
-       Result := LoadResString(@RsPeDeCommitFreeBlockThreshold);
 
-     JclLoadConfig_DeCommitTotalFreeThreshold:
 
-       Result := LoadResString(@RsPeDeCommitTotalFreeThreshold);
 
-     JclLoadConfig_LockPrefixTable:
 
-       Result := LoadResString(@RsPeLockPrefixTable);
 
-     JclLoadConfig_MaximumAllocationSize:
 
-       Result := LoadResString(@RsPeMaximumAllocationSize);
 
-     JclLoadConfig_VirtualMemoryThreshold:
 
-       Result := LoadResString(@RsPeVirtualMemoryThreshold);
 
-     JclLoadConfig_ProcessHeapFlags:
 
-       Result := LoadResString(@RsPeProcessHeapFlags);
 
-     JclLoadConfig_ProcessAffinityMask:
 
-       Result := LoadResString(@RsPeProcessAffinityMask);
 
-     JclLoadConfig_CSDVersion:
 
-       Result := LoadResString(@RsPeCSDVersion);
 
-     JclLoadConfig_Reserved1:
 
-       Result := LoadResString(@RsPeReserved);
 
-     JclLoadConfig_EditList:
 
-       Result := LoadResString(@RsPeEditList);
 
-     JclLoadConfig_Reserved:
 
-       Result := LoadResString(@RsPeReserved);
 
-   else
 
-     Result := '';
 
-   end;
 
- end;
 
- procedure TJclPeImage.RaiseStatusException;
 
- begin
 
-   if not FNoExceptions then
 
-     case FStatus of
 
-       stNotPE:
 
-         raise EJclPeImageError.CreateRes(@RsPeNotPE);
 
-       stNotFound:
 
-         raise EJclPeImageError.CreateResFmt(@RsPeCantOpen, [FFileName]);
 
-       stNotSupported:
 
-         raise EJclPeImageError.CreateRes(@RsPeUnknownTarget);
 
-       stError:
 
-         RaiseLastOSError;
 
-     end;
 
- end;
 
- function TJclPeImage.RawToVa(Raw: DWORD): Pointer;
 
- begin
 
-   Result := Pointer(TJclAddr(FLoadedImage.MappedAddress) + Raw);
 
- end;
 
- procedure TJclPeImage.ReadImageSections;
 
- var
 
-   I: Integer;
 
-   Header: PImageSectionHeader;
 
-   UTF8Name: TUTF8String;
 
-   SectionName: string;
 
- begin
 
-   if not StatusOK then
 
-     Exit;
 
-   Header := FLoadedImage.Sections;
 
-   for I := 0 to FLoadedImage.NumberOfSections - 1 do
 
-   begin
 
-     SetLength(UTF8Name, IMAGE_SIZEOF_SHORT_NAME);
 
-     Move(Header.Name[0], UTF8Name[1], IMAGE_SIZEOF_SHORT_NAME * SizeOf(AnsiChar));
 
-     StrResetLength(UTF8Name);
 
-     if not TryUTF8ToString(UTF8Name, SectionName) then
 
-       SectionName := string(UTF8Name);
 
-     FImageSections.AddObject(SectionName, Pointer(Header));
 
-     Inc(Header);
 
-   end;
 
- end;
 
- procedure TJclPeImage.ReadStringTable;
 
- var
 
-   SymbolTable: DWORD;
 
-   StringTablePtr: PAnsiChar;
 
-   Ptr: PAnsiChar;
 
-   ByteSize: ULONG;
 
-   Start: PAnsiChar;
 
-   StringEntry: AnsiString;
 
- begin
 
-   SymbolTable := LoadedImage.FileHeader.FileHeader.PointerToSymbolTable;
 
-   if SymbolTable = 0 then
 
-     Exit;
 
-   StringTablePtr := PAnsiChar(LoadedImage.MappedAddress) +
 
-                     SymbolTable +
 
-                     (LoadedImage.FileHeader.FileHeader.NumberOfSymbols * SizeOf(IMAGE_SYMBOL));
 
-   ByteSize := PULONG(StringTablePtr)^;
 
-   Ptr := StringTablePtr + SizeOf(ByteSize);
 
-   while Ptr < StringTablePtr + ByteSize do
 
-   begin
 
-     Start := Ptr;
 
-     while (Ptr^ <> #0) and (Ptr < StringTablePtr + ByteSize) do
 
-       Inc(Ptr);
 
-     if Start <> Ptr then
 
-     begin
 
-       SetLength(StringEntry, Ptr - Start);
 
-       Move(Start^, StringEntry[1], Ptr - Start);
 
-       FStringTable.Add(string(StringEntry));
 
-     end;
 
-     Inc(Ptr); // to skip the #0 character
 
-   end;
 
- end;
 
- function TJclPeImage.ResourceItemCreate(AEntry: PImageResourceDirectoryEntry;
 
-   AParentItem: TJclPeResourceItem): TJclPeResourceItem;
 
- begin
 
-   Result := TJclPeResourceItem.Create(Self, AParentItem, AEntry);
 
- end;
 
- function TJclPeImage.ResourceListCreate(ADirectory: PImageResourceDirectory;
 
-   AParentItem: TJclPeResourceItem): TJclPeResourceList;
 
- begin
 
-   Result := TJclPeResourceList.Create(Self, AParentItem, ADirectory);
 
- end;
 
- function TJclPeImage.RvaToSection(Rva: DWORD): PImageSectionHeader;
 
- var
 
-   I: Integer;
 
-   SectionHeader: PImageSectionHeader;
 
-   EndRVA: DWORD;
 
- begin
 
-   Result := ImageRvaToSection(FLoadedImage.FileHeader, FLoadedImage.MappedAddress, Rva);
 
-   if Result = nil then
 
-     for I := 0 to FImageSections.Count - 1 do
 
-     begin
 
-       SectionHeader := PImageSectionHeader(FImageSections.Objects[I]);
 
-       if SectionHeader^.SizeOfRawData = 0 then
 
-         EndRVA := SectionHeader^.Misc.VirtualSize
 
-       else
 
-         EndRVA := SectionHeader^.SizeOfRawData;
 
-       Inc(EndRVA, SectionHeader^.VirtualAddress);
 
-       if (SectionHeader^.VirtualAddress <= Rva) and (EndRVA >= Rva) then
 
-       begin
 
-         Result := SectionHeader;
 
-         Break;
 
-       end;
 
-     end;
 
- end;
 
- function TJclPeImage.RvaToVa(Rva: DWORD): Pointer;
 
- begin
 
-   if FAttachedImage then
 
-     Result := Pointer(TJclAddr(FLoadedImage.MappedAddress) + Rva)
 
-   else
 
-     Result := ImageRvaToVa(FLoadedImage.FileHeader, FLoadedImage.MappedAddress, Rva, nil);
 
- end;
 
- function TJclPeImage.RvaToVaEx(Rva: DWORD): Pointer;
 
-   function RvaToVaEx32(Rva: DWORD): Pointer;
 
-   var
 
-     OptionalHeader: TImageOptionalHeader32;
 
-   begin
 
-     OptionalHeader := OptionalHeader32;
 
-     if (Rva >= OptionalHeader.ImageBase) and (Rva < (OptionalHeader.ImageBase + FLoadedImage.SizeOfImage)) then
 
-       Dec(Rva, OptionalHeader.ImageBase);
 
-     Result := RvaToVa(Rva);
 
-   end;
 
-   function RvaToVaEx64(Rva: DWORD): Pointer;
 
-   var
 
-     OptionalHeader: TImageOptionalHeader64;
 
-   begin
 
-     OptionalHeader := OptionalHeader64;
 
-     if (Rva >= OptionalHeader.ImageBase) and (Rva < (OptionalHeader.ImageBase + FLoadedImage.SizeOfImage)) then
 
-       Dec(Rva, OptionalHeader.ImageBase);
 
-     Result := RvaToVa(Rva);
 
-   end;
 
- begin
 
-   case Target of
 
-     taWin32:
 
-       Result := RvaToVaEx32(Rva);
 
-     taWin64:
 
-       Result := RvaToVaEx64(Rva);
 
-     //taUnknown:
 
-   else
 
-     Result := nil;
 
-   end;
 
- end;
 
- procedure TJclPeImage.SetFileName(const Value: TFileName);
 
- begin
 
-   if FFileName <> Value then
 
-   begin
 
-     Clear;
 
-     FFileName := Value;
 
-     if FFileName = '' then
 
-       Exit;
 
-     // OF: possible loss of data
 
-     if MapAndLoad(PAnsiChar(AnsiString(FFileName)), nil, FLoadedImage, True, FReadOnlyAccess) then
 
-     begin
 
-       FTarget := PeMapImgTarget(FLoadedImage.MappedAddress);
 
-       if FTarget <> taUnknown then
 
-       begin
 
-         FStatus := stOk;
 
-         ReadImageSections;
 
-         ReadStringTable;
 
-         AfterOpen;
 
-       end
 
-       else
 
-         FStatus := stNotSupported;
 
-     end
 
-     else
 
-       case GetLastError of
 
-         ERROR_SUCCESS:
 
-           FStatus := stNotPE;
 
-         ERROR_FILE_NOT_FOUND:
 
-           FStatus := stNotFound;
 
-       else
 
-         FStatus := stError;
 
-       end;
 
-     RaiseStatusException;
 
-   end;
 
- end;
 
- class function TJclPeImage.ShortSectionInfo(Characteristics: DWORD): string;
 
- type
 
-   TSectionCharacteristics = packed record
 
-     Mask: DWORD;
 
-     InfoChar: Char;
 
-   end;
 
- const
 
-   Info: array [1..8] of TSectionCharacteristics = (
 
-     (Mask: IMAGE_SCN_CNT_CODE; InfoChar: 'C'),
 
-     (Mask: IMAGE_SCN_MEM_EXECUTE; InfoChar: 'E'),
 
-     (Mask: IMAGE_SCN_MEM_READ; InfoChar: 'R'),
 
-     (Mask: IMAGE_SCN_MEM_WRITE; InfoChar: 'W'),
 
-     (Mask: IMAGE_SCN_CNT_INITIALIZED_DATA; InfoChar: 'I'),
 
-     (Mask: IMAGE_SCN_CNT_UNINITIALIZED_DATA; InfoChar: 'U'),
 
-     (Mask: IMAGE_SCN_MEM_SHARED; InfoChar: 'S'),
 
-     (Mask: IMAGE_SCN_MEM_DISCARDABLE; InfoChar: 'D')
 
-   );
 
- var
 
-   I: Integer;
 
- begin
 
-   SetLength(Result, High(Info));
 
-   Result := '';
 
-   for I := Low(Info) to High(Info) do
 
-     with Info[I] do
 
-       if (Characteristics and Mask) = Mask then
 
-         Result := Result + InfoChar;
 
- end;
 
- function TJclPeImage.StatusOK: Boolean;
 
- begin
 
-   Result := (FStatus = stOk);
 
- end;
 
- class function TJclPeImage.StampToDateTime(TimeDateStamp: DWORD): TDateTime;
 
- begin
 
-   Result := TimeDateStamp / SecsPerDay + UnixTimeStart
 
- end;
 
- procedure TJclPeImage.TryGetNamesForOrdinalImports;
 
- begin
 
-   if StatusOK then
 
-   begin
 
-     GetImportList;
 
-     FImportList.TryGetNamesForOrdinalImports;
 
-   end;
 
- end;
 
- function TJclPeImage.VerifyCheckSum: Boolean;
 
-   function VerifyCheckSum32: Boolean;
 
-   var
 
-     OptionalHeader: TImageOptionalHeader32;
 
-   begin
 
-     OptionalHeader := OptionalHeader32;
 
-     Result := StatusOK and ((OptionalHeader.CheckSum = 0) or (CalculateCheckSum = OptionalHeader.CheckSum));
 
-   end;
 
-   function VerifyCheckSum64: Boolean;
 
-   var
 
-     OptionalHeader: TImageOptionalHeader64;
 
-   begin
 
-     OptionalHeader := OptionalHeader64;
 
-     Result := StatusOK and ((OptionalHeader.CheckSum = 0) or (CalculateCheckSum = OptionalHeader.CheckSum));
 
-   end;
 
- begin
 
-   CheckNotAttached;
 
-   case Target of
 
-     taWin32:
 
-       Result := VerifyCheckSum32;
 
-     taWin64:
 
-       Result := VerifyCheckSum64;
 
-     //taUnknown: ;
 
-   else
 
-     Result := True;
 
-   end;
 
- end;
 
- {$IFDEF BORLAND}
 
- //=== { TJclPeBorImagesCache } ===============================================
 
- function TJclPeBorImagesCache.GetImages(const FileName: TFileName): TJclPeBorImage;
 
- begin
 
-   Result := TJclPeBorImage(inherited Images[FileName]);
 
- end;
 
- function TJclPeBorImagesCache.GetPeImageClass: TJclPeImageClass;
 
- begin
 
-   Result := TJclPeBorImage;
 
- end;
 
- //=== { TJclPePackageInfo } ==================================================
 
- constructor TJclPePackageInfo.Create(ALibHandle: THandle);
 
- begin
 
-   FContains := TStringList.Create;
 
-   FRequires := TStringList.Create;
 
-   FEnsureExtension := True;
 
-   FSorted := True;
 
-   ReadPackageInfo(ALibHandle);
 
- end;
 
- destructor TJclPePackageInfo.Destroy;
 
- begin
 
-   FreeAndNil(FContains);
 
-   FreeAndNil(FRequires);
 
-   inherited Destroy;
 
- end;
 
- function TJclPePackageInfo.GetContains: TStrings;
 
- begin
 
-   Result := FContains;
 
- end;
 
- function TJclPePackageInfo.GetContainsCount: Integer;
 
- begin
 
-   Result := Contains.Count;
 
- end;
 
- function TJclPePackageInfo.GetContainsFlags(Index: Integer): Byte;
 
- begin
 
-   Result := Byte(Contains.Objects[Index]);
 
- end;
 
- function TJclPePackageInfo.GetContainsNames(Index: Integer): string;
 
- begin
 
-   Result := Contains[Index];
 
- end;
 
- function TJclPePackageInfo.GetRequires: TStrings;
 
- begin
 
-   Result := FRequires;
 
- end;
 
- function TJclPePackageInfo.GetRequiresCount: Integer;
 
- begin
 
-   Result := Requires.Count;
 
- end;
 
- function TJclPePackageInfo.GetRequiresNames(Index: Integer): string;
 
- begin
 
-   Result := Requires[Index];
 
-   if FEnsureExtension then
 
-     StrEnsureSuffix(BinaryExtensionPackage, Result);
 
- end;
 
- class function TJclPePackageInfo.PackageModuleTypeToString(Flags: Cardinal): string;
 
- begin
 
-   case Flags and pfModuleTypeMask of
 
-     pfExeModule, pfModuleTypeMask:
 
-       Result := LoadResString(@RsPePkgExecutable);
 
-     pfPackageModule:
 
-       Result := LoadResString(@RsPePkgPackage);
 
-     pfLibraryModule:
 
-       Result := LoadResString(@PsPePkgLibrary);
 
-   else
 
-     Result := '';
 
-   end;
 
- end;
 
- class function TJclPePackageInfo.PackageOptionsToString(Flags: Cardinal): string;
 
- begin
 
-   Result := '';
 
-   AddFlagTextRes(Result, @RsPePkgNeverBuild, Flags, pfNeverBuild);
 
-   AddFlagTextRes(Result, @RsPePkgDesignOnly, Flags, pfDesignOnly);
 
-   AddFlagTextRes(Result, @RsPePkgRunOnly, Flags, pfRunOnly);
 
-   AddFlagTextRes(Result, @RsPePkgIgnoreDupUnits, Flags, pfIgnoreDupUnits);
 
- end;
 
- class function TJclPePackageInfo.ProducerToString(Flags: Cardinal): string;
 
- begin
 
-   case Flags and pfProducerMask of
 
-     pfV3Produced:
 
-       Result := LoadResString(@RsPePkgV3Produced);
 
-     pfProducerUndefined:
 
-       Result := LoadResString(@RsPePkgProducerUndefined);
 
-     pfBCB4Produced:
 
-       Result := LoadResString(@RsPePkgBCB4Produced);
 
-     pfDelphi4Produced:
 
-       Result := LoadResString(@RsPePkgDelphi4Produced);
 
-   else
 
-     Result := '';
 
-   end;
 
- end;
 
- procedure PackageInfoProc(const Name: string; NameType: TNameType; AFlags: Byte; Param: Pointer);
 
- begin
 
-   with TJclPePackageInfo(Param) do
 
-     case NameType of
 
-       ntContainsUnit:
 
-         Contains.AddObject(Name, Pointer(AFlags));
 
-       ntRequiresPackage:
 
-         Requires.Add(Name);
 
-       ntDcpBpiName:
 
-         SetDcpName(Name);
 
-     end;
 
- end;
 
- procedure TJclPePackageInfo.ReadPackageInfo(ALibHandle: THandle);
 
- var
 
-   DescrResInfo: HRSRC;
 
-   DescrResData: HGLOBAL;
 
- begin
 
-   FAvailable := FindResource(ALibHandle, PackageInfoResName, RT_RCDATA) <> 0;
 
-   if FAvailable then
 
-   begin
 
-     GetPackageInfo(ALibHandle, Self, FFlags, PackageInfoProc);
 
-     if FDcpName = '' then
 
-       FDcpName := PathExtractFileNameNoExt(GetModulePath(ALibHandle)) + CompilerExtensionDCP;
 
-     if FSorted then
 
-     begin
 
-       FContains.Sort;
 
-       FRequires.Sort;
 
-     end;
 
-   end;
 
-   DescrResInfo := FindResource(ALibHandle, DescriptionResName, RT_RCDATA);
 
-   if DescrResInfo <> 0 then
 
-   begin
 
-     DescrResData := LoadResource(ALibHandle, DescrResInfo);
 
-     if DescrResData <> 0 then
 
-     begin
 
-       FDescription := WideCharLenToString(LockResource(DescrResData),
 
-         SizeofResource(ALibHandle, DescrResInfo));
 
-       StrResetLength(FDescription);
 
-     end;
 
-   end;
 
- end;
 
- procedure TJclPePackageInfo.SetDcpName(const Value: string);
 
- begin
 
-   FDcpName := Value;
 
- end;
 
- class function TJclPePackageInfo.UnitInfoFlagsToString(UnitFlags: Byte): string;
 
- begin
 
-   Result := '';
 
-   AddFlagTextRes(Result, @RsPePkgMain, UnitFlags, ufMainUnit);
 
-   AddFlagTextRes(Result, @RsPePkgPackage, UnitFlags, ufPackageUnit);
 
-   AddFlagTextRes(Result, @RsPePkgWeak, UnitFlags, ufWeakUnit);
 
-   AddFlagTextRes(Result, @RsPePkgOrgWeak, UnitFlags, ufOrgWeakUnit);
 
-   AddFlagTextRes(Result, @RsPePkgImplicit, UnitFlags, ufImplicitUnit);
 
- end;
 
- //=== { TJclPeBorForm } ======================================================
 
- constructor TJclPeBorForm.Create(AResItem: TJclPeResourceItem;
 
-   AFormFlags: TFilerFlags; AFormPosition: Integer;
 
-   const AFormClassName, AFormObjectName: string);
 
- begin
 
-   inherited Create;
 
-   FResItem := AResItem;
 
-   FFormFlags := AFormFlags;
 
-   FFormPosition := AFormPosition;
 
-   FFormClassName := AFormClassName;
 
-   FFormObjectName := AFormObjectName;
 
- end;
 
- procedure TJclPeBorForm.ConvertFormToText(const Stream: TStream);
 
- var
 
-   SourceStream: TJclPeResourceRawStream;
 
- begin
 
-   SourceStream := TJclPeResourceRawStream.Create(ResItem);
 
-   try
 
-     ObjectBinaryToText(SourceStream, Stream);
 
-   finally
 
-     SourceStream.Free;
 
-   end;
 
- end;
 
- procedure TJclPeBorForm.ConvertFormToText(const Strings: TStrings);
 
- var
 
-   TempStream: TMemoryStream;
 
- begin
 
-   TempStream := TMemoryStream.Create;
 
-   try
 
-     ConvertFormToText(TempStream);
 
-     TempStream.Seek(0, soFromBeginning);
 
-     Strings.LoadFromStream(TempStream);
 
-   finally
 
-     TempStream.Free;
 
-   end;
 
- end;
 
- function TJclPeBorForm.GetDisplayName: string;
 
- begin
 
-   if FFormObjectName <> '' then
 
-     Result := FFormObjectName + ': '
 
-   else
 
-     Result := '';
 
-   Result := Result + FFormClassName;
 
- end;
 
- //=== { TJclPeBorImage } =====================================================
 
- constructor TJclPeBorImage.Create(ANoExceptions: Boolean);
 
- begin
 
-   FForms := TObjectList.Create(True);
 
-   FPackageInfoSorted := True;
 
-   inherited Create(ANoExceptions);
 
- end;
 
- destructor TJclPeBorImage.Destroy;
 
- begin
 
-   inherited Destroy;
 
-   FreeAndNil(FForms);
 
- end;
 
- procedure TJclPeBorImage.AfterOpen;
 
- var
 
-   HasDVCLAL, HasPACKAGEINFO, HasPACKAGEOPTIONS: Boolean;
 
- begin
 
-   inherited AfterOpen;
 
-   if StatusOK then
 
-     with ResourceList do
 
-     begin
 
-       HasDVCLAL := (FindResource(rtRCData, DVclAlResName) <> nil);
 
-       HasPACKAGEINFO := (FindResource(rtRCData, PackageInfoResName) <> nil);
 
-       HasPACKAGEOPTIONS := (FindResource(rtRCData, PackageOptionsResName) <> nil);
 
-       FIsPackage := HasPACKAGEINFO and HasPACKAGEOPTIONS;
 
-       FIsBorlandImage := HasDVCLAL or FIsPackage;
 
-     end;
 
- end;
 
- procedure TJclPeBorImage.Clear;
 
- begin
 
-   FForms.Clear;
 
-   FreeAndNil(FPackageInfo);
 
-   FreeLibHandle;
 
-   inherited Clear;
 
-   FIsBorlandImage := False;
 
-   FIsPackage := False;
 
-   FPackageCompilerVersion := 0;
 
- end;
 
- procedure TJclPeBorImage.CreateFormsList;
 
- var
 
-   ResTypeItem: TJclPeResourceItem;
 
-   I: Integer;
 
-   procedure ProcessListItem(DfmResItem: TJclPeResourceItem);
 
-   const
 
-     FilerSignature: array [1..4] of AnsiChar = string('TPF0');
 
-   var
 
-     SourceStream: TJclPeResourceRawStream;
 
-     Reader: TReader;
 
-     FormFlags: TFilerFlags;
 
-     FormPosition: Integer;
 
-     ClassName, FormName: string;
 
-   begin
 
-     SourceStream := TJclPeResourceRawStream.Create(DfmResItem);
 
-     try
 
-       if (SourceStream.Size > SizeOf(FilerSignature)) and
 
-         (PInteger(SourceStream.Memory)^ = Integer(FilerSignature)) then
 
-       begin
 
-         Reader := TReader.Create(SourceStream, 4096);
 
-         try
 
-           Reader.ReadSignature;
 
-           Reader.ReadPrefix(FormFlags, FormPosition);
 
-           ClassName := Reader.ReadStr;
 
-           FormName := Reader.ReadStr;
 
-           FForms.Add(TJclPeBorForm.Create(DfmResItem, FormFlags, FormPosition,
 
-             ClassName, FormName));
 
-         finally
 
-           Reader.Free;
 
-         end;
 
-       end;
 
-     finally
 
-       SourceStream.Free;
 
-     end;
 
-   end;
 
- begin
 
-   if StatusOK then
 
-     with ResourceList do
 
-     begin
 
-       ResTypeItem := FindResource(rtRCData, '');
 
-       if ResTypeItem <> nil then
 
-         with ResTypeItem.List do
 
-           for I := 0 to Count - 1 do
 
-             ProcessListItem(Items[I].List[0]);
 
-     end;
 
- end;
 
- function TJclPeBorImage.DependedPackages(List: TStrings; FullPathName, Descriptions: Boolean): Boolean;
 
- var
 
-   ImportList: TStringList;
 
-   I: Integer;
 
-   Name: string;
 
- begin
 
-   Result := IsBorlandImage;
 
-   if not Result then
 
-     Exit;
 
-   ImportList := InternalImportedLibraries(FileName, True, FullPathName, nil);
 
-   List.BeginUpdate;
 
-   try
 
-     for I := 0 to ImportList.Count - 1 do
 
-     begin
 
-       Name := ImportList[I];
 
-       if StrSame(ExtractFileExt(Name), BinaryExtensionPackage) then
 
-       begin
 
-         if Descriptions then
 
-           List.Add(Name + '=' + GetPackageDescription(PChar(Name)))
 
-         else
 
-           List.Add(Name);
 
-       end;
 
-     end;
 
-   finally
 
-     ImportList.Free;
 
-     List.EndUpdate;
 
-   end;
 
- end;
 
- function TJclPeBorImage.FreeLibHandle: Boolean;
 
- begin
 
-   if FLibHandle <> 0 then
 
-   begin
 
-     Result := FreeLibrary(FLibHandle);
 
-     FLibHandle := 0;
 
-   end
 
-   else
 
-     Result := True;
 
- end;
 
- function TJclPeBorImage.GetFormCount: Integer;
 
- begin
 
-   if FForms.Count = 0 then
 
-     CreateFormsList;
 
-   Result := FForms.Count;
 
- end;
 
- function TJclPeBorImage.GetFormFromName(const FormClassName: string): TJclPeBorForm;
 
- var
 
-   I: Integer;
 
- begin
 
-   Result := nil;
 
-   for I := 0 to FormCount - 1 do
 
-     if StrSame(FormClassName, Forms[I].FormClassName) then
 
-     begin
 
-       Result := Forms[I];
 
-       Break;
 
-     end;
 
- end;
 
- function TJclPeBorImage.GetForms(Index: Integer): TJclPeBorForm;
 
- begin
 
-   Result := TJclPeBorForm(FForms[Index]);
 
- end;
 
- function TJclPeBorImage.GetLibHandle: THandle;
 
- begin
 
-   if StatusOK and (FLibHandle = 0) then
 
-   begin
 
-     FLibHandle := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE);
 
-     if FLibHandle = 0 then
 
-       RaiseLastOSError;
 
-   end;
 
-   Result := FLibHandle;
 
- end;
 
- function TJclPeBorImage.GetPackageCompilerVersion: Integer;
 
- var
 
-   I: Integer;
 
-   ImportName: string;
 
-   function CheckName: Boolean;
 
-   begin
 
-     Result := False;
 
-     ImportName := AnsiUpperCase(ImportName);
 
-     if StrSame(ExtractFileExt(ImportName), BinaryExtensionPackage) then
 
-     begin
 
-       ImportName := PathExtractFileNameNoExt(ImportName);
 
-       if (Length(ImportName) = 5) and
 
-         CharIsDigit(ImportName[4]) and CharIsDigit(ImportName[5]) and
 
-         ((Pos('RTL', ImportName) = 1) or (Pos('VCL', ImportName) = 1)) then
 
-       begin
 
-         FPackageCompilerVersion := StrToIntDef(Copy(ImportName, 4, 2), 0);
 
-         Result := True;
 
-       end;
 
-     end;
 
-   end;
 
- begin
 
-   if (FPackageCompilerVersion = 0) and IsPackage then
 
-   begin
 
-     with ImportList do
 
-       for I := 0 to UniqueLibItemCount - 1 do
 
-       begin
 
-         ImportName := UniqueLibNames[I];
 
-         if CheckName then
 
-           Break;
 
-       end;
 
-     if FPackageCompilerVersion = 0 then
 
-     begin
 
-       ImportName := ExtractFileName(FileName);
 
-       CheckName;
 
-     end;
 
-   end;
 
-   Result := FPackageCompilerVersion;
 
- end;
 
- function TJclPeBorImage.GetPackageInfo: TJclPePackageInfo;
 
- begin
 
-   if StatusOK and (FPackageInfo = nil) then
 
-   begin
 
-     GetLibHandle;
 
-     FPackageInfo := TJclPePackageInfo.Create(FLibHandle);
 
-     FPackageInfo.Sorted := FPackageInfoSorted;
 
-     FreeLibHandle;
 
-   end;
 
-   Result := FPackageInfo;
 
- end;
 
- {$ENDIF BORLAND}
 
- //=== { TJclPeNameSearch } ===================================================
 
- constructor TJclPeNameSearch.Create(const FunctionName, Path: string; Options: TJclPeNameSearchOptions);
 
- begin
 
-   inherited Create(True);
 
-   FFunctionName := FunctionName;
 
-   FOptions := Options;
 
-   FPath := Path;
 
-   FreeOnTerminate := True;
 
- end;
 
- function TJclPeNameSearch.CompareName(const FunctionName, ComparedName: string): Boolean;
 
- begin
 
-   Result := PeSmartFunctionNameSame(ComparedName, FunctionName, [scIgnoreCase]);
 
- end;
 
- procedure TJclPeNameSearch.DoFound;
 
- begin
 
-   if Assigned(FOnFound) then
 
-     FOnFound(Self, F_FileName, F_FunctionName, F_Option);
 
- end;
 
- procedure TJclPeNameSearch.DoProcessFile;
 
- begin
 
-   if Assigned(FOnProcessFile) then
 
-     FOnProcessFile(Self, FPeImage, F_Process);
 
- end;
 
- procedure TJclPeNameSearch.Execute;
 
- var
 
-   PathList: TStringList;
 
-   I: Integer;
 
-   function CompareNameAndNotify(const S: string): Boolean;
 
-   begin
 
-     Result := CompareName(S, FFunctionName);
 
-     if Result and not Terminated then
 
-     begin
 
-       F_FunctionName := S;
 
-       Synchronize(DoFound);
 
-     end;
 
-   end;
 
-   procedure ProcessDirectorySearch(const DirName: string);
 
-   var
 
-     Se: TSearchRec;
 
-     SearchResult: Integer;
 
-     ImportList: TJclPeImportList;
 
-     ExportList: TJclPeExportFuncList;
 
-     I: Integer;
 
-   begin
 
-     SearchResult := FindFirst(DirName, faArchive + faReadOnly, Se);
 
-     try
 
-       while not Terminated and (SearchResult = 0) do
 
-       begin
 
-         F_FileName := PathAddSeparator(ExtractFilePath(DirName)) + Se.Name;
 
-         F_Process := True;
 
-         FPeImage.FileName := F_FileName;
 
-         if Assigned(FOnProcessFile) then
 
-           Synchronize(DoProcessFile);
 
-         if F_Process and FPeImage.StatusOK then
 
-         begin
 
-           if seExports in FOptions then
 
-           begin
 
-             ExportList := FPeImage.ExportList;
 
-             F_Option := seExports;
 
-             for I := 0 to ExportList.Count - 1 do
 
-             begin
 
-               if Terminated then
 
-                 Break;
 
-               CompareNameAndNotify(ExportList[I].Name);
 
-             end;
 
-           end;
 
-           if FOptions * [seImports, seDelayImports, seBoundImports] <> [] then
 
-           begin
 
-             ImportList := FPeImage.ImportList;
 
-             FPeImage.TryGetNamesForOrdinalImports;
 
-             for I := 0 to ImportList.AllItemCount - 1 do
 
-               with ImportList.AllItems[I] do
 
-               begin
 
-                 if Terminated then
 
-                   Break;
 
-                 case ImportLib.ImportKind of
 
-                   ikImport:
 
-                     if seImports in FOptions then
 
-                     begin
 
-                       F_Option := seImports;
 
-                       CompareNameAndNotify(Name);
 
-                     end;
 
-                   ikDelayImport:
 
-                     if seDelayImports in FOptions then
 
-                     begin
 
-                       F_Option := seDelayImports;
 
-                       CompareNameAndNotify(Name);
 
-                     end;
 
-                   ikBoundImport:
 
-                     if seDelayImports in FOptions then
 
-                     begin
 
-                       F_Option := seBoundImports;
 
-                       CompareNameAndNotify(Name);
 
-                     end;
 
-                 end;
 
-               end;
 
-           end;
 
-         end;
 
-         SearchResult := FindNext(Se);
 
-       end;
 
-     finally
 
-       FindClose(Se);
 
-     end;
 
-   end;
 
- begin
 
-   FPeImage := TJclPeImage.Create(True);
 
-   PathList := TStringList.Create;
 
-   try
 
-     PathList.Sorted := True;
 
-     PathList.Duplicates := dupIgnore;
 
-     StrToStrings(FPath, ';', PathList);
 
-     for I := 0 to PathList.Count - 1 do
 
-       ProcessDirectorySearch(PathAddSeparator(Trim(PathList[I])) + '*.*');
 
-   finally
 
-     PathList.Free;
 
-     FPeImage.Free;
 
-   end;
 
- end;
 
- procedure TJclPeNameSearch.Start;
 
- begin
 
-   {$IFDEF RTL210_UP}
 
-   Suspended := False;
 
-   {$ELSE ~RTL210_UP}
 
-   Resume;
 
-   {$ENDIF ~RTL210_UP}
 
- end;
 
- //=== PE Image miscellaneous functions =======================================
 
- function IsValidPeFile(const FileName: TFileName): Boolean;
 
- var
 
-   NtHeaders: TImageNtHeaders32;
 
- begin
 
-   Result := PeGetNtHeaders32(FileName, NtHeaders);
 
- end;
 
- function InternalGetNtHeaders32(const FileName: TFileName; out NtHeaders): Boolean;
 
- var
 
-   FileHandle: THandle;
 
-   Mapping: TJclFileMapping;
 
-   View: TJclFileMappingView;
 
-   HeadersPtr: PImageNtHeaders32;
 
- begin
 
-   Result := False;
 
-   ResetMemory(NtHeaders, SizeOf(TImageNtHeaders32));
 
-   FileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyWrite);
 
-   if FileHandle = INVALID_HANDLE_VALUE then
 
-     Exit;
 
-   try
 
-     if GetSizeOfFile(FileHandle) >= SizeOf(TImageDosHeader) then
 
-     begin
 
-       Mapping := TJclFileMapping.Create(FileHandle, '', PAGE_READONLY, 0, nil);
 
-       try
 
-         View := TJclFileMappingView.Create(Mapping, FILE_MAP_READ, 0, 0);
 
-         HeadersPtr := PeMapImgNtHeaders32(View.Memory);
 
-         if HeadersPtr <> nil then
 
-         begin
 
-           Result := True;
 
-           TImageNtHeaders32(NtHeaders) := HeadersPtr^;
 
-         end;
 
-       finally
 
-         Mapping.Free;
 
-       end;
 
-     end;
 
-   finally
 
-     FileClose(FileHandle);
 
-   end;
 
- end;
 
- function PeGetNtHeaders32(const FileName: TFileName; out NtHeaders: TImageNtHeaders32): Boolean;
 
- begin
 
-   Result := InternalGetNtHeaders32(FileName, NtHeaders);
 
- end;
 
- function PeGetNtHeaders64(const FileName: TFileName; out NtHeaders: TImageNtHeaders64): Boolean;
 
- var
 
-   FileHandle: THandle;
 
-   Mapping: TJclFileMapping;
 
-   View: TJclFileMappingView;
 
-   HeadersPtr: PImageNtHeaders64;
 
- begin
 
-   Result := False;
 
-   ResetMemory(NtHeaders, SizeOf(NtHeaders));
 
-   FileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyWrite);
 
-   if FileHandle = INVALID_HANDLE_VALUE then
 
-     Exit;
 
-   try
 
-     if GetSizeOfFile(FileHandle) >= SizeOf(TImageDosHeader) then
 
-     begin
 
-       Mapping := TJclFileMapping.Create(FileHandle, '', PAGE_READONLY, 0, nil);
 
-       try
 
-         View := TJclFileMappingView.Create(Mapping, FILE_MAP_READ, 0, 0);
 
-         HeadersPtr := PeMapImgNtHeaders64(View.Memory);
 
-         if HeadersPtr <> nil then
 
-         begin
 
-           Result := True;
 
-           NtHeaders := HeadersPtr^;
 
-         end;
 
-       finally
 
-         Mapping.Free;
 
-       end;
 
-     end;
 
-   finally
 
-     FileClose(FileHandle);
 
-   end;
 
- end;
 
- function PeCreateNameHintTable(const FileName: TFileName): Boolean;
 
- var
 
-   PeImage, ExportsImage: TJclPeImage;
 
-   I: Integer;
 
-   ImportItem: TJclPeImportLibItem;
 
-   Thunk32: PImageThunkData32;
 
-   Thunk64: PImageThunkData64;
 
-   OrdinalName: PImageImportByName;
 
-   ExportItem: TJclPeExportFuncItem;
 
-   Cache: TJclPeImagesCache;
 
-   ImageBase32: TJclAddr32;
 
-   ImageBase64: TJclAddr64;
 
-   UTF8Name: TUTF8String;
 
-   ExportName: string;
 
- begin
 
-   Cache := TJclPeImagesCache.Create;
 
-   try
 
-     PeImage := TJclPeImage.Create(False);
 
-     try
 
-       PeImage.ReadOnlyAccess := False;
 
-       PeImage.FileName := FileName;
 
-       Result := PeImage.ImportList.Count > 0;
 
-       for I := 0 to PeImage.ImportList.Count - 1 do
 
-       begin
 
-         ImportItem := PeImage.ImportList[I];
 
-         if ImportItem.ImportKind = ikBoundImport then
 
-           Continue;
 
-         ExportsImage := Cache[ImportItem.FileName];
 
-         ExportsImage.ExportList.PrepareForFastNameSearch;
 
-         case PEImage.Target of
 
-           taWin32:
 
-             begin
 
-               Thunk32 := ImportItem.ThunkData32;
 
-               ImageBase32 := PeImage.OptionalHeader32.ImageBase;
 
-               while Thunk32^.Function_ <> 0 do
 
-               begin
 
-                 if Thunk32^.Ordinal and IMAGE_ORDINAL_FLAG32 = 0 then
 
-                 begin
 
-                   case ImportItem.ImportKind of
 
-                     ikImport:
 
-                       OrdinalName := PImageImportByName(PeImage.RvaToVa(Thunk32^.AddressOfData));
 
-                     ikDelayImport:
 
-                       OrdinalName := PImageImportByName(PeImage.RvaToVa(Thunk32^.AddressOfData - ImageBase32));
 
-                   else
 
-                     OrdinalName := nil;
 
-                   end;
 
-                   UTF8Name := PAnsiChar(@OrdinalName.Name);
 
-                   if not TryUTF8ToString(UTF8Name, ExportName) then
 
-                     ExportName := string(UTF8Name);
 
-                   ExportItem := ExportsImage.ExportList.ItemFromName[ExportName];
 
-                   if ExportItem <> nil then
 
-                     OrdinalName.Hint := ExportItem.Hint
 
-                   else
 
-                     OrdinalName.Hint := 0;
 
-                 end;
 
-                 Inc(Thunk32);
 
-               end;
 
-             end;
 
-           taWin64:
 
-             begin
 
-               Thunk64 := ImportItem.ThunkData64;
 
-               ImageBase64 := PeImage.OptionalHeader64.ImageBase;
 
-               while Thunk64^.Function_ <> 0 do
 
-               begin
 
-                 if Thunk64^.Ordinal and IMAGE_ORDINAL_FLAG64 = 0 then
 
-                 begin
 
-                   case ImportItem.ImportKind of
 
-                     ikImport:
 
-                       OrdinalName := PImageImportByName(PeImage.RvaToVa(Thunk64^.AddressOfData));
 
-                     ikDelayImport:
 
-                       OrdinalName := PImageImportByName(PeImage.RvaToVa(Thunk64^.AddressOfData - ImageBase64));
 
-                   else
 
-                     OrdinalName := nil;
 
-                   end;
 
-                   UTF8Name := PAnsiChar(@OrdinalName.Name);
 
-                   if not TryUTF8ToString(UTF8Name, ExportName) then
 
-                     ExportName := string(UTF8Name);
 
-                   ExportItem := ExportsImage.ExportList.ItemFromName[ExportName];
 
-                   if ExportItem <> nil then
 
-                     OrdinalName.Hint := ExportItem.Hint
 
-                   else
 
-                     OrdinalName.Hint := 0;
 
-                 end;
 
-                 Inc(Thunk64);
 
-               end;
 
-             end;
 
-         end;
 
-       end;
 
-     finally
 
-       PeImage.Free;
 
-     end;
 
-   finally
 
-     Cache.Free;
 
-   end;
 
- end;
 
- function PeRebaseImage32(const ImageName: TFileName; NewBase: TJclAddr32;
 
-   TimeStamp, MaxNewSize: DWORD): TJclRebaseImageInfo32;
 
-   function CalculateBaseAddress: TJclAddr32;
 
-   var
 
-     FirstChar: Char;
 
-     ModuleName: string;
 
-   begin
 
-     ModuleName := ExtractFileName(ImageName);
 
-     if Length(ModuleName) > 0 then
 
-       FirstChar := UpCase(ModuleName[1])
 
-     else
 
-       FirstChar := NativeNull;
 
-     if not CharIsUpper(FirstChar) then
 
-       FirstChar := 'A';
 
-     Result := $60000000 + (((Ord(FirstChar) - Ord('A')) div 3) * $1000000);
 
-   end;
 
- {$IFDEF CPU64}
 
- {$IFNDEF DELPHI64_TEMPORARY}
 
- var
 
-   NewIB, OldIB: QWord;
 
- {$ENDIF CPU64}
 
- {$ENDIF ~DELPHI64_TEMPORARY}
 
- begin
 
-   if NewBase = 0 then
 
-     NewBase := CalculateBaseAddress;
 
-   with Result do
 
-   begin
 
-     NewImageBase := NewBase;
 
-     // OF: possible loss of data
 
-     {$IFDEF CPU32}
 
-     Win32Check(ReBaseImage(PAnsiChar(AnsiString(ImageName)), nil, True, False, False, MaxNewSize,
 
-       OldImageSize, OldImageBase, NewImageSize, NewImageBase, TimeStamp));
 
-     {$ENDIF CPU32}
 
-     {$IFDEF CPU64}
 
-     {$IFDEF DELPHI64_TEMPORARY}
 
-     System.Error(rePlatformNotImplemented);
 
-     {$ELSE ~DELPHI64_TEMPORARY}
 
-     NewIB := NewImageBase;
 
-     OldIB := OldImageBase;
 
-     Win32Check(ReBaseImage(PAnsiChar(AnsiString(ImageName)), nil, True, False, False, MaxNewSize,
 
-       OldImageSize, OldIB, NewImageSize, NewIB, TimeStamp));
 
-     NewImageBase := NewIB;
 
-     OldImageBase := OldIB;
 
-     {$ENDIF ~DELPHI64_TEMPORARY}
 
-     {$ENDIF CPU64}
 
-   end;
 
- end;
 
- function PeRebaseImage64(const ImageName: TFileName; NewBase: TJclAddr64;
 
-   TimeStamp, MaxNewSize: DWORD): TJclRebaseImageInfo64;
 
-   function CalculateBaseAddress: TJclAddr64;
 
-   var
 
-     FirstChar: Char;
 
-     ModuleName: string;
 
-   begin
 
-     ModuleName := ExtractFileName(ImageName);
 
-     if Length(ModuleName) > 0 then
 
-       FirstChar := UpCase(ModuleName[1])
 
-     else
 
-       FirstChar := NativeNull;
 
-     if not CharIsUpper(FirstChar) then
 
-       FirstChar := 'A';
 
-     Result := $60000000 + (((Ord(FirstChar) - Ord('A')) div 3) * $1000000);
 
-     Result := Result shl 32;
 
-   end;
 
- begin
 
-   if NewBase = 0 then
 
-     NewBase := CalculateBaseAddress;
 
-   with Result do
 
-   begin
 
-     NewImageBase := NewBase;
 
-     // OF: possible loss of data
 
-     Win32Check(ReBaseImage64(PAnsiChar(AnsiString(ImageName)), nil, True, False, False, MaxNewSize,
 
-       OldImageSize, OldImageBase, NewImageSize, NewImageBase, TimeStamp));
 
-   end;
 
- end;
 
- function PeUpdateLinkerTimeStamp(const FileName: TFileName; const Time: TDateTime): Boolean;
 
- var
 
-   Mapping: TJclFileMapping;
 
-   View: TJclFileMappingView;
 
-   Headers: PImageNtHeaders32; // works with 64-bit binaries too
 
-                               // only the optional field differs
 
- begin
 
-   Mapping := TJclFileMapping.Create(FileName, fmOpenReadWrite, '', PAGE_READWRITE, 0, nil);
 
-   try
 
-     View := TJclFileMappingView.Create(Mapping, FILE_MAP_WRITE, 0, 0);
 
-     Headers := PeMapImgNtHeaders32(View.Memory);
 
-     Result := (Headers <> nil);
 
-     if Result then
 
-       Headers^.FileHeader.TimeDateStamp := TJclPeImage.DateTimeToStamp(Time);
 
-   finally
 
-     Mapping.Free;
 
-   end;
 
- end;
 
- function PeReadLinkerTimeStamp(const FileName: TFileName): TDateTime;
 
- var
 
-   Mapping: TJclFileMappingStream;
 
-   Headers: PImageNtHeaders32; // works with 64-bit binaries too
 
-                               // only the optional field differs
 
- begin
 
-   Mapping := TJclFileMappingStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
 
-   try
 
-     Headers := PeMapImgNtHeaders32(Mapping.Memory);
 
-     if Headers <> nil then
 
-       Result := TJclPeImage.StampToDateTime(Headers^.FileHeader.TimeDateStamp)
 
-     else
 
-       Result := -1;
 
-   finally
 
-     Mapping.Free;
 
-   end;
 
- end;
 
- { TODO -cHelp : Author: Uwe Schuster(just a generic version of JclDebug.InsertDebugDataIntoExecutableFile) }
 
- function PeInsertSection(const FileName: TFileName; SectionStream: TStream; SectionName: string): Boolean;
 
-   procedure RoundUpToAlignment(var Value: DWORD; Alignment: DWORD);
 
-   begin
 
-     if (Value mod Alignment) <> 0 then
 
-       Value := ((Value div Alignment) + 1) * Alignment;
 
-   end;
 
-   function PeInsertSection32(ImageStream: TMemoryStream): Boolean;
 
-   var
 
-     NtHeaders: PImageNtHeaders32;
 
-     Sections, LastSection, NewSection: PImageSectionHeader;
 
-     VirtualAlignedSize: DWORD;
 
-     I, X, NeedFill: Integer;
 
-     SectionDataSize: Integer;
 
-     UTF8Name: TUTF8String;
 
-   begin
 
-     Result := True;
 
-     try
 
-       SectionDataSize := SectionStream.Size;
 
-       NtHeaders := PeMapImgNtHeaders32(ImageStream.Memory);
 
-       Assert(NtHeaders <> nil);
 
-       Sections := PeMapImgSections32(NtHeaders);
 
-       Assert(Sections <> nil);
 
-       // Check whether there is not a section with the name already. If so, return True (#0000069)
 
-       if PeMapImgFindSection32(NtHeaders, SectionName) <> nil then
 
-       begin
 
-         Result := True;
 
-         Exit;
 
-       end;
 
-       LastSection := Sections;
 
-       Inc(LastSection, NtHeaders^.FileHeader.NumberOfSections - 1);
 
-       NewSection := LastSection;
 
-       Inc(NewSection);
 
-       // Increase the number of sections
 
-       Inc(NtHeaders^.FileHeader.NumberOfSections);
 
-       ResetMemory(NewSection^, SizeOf(TImageSectionHeader));
 
-       // JCLDEBUG Virtual Address
 
-       NewSection^.VirtualAddress := LastSection^.VirtualAddress + LastSection^.Misc.VirtualSize;
 
-       RoundUpToAlignment(NewSection^.VirtualAddress, NtHeaders^.OptionalHeader.SectionAlignment);
 
-       // JCLDEBUG Physical Offset
 
-       NewSection^.PointerToRawData := LastSection^.PointerToRawData + LastSection^.SizeOfRawData;
 
-       RoundUpToAlignment(NewSection^.PointerToRawData, NtHeaders^.OptionalHeader.FileAlignment);
 
-       // JCLDEBUG Section name
 
-       if not TryStringToUTF8(SectionName, UTF8Name) then
 
-         UTF8Name := TUTF8String(SectionName);
 
-       StrPLCopyA(PAnsiChar(@NewSection^.Name), UTF8Name, IMAGE_SIZEOF_SHORT_NAME);
 
-       // JCLDEBUG Characteristics flags
 
-       NewSection^.Characteristics := IMAGE_SCN_MEM_READ or IMAGE_SCN_CNT_INITIALIZED_DATA;
 
-       // Size of virtual data area
 
-       NewSection^.Misc.VirtualSize := SectionDataSize;
 
-       VirtualAlignedSize := SectionDataSize;
 
-       RoundUpToAlignment(VirtualAlignedSize, NtHeaders^.OptionalHeader.SectionAlignment);
 
-       // Update Size of Image
 
-       Inc(NtHeaders^.OptionalHeader.SizeOfImage, VirtualAlignedSize);
 
-       // Raw data size
 
-       NewSection^.SizeOfRawData := SectionDataSize;
 
-       RoundUpToAlignment(NewSection^.SizeOfRawData, NtHeaders^.OptionalHeader.FileAlignment);
 
-       // Update Initialized data size
 
-       Inc(NtHeaders^.OptionalHeader.SizeOfInitializedData, NewSection^.SizeOfRawData);
 
-       // Fill data to alignment
 
-       NeedFill := INT_PTR(NewSection^.SizeOfRawData) - SectionDataSize;
 
-       // Note: Delphi linker seems to generate incorrect (unaligned) size of
 
-       // the executable when adding TD32 debug data so the position could be
 
-       // behind the size of the file then.
 
-       ImageStream.Seek(NewSection^.PointerToRawData, soBeginning);
 
-       ImageStream.CopyFrom(SectionStream, 0);
 
-       X := 0;
 
-       for I := 1 to NeedFill do
 
-         ImageStream.WriteBuffer(X, 1);
 
-     except
 
-       Result := False;
 
-     end;
 
-   end;
 
-   function PeInsertSection64(ImageStream: TMemoryStream): Boolean;
 
-   var
 
-     NtHeaders: PImageNtHeaders64;
 
-     Sections, LastSection, NewSection: PImageSectionHeader;
 
-     VirtualAlignedSize: DWORD;
 
-     I, X, NeedFill: Integer;
 
-     SectionDataSize: Integer;
 
-     UTF8Name: TUTF8String;
 
-   begin
 
-     Result := True;
 
-     try
 
-       SectionDataSize := SectionStream.Size;
 
-       NtHeaders := PeMapImgNtHeaders64(ImageStream.Memory);
 
-       Assert(NtHeaders <> nil);
 
-       Sections := PeMapImgSections64(NtHeaders);
 
-       Assert(Sections <> nil);
 
-       // Check whether there is not a section with the name already. If so, return True (#0000069)
 
-       if PeMapImgFindSection64(NtHeaders, SectionName) <> nil then
 
-       begin
 
-         Result := True;
 
-         Exit;
 
-       end;
 
-       LastSection := Sections;
 
-       Inc(LastSection, NtHeaders^.FileHeader.NumberOfSections - 1);
 
-       NewSection := LastSection;
 
-       Inc(NewSection);
 
-       // Increase the number of sections
 
-       Inc(NtHeaders^.FileHeader.NumberOfSections);
 
-       ResetMemory(NewSection^, SizeOf(TImageSectionHeader));
 
-       // JCLDEBUG Virtual Address
 
-       NewSection^.VirtualAddress := LastSection^.VirtualAddress + LastSection^.Misc.VirtualSize;
 
-       RoundUpToAlignment(NewSection^.VirtualAddress, NtHeaders^.OptionalHeader.SectionAlignment);
 
-       // JCLDEBUG Physical Offset
 
-       NewSection^.PointerToRawData := LastSection^.PointerToRawData + LastSection^.SizeOfRawData;
 
-       RoundUpToAlignment(NewSection^.PointerToRawData, NtHeaders^.OptionalHeader.FileAlignment);
 
-       // JCLDEBUG Section name
 
-       if not TryStringToUTF8(SectionName, UTF8Name) then
 
-         UTF8Name := TUTF8String(SectionName);
 
-       StrPLCopyA(PAnsiChar(@NewSection^.Name), UTF8Name, IMAGE_SIZEOF_SHORT_NAME);
 
-       // JCLDEBUG Characteristics flags
 
-       NewSection^.Characteristics := IMAGE_SCN_MEM_READ or IMAGE_SCN_CNT_INITIALIZED_DATA;
 
-       // Size of virtual data area
 
-       NewSection^.Misc.VirtualSize := SectionDataSize;
 
-       VirtualAlignedSize := SectionDataSize;
 
-       RoundUpToAlignment(VirtualAlignedSize, NtHeaders^.OptionalHeader.SectionAlignment);
 
-       // Update Size of Image
 
-       Inc(NtHeaders^.OptionalHeader.SizeOfImage, VirtualAlignedSize);
 
-       // Raw data size
 
-       NewSection^.SizeOfRawData := SectionDataSize;
 
-       RoundUpToAlignment(NewSection^.SizeOfRawData, NtHeaders^.OptionalHeader.FileAlignment);
 
-       // Update Initialized data size
 
-       Inc(NtHeaders^.OptionalHeader.SizeOfInitializedData, NewSection^.SizeOfRawData);
 
-       // Fill data to alignment
 
-       NeedFill := INT_PTR(NewSection^.SizeOfRawData) - SectionDataSize;
 
-       // Note: Delphi linker seems to generate incorrect (unaligned) size of
 
-       // the executable when adding TD32 debug data so the position could be
 
-       // behind the size of the file then.
 
-       ImageStream.Seek(NewSection^.PointerToRawData, soBeginning);
 
-       ImageStream.CopyFrom(SectionStream, 0);
 
-       X := 0;
 
-       for I := 1 to NeedFill do
 
-         ImageStream.WriteBuffer(X, 1);
 
-     except
 
-       Result := False;
 
-     end;
 
-   end;
 
- var
 
-   ImageStream: TMemoryStream;
 
- begin
 
-   Result := Assigned(SectionStream) and (SectionName <> '');
 
-   if not Result then
 
-     Exit;
 
-   ImageStream := TMemoryStream.Create;
 
-   try
 
-     ImageStream.LoadFromFile(FileName);
 
-     case PeMapImgTarget(ImageStream.Memory) of
 
-       taWin32:
 
-         Result := PeInsertSection32(ImageStream);
 
-       taWin64:
 
-         Result := PeInsertSection64(ImageStream);
 
-       //taUnknown:
 
-     else
 
-       Result := False;
 
-     end;
 
-     if Result then
 
-       ImageStream.SaveToFile(FileName);
 
-   finally
 
-     ImageStream.Free;
 
-   end;
 
- end;
 
- function PeVerifyCheckSum(const FileName: TFileName): Boolean;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-   try
 
-     Result := VerifyCheckSum;
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- function PeClearCheckSum(const FileName: TFileName): Boolean;
 
-   function PeClearCheckSum32(ModuleAddress: Pointer): Boolean;
 
-   var
 
-     Headers: PImageNtHeaders32;
 
-   begin
 
-     Headers := PeMapImgNtHeaders32(ModuleAddress);
 
-     Result := (Headers <> nil);
 
-     if Result then
 
-       Headers^.OptionalHeader.CheckSum := 0;
 
-   end;
 
-   function PeClearCheckSum64(ModuleAddress: Pointer): Boolean;
 
-   var
 
-     Headers: PImageNtHeaders64;
 
-   begin
 
-     Headers := PeMapImgNtHeaders64(ModuleAddress);
 
-     Result := (Headers <> nil);
 
-     if Result then
 
-       Headers^.OptionalHeader.CheckSum := 0;
 
-   end;
 
- var
 
-   Mapping: TJclFileMapping;
 
-   View: TJclFileMappingView;
 
- begin
 
-   Mapping := TJclFileMapping.Create(FileName, fmOpenReadWrite, '', PAGE_READWRITE, 0, nil);
 
-   try
 
-     View := TJclFileMappingView.Create(Mapping, FILE_MAP_WRITE, 0, 0);
 
-     case PeMapImgTarget(View.Memory) of
 
-       taWin32:
 
-         Result := PeClearCheckSum32(View.Memory);
 
-       taWin64:
 
-         Result := PeClearCheckSum64(View.Memory);
 
-       //taUnknown:
 
-     else
 
-       Result := False;
 
-     end;
 
-   finally
 
-     Mapping.Free;
 
-   end;
 
- end;
 
- function PeUpdateCheckSum(const FileName: TFileName): Boolean;
 
- var
 
-   LI: TLoadedImage;
 
- begin
 
-   LI.ModuleName := nil;
 
-   // OF: possible loss of data
 
-   Result := MapAndLoad(PAnsiChar(AnsiString(FileName)), nil, LI, True, False);
 
-   if Result then
 
-     Result := UnMapAndLoad(LI);
 
- end;
 
- // Various simple PE Image searching and listing routines
 
- function PeDoesExportFunction(const FileName: TFileName; const FunctionName: string;
 
-   Options: TJclSmartCompOptions): Boolean;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-   try
 
-     Result := StatusOK and Assigned(ExportList.SmartFindName(FunctionName, Options));
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- function PeIsExportFunctionForwardedEx(const FileName: TFileName; const FunctionName: string;
 
-   out ForwardedName: string; Options: TJclSmartCompOptions): Boolean;
 
- var
 
-   ExportItem: TJclPeExportFuncItem;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-   try
 
-     Result := StatusOK;
 
-     if Result then
 
-     begin
 
-       ExportItem := ExportList.SmartFindName(FunctionName, Options);
 
-       if ExportItem <> nil then
 
-       begin
 
-         Result := ExportItem.IsForwarded;
 
-         ForwardedName := ExportItem.ForwardedName;
 
-       end
 
-       else
 
-       begin
 
-         Result := False;
 
-         ForwardedName := '';
 
-       end;
 
-     end;
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- function PeIsExportFunctionForwarded(const FileName: TFileName; const FunctionName: string;
 
-   Options: TJclSmartCompOptions): Boolean;
 
- var
 
-   Dummy: string;
 
- begin
 
-   Result := PeIsExportFunctionForwardedEx(FileName, FunctionName, Dummy, Options);
 
- end;
 
- function PeDoesImportFunction(const FileName: TFileName; const FunctionName: string;
 
-   const LibraryName: string; Options: TJclSmartCompOptions): Boolean;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-   try
 
-     Result := StatusOK;
 
-     if Result then
 
-       with ImportList do
 
-       begin
 
-         TryGetNamesForOrdinalImports;
 
-         Result := SmartFindName(FunctionName, LibraryName, Options) <> nil;
 
-       end;
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- function PeDoesImportLibrary(const FileName: TFileName; const LibraryName: string;
 
-   Recursive: Boolean): Boolean;
 
- var
 
-   SL: TStringList;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-   try
 
-     Result := StatusOK;
 
-     if Result then
 
-     begin
 
-       SL := InternalImportedLibraries(FileName, Recursive, False, nil);
 
-       try
 
-         Result := SL.IndexOf(LibraryName) > -1;
 
-       finally
 
-         SL.Free;
 
-       end;
 
-     end;
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- function PeImportedLibraries(const FileName: TFileName; const LibrariesList: TStrings;
 
-   Recursive, FullPathName: Boolean): Boolean;
 
- var
 
-   SL: TStringList;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-   try
 
-     Result := StatusOK;
 
-     if Result then
 
-     begin
 
-       SL := InternalImportedLibraries(FileName, Recursive, FullPathName, nil);
 
-       try
 
-         LibrariesList.Assign(SL);
 
-       finally
 
-         SL.Free;
 
-       end;
 
-     end;
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- function PeImportedFunctions(const FileName: TFileName; const FunctionsList: TStrings;
 
-   const LibraryName: string; IncludeLibNames: Boolean): Boolean;
 
- var
 
-   I: Integer;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-     try
 
-       Result := StatusOK;
 
-       if Result then
 
-         with ImportList do
 
-         begin
 
-           TryGetNamesForOrdinalImports;
 
-           FunctionsList.BeginUpdate;
 
-           try
 
-             for I := 0 to AllItemCount - 1 do
 
-               with AllItems[I] do
 
-                 if ((Length(LibraryName) = 0) or StrSame(ImportLib.Name, LibraryName)) and
 
-                   (Name <> '') then
 
-                 begin
 
-                   if IncludeLibNames then
 
-                     FunctionsList.Add(ImportLib.Name + '=' + Name)
 
-                   else
 
-                     FunctionsList.Add(Name);
 
-                 end;
 
-           finally
 
-             FunctionsList.EndUpdate;
 
-           end;
 
-         end;
 
-     finally
 
-       Free;
 
-     end;
 
- end;
 
- function PeExportedFunctions(const FileName: TFileName; const FunctionsList: TStrings): Boolean;
 
- var
 
-   I: Integer;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-     try
 
-       Result := StatusOK;
 
-       if Result then
 
-       begin
 
-         FunctionsList.BeginUpdate;
 
-         try
 
-           with ExportList do
 
-             for I := 0 to Count - 1 do
 
-               with Items[I] do
 
-                 if not IsExportedVariable then
 
-                   FunctionsList.Add(Name);
 
-         finally
 
-           FunctionsList.EndUpdate;
 
-         end;
 
-       end;
 
-     finally
 
-       Free;
 
-     end;
 
- end;
 
- function PeExportedNames(const FileName: TFileName; const FunctionsList: TStrings): Boolean;
 
- var
 
-   I: Integer;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-   try
 
-     Result := StatusOK;
 
-     if Result then
 
-     begin
 
-       FunctionsList.BeginUpdate;
 
-       try
 
-         with ExportList do
 
-           for I := 0 to Count - 1 do
 
-             FunctionsList.Add(Items[I].Name);
 
-       finally
 
-         FunctionsList.EndUpdate;
 
-       end;
 
-     end;
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- function PeExportedVariables(const FileName: TFileName; const FunctionsList: TStrings): Boolean;
 
- var
 
-   I: Integer;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-   try
 
-     Result := StatusOK;
 
-     if Result then
 
-     begin
 
-       FunctionsList.BeginUpdate;
 
-       try
 
-         with ExportList do
 
-           for I := 0 to Count - 1 do
 
-             with Items[I] do
 
-               if IsExportedVariable then
 
-                 FunctionsList.AddObject(Name, Pointer(Address));
 
-       finally
 
-         FunctionsList.EndUpdate;
 
-       end;
 
-     end;
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- function PeResourceKindNames(const FileName: TFileName; ResourceType: TJclPeResourceKind;
 
-   const NamesList: TStrings): Boolean;
 
- begin
 
-   with CreatePeImage(FileName) do
 
-   try
 
-     Result := StatusOK and ResourceList.ListResourceNames(ResourceType, NamesList);
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- {$IFDEF BORLAND}
 
- function PeBorFormNames(const FileName: TFileName; const NamesList: TStrings): Boolean;
 
- var
 
-   I: Integer;
 
-   BorImage: TJclPeBorImage;
 
-   BorForm: TJclPeBorForm;
 
- begin
 
-   BorImage := TJclPeBorImage.Create(True);
 
-   try
 
-     BorImage.FileName := FileName;
 
-     Result := BorImage.IsBorlandImage;
 
-     if Result then
 
-     begin
 
-       NamesList.BeginUpdate;
 
-       try
 
-         for I := 0 to BorImage.FormCount - 1 do
 
-         begin
 
-           BorForm := BorImage.Forms[I];
 
-           NamesList.AddObject(BorForm.DisplayName, Pointer(BorForm.ResItem.RawEntryDataSize));
 
-         end;
 
-       finally
 
-         NamesList.EndUpdate;
 
-       end;
 
-     end;
 
-   finally
 
-     BorImage.Free;
 
-   end;
 
- end;
 
- function PeBorDependedPackages(const FileName: TFileName; PackagesList: TStrings;
 
-   FullPathName, Descriptions: Boolean): Boolean;
 
- var
 
-   BorImage: TJclPeBorImage;
 
- begin
 
-   BorImage := TJclPeBorImage.Create(True);
 
-   try
 
-     BorImage.FileName := FileName;
 
-     Result := BorImage.DependedPackages(PackagesList, FullPathName, Descriptions);
 
-   finally
 
-     BorImage.Free;
 
-   end;
 
- end;
 
- {$ENDIF BORLAND}
 
- // Missing imports checking routines
 
- function PeFindMissingImports(const FileName: TFileName; MissingImportsList: TStrings): Boolean;
 
- var
 
-   Cache: TJclPeImagesCache;
 
-   FileImage, LibImage: TJclPeImage;
 
-   L, I: Integer;
 
-   LibItem: TJclPeImportLibItem;
 
-   List: TStringList;
 
- begin
 
-   Result := False;
 
-   List := nil;
 
-   Cache := TJclPeImagesCache.Create;
 
-   try
 
-     List := TStringList.Create;
 
-     List.Duplicates := dupIgnore;
 
-     List.Sorted := True;
 
-     FileImage := Cache[FileName];
 
-     if FileImage.StatusOK then
 
-     begin
 
-       for L := 0 to FileImage.ImportList.Count - 1 do
 
-       begin
 
-         LibItem := FileImage.ImportList[L];
 
-         LibImage := Cache[LibItem.FileName];
 
-         if LibImage.StatusOK then
 
-         begin
 
-           LibImage.ExportList.PrepareForFastNameSearch;
 
-           for I := 0 to LibItem.Count - 1 do
 
-             if LibImage.ExportList.ItemFromName[LibItem[I].Name] = nil then
 
-               List.Add(LibItem.Name + '=' + LibItem[I].Name);
 
-         end
 
-         else
 
-           List.Add(LibItem.Name + '=');
 
-       end;
 
-       MissingImportsList.Assign(List);
 
-       Result := List.Count > 0;
 
-     end;
 
-   finally
 
-     List.Free;
 
-     Cache.Free;
 
-   end;
 
- end;
 
- function PeFindMissingImports(RequiredImportsList, MissingImportsList: TStrings): Boolean;
 
- var
 
-   Cache: TJclPeImagesCache;
 
-   LibImage: TJclPeImage;
 
-   I, SepPos: Integer;
 
-   List: TStringList;
 
-   S, LibName, ImportName: string;
 
- begin
 
-   List := nil;
 
-   Cache := TJclPeImagesCache.Create;
 
-   try
 
-     List := TStringList.Create;
 
-     List.Duplicates := dupIgnore;
 
-     List.Sorted := True;
 
-     for I := 0 to RequiredImportsList.Count - 1 do
 
-     begin
 
-       S := RequiredImportsList[I];
 
-       SepPos := Pos('=', S);
 
-       if SepPos = 0 then
 
-         Continue;
 
-       LibName := StrLeft(S, SepPos - 1);
 
-       LibImage := Cache[LibName];
 
-       if LibImage.StatusOK then
 
-       begin
 
-         LibImage.ExportList.PrepareForFastNameSearch;
 
-         ImportName := StrRestOf(S, SepPos + 1);
 
-         if LibImage.ExportList.ItemFromName[ImportName] = nil then
 
-           List.Add(LibName + '=' + ImportName);
 
-       end
 
-       else
 
-         List.Add(LibName + '=');
 
-     end;
 
-     MissingImportsList.Assign(List);
 
-     Result := List.Count > 0;
 
-   finally
 
-     List.Free;
 
-     Cache.Free;
 
-   end;
 
- end;
 
- function PeCreateRequiredImportList(const FileName: TFileName; RequiredImportsList: TStrings): Boolean;
 
- begin
 
-   Result := PeImportedFunctions(FileName, RequiredImportsList, '', True);
 
- end;
 
- // Mapped or loaded image related functions
 
- function PeMapImgNtHeaders32(const BaseAddress: Pointer): PImageNtHeaders32;
 
- begin
 
-   Result := nil;
 
-   if IsBadReadPtr(BaseAddress, SizeOf(TImageDosHeader)) then
 
-     Exit;
 
-   if (PImageDosHeader(BaseAddress)^.e_magic <> IMAGE_DOS_SIGNATURE) or
 
-     (PImageDosHeader(BaseAddress)^._lfanew = 0) then
 
-     Exit;
 
-   Result := PImageNtHeaders32(TJclAddr(BaseAddress) + DWORD(PImageDosHeader(BaseAddress)^._lfanew));
 
-   if IsBadReadPtr(Result, SizeOf(TImageNtHeaders32)) or
 
-     (Result^.Signature <> IMAGE_NT_SIGNATURE) then
 
-       Result := nil
 
- end;
 
- function PeMapImgNtHeaders32(Stream: TStream; const BasePosition: Int64; out NtHeaders32: TImageNtHeaders32): Int64;
 
- var
 
-   ImageDosHeader: TImageDosHeader;
 
- begin
 
-   ResetMemory(NtHeaders32, SizeOf(NtHeaders32));
 
-   Result := -1;
 
-   if (Stream.Seek(BasePosition, soBeginning) <> BasePosition) or
 
-     (Stream.Read(ImageDosHeader, SizeOf(ImageDosHeader)) <> SizeOf(ImageDosHeader)) then
 
-     raise EJclPeImageError.CreateRes(@SReadError);
 
-   if (ImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE) or
 
-     (ImageDosHeader._lfanew = 0) then
 
-     Exit;
 
-   Result := BasePosition + DWORD(ImageDosHeader._lfanew);
 
-   if (Stream.Seek(Result, soBeginning) <> Result) or
 
-     (Stream.Read(NtHeaders32, SizeOf(NtHeaders32)) <> SizeOf(NtHeaders32)) then
 
-     raise EJclPeImageError.CreateRes(@SReadError);
 
-   if NtHeaders32.Signature <> IMAGE_NT_SIGNATURE then
 
-     Result := -1;
 
- end;
 
- function PeMapImgNtHeaders64(const BaseAddress: Pointer): PImageNtHeaders64;
 
- begin
 
-   Result := nil;
 
-   if IsBadReadPtr(BaseAddress, SizeOf(TImageDosHeader)) then
 
-     Exit;
 
-   if (PImageDosHeader(BaseAddress)^.e_magic <> IMAGE_DOS_SIGNATURE) or
 
-     (PImageDosHeader(BaseAddress)^._lfanew = 0) then
 
-     Exit;
 
-   Result := PImageNtHeaders64(TJclAddr(BaseAddress) + DWORD(PImageDosHeader(BaseAddress)^._lfanew));
 
-   if IsBadReadPtr(Result, SizeOf(TImageNtHeaders64)) or
 
-     (Result^.Signature <> IMAGE_NT_SIGNATURE) then
 
-       Result := nil
 
- end;
 
- function PeMapImgNtHeaders64(Stream: TStream; const BasePosition: Int64; out NtHeaders64: TImageNtHeaders64): Int64;
 
- var
 
-   ImageDosHeader: TImageDosHeader;
 
- begin
 
-   ResetMemory(NtHeaders64, SizeOf(NtHeaders64));
 
-   Result := -1;
 
-   if (Stream.Seek(BasePosition, soBeginning) <> BasePosition) or
 
-     (Stream.Read(ImageDosHeader, SizeOf(ImageDosHeader)) <> SizeOf(ImageDosHeader)) then
 
-     raise EJclPeImageError.CreateRes(@SReadError);
 
-   if (ImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE) or
 
-     (ImageDosHeader._lfanew = 0) then
 
-     Exit;
 
-   Result := BasePosition + DWORD(ImageDosHeader._lfanew);
 
-   if (Stream.Seek(Result, soBeginning) <> Result) or
 
-     (Stream.Read(NtHeaders64, SizeOf(NtHeaders64)) <> SizeOf(NtHeaders64)) then
 
-     raise EJclPeImageError.CreateRes(@SReadError);
 
-   if NtHeaders64.Signature <> IMAGE_NT_SIGNATURE then
 
-     Result := -1;
 
- end;
 
- function PeMapImgSize(const BaseAddress: Pointer): DWORD;
 
- begin
 
-   case PeMapImgTarget(BaseAddress) of
 
-     taWin32:
 
-       Result := PeMapImgSize32(BaseAddress);
 
-     taWin64:
 
-       Result := PeMapImgSize64(BaseAddress);
 
-     //taUnknown:
 
-   else
 
-     Result := 0;
 
-   end;
 
- end;
 
- function PeMapImgSize(Stream: TStream; const BasePosition: Int64): DWORD;
 
- begin
 
-   case PeMapImgTarget(Stream, BasePosition) of
 
-     taWin32:
 
-       Result := PeMapImgSize32(Stream, BasePosition);
 
-     taWin64:
 
-       Result := PeMapImgSize64(Stream, BasePosition);
 
-     //taUnknown:
 
-   else
 
-     Result := 0;
 
-   end;
 
- end;
 
- function PeMapImgSize32(const BaseAddress: Pointer): DWORD;
 
- var
 
-   NtHeaders32: PImageNtHeaders32;
 
- begin
 
-   Result := 0;
 
-   NtHeaders32 := PeMapImgNtHeaders32(BaseAddress);
 
-   if Assigned(NtHeaders32) then
 
-     Result := NtHeaders32^.OptionalHeader.SizeOfImage;
 
- end;
 
- function PeMapImgSize32(Stream: TStream; const BasePosition: Int64): DWORD;
 
- var
 
-   NtHeaders32: TImageNtHeaders32;
 
- begin
 
-   Result := 0;
 
-   if PeMapImgNtHeaders32(Stream, BasePosition, NtHeaders32) <> -1 then
 
-     Result := NtHeaders32.OptionalHeader.SizeOfImage;
 
- end;
 
- function PeMapImgSize64(const BaseAddress: Pointer): DWORD;
 
- var
 
-   NtHeaders64: PImageNtHeaders64;
 
- begin
 
-   Result := 0;
 
-   NtHeaders64 := PeMapImgNtHeaders64(BaseAddress);
 
-   if Assigned(NtHeaders64) then
 
-     Result := NtHeaders64^.OptionalHeader.SizeOfImage;
 
- end;
 
- function PeMapImgSize64(Stream: TStream; const BasePosition: Int64): DWORD;
 
- var
 
-   NtHeaders64: TImageNtHeaders64;
 
- begin
 
-   Result := 0;
 
-   if PeMapImgNtHeaders64(Stream, BasePosition, NtHeaders64) <> -1 then
 
-     Result := NtHeaders64.OptionalHeader.SizeOfImage;
 
- end;
 
- function PeMapImgLibraryName(const BaseAddress: Pointer): string;
 
- begin
 
-   case PeMapImgTarget(BaseAddress) of
 
-     taWin32:
 
-       Result := PeMapImgLibraryName32(BaseAddress);
 
-     taWin64:
 
-       Result := PeMapImgLibraryName64(BaseAddress);
 
-     //taUnknown:
 
-   else
 
-     Result := '';
 
-   end;
 
- end;
 
- function PeMapImgLibraryName32(const BaseAddress: Pointer): string;
 
- var
 
-   NtHeaders: PImageNtHeaders32;
 
-   DataDir: TImageDataDirectory;
 
-   ExportDir: PImageExportDirectory;
 
-   UTF8Name: TUTF8String;
 
- begin
 
-   Result := '';
 
-   NtHeaders := PeMapImgNtHeaders32(BaseAddress);
 
-   if NtHeaders = nil then
 
-     Exit;
 
-   DataDir := NtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
 
-   if DataDir.Size = 0 then
 
-     Exit;
 
-   ExportDir := PImageExportDirectory(TJclAddr(BaseAddress) + DataDir.VirtualAddress);
 
-   if IsBadReadPtr(ExportDir, SizeOf(TImageExportDirectory)) or (ExportDir^.Name = 0) then
 
-     Exit;
 
-   UTF8Name := PAnsiChar(TJclAddr(BaseAddress) + ExportDir^.Name);
 
-   if not TryUTF8ToString(UTF8Name, Result) then
 
-     Result := string(UTF8Name);
 
- end;
 
- function PeMapImgLibraryName64(const BaseAddress: Pointer): string;
 
- var
 
-   NtHeaders: PImageNtHeaders64;
 
-   DataDir: TImageDataDirectory;
 
-   ExportDir: PImageExportDirectory;
 
-   UTF8Name: TUTF8String;
 
- begin
 
-   Result := '';
 
-   NtHeaders := PeMapImgNtHeaders64(BaseAddress);
 
-   if NtHeaders = nil then
 
-     Exit;
 
-   DataDir := NtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
 
-   if DataDir.Size = 0 then
 
-     Exit;
 
-   ExportDir := PImageExportDirectory(TJclAddr(BaseAddress) + DataDir.VirtualAddress);
 
-   if IsBadReadPtr(ExportDir, SizeOf(TImageExportDirectory)) or (ExportDir^.Name = 0) then
 
-     Exit;
 
-   UTF8Name := PAnsiChar(TJclAddr(BaseAddress) + ExportDir^.Name);
 
-   if not TryUTF8ToString(UTF8Name, Result) then
 
-     Result := string(UTF8Name);
 
- end;
 
- function PeMapImgTarget(const BaseAddress: Pointer): TJclPeTarget;
 
- var
 
-   ImageNtHeaders: PImageNtHeaders32;
 
- begin
 
-   Result := taUnknown;
 
-   ImageNtHeaders := PeMapImgNtHeaders32(BaseAddress);
 
-   if Assigned(ImageNtHeaders) then
 
-     case ImageNtHeaders.FileHeader.Machine of
 
-       IMAGE_FILE_MACHINE_I386:
 
-         Result := taWin32;
 
-       IMAGE_FILE_MACHINE_AMD64:
 
-         Result := taWin64;
 
-     end;
 
- end;
 
- function PeMapImgTarget(Stream: TStream; const BasePosition: Int64): TJclPeTarget;
 
- var
 
-   ImageNtHeaders: TImageNtHeaders32;
 
- begin
 
-   Result := taUnknown;
 
-   if PeMapImgNtHeaders32(Stream, BasePosition, ImageNtHeaders) <> -1 then
 
-   begin
 
-     case ImageNtHeaders.FileHeader.Machine of
 
-       IMAGE_FILE_MACHINE_I386:
 
-         Result := taWin32;
 
-       IMAGE_FILE_MACHINE_AMD64:
 
-         Result := taWin64;
 
-     end;
 
-   end;
 
- end;
 
- function PeMapImgSections32(NtHeaders: PImageNtHeaders32): PImageSectionHeader;
 
- begin
 
-   if NtHeaders = nil then
 
-     Result := nil
 
-   else
 
-     Result := PImageSectionHeader(TJclAddr(@NtHeaders^.OptionalHeader) +
 
-       NtHeaders^.FileHeader.SizeOfOptionalHeader);
 
- end;
 
- function PeMapImgSections32(Stream: TStream; const NtHeaders32Position: Int64; const NtHeaders32: TImageNtHeaders32;
 
-   out ImageSectionHeaders: TImageSectionHeaderArray): Int64;
 
- var
 
-   SectionSize: Integer;
 
- begin
 
-   if NtHeaders32Position = -1 then
 
-   begin
 
-     SetLength(ImageSectionHeaders, 0);
 
-     Result := -1;
 
-   end
 
-   else
 
-   begin
 
-     SetLength(ImageSectionHeaders, NtHeaders32.FileHeader.NumberOfSections);
 
-     Result := NtHeaders32Position + SizeOf(NtHeaders32.Signature) + SizeOf(NtHeaders32.FileHeader) + NtHeaders32.FileHeader.SizeOfOptionalHeader;
 
-     SectionSize := SizeOf(ImageSectionHeaders[0]) * Length(ImageSectionHeaders);
 
-     if (Stream.Seek(Result, soBeginning) <> Result) or
 
-       (Stream.Read(ImageSectionHeaders[0], SectionSize) <> SectionSize) then
 
-       raise EJclPeImageError.CreateRes(@SReadError);
 
-   end;
 
- end;
 
- function PeMapImgSections64(NtHeaders: PImageNtHeaders64): PImageSectionHeader;
 
- begin
 
-   if NtHeaders = nil then
 
-     Result := nil
 
-   else
 
-     Result := PImageSectionHeader(TJclAddr(@NtHeaders^.OptionalHeader) +
 
-       NtHeaders^.FileHeader.SizeOfOptionalHeader);
 
- end;
 
- function PeMapImgSections64(Stream: TStream; const NtHeaders64Position: Int64; const NtHeaders64: TImageNtHeaders64;
 
-   out ImageSectionHeaders: TImageSectionHeaderArray): Int64;
 
- var
 
-   SectionSize: Integer;
 
- begin
 
-   if NtHeaders64Position = -1 then
 
-   begin
 
-     SetLength(ImageSectionHeaders, 0);
 
-     Result := -1;
 
-   end
 
-   else
 
-   begin
 
-     SetLength(ImageSectionHeaders, NtHeaders64.FileHeader.NumberOfSections);
 
-     Result := NtHeaders64Position + SizeOf(NtHeaders64.Signature) + SizeOf(NtHeaders64.FileHeader) + NtHeaders64.FileHeader.SizeOfOptionalHeader;
 
-     SectionSize := SizeOf(ImageSectionHeaders[0]) * Length(ImageSectionHeaders);
 
-     if (Stream.Seek(Result, soBeginning) <> Result) or
 
-       (Stream.Read(ImageSectionHeaders[0], SectionSize) <> SectionSize) then
 
-       raise EJclPeImageError.CreateRes(@SReadError);
 
-   end;
 
- end;
 
- function PeMapImgFindSection32(NtHeaders: PImageNtHeaders32;
 
-   const SectionName: string): PImageSectionHeader;
 
- var
 
-   Header: PImageSectionHeader;
 
-   I: Integer;
 
-   P: PAnsiChar;
 
-   UTF8Name: TUTF8String;
 
- begin
 
-   Result := nil;
 
-   if NtHeaders <> nil then
 
-   begin
 
-     if not TryStringToUTF8(SectionName, UTF8Name) then
 
-       UTF8Name := TUTF8String(SectionName);
 
-     P := PAnsiChar(UTF8Name);
 
-     Header := PeMapImgSections32(NtHeaders);
 
-     for I := 1 to NtHeaders^.FileHeader.NumberOfSections do
 
-       if StrLCompA(PAnsiChar(@Header^.Name), P, IMAGE_SIZEOF_SHORT_NAME) = 0 then
 
-       begin
 
-         Result := Header;
 
-         Break;
 
-       end
 
-       else
 
-         Inc(Header);
 
-   end;
 
- end;
 
- function PeMapImgFindSection64(NtHeaders: PImageNtHeaders64;
 
-   const SectionName: string): PImageSectionHeader;
 
- var
 
-   Header: PImageSectionHeader;
 
-   I: Integer;
 
-   P: PAnsiChar;
 
-   UTF8Name: TUTF8String;
 
- begin
 
-   Result := nil;
 
-   if NtHeaders <> nil then
 
-   begin
 
-     if not TryStringToUTF8(SectionName, UTF8Name) then
 
-       UTF8Name := TUTF8String(SectionName);
 
-     P := PAnsiChar(UTF8Name);
 
-     Header := PeMapImgSections64(NtHeaders);
 
-     for I := 1 to NtHeaders^.FileHeader.NumberOfSections do
 
-       if StrLCompA(PAnsiChar(@Header^.Name), P, IMAGE_SIZEOF_SHORT_NAME) = 0 then
 
-       begin
 
-         Result := Header;
 
-         Break;
 
-       end
 
-       else
 
-         Inc(Header);
 
-   end;
 
- end;
 
- function PeMapImgFindSection(const ImageSectionHeaders: TImageSectionHeaderArray;
 
-   const SectionName: string): SizeInt;
 
- var
 
-   P: PAnsiChar;
 
-   UTF8Name: TUTF8String;
 
- begin
 
-   if Length(ImageSectionHeaders) > 0 then
 
-   begin
 
-     if not TryStringToUTF8(SectionName, UTF8Name) then
 
-       UTF8Name := TUTF8String(SectionName);
 
-     P := PAnsiChar(UTF8Name);
 
-     for Result := Low(ImageSectionHeaders) to High(ImageSectionHeaders) do
 
-       if StrLCompA(PAnsiChar(@ImageSectionHeaders[Result].Name), P, IMAGE_SIZEOF_SHORT_NAME) = 0 then
 
-         Exit;
 
-   end;
 
-   Result := -1;
 
- end;
 
- function PeMapImgFindSectionFromModule(const BaseAddress: Pointer;
 
-   const SectionName: string): PImageSectionHeader;
 
-   function PeMapImgFindSectionFromModule32(const BaseAddress: Pointer;
 
-     const SectionName: string): PImageSectionHeader;
 
-   var
 
-     NtHeaders32: PImageNtHeaders32;
 
-   begin
 
-     Result := nil;
 
-     NtHeaders32 := PeMapImgNtHeaders32(BaseAddress);
 
-     if Assigned(NtHeaders32) then
 
-       Result := PeMapImgFindSection32(NtHeaders32, SectionName);
 
-   end;
 
-   function PeMapImgFindSectionFromModule64(const BaseAddress: Pointer;
 
-     const SectionName: string): PImageSectionHeader;
 
-   var
 
-     NtHeaders64: PImageNtHeaders64;
 
-   begin
 
-     Result := nil;
 
-     NtHeaders64 := PeMapImgNtHeaders64(BaseAddress);
 
-     if Assigned(NtHeaders64) then
 
-       Result := PeMapImgFindSection64(NtHeaders64, SectionName);
 
-   end;
 
- begin
 
-   case PeMapImgTarget(BaseAddress) of
 
-     taWin32:
 
-       Result := PeMapImgFindSectionFromModule32(BaseAddress, SectionName);
 
-     taWin64:
 
-       Result := PeMapImgFindSectionFromModule64(BaseAddress, SectionName);
 
-     //taUnknown:
 
-   else
 
-     Result := nil;
 
-   end;
 
- end;
 
- function PeMapImgExportedVariables(const Module: HMODULE; const VariablesList: TStrings): Boolean;
 
- var
 
-   I: Integer;
 
- begin
 
-   with TJclPeImage.Create(True) do
 
-   try
 
-     AttachLoadedModule(Module);
 
-     Result := StatusOK;
 
-     if Result then
 
-     begin
 
-       VariablesList.BeginUpdate;
 
-       try
 
-         with ExportList do
 
-           for I := 0 to Count - 1 do
 
-             with Items[I] do
 
-               if IsExportedVariable then
 
-                 VariablesList.AddObject(Name, MappedAddress);
 
-       finally
 
-         VariablesList.EndUpdate;
 
-       end;
 
-     end;
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- function PeMapImgResolvePackageThunk(Address: Pointer): Pointer;
 
- {$IFDEF BORLAND}
 
- const
 
-   JmpInstructionCode = $25FF;
 
- type
 
-   PPackageThunk = ^TPackageThunk;
 
-   TPackageThunk = packed record
 
-     JmpInstruction: Word;
 
-     JmpAddress: PPointer;
 
-   end;
 
- begin
 
-   if not IsCompiledWithPackages then
 
-     Result := Address
 
-   else
 
-   if not IsBadReadPtr(Address, SizeOf(TPackageThunk)) and
 
-     (PPackageThunk(Address)^.JmpInstruction = JmpInstructionCode) then
 
-     Result := PPackageThunk(Address)^.JmpAddress^
 
-   else
 
-     Result := nil;
 
- end;
 
- {$ENDIF BORLAND}
 
- {$IFDEF FPC}
 
- begin
 
-   Result := Address;
 
- end;
 
- {$ENDIF FPC}
 
- function PeMapFindResource(const Module: HMODULE; const ResourceType: PChar;
 
-   const ResourceName: string): Pointer;
 
- var
 
-   ResItem: TJclPeResourceItem;
 
- begin
 
-   Result := nil;
 
-   with TJclPeImage.Create(True) do
 
-   try
 
-     AttachLoadedModule(Module);
 
-     if StatusOK then
 
-     begin
 
-       ResItem := ResourceList.FindResource(ResourceType, PChar(ResourceName));
 
-       if (ResItem <> nil) and ResItem.IsDirectory then
 
-         Result := ResItem.List[0].RawEntryData;
 
-     end;
 
-   finally
 
-     Free;
 
-   end;
 
- end;
 
- //=== { TJclPeSectionStream } ================================================
 
- constructor TJclPeSectionStream.Create(Instance: HMODULE; const ASectionName: string);
 
- begin
 
-   inherited Create;
 
-   Initialize(Instance, ASectionName);
 
- end;
 
- procedure TJclPeSectionStream.Initialize(Instance: HMODULE; const ASectionName: string);
 
- var
 
-   Header: PImageSectionHeader;
 
-   NtHeaders32: PImageNtHeaders32;
 
-   NtHeaders64: PImageNtHeaders64;
 
-   DataSize: Integer;
 
- begin
 
-   FInstance := Instance;
 
-   case PeMapImgTarget(Pointer(Instance)) of
 
-     taWin32:
 
-       begin
 
-         NtHeaders32 := PeMapImgNtHeaders32(Pointer(Instance));
 
-         if NtHeaders32 = nil then
 
-           raise EJclPeImageError.CreateRes(@RsPeNotPE);
 
-         Header := PeMapImgFindSection32(NtHeaders32, ASectionName);
 
-       end;
 
-     taWin64:
 
-       begin
 
-         NtHeaders64 := PeMapImgNtHeaders64(Pointer(Instance));
 
-         if NtHeaders64 = nil then
 
-           raise EJclPeImageError.CreateRes(@RsPeNotPE);
 
-         Header := PeMapImgFindSection64(NtHeaders64, ASectionName);
 
-       end;
 
-     //toUnknown:
 
-   else
 
-     raise EJclPeImageError.CreateRes(@RsPeUnknownTarget);
 
-   end;
 
-   if Header = nil then
 
-     raise EJclPeImageError.CreateResFmt(@RsPeSectionNotFound, [ASectionName]);
 
-   // Borland and Microsoft seems to have swapped the meaning of this items.
 
-   DataSize := Min(Header^.SizeOfRawData, Header^.Misc.VirtualSize);
 
-   SetPointer(Pointer(FInstance + Header^.VirtualAddress), DataSize);
 
-   FSectionHeader := Header^;
 
- end;
 
- function TJclPeSectionStream.Write(const Buffer; Count: Integer): Longint;
 
- begin
 
-   raise EJclPeImageError.CreateRes(@RsPeReadOnlyStream);
 
- end;
 
- //=== { TJclPeMapImgHookItem } ===============================================
 
- constructor TJclPeMapImgHookItem.Create(AList: TObjectList;
 
-   const AFunctionName: string; const AModuleName: string;
 
-   ABaseAddress, ANewAddress, AOriginalAddress: Pointer);
 
- begin
 
-   inherited Create;
 
-   FList := AList;
 
-   FFunctionName := AFunctionName;
 
-   FModuleName := AModuleName;
 
-   FBaseAddress := ABaseAddress;
 
-   FNewAddress := ANewAddress;
 
-   FOriginalAddress := AOriginalAddress;
 
- end;
 
- destructor TJclPeMapImgHookItem.Destroy;
 
- begin
 
-   if FBaseAddress <> nil then
 
-     InternalUnhook;
 
-   inherited Destroy;
 
- end;
 
- function TJclPeMapImgHookItem.InternalUnhook: Boolean;
 
- var
 
-   Buf: TMemoryBasicInformation;
 
- begin
 
-   Buf.AllocationBase := nil;
 
-   if (VirtualQuery(FBaseAddress, Buf, SizeOf(Buf)) = SizeOf(Buf)) and (Buf.State and MEM_FREE = 0) then
 
-     Result := TJclPeMapImgHooks.ReplaceImport(FBaseAddress, ModuleName, NewAddress, OriginalAddress)
 
-   else
 
-     Result := True; // PE image is not available anymore (DLL got unloaded)
 
-   if Result then
 
-     FBaseAddress := nil;
 
- end;
 
- function TJclPeMapImgHookItem.Unhook: Boolean;
 
- begin
 
-   Result := InternalUnhook;
 
-   if Result then
 
-     FList.Remove(Self);
 
- end;
 
- //=== { TJclPeMapImgHooks } ==================================================
 
- type
 
-   PWin9xDebugThunk32 = ^TWin9xDebugThunk32;
 
-   TWin9xDebugThunk32 = packed record
 
-     PUSH: Byte;    // PUSH instruction opcode ($68)
 
-     Addr: DWORD; // The actual address of the DLL routine
 
-     JMP: Byte;     // JMP instruction opcode ($E9)
 
-     Rel: DWORD;  // Relative displacement (a Kernel32 address)
 
-   end;
 
- function TJclPeMapImgHooks.GetItemFromNewAddress(NewAddress: Pointer): TJclPeMapImgHookItem;
 
- var
 
-   I: Integer;
 
- begin
 
-   Result := nil;
 
-   for I := 0 to Count - 1 do
 
-     if Items[I].NewAddress = NewAddress then
 
-     begin
 
-       Result := Items[I];
 
-       Break;
 
-     end;
 
- end;
 
- function TJclPeMapImgHooks.GetItemFromOriginalAddress(OriginalAddress: Pointer): TJclPeMapImgHookItem;
 
- var
 
-   I: Integer;
 
- begin
 
-   Result := nil;
 
-   for I := 0 to Count - 1 do
 
-     if Items[I].OriginalAddress = OriginalAddress then
 
-     begin
 
-       Result := Items[I];
 
-       Break;
 
-     end;
 
- end;
 
- function TJclPeMapImgHooks.GetItems(Index: Integer): TJclPeMapImgHookItem;
 
- begin
 
-   Result := TJclPeMapImgHookItem(Get(Index));
 
- end;
 
- function TJclPeMapImgHooks.HookImport(Base: Pointer; const ModuleName: string;
 
-   const FunctionName: string; NewAddress: Pointer; var OriginalAddress: Pointer): Boolean;
 
- var
 
-   ModuleHandle: THandle;
 
-   OriginalItem: TJclPeMapImgHookItem;
 
-   UTF8Name: TUTF8String;
 
- begin
 
-   ModuleHandle := GetModuleHandle(PChar(ModuleName));
 
-   Result := (ModuleHandle <> 0);
 
-   if not Result then
 
-   begin
 
-     SetLastError(ERROR_MOD_NOT_FOUND);
 
-     Exit;
 
-   end;
 
-   if not TryStringToUTF8(FunctionName, UTF8Name) then
 
-     UTF8Name := TUTF8String(FunctionName);
 
-   OriginalAddress := GetProcAddress(ModuleHandle, PAnsiChar(UTF8Name));
 
-   Result := (OriginalAddress <> nil);
 
-   if not Result then
 
-   begin
 
-     SetLastError(ERROR_PROC_NOT_FOUND);
 
-     Exit;
 
-   end;
 
-   OriginalItem := ItemFromOriginalAddress[OriginalAddress];
 
-   Result := ((OriginalItem = nil) or (OriginalItem.ModuleName = ModuleName)) and
 
-     (NewAddress <> nil) and (OriginalAddress <> NewAddress);
 
-   if not Result then
 
-   begin
 
-     SetLastError(ERROR_ALREADY_EXISTS);
 
-     Exit;
 
-   end;
 
-   if Result then
 
-     Result := ReplaceImport(Base, ModuleName, OriginalAddress, NewAddress);
 
-   if Result then
 
-   begin
 
-     Add(TJclPeMapImgHookItem.Create(Self, FunctionName, ModuleName, Base,
 
-       NewAddress, OriginalAddress));
 
-   end
 
-   else
 
-     SetLastError(ERROR_INVALID_PARAMETER);
 
- end;
 
- class function TJclPeMapImgHooks.IsWin9xDebugThunk(P: Pointer): Boolean;
 
- begin
 
-   with PWin9xDebugThunk32(P)^ do
 
-     Result := (PUSH = $68) and (JMP = $E9);
 
- end;
 
- class function TJclPeMapImgHooks.ReplaceImport(Base: Pointer; const ModuleName: string;
 
-   FromProc, ToProc: Pointer): Boolean;
 
- var
 
-   {$IFDEF CPU32}
 
-   FromProcDebugThunk32, ImportThunk32: PWin9xDebugThunk32;
 
-   IsThunked: Boolean;
 
-   NtHeader: PImageNtHeaders32;
 
-   ImportEntry: PImageThunkData32;
 
-   {$ENDIF CPU32}
 
-   {$IFDEF CPU64}
 
-   NtHeader: PImageNtHeaders64;
 
-   ImportEntry: PImageThunkData64;
 
-   {$ENDIF CPU64}
 
-   ImportDir: TImageDataDirectory;
 
-   ImportDesc: PImageImportDescriptor;
 
-   CurrName, RefName: PAnsiChar;
 
-   FoundProc: Boolean;
 
-   WrittenBytes: Cardinal;
 
-   UTF8Name: TUTF8String;
 
- begin
 
-   Result := False;
 
-   {$IFDEF CPU32}
 
-   FromProcDebugThunk32 := PWin9xDebugThunk32(FromProc);
 
-   IsThunked := (Win32Platform <> VER_PLATFORM_WIN32_NT) and IsWin9xDebugThunk(FromProcDebugThunk32);
 
-   NtHeader := PeMapImgNtHeaders32(Base);
 
-   {$ENDIF CPU32}
 
-   {$IFDEF CPU64}
 
-   NtHeader := PeMapImgNtHeaders64(Base);
 
-   {$ENDIF CPU64}
 
-   if NtHeader = nil then
 
-     Exit;
 
-   ImportDir := NtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
 
-   if ImportDir.VirtualAddress = 0 then
 
-     Exit;
 
-   ImportDesc := PImageImportDescriptor(TJclAddr(Base) + ImportDir.VirtualAddress);
 
-   if not TryStringToUTF8(ModuleName, UTF8Name) then
 
-     UTF8Name := TUTF8String(ModuleName);
 
-   RefName := PAnsiChar(UTF8Name);
 
-   while ImportDesc^.Name <> 0 do
 
-   begin
 
-     CurrName := PAnsiChar(Base) + ImportDesc^.Name;
 
-     if StrICompA(CurrName, RefName) = 0 then
 
-     begin
 
-       {$IFDEF CPU32}
 
-       ImportEntry := PImageThunkData32(TJclAddr(Base) + ImportDesc^.FirstThunk);
 
-       {$ENDIF CPU32}
 
-       {$IFDEF CPU64}
 
-       ImportEntry := PImageThunkData64(TJclAddr(Base) + ImportDesc^.FirstThunk);
 
-       {$ENDIF CPU64}
 
-       while ImportEntry^.Function_ <> 0 do
 
-       begin
 
-         {$IFDEF CPU32}
 
-         if IsThunked then
 
-         begin
 
-           ImportThunk32 := PWin9xDebugThunk32(ImportEntry^.Function_);
 
-           FoundProc := IsWin9xDebugThunk(ImportThunk32) and (ImportThunk32^.Addr = FromProcDebugThunk32^.Addr);
 
-         end
 
-         else
 
-         {$ENDIF CPU32}
 
-           FoundProc := Pointer(ImportEntry^.Function_) = FromProc;
 
-         if FoundProc then
 
-           Result := WriteProtectedMemory(@ImportEntry^.Function_, @ToProc, SizeOf(ToProc), WrittenBytes);
 
-         Inc(ImportEntry);
 
-       end;
 
-     end;
 
-     Inc(ImportDesc);
 
-   end;
 
- end;
 
- class function TJclPeMapImgHooks.SystemBase: Pointer;
 
- begin
 
-   Result := Pointer(SystemTObjectInstance);
 
- end;
 
- procedure TJclPeMapImgHooks.UnhookAll;
 
- var
 
-   I: Integer;
 
- begin
 
-   I := 0;
 
-   while I < Count do
 
-     if not Items[I].Unhook then
 
-       Inc(I);
 
- end;
 
- function TJclPeMapImgHooks.UnhookByNewAddress(NewAddress: Pointer): Boolean;
 
- var
 
-   Item: TJclPeMapImgHookItem;
 
- begin
 
-   Item := ItemFromNewAddress[NewAddress];
 
-   Result := (Item <> nil) and Item.Unhook;
 
- end;
 
- procedure TJclPeMapImgHooks.UnhookByBaseAddress(BaseAddress: Pointer);
 
- var
 
-   I: Integer;
 
- begin
 
-   for I := Count - 1 downto 0 do
 
-     if Items[I].BaseAddress = BaseAddress then
 
-       Items[I].Unhook;
 
- end;
 
- // Image access under a debbuger
 
- {$IFDEF USE_64BIT_TYPES}
 
- function InternalReadProcMem(ProcessHandle: THandle; Address: DWORD;
 
-   Buffer: Pointer; Size: SIZE_T): Boolean;
 
- var
 
-   BR: SIZE_T;
 
- {$ELSE}
 
- function InternalReadProcMem(ProcessHandle: THandle; Address: DWORD;
 
-   Buffer: Pointer; Size: Integer): Boolean;
 
- var
 
-   BR: DWORD;
 
- {$ENDIF}
 
- begin
 
-   BR := 0;
 
-   Result := ReadProcessMemory(ProcessHandle, Pointer(Address), Buffer, Size, BR);
 
- end;
 
- // TODO: 64 bit version
 
- function PeDbgImgNtHeaders32(ProcessHandle: THandle; BaseAddress: TJclAddr32;
 
-   var NtHeaders: TImageNtHeaders32): Boolean;
 
- var
 
-   DosHeader: TImageDosHeader;
 
- begin
 
-   Result := False;
 
-   ResetMemory(NtHeaders, SizeOf(NtHeaders));
 
-   ResetMemory(DosHeader, SizeOf(DosHeader));
 
-   if not InternalReadProcMem(ProcessHandle, TJclAddr32(BaseAddress), @DosHeader, SizeOf(DosHeader)) then
 
-     Exit;
 
-   if DosHeader.e_magic <> IMAGE_DOS_SIGNATURE then
 
-     Exit;
 
-   Result := InternalReadProcMem(ProcessHandle, TJclAddr32(BaseAddress) + TJclAddr32(DosHeader._lfanew),
 
-     @NtHeaders, SizeOf(TImageNtHeaders32));
 
- end;
 
- // TODO: 64 bit version
 
- function PeDbgImgLibraryName32(ProcessHandle: THandle; BaseAddress: TJclAddr32;
 
-   var Name: string): Boolean;
 
- var
 
-   NtHeaders32: TImageNtHeaders32;
 
-   DataDir: TImageDataDirectory;
 
-   ExportDir: TImageExportDirectory;
 
-   UTF8Name: TUTF8String;
 
- begin
 
-   Name := '';
 
-   NtHeaders32.Signature := 0;
 
-   Result := PeDbgImgNtHeaders32(ProcessHandle, BaseAddress, NtHeaders32);
 
-   if not Result then
 
-     Exit;
 
-   DataDir := NtHeaders32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
 
-   if DataDir.Size = 0 then
 
-     Exit;
 
-   if not InternalReadProcMem(ProcessHandle, TJclAddr(BaseAddress) + DataDir.VirtualAddress,
 
-     @ExportDir, SizeOf(ExportDir)) then
 
-     Exit;
 
-   if ExportDir.Name = 0 then
 
-     Exit;
 
-   SetLength(UTF8Name, MAX_PATH);
 
-   if InternalReadProcMem(ProcessHandle, TJclAddr(BaseAddress) + ExportDir.Name, PAnsiChar(UTF8Name), MAX_PATH) then
 
-   begin
 
-     StrResetLength(UTF8Name);
 
-     if not TryUTF8ToString(UTF8Name, Name) then
 
-       Name := string(UTF8Name);
 
-   end
 
-   else
 
-     Name := '';
 
- end;
 
- // Borland BPL packages name unmangling
 
- function PeBorUnmangleName(const Name: string; out Unmangled: string;
 
-   out Description: TJclBorUmDescription; out BasePos: Integer): TJclBorUmResult;
 
- var
 
-   NameP, NameU, NameUFirst: PAnsiChar;
 
-   QualifierFound, LinkProcFound: Boolean;
 
-   UTF8Unmangled, UTF8Name: TUTF8String;
 
-   procedure MarkQualifier;
 
-   begin
 
-     if not QualifierFound then
 
-     begin
 
-       QualifierFound := True;
 
-       BasePos := NameU - NameUFirst + 2;
 
-     end;
 
-   end;
 
-   procedure ReadSpecialSymbol;
 
-   var
 
-     SymbolLength: Integer;
 
-   begin
 
-     SymbolLength := 0;
 
-     while CharIsDigit(Char(NameP^)) do
 
-     begin
 
-       SymbolLength := SymbolLength * 10 + Ord(NameP^) - 48;
 
-       Inc(NameP);
 
-     end;
 
-     while (SymbolLength > 0) and (NameP^ <> #0) do
 
-     begin
 
-       if NameP^ = '@' then
 
-       begin
 
-         MarkQualifier;
 
-         NameU^ := '.';
 
-       end
 
-       else
 
-         NameU^ := NameP^;
 
-       Inc(NameP);
 
-       Inc(NameU);
 
-       Dec(SymbolLength);
 
-     end;
 
-   end;
 
-   procedure ReadRTTI;
 
-   begin
 
-     if StrLCompA(NameP, '$xp$', 4) = 0 then
 
-     begin
 
-       Inc(NameP, 4);
 
-       Description.Kind := skRTTI;
 
-       QualifierFound := False;
 
-       ReadSpecialSymbol;
 
-       if QualifierFound then
 
-         Include(Description.Modifiers, smQualified);
 
-     end
 
-     else
 
-       Result := urError;
 
-   end;
 
-   procedure ReadNameSymbol;
 
-   begin
 
-     if NameP^ = '@' then
 
-     begin
 
-       LinkProcFound := True;
 
-       Inc(NameP);
 
-     end;
 
-     while CharIsValidIdentifierLetter(Char(NameP^)) do
 
-     begin
 
-       NameU^ := NameP^;
 
-       Inc(NameP);
 
-       Inc(NameU);
 
-     end;
 
-   end;
 
-   procedure ReadName;
 
-   begin
 
-     Description.Kind := skData;
 
-     QualifierFound := False;
 
-     LinkProcFound := False;
 
-     repeat
 
-       ReadNameSymbol;
 
-       if LinkProcFound and not QualifierFound then
 
-         LinkProcFound := False;
 
-       case NameP^ of
 
-         '@':
 
-           case (NameP + 1)^ of
 
-             #0:
 
-               begin
 
-                 Description.Kind := skVTable;
 
-                 Break;
 
-               end;
 
-             '$':
 
-               begin
 
-                 if (NameP + 2)^ = 'b' then
 
-                 begin
 
-                   case (NameP + 3)^ of
 
-                     'c':
 
-                       Description.Kind := skConstructor;
 
-                     'd':
 
-                       Description.Kind := skDestructor;
 
-                   end;
 
-                   Inc(NameP, 6);
 
-                 end
 
-                 else
 
-                   Description.Kind := skFunction;
 
-                 Break; // no parameters unmangling yet
 
-               end;
 
-           else
 
-             MarkQualifier;
 
-             NameU^ := '.';
 
-             Inc(NameU);
 
-             Inc(NameP);
 
-           end;
 
-         '$':
 
-           begin
 
-             Description.Kind := skFunction;
 
-             Break; // no parameters unmangling yet
 
-           end;
 
-       else
 
-         Break;
 
-       end;
 
-     until False;
 
-     if QualifierFound then
 
-       Include(Description.Modifiers, smQualified);
 
-     if LinkProcFound then
 
-       Include(Description.Modifiers, smLinkProc);
 
-   end;
 
- begin
 
-   if not TryStringToUTF8(Name, UTF8Name) then
 
-     UTF8Name := TUTF8String(Name);
 
-   NameP := PAnsiChar(UTF8Name);
 
-   Result := urError;
 
-   case NameP^ of
 
-     '@':
 
-       Result := urOk;
 
-     '?':
 
-       Result := urMicrosoft;
 
-     '_', 'A'..'Z', 'a'..'z':
 
-       Result := urNotMangled;
 
-   end;
 
-   if Result <> urOk then
 
-     Exit;
 
-   Inc(NameP);
 
-   SetLength(UTF8UnMangled, 1024);
 
-   NameU := PAnsiChar(UTF8UnMangled);
 
-   NameUFirst := NameU;
 
-   Description.Modifiers := [];
 
-   BasePos := 1;
 
-   case NameP^ of
 
-     '$':
 
-       ReadRTTI;
 
-     '_', 'A'..'Z', 'a'..'z':
 
-       ReadName;
 
-   else
 
-     Result := urError;
 
-   end;
 
-   NameU^ := #0;
 
-   SetLength(UTF8Unmangled, StrLenA(PAnsiChar(UTF8Unmangled))); // SysUtils prefix due to compiler bug
 
-   if not TryUTF8ToString(UTF8Unmangled, Unmangled) then
 
-     Unmangled := string(UTF8Unmangled);
 
- end;
 
- function PeBorUnmangleName(const Name: string; out Unmangled: string;
 
-   out Description: TJclBorUmDescription): TJclBorUmResult;
 
- var
 
-   BasePos: Integer;
 
- begin
 
-   Result := PeBorUnmangleName(Name, Unmangled, Description, BasePos);
 
- end;
 
- function PeBorUnmangleName(const Name: string; out Unmangled: string): TJclBorUmResult;
 
- var
 
-   Description: TJclBorUmDescription;
 
-   BasePos: Integer;
 
- begin
 
-   Result := PeBorUnmangleName(Name, Unmangled, Description, BasePos);
 
- end;
 
- function PeBorUnmangleName(const Name: string): string;
 
- var
 
-   Unmangled: string;
 
-   Description: TJclBorUmDescription;
 
-   BasePos: Integer;
 
- begin
 
-   if PeBorUnmangleName(Name, Unmangled, Description, BasePos) = urOk then
 
-     Result := Unmangled
 
-   else
 
-     Result := '';
 
- end;
 
- function PeIsNameMangled(const Name: string): TJclPeUmResult;
 
- begin
 
-   Result := umNotMangled;
 
-   if Length(Name) > 0 then
 
-     case Name[1] of
 
-       '@':
 
-         Result := umBorland;
 
-       '?':
 
-         Result := umMicrosoft;
 
-     end;
 
- end;
 
- type
 
-   TUndecorateSymbolNameA = function (DecoratedName: PAnsiChar;
 
-     UnDecoratedName: PAnsiChar; UndecoratedLength: DWORD; Flags: DWORD): DWORD; stdcall;
 
- // 'imagehlp.dll' 'UnDecorateSymbolName'
 
-   TUndecorateSymbolNameW = function (DecoratedName: PWideChar;
 
-     UnDecoratedName: PWideChar; UndecoratedLength: DWORD; Flags: DWORD): DWORD; stdcall;
 
- // 'imagehlp.dll' 'UnDecorateSymbolNameW'
 
- var
 
-   UndecorateSymbolNameA: TUndecorateSymbolNameA = nil;
 
-   UndecorateSymbolNameAFailed: Boolean = False;
 
-   UndecorateSymbolNameW: TUndecorateSymbolNameW = nil;
 
-   UndecorateSymbolNameWFailed: Boolean = False;
 
- function UndecorateSymbolName(const DecoratedName: string; out UnMangled: string; Flags: DWORD): Boolean;
 
- const
 
-   ModuleName = 'imagehlp.dll';
 
-   BufferSize = 512;
 
- var
 
-   ModuleHandle: HMODULE;
 
-   WideBuffer: WideString;
 
-   AnsiBuffer: AnsiString;
 
-   Res: DWORD;
 
- begin
 
-   Result := False;
 
-   if ((not Assigned(UndecorateSymbolNameA)) and (not UndecorateSymbolNameAFailed)) or
 
-      ((not Assigned(UndecorateSymbolNameW)) and (not UndecorateSymbolNameWFailed)) then
 
-   begin
 
-     ModuleHandle := GetModuleHandle(ModuleName);
 
-     if ModuleHandle = 0 then
 
-     begin
 
-       ModuleHandle := SafeLoadLibrary(ModuleName);
 
-       if ModuleHandle = 0 then
 
-         Exit;
 
-     end;
 
-     UndecorateSymbolNameA := GetProcAddress(ModuleHandle, 'UnDecorateSymbolName');
 
-     UndecorateSymbolNameAFailed := not Assigned(UndecorateSymbolNameA);
 
-     UndecorateSymbolNameW := GetProcAddress(ModuleHandle, 'UnDecorateSymbolNameW');
 
-     UndecorateSymbolNameWFailed := not Assigned(UndecorateSymbolNameW);
 
-   end;
 
-   if Assigned(UndecorateSymbolNameW) then
 
-   begin
 
-     SetLength(WideBuffer, BufferSize);
 
-     Res := UnDecorateSymbolNameW(PWideChar({$IFNDEF UNICODE}WideString{$ENDIF}(DecoratedName)), PWideChar(WideBuffer), BufferSize, Flags);
 
-     if Res > 0 then
 
-     begin
 
-       StrResetLength(WideBuffer);
 
-       UnMangled := string(WideBuffer);
 
-       Result := True;
 
-     end;
 
-   end
 
-   else
 
-   if Assigned(UndecorateSymbolNameA) then
 
-   begin
 
-     SetLength(AnsiBuffer, BufferSize);
 
-     Res := UnDecorateSymbolNameA(PAnsiChar(AnsiString(DecoratedName)), PAnsiChar(AnsiBuffer), BufferSize, Flags);
 
-     if Res > 0 then
 
-     begin
 
-       StrResetLength(AnsiBuffer);
 
-       UnMangled := string(AnsiBuffer);
 
-       Result := True;
 
-     end;
 
-   end;
 
-   // For some functions UnDecorateSymbolName returns 'long'
 
-   if Result and (UnMangled = 'long') then
 
-     UnMangled := DecoratedName;
 
- end;
 
- function PeUnmangleName(const Name: string; out Unmangled: string): TJclPeUmResult;
 
- begin
 
-   Result := umNotMangled;
 
-   case PeBorUnmangleName(Name, Unmangled) of
 
-     urOk:
 
-       Result := umBorland;
 
-     urMicrosoft:
 
-       if UndecorateSymbolName(Name, Unmangled, UNDNAME_NAME_ONLY) then
 
-         Result := umMicrosoft;
 
-   end;
 
-   if Result = umNotMangled then
 
-     Unmangled := Name;
 
- end;
 
- {$IFDEF UNITVERSIONING}
 
- initialization
 
-   RegisterUnitVersion(HInstance, UnitVersioning);
 
- finalization
 
-   UnregisterUnitVersion(HInstance);
 
- {$ENDIF UNITVERSIONING}
 
- end.
 
 
  |