From 9ecbff9ce6736a73cb020fe4860bd2d47f3ec968 Mon Sep 17 00:00:00 2001 From: longpanda Date: Sat, 4 Jul 2020 22:29:54 +0800 Subject: [PATCH] add GPT support --- INSTALL/Ventoy2Disk.exe | Bin 298496 -> 318976 bytes INSTALL/tool/VentoyWorker.sh | 58 +++- INSTALL/tool/ventoy_lib.sh | 108 ++++++- INSTALL/ventoy_pack.sh | 2 +- LANGUAGES/languages.ini | Bin 96532 -> 102112 bytes Ventoy2Disk/Ventoy2Disk/Language.h | 19 ++ Ventoy2Disk/Ventoy2Disk/PhyDrive.c | 182 +++++++++--- Ventoy2Disk/Ventoy2Disk/Utility.c | 139 ++++++++- Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c | 127 +++++--- Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h | 47 ++- Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc | Bin 10832 -> 11510 bytes Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj | 1 + .../Ventoy2Disk/Ventoy2Disk.vcxproj.filters | 3 + Ventoy2Disk/Ventoy2Disk/WinDialog.c | Bin 50772 -> 57956 bytes Ventoy2Disk/Ventoy2Disk/crc32.c | 275 ++++++++++++++++++ Ventoy2Disk/Ventoy2Disk/resource.h | Bin 3830 -> 4204 bytes 16 files changed, 852 insertions(+), 109 deletions(-) create mode 100644 Ventoy2Disk/Ventoy2Disk/crc32.c diff --git a/INSTALL/Ventoy2Disk.exe b/INSTALL/Ventoy2Disk.exe index 1539d7b0524af02374eaeb7b62135857f9e17278..f8b662d89efb00dab1e9de432e914b6240adb2a7 100644 GIT binary patch delta 79770 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 delta 60315 zcmb@v3qVxW_CJ2kFvy^TGb$(w2r4Ry4;0^s4#=RX;2<(+zHe$LvLc%?D{-J<)bTi8 z>S*J=*Y4G;-D_Pd$`_gs5ECpjQ?FWCQCS^@TU2CYlIQnX`^*4Z_y7C-zW*P3UTd$t z*V=2Zz4qFBuXCpONSESmoy*2+eB5&r(j9Au=kz&|JFzfu%=^(-SdHgW&8LN5vuj=9 zMRxtH(2Q&Bp6^+D?4G8=_wjrpcS2zfuJ7|77kIrIt{n|I`ZE8cTUSK>A`V@oi*H;=XynTEq_u&#kT%|&>+ooy?S&RVq3b( z2KdWA`B}KhOC2;Zqk23AAhGi_uD{$(!UP_NELm(@jHHYyIF$h}99NsPK+|Is;|QE_ zH;`>Tu5JEIly$|@<&QnUF%CI!%0&ZV#opI6Gx_I|bkA$2YwE`A&DKs1(&WeO^@har ze3^7am#Rq~A>Gz3&|HX+=7!GKjEIsBhb9GemO1G^p*D@!Lwcb7m2JQQrlje4)3Tpg{lVbJ%3F2@yggx=7<&AXCb=pw63#7$PVw%=<-X5}(p!GrS zbgh`96?q1lMIen^BSy@lEa&Z0#faJJU8FmV?mQ(YZ!3yBjMCkm+&S86QRC)u6*aC( zyMd6T#;^psC9fxZ0G_B(u&7=rvnqh|Khj3||AzCvcLON`iI+lvNhd!06(kD(p ze~cKxm_Kjt><*(lci5~qq*P-!2YYB=?Vh4_*F=H9FMCJ6vWFG`PWVy=RB!%`V`w#kE@oTmn>@Xp++!ek)QclQGns9v<DEzWRo|5e;gHXL+)ac82URDEp>YD~FZ6s6Lt|66k9!Uc21tmfqR96Kj zi!Q1gU<;Gqb0<}hW-pj4KUzon65c*O*P8FnYL?%>EiLR6sacvRo$DNa|BOVQxDzku z<{+b7$(YrPXTh$a^a4tdQ=1{FN`vbp9>#>&LwArQ-RFp<%OV#)Y5+-RqX09 zU$x}2TFEP=Z#wnVG#-*dIzJqH7+pv_MGO<0XXPHhD$2qI$(8K+%o!#BAA`8EuYK^X&hSCH)3R;{zYr+e-eEH4*Rug$Zo0>Gpb6|9wCj&L9 zqncbo5mb{8ezzt*wVtJW{WUogsEI+E&?P#Ano1rVDJ||2(d{N|oae96=>IOoX3Y2G zHHz=bk9U+jU3yI=yj=OpO=?o;r_C_g^Vdi)TcQ~HbKL5`GwG-g_THjZD;ITzY|hI6 zKu>GarvLnelYCvG+Y8;P8sW$#^$gEQI@}q^S^KsveXwWB9m9cO;??kat>IvBB*0a5!G9|GLIJNq zVNFO0I#=~eXwV1sT|Aan9#`1=AJtC&R-wg5YOs(4gMV3D}1LiX|{#ZJ<+FcV| zRxS0EBbjpW1~e6VdHc+ipI3Z?JNr<>0hW|} zUNkqbhMy92>gSuDyk?7>+gW-mvXA5cWqbHq+Jh<&<^TCgRAnEiN*fh9bHlF)tZeMv2nO0HZ`eK+#^P*LiDm(fE4A`MZ_v0Hzs_V)72z*0-= zGwwU|bJeo7uUR_+BBeiwHP9N)HAc=Br>xY&bgZTRWKoUB&yCVg-6ux1`$_O5FmfQ(1&$?a?umDq|0ktA3Fl>G2%jQ&M^)hMxdg&)OuECtfJvE$Cf!K50Uf zNi$@iR2*e?=>6Qfvzltm&BPN#F%t@4g;A!Z20Xt+96r&<7Bs1{3OTt*xDy zsds1UMEtMK7mIX#sRLDA4|Qkh-DaN)R`f3bB%k*W9vHEnPDuQvMB%{QibChHBuGWE z4H(PBV+#YX8_*5@YxyiaL|auC%4h0= z&Lvm6^O}huM*i*~h}_r7Mjj_Ri9XS+OFWU{Gfei4-9!`(rF&3o=P}kMw){Zr1`L!xb|!Vern% zRT!pe1hS2Q*;du^YzGVhm9{?jsPDS}1gw83^4)^)k`*#0%`r!k0zSzy!(+ioD=}7B ze>6DEwc_{gtdj&Y0Y;E3`SfI2Dak$G)TDo~cU$ZrzDpqUk4QQ)Bc0oRW`^`}-0ZF| zzu#sYV55K$qp5UXuil!+-m!Pvfm_tR_!-SSgKIm|-kj%|6tqECdfL|2vm~A~ zje7?k5gy?Y=`wNoHrsheu|0+UpcgOYz1u1Ca&tg$? zN~2*$qct~Q=6Xwu`*aCifDXodgS}7p8Lrb5euK2-og|&R~bpEN`wq}Ns*qE8Qskm zt3+G_#G=^s3{SE9gmY*ax&4!D;7+dW@Uy++p<)Q_*z9A{lS9X7aCu{BLb^(<$z9}Y zL#*oSP>Z#NRs%{FePiu28Q#9uDJ9 zu3rym9L8c#-o*k=eBZFE))6|h>hn-bjw%m#)dzHm)nFWhw z_KEL`x1FDdRDBopCSURm4JYTn5T`^ttL}*8?o8T{F=lq}6PoiWAFc>Z{+Jo~;pfq# zx@JNY&O5w4LNv?HN{!#$hN$L~kW%JfwRI~!Z$B~_#j3;48)BBjcfAUxQtcA(Bp0@H zy*4i8h+H(lULKC+E%8K^tWQ3D3|w&#w%gtqGw{2B z)fb^TGyScTcMc8I+B!|DE+fZ1P1B?{johYbn*2>8t4-5&xxZ-~;Jkym88R!n7U-pF z%QUivX?9PZC7Q3g^DWL3ygSe5%xi|l$5c75!83Js(EFl-nP9bj$nfgy_57*HK|Ca4 z>!$hGE~lsM~ECa;$x%lyRLU%eaM_gsIXS<6<=5-jvRbvua+r zDJ7)buNik!Doq)yQGSw+ryT0|z!Vb~cb|!y%MNMn_|ck$H>Km_vo$k*kqoJEnpba2 z!&1vNDL+YHrcTj(-y{v55FZsqVm?Qck@NOc=nuxLF1g}43{1SVe8N(`gLHmEistw# z$uKcjqr4$4nK*?E$ZHdG=)#)@TU0x8#hrIml|2gaWXT0w4xA55zQ1kEFk{SKWuZZv z$7acGjEM}ZsMwoTyJcA_tuaL{ErS+-sd`%hXV~>lsKE9Hw#8;8q@8` zIf}i>lRq1r%Ky3{?VNN@vnWThXMEgqV?9vFk#qS-L-U#m6KI~9v*kK@@1y32d5y)g z_v6e)KD?8RwFR>t3Nk1sH{WBOEkE{^^x2eonne~V^}gOQkGW3U8a8Ck9)I1Y8((kJ zj+gCEd0yCra^G5RkyhUq>6lCyo)=yL=y)(r$5vx7N&KNc$a5cOIH2w7naLXtOjQzV zXV?-5HK0jz=2v4m<2g?n54BPs4zW(n?rlvA7cfjpYO%1)ybfxec4NM+E5M*9-jbh{ zZr|5Ov*sHqZfdvqpI$<}VH-R%X3Gz;S+c!rMG%-H4Q4A47haO)PEFBdekE<4IEWx6^G1GXSUm(R!?=`+* zr%Elrrs~dsH}RL65D?|$8_bwLrLTbZrS>8$DvWT=u1uF!Pk+7p8(%0&P__7u+uYRU zeT*5NP2}s!Pk$k0WR207zL3^r^@)rEQu67bYImjyNZA>lO>CUdN{6z>X-d~*24bp4beKhZW zAzjE`tXW?tjhgWU-$i<5#;5!U$!&Q_^Jtxvlrwbl{7)4nb>_^)Y4#zWP2*t?9-Y-EmlS#fQYWG8e(PQ7oKzL8PJpG%kf}&$jIga+Pfx{d17BIxNU@p@6x0kPu`Up^To{|=E=G!U%n;% zob$3~U5@nknKLyN+oYQ_SMd|1$8yJLw&zMO=l0eV=Sc76{yCy=gE~_0M}Z#CD(H{= z!*|l^S(7yX`HxgJ>w!VSRmdA_Txjj=A%K>xN|2WXs)d*8K=A;uox-n{s(4KZK|&8)@OIAF>iw`;kpJ~T0fC{ zd_a}RmERD_Rf*g;b?;aANAZq;#fav&femA&#*T8b$(ArS<4DhSE zOYh{t0zHl7BODbO&gY(&iF`G7q4Aeuq#K@{iu;>YT0`jxY0#qn(J!{=umCS+opDt@+1c=Hdxl9nGlpmHNRKT_ zH*6P+c3GU4xtZ>wtMa}LQsts3e!FyaQ9}1^QCYhTdrt5l$SJieIvUo^My`}!3{Hy_ zvp70B8BeKLaB&#cCE(Us86v(5FA(d1=B-lR;@HL8l25~_PW~866j?{G0&hM?X|Y|GD{^B?F|9Y21iJ{lvIwg7j5X;v|ul}K5$ToLYt(dh{`sfd~m`~qn zLAixh6uzjgleu<4(K-8i(Y#%H_<>r@t<%!TC4>2`(gRD}OSg8(+vd*OCSFP9OlTQ8 z875!JotYzElH*Ue6g3exQ3Triq@W;myci4yz3a}}+U1;Ru1l;&8E$i({h(;xC1#b2 z^Un;(+CCs_A7oMiw;*Tf12MZi*(SwaE^}Z|vG4X|Pf_fZ@(-XPW^Ld5!P0e1-|v60 zR}QmLo}~502tDOF_aCGJ_8Z0TPQCi6wWD z*!H_5w*7|0wzeda$4egzqgzQl^-zF>z(_2=i$v}3lBoR+iQ2X#`lLwp56vR}(+YaF z%zDjjX1zy#x7Z`UDfUR)Vwa4QUMYz0_7~Uhbjz19?=3KQn@DM0(B5skY*wk1_V94c zOt_B^&(oymNEaTS@7QH{-F(uWwcTA*5p=?tSH}faxy_q971d=2of7SP&?!W7?UbL- z^`e_|iRR74Mc)JgYVX3E_XVL3Y!|bxqIV*H{h;LYKif|N&2`>pRLuLPIIDOdsHs?M z&bms;c}FN4rXJ$$s&Ay%m$%dI3M$$x9a?@vQ)rQ1dgPd9wMAO`=#c2Kp8NRqY06Z4 zQ~i*dOl(s0%JyU@uFvdxyv!oK{%HTPyO!0gy@PI-_e#Dz^>~ZoFKwh1_-~4T2{O3g zvteGn%URQ|fOnqbupE;w#~zmqkM)4j8u(bA=G9|T$zu^wFC1feXc?;V5XZ%F;vKhn zJ^D@2cIl1Ba;9$3TG#W zb~bl+lEys|?`ZBsi$w*zGVdF3$`3p;d>VSxEhP~69mh^g-A$A}6n+UpN$wYEAX6?2jyv=yHsba+?v(um7q2Ln z#jr7NV2!D&^ejd#X0&pwO2i&2gQbWJ6Y0k|E=OoaUaN8$drE|{gR%yf!XLE=zp5!> zDkWG@?ntUJ9J^5AZPdx3>}Lk?k}xliz``U502LLM-1WHQB820rTov`FnHFI=l00kx zEihT+1FM-AU5hL4w|S1}8c9PBG>R(3>?LForK$YcU zs8-mS9a5UTYdi_1!00I{g^pQpxr7UHZ%2j&>U^xv)6z5c?tQ@74r0{0lQ?&W5x+_V zQxuxEEs(!?N;+tNT+`f18o07&M?y7hu4HwSYb5K+gbBnEcwt#U9`g(A3!7`*>^`}2 z{s|+8ePf+`6VpQ0EeKKo#nUMfyE;inR>rn<(Q<@UBysar_m*pS6r~`^lB~#6ASdTZ zV}T}LiHPnDZOqRv2*Oi-fdWW4AnInhMeyOiAUt2NJVe!q#}nLuNU)b-Bmi576?TEb z^+s$bh-?Sm6S{@A`ezE~@}viz>^-^-=0(DMg<%qkMbwFDM&;b^l-ZOg9eJ`}Sev}z zR_VJZCu(+gmXcNt)l_tr7O(PXYCB7ftJY|)be0OA8l`z@wY2-GtrO(?ff1%!h^*48$%HZNiK_szoltrUOuV zF($((z58@rNClw`8Yunnbia^mbgvAMVxJi}NtH=6L23t(oOP2+PL&~NidxFXKcKAo zFd=$2F#e%pDEo~7GCxa+i0mwFd?w2A(-Uef?h$qp3cikRLpsuyaUJ0G58eZmtpLuv zr-~H>OuYxVo`4B$fY^Ys2#W~Xr45vTCIICt39M?+ecI2V&X?)ums!b@1`BKfZHO#i zovayrOxm$JBEf_jyFDk-@NQQH&T<|rB;4a7Wnl3I;D5SN`gC=aX6Fj&_Ue8i#U!Ph z{iTGWQJSqrX;IOjA(l}?7R!c0DcmtQ zXZ&31$Yi30Vp16S!Bvc+3ZrEw^m-fu5{n`EtzZJzj#$li;#hme$ZBQZTKRlQR666@#N1QrINzyp^gN#2)hWk zs*g0kBr{GGjamx!KvZ(M7OPN6NOSv0)g_4&>gav|3g7VJV<-V^)yJ#1r61dSIPVN! z6CvpC2Tm|>_VQ@H^$f9Ki4rl!C=GfxI-DuBTDnD;N4O_?OY@$M8onC$6*im<8C8}5 z!g@jwdou|XAAJ-wvCI4kT2qXfVw7HfHqN-4FtQnjR*9Gm-FbE_^#Hn0=Tf!^$g|?T zC$%Z3R@AgK6}b@>;TmQAtk+#l^}Z4ij+Pp-ilyqv0{B-Yhc5T`hg!rBl(2_>D|(}4uP8NNP0uMS(?yw%^=#KHe?)Kf*E?g(6AhWxDhLjaP{sCkz+`O zVcvnT<@!KF=y# zR5`TO_eUR>vew4Lsv>jmC+fmHUYkq!x zivIe83=g|0-y}$r*T;@N)&e+!0Y#h?4u2wE+)o*Usx2j_CvSBkeGe7UjuiA%m)&A4S!PFR3v}@4KUN zN5Io0OE*{Ey%d%4N1Cx!RwG3dHZd>Za4E84AN$aHDx&8GhzP68hSGMZYHMVP)vd+_ zrEZ9y;t#;kApnB~V+7)D!r&IQ0>m{scTqD|qC=Dq7)GG5_VSJOYGHrd6n}qfIFV;E zZ;}5^oMKqiVuCjo5mC+9U^wCdPiEZJm}wJ-JEa}N$suTBbtEi^!Rl@5QmIK@%%2q4Y<&PXKl-daUCG;>GARIjQ9j~9Y(YpJsI(OIPBQR2Wh=B zl91G(0op^dwHs@T*V}sdd$wYWhZu#eB(_Crpx;6^gYYk~L(o=7evWvbR{VucM~^g- zY@y<0g+l$44Qzg_yF^-bk(z-~+(}H=FrKNpvX&LDm6xxBol)bz5b?ACPb`k5COG~u zf=T{lLLL@*NqH=G8q00VA}m5F1vFGel3;YK#p}c2^w$J$E>Gt`n3G*lJIK7H*&||W9V_@9-fu=p}Pn+!tMcV z^o>K?=^+c<;!q{sO`W1o=iP_P}l%B72c z>>WIxX%ahL^T7)bX zk9oI6{#%3;`&>lSYAWMPECT|?-zU{+_>2Y8jOXGU#Gqo|ESk3|_A(T@jqtZJ{BSlD zV6}p3Cy#iUl|e4BM%FK60^3O`7{W`*a0#`Pbw09+_HvJTAL1S;S-gbJcrk0Y{Nw$U zCp^Wz&)|B4@SB03AP=StBgey-qv@@}HL^F|8GRiZ&>(Qs+`2AO*XI*VR2~>GazQl+ zYQk0++thDtk=Y)r5V;8G2M~#j2?J^Vd(eE*zR#20PA*K4);u5M$N&a26!Mb{O?&+X z;IMiLizxRZ2G-S>w*$@{Bcf%Ds{HYMR&94Xs`Ff=I!|d!?$iNc^{2vS${UZoJ6N^z z%4yyp#QoL8s?StI-am)SAt98clJ?+FV{p+TGn0iZclxa;E&>LvZ52f|18D1m<*``Y zKLlFR!_tuM|3wnZJ4tU!eW#tdOqQNjN|qTOJ>@Z1{Al>P5<9a$80G{=u1x2CFf0i6 z+3DIz8!yO(7*4S0wC4e$9S(G~<%la(L_;U3_vRt<2F#-r%-^ptA6QK+Ik7i)IQDFwn5fh*`g9wM>I9` zKhNheH|1Dzp|1`wB$wn9F2eZHjIAPTns{+K`2+Q zS9Kl(ye-C(2JD4O27%pJiZe@@e_nVV1!n>?8OA6&)YA471YT+a$Z$&Z^K)@fKxj+tP7zo#3?5_@L%RZtZgdp?{kLwN0nQB~{vHV7@ zht_m$!~Mi@^B_Zud;dl}oN|@ZWK6!clQ`BR+FDtulMi%<_v7%a-HL1$PbQYpR%(T7 z#7h|Q5<`j%KL{kLx zdJYQkY@sU3O)T(4TYQvN*gi>EPPr!_H!|+cP$EV^x3D+4o44sckndFQcJOwe;aIgr z*a*b+FOukFBk|;~zOMdp4=co4HOaIDfIT%=4-BNOE0ajgd! zZA)E-b(?4|6pJ_{F(qOOhz9Oy6$c2K-?ZM9*4A^}WsCMNAQEkD(PhXs`Mmu4C+f0} zzczx87`lPz8!#lqJ%EQ#*n<}If__7)Ajg8$#nN31NnhYLJOS$8Qnc(9D!kQ;_uLjTLL<6l@3b7 zzt+(~ZD=-RcwA&yXaj`CXV~t3twIiXE&Hj{2(zfbF|0s+{Xk*$l5_`_$W#Kq?N@D- z2W9(v(}3Sp$#_qd0yTP+4Ssh^u8bI{&@ssgGAz1-*4p58-t;gV%@+TxFx%9dWz%1w zN=HeRRP%=R6lZAV?ucANW2-qV!bvJ~DJxT#{PBj;7&1(y@SXmNMo?{1^3598Er1uAIuluP7~%2M^V=BVwyDCRrRg*9 zN*}92IQBrwh;mQ%s1?fTp%byeMrDx=vFbAWGdY0zmqOHS*pi0j!EAVzmhX;pe26g^ zZX-#P#^4t>;{gqTGY!ju(Rk`M5}jUo0{?Y#G<;f%$Egm+lQ0-Rp%wNK3s1BowBHQF z%+LJ&p%{Id9Lp=SDPvpxgJTKT{u-+#N)@M(fyLwp^Jlgp?moH|JkpB0f7tb*QjolV zO5XT>1Sq*B)f1FbgT`l~4!ZGRc1bTC@k;wPjeD*uNbZ^50OXn5*-k zvGE$mG`(TZJE3@8D)F52Lk{;Hs;+m)nJJ7w2H8fa)BJ-w#!ETqGp721@x8M;zGtay zUN42fJ^QJNJ&tUCL%U4&mI;Er);y{X;;qB=^wG+C54DK=IfhkeQAoDyrbDiu=wa=I zMSr6I6Wku?s~`5;A)N}qS|kmI?=V!O$V6DcIXtR3R3X8)r9m1pp^*p|GA1qC*LMw= zm#9tu+khEF9?$Q&SHf~)cQSZT8*xY*JWWl@o*AGP29gZ1(H#FuDFFX09u4MstS1W)hu$|NB+)ha5Yey zG1~_>hYBbSl8W}kIoQH6+xC&2qq&;EyS>BYEQVJlEnn?b&e{Gf*UMOuHQgp*W4E>R#)S$miv{dhr9 zNSe$?IspGH(Ab93pD|rQYu@EowAhRP=3A7_YTKd?|3nn_qK>H3@*+r!?*?ihFA4B( zaIK&QRutPf*j;7>eoyP$h&fz9iKVQ>z_yz(hG2yOD)O*)-;>8_aCM{J>?wy}4Vq0j*D|vX`Lsu&Tq9(d?zfYBEwLmn9BAp@UFo_ z`NB4W{tPig_$r?ebAnNddwuX+Hos@c;1(e$`>8fo;Rt1cwMG`Be`CwOtoY~}@KJ1^ zFUXW!#FDkAT(s|1e9A?Mu>SNkUqWatJOQx`@?cJqUyqH3RltiP@1REN zwkww5LcC{3YJ`qRmjE{l-I<7$FeDR4-&$ni6!Z%+2?@psr%VLcLq8a=K$ zO5TVEi##e%ihVme4f9E5KY_3a*0sDskW&OI^8k~#CZe5f)WmQX^Gj)v>+1RoMEFWI7dnKl6O`G{^4h%hHGa5v*{q zPR15F%9#kekdH#$)fQTD{2?i%W_S{9p%<70$||3nfu#$1%@o#$7E}-{;2{W=C?H3E zdxrE-&4{7?OpQP|g|0py`Jh!5^jwXCaaJWh3*DV0ex|0^@S)EW5)4uWI<`QHm~WAL z1c0+4_5d&#Kyl155TWzyrPiyTddP4uGuIb4o6fa&XAlvFTB ziSWV0a8({}1ndx3K>NeD>eskVAJ^l)BAfwy^^X7$M}T-gU>*P?2r$MEm^^ef7b|x8Y7W2X2HqoN8QD zb+C#>HXCXUZCy^%!Df}s=wXQfEiy`H-Wf4>H?pcqEzll^MfOdjW{9rOTqb&^LpsaA z0Y1}FWyu##-iv#N;YQZ?$QQ2On^rzen)`15MU8;VU-?L_^et-|d6Up07>q4~5$?Bq ziY4n>2DDNBWKjt{Wa7Hu7=$AgM>dXyI0|u;;CShf^u@c&lFIxm+SdFUb0fL`mt}?QbNPUs`phPk0Xc0x>~7w-TQcSs+hLmtH?Js_QqY@YsCf5A0Q> zY6Q?(^W_Vv((N;UP7H5dTBA30ZppOX>oGS#o^c3x673CEVKr6hwVP7q*$9U?lH%~H zk=N2dl7|unY0}c;csrI81Lm2WkF5n`$13BU@wF$vbd? zk9(?JvFG4fq@G%L0_PBqh!$23lY_}N;eh!hFi{`K`cymYXvUmccOIDEA=0mA-5uQJ zy@EE7pEa?XOOK!L=FlB8aTVoYqPn7joh#Y-Bs-sB=X30Qg`Kam^EGyEVCP15_OWv_ zJ9F55uddLsb2K~0v-56B)qvi%qbBa}ICdX3P2yg|%|0B5aa7_sh2sp4^Ej^H_!P%A z95-+@;<$;U83#rUd<4Xqy1QJOdZDMIu@d6P`>{X1L|TSsZC$?|1nL&q+4741Okq4A z@_E{1BomCq&O^oME#mDTU$V%N5Ds7-XEEgEZ&#LF6TG`z-3JtZJWk|(d`S(D1u-FH z78P0CBz=3Kcl4MEJeI$WVR4u<(|$CT#6Mtr(lOYK9(3_yY$cEdn7(2qf@3`sF)ajI zPKC_)QHuR{&yf|lr#J8-w7^hbEVKv&6xI`#@keTDd>SDfuPFl0%_|W)qqO4R16m>x zt?0R3ipO%cjyZzv5#*`(fm!$Dn`1}D|0A7S^Gq9ixFZ1&tfEB%Q5jJ#N2fAtjFBKc zkQD7t;#-pX2a@9aNnel0WM3WBy4D0=fyzUOTz&hR;H#wm_{&UTv{#n}q8;hwcqO73 zl@#JpiVF6J2gSqx7Dui|nhHkA7L4hniozHod5J##(Tf%CFRy@`ESQiaOkwF_7%{>Lz4Za+K02zrpo2tvGD(ti))(!Sy80 z#kcYdt|P!2|BAu257%VHvws{C$SO|G7s{zX8wxZW$i%DjSLtyndu(SBn&>GXPqcKd ze-sZ>*@I3)FIGCwnx%Lp`Yd?hLI!Ta=fH+S^dR9VmTEj*&I1*hGa84!5Y3pSX>Im&spg{?B zZGzXMFlaJc?@9;yh8JlqCYUmbo|#n2mTa7hZ+~ZBo^sAEl-welYG1U$Gm5~sif!FD zxH54&zSw3k9H_Jy4j_Ii?lBC?Pb>RL1H_}G6Q2FlaLiaZetb!=0734}cvfd}E#seO ztjdl+baE^+h3}v`_`CyTO%?bS5%?H_+wecnpP_~LMrxB&43FM7Csc|D9pT5zb5Kls zG?qVFm3Ie4xzMPUnuMEUX&~u#HNsDJAC+;gVV*XC@E;oROn2%|f_TOCu`M-OxmnHI z`if`W`;PjME}uRFCAA8LsHMB~s1G%lN2v@=&iuepZ~wr3l*$oV>4;LsJ?(YQhW2?5 z(h889QA}0?c}k8^%p|FA%~}C>^jEW%rcZRYqW6=b&SQnR<5qUFdNPZlH6-0rYi!OJ3G!}s}%<@?S9Nk!hF$>`6q_StdT9od5nyFh%H<#QYJ*3idg@IxP{oq z+g!(ppUJNCYX*p$Xopo@K^(i$MRm4?m{Lxx{-HihEOn7s+>B?@p<-^4v1*L{Bl&Mg zQXT8)9M9VIplb23M9(HFU49+&T%?zrGC=~0hbBD+*9{uY{Y^v=Rg^Hv-KpC;Cvrt0 zHIpeynnNHH@=dYVLl;C6tCadlh$CUNs%A9JLKG{Da;k*a0zWWHj36x#+q+J$(x$v` zGnz_HP!WhptY1iAm5{2*71p+x!;4>{}1#)?%| ze1@Z>IueL(srr+yf1tY%`y}UE%@7u6ALm>Z&f7;EqS$QDUKuc~S>gQSODgCs0*Q@* z$NiKh`tSvbtj1vC?>=`{qkWf{*F+UH`_fCQO;XCIeI3jj&d3X3BM3Y!i{j<6mD30yHn zpxg(cVoF897rp`wKK~=PGjpi~@@Pk4bjp{1&R`gF{ZzuYpkSCe>Y+qWo$~tQwe_$- zH2vB5S@(1u{6~*PDfvagYV4B_cs$Mcpg|5cd9W(4MH-qt8?#{mvHswri*SW%>moe( zDf-URH=o5sUj+=)wL0w5%hxd)!;X-BfOmUrgcMg7i4fkgbv+&bvt9h{b_w7MFdaTkW8Nk_Bm5IOY;>K64qvc!Ok*mNa&|=nEG;znbc+Vt9`KaML4EMr zU?mZGkS!8BQ^`4iohY8b*|2I=Z=~0X0{qnL+dKj8=MHPh%E$y(kt?V{;Jy*}MAhH2 zS6hyU#rdSQq)g}ivU^y`;BlPDEmJDQKc{d1HSLCXBlZBpfAKVV_h zFY-$*uSof<~Cbwn4z#Q~o3@{=4_d%LtbPtCB-XL^fwD7|B8q56 zIFdNCb!~am>ovqvfN>obr|LWV%K)skGI-<64?X~}z;B05qNOYdPq`$HyoTahv^@()fcxZp1RlF8pGssz@@d`asuMM)e3(L?3)~~YDxbg;Mc|&I zR3*!2e+4F0@j0Z zRe*+rm2MWh>{t7d)QWgzkX`^31hCE;0;@hs#5Sa`#_(&OMGY-hA}Wv|#9e-slm9uC z7}f4%(gVbSCPOsPQv~(D0wENlP}+>@NJ5R-2u_fetYDI_^Dj7+grQl?la{?!R3OZ7+>s^P^yL4{mtcpx~O77Hxn8D)!dFcCQV%-;N z*f<@}hiV^}mR%q1*al!LW1e-ZF^yE&6Rv_sWTP50jDq$;lM3QGLFO-#S1kVMUe}B) zcqRTQMS8nmq%iqBJjh7>Z&)2vd&9=3AQ9E= zR)R^vOV|vGv}F4E9rKyQ-MZqcpYPihBDegiJ^ju6RL|{#4&1glXi671H7Q zC>_<9?1A)2eUxJt*3&Q$s8fP(20|99<3Z-&T4hOt4V5g&G&7avX@ zbR-%fSrHL8jsl$HL!jV4psr$RNHp9QyvWhLtPLI{e+4z!V+qWTDXeO;ivBN*4NDJKq9JL6g1fa+_>5ho!mwZClU85+A%JZSjZJP9E{Qq5(&IRqM|0iwwdrkTUR>;~m=?{JUO{#Oyga~GVblsX?Fv7FG zv@3_1z@zZH10CUl)7Q@6>O&(M`(8i`(#qc;-GNd$Q<-|fZ;hlD|M3cIalg;ZRG4O- z%1AcgIoLo$0lIK=3H|N6(8XFgyaBvpdCXAycUCyt$Hl{(I1zoTOT!X4n)HvtLDR>WiLQw2@HmZdb>W59V_sfo)k zC=875M_7jIw1QbdGc2I3a2#V(C&R(B!30XFEqZlfNfioI7F?$_+LlF*z+@{2uhhVm zO6>$4GOYU!!n3V(`i!=iRC*oKu4mtnh-Vv7>Zeua(03#PIyubWmSlWcM;%&1s~!PO zXU!rXgd~~qV_6|h^%E3m;TLa6!*0hq?1p9Zanxi4-z`N)k zQ?x3M%i{d-lxmxiIg9wjNlG=oC`oR%9jhytlNh1E0L3Lv^qD25_iErDyYucevIWg1ZtP671a<GmSx+tNhf4A(At&21B)e z$584fG^%u(dzuy%e?2kV7?i!r`FW7@G-v;am74rH*!R4!9;nB|aq?u(CQY7kKl{=4&LV@_&;ju@AvlU z%BKab{>60g!LGbsqxsWpuRW6gXP?@i5s=}-ElvzC-wkHfFT-u*rJM1H^b^B#O$ zF6|nlc&xL*Zq35(8D0#XqQb;uyHUE+F`mPZa!if{<9O3;keZe+_rZ--j$w~F;Tmib z`-F-7+5zvZD1Ja}SA1<0Ixrr4RHCnbQ9vhEXutn>x8f5W^Xh&@kWAoLX9OK4ch^H< z%mowODbRgkBi;Q(cYElLKA8f=+=F}4#J4E%4NW936qq!^!9pU z_-+ouLVAqcOhxsSXZArWDPQ$`02KIQAN`8gCUx9w^ z*x;>uus$1Rm0c)f4oZ8uK14R+-W@52vI|}yoLe7mm6s5L{8KM9A8W*9Z=arE;sTq> zgwLlRS3)2)RRb00HG1v$c(ai1Cva5Ed4p)y^w=eSYF*(p{O{|E!v7yu^%|-=?*E{MZ7K*Z-Rr52#Q*d-zUO_(BcYf+_Zpp; zzuetboFTZgwJ8zdTcJ~(c3i>5HMtN!!SZk-6be6wqFtC0yk`p%BgAZ-nx0k&6?t!n zcW)fORR2>?(k@I`IQbcGd@sHq|H#2_&70^~Fm|{25Clu^Ddx&su zt2ed}9}&fp>~=9vhp(A;li!JMDazuV(TCp>HlP*qdX)G3KKzpK2a{pLvKkEseTIYW zJaaWU7I~KUp?H3B>`SN^W@jy%kC<)g#Ef`tey-J-dSuVRiGBG=njX7>h2QpCFn3|K zSVQLmy->Ugy1&@Ftv^4BU*oOo&yS?H$K@~CKA^t-Z-_fH;^!=Ky#o{Y9)@4Xaa=Vy zghkh^@=K$tyVu$8fm9uG-w{Q@j9QxN$tb|X7dG`$BM|BM!4pi!+74#Wb`Cqfy zTBz4Ih#$shdIt{Xqj1R_%qMAT_jp$g=9kg6ZZJP$a4p(PvGId&;8Q9xrmgZXc~BWo z9nD}Hu~W}tJ&dB(g)C`9_@U9Vk*u1bl)ls=dYX`)o8!;Qc{dK>XYhaVULC^s28|bn z^6R6C#N3-1ytddt-w8xOR<0lY`b_Vxp?tokY^L|up}dKhnwZ27>$I9?pjh5TW7Scu zS9?p6_(7VF276ym;(K>2L~UD|B+~m?5P z0Yyu)eLKpCT!Ehxk?S#1E2HF`8{Vgr`5w{6F6y*kJVUc}6A}PG2^1*nEl=j-G-En> z&nNTg4$BPmQCoL`u5uJ~g^0BW8N_4(G)L|P7KG`YVMa#aB)^A7!#GummvU!4oQ4l) z+>f5CjZY$kL4>dp2#8d{6aaX(D1q+e6ObhpOp9n5n#d3opB=3BN+bC0{gc2ZmOd%*MZG;NFR!elfVV0iulD2WGJI4koZ^c?Dm$heKmiMwSB% zfX_Yu8vQ~>(N*VnT6a)I81ObCK%F-w}>1KHv|Qz#wRGk7eUhtql-dwO`Mj^+Dn z#zc9a7|X}g^-p8@=)P1K+^nIvMB@m@p~s=c(Tr?OI2w9*KN`zV2`5xhq0%il=HV!e z@{StEFByL^no@rL5JXFHOY;dod$&~f5{bPl$N>yOE|YPu$IXan@1=2ktmb00_vdkZ z0$qEh@JW3M3B{}@TpU|*Y{#)1M>&oP9PdVZSEhh1mH0J48gMk@Fvc7_pTa-D_u4lH zuO~xFTtT?7h!pNXUs%_np^)~$#sZBz*=tSZ7vxIa*?VZZ0;BvckmtyAr$e&PNBP!d zN_k3G5GB7sDflQM6lmve>K}hW;X7wRE#<9fTZW~R&*RU$+(CljRV#Z;uDa?~OL2 zZ|{KjzBY~T<Mr)4z3@ZgwMuQ8BbDWR?M8@JV zV$q7BXHz=gwci6UgJ2cXDiVxwJPZqQBG;=t)aMr<#CldI?>p&yYKomCgWYx=%ue7< zYkD7)y&X{dp{g9Y^d~pKLVsYoydw^G$-(564yl8!9q}!xNV91vRf$-I zM5Ylt5`HhauqAm=n`ClL0|nT+1W=p}8Te)|reLc(c{gVA-E~R+EZ$e~R@RnK8SzWG$&9h(X5rpmY5-i+BAesCiPKQ-uk+RkUX8Des!>*fN(-)K3E;`6ql z!4M&i62+11MHZh>0T7}&)MA8_^t6-Y5db-aGYm#j2*89Z3`8|=0bOGts%;C1>q&)C zZCXG^1{%>86wg3o+JeS2(0B%N_&J-!V5YWc0t02V1+8bGDQ!X98EAT2Pz3{7+Jeq7 z(5yC~owM;E)Hx`jh5u%THm?nu5FJakT+|jchJlu}1jYWQifwuaewy`Xr9Pk}9WC`N{GqmIXto)6ql$bCco1+w_DKVv)O3BBfPpoi#@MsG83Hrd19)@2#E2 zFN0KuPUkaniphnb-9G2iYxoK-+z3pt!q_A{yU^C#xn?rJNC{s!SskR5=yWUN>D$@>HGC=@OlDAIDO6d@f>qwYX;GzEk?MqEkyLL+Rul1 zwb^_ZKG++Xjj6Nb9hVJPq|CcKoA0hE>*QUR%|FV=dT(Z9`ttXs-pCnPad_H0aR&dd zc+Gn)lf>;LSPedkhTqGxUz0lY!uNDUAf>t>Odd22)rWl+pA>+WGLkKH zjKKO^BtFF2XsBvuH#WPb!T03-U==6f{+S-bXl zpUdI@S9@$WqN0K#l9GbqU5lXx zt|pZ>mUno6TT-cznc_W~DW(-AB`MW0tf*m&vpH--`~F<58pm#=FFKh zXU^Qb=RI@Ib|o*<1LH{0fLCG^!y3Pl^Ivq4-JB6 z0M$X#GrN9mDvaAcNfLzzliR!dP+RaL?)a^h3&=cLB{Ji?T*5s^7gh0e?RXL~U^(gx zGcD{z=$fGt+nH4A3VH!SSp;d|dslde)=F=WCyAsNH6)PUdR7_p+9gR_ur6}<5Mtti z-rfK2Gqz#10y@*|p$&Y=(E2rnRqJVK0;K9VT^Znn>D3} zk;^GF9Ne1m+>8>kW&}4j|7ZO21g?X7ngTUSensVCwX-hDttJpZu$KTElC+9i5@B+= zK7r0nBqGV72NQ|jUeBsWpbx5OK0aILyZjN$?(<=aytXY1!lcVcDYXcn{$<`s=>w-% zD|@xlTTU^Le)Tbdd#)qS@aDJMU&Vo?m ze!}X4+^IOmWMRG8)f@<#!ynFiFiz63sIAo=YNi5xQ6)PKVXPZ)JfDM=@ZQOiFIIR` z%@*0h=)bHbko8L5c&#JfBUyU=K3-yaoC-{d&{@C4ciU2>v9N%gRs~l z(n;B!B%wK>x0E|YKk02uY0xQ7h9c!Op|t4A&~d|n(;{1~U{lW@o^>3(9cv~6jTOqT zvYCPv3Vkb?1kOSlED4`@X*A*$wP&Zaq~1LSV;qWwXT{P5R-6;;i5oFE;koxm9%taV zToy@LEKItMI*^*WgSlI8k*!ooJ#a3&r!oy4oPwcX0Ueh@^suxRrw|_2%lA^qFmL>% zs;eK8JZQUA(#`wnCn5Dzor+n-TeKvVjPc%w@5#9=)r0AsR1y_C2_g6lSxbH(_P&^J zEr@gkvX2fYWm#WGL2bqDVhxOqZlfeM`xu?jD}S~W0ar<2<1`1hlOiIW`7{Y>_Ye!< z?66Myg|2;?1a$oZ0T&d#a378Bq>p3|#%p}}gPz1;@BL3gczXM3R2TV@Y{6tFMdD8wrl5&F1n(;;La|G0ZLKAqWzRc z0?aIgH3=3Hqu3jo*Qw}As52rPIi10eSM?t6Jdy49v6DyyaZ^H7nL8P)Sa4twCtjKY zJL?VwJhDNud$uyEM8}Rv!~S)^Jv%66@)>;awFwt4@#cz7g{~Q|T=qxq#u&U{wv8pw zD6v<I&=yd92kr)M1Drll$_B{&Ff)7tkqLs5fAJ@%cqb5?E>Xk&=ukr(Ql`a zP#<;+zH5%6P*~ome>zcjVwY~wR^r_&xh2X6QqxIm0_;q>A(62b*y9i1^OoO(BQ-zPmkQ#XhjAJ z5Pw*V@hiy*^IHQMP>&r%%vMu2ouo!WU%;0P5;`Kg+;J|T#3%xhb=T=rh;JlW(Em{;&>^8L<8QLq=zxO z5~(G(rlyuu%s&)Ar|SHkY3oIUSnxkC>QzZIGKtEkY}n&_VOigiNlLh=3OZ;8dERr_ z@MwG(BERH~tW&LRW+cVc4`a&rxE=0-~Xlp3?KR5P6&5u{Q&Cz}Miv0Rm8laO94 zSF2)!lzU;ue}s`?8B?_F3j!oBXMDq_v^pC$B+L%8$yo2xpRj~6JSwCjI(#+>4`2zD z#CDCqq@yIUYoufJeTV-VWUy#9iV!THP5ehVuM!w8dgVQZ3Bd4TF20^T(Dpf`XBT$jgV?UhLcEhVv_8H?i$xm0 z4m1|Wy0K#|+CaR_h&G4;8m-{Ul#Yj62p&NPtPlA@*eupy7VWTae==o_AaH5`2J88VTv%N#Nc>v5Cjkgh@K z`xJS19h2&OkGAnWQONp2q~Isb{g{@{A;B#ATXRUaKz22Jf~`2VYdD%q(VuSlJ`QiT z{P*=7tYgJ?pdoWfH~F4RMg{UHXU8PTJk&c6^WcYc%v`dNrF3yFIV9hj>xSfO`LKM` zHMt~+McJ22`h?0C!^>V?xSYGg8~1>V5B)>FxO_)H<&q2*d&0A%UsqOg+3u6g=TXt; zUwvGsv{xy8mUQprk08{k=qE=m(CTNgH|hVpUb1(>|7pF19sRHCCC3xx1&K;_919a7 z<7I?3LxLwb*Gu+JaITkt@_GqN3=0!mfz^=ZkR^~jNDd?ek~YD)Uc#a}T3G5;kjs$z z3C{JB*yP9SCHIs5x9cTwID~Am$fYT8FM;e#a;}%eCOg+lKzY4{MMAck5k&!~C&UjD z2nmHmK+MU`^%CdB6A_XI$$=CmSDaozGKr~_^+@q}E%x6%k^^%G^Z}KCt4Cr39qW-O z=;n4KiOm-s(AoAyzU)00Rw{c9E$T7M`Y9)mxD-j2(0 zPYxF&1j>{2E_Oz;F}$(~W^9SQa2H<~ZSKw&A z>jjTvMFez4XKS6hlvMpIsmSL^Qv1cHTc3g?o~CP`Cwu-CC)!TFXBitNe`mD zi}LV|f9ZN1n@zappt6Fq`~?#4#&oF9ULfWkwX8;F*8gXXEc-yNA|Fvzk!$SvZ}l%3 zv0U}<%8372|0dwDYfS6%fn5KBx{hYbqV)Z7Ir)Gm5jN9bib$VM-{64rly(;y7ve2| z`+ju5a?(%!g`Rln1v+s#2}&uJW3h3T6;F`ke9^Z(PBpuq`nHX{3nNBRn87RmM!!4J z^_{f9tY&tfSHD7jue6lp*OuhhIhJ}BwLHoXl-eLQ+=Zk*PCr^s0<0Km6~09;BX!3G zq*^kx!EvkTPLES}T2n_03}iY%UT(5vifg@ZL{qXcpw|l0tNnZLx88@e=zThF1sUu= z0zvFD`A-i0Mc1uBr5W-*J-&i;?|WaaH2J=*dA>$>6%p}$RoD^KN*o* zK;K%0O*aM1Q&2#!tirM^764&-Pm-QxnPAq5><-eHeR%FI+TY4?&^a@~tTrk61oJx{ zB{+IuD@H((9l7rS`(GV0lOT0`6@}Or`sM}CWi2(E@rHQqM7#r>=Tr2&l3)s;cSbBa z@44)eeE2qdQNq)nmBI?w6RLEPg{?{}&>#YiLb2{HJp(v5WA5F{IuSG&%}rzQ-z*#X zY1x621D$!QY;*FJh96;N#neo6WHFd)cZF7(S~BTj>j{C*nOKr!VeR0ocZrrI)#MJ(wx#SijA`MHa{R~MeaH^P{I{qNvWs%?&f36=VI6d3 zdFkOa{bda*-sU~d;ZXi1TDBD?*|~v*ZDc_@)cO*6rq|=7<(U@qt$9jW;x^8?7lvJr ze)JO2+PlZ1Vd1Bnys>dL+~^*7C`Pd$BuVl{aV$G8v7$8VU=WUd%WN!RgNztQ-dEd%*zDibN4y=4gl>Uyi$E_NIpH$3R zmJ8xUqA$qEm^n1EfIjeqbM37!Tgg0FdBLYiq8~d*@ z2tIa&ZS22BZ}`|%wz2}B!{R~1hCy+RC}aEMNO zg$(QTU>*!u&8oHib2H3SP%IytZP+ZXkrQ5IgI!b;uJIwY?$Um(W&fE%gG8$|l zK8{S_IVe&w#Nx5C6s2J-iE!qW$7QSq#j`)D2>lt`HNolu+iKEk{=o~*J&T&T=i3)G zyV>#s9PQ(AmyPY5+`&AKQ_TT6+q#^1M`Q97=N<+PeyWQ-0laAC zkM7a=Yh85slYab;p+ui_gU}`b`|F_7N+dO!czVf7AS|M{WEMw z27J&O@Iod#`1t%C=?Hf$m9T4ng8XFgg{z?ri0FX|aNG}O_WXN!A=tWp7lvQiD2g4AEv_sgh8)KO7ye+Mq z)@&jHTw*!ByNUFeo>7R0jNL1&s*m<8`r{FdMqlq})gc-Me03|#%v3AI{9wnaqOWD0 z_3M9Vm7dTlqfp}yK0ZlO!^w7bA|KJGz-7wOsRsaUp)>}K&J_K=?m$LG^-`^eK>exL8Wcgap4U)-Hi z$3D`-l<*|z^Vjfcy$`C8PsQCLEOeCqvJ9II?buofi7t#*yaL$@xd#b&fi~>JY%6~O zt=Ug(-Ab9YzUU$`w$H*7!H;>fQo$lTo1^wWKzfi(bmRdtnCYC050K%EXAh7OjJ^lS zSZ)HP=?4kl;T(H;BlYpOGCsk0P=D~9N$GhUV!xuaK&H1eN2Z@N1GKj+@Rugb0fABy zqh1;-dqbt+GQ%XB%m~RKGg2BXlb8C+)Ji>M21@}l1<6;YD0zVRTwBY6DCyxdEDN#H zeVK96J(;7V2D|Ktm+E9DN;hPtNS9@%NoQrIOUGqqNQY%+Ne5--NIPZbN}FWnN$X@5 zNULQok(Prj4@V2pS4j(4sB>q~Y}r|CXTj;Rn^~Zx39_@4IY-J)Hgl6~vXkxnk+iZ? z-p$ibc9yZw?y_?yb9R!QY%77}DLX5f^Y0vXWo8POevzG3%=ul8odus|?m9WRnmMn* zDQEgJ^PQ0o9A?f+*?EIG-;|xT%(-25)-flQo%PJQT6Q)t=Q7zTG3Nr=S;L&OnbUss z9&@M5!A;CLL3Z9}&XKaSnK^B;^C5F;Whc{9q<*rKeV|S14yT-FPv-NJ4|p@DyX<5y zZA*X7W_Rn)oIlCVK=yG}sX=xJv*6EVC$^U2XVGLQd+Sg-BRla87L=c=Ene2>W&IPhFmN{q7ZkgiDbR6?el8>-uOliFAjAzc_vNMr6 zMcJ9coGRIw#+-d*XF79sgA*TZaW=zo<5(9O^)8vtI=@}-5;LizU%yK_aci>agLlb5 z794(cB!UNp-CS!jo7l3I{4;@dGyY2kwq(;iM@bG>tfQSPuup%rj#|MkS%a8D>KbCV zv0Z~~7bjg@0Zaa2KUz^iD0b_Ot;FD2=|^W)lJOXRk5!V)Het9I>2n(X9C)(^-%46dtBkoivr<2F?!Jkm8XLw%}AO)dQ3CnPg7KNypuz%?sM;X%3Rnp}}8 zlB>uYY>@ut6gfe-*Po{EoFNu(pQVq-=5_S1Go(-7r&66oReEz%wBpVi7;`s9E3zS# zkaG}Ugpb=y%d8}zP_|eGo*pzT|5mQ##(w$`yO*jurN%La5=sf8$j+rx;Cj7&c87rGI z{otkXa8U(&BNS`n6Yo%Rhmgnh|6D;cq66VmtRv8)xiga%w7-My<9 zwq||oLK=O66f@=E!wc9vmpz;QZ~?21Q?T&}F9kW8q(MnEq?)AL&ZnS^hBj$FHpYAA zcadu!CgFDzSp)KR)Z9IZJ9SL*gi*%Bv6Rj3gQU>~j|=)bJzh<|=5{C3trxNK(vj*f^ZgwU4!Gi z9pk-?<2>`-E77JEXA;J}pNm1Zv7PLo*_VmbJ$(sgX5mn~V7~b;7QEb#NEj)h>pvpB z`?E@1ROOA&J~^#UnyM)2xAicA;8a+2=EF{hT{VGO!V-G>BNFY;;xnzEy|adwfn;+V zHC!R0dOz+Th0`+JQ+~^1Fe{;&GWY_>%gHFK)#->v(?oM;0!}|kv&VyJVBx)%VeOmGi@@o<& zuaeNva@JQUHq+uG zU@iDuE_=aaR}Jay%DHUDEYW(vR)w7Rd~$)?RH`9i;q2DkPN7_#+a{nDkK0y?iokZv zcuAMpGEV6hs=7u(rX564U=nkC2IhtG8-)0gURFc8yn=ZK+Z^gLi~C6{pbk2V;cf*= z2@kq>D`=K2yuL-RvS;eFkJtapK2FQ8kzk$kX}F19}#vcK#!#IaY*vEF`Ajv-rn)Xo?%Ex~m9 z_`UO;NZx5AU?;T0fFV763VDEC3)?R-1#iz9+S@D$m0@&3BabjL3~k#p8{gk?y}jPV zGKuf}ApeuhrO7NihnlXboEUcKUCe*Yp1d)-}uk5@}S zJVRffNP4B=J*&6VkF&>jB`N63d^1DhU^snnA zgv_R0ZxBnkY84)m>-Cp#+3kA$rFS(>L!*a$cDnxt86Yp9|CiTa%=CvF z7!DoVX~-v}U;MZ=cx8D&bw+Q>6+)Up zBWlU24AvkDGdz`#T32`W%|z))XYs!y@b0rpW+cIq2y31BF%DnHDJ(rP6TxHqz&}oA zuZ3o_)7f?i`DX%9eGlUu>Moxnb7vn=%jYB{h+VNb(Np<96Qg;b6P2a-04`l!GW168 zOC=NT72%f&{%FC&-3;w%nNWnR=Owflq>YELW0-Aq%qDAw)|E`Ei$`G7T6+6)yigZP zeZC;ScZt}K8gSOH-D%(D-{3sFDTO$lXt$df@;AOj4L8YJRs#+dWR*ZsYKlx44uj zy&Pxme*Gs*vFuN(o91d77WozZB$!B9zY-wz!ev~Rmc58mi6!zDd!v=TN1JyC!)1%z znD2*a>t8tNinokz`I1=4@AS(rp$5G2j1>~YD5 ze)Qoj(yj9Xq~M6a|xerPmqSu zU%tlgK>vDyrrpMe0J_kE+eA&e(*w83WUlfcZFh$Zgwk)k12u7xg-*Ofp6$RJk*L$w zS9C9eO`pEJLjuSx`r93nNw(984P>6ZHX1Kk-+)fO_v>iI4z_}VpGU#}#@p;b9bB)< zu6nov?;uKp97V$aU&`m+gKL}|g=zNhA(ad6_u<-!Fy}|*<$f>rALd@D8A-{$713Ur zoAku@WExksrK0>BY-VkXn&LP;z#aZk_h7=~&TgUie;}nkl{nzLdOOPB(H>!;cgY%N zqte`T)3HNC?yhHtbeG{?mf6HAwcF2f%xiav19PLRKatK{^%nZ=Poz(WY3hHJ3(FTh z@I6^T_%>xVjM;;Ird054P z$V3+;#`56b6!|z0%kC8-^DG;oO_%`j@sHc#Q97%MSh?EhihWIFvRfylT=ac9d*7fv zj8O}{j>VN#1l=duZu)|7XL9?m;q7Ng(#O$?7avekU zcXG)%HUj4^^ef?fVcv{hf%u0sB5~ z(;W}V*e=V6t%)Y_KcwPXkv$A zaJlo1dH8%AMiwv0X9!*PH<{0Q;!UH!Nso{dy>MJM5jwNuFU`Oi&LQ##s(wUXCsXO= zN0?fa(w`rZfuVEJ^f9>p5ry;4H0D6nVF~+5$KV%!8uh*C?&{F}^oxJjX?ncPf^091Pi+!8BLNb;kP2N+qXm@B9`^2Waiv_HLl( zlw3~^-%OE|TnuS9-Nf#d&0fE!x;9*2yih)=4VU0m2Q4)!J|RgOLXWlKzQnz6@Zgg1 z{!EhxHa6e)civp^#4 z;U0b6iyMe`a>0vBBV`p~?YOTz$e+}$6BkGBRE+Axb>!H6rg!FaTu2$47|er`%=Vk3 z9xa)ONyFZ#ypctg>TUF$08Z5tzi)sQIM0*5Z%t@@g`?4{sQx70?_)vI7^)29;=>W` z<|NOJ4^DaJ`E9&ae{*0tLcW~Tyb+!Ur~LA~ZVo)YjV=u2be@qIOIpJHJJ6$n+>X!< z3vjQ&?{T<&d{K8`8S}P(4-HiIZdgDUcIA3=l?&*Wu3RWrx`0+OfB6FXO;>JM$6Q3m zY2gLn4Bt5eYZg#T5O><^B>ee(J|9@WfVS<%4Q{;(bg+M3#r?@uQo3;_ZtnuRt{Z1& zsbA~Hi5#x(8;o#V^{HS~v2^)rDW}fhQsK3(OV&B5yRm>eg1IGJAubuhO~pf=9m0*} znzqy9A>0`93vJh(TgTOIr`x)7UG=rwai41Z(%0ud)^$Y@opoQ-{Y!T_wEMq8J->9X zW^rX!G6OwiG&t6=&PW34FJkO}2=8z>nH+nd{&oykT zi0IAL5_|S?PLTvz1Yv(X*bCwZ5nW;4g`A>0goliTq(O2a1&~t6e#kM%Wk@~bM~Gq> zr|1ZYfQXRskSxd|$STMd$Xm-eyW%_?UqKWv;35zcWEkX;ol|6k3m`ScoZ>j-AY>C{ zHDnPa12PiAL%Ki|kZ)f^e8>sNZpa46k4Wn_^5hmT-zJ zfIJO}f%JzwLMeEyzy%=vA;Ta^kQtCX$STMt$UBf~$QO`%kcW_tD>=m=$S6o2q!_Xe zvK>+mIcCRymm&3#Umy=5p17z#g#Aq};uPnR!5ffz$U4Yw$OD8+kWV3(AjcpFA!U%) zAgdq+kQ~U5h#wCQgJ>aP5PygQGW{qHvcEEv#7amWg#GQuU7v=03~7M82Kmpwrv^nU z#)#31zpPlqn-i@t%#VH?9ganA! zFBN4Vdo51UB}RcaTorL3o064*T|vKq7zOsZD$>DjU=0`yMg_(wx`V4h*rXLTU?{ku zYmA~NruYg)P>iA%0-CzTCcor>F<89@%)VR?4ge)E5^Mqog3TbaIV!9%3O(Qn8bCi#00TiI z7z$c(eMJNuHjoFSKmm*fqrf3x92g76gTufSa5$I_jsUa3kzg+P6j%U`0Sm#gU@;gE zmV!y(29UiYS_aymhGQ=rnP52!0Ba^-yhSCbgr5V?f^J|9s07PVf!x75_}NENCC~%B z4|;+MoBXXmg?AY01pMCcdxL>sdoT?20eKs~o$CvShyXt@4(tH3n%WU$HMJ9%h;V-} z9qbI|fL*`>Fc4f0b_GkpAaE1d4crR`gNMNounO!BUIu%BwKh8{1sn|s=m|D~y}*ZH zZ_qOebprGU!@*Fn4;Tsd1qHAl7z_3X{Qf)Ch#6;2Ae@EsEkJ40sX)zFc^#mBfue`7K{Z)fkVL*kbP@3 z0~`+8bKw{P#}aTPSPVV|t^-GbW#Aa_AUGDR1mnT8;CQeGOakk`WKaU12Ajc5&@(1R zF&hj7bHE628K?z`C#qW%9PEcqSkL4Ej)K1}m;!o%86f-7vRu#)Tmp6ii$Q;I9oPjd z1B1YWUZPb{x!O$0Lv-b{s5a$H7fQ z(f&y!a>NdRhuHzJ3M4$*DGLW{Svc6h!nJ6oEF65u!a>hr2p3Rdpcfd*{31$>`9XpC zqflbZ55_abBBR65{=MRmQx-4^Ic1DTdj*wC&|bkHa1+RS#TW%HhF%VNRP00;+c?ce zQ1(|2e=T?%`~s{7-v)1hWnewH7Q6>u1)IT7Sa+)&9;5ge^aJ;S!Qgvf1b7zIf^}dN z$i{l;kTm{6qRr+1|^WN>GBI4LtY37eS^IxPywg7zGMZ)(x1h;0^zFFc5qh3U@SNqj0cZ`Y2a~?DG^pM3;tq|DI-kF$%CI&YCojw4Hm-Bl#x&zXIjx} z`18PA97i8yS8PDQAq4CMnKBZH1MR_b_{V}wy@~*j!=DZAg}(<_4gXXy6n-D@2K;Eb zvSR5A*2B+ihxfp7Adh%{U^D#VK|f?@Aj_)qsTjpP76Ab&b^!hYumFA&7!3alpnwEA zfJ|+&fe{EVVc}o`Bf`~SEc^?>8pIC=L0#rolf0%mQCxMWw)r1AsgPJOdVj zMPMnyndxOU{3}^F{AO?i{L8@z_<3+A{F}jY@Hy}}m=9Ki6Tm23xFdK2{@1{IFcG{5 z+9@1yh|mdaM!*^{1qtgxX8gR$UNFcI7f zrXzkAFa!P+FbnG9m5 zj^rGjm&x_77&V8BVA|D_zlyS1+(BhU-dygiXGK&2_cuqMS3I&@fcV(6@A zW`+(LGzh1%W7Ka2$5WVrOcZ7vJ#BcN%ctQlZ~@f+1+D{4wR11FpOBj|H81lYSLjW1 zU*NQcgghjgkU2eX?!3@hb3)_cOPrQt3TJIJP%E%ugbQzx88v+wo2JzN)ylii_ha;@7|+Tyc0Um(J0YSGaU~`4ujZ zO0RIED&k+|+HiEsdTw{f%z63K(%654rq5t~#!&Q3^YA=a|D>o``WhFnG?e0r;w3Kj zaK%32Y=ZcOw_*mfAL&&fds{xcPd!9N)KhIlk@Sax`~zI=GviX#Y)IcW!3sq~G_NU3yswDV5z|I^c>=^>;Plb+!WY)!4&b*WbWqs)IF zU-BQvSI%-?M9h}6%WcYG4D$H=8Eg-K#&u5z=E#A4UdL-kn<4D4^#a%eA>Ui8KWCmZ z!PoZ4xgKoX`|tSwnL)2|=W&*%c*s>0Q{R$L=E~optG068?9I`NFCnAs9E&FZ9fe!j z5jMA_Pr_Edz$wD~U_yKTNtkju42B&zManG!gg*a>9@{3DRW*zX5Nswb28A0&z&=R>ipS?w%l+8<zPai?XZjMT=CK_u8LIT z?cox+&L6rb&&tRgk~MW+;@r{sIeD{U7UpGET-e85Bkis1LC)O3Gxu)*%K-! zBp4D334=sHA|X6P3lSh9BnlD>iGz%SBtp_5Sr8UKwwQBAp4LW>!}m_A#=z? z8KkuY6&GBmUx=yr>nQh$(mwETwBr9pTJz4{Vquzz63oG(`2UmGU4JQvpNshaA)Ouv zuteD%jqg`6?Krov zYzB58WHYIUAe%WU5zig;2ALw^53+ehAQ%b;KZh#HRJ~9HusLM}$mR(=$dp<#9CVPG!EW>k4#A8-li{A;p1S<&Vc=SgT)7?eMs z)0~gJ5K2DF^9Ild#4MnY-AfI~E-it;KmOV{pF2?$atI9snWn{qN)RtV$myknZQw5e zfq(oFS$!^bhSMFVxemSd!jp?ARsSV2oAA{V`qgQ!3)keN(vwpZQvNL0*$r8serGs; zCI8qJ_1G2fa#h;#!#au@`08(Cd6V6)>n~2i(x>O+daTH8a>J&))}xs4!89BZ^TZ$e zqEfM!m9Xot`XKzQxLkjs=alk1t<@iK3Vy7tw)z!WXOzxg!F7e?exQ^m^{o+V;7?)Y z>H14Qr+iU!j;qj|bNl;?il%bqOgFDWX0K4d3Q|I+9#)PZGwFfD%7NrV`uSmHhzG}s4N{H!YL1ncis z&i0&bgYB3NnG1!s4EXSa`6YZ4pQKurdjh)gOvcSr#4snt(NH8>8!e^bQ5%$x&qxY z-8$VncHMa$(RbAM*X#6VeVo2XU#4%=|E3Q!6bpNVli z-|GSly$yoFYKS*XH53}A2oa`86K~R*(kzE8Us=AlJhFIL1Fe0n)2(x@%d9V2H(2*r zk)wFbM}gkz5^bZtzhQ!*!tkyz!jx^xv+cLNW4mT+v?=WAEEo9W`|}nQ_3x@~>J6IB znjf_j^m+P1{VVzn`u+O%^VmU^3(w?g$SAPos~qhjEZG-jri1Fs(9` znzotBO;=1$iP_>J@eT2Wcv)2B!k~)ePim@ljk>>ezWUDkJ}B$Y^ndET4c!g)FoVtz zYxvIKB?JqD1g$VsNE8kUSB0Cx55lj4(%8v(#~5wuBwiOoEUYhJZ&!8Wd-J>acvYe* zMU|#XS7oTOR5_|#Rk7+VRi)~Z>MK=)>IapVIuLbZqI#-&srm)=YwE4)BkHs2>*`ym zAwilRnlMeW#%|ZF)@;>OXs&2}MP+%UQEI)k#oE2va_v{zZ?uit-?c$HlP*p-Q@2pJ zLbpcus&0#Jr*6OQl&%2}rb*|c_tyvMqxHk}qxCQ8PwK}Qt{BRN8sSr+PH1oJXMD<7 zVBBXsWV~kl-q_I;XzFh2k4L9B*-S%CPni-;_NPthrdg)BrhL=$rsXKaS52>*wwf-P zx|l`tGV=*@qxo0!pXN@YO)L;g#eL!-@v8W<*xu6LVz6wpT*LEkv;Mtg8&rE#M^&Gq=(?&$sFT#w)mzl>sO!`%YHv+9%}7n6W{u{E=6%g~nl9QTlvA1Z zlJ>T?v#zIZC@Sn5sIIqklCGy-r8nqDp~4+7NQO{hr0}e;P0xL&Lf&xqCH4e@jFd$CFUTkLHa zY?)-qw&Yo!w-j4mu~5rS%Qu!^?3TYRp4Nd@wKd5)*_vhDYrSN>Y5m69*JifOM*&{7 z-Lm~^QBIt58otlOqLq&u#=q5Df`)Q`|l)z8zvi{^MyU#FM!f9v}iG=><% zC_|dzS;LElHHJ3~ZyVk>d}ydgi}Dc6LXwasOciDd`N9g}4Pl#bOSmiiA@~?O8^;+Z z8fO~|?Zy|4mB!P?kB#4v~;=HcdX=2_+v z^A;3+y?LOhLtmGQ0)InPTDn5>-`PkxS?Qea-O08S1Z(3`u zw@|M4t&glewqRR78*huZEw$NSv{BnZ+qLPzH#L|f(>+s@DH&CEjyd1F(!58k5-*D1p;CHSHdySNEjujx(2pOn zyl**WxnTLoa^3Q|YaVHiAL04-rNPV}<>~IpJ%e8ATpu9AHc~K4)BNeAT$oxXXA9h5LitHxN@h zQ;2Dh$zqyn$~7%8Ex~}Z#kALS*mTTPWjb&A!qj5&GzXYt&122U=4s}+=H=#9=9kUy zo6nmso4+vMG2bvA{oi}R2A{{j$-jf@T#drN!QbTVxA_jLE~-8%oocJvIE=@69S`)b(1J(m2Q8tW(PWH6>zQoKGcGcg z8IKw-8?PI`GTQGNe=`1Nj4%y04KpQ~X5*+=C0=6=D}v8*=l~u zJk>nYoP%+Znm3ydnh%>lGG8};X?|$tL@&`#3=+e{exgwvCXN*+i#cK;MuN5CE<99! zjF-G+q@}^)Ywc$3Z8ca&TAzl#G~13rv&g#6T85@`(fYB~-R5iSZ0lw_V^h>)wGJ)F zjUT6eTOF&}u1&(o_JzS8qj<0>)D&iFRl@|6qDj`a6lV=fOoh0CV$*6=&UK~@rcI`^ zs9$?6M=e#TJ2x!#$bw|KhdOlM(rkHXv2)fRtiR&2VYVT*r){%Pajvq8qagBfKoB3w z_rZ{(<^|ry4@3J+N{uBNi{zty2s;_Dw8nY42 zd6;T6w4{luY3Ma`RRtKDidC;-nBSt>t9nOuPIbwyQlRq;QTJ7^(r(rs){fTi7Q&2c z%?mAUtShZQTElE(ZH2b)Z3;ia3IrxdzX`SLUH!)xynfL)>)j0YKIjY#2GKCl z&|7#)NEO^oz0r*hfpQcN^(e)(%(TaJ&UE=dx>U7UfPNH(w!Ytd#9RZVybeQB1HMBs zSe%OXog?OodC-`apbjh-uRsr|73;)$ah!FYbtxYBdJIW>txeY7?A8`*jBN)Bo&7F& zG1}_e{LknSIn_+nM)ZESRNtw7RJEwwQ9^NOjLX&Qph7mPe^YnR1Zui#A~kBwa7~IP zLo-`5584scoWsPUuU0@Qe5m)5HRk>XHPrXvhH-{u!wf?%T2L|C&k+pNpBn7n8h%1o z=qvORBB1~31gpS$#BuV-ogvH;<_gaVOVF%V32TM*!e(K+uvaJ-jtK7yXM}3u3KY$o zazpzOD%C@Q7(I->Mt@_Fv6rzg)GHmDT@)JLXybT{_vywN#yJ?g78;jf_*!jTXMEjm z+-lroJZO9e9qmcuIpasr1Zs`-#&3*`=yaQnkBn{5?RGGAh2|QDX@|;WfPN5b8fhAD zN;XY0Wty_l85fwAnqDwDQ0HGmm%I~=w+brTC#Kt`M$<6!CUX)RqQz2Vc^$o{);b!R zR5etNn=eto4ela{XqFgWkHHjao1Vz>RD=!+hLKQt`xMk=m z%tL8z5#ECudPn$K_{)wW>ul_49ATaZB|8C?r$8(c-w^{Wp%?{X(EBg26e8a{(ElGp z?jKsa*m~R4Hqkc5Hp!M@%eNKTUb4N08uX^^I_7jlUa3{`9iS;%`Pu02Uqkc!l>Zjp zd~fL4v8oZ6#)c!y3pDFBcQy77+CfmHyXkskm`s5R9S-GLL|cdyVxef9G5%@vH%-B8 zK#yLogJ=~KF}W%dH)3-2F{YP~L{I3oF&Ls+pvHEz_OTAP?zA?dKk1AtrrPG(4xmRt zQ9`YPa-~S-Jyji4-H?$fs=1g|-?6KF)UT@FS6@`;YhOhxepmaxwn}>ziqg;80G&=J z>Y{Y9nE#B@#p@E0!R@-ex`VoM-CK3{{Z{=oeJzT-Uf+P$eNW${ zzpuAqY8MCfG~Q4l{D}GDAmiJ{aMLc+9q2?}<|XD4qP;*|CVqyN`GKX{a?|pYv`53(}}!0=Y8H?<)hL=9l4-7p>Dtv?|{a(9Xj)`ny%XSpknmW3A#LJ%H_IjOj+0J zztVRw^f5#lGSJk@4Ob0Hp@)!x!RcAyJe0Z)P~cuMUNqh^x|{5#<8~+x-_;)nfL-#9|s|vwOuiQQ+T+KZr?|iI!(94$D@{F3WgpvNa7_ zz;Wvt>xWjeEy^~+HUZsune7Os*T2{lxrCX(6e@JxQ}|5Ohb8=5P-x#nXZ;a>oxjD~ z8~D5Evw!DDs>Z5bLf_1^TBdd#S9MkQR$I~ORH&QOf@Y8Qxc0pEvi4(btya`U>#m`o znO$I}VZOm`c**cOX7|?(H=+4^3w;HR5QE+{MR*atMwxH}lPw=(S7W5nXpAx9`*yfB zB}U9HVjsI0DVoI?alDvDuD|1rtKt(u*s$=Of6+Z z-oNk?zm7k~SE1Oy;S1HrFkqdwqfjqtub@~z)o#%r(|a2FLDxw}<(Xx8&algnD%>-V z!?f}f@h9B$}!-*4{RaZ7Sx7Z`iim>THT~j33Bo7;nNbJ(pj=pGLdy zfWcS;GsP4<*j=h})k&y$KdXA;!KPs}S**4{RCAhW3?T`aschH$2%D8cJ3@O)_pNTV z{$)MYZ_z*0zb?FE{J{7bG^Ia{-YCv_rU{s09mFGeWC^rdQ3dmCD{QaZw%T^GM^Q!O zEkORz`9I*#@_+LERd!VwhA}Vo0CiifL3>ksS@*H-Q{7G7*LK}Eu*>|U`%U+U?vYNZ z_tg8q8WyMz*7t&)#-M*oUt_2>6vB4V-EX(IZ{edbUx1`5?L*5$TRcF`Il z+bO%_A*uOj)b0kpyK1+pjV@5PS|}CP2^)k>sERu=d>zC9c37wsHd=nM*mc&QplT6C zDAFkBD|KgZ=dTGXO|j-l(Dc@r&zXCPiY8~}nyg=sB+7-`LV__9bA-2yhmEPGEYovP zvreE>8DQ3!&1ke9q96_zlf+kGD`{^TVac&9v@Elfz)Cg?y~|eE7;9|b+I~c~xd_?x z9;)fA?ZftOU?G-Ss|2;Ej#9^>@g=HL@T6d%qsCh0U}okI#XA?k63n5NV}6=r&9g4C zF1J$UXUeI}j;yVi^_eo0cogeObsKbL6`#~9PqFU{DPURl2I5(1<#Mvs?Vh2@umL4e zi>XhbQ81=JJ1#J8z>K^WW3LigW~3<&H&_gXxEgcHCX=6;H^-ZE&8y9&=5kDHYRpY$ zKam&XVRbAJH;9MDN@gxD9y3e{=1WZ9NK G{C@#NM}~d? diff --git a/INSTALL/tool/VentoyWorker.sh b/INSTALL/tool/VentoyWorker.sh index 9c6967b..099b2d5 100644 --- a/INSTALL/tool/VentoyWorker.sh +++ b/INSTALL/tool/VentoyWorker.sh @@ -12,6 +12,7 @@ print_usage() { echo ' OPTION: (optional)' echo ' -r SIZE_MB preserve some space at the bottom of the disk (only for install)' echo ' -s enable secure boot support (default is disabled)' + echo ' -g use GPT partition style, default is MBR (only for install)' echo '' } @@ -27,6 +28,8 @@ while [ -n "$1" ]; do MODE="update" elif [ "$1" = "-s" ]; then SECUREBOOT="YES" + elif [ "$1" = "-g" ]; then + VTGPT="YES" elif [ "$1" = "-r" ]; then RESERVE_SPACE="YES" shift @@ -110,13 +113,22 @@ fi if [ "$MODE" = "install" ]; then vtdebug "install ventoy ..." - if parted -v > /dev/null 2>&1; then - PARTTOOL='parted' - elif fdisk -v >/dev/null 2>&1; then - PARTTOOL='fdisk' + if [ -n "$VTGPT" ]; then + if parted -v > /dev/null 2>&1; then + PARTTOOL='parted' + else + vterr "parted is not found in the sysstem, Ventoy can't create new partition." + exit 1 + fi else - vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition." - exit 1 + if parted -v > /dev/null 2>&1; then + PARTTOOL='parted' + elif fdisk -v >/dev/null 2>&1; then + PARTTOOL='fdisk' + else + vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition." + exit 1 + fi fi version=$(get_disk_ventoy_version $DISK) @@ -148,11 +160,15 @@ if [ "$MODE" = "install" ]; then fi fi - #Print disk info echo "Disk : $DISK" parted -s $DISK p 2>&1 | grep Model - echo "Size : $disk_size_gb GB" + echo "Size : $disk_size_gb GB" + if [ -n "$VTGPT" ]; then + echo "Style: GPT" + else + echo "Style: MBR" + fi echo '' if [ -n "$RESERVE_SPACE" ]; then @@ -192,7 +208,13 @@ if [ "$MODE" = "install" ]; then exit 1 fi - format_ventoy_disk $RESERVE_SIZE_MB $DISK $PARTTOOL + if [ -n "$VTGPT" ]; then + vtdebug "format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL ..." + format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL + else + vtdebug "format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL ..." + format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL + fi # format part1 if ventoy_is_linux64; then @@ -216,8 +238,17 @@ if [ "$MODE" = "install" ]; then chmod +x ./tool/vtoy_gen_uuid vtinfo "writing data to disk ..." + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446 - ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + + if [ -n "$VTGPT" ]; then + echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92 + ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34 + echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none + else + ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + fi + ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector #disk uuid @@ -307,8 +338,11 @@ else echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none fi - - ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + + + ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + + ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start sync diff --git a/INSTALL/tool/ventoy_lib.sh b/INSTALL/tool/ventoy_lib.sh index 6fa869a..9e4d45d 100644 --- a/INSTALL/tool/ventoy_lib.sh +++ b/INSTALL/tool/ventoy_lib.sh @@ -103,7 +103,7 @@ get_ventoy_version_from_cfg() { } is_disk_contains_ventoy() { - DISK=$1 + DISK=$1 PART1=$(get_disk_part_name $1 1) PART2=$(get_disk_part_name $1 2) @@ -126,11 +126,15 @@ is_disk_contains_ventoy() { return fi + PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') PART2_TYPE=$(dd if=$DISK bs=1 count=1 skip=466 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') - if [ "$PART2_TYPE" != "EF" ]; then - vtdebug "part2 type is $PART2_TYPE not EF" - ventoy_false - return + + if [ "$PART1_TYPE" != "EE" ]; then + if [ "$PART2_TYPE" != "EF" ]; then + vtdebug "part2 type is $PART2_TYPE not EF" + ventoy_false + return + fi fi # PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') @@ -185,7 +189,7 @@ get_disk_ventoy_version() { ventoy_false } -format_ventoy_disk() { +format_ventoy_disk_mbr() { reserve_mb=$1 DISK=$2 PARTTOOL=$3 @@ -218,7 +222,7 @@ format_ventoy_disk() { fi echo "" - echo "Create partitions on $DISK by $PARTTOOL ..." + echo "Create partitions on $DISK by $PARTTOOL in MBR style ..." if [ "$PARTTOOL" = "parted" ]; then vtdebug "format disk by parted ..." @@ -300,5 +304,95 @@ EOF } +format_ventoy_disk_gpt() { + reserve_mb=$1 + DISK=$2 + PARTTOOL=$3 + + PART1=$(get_disk_part_name $DISK 1) + PART2=$(get_disk_part_name $DISK 2) + + sector_num=$(cat /sys/block/${DISK#/dev/}/size) + + part1_start_sector=2048 + + if [ $reserve_mb -gt 0 ]; then + reserve_sector_num=$(expr $reserve_mb \* 2048 + 33) + part1_end_sector=$(expr $sector_num - $reserve_sector_num - $VENTOY_SECTOR_NUM - 1) + else + part1_end_sector=$(expr $sector_num - $VENTOY_SECTOR_NUM - 34) + fi + + part2_start_sector=$(expr $part1_end_sector + 1) + part2_end_sector=$(expr $part2_start_sector + $VENTOY_SECTOR_NUM - 1) + + export part2_start_sector + + vtdebug "part1_start_sector=$part1_start_sector part1_end_sector=$part1_end_sector" + vtdebug "part2_start_sector=$part2_start_sector part2_end_sector=$part2_end_sector" + + if [ -e $PART2 ]; then + echo "delete $PART2" + rm -f $PART2 + fi + + echo "" + echo "Create partitions on $DISK by $PARTTOOL in GPT style ..." + + vtdebug "format disk by parted ..." + parted -a none --script $DISK \ + mklabel gpt \ + unit s \ + mkpart Ventoy ntfs $part1_start_sector $part1_end_sector \ + mkpart VTOYEFI fat16 $part2_start_sector $part2_end_sector \ + set 2 boot on \ + set 2 esp on \ + set 2 hidden on \ + quit + + sync + + udevadm trigger >/dev/null 2>&1 + partprobe >/dev/null 2>&1 + sleep 3 + echo "Done" + + echo 'mkfs on disk partitions ...' + for i in 1 2 3 4 5 6 7; do + if [ -b $PART2 ]; then + break + else + echo "wait $PART2 ..." + sleep 1 + fi + done + + + if ! [ -b $PART2 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART2#/dev/}/dev) + echo "mknod -m 0660 $PART2 b $MajorMinor ..." + mknod -m 0660 $PART2 b $MajorMinor + + if ! [ -b $PART1 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART1#/dev/}/dev) + echo "mknod -m 0660 $PART1 b $MajorMinor ..." + mknod -m 0660 $PART1 b $MajorMinor + fi + fi + + echo "create efi fat fs $PART2 ..." + for i in 0 1 2 3 4 5 6 7 8 9; do + if mkfs.vfat -F 16 -n VTOYEFI $PART2; then + echo 'success' + break + else + echo "$? retry ..." + sleep 2 + fi + done +} + + + diff --git a/INSTALL/ventoy_pack.sh b/INSTALL/ventoy_pack.sh index 1660a50..9f21bbf 100644 --- a/INSTALL/ventoy_pack.sh +++ b/INSTALL/ventoy_pack.sh @@ -31,7 +31,7 @@ while ! grep -q 524288 /sys/block/${LOOP#/dev/}/size 2>/dev/null; do sleep 1 done -format_ventoy_disk 0 $LOOP fdisk +format_ventoy_disk_mbr 0 $LOOP fdisk $GRUB_DIR/sbin/grub-bios-setup --skip-fs-probe --directory="./grub/i386-pc" $LOOP diff --git a/LANGUAGES/languages.ini b/LANGUAGES/languages.ini index 926f47653e731905b45af22fec35469fed195d83..c85501afb5561cb5f95563cd29ec716820a87a0d 100644 GIT binary patch delta 3362 zcmbR8iS@x;whbLDj7F0mGKo*#Ajl;c%n-s5$>77_%D~IO#bC@}FqxlGRMH42>ckMw z;0q*!fV3-+3}WzS2-@7tGGAbFi~+}V1$9OdPPp#Ljj@vK!3-q~l?*wP^WCJmkxZCu z$SFLTO^eUGm?4!R2Z)n_>J%8<83KT|C@`ck36>bZ7wVRo;}SHxSlt_R3e|r++XjZ|2(_r|Gt|OHz5Aa zSbb(d>PartTbl[1].StartSectorId; + g_Part2StartSec = Part2StartSector; Log("Parse FAT fs..."); @@ -1154,7 +1154,7 @@ End: return rc; } -static int WriteGrubStage1ToPhyDrive(HANDLE hDrive) +static int WriteGrubStage1ToPhyDrive(HANDLE hDrive, int PartStyle) { int Len = 0; int readLen = 0; @@ -1180,9 +1180,20 @@ static int WriteGrubStage1ToPhyDrive(HANDLE hDrive) unxz(ImgBuf, Len, NULL, NULL, RawBuf, &readLen, unxz_error); - SetFilePointer(hDrive, 512, NULL, FILE_BEGIN); + if (PartStyle) + { + Log("Write GPT stage1 ..."); + RawBuf[500] = 35;//update blocklist + SetFilePointer(hDrive, 512 * 34, NULL, FILE_BEGIN); + bRet = WriteFile(hDrive, RawBuf, SIZE_1MB - 512 * 34, &dwSize, NULL); + } + else + { + Log("Write MBR stage1 ..."); + SetFilePointer(hDrive, 512, NULL, FILE_BEGIN); + bRet = WriteFile(hDrive, RawBuf, SIZE_1MB - 512, &dwSize, NULL); + } - bRet = WriteFile(hDrive, RawBuf, SIZE_1MB - 512, &dwSize, NULL); Log("WriteFile Ret:%u dwSize:%u ErrCode:%u", bRet, dwSize, GetLastError()); free(RawBuf); @@ -1372,7 +1383,7 @@ int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLett VentoyFillLocation(pPhyDrive->SizeInBytes, 2048, (UINT32)(pPhyDrive->SizeInBytes / 512 - 2048), MBR.PartTbl); - MBR.PartTbl[0].Active = 0x80; // bootable + MBR.PartTbl[0].Active = 0x00; // bootable MBR.PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS SET_FILE_POS(0); @@ -1386,6 +1397,9 @@ int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLett Log("Clear Ventoy successfully finished"); + //Refresh Drive Layout + DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); + End: PROGRESS_BAR_SET_POS(PT_MOUNT_VOLUME); @@ -1436,14 +1450,11 @@ End: FindProcessOccupyDisk(hDrive, pPhyDrive); } - //Refresh Drive Layout - DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); - CHECK_CLOSE_HANDLE(hDrive); return rc; } -int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) +int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle) { int i; int rc = 0; @@ -1455,14 +1466,25 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) CHAR DriveName[] = "?:\\"; CHAR DriveLetters[MAX_PATH] = { 0 }; MBR_HEAD MBR; + VTOY_GPT_INFO *pGptInfo = NULL; - Log("InstallVentoy2PhyDrive PhyDrive%d <<%s %s %dGB>>", - pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, + Log("InstallVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>", + PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, GetHumanReadableGBSize(pPhyDrive->SizeInBytes)); + if (PartStyle) + { + pGptInfo = malloc(sizeof(VTOY_GPT_INFO)); + memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO)); + } + PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); - VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR); + VentoyFillMBR(pPhyDrive->SizeInBytes, &MBR, PartStyle);//also used to format 1st partition in GPT mode + if (PartStyle) + { + VentoyFillGpt(pPhyDrive->SizeInBytes, pGptInfo); + } Log("Lock disk for clean ............................. "); @@ -1470,6 +1492,7 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) if (hDrive == INVALID_HANDLE_VALUE) { Log("Failed to open physical disk"); + free(pGptInfo); return 1; } @@ -1531,7 +1554,7 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) Log("Formatting part1 exFAT ..."); if (0 != FormatPart1exFAT(pPhyDrive->SizeInBytes)) { - log("FormatPart1exFAT failed."); + Log("FormatPart1exFAT failed."); rc = 1; goto End; } @@ -1540,16 +1563,16 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) Log("Writing part2 FAT img ..."); if (0 != FormatPart2Fat(hDrive, MBR.PartTbl[1].StartSectorId)) { - log("FormatPart2Fat failed."); + Log("FormatPart2Fat failed."); rc = 1; goto End; } PROGRESS_BAR_SET_POS(PT_WRITE_STG1_IMG); Log("Writting Boot Image ............................. "); - if (WriteGrubStage1ToPhyDrive(hDrive) != 0) + if (WriteGrubStage1ToPhyDrive(hDrive, PartStyle) != 0) { - log("WriteGrubStage1ToPhyDrive failed."); + Log("WriteGrubStage1ToPhyDrive failed."); rc = 1; goto End; } @@ -1557,14 +1580,50 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) PROGRESS_BAR_SET_POS(PT_WRITE_PART_TABLE); Log("Writting Partition Table ........................ "); SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); - if (!WriteFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL)) + + if (PartStyle) { - rc = 1; - Log("Write MBR Failed, dwSize:%u ErrCode:%u", dwSize, GetLastError()); - goto End; - } + VTOY_GPT_HDR BackupHead; + LARGE_INTEGER liCurrentPosition; + + SET_FILE_POS(pPhyDrive->SizeInBytes - 512); + VentoyFillBackupGptHead(pGptInfo, &BackupHead); + if (!WriteFile(hDrive, &BackupHead, sizeof(VTOY_GPT_HDR), &dwSize, NULL)) + { + rc = 1; + Log("Write GPT Backup Head Failed, dwSize:%u (%u) ErrCode:%u", dwSize, sizeof(VTOY_GPT_INFO), GetLastError()); + goto End; + } + + SET_FILE_POS(pPhyDrive->SizeInBytes - 512 * 33); + if (!WriteFile(hDrive, pGptInfo->PartTbl, sizeof(pGptInfo->PartTbl), &dwSize, NULL)) + { + rc = 1; + Log("Write GPT Backup Part Table Failed, dwSize:%u (%u) ErrCode:%u", dwSize, sizeof(VTOY_GPT_INFO), GetLastError()); + goto End; + } - Log("Write MBR OK ..."); + SET_FILE_POS(0); + if (!WriteFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL)) + { + rc = 1; + Log("Write GPT Info Failed, dwSize:%u (%u) ErrCode:%u", dwSize, sizeof(VTOY_GPT_INFO), GetLastError()); + goto End; + } + + Log("Write GPT Info OK ..."); + } + else + { + if (!WriteFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL)) + { + rc = 1; + Log("Write MBR Failed, dwSize:%u ErrCode:%u", dwSize, GetLastError()); + goto End; + } + Log("Write MBR OK ..."); + } + //Refresh Drive Layout DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); @@ -1619,6 +1678,11 @@ End: FindProcessOccupyDisk(hDrive, pPhyDrive); } + if (pGptInfo) + { + free(pGptInfo); + } + CHECK_CLOSE_HANDLE(hDrive); return rc; } @@ -1635,13 +1699,14 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) BOOL bRet; CHAR DriveName[] = "?:\\"; CHAR DriveLetters[MAX_PATH] = { 0 }; - UINT32 StartSector; + UINT64 StartSector; UINT64 ReservedMB = 0; MBR_HEAD BootImg; MBR_HEAD MBR; + VTOY_GPT_INFO *pGptInfo = NULL; - Log("UpdateVentoy2PhyDrive PhyDrive%d <<%s %s %dGB>>", - pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, + Log("UpdateVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>", + pPhyDrive->PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId, GetHumanReadableGBSize(pPhyDrive->SizeInBytes)); PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN); @@ -1655,15 +1720,38 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) return 1; } - // Read MBR - SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); - ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); + if (pPhyDrive->PartStyle) + { + pGptInfo = malloc(sizeof(VTOY_GPT_INFO)); + if (!pGptInfo) + { + return 1; + } - StartSector = MBR.PartTbl[1].StartSectorId; - Log("StartSector in PartTbl:%u", StartSector); + memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO)); + + // Read GPT Info + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL); - ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048; - Log("Reserved Disk Space:%u MB", ReservedMB); + StartSector = pGptInfo->PartTbl[1].StartLBA; + Log("GPT StartSector in PartTbl:%llu", (ULONGLONG)StartSector); + + ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512) - 33) / 2048; + Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB); + } + else + { + // Read MBR + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); + + StartSector = MBR.PartTbl[1].StartSectorId; + Log("MBR StartSector in PartTbl:%llu", (ULONGLONG)StartSector); + + ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048; + Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB); + } GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters)); @@ -1781,7 +1869,7 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) } Log("Updating Boot Image ............................. "); - if (WriteGrubStage1ToPhyDrive(hDrive) != 0) + if (WriteGrubStage1ToPhyDrive(hDrive, pPhyDrive->PartStyle) != 0) { rc = 1; goto End; @@ -1792,6 +1880,10 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) // Use Old UUID memcpy(BootImg.BootCode + 0x180, MBR.BootCode + 0x180, 16); + if (pPhyDrive->PartStyle) + { + BootImg.BootCode[92] = 0x22; + } if (ForceMBR == FALSE && memcmp(BootImg.BootCode, MBR.BootCode, 440) == 0) { @@ -1808,16 +1900,19 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive) Log("Write Boot Image ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR); } - if (0x00 == MBR.PartTbl[0].Active && 0x80 == MBR.PartTbl[1].Active) + if (pPhyDrive->PartStyle == 0) { - Log("Need to chage 1st partition active and 2nd partition inactive."); + if (0x00 == MBR.PartTbl[0].Active && 0x80 == MBR.PartTbl[1].Active) + { + Log("Need to chage 1st partition active and 2nd partition inactive."); - MBR.PartTbl[0].Active = 0x80; - MBR.PartTbl[1].Active = 0x00; + MBR.PartTbl[0].Active = 0x80; + MBR.PartTbl[1].Active = 0x00; - SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); - bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL); - Log("Write NEW MBR ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR); + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL); + Log("Write NEW MBR ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR); + } } //Refresh Drive Layout @@ -1836,6 +1931,11 @@ End: CHECK_CLOSE_HANDLE(hDrive); + if (pGptInfo) + { + free(pGptInfo); + } + return rc; } diff --git a/Ventoy2Disk/Ventoy2Disk/Utility.c b/Ventoy2Disk/Ventoy2Disk/Utility.c index e7df557..dc8491d 100644 --- a/Ventoy2Disk/Ventoy2Disk/Utility.c +++ b/Ventoy2Disk/Ventoy2Disk/Utility.c @@ -424,7 +424,7 @@ int VentoyFillLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 Sect return 0; } -int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR) +int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR, int PartStyle) { GUID Guid; int ReservedValue; @@ -444,7 +444,14 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR) *((UINT32 *)(pMBR->BootCode + 0x1B8)) = DiskSignature; - DiskSectorCount = (UINT32)(DiskSizeBytes / 512); + if (DiskSizeBytes / 512 > 0xFFFFFFFF) + { + DiskSectorCount = 0xFFFFFFFF; + } + else + { + DiskSectorCount = (UINT32)(DiskSizeBytes / 512); + } ReservedValue = GetReservedSpaceInMB(); if (ReservedValue <= 0) @@ -456,6 +463,11 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR) ReservedSector = (UINT32)(ReservedValue * 2048); } + if (PartStyle) + { + ReservedSector += 33; // backup GPT part table + } + Log("ReservedSector: %u", ReservedSector); //Part1 @@ -480,6 +492,129 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR) return 0; } + +static int VentoyFillProtectMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR) +{ + GUID Guid; + UINT32 DiskSignature; + UINT64 DiskSectorCount; + + VentoyGetLocalBootImg(pMBR); + + CoCreateGuid(&Guid); + + memcpy(&DiskSignature, &Guid, sizeof(UINT32)); + + Log("Disk signature: 0x%08x", DiskSignature); + + *((UINT32 *)(pMBR->BootCode + 0x1B8)) = DiskSignature; + + DiskSectorCount = DiskSizeBytes / 512 - 1; + if (DiskSectorCount > 0xFFFFFFFF) + { + DiskSectorCount = 0xFFFFFFFF; + } + + memset(pMBR->PartTbl, 0, sizeof(pMBR->PartTbl)); + + pMBR->PartTbl[0].Active = 0x00; + pMBR->PartTbl[0].FsFlag = 0xee; // EE + + pMBR->PartTbl[0].StartHead = 0; + pMBR->PartTbl[0].StartSector = 1; + pMBR->PartTbl[0].StartCylinder = 0; + pMBR->PartTbl[0].EndHead = 254; + pMBR->PartTbl[0].EndSector = 63; + pMBR->PartTbl[0].EndCylinder = 1023; + + pMBR->PartTbl[0].StartSectorId = 1; + pMBR->PartTbl[0].SectorCount = (UINT32)DiskSectorCount; + + pMBR->Byte55 = 0x55; + pMBR->ByteAA = 0xAA; + + pMBR->BootCode[92] = 0x22; + + return 0; +} + + +int VentoyFillGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo) +{ + INT64 ReservedValue = 0; + UINT64 ReservedSector = 33; + UINT64 Part1SectorCount = 0; + UINT64 DiskSectorCount = DiskSizeBytes / 512; + VTOY_GPT_HDR *Head = &pInfo->Head; + VTOY_GPT_PART_TBL *Table = pInfo->PartTbl; + static GUID WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } }; + static GUID EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } }; + + VentoyFillProtectMBR(DiskSizeBytes, &pInfo->MBR); + + ReservedValue = GetReservedSpaceInMB(); + if (ReservedValue > 0) + { + ReservedSector += ReservedValue * 2048; + } + + Part1SectorCount = DiskSectorCount - ReservedSector - (VENTOY_EFI_PART_SIZE / 512) - 2048; + + memcpy(Head->Signature, "EFI PART", 8); + Head->Version[2] = 0x01; + Head->Length = 92; + Head->Crc = 0; + Head->EfiStartLBA = 1; + Head->EfiBackupLBA = DiskSectorCount - 1; + Head->PartAreaStartLBA = 34; + Head->PartAreaEndLBA = DiskSectorCount - 34; + CoCreateGuid(&Head->DiskGuid); + Head->PartTblStartLBA = 2; + Head->PartTblTotNum = 128; + Head->PartTblEntryLen = 128; + + + memcpy(&(Table[0].PartType), &WindowsDataPartType, sizeof(GUID)); + CoCreateGuid(&(Table[0].PartGuid)); + Table[0].StartLBA = 2048; + Table[0].LastLBA = 2048 + Part1SectorCount - 1; + Table[0].Attr = 0; + memcpy(Table[0].Name, L"Ventoy", 6 * 2); + + memcpy(&(Table[1].PartType), &EspPartType, sizeof(GUID)); + CoCreateGuid(&(Table[1].PartGuid)); + Table[1].StartLBA = Table[0].LastLBA + 1; + Table[1].LastLBA = Table[1].StartLBA + VENTOY_EFI_PART_SIZE / 512 - 1; + Table[1].Attr = 1; + memcpy(Table[1].Name, L"VTOYEFI", 7 * 2); + + //Update CRC + Head->PartTblCrc = VentoyCrc32(Table, sizeof(pInfo->PartTbl)); + Head->Crc = VentoyCrc32(Head, Head->Length); + + return 0; +} + +int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead) +{ + UINT64 LBA; + UINT64 BackupLBA; + + memcpy(pHead, &pInfo->Head, sizeof(VTOY_GPT_HDR)); + + LBA = pHead->EfiStartLBA; + BackupLBA = pHead->EfiBackupLBA; + + pHead->EfiStartLBA = BackupLBA; + pHead->EfiBackupLBA = LBA; + pHead->PartTblStartLBA = BackupLBA + 1 - 33; + + pHead->Crc = 0; + pHead->Crc = VentoyCrc32(pHead, pHead->Length); + + return 0; +} + CHAR GetFirstUnusedDriveLetter(void) { CHAR Letter = 'D'; diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c index 59ca86c..f8d709f 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c @@ -70,7 +70,7 @@ int ParseCmdLineOption(LPSTR lpCmdLine) return 0; } -static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR) +static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector) { int i; BOOL bRet; @@ -80,6 +80,7 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR) UINT32 PartStartSector; UINT32 PartSectorCount; CHAR PhyDrivePath[128]; + VTOY_GPT_INFO *pGpt = NULL; safe_sprintf(PhyDrivePath, "\\\\.\\PhysicalDrive%d", PhyDrive); hDrive = CreateFileA(PhyDrivePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); @@ -90,63 +91,101 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR) return FALSE; } - bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); - CHECK_CLOSE_HANDLE(hDrive); - - Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR); + bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); + Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR); if ((!bRet) || (dwSize != sizeof(MBR))) { + CHECK_CLOSE_HANDLE(hDrive); return FALSE; } if (MBR.Byte55 != 0x55 || MBR.ByteAA != 0xAA) { Log("Byte55 ByteAA not match 0x%x 0x%x", MBR.Byte55, MBR.ByteAA); + CHECK_CLOSE_HANDLE(hDrive); return FALSE; } - for (i = 0; i < 4; i++) - { - Log("=========== Partition Table %d ============", i + 1); - Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active); - Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag); - Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId); - Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount); - Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead); - Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector); - Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder); - Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead); - Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector); - Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder); - } + if (MBR.PartTbl[1].FsFlag == 0xEE) + { + pGpt = malloc(sizeof(VTOY_GPT_INFO)); + if (!pGpt) + { + CHECK_CLOSE_HANDLE(hDrive); + return FALSE; + } + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL); + CHECK_CLOSE_HANDLE(hDrive); + if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO))) + { + Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR); + return FALSE; + } - if (MBR.PartTbl[0].StartSectorId != 2048) - { - Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId); - return FALSE; - } + if (memcmp(pGpt->Head.Signature, "EFI PART", 8)) + { + Log("Invalid GPT signature"); + return FALSE; + } - PartStartSector = MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount; - PartSectorCount = VENTOY_EFI_PART_SIZE / 512; + if (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2)) + { + Log("Invalid ventoy efi part name"); + return FALSE; + } - if (MBR.PartTbl[1].FsFlag != 0xEF || - MBR.PartTbl[1].StartSectorId != PartStartSector || - MBR.PartTbl[1].SectorCount != PartSectorCount) - { - Log("Part2 not match [0x%x 0x%x] [%u %u] [%u %u]", - MBR.PartTbl[1].FsFlag, 0xEF, - MBR.PartTbl[1].StartSectorId, PartStartSector, - MBR.PartTbl[1].SectorCount, PartSectorCount); - return FALSE; - } + *Part2StartSector = pGpt->PartTbl[1].StartLBA; + } + else + { + CHECK_CLOSE_HANDLE(hDrive); - if (MBR.PartTbl[0].Active != 0x80 && MBR.PartTbl[1].Active != 0x80) - { - Log("Part1 and Part2 are both NOT active 0x%x 0x%x", MBR.PartTbl[0].Active, MBR.PartTbl[1].Active); - return FALSE; - } + for (i = 0; i < 4; i++) + { + Log("=========== Partition Table %d ============", i + 1); + Log("PartTbl.Active = 0x%x", MBR.PartTbl[i].Active); + Log("PartTbl.FsFlag = 0x%x", MBR.PartTbl[i].FsFlag); + Log("PartTbl.StartSectorId = %u", MBR.PartTbl[i].StartSectorId); + Log("PartTbl.SectorCount = %u", MBR.PartTbl[i].SectorCount); + Log("PartTbl.StartHead = %u", MBR.PartTbl[i].StartHead); + Log("PartTbl.StartSector = %u", MBR.PartTbl[i].StartSector); + Log("PartTbl.StartCylinder = %u", MBR.PartTbl[i].StartCylinder); + Log("PartTbl.EndHead = %u", MBR.PartTbl[i].EndHead); + Log("PartTbl.EndSector = %u", MBR.PartTbl[i].EndSector); + Log("PartTbl.EndCylinder = %u", MBR.PartTbl[i].EndCylinder); + } + + if (MBR.PartTbl[0].StartSectorId != 2048) + { + Log("Part1 not match %u", MBR.PartTbl[0].StartSectorId); + return FALSE; + } + + PartStartSector = MBR.PartTbl[0].StartSectorId + MBR.PartTbl[0].SectorCount; + PartSectorCount = VENTOY_EFI_PART_SIZE / 512; + + if (MBR.PartTbl[1].FsFlag != 0xEF || + MBR.PartTbl[1].StartSectorId != PartStartSector || + MBR.PartTbl[1].SectorCount != PartSectorCount) + { + Log("Part2 not match [0x%x 0x%x] [%u %u] [%u %u]", + MBR.PartTbl[1].FsFlag, 0xEF, + MBR.PartTbl[1].StartSectorId, PartStartSector, + MBR.PartTbl[1].SectorCount, PartSectorCount); + return FALSE; + } + + if (MBR.PartTbl[0].Active != 0x80 && MBR.PartTbl[1].Active != 0x80) + { + Log("Part1 and Part2 are both NOT active 0x%x 0x%x", MBR.PartTbl[0].Active, MBR.PartTbl[1].Active); + return FALSE; + } + + *Part2StartSector = MBR.PartTbl[1].StartSectorId; + } memcpy(pMBR, &MBR, sizeof(MBR_HEAD)); Log("PhysicalDrive%d is ventoy disk", PhyDrive); @@ -161,6 +200,7 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount) int Letter = 'A'; int Id = 0; int LetterCount = 0; + UINT64 Part2StartSector = 0; PHY_DRIVE_INFO *CurDrive; MBR_HEAD MBR; int LogLetter[VENTOY_MAX_PHY_DRIVE]; @@ -217,9 +257,10 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount) } } - if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR)) + if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR, &Part2StartSector)) { - GetVentoyVerInPhyDrive(CurDrive, &MBR, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion)); + CurDrive->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0; + GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion)); } } diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h index 13b71f7..dd42617 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h @@ -79,6 +79,43 @@ typedef struct MBR_HEAD UINT8 Byte55; UINT8 ByteAA; }MBR_HEAD; + +typedef struct VTOY_GPT_HDR +{ + CHAR Signature[8]; /* EFI PART */ + UINT8 Version[4]; + UINT32 Length; + UINT32 Crc; + UINT8 Reserved1[4]; + UINT64 EfiStartLBA; + UINT64 EfiBackupLBA; + UINT64 PartAreaStartLBA; + UINT64 PartAreaEndLBA; + GUID DiskGuid; + UINT64 PartTblStartLBA; + UINT32 PartTblTotNum; + UINT32 PartTblEntryLen; + UINT32 PartTblCrc; + UINT8 Reserved2[420]; +}VTOY_GPT_HDR; + +typedef struct VTOY_GPT_PART_TBL +{ + GUID PartType; + GUID PartGuid; + UINT64 StartLBA; + UINT64 LastLBA; + UINT64 Attr; + UINT16 Name[36]; +}VTOY_GPT_PART_TBL; + +typedef struct VTOY_GPT_INFO +{ + MBR_HEAD MBR; + VTOY_GPT_HDR Head; + VTOY_GPT_PART_TBL PartTbl[128]; +}VTOY_GPT_INFO; + #pragma pack() #define VENTOY_MAX_PHY_DRIVE 128 @@ -87,6 +124,7 @@ typedef struct PHY_DRIVE_INFO { int Id; int PhyDrive; + int PartStyle;//0:MBR 1:GPT UINT64 SizeInBytes; BYTE DeviceType; BOOL RemovableMedia; @@ -138,19 +176,21 @@ const CHAR * GetBusTypeString(STORAGE_BUS_TYPE Type); int VentoyGetLocalBootImg(MBR_HEAD *pMBR); int GetHumanReadableGBSize(UINT64 SizeBytes); void TrimString(CHAR *String); -int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR); +int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR, int PartStyle); +int VentoyFillGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo); BOOL IsVentoyLogicalDrive(CHAR DriveLetter); int GetRegDwordValue(HKEY Key, LPCSTR SubKey, LPCSTR ValueName, DWORD *pValue); int GetPhysicalDriveCount(void); int GetAllPhysicalDriveInfo(PHY_DRIVE_INFO *pDriveList, DWORD *pDriveCount); int GetPhyDriveByLogicalDrive(int DriveLetter); -int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, MBR_HEAD *pMBR, CHAR *VerBuf, size_t BufLen); +int GetVentoyVerInPhyDrive(const PHY_DRIVE_INFO *pDriveInfo, UINT64 Part2StartSector, CHAR *VerBuf, size_t BufLen); int Ventoy2DiskInit(void); int Ventoy2DiskDestroy(void); PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id); int ParseCmdLineOption(LPSTR lpCmdLine); -int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive); +int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle); int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive); +int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead); void SetProgressBarPos(int Pos); int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen); int INIT unxz(unsigned char *in, int in_size, @@ -164,6 +204,7 @@ int GetReservedSpaceInMB(void); int FindProcessOccupyDisk(HANDLE hDrive, PHY_DRIVE_INFO *pPhyDrive); int VentoyFillLocation(UINT64 DiskSizeInBytes, UINT32 StartSectorId, UINT32 SectorCount, PART_TABLE *Table); int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLetter); +UINT32 VentoyCrc32(void *Buffer, UINT32 Length); #define SET_FILE_POS(pos) \ liCurrentPosition.QuadPart = pos; \ diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.rc index 43075fb6642c13a25e7891e363f7af9d5a73fea9..03a4a003ff6786f74be1fe58bfdbfdc5ff5ef70b 100644 GIT binary patch delta 349 zcmcZ*@-1>hjj*UMgC~O@5QFF_23H0r27iW#&H2LnnHilY>x&2S8#0(O=m0T@G-oiK zyime)@)7Ymu&m-_J2{ETH4w1j3J%@S&t!5mpPIyGa%bybGOt^ z?#Xt%9FwQ1@<|6UBr+5+lrUt1aXv#Hg96Zq5{62KoXLp-l9RKPZaxo56AliV~CONr>?q aGnk;sn{NIgv5Rr@66r16n_p@0umAv>z!~NM diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj index f82d5fc..821d13e 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj @@ -91,6 +91,7 @@ + diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters index 9c74bea..1eac7fb 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters @@ -75,6 +75,9 @@ 源文件 + + 源文件 + diff --git a/Ventoy2Disk/Ventoy2Disk/WinDialog.c b/Ventoy2Disk/Ventoy2Disk/WinDialog.c index 42bda379646ec0cd006264f62b34c1e71f5fa502..814ba2777615c631feaaf281d273399fbc8f896e 100644 GIT binary patch delta 2747 zcmc&$ZA?>F7(SJ%x23I@LdQo-xwL$=iqKYNN})ihsMtwCC0VxlF#*Lf$Dng!bd0%V z%$W#2nz=-cEM{4dImyk8G81)a{9!UPlPy`yVr1dRvMkQ*$6`o^d+)t1?HKr#CCkZe z?>*!it>Sy#-239N!17xU6@2{q}xjJ?48tdZUY=BBSzEW|d5-P(`lz*VD$rJ2M1 zbh$Wwn{Ejvj`A4NW#Jc_6{lO&_HFDf0^Q7J2X~`kAQMY#cnF7$xci9#LNzD) z^`RtFkl6@ZVI7Bgo&OR?_^ixXm&RZuU38_4CS%g6!>Miun)OEb_G`^etcBRTL~eQ5 za`pJ8<`&}U#hARCH5MzPxx%kOoL*H-L1lw zh#Dt`bhwjOh6jsy{A@3cFO2NGT=&1W<8fY~r)bHvbskzX(N|=cFU4NNG#J^MEAGoH zQqQFi`uriU20u2X;i@Bu(F-~p-^Qb(z<~3%EHU7GpvHKbQD!9vMO;?AKtIi+!{xbf z+5PDA?m}@Rk9l^-EHmz%HDXVB9WL0?aI<{+tcGC|0c~I}vLIWDYikQ(t?(rD4BE5t z@~~8bu{pgJ-f2h;!)AQ5wty^mVKi)*ACB(jNU^kb>}#ytgcFr%I4>A*p(+D^9L>;A zjZ%mU&?97`Ry5$g%{L7}*<6X8&u&4V@G34_Icyo22j0Pfe{bOo{>N>s6%Ilzi`r<# zCf~RozX}=Yvt%wBE~gTS=g?WXaFK(uYYkgR?mOu}K=~G8)g&DoDDR>np*}gEF;eBk zy|Y=EXyKp2R;~@%w$E!gQq5tax9Ta(9na=Eb+$-71av*Y;Z~1a=yyN%mm-D!AHo2^nO5%`WGKBIz`q z5@0J?lU&NNENfU`Lg;ffZnw3Hft`~a7A{*#%G8XTrB>|h(#hgb9Bwk(SsQDm^l>Q~ zm&g!TO7c~1+% zt9uNpBuPeY9ZP?HCbg0dyhjosp=}s2MT;j(ob0aSr?^b?HHxPW-q02*adkX)rNQ@8 zaptHI{&t0MQ=;!Sr%;`s-z&rzuKRQx{s?6T%k?&P!0K&`oXomCS2UR z?#OX9>W*8*)?>pNGQ*B93UVG-d1JQx|EpxAVyA0>c@{B|uPwh1rejM1H{(e+(PG3I zUn%;1JbugP@u@F}6CcFY?a}Tl;_ zoC)n00||Okf2lB4VEd>=k6Y=CrSj@N9I lqx>p~>m=D%u28XgCr7)c&g|3a90Z32{a+P}{a;74e*;0c#p3_~ delta 477 zcmYk1OK1~e6ouzchVsv3G99K8N;;O&v`z?VO@}N*YiOx`kV;g9LZL{Ype{nxV(~#K zQpHE88gg8ST9GcK7LlR1iny>SgMuQRh3GaFmm;o2M1ntEh|BwN4(EPf{qV>6u=j>j zui`U|Oq$3YQ)w!4B*YZFk2#cSJ{m?~R-nZ=^6eTLEjq2VJdU96X%iK;?PsWOl~LcG zLeaKRy`Mw#!3t%DYq0E+&Nt7veHfr?;?SKo%v{^?e{W^MQz`Xmxt094RuuLr1NAmBo6ggN&%XK>-`cvO diff --git a/Ventoy2Disk/Ventoy2Disk/crc32.c b/Ventoy2Disk/Ventoy2Disk/crc32.c new file mode 100644 index 0000000..3af9d20 --- /dev/null +++ b/Ventoy2Disk/Ventoy2Disk/crc32.c @@ -0,0 +1,275 @@ +#include + +static UINT32 g_CrcTable[256] = { + 0x00000000, + 0x77073096, + 0xEE0E612C, + 0x990951BA, + 0x076DC419, + 0x706AF48F, + 0xE963A535, + 0x9E6495A3, + 0x0EDB8832, + 0x79DCB8A4, + 0xE0D5E91E, + 0x97D2D988, + 0x09B64C2B, + 0x7EB17CBD, + 0xE7B82D07, + 0x90BF1D91, + 0x1DB71064, + 0x6AB020F2, + 0xF3B97148, + 0x84BE41DE, + 0x1ADAD47D, + 0x6DDDE4EB, + 0xF4D4B551, + 0x83D385C7, + 0x136C9856, + 0x646BA8C0, + 0xFD62F97A, + 0x8A65C9EC, + 0x14015C4F, + 0x63066CD9, + 0xFA0F3D63, + 0x8D080DF5, + 0x3B6E20C8, + 0x4C69105E, + 0xD56041E4, + 0xA2677172, + 0x3C03E4D1, + 0x4B04D447, + 0xD20D85FD, + 0xA50AB56B, + 0x35B5A8FA, + 0x42B2986C, + 0xDBBBC9D6, + 0xACBCF940, + 0x32D86CE3, + 0x45DF5C75, + 0xDCD60DCF, + 0xABD13D59, + 0x26D930AC, + 0x51DE003A, + 0xC8D75180, + 0xBFD06116, + 0x21B4F4B5, + 0x56B3C423, + 0xCFBA9599, + 0xB8BDA50F, + 0x2802B89E, + 0x5F058808, + 0xC60CD9B2, + 0xB10BE924, + 0x2F6F7C87, + 0x58684C11, + 0xC1611DAB, + 0xB6662D3D, + 0x76DC4190, + 0x01DB7106, + 0x98D220BC, + 0xEFD5102A, + 0x71B18589, + 0x06B6B51F, + 0x9FBFE4A5, + 0xE8B8D433, + 0x7807C9A2, + 0x0F00F934, + 0x9609A88E, + 0xE10E9818, + 0x7F6A0DBB, + 0x086D3D2D, + 0x91646C97, + 0xE6635C01, + 0x6B6B51F4, + 0x1C6C6162, + 0x856530D8, + 0xF262004E, + 0x6C0695ED, + 0x1B01A57B, + 0x8208F4C1, + 0xF50FC457, + 0x65B0D9C6, + 0x12B7E950, + 0x8BBEB8EA, + 0xFCB9887C, + 0x62DD1DDF, + 0x15DA2D49, + 0x8CD37CF3, + 0xFBD44C65, + 0x4DB26158, + 0x3AB551CE, + 0xA3BC0074, + 0xD4BB30E2, + 0x4ADFA541, + 0x3DD895D7, + 0xA4D1C46D, + 0xD3D6F4FB, + 0x4369E96A, + 0x346ED9FC, + 0xAD678846, + 0xDA60B8D0, + 0x44042D73, + 0x33031DE5, + 0xAA0A4C5F, + 0xDD0D7CC9, + 0x5005713C, + 0x270241AA, + 0xBE0B1010, + 0xC90C2086, + 0x5768B525, + 0x206F85B3, + 0xB966D409, + 0xCE61E49F, + 0x5EDEF90E, + 0x29D9C998, + 0xB0D09822, + 0xC7D7A8B4, + 0x59B33D17, + 0x2EB40D81, + 0xB7BD5C3B, + 0xC0BA6CAD, + 0xEDB88320, + 0x9ABFB3B6, + 0x03B6E20C, + 0x74B1D29A, + 0xEAD54739, + 0x9DD277AF, + 0x04DB2615, + 0x73DC1683, + 0xE3630B12, + 0x94643B84, + 0x0D6D6A3E, + 0x7A6A5AA8, + 0xE40ECF0B, + 0x9309FF9D, + 0x0A00AE27, + 0x7D079EB1, + 0xF00F9344, + 0x8708A3D2, + 0x1E01F268, + 0x6906C2FE, + 0xF762575D, + 0x806567CB, + 0x196C3671, + 0x6E6B06E7, + 0xFED41B76, + 0x89D32BE0, + 0x10DA7A5A, + 0x67DD4ACC, + 0xF9B9DF6F, + 0x8EBEEFF9, + 0x17B7BE43, + 0x60B08ED5, + 0xD6D6A3E8, + 0xA1D1937E, + 0x38D8C2C4, + 0x4FDFF252, + 0xD1BB67F1, + 0xA6BC5767, + 0x3FB506DD, + 0x48B2364B, + 0xD80D2BDA, + 0xAF0A1B4C, + 0x36034AF6, + 0x41047A60, + 0xDF60EFC3, + 0xA867DF55, + 0x316E8EEF, + 0x4669BE79, + 0xCB61B38C, + 0xBC66831A, + 0x256FD2A0, + 0x5268E236, + 0xCC0C7795, + 0xBB0B4703, + 0x220216B9, + 0x5505262F, + 0xC5BA3BBE, + 0xB2BD0B28, + 0x2BB45A92, + 0x5CB36A04, + 0xC2D7FFA7, + 0xB5D0CF31, + 0x2CD99E8B, + 0x5BDEAE1D, + 0x9B64C2B0, + 0xEC63F226, + 0x756AA39C, + 0x026D930A, + 0x9C0906A9, + 0xEB0E363F, + 0x72076785, + 0x05005713, + 0x95BF4A82, + 0xE2B87A14, + 0x7BB12BAE, + 0x0CB61B38, + 0x92D28E9B, + 0xE5D5BE0D, + 0x7CDCEFB7, + 0x0BDBDF21, + 0x86D3D2D4, + 0xF1D4E242, + 0x68DDB3F8, + 0x1FDA836E, + 0x81BE16CD, + 0xF6B9265B, + 0x6FB077E1, + 0x18B74777, + 0x88085AE6, + 0xFF0F6A70, + 0x66063BCA, + 0x11010B5C, + 0x8F659EFF, + 0xF862AE69, + 0x616BFFD3, + 0x166CCF45, + 0xA00AE278, + 0xD70DD2EE, + 0x4E048354, + 0x3903B3C2, + 0xA7672661, + 0xD06016F7, + 0x4969474D, + 0x3E6E77DB, + 0xAED16A4A, + 0xD9D65ADC, + 0x40DF0B66, + 0x37D83BF0, + 0xA9BCAE53, + 0xDEBB9EC5, + 0x47B2CF7F, + 0x30B5FFE9, + 0xBDBDF21C, + 0xCABAC28A, + 0x53B39330, + 0x24B4A3A6, + 0xBAD03605, + 0xCDD70693, + 0x54DE5729, + 0x23D967BF, + 0xB3667A2E, + 0xC4614AB8, + 0x5D681B02, + 0x2A6F2B94, + 0xB40BBE37, + 0xC30C8EA1, + 0x5A05DF1B, + 0x2D02EF8D +}; + +UINT32 VentoyCrc32(void *Buffer, UINT32 Length) +{ + UINT32 Index; + UINT32 Crc; + UINT8 *Byte = Buffer; + + Crc = 0xffffffff; + for (Index = 0; Index < Length; Index++, Byte++) + { + Crc = (Crc >> 8) ^ g_CrcTable[(UINT8)Crc ^ *Byte]; + } + + return Crc ^ 0xffffffff; +} diff --git a/Ventoy2Disk/Ventoy2Disk/resource.h b/Ventoy2Disk/Ventoy2Disk/resource.h index 9de7e743bd97c2911172148a787431f251ffb9b4..fa0b4ab19f1073da8066d352c4c07ecc4180ea67 100644 GIT binary patch delta 192 zcmew+`$l1d8^`2D91)ZKSmZc^8A2E$8GIOACtqZdoLs^uF}Z+|W%52&5q?*OFot*r zgnS{3EVB`V+2)5F8<{7sVilRJ$IZcLI606*cj5!K$pKt!lO=$<1%R{xJBJ`#AJ7b6 z1}BD~i5C??ikJ-jK`1cZ+{@F;$Y?T|kx_KA0iWCCB5pAtEi!ol GUl;(IZ!bmw delta 60 zcmaE(@J)7u8^>fjW*$bvi5K-5jV8-8%TIRWh}ay)IfHpK2VV!{WH(;1$?y0?Chy`m Nn*4wR!WI(<0{~Ub6L0_k -- 2.47.3