wok-next diff syslinux/stuff/iso2exe/win32.c @ rev 14261
syslinux/iso2exe: add NT+ support
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Mar 30 18:36:46 2013 +0100 (2013-03-30) |
parents | 65b3fd0022ed |
children | 692d9593f959 |
line diff
1.1 --- a/syslinux/stuff/iso2exe/win32.c Thu Mar 28 11:51:42 2013 +0100 1.2 +++ b/syslinux/stuff/iso2exe/win32.c Sat Mar 30 18:36:46 2013 +0100 1.3 @@ -1,6 +1,259 @@ 1.4 #include <windows.h> 1.5 +#include <winnt.h> 1.6 +#include <sys/types.h> 1.7 +#include <sys/stat.h> 1.8 +#include <fcntl.h> 1.9 1.10 -int main() 1.11 +#define BOOTSTRAP_SECTOR_COUNT_OFFSET 28 1.12 + 1.13 +static int fullread(int fd, char *p, int n) 1.14 { 1.15 - MessageBox(NULL,"No support for Windows yet.","Sorry",MB_OK|MB_ICONERROR); 1.16 + int i, j; 1.17 + for (i = 0; n > 0; i += j, n -= j) { 1.18 + j = read(fd, p + i, n); 1.19 + if (j <= 0) break; 1.20 + } 1.21 + return i; 1.22 } 1.23 + 1.24 +static int fullwrite(int fd, char *p, int n) 1.25 +{ 1.26 + int i, j; 1.27 + for (i = 0; n > 0; i += j, n -= j) { 1.28 + j = write(fd, p + i, n); 1.29 + if (j <= 0) break; 1.30 + } 1.31 + return i; 1.32 +} 1.33 + 1.34 +static void exec16bits(char *isoFileName) 1.35 +{ 1.36 + int fdiso, fdtmp, i; 1.37 + long buffer[512/4]; 1.38 + char tmpFileName[MAX_PATH], *p; 1.39 + 1.40 + strcpy(tmpFileName, isoFileName); 1.41 + p = strrchr(tmpFileName, '\\'); 1.42 + if (!p++) p = tmpFileName; 1.43 + strcpy(p, "tazboot.exe"); 1.44 + fdiso = open(isoFileName, O_RDONLY|O_BINARY); 1.45 + fdtmp = open(tmpFileName, O_WRONLY|O_BINARY|O_CREAT,0555); 1.46 + for (i = 0; i < 0x8000; i += sizeof(buffer)) { 1.47 + fullread(fdiso, (char *) buffer, sizeof(buffer)); 1.48 + if (i == 0) buffer[15] = 0; // kill PE header 1.49 + fullwrite(fdtmp, (char *) buffer, sizeof(buffer)); 1.50 + } 1.51 + close(fdiso); 1.52 + close(fdtmp); 1.53 + execl(tmpFileName, isoFileName); 1.54 +} 1.55 + 1.56 +static int iswinnt(void) 1.57 +{ 1.58 + OSVERSIONINFOA Version; 1.59 + Version.dwOSVersionInfoSize = sizeof(Version); 1.60 + return (GetVersionEx(&Version) && 1.61 + Version.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); // not Win9x 1.62 +} 1.63 + 1.64 +static int ishybrid(char *isoFileName) 1.65 +{ 1.66 + int fdiso; 1.67 + char buffer[2048]; 1.68 + unsigned long magic = 0; 1.69 + 1.70 + fdiso = open(isoFileName, O_RDONLY|O_BINARY); 1.71 + if (lseek(fdiso, 17 * 2048L, SEEK_SET) != -1 && 1.72 + fullread(fdiso, buffer, 2048) == 2048 && 1.73 + strncmp(buffer+23,"EL TORITO SPECIFICATION",23) == 0) { 1.74 + unsigned long lba = * (unsigned long *) (buffer + 71); 1.75 + 1.76 + if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 && 1.77 + fullread(fdiso, buffer, 2048) == 2048 && 1.78 + * (unsigned long *) (buffer + 0) == 1 && 1.79 + * (unsigned long *) (buffer + 30) == 0x88AA55) { 1.80 + lba = * (unsigned long *) (buffer + 40); 1.81 + if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 && 1.82 + fullread(fdiso, buffer, 2048) == 2048) 1.83 + magic = * (unsigned long *) (buffer + 64); 1.84 + } 1.85 + } 1.86 + close(fdiso); 1.87 + return (magic == 1886961915); 1.88 +} 1.89 + 1.90 +#define MODE_READ 0 1.91 +#define MODE_WRITE 1 1.92 +static int rdwrsector(int mode, int drive, unsigned long startingsector, 1.93 + unsigned long count, char *buffer) 1.94 +{ 1.95 + HANDLE hDevice; 1.96 + DWORD result; 1.97 + char devname[sizeof("\\\\.\\PhysicalDrive0")]; 1.98 + 1.99 + if (drive >= 128) { 1.100 + strcpy(devname, "\\\\.\\PhysicalDrive0"); 1.101 + devname[17] += drive - 128; 1.102 + } 1.103 + else { 1.104 + strcpy(devname, "\\\\.\\A:"); 1.105 + devname[4] += drive; 1.106 + } 1.107 + hDevice = CreateFile (devname, GENERIC_READ, 1.108 + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 1.109 + if (hDevice == INVALID_HANDLE_VALUE) 1.110 + return -1; 1.111 + SetFilePointer(hDevice, (startingsector*512), NULL, FILE_BEGIN); 1.112 + if (mode == MODE_READ) { 1.113 + if (!ReadFile(hDevice, buffer, 512*count, &result, NULL)) 1.114 + result = -1; 1.115 + } 1.116 + else { 1.117 + if (!WriteFile(hDevice, buffer, 512*count, &result, NULL)) 1.118 + result = -1; 1.119 + } 1.120 + CloseHandle(hDevice); 1.121 + return result; 1.122 +} 1.123 + 1.124 +static void rawrite(unsigned long drive, char *isoFileName) 1.125 +{ 1.126 + int fdiso, s, dev, isohybrid = -1; 1.127 + char buffer[2048]; 1.128 + 1.129 + if (drive == 0) return; 1.130 + for (dev = 128; (drive & 1) == 0; dev++) 1.131 + drive >>= 1; 1.132 + fdiso = open(isoFileName, O_RDONLY|O_BINARY); 1.133 + for (s = 0;;) { 1.134 + int s, n = fullread(fdiso, buffer, sizeof(buffer)); 1.135 + if (n <= 0) break; 1.136 + n = (n+511)/512; 1.137 + if (s == 0) isohybrid = buffer[69]; 1.138 + rdwrsector(MODE_WRITE, dev, s, n, buffer); 1.139 + if (s == isohybrid) 1.140 + rdwrsector(MODE_WRITE, dev, 0, 1, buffer); 1.141 + s += n; 1.142 + } 1.143 + close(fdiso); 1.144 +} 1.145 + 1.146 +static unsigned long drives(void) 1.147 +{ 1.148 + int i, mask, result; 1.149 + char buffer[512]; 1.150 + for (i = result = 0, mask = 1; i < 8; i++, mask <<= 1) { 1.151 + if (rdwrsector(MODE_READ, i+128, 0, 1, buffer) != -1) 1.152 + result |= mask; 1.153 + } 1.154 + return result; 1.155 +} 1.156 + 1.157 +static void writefloppy(char *isoFileName) 1.158 +{ 1.159 + char buffer[512]; 1.160 + int i, n, fd; 1.161 + 1.162 + buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0; 1.163 + fd = open(isoFileName, O_RDONLY|O_BINARY); 1.164 + if (fd != -1) { 1.165 + read(fd, buffer, sizeof(buffer)); 1.166 + n = buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET]; 1.167 + if (n != 0 && 1.168 + lseek(fd, * (unsigned long *) (buffer + 60) - (512 * n), 1.169 + SEEK_SET) != -1) { 1.170 + for (i = 0; i < n; i++) { 1.171 + fullread(fd, buffer, 512); 1.172 + if (i == 1) strncpy(buffer, isoFileName, 512); 1.173 + rdwrsector(MODE_WRITE, 0, i, 1, buffer); 1.174 + } 1.175 + } 1.176 + close(fd); 1.177 + } 1.178 +} 1.179 + 1.180 +//TODO #define VCPI_LINUX_LOADER The DOS/EXE loader can boot in VM86 using VCPI API 1.181 +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 1.182 + LPSTR lpCmdLine, int nCmdShow) 1.183 +{ 1.184 + char isoFileName[MAX_PATH]; 1.185 + char header[32]; 1.186 + int fd; 1.187 + int usbkeyicon = MB_ICONASTERISK; 1.188 + char *usbkeymsg = "You can either:\n\n" 1.189 + "- create a SliTaz USB boot key or a boot memory card.\n" 1.190 + " (note that this will be read only like a CDROM.\n" 1.191 + " The Slitaz utility 'tazusb' can be used later to create\n" 1.192 + " a true read/write USB key).\n\n" 1.193 + "- create a SliTaz bootstrap floppy for the ISO image\n" 1.194 + " on the hard disk.\n" 1.195 + "\nDo you want to create a boot key now ?"; 1.196 + 1.197 + GetModuleFileName(hInstance, isoFileName, MAX_PATH); 1.198 + if (!iswinnt()) { 1.199 +#ifdef VCPI_LINUX_LOADER 1.200 + exec16bits(isoFileName); 1.201 +#else 1.202 + MessageBox(NULL,"No support for Win9x yet.\n" 1.203 + "Retry in DOS mode without emm386.\n", 1.204 + "Sorry", MB_OK|MB_ICONERROR); 1.205 + exit(1); 1.206 +#endif 1.207 + } 1.208 + if (!ishybrid(isoFileName)) { 1.209 + if (MessageBox(NULL,"Not an isolinux hybrid ISO.\n" 1.210 + "This ISO image will not boot\n" 1.211 + "from the media you will create !", 1.212 + "Will not boot !", 1.213 + MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL) 1.214 + exit(0); 1.215 + } 1.216 + header[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0; 1.217 + fd = open(isoFileName, O_RDONLY|O_BINARY); 1.218 + if (fd != -1) { 1.219 + read(fd, header, sizeof(header)); 1.220 + close(fd); 1.221 + } 1.222 + if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] == 0) { // No floppy bootstrap available 1.223 + usbkeyicon = MB_ICONQUESTION; 1.224 + usbkeymsg = "Do you want to create a boot key ?"; 1.225 + } 1.226 + if (MessageBox(NULL,usbkeymsg, "Create a boot stick ?", 1.227 + MB_YESNO|usbkeyicon) == IDYES) { 1.228 + unsigned long base, new; 1.229 + int retry; 1.230 + 1.231 + if (MessageBox(NULL,"Step 1: unplug the USB stick.", 1.232 + "Drive detection 1/2", 1.233 + MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL) 1.234 + exit(0); 1.235 + base = drives(); 1.236 + if (MessageBox(NULL,"Step 2: plug the USB stick in.", 1.237 + "Drive detection 2/2", 1.238 + MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL) 1.239 + exit(0); 1.240 + retry = 0; 1.241 + do { 1.242 + Sleep(1000); // ms 1.243 + new = drives(); 1.244 + } while (new == base && retry++ < 10); 1.245 + if (new == base) { 1.246 + MessageBox(NULL,"No USB stick found.","Sorry", 1.247 + MB_OK|MB_ICONERROR); 1.248 + exit(1); 1.249 + } 1.250 + rawrite(base ^ new, isoFileName); 1.251 + } 1.252 + if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] != 0 && 1.253 + MessageBox(NULL,"Do you want to create a bootstrap floppy ?", 1.254 + "Create a bootstrap floppy ?", 1.255 + MB_YESNO|MB_ICONQUESTION) == IDYES && 1.256 + MessageBox(NULL,"Insert a floppy disk in drive now", 1.257 + "Insert floppy", 1.258 + MB_OKCANCEL|MB_ICONEXCLAMATION) != IDCANCEL) { 1.259 + 1.260 + // Create a 9k bootstrap with vfat, ext2 & ntfs drivers 1.261 + // to boot the ISO image on hard disk 1.262 + writefloppy(isoFileName); 1.263 + } 1.264 +}