wok view syslinux/stuff/iso2exe/win32.c @ rev 21314

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