wok annotate syslinux/stuff/iso2exe/win32.c @ rev 20892

Remove ashism ==
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Feb 26 09:14:07 2019 +0100 (2019-02-26)
parents bbfea59cd312
children 5b74f1dbb49a
rev   line source
pascal@13974 1 #include <windows.h>
pascal@14261 2 #include <winnt.h>
pascal@14261 3 #include <sys/types.h>
pascal@14261 4 #include <sys/stat.h>
pascal@14261 5 #include <fcntl.h>
pascal@13972 6
pascal@19676 7 #define VCPI_LINUX_LOADER The DOS/EXE loader can boot in VM86 using VCPI API
pascal@18787 8 #define BOOTSTRAP_SECTOR_COUNT_OFFSET 26
pascal@14261 9
pascal@14261 10 static int fullread(int fd, char *p, int n)
pascal@13972 11 {
pascal@14261 12 int i, j;
pascal@14261 13 for (i = 0; n > 0; i += j, n -= j) {
pascal@14261 14 j = read(fd, p + i, n);
pascal@14261 15 if (j <= 0) break;
pascal@14261 16 }
pascal@14261 17 return i;
pascal@14264 18 #define read fullread
pascal@13972 19 }
pascal@14261 20
pascal@14261 21 static int fullwrite(int fd, char *p, int n)
pascal@14261 22 {
pascal@14261 23 int i, j;
pascal@14261 24 for (i = 0; n > 0; i += j, n -= j) {
pascal@14261 25 j = write(fd, p + i, n);
pascal@14261 26 if (j <= 0) break;
pascal@14261 27 }
pascal@14261 28 return i;
pascal@14264 29 #define write fullwrite
pascal@14261 30 }
pascal@14261 31
pascal@19676 32 #ifdef VCPI_LINUX_LOADER
pascal@14261 33 static void exec16bits(char *isoFileName)
pascal@14261 34 {
pascal@14261 35 int fdiso, fdtmp, i;
pascal@20881 36 char buffer[512];
pascal@14261 37 char tmpFileName[MAX_PATH], *p;
pascal@14261 38
pascal@14261 39 strcpy(tmpFileName, isoFileName);
pascal@14261 40 p = strrchr(tmpFileName, '\\');
pascal@14261 41 if (!p++) p = tmpFileName;
pascal@14261 42 strcpy(p, "tazboot.exe");
pascal@14261 43 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
pascal@14261 44 fdtmp = open(tmpFileName, O_WRONLY|O_BINARY|O_CREAT,0555);
pascal@14261 45 for (i = 0; i < 0x8000; i += sizeof(buffer)) {
pascal@14264 46 read(fdiso, (char *) buffer, sizeof(buffer));
pascal@20881 47 if (i == 0) {
pascal@20881 48 buffer[2] = buffer[3] = // reset last page size
pascal@20881 49 buffer[18] = buffer[19] = 0; // reset checksum
pascal@20881 50 buffer[63]++; // kill PE header
pascal@20881 51 }
pascal@14264 52 write(fdtmp, (char *) buffer, sizeof(buffer));
pascal@14261 53 }
pascal@14261 54 close(fdiso);
pascal@14261 55 close(fdtmp);
pascal@14261 56 execl(tmpFileName, isoFileName);
pascal@14261 57 }
pascal@19676 58 #endif
pascal@14261 59
pascal@14261 60 static int iswinnt(void)
pascal@14261 61 {
pascal@14261 62 OSVERSIONINFOA Version;
pascal@14261 63 Version.dwOSVersionInfoSize = sizeof(Version);
pascal@14261 64 return (GetVersionEx(&Version) &&
pascal@14261 65 Version.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); // not Win9x
pascal@14261 66 }
pascal@14261 67
pascal@19676 68 #define LONG(x) * (unsigned long *) (x)
pascal@14261 69 static int ishybrid(char *isoFileName)
pascal@14261 70 {
pascal@14261 71 int fdiso;
pascal@14261 72 char buffer[2048];
pascal@14261 73 unsigned long magic = 0;
pascal@14261 74
pascal@14261 75 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
pascal@14261 76 if (lseek(fdiso, 17 * 2048L, SEEK_SET) != -1 &&
pascal@14264 77 read(fdiso, buffer, 2048) == 2048 &&
pascal@14266 78 strncmp(buffer+7,"EL TORITO SPECIFICATION",23) == 0) {
pascal@19676 79 unsigned long lba = LONG(buffer + 71);
pascal@14261 80
pascal@14261 81 if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 &&
pascal@14264 82 read(fdiso, buffer, 2048) == 2048 &&
pascal@19676 83 LONG(buffer + 0) == 1 && LONG(buffer + 30) == 0x88AA55) {
pascal@19676 84 lba = LONG(buffer + 40);
pascal@14261 85 if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 &&
pascal@14264 86 read(fdiso, buffer, 2048) == 2048)
pascal@19676 87 magic = LONG(buffer + 64);
pascal@14261 88 }
pascal@14261 89 }
pascal@14261 90 close(fdiso);
pascal@14261 91 return (magic == 1886961915);
pascal@14261 92 }
pascal@14261 93
pascal@14268 94 static char buffer[512];
pascal@14268 95
pascal@14261 96 #define MODE_READ 0
pascal@14261 97 #define MODE_WRITE 1
pascal@14268 98 static int rdwrsector(int mode, int drive, unsigned long startingsector)
pascal@14261 99 {
pascal@14261 100 HANDLE hDevice;
pascal@14261 101 DWORD result;
pascal@14261 102 char devname[sizeof("\\\\.\\PhysicalDrive0")];
pascal@14261 103
pascal@14261 104 if (drive >= 128) {
pascal@14261 105 strcpy(devname, "\\\\.\\PhysicalDrive0");
pascal@14261 106 devname[17] += drive - 128;
pascal@14261 107 }
pascal@14261 108 else {
pascal@14261 109 strcpy(devname, "\\\\.\\A:");
pascal@14261 110 devname[4] += drive;
pascal@14261 111 }
pascal@19025 112 hDevice = CreateFile (devname, (mode == MODE_READ) ? GENERIC_READ : GENERIC_WRITE,
pascal@14261 113 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
pascal@14261 114 if (hDevice == INVALID_HANDLE_VALUE)
pascal@14261 115 return -1;
pascal@14261 116 SetFilePointer(hDevice, (startingsector*512), NULL, FILE_BEGIN);
pascal@14261 117 if (mode == MODE_READ) {
pascal@14268 118 if (!ReadFile(hDevice, buffer, 512, &result, NULL))
pascal@14261 119 result = -1;
pascal@14261 120 }
pascal@14261 121 else {
pascal@14268 122 if (!WriteFile(hDevice, buffer, 512, &result, NULL))
pascal@14261 123 result = -1;
pascal@14261 124 }
pascal@14261 125 CloseHandle(hDevice);
pascal@14261 126 return result;
pascal@14261 127 }
pascal@14261 128
pascal@14266 129 static int rawrite(unsigned long drive, char *isoFileName)
pascal@14261 130 {
pascal@14266 131 int fdiso, s, dev;
pascal@14261 132
pascal@14261 133 if (drive == 0) return;
pascal@14261 134 for (dev = 128; (drive & 1) == 0; dev++)
pascal@14261 135 drive >>= 1;
pascal@14261 136 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
pascal@14268 137 for (s = 0;; s++) {
pascal@19024 138 int n = read(fdiso, buffer, sizeof(buffer));
pascal@14261 139 if (n <= 0) break;
pascal@14268 140 rdwrsector(MODE_WRITE, dev, s);
pascal@14261 141 }
pascal@14261 142 close(fdiso);
pascal@14266 143 return dev;
pascal@14261 144 }
pascal@14261 145
pascal@14261 146 static unsigned long drives(void)
pascal@14261 147 {
pascal@14261 148 int i, mask, result;
pascal@14268 149
pascal@14261 150 for (i = result = 0, mask = 1; i < 8; i++, mask <<= 1) {
pascal@14268 151 if (rdwrsector(MODE_READ, i+128, 0) != -1)
pascal@14261 152 result |= mask;
pascal@14261 153 }
pascal@14261 154 return result;
pascal@14261 155 }
pascal@14261 156
pascal@14261 157 static void writefloppy(char *isoFileName)
pascal@14261 158 {
pascal@14261 159 int i, n, fd;
pascal@14261 160
pascal@14261 161 buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0;
pascal@14261 162 fd = open(isoFileName, O_RDONLY|O_BINARY);
pascal@14261 163 if (fd != -1) {
pascal@14261 164 read(fd, buffer, sizeof(buffer));
pascal@14261 165 n = buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET];
pascal@14261 166 if (n != 0 &&
pascal@14264 167 lseek(fd, * (unsigned short *) (buffer + 66) - (512 * n),
pascal@14261 168 SEEK_SET) != -1) {
pascal@14268 169 for (i = 0; i <= n; i++) {
pascal@14261 170 if (i == 1) strncpy(buffer, isoFileName, 512);
pascal@14268 171 else read(fd, buffer, 512);
pascal@14268 172 rdwrsector(MODE_WRITE, 0, i);
pascal@14261 173 }
pascal@14261 174 }
pascal@14261 175 close(fd);
pascal@14261 176 }
pascal@14261 177 }
pascal@14261 178
pascal@14261 179 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
pascal@14261 180 LPSTR lpCmdLine, int nCmdShow)
pascal@14261 181 {
pascal@14261 182 char isoFileName[MAX_PATH];
pascal@14261 183 char header[32];
pascal@14261 184 int fd;
pascal@14261 185 int usbkeyicon = MB_ICONASTERISK;
pascal@14261 186 char *usbkeymsg = "You can either:\n\n"
pascal@14261 187 "- create a SliTaz USB boot key or a boot memory card.\n"
pascal@14261 188 " (note that this will be read only like a CDROM.\n"
pascal@14261 189 " The Slitaz utility 'tazusb' can be used later to create\n"
pascal@14261 190 " a true read/write USB key).\n\n"
pascal@14261 191 "- create a SliTaz bootstrap floppy for the ISO image\n"
pascal@14261 192 " on the hard disk.\n"
pascal@14261 193 "\nDo you want to create a boot key now ?";
pascal@14261 194
pascal@14261 195 GetModuleFileName(hInstance, isoFileName, MAX_PATH);
pascal@14261 196 if (!iswinnt()) {
pascal@14261 197 #ifdef VCPI_LINUX_LOADER
pascal@20804 198 if (MessageBox(NULL,"This program must be run in DOS mode.\n"
pascal@20805 199 "I can try to launch it, but it's safer to\n"
pascal@20805 200 "reboot in DOS mode and run it at DOS prompt.",
pascal@20805 201 "Launch SliTaz now ?",
pascal@20804 202 MB_YESNO|MB_ICONQUESTION) == IDYES) {
pascal@20804 203 exec16bits(isoFileName);
pascal@20804 204 }
pascal@14261 205 #else
pascal@14261 206 MessageBox(NULL,"No support for Win9x yet.\n"
pascal@14261 207 "Retry in DOS mode without emm386.\n",
pascal@14261 208 "Sorry", MB_OK|MB_ICONERROR);
pascal@20804 209 #endif
pascal@14261 210 exit(1);
pascal@14261 211 }
pascal@14261 212 if (!ishybrid(isoFileName)) {
pascal@14261 213 if (MessageBox(NULL,"Not an isolinux hybrid ISO.\n"
pascal@14261 214 "This ISO image will not boot\n"
paul@14263 215 "from the media that you create !",
pascal@14261 216 "Will not boot !",
pascal@14261 217 MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL)
pascal@14261 218 exit(0);
pascal@14261 219 }
pascal@14261 220 header[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0;
pascal@14261 221 fd = open(isoFileName, O_RDONLY|O_BINARY);
pascal@14261 222 if (fd != -1) {
pascal@14261 223 read(fd, header, sizeof(header));
pascal@14261 224 close(fd);
pascal@14261 225 }
pascal@14261 226 if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] == 0) { // No floppy bootstrap available
pascal@14261 227 usbkeyicon = MB_ICONQUESTION;
pascal@19676 228 usbkeymsg =
pascal@19676 229 "You can create a SliTaz USB boot key or\n"
pascal@19676 230 "a boot memory card.\n"
pascal@19676 231 "(note that this will be read only like\n"
pascal@19676 232 "a CDROM. The Slitaz utility 'tazusb'\n"
pascal@19676 233 "can be used later to create a true\n"
pascal@19676 234 "read/write USB key).\n"
pascal@19676 235 "\nDo you want to create a boot key now ?";
pascal@14261 236 }
pascal@14261 237 if (MessageBox(NULL,usbkeymsg, "Create a boot stick ?",
pascal@14261 238 MB_YESNO|usbkeyicon) == IDYES) {
pascal@14261 239 unsigned long base, new;
pascal@14261 240 int retry;
pascal@14261 241
pascal@14261 242 if (MessageBox(NULL,"Step 1: unplug the USB stick.",
pascal@14261 243 "Drive detection 1/2",
pascal@14261 244 MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
pascal@14261 245 exit(0);
pascal@14261 246 base = drives();
pascal@19023 247 if (MessageBox(NULL,"Step 2: plug the USB stick in, "
pascal@19668 248 "wait for Windows to mount it",
pascal@14261 249 "Drive detection 2/2",
pascal@14261 250 MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
pascal@14261 251 exit(0);
pascal@14261 252 retry = 0;
pascal@14261 253 do {
pascal@14261 254 Sleep(1000); // ms
pascal@14261 255 new = drives();
pascal@14261 256 } while (new == base && retry++ < 10);
pascal@14261 257 if (new == base) {
pascal@14261 258 MessageBox(NULL,"No USB stick found.","Sorry",
pascal@14261 259 MB_OK|MB_ICONERROR);
pascal@14261 260 }
pascal@14266 261 else {
pascal@14266 262 char *msg = "(hd0) is up to date.";
pascal@14266 263 msg[3] += rawrite(base ^ new, isoFileName) - 128;
pascal@14266 264 MessageBox(NULL,msg,"Finished",MB_OK);
pascal@14266 265 }
pascal@14261 266 }
pascal@14266 267 else if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] != 0 &&
pascal@14261 268 MessageBox(NULL,"Do you want to create a bootstrap floppy ?",
pascal@14261 269 "Create a bootstrap floppy ?",
pascal@14261 270 MB_YESNO|MB_ICONQUESTION) == IDYES &&
pascal@14261 271 MessageBox(NULL,"Insert a floppy disk in drive now",
pascal@14261 272 "Insert floppy",
pascal@14261 273 MB_OKCANCEL|MB_ICONEXCLAMATION) != IDCANCEL) {
pascal@14261 274
pascal@14261 275 // Create a 9k bootstrap with vfat, ext2 & ntfs drivers
pascal@14261 276 // to boot the ISO image on hard disk
pascal@14261 277 writefloppy(isoFileName);
pascal@14266 278 MessageBox(NULL,"The bootstrap floppy is up to date.",
pascal@14266 279 "Finished",MB_OK);
pascal@14261 280 }
pascal@14261 281 }