wok diff syslinux/stuff/iso2exe/win32.c @ rev 25682

Up libqcow (20240308)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Mar 24 18:25:46 2024 +0000 (7 weeks ago)
parents 7744355508b9
children
line diff
     1.1 --- a/syslinux/stuff/iso2exe/win32.c	Thu May 28 08:35:55 2020 +0000
     1.2 +++ b/syslinux/stuff/iso2exe/win32.c	Sun Mar 24 18:25:46 2024 +0000
     1.3 @@ -1,9 +1,196 @@
     1.4  #include <windows.h>
     1.5  #include <winnt.h>
     1.6 +#include <winioctl.h>
     1.7 +#include <commctrl.h>
     1.8  #include <sys/types.h>
     1.9  #include <sys/stat.h>
    1.10  #include <fcntl.h>
    1.11  
    1.12 +#define e_grave "\xE8"
    1.13 +#define e_acute "\xE9"
    1.14 +#define e_circ  "\xEA"
    1.15 +#define e_trema "\xEB"
    1.16 +#define E_grave "\xC8"
    1.17 +#define E_acute "\xC9"
    1.18 +#define E_circ  "\xCA"
    1.19 +#define E_trema "\xCB"
    1.20 +#define a_grave "\xE0"
    1.21 +#define A_grave "\xC0"
    1.22 +#define a_circ  "\xE2"
    1.23 +#define A_circ  "\xC2"
    1.24 +#define c_cedil "\xE7"
    1.25 +#define C_cedil "\xC7"
    1.26 +#define i_circ  "\xEE"
    1.27 +#define I_circ  "\xCE"
    1.28 +#define i_trema "\xEF"
    1.29 +#define I_trema "\xCF"
    1.30 +#define o_circ  "\xF4"
    1.31 +#define O_circ  "\xD4"
    1.32 +#define o_trema "\xF6"
    1.33 +#define O_trema "\xD6"
    1.34 +#define u_grave "\xF9"
    1.35 +#define U_grave "\xD9"
    1.36 +#define u_circ  "\xFB"
    1.37 +#define U_circ  "\xDB"
    1.38 +#define u_trema "\xFC"
    1.39 +#define U_trema "\xDC"
    1.40 +
    1.41 +static char *MsgSet[2][27] = {
    1.42 +	{
    1.43 +#define LANG_EN	0
    1.44 +#define MSG_BUILD_KEY	0
    1.45 +		"Build the SliTaz USB key...",
    1.46 +#define MSG_EITHER_CREATE_KEY_OR_BOOT_FLOPPY	1
    1.47 +		"You can either:\n\n"
    1.48 +		"- create a SliTaz USB boot key or a boot memory card.\n"
    1.49 +		"  (note that the Linux kernel will not be upgradable.\n"
    1.50 +		"  The Slitaz utility 'tazusb' can be used later to create\n"
    1.51 +		"  a true read/write USB key).\n\n"
    1.52 +		"- create a SliTaz bootstrap floppy for the ISO image\n"
    1.53 +		"  on the hard disk.\n"
    1.54 +		"\nDo you want to create a boot key now ?",
    1.55 +#define MSG_NOT_DOS_MODE	2
    1.56 +		"This program should run in DOS mode.\n"
    1.57 +		"It can create the file slitaz.pif and launch it,\n"
    1.58 +		"but you can reboot in DOS mode too and run it.\n"
    1.59 +		"\nDo you want to create the slitaz.pif file and execute it now ?",
    1.60 +#define MSG_CRATE_PIF_NOW	3
    1.61 +		"Create slitaz.pif now ?",
    1.62 +#define MSG_NOT_HYBRID		4
    1.63 +		"Not an isolinux hybrid ISO.\n"
    1.64 +		"This ISO image will not boot\n"
    1.65 +		"from the media that you create !",
    1.66 +#define MSG_WILL_NOT_BOOT	5
    1.67 +		"Will not boot !", 
    1.68 +#define MSG_WANT_CREATE_BOOT_KEY	6
    1.69 +		"You can create a SliTaz USB boot key or\n"
    1.70 +		"a boot memory card.\n"
    1.71 +		"\nDo you want to create a boot key now ?",
    1.72 +#define MSG_Q_CREATE_STICK	7
    1.73 +		"Create a boot stick ?",
    1.74 +#define MSG_STEP_1		8
    1.75 +		"Step 1: unplug the USB stick.",
    1.76 +#define MSG_DETECT_1		9
    1.77 +		"Drive detection 1/2",
    1.78 +#define MSG_STEP_2		10
    1.79 +		"Step 2: plug the USB stick in, "
    1.80 +		"wait for Windows to mount it",
    1.81 +#define MSG_DETECT_2		11
    1.82 +		"Drive detection 2/2",
    1.83 +#define MSG_NOT_FOUND		12
    1.84 +		"No USB stick found.",
    1.85 +#define MSG_SORRY		13
    1.86 +		"Sorry",
    1.87 +#define MSG_HD0_UP_TO_DATE	14
    1.88 +		"(hd0) is up to date.",
    1.89 +#define MSG_HD0_UP_TO_DATE_BUT	15
    1.90 +		"(hd0) is up to date but the partition table is not\n"
    1.91 +		"updated because I can't get the total USB stick size\n\n"
    1.92 +		"You can boot SliTaz with this stick and you can update\n"
    1.93 +		"the partition table with 'taziso' by selecting "
    1.94 +		"'usbbootkey' as root.",
    1.95 +#define MSG_NO_REPART		16
    1.96 +		"Finished without repartitioning",
    1.97 +#define MSG_KEEP_CUSTOM_CONF	17
    1.98 +		"Do you want to keep your custom configuration ?",
    1.99 +#define MSG_KEEP_CONF		18
   1.100 +		"keep configuration ?",
   1.101 +#define MSG_WANT_HOME		19
   1.102 +		"Do you want to create a persistent partition for /home ?",
   1.103 +#define MSG_DO_HOME		20
   1.104 +		"Create a persistent /home ?",
   1.105 +#define MSG_FINISHED		21
   1.106 +		"Finished",
   1.107 +#define MSG_WANT_FLOPPY		22
   1.108 +		"Do you want to create a bootstrap floppy ?",
   1.109 +#define MSG_DO_FLOPPY		23
   1.110 +		"Create a bootstrap floppy ?",
   1.111 +#define MSG_INSERT_A_FLOPPY	24
   1.112 +		"Insert a floppy disk in drive now",
   1.113 +#define MSG_INSERT_FLOPPY	25
   1.114 +		"Insert floppy",
   1.115 +#define MSG_FLOPPY_DONE		26
   1.116 +		"The bootstrap floppy is up to date."
   1.117 +	},
   1.118 +	{
   1.119 +#define LANG_FR	1
   1.120 +// MSG_BUILD_KEY
   1.121 +		"Construit la cl" e_acute " USB SliTaz...",
   1.122 +// MSG_EITHER_CREATE_KEY_OR BOOT_FLOPPY
   1.123 +		"Vous pouvez soit :\n\n"
   1.124 +		"- cr" e_acute "er une cl" e_acute " USB ou une carte m" e_acute "moire de d" e_acute "marrage.\n"
   1.125 +		"  (notez que le noyau Linux ne pourra pas " e_circ "tre mis " a_grave " jour.\n" 
   1.126 +		"  L'outil SliTaz 'tazusb' pourra " e_circ "tre utilis" e_acute " ensuite pour cr" e_acute "er\n"
   1.127 +		"  une v" e_acute "ritable cl" e_acute " USB read/write).\n\n"
   1.128 +		"- cr" e_acute "er une disquette de d" e_acute "marrage pour une image ISO\n"
   1.129 +		"  plac" e_acute " sur le disque dur.\n"
   1.130 +		"\nVoulez vous cr" e_acute "er une disquette de d" e_acute "marrage maintenant ?",
   1.131 +// MSG_NOT_DOS_MODE
   1.132 +		"Ce programme devrait " e_circ "tre lanc" e_acute " en mode DOS.\n"
   1.133 +		"Il peut cr" e_acute "er le fichier slitaz.pif et l'ex" e_acute "cuter,\n"
   1.134 +		"mais vous pouvez aussi red" e_acute "marrer en mode DOS et le lancer.\n"
   1.135 +		"\nVoulez cr" e_acute "er le fichier slitaz.pif et le lancer maintenant ?",
   1.136 +// MSG_CRATE_PIF_NOW
   1.137 +		"Cr" e_acute "er slitaz.pif maintenant ?",
   1.138 +// MSG_NOT_HYBRID
   1.139 +		"Ce n'est pas une image ISO hybride isolinux.\n"
   1.140 +		"Cette image ISO ne d" e_acute "marrera pas\n"
   1.141 +		"depuis le media o" u_grave " vous la cr" e_acute "er !",
   1.142 +// MSG_WILL_NOT_BOOT
   1.143 +		"Ne d" e_acute "marrera pas !\n",
   1.144 +// MSG_WANT_CREATE_BOOT_KEY
   1.145 +		"Vous pouvez cr" e_acute "er une cl" e_acute " USB / carte m" e_acute "moire de d" e_acute "marrage.\n"
   1.146 +		"\nVoulez vous cr" e_acute "er une cl" e_acute " de d" e_acute "marrage maintenant ?",
   1.147 +// MSG_Q_CREATE_STICK
   1.148 +		"Cr" e_acute "er une cl" e_acute " de d" e_acute "marrage ?",
   1.149 +// MSG_STEP_1
   1.150 +		"Etape 1 : d" e_acute "branchez la cl" e_acute " USB.",
   1.151 +// MSG_DETECT_1
   1.152 +		"D" e_acute "tection du p" e_acute "riph" e_acute "rique 1/2",
   1.153 +// MSG_STEP_2
   1.154 +		"Etape 2 : rebranchez la cl" e_acute " USB, "
   1.155 +		"et attendez que Windows la reconnaisse.",
   1.156 +// MSG_DETECT_2
   1.157 +		"D" e_acute "tection du p" e_acute "riph" e_acute "rique 2/2",
   1.158 +// MSG_NOT_FOUND
   1.159 +		"Aucune cl" e_acute " USB trouv" e_acute "e.",
   1.160 +// MSG_SORRY
   1.161 +		"D" e_acute " sol" e_acute,
   1.162 +// MSG_HD0_UP_TO_DATE
   1.163 +		"(hd0) a " e_acute "t" e_acute " mis " a_grave " jour.",
   1.164 +// MSG_HD0_UP_TO_DATE_BUT
   1.165 +		"(hd0) a " e_acute "t" e_acute " mis " a_grave " jour mais la table de partition n'est pas\n"
   1.166 +		"modifi" e_acute "e car la taille totale de la cl" e_acute " USB n'a pu " e_circ "tre d" e_acute "tect" e_acute "e\n\n"
   1.167 +		"Vous pouvez d" e_acute "marrer avec cette cl" e_acute " puis vous pouvez mettre " a_grave " jour\n"
   1.168 +		"la table de partition avec 'taziso' en choisissant "
   1.169 +		"'usbbootkey' (si root).",
   1.170 +// MSG_NO_REPART
   1.171 +		"Termin" e_acute " sans repartitionement",
   1.172 +// MSG_KEEP_CUSTOM_CONF
   1.173 +		"Voulez vous conserver votre configuration personnelle ?",
   1.174 +// MSG_KEEP_CONF
   1.175 +		"Garder votre configuration ?",
   1.176 +// MSG_WANT_HOME
   1.177 +		"voulez vous cr" e_acute "er une partition persistante pour /home ?",
   1.178 +// MSG_DO_HOME
   1.179 +		"Cr" e_acute "er un /home persistant ?",
   1.180 +// MSG_FINISHED
   1.181 +		"Termin" e_acute,
   1.182 +// MSG_WANT_FLOPPY
   1.183 +		"Voulez-vous cr" e_acute "er une disquette de d" e_acute "marrage ?",
   1.184 +// MSG_DO_FLOPPY
   1.185 +		"Cr" e_acute "er une disquette de boot ?",
   1.186 +// MSG_INSERT_A_FLOPPY
   1.187 +		"Veuillez ins" e_acute "rer une disquette maintenant",
   1.188 +// MSG_INSERT_FLOPPY
   1.189 +		"Ins" e_acute "rer une disquette",
   1.190 +// MSG_FLOPPY_DONE
   1.191 +		"La disquette de d" e_acute "marage est cr" e_acute e_acute "e."
   1.192 +	}
   1.193 +};
   1.194 +static char **Msg = MsgSet[LANG_EN];
   1.195 +
   1.196 +#define BOOTSTRAP_SECTOR_COUNT_OFFSET	26
   1.197  #define BOOTSTRAP_SECTOR_COUNT_OFFSET	26
   1.198  
   1.199  static int fullread(int fd, char *p, int n)
   1.200 @@ -161,14 +348,14 @@
   1.201  };
   1.202  #pragma pack(pop)
   1.203  
   1.204 -static void exec16bits(char *isoFileName)
   1.205 +static void exec16bits(const char *isoFileName)
   1.206  {
   1.207  	int fd;
   1.208  	const char pifFileName[] = "slitaz.pif";
   1.209  
   1.210  	strcpy(PIF_content.s0.program_filename, isoFileName);
   1.211  	fd = open(pifFileName, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0555);
   1.212 -	write(fd,&PIF_content,sizeof(PIF_content));
   1.213 +	write(fd,(void*)&PIF_content,sizeof(PIF_content));
   1.214  	close(fd);
   1.215  	WinExec(pifFileName, SW_MINIMIZE);
   1.216  	exit(0);
   1.217 @@ -183,7 +370,7 @@
   1.218  }
   1.219  
   1.220  #define LONG(x)	* (unsigned long *) (x)
   1.221 -static int ishybrid(char *isoFileName)
   1.222 +static int ishybrid(const char *isoFileName)
   1.223  {
   1.224  	int fdiso;
   1.225  	char buffer[2048];
   1.226 @@ -208,11 +395,69 @@
   1.227  	return (magic == 1886961915);
   1.228  }
   1.229  
   1.230 -static char buffer[512];
   1.231 +static unsigned long crc32(void *buf, int cnt)
   1.232 +{
   1.233 +	static unsigned long t[256] = {
   1.234 +	0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
   1.235 +	0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
   1.236 +	0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
   1.237 +	0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
   1.238 +	0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
   1.239 +	0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
   1.240 +	0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
   1.241 +	0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
   1.242 +	0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
   1.243 +	0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
   1.244 +	0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
   1.245 +	0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
   1.246 +	0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
   1.247 +	0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
   1.248 +	0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
   1.249 +	0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
   1.250 +	0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
   1.251 +	0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
   1.252 +	0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
   1.253 +	0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
   1.254 +	0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
   1.255 +	0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
   1.256 +	0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
   1.257 +	0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
   1.258 +	0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
   1.259 +	0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
   1.260 +	0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
   1.261 +	0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
   1.262 +	0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
   1.263 +	0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
   1.264 +	0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
   1.265 +	0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
   1.266 +	unsigned long crc;
   1.267 +	unsigned char *p = buf;
   1.268 +	int i;
   1.269  
   1.270 -#define MODE_READ  0
   1.271 -#define MODE_WRITE 1
   1.272 -static int rdwrsector(int mode, int drive, unsigned long startingsector)
   1.273 +	for (crc=0xFFFFFFFF, i=0; i < cnt; i++) {
   1.274 +		crc=((crc >> 8) ^ t[(crc ^ p[i]) & 255]);
   1.275 +	}
   1.276 +	return crc ^ 0xFFFFFFFF;
   1.277 +}
   1.278 +
   1.279 +static char buffer[2048];
   1.280 +
   1.281 +static int getDrive(unsigned long mask)
   1.282 +{
   1.283 +	int dev;
   1.284 +	if (mask == 0) {
   1.285 +		exit(1);
   1.286 +	}
   1.287 +	for (dev = 128; (mask & 1) == 0; dev++)
   1.288 +		mask >>= 1;
   1.289 +	return dev;
   1.290 +}
   1.291 +
   1.292 +static unsigned long end = 0;
   1.293 +#define MODE_READ	0
   1.294 +#define MODE_WRITE	1
   1.295 +#define MODE_GET_SIZE	2
   1.296 +static int rdwrsector(int mode, int drive, unsigned long startingsector, int bufsiz)
   1.297  {
   1.298  	HANDLE hDevice;
   1.299  	DWORD  result;
   1.300 @@ -230,33 +475,99 @@
   1.301  		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
   1.302  	if (hDevice == INVALID_HANDLE_VALUE)
   1.303  		return -1;
   1.304 -	SetFilePointer(hDevice, (startingsector*512), NULL, FILE_BEGIN);
   1.305 +
   1.306 +	SetFilePointer(hDevice, (startingsector*bufsiz), NULL, FILE_BEGIN);
   1.307  	if (mode == MODE_READ) {
   1.308 -		if (!ReadFile(hDevice, buffer, 512, &result, NULL))
   1.309 +		if (!ReadFile(hDevice, buffer, bufsiz, &result, NULL))
   1.310 +			result = -1;
   1.311 +	}
   1.312 +	else if (mode == MODE_WRITE) {
   1.313 +		if (!WriteFile(hDevice, buffer, bufsiz, &result, NULL))
   1.314  			result = -1;
   1.315  	}
   1.316  	else {
   1.317 -		if (!WriteFile(hDevice, buffer, 512, &result, NULL))
   1.318 -			result = -1;
   1.319 +		GET_LENGTH_INFORMATION li;
   1.320 +		DWORD rsize;
   1.321 +
   1.322 +		result = -1;
   1.323 +		if (DeviceIoControl(hDevice, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &li, sizeof(li), 
   1.324 +                 		&rsize, NULL) != 0) {
   1.325 +			end = li.Length.QuadPart >> 9;
   1.326 +			result = 0;
   1.327 +		}
   1.328 +		else {
   1.329 +			long i, high;
   1.330 +			high = -1;
   1.331 +			i = GetFileSize(hDevice, &high);
   1.332 +			if (i == INVALID_FILE_SIZE) {
   1.333 +				high = -1;
   1.334 +				i = SetFilePointer(hDevice, 0, &high, FILE_END);
   1.335 +			}
   1.336 +			if (i != INVALID_SET_FILE_POINTER) {
   1.337 +				end = (high << 23)|(i >> 9);
   1.338 +				result = 0;
   1.339 +			}
   1.340 +#if 0
   1.341 +			if (result == -1) {
   1.342 +				LARGE_INTEGER size;
   1.343 +				//if (GetFileSizeEx(hDevice, &size) != 0) {
   1.344 +				if ((*GetProcAddress(GetModuleHandle("kernel32.dll"),
   1.345 +						     "GetFileSizeEx"))(hDevice, &size) != 0) {
   1.346 +					end = (size.QuadPart >> 9);
   1.347 +					result = 0;
   1.348 +				}
   1.349 +			}
   1.350 +#endif
   1.351 +#if 0
   1.352 +			if (result == -1) {
   1.353 +				for (end = 0x40000000, i = (end >> 1); i != 0; i >>= 1) {
   1.354 +					high = (end >> 23);
   1.355 +					if (SetFilePointer(hDevice, end << 9, &high, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
   1.356 +						!ReadFile(hDevice, buffer, 512, &result, NULL) || result != 512) end -= i;
   1.357 +					else end += i;
   1.358 +				}
   1.359 +				high = (end >> 23);
   1.360 +				if (SetFilePointer(hDevice, end << 9, &high, FILE_BEGIN)
   1.361 +					!= INVALID_SET_FILE_POINTER) end++;
   1.362 +				if (end > startingsector) result = 0;
   1.363 +			}
   1.364 +#endif
   1.365 +		}
   1.366 +	
   1.367  	}
   1.368  	CloseHandle(hDevice);
   1.369  	return result;
   1.370  }
   1.371  
   1.372 -static int rawrite(unsigned long drive, char *isoFileName)
   1.373 +static int rawrite(int dev, char *isoFileName)
   1.374  {
   1.375 -	int fdiso, s, dev;
   1.376 +	int fdiso, s;
   1.377 +	float next;
   1.378 +	off_t size;
   1.379 +	HWND hwndPB;
   1.380  	
   1.381 -	if (drive == 0) return;
   1.382 -	for (dev = 128; (drive & 1) == 0; dev++)
   1.383 -		drive >>= 1;
   1.384  	fdiso = open(isoFileName, O_RDONLY|O_BINARY);
   1.385 -	for (s = 0;; s++) {
   1.386 -		int n = read(fdiso, buffer, sizeof(buffer));
   1.387 +	size = lseek(fdiso,0,SEEK_END);
   1.388 +	lseek(fdiso,0,SEEK_SET);
   1.389 +	if (size != -1) { // https://docs.microsoft.com/en-us/windows/win32/controls/create-progress-bar-controls
   1.390 +		const left=100, right=100+400, bottom=80, scroll=50;
   1.391 +
   1.392 +		InitCommonControls();	// need -lcomctl32
   1.393 +		hwndPB = CreateWindowEx(0, PROGRESS_CLASS, Msg[MSG_BUILD_KEY],
   1.394 +					WS_VISIBLE | PBS_SMOOTH, left,
   1.395 +					bottom - scroll, right, scroll,
   1.396 +					NULL, (HMENU) 0, GetModuleHandle(0), NULL);
   1.397 +		if (hwndPB == NULL) size = -1;
   1.398 +		else SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, 0xFFFF));
   1.399 +	}
   1.400 +	for (s = 0, next = 0.0;; s++) {
   1.401 +		int n = read(fdiso, buffer, 2048);
   1.402  		if (n <= 0) break;
   1.403 -		rdwrsector(MODE_WRITE, dev, s);
   1.404 +		rdwrsector(MODE_WRITE, dev, s, 2048);
   1.405 +		if (size != -1) SendMessage(hwndPB, PBM_SETPOS, (WPARAM) floor((65536.0*2048.0*s)/size), 0 ); 
   1.406  	}
   1.407  	close(fdiso);
   1.408 +	if (size != -1) DestroyWindow(hwndPB);
   1.409  	return dev;
   1.410  }
   1.411  
   1.412 @@ -265,12 +576,75 @@
   1.413  	int i, mask, result;
   1.414  
   1.415  	for (i = result = 0, mask = 1; i < 8; i++, mask <<= 1) {
   1.416 -		if (rdwrsector(MODE_READ, i+128, 0) != -1)
   1.417 +		if (rdwrsector(MODE_READ, getDrive(i+128), 0, 512) != -1)
   1.418  			result |= mask;
   1.419  	}
   1.420  	return result;
   1.421  }
   1.422  
   1.423 +static int EndOfIso(int dev, unsigned long *endiso,  unsigned long *endcustom)
   1.424 +{
   1.425 +	if (rdwrsector(MODE_READ, dev, 16, 2048) == -1) return -1;
   1.426 +	*endiso = *endcustom = LONG(buffer+80);
   1.427 +	if (rdwrsector(MODE_GET_SIZE, dev, *endiso, 512) == -1) return -1;
   1.428 +	if (rdwrsector(MODE_READ, dev, *endiso, 2048) != -1 && !memcmp(buffer,"#!boot",6)) {
   1.429 +		char *s;
   1.430 +		*endcustom++;
   1.431 +		s = strstr(buffer, "\ninitrd:");
   1.432 +		if (s) {
   1.433 +			long n = strtol(s+8,&s,10);
   1.434 +			n += s - buffer;
   1.435 +			*endcustom += n/2048;
   1.436 +		}
   1.437 +		*endcustom += 511L; *endcustom &= ~511L;
   1.438 +	}
   1.439 +	return 0;
   1.440 +}
   1.441 +
   1.442 +static void AddPartition(int dev, char *label, unsigned long next)
   1.443 +{
   1.444 +	int i;
   1.445 +	unsigned long crc;
   1.446 +
   1.447 +	// https://en.wikipedia.org/wiki/GUID_Partition_Table
   1.448 +	if (rdwrsector(MODE_READ, dev, 2, 512) == -1) return;
   1.449 +	if (buffer[128+56] == 0) {
   1.450 +		static char id[16] = { 0xA2, 0xA0, 0xD0, 0xEB,
   1.451 +			0xE5, 0xB9, 0x33, 0x44, 0x87, 0xC0,
   1.452 +			0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 };
   1.453 +		memcpy(buffer + 128, id, 16);
   1.454 +		for (i = 0; i < 16; i += 2)
   1.455 +			* (unsigned short *) (buffer + 128+16 + i) = rand();
   1.456 +		for (i = 56; *label; i += 2)
   1.457 +			buffer[128+i] = *label++;
   1.458 +		LONG(buffer + 128+32) = next * 2048/512;
   1.459 +		LONG(buffer + 128+40) = end - 3;
   1.460 +	}
   1.461 +	rdwrsector(MODE_WRITE, dev, 2, 512);
   1.462 +	rdwrsector(MODE_WRITE, dev, end - 2, 512);
   1.463 +	crc = crc32(buffer, 512L);
   1.464 +	if (rdwrsector(MODE_READ, dev, 1, 512) == -1) return;
   1.465 +	LONG(buffer+88) = crc;
   1.466 +	LONG(buffer+24) = 1;		// Current header
   1.467 +	LONG(buffer+28) = 0;
   1.468 +	LONG(buffer+32) = end - 1;	// Backup header
   1.469 +	LONG(buffer+36) = 0;
   1.470 +	LONG(buffer+48) = end - 3;	// Last usable sector
   1.471 +	LONG(buffer+52) = 0;
   1.472 +	LONG(buffer+16) = 0;
   1.473 +	crc = crc32(buffer, LONG(buffer + 0x0C));
   1.474 +	LONG(buffer+16) = crc;
   1.475 +	rdwrsector(MODE_WRITE, dev, 1, 512);
   1.476 +	LONG(buffer+24) = end - 1;	// Current header
   1.477 +	LONG(buffer+28) = 0;
   1.478 +	LONG(buffer+32) = 1;		// Backup header
   1.479 +	LONG(buffer+36) = 0;
   1.480 +	LONG(buffer+16) = 0;
   1.481 +	crc = crc32(buffer, LONG(buffer + 0x0C));
   1.482 +	LONG(buffer+16) = crc;
   1.483 +	rdwrsector(MODE_WRITE, dev, end - 1, 512);
   1.484 +}
   1.485 +
   1.486  static void writefloppy(char *isoFileName)
   1.487  {
   1.488  	int i, n, fd;
   1.489 @@ -278,7 +652,7 @@
   1.490  	buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0;
   1.491  	fd = open(isoFileName, O_RDONLY|O_BINARY);
   1.492  	if (fd != -1) {
   1.493 -		read(fd, buffer, sizeof(buffer));
   1.494 +		read(fd, buffer, 512);
   1.495  		n = buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET];
   1.496  		if (n != 0 &&
   1.497  	            lseek(fd, * (unsigned short *) (buffer + 66) - (512 * n),
   1.498 @@ -286,7 +660,7 @@
   1.499  			for (i = 0; i <= n; i++) {
   1.500  				if (i == 1) strncpy(buffer, isoFileName, 512);
   1.501  				else read(fd, buffer, 512);
   1.502 -				rdwrsector(MODE_WRITE, 0, i);
   1.503 +				rdwrsector(MODE_WRITE, 0, i, 512);
   1.504  			}
   1.505  		}
   1.506  		close(fd);
   1.507 @@ -300,33 +674,24 @@
   1.508  	char header[32];
   1.509  	int fd;
   1.510  	int  usbkeyicon = MB_ICONASTERISK;
   1.511 -	char *usbkeymsg = "You can either:\n\n"
   1.512 -		"- create a SliTaz USB boot key or a boot memory card.\n"
   1.513 -		"  (note that this will be read only like a CDROM.\n"
   1.514 -		"  The Slitaz utility 'tazusb' can be used later to create\n"
   1.515 -		"  a true read/write USB key).\n\n"
   1.516 -		"- create a SliTaz bootstrap floppy for the ISO image\n"
   1.517 -		"  on the hard disk.\n"
   1.518 -		"\nDo you want to create a boot key now ?";
   1.519 +	char *usbkeymsg;
   1.520  	
   1.521  	GetModuleFileName(hInstance, isoFileName, MAX_PATH);
   1.522 -	if (!iswinnt()) {
   1.523 -		if (MessageBox(NULL,
   1.524 -			"This program must be run in DOS mode.\n"
   1.525 -			"I can create the file slitaz.pif to launch it,\n"
   1.526 -			"but you can reboot in DOS mode to run it.\n"
   1.527 -			"\nDo you want to create the slitaz.pif file and execute it now ?",
   1.528 -			"Create slitaz.pif now ?",
   1.529 +	if (iswinnt()) {
   1.530 +		LANGID lid = (*GetProcAddress(GetModuleHandle("kernel32.dll"), "GetSystemDefaultUILanguage"))();
   1.531 +		if ((lid & 0xff) == 0x0c) Msg = MsgSet[LANG_FR];
   1.532 +	}
   1.533 +	else {
   1.534 +		struct stat statbuf;
   1.535 +		if (stat("C:\\Mes Documents",&statbuf) != -1) Msg = MsgSet[LANG_FR];
   1.536 +		if (MessageBox(NULL, Msg[MSG_NOT_DOS_MODE], Msg[MSG_CRATE_PIF_NOW],
   1.537  			MB_YESNO|MB_ICONQUESTION) == IDYES) {
   1.538  			exec16bits(isoFileName);
   1.539  		}
   1.540  		exit(1);
   1.541  	}
   1.542  	if (!ishybrid(isoFileName)) {
   1.543 -		if (MessageBox(NULL,"Not an isolinux hybrid ISO.\n"
   1.544 -				    "This ISO image will not boot\n"
   1.545 -				    "from the media that you create !",
   1.546 -			   "Will not boot !", 
   1.547 +		if (MessageBox(NULL, Msg[MSG_NOT_HYBRID], Msg[MSG_WILL_NOT_BOOT],
   1.548  			   MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL)
   1.549  			exit(0);
   1.550  	}
   1.551 @@ -336,30 +701,21 @@
   1.552  		read(fd, header, sizeof(header));
   1.553  		close(fd);
   1.554  	}
   1.555 +	usbkeymsg = Msg[MSG_EITHER_CREATE_KEY_OR_BOOT_FLOPPY];
   1.556  	if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] == 0) { // No floppy bootstrap available
   1.557  		usbkeyicon = MB_ICONQUESTION;
   1.558 -		usbkeymsg =
   1.559 -		"You can create a SliTaz USB boot key or\n"
   1.560 -		"a boot memory card.\n"
   1.561 -		"(note that this will be read only like\n"
   1.562 -		"a CDROM. The Slitaz utility 'tazusb'\n"
   1.563 -		"can be used later to create a true\n"
   1.564 -		"read/write USB key).\n"
   1.565 -		"\nDo you want to create a boot key now ?";
   1.566 +		usbkeymsg = Msg[MSG_WANT_CREATE_BOOT_KEY];
   1.567  	}
   1.568 -	if (MessageBox(NULL,usbkeymsg, "Create a boot stick ?",
   1.569 +	if (MessageBox(NULL,usbkeymsg, Msg[MSG_Q_CREATE_STICK],
   1.570  			MB_YESNO|usbkeyicon) == IDYES) {
   1.571  		unsigned long base, new;
   1.572  		int retry;
   1.573  		
   1.574 -		if (MessageBox(NULL,"Step 1: unplug the USB stick.",
   1.575 -				"Drive detection 1/2",
   1.576 +		if (MessageBox(NULL, Msg[MSG_STEP_1], Msg[MSG_DETECT_1],
   1.577  				MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
   1.578  			exit(0);
   1.579  		base = drives();
   1.580 -		if (MessageBox(NULL,"Step 2: plug the USB stick in, "
   1.581 -				    "wait for Windows to mount it",
   1.582 -				"Drive detection 2/2",
   1.583 +		if (MessageBox(NULL, Msg[MSG_STEP_2], Msg[MSG_DETECT_2],
   1.584  				MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
   1.585  			exit(0);
   1.586  		retry = 0;
   1.587 @@ -368,27 +724,40 @@
   1.588  			new = drives();
   1.589  		} while (new == base && retry++ < 10);
   1.590  		if (new == base) {
   1.591 -			MessageBox(NULL,"No USB stick found.","Sorry",
   1.592 +			MessageBox(NULL, Msg[MSG_NOT_FOUND], Msg[MSG_SORRY],
   1.593  				   MB_OK|MB_ICONERROR);
   1.594  		}
   1.595  		else {
   1.596 -			char *msg = "(hd0) is up to date.";
   1.597 -			msg[3] += rawrite(base ^ new, isoFileName) - 128;
   1.598 -			MessageBox(NULL,msg,"Finished",MB_OK);
   1.599 +			unsigned long endiso, endcustom;
   1.600 +			char *msg = Msg[MSG_HD0_UP_TO_DATE];
   1.601 +			int drive = getDrive(base ^ new);
   1.602 +			msg[3] += rawrite(drive, isoFileName) - 128;
   1.603 +			if (EndOfIso(drive, &endiso, &endcustom) == -1) {
   1.604 +				char *msg2 = Msg[MSG_HD0_UP_TO_DATE_BUT];
   1.605 +				msg2[3] = msg[3];
   1.606 +				MessageBox(NULL,msg2, Msg[MSG_NO_REPART] ,MB_OK|MB_ICONEXCLAMATION);
   1.607 +			}
   1.608 +			else {
   1.609 +				static char *labels[2] = { "Basic data partition", "SliTaz persistent /home" };
   1.610 +				if (endiso != endcustom && MessageBox(NULL, Msg[MSG_KEEP_CUSTOM_CONF],
   1.611 +						Msg[MSG_KEEP_CONF], MB_YESNO|MB_ICONQUESTION) == IDYES)
   1.612 +					endiso = endcustom;
   1.613 +				AddPartition(drive, labels[MessageBox(NULL, Msg[MSG_WANT_HOME],
   1.614 +					Msg[MSG_DO_HOME], MB_YESNO|MB_ICONQUESTION) == IDYES], endiso); 
   1.615 +				MessageBox(NULL,msg, Msg[MSG_FINISHED], MB_OK);
   1.616 +			}
   1.617  		}
   1.618  	}
   1.619  	else if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] != 0 &&
   1.620 -	    MessageBox(NULL,"Do you want to create a bootstrap floppy ?",
   1.621 -			    "Create a bootstrap floppy ?",
   1.622 +	    MessageBox(NULL, Msg[MSG_WANT_FLOPPY], Msg[MSG_DO_FLOPPY],
   1.623  			MB_YESNO|MB_ICONQUESTION) == IDYES &&
   1.624 -	    MessageBox(NULL,"Insert a floppy disk in drive now",
   1.625 -			    "Insert floppy",
   1.626 +	    MessageBox(NULL, Msg[MSG_INSERT_A_FLOPPY], Msg[MSG_INSERT_FLOPPY],
   1.627  			MB_OKCANCEL|MB_ICONEXCLAMATION) != IDCANCEL) {
   1.628  
   1.629 -		// Create a 9k bootstrap with vfat, ext2 & ntfs drivers
   1.630 +		// Create a 9k bootstrap with vfat, exfat, ntfs, ext2 & usb drivers
   1.631  		// to boot the ISO image on hard disk
   1.632  		writefloppy(isoFileName);
   1.633 -		MessageBox(NULL,"The bootstrap floppy is up to date.",
   1.634 -				"Finished",MB_OK);
   1.635 +		MessageBox(NULL, Msg[MSG_FLOPPY_DONE],
   1.636 +			Msg[MSG_FINISHED], MB_OK);
   1.637  	}
   1.638  }