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