larn(6): Fix two "use of index before limits check" issues.
[dragonfly.git] / usr.sbin / ndiscvt / ndisgen.sh
blobc985d1ea07c89ee0a5d2b9b6ffdde589249cec2b
1 #!/bin/sh
3 # Copyright (c) 2005
4 # Bill Paul <wpaul@windriver.com>. All rights reserved.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # 3. All advertising materials mentioning features or use of this software
15 # must display the following acknowledgement:
16 # This product includes software developed by Bill Paul.
17 # 4. Neither the name of the author nor the names of any co-contributors
18 # may be used to endorse or promote products derived from this software
19 # without specific prior written permission.
21 # THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
22 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 # ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
25 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 # THE POSSIBILITY OF SUCH DAMAGE.
33 # $FreeBSD: src/usr.sbin/ndiscvt/ndisgen.sh,v 1.6 2008/04/15 04:17:13 thompsa Exp $
36 header () {
37 clear
38 echo " =================================================================="
39 echo " ------------------ Windows(r) driver converter -------------------"
40 echo " =================================================================="
41 echo ""
44 mainmenu() {
45 header
46 echo " This script is designed to guide you through the process"
47 echo " of converting a Windows(r) binary driver module and .INF"
48 echo " specification file into a DragonFly ELF kernel module for use"
49 echo " with the NDIS compatibility system."
50 echo ""
51 echo " The following options are available:"
52 echo ""
53 echo " 1] Learn about the NDIS compatibility system"
54 echo " 2] Convert individual firmware files"
55 echo " 3] Convert driver"
56 echo " 4] Exit"
57 echo ""
58 echo -n " Enter your selection here and press return: "
59 read KEYPRESS
60 return
64 help1 () {
65 header
66 echo " General information"
67 echo ""
68 echo " The NDIS compatibility system is designed to let you use Windows(r)"
69 echo " binary drivers for networking devices with DragonFly, in cases where"
70 echo " a native DragonFly driver is not available due to hardware manufacturer"
71 echo " oversight or stupidity. NDIS stands for Network Driver Interface"
72 echo " Standard, and refers to the programming model used to write Windows(r)"
73 echo " network drivers. (These are often called \"NDIS miniport\" drivers.)"
74 echo ""
75 echo " In order to use your network device in NDIS compatibility mode,"
76 echo " you need the Windows(r) driver that goes with it. Also, the driver"
77 echo " must be compiled for the same architecture as the release of DragonFly"
78 echo " you have installed. At this time, the x86_64 architecture is"
79 echo " supported. Note that you cannot use a Windows/i386 driver"
80 echo " with DragonFly/x86_64: you must obtain a Windows/x86_64 driver."
81 echo ""
82 echo -n " Press return to continue... "
83 read KEYPRESS
84 return
87 help2() {
88 header
89 echo " Where to get drivers"
90 echo ""
91 echo " If you purchased your network card separately from your computer,"
92 echo " there should have been a driver distribution CD included with the"
93 echo " card which contains Windows(r) drivers. The NDIS compatibility"
94 echo " system is designed to emulate the NDIS API of a couple of different"
95 echo " Windows(r) releases, however it works best with drivers designed"
96 echo " for NDIS 5.0 or later. Drivers distributed for Windows 2000 should"
97 echo " work; however, for best results you should use a driver designed"
98 echo " for Windows XP or Windows Server 2003."
99 echo ""
100 echo " If your card was supplied with your computer, or is a built-in device,"
101 echo " drivers may have been included on a special driver bundle CD shipped"
102 echo " with the computer."
103 echo ""
104 echo " If you don't have a driver CD, you should be able to find a driver"
105 echo " kit on the card or computer vendor's web site."
106 echo ""
107 echo -n " Press return to continue... "
108 read KEYPRESS
109 return
112 help3 () {
113 header
114 echo " What files do I need?"
115 echo ""
116 echo " In most cases, you will need only two files: a .INF file and a .SYS"
117 echo " file. The .INF file is a text file used by the Windows(r) installer to"
118 echo " perform the driver installation. It contains information that tells"
119 echo " the installer what devices the driver supports and what registry keys"
120 echo " should be created to control driver configuration. The .SYS file"
121 echo " is the actual driver executable code in Windows(r) Portable Executable"
122 echo " (PE) format. Note that sometimes the .INF file is supplied in Unicode"
123 echo " format. Unicode .INF files must be converted to ASCII form with the"
124 echo " iconv(1) utility before this installer script can use them."
125 echo " Occasionally, a driver may require firmware or register setup"
126 echo " files that are external to the main .SYS file. These are provided"
127 echo " on the same CD with the driver itself, and sometimes have a .BIN"
128 echo " extension, though they can be named almost anything. You will need"
129 echo " these additional files to make your device work with the NDIS"
130 echo " compatibility system as well."
131 echo ""
132 echo -n " Press return to continue... "
133 read KEYPRESS
134 return
137 help4 () {
138 header
139 echo " How does it all work?"
140 echo ""
141 echo " The installer script uses the ndiscvt(1) utility to convert the .INF,"
142 echo " .SYS and optional firmware files into a DragonFly kernel module"
143 echo " (.ko) file. This module can be loaded via the kldload(8) utility or"
144 echo " loaded automatically via the /boot/loader.conf file. The ndiscvt(1)"
145 echo " utility extracts the device ID information and registry key data"
146 echo " from the .INF file and converts it into a C header file. It also uses"
147 echo " the objcopy(1) utility to convert the .SYS file and optional firmware"
148 echo " files into ELF objects. The header file is compiled into a small C"
149 echo " stub file which contains a small amount of code to interface with"
150 echo " the DragonFly module system. This stub is linked together with the"
151 echo " converted ELF objects to form a DragonFly kernel module. A static ELF"
152 echo " object (.o) file is also created. This file can be linked into a"
153 echo " static kernel image for those who want/need a fully linked kernel"
154 echo " image (possibly for embedded bootstrap purposes, or just plain old"
155 echo " experimentation)."
156 echo ""
157 echo -n " Press return to continue... "
158 read KEYPRESS
159 return
162 help5 () {
163 header
164 echo " Prerequisites"
165 echo ""
166 echo " Converting a driver requires the following utilities:"
167 echo ""
168 echo " - The DragonFly C compiler, cc(1) (part of the base install)."
169 echo " - The DragonFly linker, ld(1) (part of the base install)."
170 echo " - The objcopy(1) utility (part of the base install)."
171 echo " - The ndiscvt(1) utility (part of the base install)."
172 echo ""
173 echo " If you happen to end up with a .INF file that's in Unicode format,"
174 echo " then you'll also need:"
175 echo ""
176 echo " - The iconv(1) utility (part of the base install)."
177 echo ""
178 echo -n " Press return to continue... "
179 read KEYPRESS
180 return
183 infconv () {
184 header
185 echo " INF file validation"
187 if [ -z "$INFPATH" ]; then
188 echo ""
189 echo ""
190 echo " A .INF file is most often provided as an ASCII file, however"
191 echo " files with multilanguage support are provided in Unicode format."
192 echo " Please type in the path to your .INF file now."
193 echo ""
194 echo -n " > "
195 read INFPATH
198 if [ ${INFPATH} ] && [ -e ${INFPATH} ]; then
199 INFTYPE=`${EGREP} -i -c "Signature|.S.i.g.n.a.t.u.r.e" ${INFPATH}`
200 if [ ${INFTYPE} -le 0 ]; then
201 echo ""
202 echo " I don't recognize this file format. It may not be a valid .INF file."
203 echo ""
204 echo -n " Press enter to try again, or ^C to quit. "
205 read KEYPRESS
206 INFPATH=""
207 return
210 INFTYPE=`${EGREP} -i -c "Class.*=.*Net" ${INFPATH}`
211 if [ ${INFTYPE} -gt 0 ]; then
212 echo ""
213 echo " This .INF file appears to be ASCII."
214 echo ""
215 echo -n " Press return to continue... "
216 read KEYPRESS
217 return
220 INFTYPE=`${EGREP} -i -c ".C.l.a.s.s.*=.*N.e.t" ${INFPATH}`
221 if [ ${INFTYPE} -gt 0 ]; then
222 echo ""
223 echo " This .INF file appears to be Unicode."
224 if [ -e ${ICONVPATH} ]; then
225 echo " Trying to convert to ASCII..."
226 ${ICONVPATH} -f utf-16 -t utf-8 ${INFPATH} > ${INFFILE}
227 INFPATH=${INFFILE}
228 echo " Done."
229 echo ""
230 echo -n " Press return to continue... "
231 read KEYPRESS
232 else
233 echo " The iconv(1) utility does not appear to be installed."
234 echo " Please install this utility or convert the .INF file"
235 echo " to ASCII and run this utility again."
236 echo ""
237 exit
239 return
242 echo ""
243 echo " I don't recognize this file format. It may not be a valid .INF file."
244 echo ""
245 echo -n " Press enter to try again, or ^C to quit. "
246 read KEYPRESS
247 INFPATH=""
248 else
249 echo ""
250 echo " The file '${INFPATH}' was not found."
251 echo ""
252 echo -n " Press enter to try again, or ^C to quit. "
253 read KEYPRESS
254 INFPATH=""
256 return
259 sysconv() {
260 header
261 echo " Driver file validation"
263 if [ ! -r "$SYSPATH" ]; then
264 echo ""
265 echo ""
266 echo " Now you need to specify the name of the Windows(r) driver .SYS"
267 echo " file for your device. Note that if you are running DragonFly/x86_64,"
268 echo " then you must provide a driver that has been compiled for the"
269 echo " 64-bit Windows(r) platform."
270 echo ""
271 echo " Please type in the path to the Windows(r) driver .SYS file now."
272 echo ""
273 echo -n " > "
274 read SYSPATH
277 if [ ${SYSPATH} ] && [ -e ${SYSPATH} ]; then
278 SYSTYPE=`${FILE} ${SYSPATH}`
280 case ${SYSTYPE} in
281 *Windows*)
282 echo ""
283 echo " This .SYS file appears to be in Windows(r) PE format."
284 echo ""
285 echo -n " Press return to continue... "
286 read KEYPRESS
287 SYSBASE=`${BASENAME} ${SYSPATH} | ${TR} '.' '_'`
290 echo ""
291 echo " I don't recognize this file format. It may not be a valid .SYS file."
292 echo ""
294 echo -n " Press enter to try again, or ^C to quit. "
295 read KEYPRESS
296 SYSPATH=""
298 esac
299 else
300 echo ""
301 echo " The file '${SYSPATH}' was not found."
302 echo ""
303 echo -n " Press enter to try again, or ^C to quit. "
304 read KEYPRESS
305 SYSPATH=""
307 return
310 ndiscvt() {
311 header
312 echo " Driver file conversion"
313 echo ""
314 echo " The script will now try to convert the .INF and .SYS files"
315 echo " using the ndiscvt(1) utility. This utility can handle most"
316 echo " .INF files; however, occasionally it can fail to parse some files"
317 echo " due to subtle syntax issues: the .INF syntax is very complex,"
318 echo " and the Windows(r) parser will sometimes allow files with small"
319 echo " syntax errors to be processed correctly which ndiscvt(1) will"
320 echo " not. If the conversion fails, you may have to edit the .INF"
321 echo " file by hand to remove the offending lines."
322 echo ""
323 echo -n " Press enter to try converting the files now: "
324 read KEYPRESS
325 if ! ${NDISCVT} -i ${INFPATH} -s ${SYSPATH} -O -o ${DNAME}.h > /dev/null; then
326 echo "CONVERSION FAILED"
327 exit
328 else
329 echo ""
330 echo " Conversion was successful."
331 echo ""
332 echo -n " Press enter to continue... "
333 read KEYPRESS
335 return
338 firmcvt() {
339 while : ; do
340 header
341 echo " Firmware file conversion"
342 echo ""
343 echo " If your driver uses additional firmware files, please list them"
344 echo " below. When you're finished, just press enter to continue. (If your"
345 echo " driver doesn't need any extra firmware files, just press enter"
346 echo " to move to the next step.)"
347 echo ""
348 echo -n " > "
349 read FIRMPATH
351 if [ ${FIRMPATH} ]; then
352 if [ ! -e ${FIRMPATH} ]; then
353 echo ""
354 echo " The file '${FIRMPATH}' was not found"
355 echo ""
356 echo -n " Press enter to try again, or ^C to quit. "
357 read KEYPRESS
358 continue
360 if ! ${NDISCVT} -f ${FIRMPATH} > /dev/null; then
361 echo ""
362 echo "CONVERSION FAILED"
363 else
364 echo ""
365 echo " Conversion was successful."
366 echo ""
367 FRMBASE=`${BASENAME} ${FIRMPATH}`
368 FRMBASE="${FRMBASE}.o"
369 FRMLIST="${FRMLIST} ${FRMBASE}"
371 echo -n " Press enter to continue... "
372 read KEYPRESS
373 else
374 break
376 done
378 header
379 echo ""
380 echo " List of files converted firmware files:"
381 echo ""
382 for i in ${FRMLIST}
384 echo " "$i
385 done
386 echo ""
387 echo -n " Press enter to continue... "
388 read KEYPRESS
389 return
392 drvgen () {
393 header
394 echo " Kernel module generation"
395 echo ""
396 echo ""
397 echo " The script will now try to generate the kernel driver module."
398 echo " This is the last step. Once this module is generated, you should"
399 echo " be able to load it just like any other DragonFly driver module."
400 echo ""
401 echo " Press enter to compile the stub module and generate the driver"
402 echo -n " module now: "
403 read KEYPRESS
404 echo ""
405 echo -n " Generating Makefile... "
406 echo ".PATH: ${PWD} ${STUBPATH}" > ${MAKEFILE}
407 echo "KMOD= ${SYSBASE}" >> ${MAKEFILE}
408 echo "SRCS+= ${STUBFILE} ${DNAME}.h bus_if.h device_if.h" >> ${MAKEFILE}
409 echo "OBJS+=${FRMLIST} ${DNAME}.o" >> ${MAKEFILE}
410 echo "KCFLAGS+= \\" >> ${MAKEFILE}
411 echo " -DDRV_DATA_START=ndis_${SYSBASE}_drv_data_start \\" >> ${MAKEFILE}
412 echo " -DDRV_NAME=ndis_${SYSBASE} \\" >> ${MAKEFILE}
413 echo " -DDRV_DATA_END=ndis_${SYSBASE}_drv_data_end" >> ${MAKEFILE}
414 echo "CLEANFILES+= \\" >> ${MAKEFILE}
415 echo " ${INFFILE} \\" >> ${MAKEFILE}
416 echo " ${DNAME}.h \\" >> ${MAKEFILE}
417 echo " ${DNAME}.o" >> ${MAKEFILE}
418 echo ".include <bsd.kmod.mk>" >> ${MAKEFILE}
419 if [ -f ${MAKEFILE} ]; then
420 echo "done."
421 else
422 echo "generating Makefile failed. Exiting."
423 echo ""
424 exit
426 echo -n " Building kernel module... "
427 echo "" > bus_if.h
428 echo "" > device_if.h
429 if ! ${MAKE} -f ${MAKEFILE} depend > /dev/null; then
430 echo "build failed. Exiting."
431 echo ""
432 exit
434 if ! ${MAKE} -f ${MAKEFILE} all > /dev/null; then
435 echo "build failed. Exiting."
436 echo ""
437 exit
438 else
439 if [ -f ${SYSBASE}.ko ]; then
440 ${MV} ${SYSBASE}.ko ${SYSBASE}.kmod
441 echo "done."
442 else
443 echo "build failed. Exiting."
444 echo ""
445 exit
448 echo -n " Cleaning up... "
449 if ! ${MAKE} -f ${MAKEFILE} clean cleandepend > /dev/null; then
450 echo "cleanup failed. Exiting."
451 echo ""
452 exit
453 else
454 echo "done."
456 ${RM} ${MAKEFILE}
457 ${MV} ${SYSBASE}.kmod ${SYSBASE}.ko
458 echo ""
459 echo " The file ${SYSBASE}.ko has been successfully generated."
460 echo " You can kldload this module to get started."
461 echo ""
462 echo -n " Press return to exit. "
463 read KEYPRESS
464 echo ""
465 echo ""
466 return
469 convert_driver () {
470 while : ; do
471 infconv
472 if [ ${INFPATH} ]; then
473 break
475 done
477 while : ; do
478 sysconv
479 if [ ${SYSPATH} ]; then
480 break
482 done
484 ndiscvt
485 firmcvt
486 drvgen
487 return
490 ICONVPATH=/usr/bin/iconv
491 NDISCVT=/usr/sbin/ndiscvt
492 STUBPATH=/usr/share/misc
493 STUBFILE=windrv_stub.c
494 DNAME=windrv
495 CP=/bin/cp
496 MV=/bin/mv
497 RM=/bin/rm
498 TR=/usr/bin/tr
499 FILE=/usr/bin/file
500 EGREP=/usr/bin/egrep
501 MAKE=/usr/bin/make
502 BASENAME=/usr/bin/basename
503 TOUCH=/usr/bin/touch
504 MKTEMP=/usr/bin/mktemp
506 MAKEFILE=`${MKTEMP} /tmp/Makefile.XXXXXX`
507 INFFILE=`${MKTEMP} /tmp/ascii_inf.XXXXXX`
509 INFPATH=""
510 FRMLIST=""
511 SYSPATH=""
512 SYSBASE=""
513 FRMBASE=""
515 if [ -r "$1" -a -r "$2" ]; then
516 # Looks like the user supplied .INF and .SYS files on the command line
517 INFPATH=$1
518 SYSPATH=$2
519 convert_driver && exit 0
522 while : ; do
523 mainmenu
524 case ${KEYPRESS} in
526 help1
527 help2
528 help3
529 help4
530 help5
533 firmcvt
536 convert_driver
539 header
540 echo ""
541 echo " Be seeing you!"
542 echo ""
543 exit
546 header
547 echo ""
548 echo -n " Sorry, I didn't understand that. Press enter to try again: "
549 read KEYPRESS
551 esac
552 done
553 exit