Compare commits

...

1 Commits

Author SHA1 Message Date
The ReactOS Team
63b2a4f19c This commit was manufactured by cvs2svn to create tag 'krnl0018'.
svn path=/tags/krnl0018/; revision=2136
2001-08-02 08:09:11 +00:00
298 changed files with 104 additions and 63499 deletions

View File

@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@@ -1,145 +0,0 @@
# FreeLoader by Brian Palmer
# FREELDR.INI - FreeLoader Initialization file
#
# Each line must be less than 1024 characters long
# and must be either a section heading (i.e. [section_name])
# or a setting (i.e. name=value) or a blank line.
# Comments start with a '#' character.
# Background colors can be any one of the following:
# Black
# Blue
# Green
# Cyan
# Red
# Magenta
# Brown
# Gray
# Text colors can be any one of the background
# colors and any of the following:
# DarkGray
# LightBlue
# LightGreen
# LightCyan
# LightRed
# LightMagenta
# Yellow
# White
# [FREELOADER] Section Commands:
#
# MessageBox - displays the specified text in a message box upon bootup
# MessageLine - adds a new line of text to a message box (must come before MessageBox command)
# TitleText - text that is displayed in the title box
# StatusBarColor - color of status bar's background
# StatusBarTextColor - color of status bar's text
# BackdropTextColor - color of the backdrop's fill
# BackdropColor - color of the backdrop's background
# BackdropFillStyle - backdrop fill style - can be Light, Medium, or Dark
# TitleBoxTextColor - title box text color
# TitleBoxColor - title box background color
# MessageBoxTextColor - message box text color
# MessageBoxColor - message box background color
# MenuTextColor - menu text color
# MenuColor - menu color
# TextColor - normal text color
# SelectedTextColor - selected text color
# SelectedColor - selected text background color
# TimeOut - sets the timeout (in seconds) before the first OS listed gets booted automagically
# [OS-General] Section Commands:
#
# BootType - sets the boot type: ReactOS, Linux, BootSector, Partition, Drive
# BootDrive - sets the boot drive: 0 - first floppy, 1 - second floppy, 0x80 - first hard disk, 0x81 - second hard disk
# BootPartition - sets the boot partition
# [BootSector OSType] Section Commands:
#
# BootSector - sets the filename of the bootsector to be loaded
# [ReactOS OSType] Section Commands:
#
# SystemPath - sets the system root path (must be a valid ARC - Path):
# multi(0)disk(0)rdisk(0)partition(1)\reactos
# multi(0)disk(0)fdisk(0)
# Options - sets the command line options for the kernel being booted
# Kernel - sets the kernel filename
# Driver - sets the name of one or more drivers to be loaded (one entry per driver)
[FREELOADER]
MessageLine=Welcome to FreeLoader!
MessageLine=Copyright (c) 2000 by Brian Palmer <brianp@sginet.com>
MessageLine=
MessageBox=Edit your FREELDR.INI file to change your boot settings.
TitleText=Boot Menu
StatusBarColor=Cyan
StatusBarTextColor=Black
BackdropTextColor=White
BackdropColor=Blue
BackdropFillStyle=Medium
TitleBoxTextColor=White
TitleBoxColor=Red
MessageBoxTextColor=White
MessageBoxColor=Blue
MenuTextColor=White
MenuColor=Blue
TextColor=Yellow
SelectedTextColor=Black
SelectedColor=Gray
OS=ReactOS (HD)
OS=ReactOS (Floppy)
#OS=ReactOS (Debug)
#OS=Linux
OS=3<> Floppy (A:)
OS=Microsoft Windows (C:)
OS=Drive D:
#TimeOut=0
# Load ReactOS from harddisk (drive C:)
# - does not work on large harddisks
[ReactOS (HD)]
BootType=ReactOS
SystemPath=multi(0)disk(0)rdisk(0)partition(1)\reactos
Options=/DEBUGPORT=SCREEN
Kernel=NTOSKRNL.EXE
Driver=IDE.SYS
Driver=VFATFS.SYS
# Load ReactOS from floppy (drive A:)
[ReactOS (Floppy)]
BootType=ReactOS
SystemPath=multi(0)disk(0)fdisk(0)
Options=/DEBUGPORT=SCREEN
Kernel=NTOSKRNL.EXE
Driver=IDE.SYS
Driver=VFATFS.SYS
#[ReactOS (Debug)]
#BootType=ReactOS
#BootDrive=0
#Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=19200
#Kernel=\NTOSKRNL.EXE
#Driver=\DRIVERS\IDE.SYS
#Driver=\DRIVERS\VFATFS.SYS
#[Linux]
# Linux boot type not implemented yet
#BootType=Partition
#BootDrive=0x80
#BootPartition=2
[3<> Floppy (A:)]
BootType=Drive
BootDrive=0
[Microsoft Windows (C:)]
BootType=Drive
BootDrive=0x80
[Drive D:]
BootType=Partition
BootDrive=0x81
BootPartition=1

View File

@@ -1,43 +0,0 @@
#
# FreeLoader
# Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
export CC = gcc
export LD = ld
export AR = ar
export RM = cmd /C del
export CP = cmd /C copy
export NASM = nasm
export MAKE = make
.PHONY : bootsect freeldr install clean
all: bootsect freeldr install
bootsect:
$(MAKE) -C bootsect
freeldr: bootsect
$(MAKE) -C freeldr
install:
$(MAKE) -C install
clean:
$(RM) *.bin

View File

@@ -1,54 +0,0 @@
#
# FreeLoader
# Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
export CC = gcc
export LD = ld
export AR = ar
export RM = cmd /C del
export CP = cmd /C copy
export NASM = nasm
.PHONY : clean
all: fat.bin fat32.bin bin2c.exe split.exe stubit.exe
fat.bin: fat.asm bin2c.exe split.exe
$(NASM) -o fat_tmp.bin -f bin fat.asm
split fat_tmp.bin fat.bin fatstub.bin 512
$(RM) fat_tmp.bin
bin2c fat.bin fat.h fat_data
fat32.bin: fat32.asm bin2c.exe
$(NASM) -o fat32.bin -f bin fat32.asm
bin2c fat32.bin fat32.h fat32_data
bin2c.exe: bin2c.c
$(CC) -o bin2c.exe bin2c.c
split.exe: split.c
$(CC) -o split.exe split.c
stubit.exe: stubit.c
$(CC) -o stubit.exe stubit.c
clean:
$(RM) *.bin
$(RM) *.exe
$(RM) *.h

View File

@@ -1,48 +0,0 @@
#include <stdio.h>
FILE *in;
FILE *out;
int main(int argc, char *argv[])
{
unsigned char ch;
int cnt = 0;
if (argc < 4)
{
printf("usage: bin2c infile.bin outfile.h array_name\n");
return -1;
}
if ((in = fopen(argv[1], "rb")) == NULL)
{
printf("Couldn't open data file.\n");
return -1;
}
if ((out = fopen(argv[2], "wb")) == NULL)
{
printf("Couldn't open output file.\n");
return -1;
}
fprintf(out, "unsigned char %s[] = {\n", argv[3]);
ch = fgetc(in);
while (!feof(in))
{
if (cnt != 0)
fprintf(out, ", ");
if (!(cnt % 16))
fprintf(out, "\n");
fprintf(out, "0x%02x", (int)ch);
cnt++;
ch = fgetc(in);
}
fprintf(out, "\n};");
fclose(in);
fclose(out);
return 0;
}

View File

@@ -1,494 +0,0 @@
; FAT.ASM
; FAT12/16 Boot Sector
; Copyright (c) 1998, 2001 Brian Palmer
; This is a FAT12/16 file system boot sector
; that searches the entire root directory
; for the file freeldr.sys and loads it into
; memory.
;
; The stack is set to 0000:7C00 so that the first
; DWORD pushed will be placed at 0000:7BFC
;
; When it locates freeldr.sys on the disk it will
; load the first sector of the file to 0000:7E00
; With the help of this sector we should be able
; to load the entire file off the disk, no matter
; how fragmented it is.
;
; We load the entire FAT table into memory at
; 7000:0000. This improves the speed of floppy disk
; boots dramatically.
org 7c00h
segment .text
bits 16
start:
jmp short main
nop
OEMName db 'FrLdr1.0'
BytesPerSector dw 512
SectsPerCluster db 1
ReservedSectors dw 1
NumberOfFats db 2
MaxRootEntries dw 224
TotalSectors dw 2880
MediaDescriptor db 0f0h
SectorsPerFat dw 9
SectorsPerTrack dw 18
NumberOfHeads dw 2
HiddenSectors dd 0
TotalSectorsBig dd 0
BootDrive db 0
Reserved db 0
ExtendSig db 29h
SerialNumber dd 00000000h
VolumeLabel db 'NO NAME '
FileSystem db 'FAT12 '
main:
cli
cld
xor ax,ax
mov ss,ax
mov bp,7c00h
mov sp,bp ; Setup a stack
mov ax,cs ; Setup segment registers
mov ds,ax ; Make DS correct
mov es,ax ; Make ES correct
sti ; Enable ints now
mov [BYTE bp+BootDrive],dl ; Save the boot drive
xor ax,ax ; Zero out AX
; Reset disk controller
int 13h
jnc Continue1
jmp BadBoot ; Reset failed...
Continue1:
; Now we must find our way to the first sector of the root directory
xor ax,ax
xor dx,dx
mov al,[BYTE bp+NumberOfFats] ; Number of fats
mul WORD [BYTE bp+SectorsPerFat] ; Times sectors per fat
add ax,WORD [BYTE bp+HiddenSectors]
adc dx,WORD [BYTE bp+HiddenSectors+2] ; Add the number of hidden sectors
add ax,WORD [BYTE bp+ReservedSectors] ; Add the number of reserved sectors
adc dx,byte 0 ; Add carry bit
push ax ; Store it on the stack
push dx ; Save 32-bit logical start sector
push ax
push dx ; Save it for later use also
; DX:AX now has the number of the starting sector of the root directory
; Now calculate the size of the root directory
mov ax,0020h ; Size of dir entry
mul WORD [BYTE bp+MaxRootEntries] ; Times the number of entries
mov bx,[BYTE bp+BytesPerSector]
add ax,bx
dec ax
div bx ; Divided by the size of a sector
; AX now has the number of root directory sectors
xchg ax,cx ; Now CX has number of sectors
pop dx
pop ax ; Restore logical sector start
push cx ; Save number of root dir sectors for later use
mov bx,7c0h ; We will load the root directory
add bx,byte 20h ; Right after the boot sector in memory
mov es,bx
xor bx,bx ; We will load it to [0000:7e00h]
call ReadSectors ; Read the sectors
; Now we have to find our way through the root directory to
; The OSLOADER.SYS file
mov bx,[BYTE bp+MaxRootEntries]; Search entire root directory
mov ax,7e0h ; We loaded at 07e0:0000
mov es,ax
xor di,di
mov si,filename
mov cx,11
rep cmpsb ; Compare filenames
jz FoundFile ; If same we found it
dec bx
jnz FindFile
jmp ErrBoot
FindFile:
mov ax,es ; We didn't find it in the previous dir entry
add ax,byte 2 ; So lets move to the next one
mov es,ax ; And search again
xor di,di
mov si,filename
mov cx,11
rep cmpsb ; Compare filenames
jz FoundFile ; If same we found it
dec bx ; Keep searching till we run out of dir entries
jnz FindFile ; Last entry?
jmp ErrBoot
FoundFile:
; We found freeldr.sys on the disk
; so we need to load the first 512
; bytes of it to 0000:7E00
xor di,di ; ES:DI has dir entry
xor dx,dx
mov ax,WORD [es:di+1ah]; Get start cluster
dec ax ; Adjust start cluster by 2
dec ax ; Because the data area starts on cluster 2
xor ch,ch
mov cl,BYTE [BYTE bp+SectsPerCluster] ; Times sectors per cluster
mul cx
pop cx ; Get number of sectors for root dir
add ax,cx ; Add it to the start sector of freeldr.sys
adc dx,byte 0
pop cx ; Get logical start sector of
pop bx ; Root directory
add ax,bx ; Now we have DX:AX with the logical start
adc dx,cx ; Sector of OSLOADER.SYS
mov cx,1 ; We will load 1 sector
push WORD [es:di+1ah] ; Save start cluster
mov bx,7e0h
mov es,bx
xor bx,bx
call ReadSectors ; Load it
pop ax ; Restore start cluster
jmp LoadFile
; Reads logical sectors into [ES:BX]
; DX:AX has logical sector number to read
; CX has number of sectors to read
; CarryFlag set on error
ReadSectors:
push ax
push dx
push cx
xchg ax,cx
xchg ax,dx
xor dx,dx
div WORD [BYTE bp+SectorsPerTrack]
xchg ax,cx
div WORD [BYTE bp+SectorsPerTrack] ; Divide logical by SectorsPerTrack
inc dx ; Sectors numbering starts at 1 not 0
xchg cx,dx
div WORD [BYTE bp+NumberOfHeads] ; Number of heads
mov dh,dl ; Head to DH, drive to DL
mov dl,[BYTE bp+BootDrive] ; Drive number
mov ch,al ; Cylinder in CX
ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits
ror ah,1 ; in CL shifted to bits 6 & 7
or cl,ah ; Or with sector number
mov ax,0201h
int 13h ; DISK - READ SECTORS INTO MEMORY
; AL = number of sectors to read, CH = track, CL = sector
; DH = head, DL = drive, ES:BX -> buffer to fill
; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read
jc BadBoot
pop cx
pop dx
pop ax
inc ax ;Increment Sector to Read
jnz NoCarry
inc dx
NoCarry:
push bx
mov bx,es
add bx,byte 20h
mov es,bx
pop bx
; Increment read buffer for next sector
loop ReadSectors ; Read next sector
ret
; Displays a bad boot message
; And reboots
BadBoot:
mov si,msgDiskError ; Bad boot disk message
call PutChars ; Display it
mov si,msgAnyKey ; Press any key message
call PutChars ; Display it
jmp Reboot
; Displays an error message
; And reboots
ErrBoot:
mov si,msgFreeLdr ; FreeLdr not found message
call PutChars ; Display it
mov si,msgAnyKey ; Press any key message
call PutChars ; Display it
Reboot:
xor ax,ax
int 16h ; Wait for a keypress
int 19h ; Reboot
PutChars:
lodsb
or al,al
jz short Done
mov ah,0eh
mov bx,07h
int 10h
jmp short PutChars
Done:
retn
msgDiskError db 'Disk error',0dh,0ah,0
msgFreeLdr db 'FREELDR.SYS not found',0dh,0ah,0
msgAnyKey db 'Press any key to continue.',0dh,0ah,0
filename db 'FREELDR SYS'
times 510-($-$$) db 0 ; Pad to 510 bytes
dw 0aa55h ; BootSector signature
; End of bootsector
;
; Now starts the extra boot code that we will store
; in the first 512 bytes of freeldr.sys
LoadFile:
; Display "Loading FreeLoader..." message
push ax
mov si,msgLoading ; Loading message
call PutChars ; Display it
pop ax
; AX has start cluster of freeldr.sys
push ax
call ReadFatIntoMemory
pop ax
mov bx,7e0h
mov es,bx
LoadFile2:
push ax
call IsFat12
pop ax
jnc LoadFile3
cmp ax,0ff8h ; Check to see if this is the last cluster in the chain
jmp LoadFile4
LoadFile3:
cmp ax,0fff8h
LoadFile4:
jae LoadFile_Done ; If so continue, if not then read then next one
push ax
xor bx,bx ; Load ROSLDR starting at 0000:8000h
push es
call ReadCluster
pop es
xor bx,bx
mov bl,BYTE [BYTE bp+SectsPerCluster]
shl bx,5 ; BX = BX * 512 / 16
mov ax,es ; Increment the load address by
add ax,bx ; The size of a cluster
mov es,ax
call IsFat12
pop ax
push es
jnc LoadFile5
call GetFatEntry12 ; Get the next entry
jmp LoadFile6
LoadFile5:
call GetFatEntry16
LoadFile6:
pop es
jmp LoadFile2 ; Load the next cluster (if any)
LoadFile_Done:
mov dl,BYTE [BYTE bp+BootDrive]
xor ax,ax
push ax
mov ax,8000h
push ax ; We will do a far return to 0000:8000h
retf ; Transfer control to ROSLDR
; Reads the entire FAT into memory at 7000:0000
ReadFatIntoMemory:
mov ax,WORD [BYTE bp+HiddenSectors]
mov dx,WORD [BYTE bp+HiddenSectors+2]
add ax,WORD [BYTE bp+ReservedSectors]
adc dx,byte 0
mov cx,WORD [BYTE bp+SectorsPerFat]
mov bx,7000h
mov es,bx
xor bx,bx
call ReadSectors
ret
; Returns the FAT entry for a given cluster number for 16-bit FAT
; On entry AX has cluster number
; On return AX has FAT entry for that cluster
GetFatEntry16:
xor dx,dx
mov cx,2 ; AX = AX * 2 (since FAT16 entries are 2 bytes)
mul cx
shl dx,0fh
mov bx,7000h
add bx,dx
mov es,bx
mov bx,ax ; Restore FAT entry offset
mov ax,WORD [es:bx] ; Get FAT entry
ret
; Returns the FAT entry for a given cluster number for 12-bit FAT
; On entry AX has cluster number
; On return AX has FAT entry for that cluster
GetFatEntry12:
push ax
mov cx,ax
shr ax,1
add ax,cx ; AX = AX * 1.5 (AX = AX + (AX / 2)) (since FAT12 entries are 12 bits)
mov bx,7000h
mov es,bx
mov bx,ax ; Put FAT entry offset into BX
mov ax,WORD [es:bx] ; Get FAT entry
pop cx ; Get cluster number from stack
and cx,1
jz UseLow12Bits
and ax,0fff0h
shr ax,4
jmp GetFatEntry12_Done
UseLow12Bits:
and ax,0fffh
GetFatEntry12_Done:
ret
; Reads cluster number in AX into [ES:0000]
ReadCluster:
; StartSector = ((Cluster - 2) * SectorsPerCluster) + + ReservedSectors + HiddenSectors;
dec ax
dec ax
xor dx,dx
movzx bx,BYTE [BYTE bp+SectsPerCluster]
mul bx
push ax
push dx
; Now calculate the size of the root directory
mov ax,0020h ; Size of dir entry
mul WORD [BYTE bp+MaxRootEntries] ; Times the number of entries
mov bx,WORD [BYTE bp+BytesPerSector]
add ax,bx
dec ax
div bx ; Divided by the size of a sector
mov cx,ax
; CX now has the number of root directory sectors
xor dx,dx
movzx ax,BYTE [BYTE bp+NumberOfFats]
mul WORD [BYTE bp+SectorsPerFat]
add ax,WORD [BYTE bp+ReservedSectors]
adc dx,byte 0
add ax,WORD [BYTE bp+HiddenSectors]
adc dx,WORD [BYTE bp+HiddenSectors+2]
add ax,cx
adc dx,byte 0
pop cx
pop bx
add ax,bx
adc dx,cx
xor bx,bx ; We will load it to [ES:0000], ES loaded before function call
movzx cx,BYTE [BYTE bp+SectsPerCluster]
call ReadSectors
ret
; Returns CF = 1 if this is a FAT12 file system
; Otherwise CF = 0 for FAT16
IsFat12:
; Now calculate the size of the root directory
mov ax,0020h ; Size of dir entry
mul WORD [BYTE bp+MaxRootEntries] ; Times the number of entries
mov bx,WORD [BYTE bp+BytesPerSector]
add ax,bx ; Plus (BytesPerSector - 1)
dec ax
div bx ; Divided by the size of a sector
; AX now has the number of root directory sectors
mov bx,ax
; Now we must find our way to the first sector of the root directory
xor ax,ax
xor dx,dx
mov al,BYTE [BYTE bp+NumberOfFats] ; Number of fats
mul WORD [BYTE bp+SectorsPerFat] ; Times sectors per fat
add ax,WORD [BYTE bp+HiddenSectors]
adc dx,WORD [BYTE bp+HiddenSectors+2] ; Add the number of hidden sectors
add ax,[BYTE bp+ReservedSectors] ; Add the number of reserved sectors
adc dx,byte 0 ; Add carry bit
add ax,bx
adc dx,byte 0 ; Add carry bit
; DX:AX now has the number of the starting sector of the data area
xor cx,cx
mov bx,WORD [BYTE bp+TotalSectors]
cmp bx,byte 0
jnz IsFat12_2
mov bx,WORD [BYTE bp+TotalSectorsBig]
mov cx,WORD [BYTE bp+TotalSectorsBig+2]
; CX:BX now contains the number of sectors on the volume
IsFat12_2:
sub bx,ax ; Subtract data area start sector
sub cx,dx ; from total sectors of volume
mov ax,bx
mov dx,cx
; DX:AX now contains the number of data sectors on the volume
movzx bx,BYTE [BYTE bp+SectsPerCluster]
div bx
; AX now has the number of clusters on the volume
stc
cmp ax,4085
jb IsFat12_Done
clc
IsFat12_Done:
ret
times 998-($-$$) db 0 ; Pad to 998 bytes
msgLoading db 'Loading FreeLoader...',0dh,0ah,0
dw 0aa55h ; BootSector signature

View File

@@ -1,380 +0,0 @@
; FAT32.ASM
; FAT32 Boot Sector
; Copyright (c) 1998, 2000, 2001 Brian Palmer
org 7c00h
segment .text
bits 16
start:
jmp short main
nop
OEMName db 'FrLdr1.0'
BytesPerSector dw 512
SectsPerCluster db 1
ReservedSectors dw 32
NumberOfFats db 2
MaxRootEntries dw 0 ; Always zero for FAT32 volumes
TotalSectors dw 0 ; Always zero for FAT32 volumes
MediaDescriptor db 0f8h
SectorsPerFat dw 0 ; Always zero for FAT32 volumes
SectorsPerTrack dw 18
NumberOfHeads dw 2
HiddenSectors dd 0
TotalSectorsBig dd 0
; FAT32 Inserted Info
SectorsPerFatBig dd 0
ExtendedFlags dw 0
FSVersion dw 0
RootDirStartCluster dd 0
FSInfoSector dw 0
BackupBootSector dw 6
Reserved1 times 12 db 0
; End FAT32 Inserted Info
BootDrive db 0
Reserved db 0
ExtendSig db 29h
SerialNumber dd 00000000h
VolumeLabel db 'NO NAME '
FileSystem db 'FAT32 '
main:
cli
cld
xor ax,ax
mov ss,ax
mov sp,7c00h ; Setup a stack
mov ax,cs ; Setup segment registers
mov ds,ax ; Make DS correct
mov es,ax ; Make ES correct
sti ; Enable ints now
mov [BootDrive],dl ; Save the boot drive
xor ax,ax ; Zero out AX
cmp word [TotalSectors],byte 0x00 ; Check the old 16-bit value of TotalSectors
jnz ErrBoot ; If it is non-zero then exit with an error
cmp word [FSVersion],byte 0x00 ; Check the file system version word
ja ErrBoot ; If it is not zero then exit with an error
; Reset disk controller
int 13h
jnc LoadExtraBootCode
jmp BadBoot ; Reset failed...
LoadExtraBootCode:
; First we have to load our extra boot code at
; sector 14 into memory at [0000:7e00h]
xor dx,dx
mov ax,0eh
add ax,WORD [HiddenSectors]
adc dx,WORD [HiddenSectors+2] ; Add the number of hidden sectors
mov cx,1
mov bx,7e0h
mov es,bx ; Read sector to [0000:7e00h]
xor bx,bx
call ReadSectors
jmp StartSearch
; Reads logical sectors into [ES:BX]
; DX:AX has logical sector number to read
; CX has number of sectors to read
; CarryFlag set on error
ReadSectors:
push ax
push dx
push cx
xchg ax,cx
xchg ax,dx
xor dx,dx
div WORD [SectorsPerTrack]
xchg ax,cx
div WORD [SectorsPerTrack] ; Divide logical by SectorsPerTrack
inc dx ; Sectors numbering starts at 1 not 0
xchg cx,dx
div WORD [NumberOfHeads] ; Number of heads
mov dh,dl ; Head to DH, drive to DL
mov dl,[BootDrive] ; Drive number
mov ch,al ; Cylinder in CX
ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits
ror ah,1 ; in CL shifted to bits 6 & 7
or cl,ah ; Or with sector number
mov ax,0201h
int 13h ; DISK - READ SECTORS INTO MEMORY
; AL = number of sectors to read, CH = track, CL = sector
; DH = head, DL = drive, ES:BX -> buffer to fill
; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read
jc BadBoot
pop cx
pop dx
pop ax
inc ax ;Increment Sector to Read
jnz NoCarry
inc dx
NoCarry:
push bx
mov bx,es
add bx,byte 20h
mov es,bx
pop bx
; Increment read buffer for next sector
loop ReadSectors ; Read next sector
ret
; Displays a bad boot message
; And reboots
BadBoot:
mov si,msgDiskError ; Bad boot disk message
call PutChars ; Display it
mov si,msgAnyKey ; Press any key message
call PutChars ; Display it
jmp Reboot
; Displays an error message
; And reboots
ErrBoot:
mov si,msgFreeLdr ; FreeLdr not found message
call PutChars ; Display it
mov si,msgAnyKey ; Press any key message
call PutChars ; Display it
Reboot:
xor ax,ax
int 16h ; Wait for a keypress
int 19h ; Reboot
PutChars:
lodsb
or al,al
jz short Done
mov ah,0eh
mov bx,07h
int 10h
jmp short PutChars
Done:
retn
msgDiskError db 'Disk error',0dh,0ah,0
msgFreeLdr db 'FREELDR.SYS not found',0dh,0ah,0
msgAnyKey db 'Press any key to continue.',0dh,0ah,0
filename db 'FREELDR SYS'
times 510-($-$$) db 0 ; Pad to 510 bytes
dw 0aa55h ; BootSector signature
; End of bootsector
;
; Now starts the extra boot code that we will store
; at sector 14 on a FAT32 volume
;
; To remain multi-boot compatible with other operating
; systems we must not overwrite anything other than
; the bootsector which means we will have to use
; a different sector like 14 to store our extra boot code
;
; Note: Win2k uses sector 12 for this purpose
StartSearch:
; Now we must get the first cluster of the root directory
mov eax,DWORD [RootDirStartCluster]
cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain
jb ContinueSearch ; If not continue, if so BadBoot
jmp ErrBoot
ContinueSearch:
mov bx,800h
mov es,bx ; Read cluster to [0000:8000h]
call ReadCluster ; Read the cluster
; Now we have to find our way through the root directory to
; The OSLOADER.SYS file
xor bx,bx
mov bl,[SectsPerCluster]
shl bx,4 ; BX = BX * 512 / 32
mov ax,800h ; We loaded at 0800:0000
mov es,ax
xor di,di
mov si,filename
mov cx,11
rep cmpsb ; Compare filenames
jz FoundFile ; If same we found it
dec bx
jnz FindFile
jmp ErrBoot
FindFile:
mov ax,es ; We didn't find it in the previous dir entry
add ax,2 ; So lets move to the next one
mov es,ax ; And search again
xor di,di
mov si,filename
mov cx,11
rep cmpsb ; Compare filenames
jz FoundFile ; If same we found it
dec bx ; Keep searching till we run out of dir entries
jnz FindFile ; Last entry?
; Get the next root dir cluster and try again until we run out of clusters
mov eax,DWORD [RootDirStartCluster]
call GetFatEntry
mov [RootDirStartCluster],eax
jmp StartSearch
FoundFile:
; Display "Loading FreeLoader..." message
mov si,msgLoading ; Loading message
call PutChars ; Display it
xor di,di ; ES:DI has dir entry
xor dx,dx
mov ax,WORD [es:di+14h] ; Get start cluster high word
shl eax,16
mov ax,WORD [es:di+1ah] ; Get start cluster low word
mov bx,800h
mov es,bx
FoundFile2:
cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain
jae FoundFile3 ; If so continue, if not then read then next one
push eax
xor bx,bx ; Load ROSLDR starting at 0000:8000h
push es
call ReadCluster
pop es
xor bx,bx
mov bl,[SectsPerCluster]
shl bx,5 ; BX = BX * 512 / 16
mov ax,es ; Increment the load address by
add ax,bx ; The size of a cluster
mov es,ax
pop eax
push es
call GetFatEntry ; Get the next entry
pop es
jmp FoundFile2 ; Load the next cluster (if any)
FoundFile3:
mov dl,[BootDrive]
xor ax,ax
push ax
mov ax,8000h
push ax ; We will do a far return to 0000:8000h
retf ; Transfer control to ROSLDR
; Returns the FAT entry for a given cluster number
; On entry EAX has cluster number
; On return EAX has FAT entry for that cluster
GetFatEntry:
shl eax,2 ; EAX = EAX * 4 (since FAT32 entries are 4 bytes)
mov ecx,eax ; Save this for later in ECX
xor edx,edx
movzx ebx,WORD [BytesPerSector]
push ebx
div ebx ; FAT Sector Number = EAX / BytesPerSector
movzx ebx,WORD [ReservedSectors]
add eax,ebx ; FAT Sector Number += ReservedSectors
mov ebx,DWORD [HiddenSectors]
add eax,ebx ; FAT Sector Number += HiddenSectors
pop ebx
dec ebx
and ecx,ebx ; FAT Offset Within Sector = ECX % BytesPerSector
; EAX holds logical FAT sector number
; ECX holds FAT entry offset
; Now we have to check the extended flags
; to see which FAT is the active one
; and use it, or if they are mirrored then
; no worries
movzx ebx,WORD [ExtendedFlags] ; Get extended flags and put into ebx
and bx,0x0f ; Mask off upper 8 bits
jz GetFatEntry2 ; If fat is mirrored then skip fat calcs
cmp bl,[NumberOfFats] ; Compare bl to number of fats
jc GetFatEntry1
jmp ErrBoot ; If bl is bigger than numfats exit with error
GetFatEntry1:
mov edx,eax ; Put logical FAT sector number in edx
mov eax,[SectorsPerFatBig] ; Get the number of sectors occupied by one fat in eax
mul ebx ; Multiplied by the active FAT index we have in ebx
add eax,edx ; Add the current FAT sector offset
GetFatEntry2:
push ecx
ror eax,16
mov dx,ax
ror eax,16
; DX:AX holds logical FAT sector number
mov bx,7000h
mov es,bx
xor bx,bx ; We will load it to [7000:0000h]
mov cx,1
call ReadSectors
jnc GetFatEntry3
jmp BadBoot
GetFatEntry3:
mov bx,7000h
mov es,bx
pop ecx
mov eax,DWORD [es:ecx] ; Get FAT entry
and eax,0fffffffh ; Mask off reserved bits
ret
; Reads cluster number in EAX into [ES:0000]
ReadCluster:
; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors;
dec eax
dec eax
xor edx,edx
movzx ebx,BYTE [SectsPerCluster]
mul ebx
push eax
xor edx,edx
movzx eax,BYTE [NumberOfFats]
mul DWORD [SectorsPerFatBig]
movzx ebx,WORD [ReservedSectors]
add eax,ebx
add eax,DWORD [HiddenSectors]
pop ebx
add eax,ebx ; EAX now contains the logical sector number of the cluster
ror eax,16
mov dx,ax
ror eax,16
xor bx,bx ; We will load it to [ES:0000], ES loaded before function call
movzx cx,BYTE [SectsPerCluster]
call ReadSectors
ret
times 998-($-$$) db 0 ; Pad to 998 bytes
msgLoading db 'Loading FreeLoader...',0dh,0ah,0
dw 0aa55h ; BootSector signature

View File

@@ -1,55 +0,0 @@
#include <stdio.h>
FILE *in;
FILE *out;
FILE *new;
int main(int argc, char *argv[])
{
unsigned char ch;
int cnt;
int split_offset;
if (argc < 5)
{
printf("usage: split infile.bin outfile.bin newfile.bin split_offset\n");
return -1;
}
if ((in = fopen(argv[1], "rb")) == NULL)
{
printf("Couldn't open data file.\n");
return -1;
}
if ((out = fopen(argv[2], "wb")) == NULL)
{
printf("Couldn't open output file.\n");
return -1;
}
if ((new = fopen(argv[3], "wb")) == NULL)
{
printf("Couldn't open new file.\n");
return -1;
}
split_offset = atoi(argv[4]);
for (cnt=0; cnt<split_offset; cnt++)
{
ch = fgetc(in);
fputc(ch, out);
}
ch = fgetc(in);
while (!feof(in))
{
fputc(ch, new);
ch = fgetc(in);
}
fclose(in);
fclose(out);
fclose(new);
return 0;
}

View File

@@ -1,52 +0,0 @@
#include <stdio.h>
FILE *in;
FILE *in2;
FILE *out;
int main(int argc, char *argv[])
{
unsigned char ch;
if (argc < 4)
{
printf("usage: stubit infile1.bin infile2.sys outfile.bin\n");
return -1;
}
if ((in = fopen(argv[1], "rb")) == NULL)
{
printf("Couldn't open data file.\n");
return -1;
}
if ((in2 = fopen(argv[2], "rb")) == NULL)
{
printf("Couldn't open data file.\n");
return -1;
}
if ((out = fopen(argv[3], "wb")) == NULL)
{
printf("Couldn't open output file.\n");
return -1;
}
ch = fgetc(in);
while (!feof(in))
{
fputc(ch, out);
ch = fgetc(in);
}
ch = fgetc(in2);
while (!feof(in2))
{
fputc(ch, out);
ch = fgetc(in2);
}
fclose(in);
fclose(in2);
fclose(out);
return 0;
}

View File

@@ -1,464 +0,0 @@
;
; Win2k FAT32 Boot Sector
;
; Brian Palmer <brianp@sginet.com>
;
;
; The BP register is initialized to 0x7c00, the start of
; the boot sector. The SP register is initialized to
; 0x7bf4, leaving 12 bytes of data storage space above
; the stack.
;
; The DWORD that gets stored at 0x7bf4 is 0xffffffff ??
;
; The DWORD that gets stored at 0x7bf8 is the count of
; total sectors of the volume, calculated from the BPB.
;
; The DWORD that gets stored at 0x7bfc is the logical
; sector number of the start of the data area.
;
segment .text
bits 16
start:
jmp short main
nop
OEMName db 'MSWIN4.0'
BytesPerSector dw 512
SectsPerCluster db 1
ReservedSectors dw 1
NumberOfFats db 2
MaxRootEntries dw 0 ;512 - Always zero for FAT32 volumes
TotalSectors dw 0 ;2880 - Always zero for FAT32 volumes
MediaDescriptor db 0f8h
SectorsPerFat dw 0 ;9 - Always zero for FAT32 volumes
SectorsPerTrack dw 18
NumberOfHeads dw 2
HiddenSectors dd 0
TotalSectorsBig dd 0
; FAT32 Inserted Info
SectorsPerFatBig dd 0
ExtendedFlags dw 0
FSVersion dw 0
RootDirStartCluster dd 0
FSInfoSector dw 0
BackupBootSector dw 6
Reserved1 times 12 db 0
; End FAT32 Inserted Info
BootDrive db 0
Reserved db 0
ExtendSig db 29h
SerialNumber dd 00000000h
VolumeLabel db 'NO NAME '
FileSystem db 'FAT32 '
main:
00007C5A 33C9 xor cx,cx
00007C5C 8ED1 mov ss,cx ; Setup the stack
00007C5E BCF47B mov sp,0x7bf4 ; Give us 12 bytes of space above the stack
00007C61 8EC1 mov es,cx
00007C63 8ED9 mov ds,cx
00007C65 BD007C mov bp,0x7c00
00007C68 884E02 mov [bp+0x2],cl ; Zero out the nop instruction?? (3rd byte of the boot sector)
00007C6B 8A5640 mov dl,[bp+BootDrive]
00007C6E B408 mov ah,0x8
00007C70 CD13 int 0x13 ; Int 13, func 8 - Get Drive Parameters
00007C72 7305 jnc drive_param_ok ; If no error jmp
drive_param_error:
00007C74 B9FFFF mov cx,0xffff ; We couldn't determine the drive parameters
00007C77 8AF1 mov dh,cl ; So just set the CHS to 0xff
drive_param_ok:
00007C79 660FB6C6 movzx eax,dh ; Store the number of heads in eax
00007C7D 40 inc ax ; Make it one-based because the bios returns it zero-based
00007C7E 660FB6D1 movzx edx,cl ; Store the sectors per track in edx
00007C82 80E23F and dl,0x3f ; Mask off the cylinder bits
00007C85 F7E2 mul dx ; Multiply the sectors per track with the heads, result in dx:ax
00007C87 86CD xchg cl,ch ; Switch the cylinder with the sectors
00007C89 C0ED06 shr ch,0x6 ; Move the top two cylinder bits down where they should be
00007C8C 41 inc cx ; Make it one-based because the bios returns it zero-based
00007C8D 660FB7C9 movzx ecx,cx
00007C91 66F7E1 mul ecx ; Multiply the cylinders with (heads * sectors) [stored in dx:ax already]
00007C94 668946F8 mov [bp-0x8],eax ; This value is the number of total sectors on the disk, so save it for later
00007C98 837E1600 cmp word [bp+TotalSectors],byte +0x0 ; Check the old 16-bit value of TotalSectors
00007C9C 7538 jnz print_ntldr_error_message ; If it is non-zero then exit with an error
00007C9E 837E2A00 cmp word [bp+FSVersion],byte +0x0 ; Check the file system version word
00007CA2 7732 ja print_ntldr_error_message ; If it is not zero then exit with an error
;
; We are now ready to load our second sector of boot code
; But first, a bit of undocumented information about how
; Win2k stores it's second sector of boot code.
;
; The FAT32 filesystem was designed so that you can store
; multiple sectors of boot code. The boot sector of a FAT32
; volume is actually three sectors long. Microsoft extended
; the BPB so much that you can't fit enough code in the
; boot sector to make it work. So they extended it. Sector 0
; is the traditional boot sector, sector 1 is the FSInfo sector,
; and sector 2 is used to store extra boot code to make up
; for the lost space the BPB takes.
;
; Now this creates an interesting problem. Suppose for example
; that the user has Win98 and Win2k installed. The Win2k
; boot sector is stored at sector 0 and the Win98 boot sector is
; stored as BOOTSECT.DOS on the file system. Now if Win2k were
; to store it's second sector of boot code in sector 2 like
; the fat spec says to do then when you try to dual boot back
; to Win98 the Win98 boot sector will load Win2k's second
; sector of boot code. Understand? ;-)
;
; To get around this problem Win2k stores it's second sector
; of boot code elsewhere. This sector is always stored at sector 13
; on the file system. Now don't ask me what happens when you don't
; have enough reserved sectors to store it, but I've never seen a
; FAT32 volume that didn't have at least 32 reserved sectors.
;
00007CA4 668B461C mov eax,[bp+HiddenSectors] ; Get the count of hidden sectors
00007CA8 6683C00C add eax,byte +0xc ; Add 12 to that value so that we are loading the 13th sector of the volume
00007CAC BB0080 mov bx,0x8000 ; Read the sector to address 0x8000
00007CAF B90100 mov cx,0x1 ; Read just one sector
00007CB2 E82B00 call read_sectors ; Read it
00007CB5 E94803 jmp 0x8000 ; Jump to the next sector of boot code
print_disk_error_message:
00007CB8 A0FA7D mov al,[DISK_ERR_offset_from_0x7d00]
putchars:
00007CBB B47D mov ah,0x7d
00007CBD 8BF0 mov si,ax
get_another_char:
00007CBF AC lodsb
00007CC0 84C0 test al,al
00007CC2 7417 jz reboot
00007CC4 3CFF cmp al,0xff
00007CC6 7409 jz print_reboot_message
00007CC8 B40E mov ah,0xe
00007CCA BB0700 mov bx,0x7
00007CCD CD10 int 0x10
00007CCF EBEE jmp short get_another_char
print_reboot_message:
00007CD1 A0FB7D mov al,[RESTART_ERR_offset_from_0x7d00]
00007CD4 EBE5 jmp short putchars
print_ntldr_error_message:
00007CD6 A0F97D mov al,[NTLDR_ERR_offset_from_0x7d00]
00007CD9 EBE0 jmp short putchars
reboot:
00007CDB 98 cbw
00007CDC CD16 int 0x16
00007CDE CD19 int 0x19
read_sectors:
00007CE0 6660 pushad
00007CE2 663B46F8 cmp eax,[bp-0x8]
00007CE6 0F824A00 jc near 0x7d34
00007CEA 666A00 o32 push byte +0x0
00007CED 6650 push eax
00007CEF 06 push es
00007CF0 53 push bx
00007CF1 666810000100 push dword 0x10010
00007CF7 807E0200 cmp byte [bp+0x2],0x0
00007CFB 0F852000 jnz near 0x7d1f
00007CFF B441 mov ah,0x41
00007D01 BBAA55 mov bx,0x55aa
00007D04 8A5640 mov dl,[bp+BootDrive]
00007D07 CD13 int 0x13
00007D09 0F821C00 jc near 0x7d29
00007D0D 81FB55AA cmp bx,0xaa55
00007D11 0F851400 jnz near 0x7d29
00007D15 F6C101 test cl,0x1
00007D18 0F840D00 jz near 0x7d29
00007D1C FE4602 inc byte [bp+0x2]
00007D1F B442 mov ah,0x42
00007D21 8A5640 mov dl,[bp+BootDrive]
00007D24 8BF4 mov si,sp
00007D26 CD13 int 0x13
00007D28 B0F9 mov al,0xf9
00007D2A 6658 pop eax
00007D2C 6658 pop eax
00007D2E 6658 pop eax
00007D30 6658 pop eax
00007D32 EB2A jmp short 0x7d5e
00007D34 6633D2 xor edx,edx
00007D37 660FB74E18 movzx ecx,word [bp+SectorsPerTrack]
00007D3C 66F7F1 div ecx
00007D3F FEC2 inc dl
00007D41 8ACA mov cl,dl
00007D43 668BD0 mov edx,eax
00007D46 66C1EA10 shr edx,0x10
00007D4A F7761A div word [bp+NumberOfHeads]
00007D4D 86D6 xchg dl,dh
00007D4F 8A5640 mov dl,[bp+BootDrive]
00007D52 8AE8 mov ch,al
00007D54 C0E406 shl ah,0x6
00007D57 0ACC or cl,ah
00007D59 B80102 mov ax,0x201
00007D5C CD13 int 0x13
00007D5E 6661 popad
00007D60 0F8254FF jc near print_disk_error_message
00007D64 81C30002 add bx,0x200
00007D68 6640 inc eax
00007D6A 49 dec cx
00007D6B 0F8571FF jnz near read_sectors
00007D6F C3 ret
NTLDR db 'NTLDR '
filler times 49 db 0
NTLDR_ERR db 0dh,0ah,'NTLDR is missing',0ffh
DISK_ERR db 0dh,0ah,'Disk error',0ffh
RESTART_ERR db 0dh,0ah,'Press any key to restart',0dh,0ah
more_filler times 16 db 0
NTLDR_offset_from_0x7d00 db 0
NTLDR_ERR_offset_from_0x7d00 db 0ach
DISK_ERR_offset_from_0x7d00 db 0bfh
RESTART_ERR_offset_from_0x7d00 db 0cch
dw 0
dw 0aa55h
;
; And that ends the code that makes up the traditional boot sector
; From here on out is a disassembly of the extra sector of boot
; code required for a FAT32 volume. Win2k stores this code at
; sector 13 on the file system.
;
00008000 660FB64610 movzx eax,byte [bp+NumberOfFats] ; Put the number of fats into eax
00008005 668B4E24 mov ecx,[bp+SectorsPerFatBig] ; Put the count of sectors per fat into ecx
00008009 66F7E1 mul ecx ; Multiply them, edx:eax = (eax * ecx)
0000800C 6603461C add eax,[bp+HiddenSectors] ; Add the hidden sectors to eax
00008010 660FB7560E movzx edx,word [bp+ReservedSectors] ; Put the count of reserved sectors into edx
00008015 6603C2 add eax,edx ; Add it to eax
00008018 668946FC mov [bp-0x4],eax ; eax now contains the start of the data area, so save it for later
0000801C 66C746F4FFFFFFFF mov dword [bp-0xc],0xffffffff ; Save 0xffffffff for later??
00008024 668B462C mov eax,[bp+RootDirStartCluster] ; Put the starting cluster of the root directory into eax
00008028 6683F802 cmp eax,byte +0x2 ; Check and see if the root directory starts at cluster 2 or above
0000802C 0F82A6FC jc near print_ntldr_error_message ; If not exit with error
00008030 663DF8FFFF0F cmp eax,0xffffff8 ; Check and see if the root directory start cluster is and end of cluster chain indicator
00008036 0F839CFC jnc near print_ntldr_error_message ; If so exit with error
search_root_directory_cluster:
0000803A 6650 push eax ; Save root directory start cluster on stack
0000803C 6683E802 sub eax,byte +0x2 ; Adjust it because the first two fat entries are unused so the third entry marks the first data area cluster
00008040 660FB65E0D movzx ebx,byte [bp+SectsPerCluster] ; Put the number of sectors per cluster in ebx
00008045 8BF3 mov si,bx ; Now store it also in si register
00008047 66F7E3 mul ebx ; Multiply sectors per cluster with root directory start cluster
0000804A 660346FC add eax,[bp-0x4] ; Add the start sector of the data area
read_directory_sector:
0000804E BB0082 mov bx,0x8200 ; We now have the start sector of the root directory, so load it to 0x8200
00008051 8BFB mov di,bx ; Put the address of the root directory sector in di also
00008053 B90100 mov cx,0x1 ; Read one sector
00008056 E887FC call read_sectors ; Perform the read
check_entry_for_ntldr:
00008059 382D cmp [di],ch ; Check the first byte of the root directory entry for zero
0000805B 741E jz ntldr_not_found ; If so then NTLDR is missing so exit with error
0000805D B10B mov cl,0xb ; Put the value 11 in cl so we can compare an 11-byte filename
0000805F 56 push si ; Save si (which contains the number of sectors per cluster)
00008060 BE707D mov si,NTLDR ;0x7d70 ; Check and see if "NTLDR" is the first file entry
00008063 F3A6 repe cmpsb ; Do the compare
00008065 5E pop si ; Restore sectors per cluster into si
00008066 741B jz ntldr_found ; If we found it then continue, else check next entry
00008068 03F9 add di,cx ; Add 0 to di? the next entry is 0x15 bytes away
0000806A 83C715 add di,byte +0x15 ; Add 0x15 to di
0000806D 3BFB cmp di,bx ; Check to see if we have reached the end of our sector we loaded, read_sectors sets bx = end address of data loaded
0000806F 72E8 jc check_entry_for_ntldr ; If we haven't reached the end then check the next entry
00008071 4E dec si ; decrement si, si holds the number of sectors per cluster
00008072 75DA jnz read_directory_sector ; If it's not zero then search the next sector for NTLDR
00008074 6658 pop eax ; If we got here that means we didn't find NTLDR in the previous root directory cluster, so restore eax with the start cluster
00008076 E86500 call get_fat_entry ; Get the next cluster in the fat chain
00008079 72BF jc search_root_directory_cluster ; If we reached end-of-file marker then don't jump, otherwise continue search
ntldr_not_found:
0000807B 83C404 add sp,byte +0x4
0000807E E955FC jmp print_ntldr_error_message
ntldr_load_segment_address dw 0x2000
ntldr_found:
00008083 83C404 add sp,byte +0x4 ; Adjust stack to remove root directory start cluster
00008086 8B7509 mov si,[di+0x9] ; Put start cluster high word in si
00008089 8B7D0F mov di,[di+0xf] ; Put start cluster low word in di
0000808C 8BC6 mov ax,si ; Put high word in ax
0000808E 66C1E010 shl eax,0x10 ; Shift it into position
00008092 8BC7 mov ax,di ; Put low word in ax, now eax contains start cluster of NTLDR
00008094 6683F802 cmp eax,byte +0x2 ; Check and see if the start cluster of NTLDR starts at cluster 2 or above
00008098 0F823AFC jc near print_ntldr_error_message ; If not exit with error
0000809C 663DF8FFFF0F cmp eax,0xffffff8 ; Check and see if the start cluster of NTLDR is and end of cluster chain indicator
000080A2 0F8330FC jnc near print_ntldr_error_message ; If so exit with error
load_next_ntldr_cluster:
000080A6 6650 push eax ; Save NTLDR start cluster for later
000080A8 6683E802 sub eax,byte +0x2 ; Adjust it because the first two fat entries are unused so the third entry marks the first data area cluster
000080AC 660FB64E0D movzx ecx,byte [bp+SectsPerCluster] ; Put the sectors per cluster into ecx
000080B1 66F7E1 mul ecx ; Multiply sectors per cluster by the start cluster, we now have the logical start sector
000080B4 660346FC add eax,[bp-0x4] ; Add the start of the data area logical sector
000080B8 BB0000 mov bx,0x0 ; Load NTLDR to offset zero
000080BB 06 push es ; Save es
000080BC 8E068180 mov es,[ntldr_load_segment_address] ; Get the segment address to load NTLDR to
000080C0 E81DFC call read_sectors ; Load the first cluster
000080C3 07 pop es ; Restore es
000080C4 6658 pop eax ; Restore eax to NTLDR start cluster
000080C6 C1EB04 shr bx,0x4 ; bx contains the amount of data we transferred, so divide it by 16
000080C9 011E8180 add [ntldr_load_segment_address],bx ; Add that value to the segment
000080CD E80E00 call get_fat_entry ; Get the next cluster in eax
000080D0 0F830200 jnc near jump_to_ntldr ; If we have reached the end of file then lets get to NTLDR
000080D4 72D0 jc load_next_ntldr_cluster ; If not, then load another cluster
jump_to_ntldr:
000080D6 8A5640 mov dl,[bp+BootDrive] ; Put the boot drive in dl
000080D9 EA00000020 jmp 0x2000:0x0 ; Jump to NTLDR
get_fat_entry:
000080DE 66C1E002 shl eax,0x2 ; Multiply cluster by 4
000080E2 E81100 call load_fat_sector ; Load the fat sector
000080E5 26668B01 mov eax,[es:bx+di] ; Get the fat entry
000080E9 6625FFFFFF0F and eax,0xfffffff ; Mask off the most significant 4 bits
000080EF 663DF8FFFF0F cmp eax,0xffffff8 ; Compare it to end of file marker to set the flags correctly
000080F5 C3 ret ; Return to caller
load_fat_sector:
000080F6 BF007E mov di,0x7e00 ; We will load the fat sector to 0x7e00
000080F9 660FB74E0B movzx ecx,word [bp+SectsPerCluster] ; Get the sectors per cluster
000080FE 6633D2 xor edx,edx ; We will divide (cluster * 4) / sectorspercluster
00008101 66F7F1 div ecx ; eax is already set before we get to this routine
00008104 663B46F4 cmp eax,[bp-0xc] ; Compare eax to 0xffffffff (initially, we set this value later)
00008108 743A jz load_fat_sector_end ; If it is the same return
0000810A 668946F4 mov [bp-0xc],eax ; Update that value
0000810E 6603461C add eax,[bp+HiddenSectors] ; Add the hidden sectors
00008112 660FB74E0E movzx ecx,word [bp+ReservedSectors] ; Add the reserved sectors
00008117 6603C1 add eax,ecx ; To the hidden sectors + the value we computed earlier
0000811A 660FB75E28 movzx ebx,word [bp+ExtendedFlags] ; Get extended flags and put into ebx
0000811F 83E30F and bx,byte +0xf ; Mask off upper 8 bits
00008122 7416 jz load_fat_sector_into_memory ; If fat is mirrored then skip fat calcs
00008124 3A5E10 cmp bl,[bp+NumberOfFats] ; Compare bl to number of fats
00008127 0F83ABFB jnc near print_ntldr_error_message ; If bl is bigger than numfats exit with error
0000812B 52 push dx ; Save dx
0000812C 668BC8 mov ecx,eax ; Put the current fat sector offset into ecx
0000812F 668B4624 mov eax,[bp+SectorsPerFatBig] ; Get the number of sectors occupied by one fat
00008133 66F7E3 mul ebx ; Multiplied by the active fat index
00008136 6603C1 add eax,ecx ; Add the current fat sector offset
00008139 5A pop dx ; Restore dx
load_fat_sector_into_memory:
0000813A 52 push dx ; Save dx, what is so important in dx??
0000813B 8BDF mov bx,di ; Put 0x7e00 in bx
0000813D B90100 mov cx,0x1 ; Load one sector
00008140 E89DFB call read_sectors ; Perform the read
00008143 5A pop dx ; Restore dx
load_fat_sector_end:
00008144 8BDA mov bx,dx ; Put it into bx, what is this value??
00008146 C3 ret ; Return
00008147 0000 add [bx+si],al
00008149 0000 add [bx+si],al
0000814B 0000 add [bx+si],al
0000814D 0000 add [bx+si],al
0000814F 0000 add [bx+si],al
00008151 0000 add [bx+si],al
00008153 0000 add [bx+si],al
00008155 0000 add [bx+si],al
00008157 0000 add [bx+si],al
00008159 0000 add [bx+si],al
0000815B 0000 add [bx+si],al
0000815D 0000 add [bx+si],al
0000815F 0000 add [bx+si],al
00008161 0000 add [bx+si],al
00008163 0000 add [bx+si],al
00008165 0000 add [bx+si],al
00008167 0000 add [bx+si],al
00008169 0000 add [bx+si],al
0000816B 0000 add [bx+si],al
0000816D 0000 add [bx+si],al
0000816F 0000 add [bx+si],al
00008171 0000 add [bx+si],al
00008173 0000 add [bx+si],al
00008175 0000 add [bx+si],al
00008177 0000 add [bx+si],al
00008179 0000 add [bx+si],al
0000817B 0000 add [bx+si],al
0000817D 0000 add [bx+si],al
0000817F 0000 add [bx+si],al
00008181 0000 add [bx+si],al
00008183 0000 add [bx+si],al
00008185 0000 add [bx+si],al
00008187 0000 add [bx+si],al
00008189 0000 add [bx+si],al
0000818B 0000 add [bx+si],al
0000818D 0000 add [bx+si],al
0000818F 0000 add [bx+si],al
00008191 0000 add [bx+si],al
00008193 0000 add [bx+si],al
00008195 0000 add [bx+si],al
00008197 0000 add [bx+si],al
00008199 0000 add [bx+si],al
0000819B 0000 add [bx+si],al
0000819D 0000 add [bx+si],al
0000819F 0000 add [bx+si],al
000081A1 0000 add [bx+si],al
000081A3 0000 add [bx+si],al
000081A5 0000 add [bx+si],al
000081A7 0000 add [bx+si],al
000081A9 0000 add [bx+si],al
000081AB 0000 add [bx+si],al
000081AD 0000 add [bx+si],al
000081AF 0000 add [bx+si],al
000081B1 0000 add [bx+si],al
000081B3 0000 add [bx+si],al
000081B5 0000 add [bx+si],al
000081B7 0000 add [bx+si],al
000081B9 0000 add [bx+si],al
000081BB 0000 add [bx+si],al
000081BD 0000 add [bx+si],al
000081BF 0000 add [bx+si],al
000081C1 0000 add [bx+si],al
000081C3 0000 add [bx+si],al
000081C5 0000 add [bx+si],al
000081C7 0000 add [bx+si],al
000081C9 0000 add [bx+si],al
000081CB 0000 add [bx+si],al
000081CD 0000 add [bx+si],al
000081CF 0000 add [bx+si],al
000081D1 0000 add [bx+si],al
000081D3 0000 add [bx+si],al
000081D5 0000 add [bx+si],al
000081D7 0000 add [bx+si],al
000081D9 0000 add [bx+si],al
000081DB 0000 add [bx+si],al
000081DD 0000 add [bx+si],al
000081DF 0000 add [bx+si],al
000081E1 0000 add [bx+si],al
000081E3 0000 add [bx+si],al
000081E5 0000 add [bx+si],al
000081E7 0000 add [bx+si],al
000081E9 0000 add [bx+si],al
000081EB 0000 add [bx+si],al
000081ED 0000 add [bx+si],al
000081EF 0000 add [bx+si],al
000081F1 0000 add [bx+si],al
000081F3 0000 add [bx+si],al
000081F5 0000 add [bx+si],al
000081F7 0000 add [bx+si],al
000081F9 0000 add [bx+si],al
000081FB 0000 add [bx+si],al
000081FD 0055AA add [di-0x56],dl ; We can't forget the infamous boot signature

View File

@@ -1,7 +0,0 @@
cd bootsect
call make.bat
cd..
cd freeldr
make
copy freeldr.sys ..
cd ..

View File

@@ -1,114 +0,0 @@
#
# FreeLoader
# Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
export CC = gcc
export LD = ld
export AR = ar
export RM = cmd /C del
export CP = cmd /C copy
#FLAGS = -Wall -nostdinc -fno-builtin
FLAGS = -Wall -fno-builtin -DDEBUG
# asmcode.o has to be first in the link line because it contains the startup code
OBJS = asmcode.a asmcode.o mb.o boot.o freeldr.o stdlib.o fs.a fs.o fs_fat.o \
reactos.o tui.o menu.o miscboot.o options.o linux.o multiboot.o arcname.o \
mem.o memory.o debug.o parseini.o
ASM_OBJS = asmcode.o mb.o boot.o mem.o
C_OBJS = freeldr.o stdlib.o fs.a reactos.o tui.o menu.o miscboot.o options.o linux.o \
multiboot.o arcname.o memory.o debug.o parseini.o
.PHONY : clean
all: freeldr.sys
freeldr.sys: asmcode.a c_code.a
$(LD) -N -Ttext=0x8000 --oformat=binary -o freeldr.sys asmcode.a c_code.a
asmcode.a: $(ASM_OBJS)
$(LD) -r -o asmcode.a $(ASM_OBJS)
c_code.a: $(C_OBJS)
$(LD) -r -o c_code.a $(C_OBJS)
asmcode.o: asmcode.S asmcode.h Makefile
$(CC) $(FLAGS) -o asmcode.o -c asmcode.S
freeldr.o: freeldr.c freeldr.h stdlib.h fs.h reactos.h tui.h asmcode.h menu.h miscboot.h Makefile
$(CC) $(FLAGS) -o freeldr.o -c freeldr.c
stdlib.o: stdlib.c freeldr.h stdlib.h Makefile
$(CC) $(FLAGS) -o stdlib.o -c stdlib.c
fs.a: fs.o fs_fat.o Makefile
$(LD) -r -o fs.a fs.o fs_fat.o
fs.o: fs.c freeldr.h fs.h stdlib.h tui.h asmcode.h Makefile
$(CC) $(FLAGS) -o fs.o -c fs.c
fs_fat.o: fs_fat.c freeldr.h fs.h stdlib.h tui.h Makefile
$(CC) $(FLAGS) -o fs_fat.o -c fs_fat.c
reactos.o: reactos.c freeldr.h reactos.h stdlib.h fs.h tui.h multiboot.h Makefile
$(CC) $(FLAGS) -o reactos.o -c reactos.c
multiboot.o: multiboot.c freeldr.h stdlib.h fs.h multiboot.h tui.h Makefile
$(CC) $(FLAGS) -o multiboot.o -c multiboot.c
mb.o: mb.S asmcode.h multiboot.h Makefile
$(CC) $(FLAGS) -o mb.o -c mb.S
tui.o: tui.c freeldr.h stdlib.h tui.h Makefile
$(CC) $(FLAGS) -o tui.o -c tui.c
menu.o: menu.c freeldr.h stdlib.h tui.h menu.h Makefile
$(CC) $(FLAGS) -o menu.o -c menu.c
boot.o: boot.S asmcode.h Makefile
$(CC) $(FLAGS) -o boot.o -c boot.S
miscboot.o: miscboot.c freeldr.h asmcode.h stdlib.h fs.h tui.h miscboot.h Makefile
$(CC) $(FLAGS) -o miscboot.o -c miscboot.c
options.o: options.c freeldr.h stdlib.h tui.h options.h Makefile
$(CC) $(FLAGS) -o options.o -c options.c
linux.o: linux.c freeldr.h stdlib.h tui.h linux.h Makefile
$(CC) $(FLAGS) -o linux.o -c linux.c
arcname.o: arcname.c freeldr.h arcname.h stdlib.h Makefile
$(CC) $(FLAGS) -o arcname.o -c arcname.c
mem.o: mem.S asmcode.h Makefile
$(CC) $(FLAGS) -o mem.o -c mem.S
memory.o: memory.c memory.h Makefile
$(CC) $(FLAGS) -o memory.o -c memory.c
debug.o: debug.c debug.h Makefile
$(CC) $(FLAGS) -o debug.o -c debug.c
parseini.o: parseini.c parseini.h Makefile
$(CC) $(FLAGS) -o parseini.o -c parseini.c
clean:
$(RM) *.o
$(RM) *.a
$(RM) freeldr.sys

View File

@@ -1,75 +0,0 @@
/*
* FreeLoader - arcname.c
*
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
* Copyright (C) 2001 Eric Kohl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "arcname.h"
#include "stdlib.h"
BOOL DissectArcPath(char *ArcPath, char *BootPath, PULONG BootDrive, PULONG BootPartition)
{
char *p;
if (_strnicmp(ArcPath, "multi(0)disk(0)", 15) != 0)
return FALSE;
p = ArcPath + 15;
if (_strnicmp(p, "fdisk(", 6) == 0)
{
/*
* floppy disk path:
* multi(0)disk(0)fdisk(x)\path
*/
p = p + 6;
*BootDrive = atoi(p);
p = strchr(p, ')');
if (p == NULL)
return FALSE;
p++;
*BootPartition = 0;
}
else if (_strnicmp(p, "rdisk(", 6) == 0)
{
/*
* hard disk path:
* multi(0)disk(0)rdisk(x)partition(y)\path
*/
p = p + 6;
*BootDrive = atoi(p) + 0x80;
p = strchr(p, ')');
if ((p == NULL) || (_strnicmp(p, ")partition(", 11) != 0))
return FALSE;
p = p + 11;
*BootPartition = atoi(p);
p = strchr(p, ')');
if ((p == NULL) || (*BootPartition == 0))
return FALSE;
p++;
}
else
{
return FALSE;
}
strcpy(BootPath, p);
return TRUE;
}

View File

@@ -1,29 +0,0 @@
/*
* FreeLoader - arcname.h
*
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
* Copyright (C) 2001 Eric Kohl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ARCNAME_H
#define __ARCNAME_H
BOOL DissectArcPath(char *ArcPath, char *BootPath, PULONG BootDrive, PULONG BootPartition);
//BOOL ConvertBiosDriveToArcName(PUCHAR ArcName, ULONG BiosDriveNumber);
//ULONG ConvertArcNameToBiosDrive(PUCHAR ArcName);
#endif // defined __ARCNAME_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,65 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Defines needed for switching between real and protected mode */
#define NULL_DESC 0x00 /* NULL descriptor */
#define PMODE_CS 0x08 /* PMode code selector, base 0 limit 4g */
#define PMODE_DS 0x10 /* PMode data selector, base 0 limit 4g */
#define RMODE_CS 0x18 /* RMode code selector, base 0 limit 64k */
#define RMODE_DS 0x20 /* RMode data selector, base 0 limit 64k */
#define KERNEL_BASE 0xC0000000
//#define USER_CS 0x08
//#define USER_DS 0x10
//#define KERNEL_CS 0x20
//#define KERNEL_DS 0x28
#define KERNEL_CS 0x08
#define KERNEL_DS 0x10
#define CR0_PE_SET 0x00000001 /* OR this value with CR0 to enable pmode */
#define CR0_PE_CLR 0xFFFFFFFE /* AND this value with CR0 to disable pmode */
#define NR_TASKS 128 /* Space reserved in the GDT for TSS descriptors */
#define STACK16ADDR 0x7000 /* The 16-bit stack top will be at 0000:7000 */
#define STACK32ADDR 0x60000 /* The 32-bit stack top will be at 6000:0000, or 0x60000 */
#define FILESYSADDR 0x80000 /* The filesystem data address will be at 8000:0000, or 0x80000 */
#define FATCLUSTERBUF 0x60000 /* The fat filesystem's cluster buffer */
#define SCREENBUFFER 0x68000 /* The screen contents will be saved here */
#define FREELDRINIADDR 0x6C000 /* The freeldr.ini load address will be at 6000:C000, or 0x6C000 */
#define SCRATCHSEG 0x7000 /* The 512-byte fixed scratch area will be at 7000:0000, or 0x70000 */
#define SCRATCHOFF 0x0000 /* The 512-byte fixed scratch area will be at 7000:0000, or 0x70000 */
#define SCRATCHAREA 0x70000 /* The 512-byte fixed scratch area will be at 7000:0000, or 0x70000 */
/* Makes "x" a global variable or label */
#define EXTERN(x) .global x; x:
#ifndef ASM
void enable_a20(void);
#endif /* ! ASM */

View File

@@ -1,47 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
.text
.code16
#define ASM
#include "asmcode.h"
#include "multiboot.h"
.code32
EXTERN(_JumpToBootCode)
call switch_to_real
.code16
/* Set the boot drive */
movb (_BootDrive),%dl
ljmpl $0x0000,$0x7C00
.code32
EXTERN(_JumpToLinuxBootCode)
call switch_to_real
.code16
/* Set the boot drive */
movb (_BootDrive),%dl
ljmpl $0x0200,$0x9000

View File

@@ -1,83 +0,0 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "debug.h"
#include "stdlib.h"
ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY;
void DebugPrint(ULONG Mask, char *format, ...)
{
int *dataptr = (int *) &format;
char c, *ptr, str[16];
char buffer[512];
char *p = buffer;
// Mask out unwanted debug messages
if (!(Mask & DebugPrintMask))
{
return;
}
dataptr++;
while ((c = *(format++)))
{
if (c != '%')
{
*p = c;
p++;
}
else
switch (c = *(format++))
{
case 'd': case 'u': case 'x':
*convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0;
ptr = str;
while (*ptr)
{
*p = *(ptr++);
p++;
}
break;
case 'c':
*p = (*(dataptr++))&0xff;
p++;
break;
case 's':
ptr = (char *)(*(dataptr++));
while ((c = *(ptr++)))
{
*p = c;
p++;
}
break;
}
}
*p=0;
print(buffer);
}

View File

@@ -1,57 +0,0 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __DEBUG_H
#define __DEBUG_H
#define DPRINT_WARNING 0x00000001 // OR this with DebugPrintMask to enable debugger messages and other misc stuff
#define DPRINT_MEMORY 0x00000002 // OR this with DebugPrintMask to enable memory management messages
void DebugPrint(ULONG Mask, char *format, ...);
#define BugCheck0(format) \
{ \
DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
DebugPrint(DPRINT_WARNING, format); \
for (;;); \
}
#define BugCheck1(format, arg1) \
{ \
DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
DebugPrint(DPRINT_WARNING, format, arg1); \
for (;;); \
}
#define BugCheck2(format, arg1, arg2) \
{ \
DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
DebugPrint(DPRINT_WARNING, format, arg1, arg2); \
for (;;); \
}
#define BugCheck3(format, arg1, arg2, arg3) \
{ \
DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d\n", __FILE__, __LINE__); \
DebugPrint(DPRINT_WARNING, format, arg1, arg2, arg3); \
for (;;); \
}
#endif // defined __DEBUG_H

View File

@@ -1,128 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "stdlib.h"
#include "fs.h"
#include "reactos.h"
#include "tui.h"
#include "asmcode.h"
#include "menu.h"
#include "miscboot.h"
#include "linux.h"
#include "memory.h"
#include "parseini.h"
// Variable BootDrive moved to asmcode.S
//ULONG BootDrive = 0; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
ULONG BootPartition = 0; // Boot Partition, 1-4
BOOL UserInterfaceUp = FALSE; // Tells us if the user interface is displayed
PUCHAR ScreenBuffer = (PUCHAR)(SCREENBUFFER); // Save buffer for screen contents
int CursorXPos = 0; // Cursor's X Position
int CursorYPos = 0; // Cursor's Y Position
OSTYPE OSList[16];
int nNumOS = 0;
int nTimeOut = -1; // Time to wait for the user before booting
void BootMain(void)
{
int i;
char name[1024];
char value[1024];
int nOSToBoot;
enable_a20();
SaveScreen(ScreenBuffer);
CursorXPos = wherex();
CursorYPos = wherey();
printf("Loading FreeLoader...\n");
InitMemoryManager((PVOID)0x100000, 0x20000);
if (!ParseIniFile())
{
printf("Press any key to reboot.\n");
getch();
return;
}
clrscr();
hidecursor();
// Draw the backdrop and title box
DrawBackdrop();
UserInterfaceUp = TRUE;
if (nNumOS == 0)
{
DrawStatusText(" Press ENTER to reboot");
MessageBox("Error: there were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
clrscr();
showcursor();
RestoreScreen(ScreenBuffer);
return;
}
DrawStatusText(" Press ENTER to continue");
// Find all the message box settings and run them
for (i=1; i<=GetNumSectionItems("FREELOADER"); i++)
{
ReadSectionSettingByNumber("FREELOADER", i, name, value);
if (stricmp(name, "MessageBox") == 0)
MessageBox(value);
if (stricmp(name, "MessageLine") == 0)
MessageLine(value);
}
for (;;)
{
nOSToBoot = RunMenu();
switch (OSList[nOSToBoot].nOSType)
{
case OSTYPE_REACTOS:
LoadAndBootReactOS(OSList[nOSToBoot].name);
break;
case OSTYPE_LINUX:
MessageBox("Cannot boot this OS type yet!");
break;
case OSTYPE_BOOTSECTOR:
LoadAndBootBootSector(nOSToBoot);
break;
case OSTYPE_PARTITION:
LoadAndBootPartition(nOSToBoot);
break;
case OSTYPE_DRIVE:
LoadAndBootDrive(nOSToBoot);
break;
}
DrawBackdrop();
}
MessageBox("Press any key to reboot.");
RestoreScreen(ScreenBuffer);
showcursor();
gotoxy(CursorXPos, CursorYPos);
}

View File

@@ -1,83 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __FREELDR_H
#define __FREELDR_H
/* just some stuff */
#define VERSION "FreeLoader v0.8"
#define COPYRIGHT "Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>"
#define ROSLDR_MAJOR_VERSION 0
#define ROSLDR_MINOR_VERSION 8
#define ROSLDR_PATCH_VERSION 0
#define size_t unsigned int
#define BOOL int
#define NULL 0
#define TRUE 1
#define FALSE 0
#define BYTE unsigned char
#define WORD unsigned short
#define DWORD unsigned long
#define CHAR char
#define PCHAR char *
#define UCHAR unsigned char
#define PUCHAR unsigned char *
#define WCHAR unsigned short
#define PWCHAR unsigned short *
#define LONG long
#define ULONG unsigned long
#define PULONG unsigned long *
#define PDWORD DWORD *
#define PWORD WORD *
#define VOID void
#define PVOID VOID*
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
#define OSTYPE_REACTOS 1
#define OSTYPE_LINUX 2
#define OSTYPE_BOOTSECTOR 3
#define OSTYPE_PARTITION 4
#define OSTYPE_DRIVE 5
typedef struct
{
char name[260];
int nOSType; // ReactOS or Linux or a bootsector, etc.
} OSTYPE, *POSTYPE;
extern ULONG BootDrive; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
extern ULONG BootPartition; // Boot Partition, 1-4
extern BOOL UserInterfaceUp; // Tells us if the user interface is displayed
extern PUCHAR ScreenBuffer; // Save buffer for screen contents
extern int CursorXPos; // Cursor's X Position
extern int CursorYPos; // Cursor's Y Position
extern OSTYPE OSList[16]; // The OS list
extern int nNumOS; // Number of OSes listed
extern int nTimeOut; // Time to wait for the user before booting
void BootMain(void);
#endif // defined __FREELDR_H

View File

@@ -1,426 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "fs.h"
#include "stdlib.h"
#include "tui.h"
#include "asmcode.h"
#define FS_DO_ERROR(s) \
{ \
if (UserInterfaceUp) \
MessageBox(s); \
else \
{ \
printf(s); \
printf("\nPress any key\n"); \
getch(); \
} \
}
int nSectorBuffered = -1; // Tells us which sector was read into SectorBuffer[]
BYTE SectorBuffer[512]; // 512 byte buffer space for read operations, ReadOneSector reads to here
int FSType = NULL; // Type of filesystem on boot device, set by OpenDiskDrive()
char *pFileSysData = (char *)(FILESYSADDR); // Load address for filesystem data
char *pFat32FATCacheIndex = (char *)(FILESYSADDR); // Load address for filesystem data
BOOL OpenDiskDrive(int nDrive, int nPartition)
{
int num_bootable_partitions = 0;
int boot_partition = 0;
int partition_type = 0;
int head, sector, cylinder;
int offset;
// Check and see if it is a floppy drive
if (nDrive < 0x80)
{
// Read boot sector
if (!biosdisk(_DISK_READ, nDrive, 0, 0, 1, 1, SectorBuffer))
{
FS_DO_ERROR("Disk Read Error");
return FALSE;
}
// Check for validity
if (*((WORD*)(SectorBuffer + 0x1fe)) != 0xaa55)//(SectorBuffer[0x1FE] != 0x55) || (SectorBuffer[0x1FF] != 0xAA))
{
FS_DO_ERROR("Invalid boot sector magic (0xaa55)");
return FALSE;
}
}
else
{
// Read master boot record
if (!biosdisk(_DISK_READ, nDrive, 0, 0, 1, 1, SectorBuffer))
{
FS_DO_ERROR("Disk Read Error");
return FALSE;
}
// Check for validity
if (*((WORD*)(SectorBuffer + 0x1fe)) != 0xaa55)//(SectorBuffer[0x1FE] != 0x55) || (SectorBuffer[0x1FF] != 0xAA))
{
FS_DO_ERROR("Invalid partition table magic (0xaa55)");
return FALSE;
}
if (nPartition == 0)
{
// Check for bootable partitions
if (SectorBuffer[0x1BE] == 0x80)
num_bootable_partitions++;
if (SectorBuffer[0x1CE] == 0x80)
{
num_bootable_partitions++;
boot_partition = 1;
}
if (SectorBuffer[0x1DE] == 0x80)
{
num_bootable_partitions++;
boot_partition = 2;
}
if (SectorBuffer[0x1EE] == 0x80)
{
num_bootable_partitions++;
boot_partition = 3;
}
// Make sure there was only one bootable partition
if (num_bootable_partitions > 1)
{
FS_DO_ERROR("Too many boot partitions");
return FALSE;
}
offset = 0x1BE + (boot_partition * 0x10);
}
else
offset = 0x1BE + ((nPartition-1) * 0x10);
partition_type = SectorBuffer[offset + 4];
// Check for valid partition
if (partition_type == 0)
{
FS_DO_ERROR("Invalid boot partition");
return FALSE;
}
head = SectorBuffer[offset + 1];
sector = (SectorBuffer[offset + 2] & 0x3F);
cylinder = SectorBuffer[offset + 3];
if (SectorBuffer[offset + 2] & 0x80)
cylinder += 0x200;
if (SectorBuffer[offset + 2] & 0x40)
cylinder += 0x100;
// Read partition boot sector
if (!biosdisk(_DISK_READ, nDrive, head, cylinder, sector, 1, SectorBuffer))
{
FS_DO_ERROR("Disk Read Error");
return FALSE;
}
// Check for validity
if (*((WORD*)(SectorBuffer + 0x1fe)) != 0xaa55)//(SectorBuffer[0x1FE] != 0x55) || (SectorBuffer[0x1FF] != 0xAA))
{
FS_DO_ERROR("Invalid boot sector magic (0xaa55)");
return FALSE;
}
}
// Reset data
nBytesPerSector = 0;
nSectorsPerCluster = 0;
nReservedSectors = 0;
nNumberOfFATs = 0;
nRootDirEntries = 0;
nTotalSectors16 = 0;
nSectorsPerFAT16 = 0;
nSectorsPerTrack = 0;
nNumberOfHeads = 0;
nHiddenSectors = 0;
nTotalSectors32 = 0;
nSectorsPerFAT32 = 0;
nExtendedFlags = 0;
nFileSystemVersion = 0;
nRootDirStartCluster = 0;
nRootDirSectorStart = 0;
nDataSectorStart = 0;
nSectorsPerFAT = 0;
nRootDirSectors = 0;
nTotalSectors = 0;
nNumberOfClusters = 0;
// Get data
memcpy(&nBytesPerSector, SectorBuffer + BPB_BYTESPERSECTOR, 2);
memcpy(&nSectorsPerCluster, SectorBuffer + BPB_SECTORSPERCLUSTER, 1);
memcpy(&nReservedSectors, SectorBuffer + BPB_RESERVEDSECTORS, 2);
memcpy(&nNumberOfFATs, SectorBuffer + BPB_NUMBEROFFATS, 1);
memcpy(&nRootDirEntries, SectorBuffer + BPB_ROOTDIRENTRIES, 2);
memcpy(&nTotalSectors16, SectorBuffer + BPB_TOTALSECTORS16, 2);
memcpy(&nSectorsPerFAT16, SectorBuffer + BPB_SECTORSPERFAT16, 2);
memcpy(&nSectorsPerTrack, SectorBuffer + BPB_SECTORSPERTRACK, 2);
memcpy(&nNumberOfHeads, SectorBuffer + BPB_NUMBEROFHEADS, 2);
memcpy(&nHiddenSectors, SectorBuffer + BPB_HIDDENSECTORS, 4);
memcpy(&nTotalSectors32, SectorBuffer + BPB_TOTALSECTORS32, 4);
memcpy(&nSectorsPerFAT32, SectorBuffer + BPB_SECTORSPERFAT32, 4);
memcpy(&nExtendedFlags, SectorBuffer + BPB_EXTENDEDFLAGS32, 2);
memcpy(&nFileSystemVersion, SectorBuffer + BPB_FILESYSTEMVERSION32, 2);
memcpy(&nRootDirStartCluster, SectorBuffer + BPB_ROOTDIRSTARTCLUSTER32, 4);
// Calc some stuff
if (nTotalSectors16 != 0)
nTotalSectors = nTotalSectors16;
else
nTotalSectors = nTotalSectors32;
if (nSectorsPerFAT16 != 0)
nSectorsPerFAT = nSectorsPerFAT16;
else
nSectorsPerFAT = nSectorsPerFAT32;
nRootDirSectorStart = (nNumberOfFATs * nSectorsPerFAT) + nReservedSectors;
nRootDirSectors = ((nRootDirEntries * 32) + (nBytesPerSector - 1)) / nBytesPerSector;
nDataSectorStart = nReservedSectors + (nNumberOfFATs * nSectorsPerFAT) + nRootDirSectors;
nNumberOfClusters = (nTotalSectors - nDataSectorStart) / nSectorsPerCluster;
// Determine FAT type
if (nNumberOfClusters < 4085)
{
/* Volume is FAT12 */
nFATType = FAT12;
}
else if (nNumberOfClusters < 65525)
{
/* Volume is FAT16 */
nFATType = FAT16;
}
else
{
/* Volume is FAT32 */
nFATType = FAT32;
// Check version
// we only work with version 0
if (*((WORD*)(SectorBuffer + BPB_FILESYSTEMVERSION32)) != 0)
{
FS_DO_ERROR("Error: FreeLoader is too old to work with this FAT32 filesystem.\nPlease update FreeLoader.");
return FALSE;
}
}
FSType = FS_FAT;
// Buffer the FAT table if it is small enough
if ((FSType == FS_FAT) && (nFATType == FAT12))
{
if (!ReadMultipleSectors(nReservedSectors, nSectorsPerFAT, pFileSysData))
return FALSE;
}
else if ((FSType == FS_FAT) && (nFATType == FAT16))
{
if (!ReadMultipleSectors(nReservedSectors, nSectorsPerFAT, pFileSysData))
return FALSE;
}
else if ((FSType == FS_FAT) && (nFATType == FAT32))
{
// The FAT table is too big to be buffered so
// we will initialize our cache and cache it
// on demand
for (offset=0; offset<256; offset++)
((int*)pFat32FATCacheIndex)[offset] = -1;
}
return TRUE;
}
BOOL ReadMultipleSectors(int nSect, int nNumberOfSectors, void *pBuffer)
{
BOOL bRetVal;
int PhysicalSector;
int PhysicalHead;
int PhysicalTrack;
int nNum;
nSect += nHiddenSectors;
while (nNumberOfSectors)
{
PhysicalSector = 1 + (nSect % nSectorsPerTrack);
PhysicalHead = (nSect / nSectorsPerTrack) % nNumberOfHeads;
PhysicalTrack = nSect / (nSectorsPerTrack * nNumberOfHeads);
if (PhysicalSector > 1)
{
if (nNumberOfSectors >= (nSectorsPerTrack - (PhysicalSector - 1)))
nNum = (nSectorsPerTrack - (PhysicalSector - 1));
else
nNum = nNumberOfSectors;
}
else
{
if (nNumberOfSectors >= nSectorsPerTrack)
nNum = nSectorsPerTrack;
else
nNum = nNumberOfSectors;
}
bRetVal = biosdisk(_DISK_READ, BootDrive, PhysicalHead, PhysicalTrack, PhysicalSector, nNum, pBuffer);
if (!bRetVal)
{
FS_DO_ERROR("Disk Error");
return FALSE;
}
pBuffer += (nNum * 512);
nNumberOfSectors -= nNum;
nSect += nNum;
}
return TRUE;
}
BOOL ReadOneSector(int nSect)
{
BOOL bRetVal;
int PhysicalSector;
int PhysicalHead;
int PhysicalTrack;
nSectorBuffered = nSect;
nSect += nHiddenSectors;
PhysicalSector = 1 + (nSect % nSectorsPerTrack);
PhysicalHead = (nSect / nSectorsPerTrack) % nNumberOfHeads;
PhysicalTrack = nSect / (nSectorsPerTrack * nNumberOfHeads);
bRetVal = biosdisk(_DISK_READ, BootDrive, PhysicalHead, PhysicalTrack, PhysicalSector, 1, SectorBuffer);
if (!bRetVal)
{
FS_DO_ERROR("Disk Error");
return FALSE;
}
return TRUE;
}
BOOL OpenFile(char *filename, FILE *pFile)
{
switch(FSType)
{
case FS_FAT:
if(!FATOpenFile(filename, &(pFile->fat)))
return FALSE;
pFile->filesize = pFile->fat.dwSize;
break;
default:
FS_DO_ERROR("Error: Unknown filesystem.");
return FALSE;
break;
}
return TRUE;
}
/*
* ReadFile()
* returns number of bytes read or EOF
*/
int ReadFile(FILE *pFile, int count, void *buffer)
{
switch(FSType)
{
case FS_FAT:
return FATRead(&(pFile->fat), count, buffer);
default:
FS_DO_ERROR("Error: Unknown filesystem.");
return EOF;
}
return 0;
}
DWORD GetFileSize(FILE *pFile)
{
return pFile->filesize;
}
DWORD Rewind(FILE *pFile)
{
switch (FSType)
{
case FS_FAT:
pFile->fat.dwCurrentCluster = pFile->fat.dwStartCluster;
pFile->fat.dwCurrentReadOffset = 0;
break;
default:
FS_DO_ERROR("Error: Unknown filesystem.");
break;
}
return pFile->filesize;
}
int feof(FILE *pFile)
{
switch (FSType)
{
case FS_FAT:
if (pFile->fat.dwCurrentReadOffset >= pFile->fat.dwSize)
return TRUE;
else
return FALSE;
break;
default:
FS_DO_ERROR("Error: Unknown filesystem.");
return TRUE;
break;
}
return TRUE;
}
int fseek(FILE *pFile, DWORD offset)
{
switch (FSType)
{
case FS_FAT:
return FATfseek(&(pFile->fat), offset);
break;
default:
FS_DO_ERROR("Error: Unknown filesystem.");
break;
}
return -1;
}

View File

@@ -1,182 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __FS_FAT_H
#define __FS_FAT_H
// Bootsector BPB defines
#define BPB_JMPBOOT 0
#define BPB_OEMNAME 3
#define BPB_BYTESPERSECTOR 11
#define BPB_SECTORSPERCLUSTER 13
#define BPB_RESERVEDSECTORS 14
#define BPB_NUMBEROFFATS 16
#define BPB_ROOTDIRENTRIES 17
#define BPB_TOTALSECTORS16 19
#define BPB_MEDIADESCRIPTOR 21
#define BPB_SECTORSPERFAT16 22
#define BPB_SECTORSPERTRACK 24
#define BPB_NUMBEROFHEADS 26
#define BPB_HIDDENSECTORS 28
#define BPB_TOTALSECTORS32 32
// Fat12/16 extended BPB defines
#define BPB_DRIVENUMBER16 36
#define BPB_RESERVED16_1 37
#define BPB_BOOTSIGNATURE16 38
#define BPB_VOLUMESERIAL16 39
#define BPB_VOLUMELABEL16 43
#define BPB_FILESYSTEMTYPE16 54
// Fat32 extended BPB defines
#define BPB_SECTORSPERFAT32 36
#define BPB_EXTENDEDFLAGS32 40
#define BPB_FILESYSTEMVERSION32 42
#define BPB_ROOTDIRSTARTCLUSTER32 44
#define BPB_FILESYSTEMINFOSECTOR32 48
#define BPB_BACKUPBOOTSECTOR32 50
#define BPB_RESERVED32_1 52
#define BPB_DRIVENUMBER32 64
#define BPB_RESERVED32_2 65
#define BPB_BOOTSIGNATURE32 66
#define BPB_VOLUMESERIAL32 67
#define BPB_VOLUMELABEL32 71
#define BPB_FILESYSTEMTYPE32 82
/*
* Structure of MSDOS directory entry
*/
typedef struct //_DIRENTRY
{
BYTE cFileName[11]; /* Filename + extension */
BYTE cAttr; /* File attributes */
BYTE cReserved[10]; /* Reserved area */
WORD wTime; /* Time last modified */
WORD wData; /* Date last modified */
WORD wCluster; /* First cluster number */
DWORD dwSize; /* File size */
} DIRENTRY, * PDIRENTRY;
/*
* Structure of internal file control block
*/
typedef struct //_FCB
{
BYTE cAttr; /* Open attributes */
BYTE cSector; /* Sector within cluster */
PDIRENTRY pDirptr; /* Pointer to directory entry */
WORD wDirSector; /* Directory sector */
WORD wFirstCluster; /* First cluster in file */
WORD wLastCluster; /* Last cluster read/written */
WORD wNextCluster; /* Next cluster to read/write */
WORD wOffset; /* Read/Write offset within sector */
DWORD dwSize; /* File size */
BYTE cBuffer[512]; /* Data transfer buffer */
} FCB, * PFCB;
typedef struct //_FAT_STRUCT
{
DWORD dwStartCluster; // File's starting cluster
DWORD dwCurrentCluster; // Current read cluster number
DWORD dwSize; // File size
DWORD dwCurrentReadOffset;// Amount of data already read
} FAT_STRUCT, * PFAT_STRUCT;
typedef struct //_FILE
{
//DIRENTRY de;
//FCB fcb;
FAT_STRUCT fat;
unsigned long filesize;
} FILE;
extern int nSectorBuffered; // Tells us which sector was read into SectorBuffer[]
extern BYTE SectorBuffer[512]; // 512 byte buffer space for read operations, ReadOneSector reads to here
extern int nFATType;
extern DWORD nBytesPerSector; // Bytes per sector
extern DWORD nSectorsPerCluster; // Number of sectors in a cluster
extern DWORD nReservedSectors; // Reserved sectors, usually 1 (the bootsector)
extern DWORD nNumberOfFATs; // Number of FAT tables
extern DWORD nRootDirEntries; // Number of root directory entries (fat12/16)
extern DWORD nTotalSectors16; // Number of total sectors on the drive, 16-bit
extern DWORD nSectorsPerFAT16; // Sectors per FAT table (fat12/16)
extern DWORD nSectorsPerTrack; // Number of sectors in a track
extern DWORD nNumberOfHeads; // Number of heads on the disk
extern DWORD nHiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
extern DWORD nTotalSectors32; // Number of total sectors on the drive, 32-bit
extern DWORD nSectorsPerFAT32; // Sectors per FAT table (fat32)
extern DWORD nExtendedFlags; // Extended flags (fat32)
extern DWORD nFileSystemVersion; // File system version (fat32)
extern DWORD nRootDirStartCluster; // Starting cluster of the root directory (fat32)
extern DWORD nRootDirSectorStart; // Starting sector of the root directory (fat12/16)
extern DWORD nDataSectorStart; // Starting sector of the data area
extern DWORD nSectorsPerFAT; // Sectors per FAT table
extern DWORD nRootDirSectors; // Number of sectors of the root directory (fat32)
extern DWORD nTotalSectors; // Total sectors on the drive
extern DWORD nNumberOfClusters; // Number of clusters on the drive
extern int FSType; // Type of filesystem on boot device, set by OpenDiskDrive()
extern char *pFileSysData; // Load address for filesystem data
extern char *pFat32FATCacheIndex; // Load address for filesystem data
BOOL OpenDiskDrive(int nDrive, int nPartition); // Opens the disk drive device for reading
BOOL ReadMultipleSectors(int nSect, int nNumberOfSectors, void *pBuffer);// Reads a sector from the open device
BOOL ReadOneSector(int nSect); // Reads one sector from the open device
BOOL OpenFile(char *filename, FILE *pFile); // Opens a file
int ReadFile(FILE *pFile, int count, void *buffer); // Reads count bytes from pFile into buffer
DWORD GetFileSize(FILE *pFile);
DWORD Rewind(FILE *pFile); // Rewinds a file and returns it's size
int feof(FILE *pFile);
int fseek(FILE *pFILE, DWORD offset);
BOOL FATLookupFile(char *file, PFAT_STRUCT pFatStruct);
int FATGetNumPathParts(char *name);
BOOL FATGetFirstNameFromPath(char *buffer, char *name);
void FATParseFileName(char *buffer, char *name);
DWORD FATGetFATEntry(DWORD nCluster);
BOOL FATOpenFile(char *szFileName, PFAT_STRUCT pFatStruct);
int FATReadCluster(DWORD nCluster, char *cBuffer);
int FATRead(PFAT_STRUCT pFatStruct, int nNumBytes, char *cBuffer);
int FATfseek(PFAT_STRUCT pFatStruct, DWORD offset);
#define EOF -1
#define ATTR_NORMAL 0x00
#define ATTR_READONLY 0x01
#define ATTR_HIDDEN 0x02
#define ATTR_SYSTEM 0x04
#define ATTR_VOLUMENAME 0x08
#define ATTR_DIRECTORY 0x10
#define ATTR_ARCHIVE 0x20
#define FS_FAT 1
#define FS_NTFS 2
#define FS_EXT2 3
#define FAT12 1
#define FAT16 2
#define FAT32 3
#endif // #defined __FS_FAT_H

View File

@@ -1,541 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "fs.h"
#include "stdlib.h"
#include "tui.h"
#include "asmcode.h"
int nFATType = FAT12;
DWORD nBytesPerSector; // Bytes per sector
DWORD nSectorsPerCluster; // Number of sectors in a cluster
DWORD nReservedSectors; // Reserved sectors, usually 1 (the bootsector)
DWORD nNumberOfFATs; // Number of FAT tables
DWORD nRootDirEntries; // Number of root directory entries (fat12/16)
DWORD nTotalSectors16; // Number of total sectors on the drive, 16-bit
DWORD nSectorsPerFAT16; // Sectors per FAT table (fat12/16)
DWORD nSectorsPerTrack; // Number of sectors in a track
DWORD nNumberOfHeads; // Number of heads on the disk
DWORD nHiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
DWORD nTotalSectors32; // Number of total sectors on the drive, 32-bit
DWORD nSectorsPerFAT32; // Sectors per FAT table (fat32)
DWORD nExtendedFlags; // Extended flags (fat32)
DWORD nFileSystemVersion; // File system version (fat32)
DWORD nRootDirStartCluster; // Starting cluster of the root directory (fat32)
DWORD nRootDirSectorStart; // Starting sector of the root directory (fat12/16)
DWORD nDataSectorStart; // Starting sector of the data area
DWORD nSectorsPerFAT; // Sectors per FAT table
DWORD nRootDirSectors; // Number of sectors of the root directory (fat32)
DWORD nTotalSectors; // Total sectors on the drive
DWORD nNumberOfClusters; // Number of clusters on the drive
BOOL FATReadRootDirectoryEntry(int nDirEntry, void *pDirEntryBuf)
{
DWORD nDirEntrySector;
int nOffsetWithinSector;
nDirEntrySector = nRootDirSectorStart + ((nDirEntry * 32) / nBytesPerSector);
if (!ReadOneSector(nDirEntrySector))
return FALSE;
nOffsetWithinSector = (nDirEntry * 32) % nBytesPerSector;
memcpy(pDirEntryBuf, SectorBuffer + nOffsetWithinSector, 32);
if (*((char *)pDirEntryBuf) == 0x05)
*((char *)pDirEntryBuf) = 0xE5;
return TRUE;
}
BOOL FATReadDirectoryEntry(DWORD nDirStartCluster, int nDirEntry, void *pDirEntryBuf)
{
DWORD nRealDirCluster;
int nSectorWithinCluster;
int nOffsetWithinSector;
int nSectorToRead;
int i;
i = (nDirEntry * 32) / (nSectorsPerCluster * nBytesPerSector);
//if ((nDirEntry * 32) % (nSectorsPerCluster * nBytesPerSector))
// i++;
for (nRealDirCluster = nDirStartCluster; i; i--)
nRealDirCluster = FATGetFATEntry(nRealDirCluster);
nSectorWithinCluster = ((nDirEntry * 32) % (nSectorsPerCluster * nBytesPerSector)) / nBytesPerSector;
nSectorToRead = ((nRealDirCluster - 2) * nSectorsPerCluster) + nDataSectorStart + nSectorWithinCluster;
if (!ReadOneSector(nSectorToRead))
return FALSE;
nOffsetWithinSector = (nDirEntry * 32) % nBytesPerSector;
memcpy(pDirEntryBuf, SectorBuffer + nOffsetWithinSector, 32);
if (*((char *)pDirEntryBuf) == 0x05)
*((char *)pDirEntryBuf) = 0xE5;
return TRUE;
}
/*
* FATLookupFile()
* This function searches the file system for the
* specified filename and fills in a FAT_STRUCT structure
* with info describing the file, etc. returns true
* if the file exists or false otherwise
*/
BOOL FATLookupFile(char *file, PFAT_STRUCT pFatStruct)
{
int i, j;
int numparts;
char filename[12];
BYTE direntry[32];
int nNumDirEntries;
FAT_STRUCT fatstruct;
BOOL bFound;
DWORD cluster;
memset(pFatStruct, 0, sizeof(FAT_STRUCT));
// Check and see if the first character is '\' and remove it if so
if (*file == '\\')
file++;
// Figure out how many sub-directories we are nested in
numparts = FATGetNumPathParts(file);
// Loop once for each part
for (i=0; i<numparts; i++)
{
// Make filename compatible with MSDOS dir entry
if (!FATGetFirstNameFromPath(filename, file))
return FALSE;
// Advance to the next part of the path
for (; (*file != '\\') && (*file != '\0'); file++);
file++;
// If we didn't find the correct sub-directory the fail
if ((i != 0) && !bFound)
return FALSE;
bFound = FALSE;
// Check if we are pulling from the root directory of a fat12/fat16 disk
if ((i == 0) && ((nFATType == FAT12) || (nFATType == FAT16)))
nNumDirEntries = nRootDirEntries;
else if ((i == 0) && (nFATType == FAT32))
{
cluster = nRootDirStartCluster;
fatstruct.dwSize = nSectorsPerCluster * nBytesPerSector;
while((cluster = FATGetFATEntry(cluster)) < 0x0FFFFFF8)
fatstruct.dwSize += nSectorsPerCluster * nBytesPerSector;
fatstruct.dwStartCluster = nRootDirStartCluster;
nNumDirEntries = fatstruct.dwSize / 32;
}
else
nNumDirEntries = fatstruct.dwSize / 32;
// Loop through each directory entry
for (j=0; j<nNumDirEntries; j++)
{
// Read the entry
if ((i == 0) && ((nFATType == FAT12) || (nFATType == FAT16)))
{
if (!FATReadRootDirectoryEntry(j, direntry))
return FALSE;
}
else
{
if (!FATReadDirectoryEntry(fatstruct.dwStartCluster, j, direntry))
return FALSE;
}
if (memcmp(direntry, filename, 11) == 0)
{
fatstruct.dwStartCluster = 0;
fatstruct.dwCurrentCluster = 0;
memcpy(&fatstruct.dwStartCluster, direntry + 26, sizeof(WORD));
memcpy(&fatstruct.dwCurrentCluster, direntry + 20, sizeof(WORD));
fatstruct.dwStartCluster += (fatstruct.dwCurrentCluster * 0x10000);
if (direntry[11] & ATTR_DIRECTORY)
{
fatstruct.dwSize = nSectorsPerCluster * nBytesPerSector;
cluster = fatstruct.dwStartCluster;
switch (nFATType)
{
case FAT12:
while((cluster = FATGetFATEntry(cluster)) < 0xFF8)
fatstruct.dwSize += nSectorsPerCluster * nBytesPerSector;
break;
case FAT16:
while((cluster = FATGetFATEntry(cluster)) < 0xFFF8)
fatstruct.dwSize += nSectorsPerCluster * nBytesPerSector;
break;
case FAT32:
while((cluster = FATGetFATEntry(cluster)) < 0x0FFFFFF8)
fatstruct.dwSize += nSectorsPerCluster * nBytesPerSector;
break;
}
}
// If we have more parts to go and this isn't a directory then fail
if ((i < (numparts-1)) && !(direntry[11] & ATTR_DIRECTORY))
return FALSE;
// If this is supposed to be a file and it is a directory then fail
if ((i == (numparts-1)) && (direntry[11] & ATTR_DIRECTORY))
return FALSE;
bFound = TRUE;
break;
}
}
}
if(!bFound)
return FALSE;
memcpy(&pFatStruct->dwStartCluster, direntry + 26, sizeof(WORD));
memcpy(&pFatStruct->dwCurrentCluster, direntry + 20, sizeof(WORD));
pFatStruct->dwStartCluster += (pFatStruct->dwCurrentCluster * 0x10000);
pFatStruct->dwCurrentCluster = pFatStruct->dwStartCluster;
memcpy(&pFatStruct->dwSize, direntry + 28, sizeof(DWORD));
pFatStruct->dwCurrentReadOffset = 0;
return TRUE;
}
/*
* FATGetNumPathParts()
* This function parses a path in the form of dir1\dir2\file1.ext
* and returns the number of parts it has (i.e. 3 - dir1,dir2,file1.ext)
*/
int FATGetNumPathParts(char *name)
{
int i, num;
for(i=0,num=0; i<(int)strlen(name); i++)
{
if(name[i] == '\\')
num++;
}
num++;
return num;
}
/*
* FATGetFirstNameFromPath()
* This function parses a path in the form of dir1\dir2\file1.ext
* and puts the first name of the path (e.g. "dir1") in buffer
* compatible with the MSDOS directory structure
*/
BOOL FATGetFirstNameFromPath(char *buffer, char *name)
{
int i;
char temp[260];
// Copy all the characters up to the end of the
// string or until we hit a '\' character
// and put them in temp
for(i=0; i<(int)strlen(name); i++)
{
if(name[i] == '\\')
break;
else
temp[i] = name[i];
}
temp[i] = 0;
// If the filename is too long then fail
if(strlen(temp) > 12)
return FALSE;
FATParseFileName(buffer, temp);
return TRUE;
}
/*
* FATParseFileName()
* This function parses "name" which is in the form of file.ext
* and puts it in "buffer" in the form of "FILE EXT" which
* is compatible with the MSDOS directory structure
*/
void FATParseFileName(char *buffer, char *name)
{
int i, j;
i = 0;
j = 0;
while(i < 8)
buffer[i++] = (name[j] && (name[j] != '.')) ? toupper(name[j++]) : ' ';
if(name[j] == '.')
j++;
while(i < 11)
buffer[i++] = name[j] ? toupper(name[j++]) : ' ';
buffer[i] = 0;
}
/*
* FATGetFATEntry()
* returns the FAT entry for a given cluster number
*/
DWORD FATGetFATEntry(DWORD nCluster)
{
DWORD fat;
int FATOffset;
int ThisFATSecNum;
int ThisFATEntOffset;
int Idx;
BOOL bEntryFound;
switch(nFATType)
{
case FAT12:
FATOffset = nCluster + (nCluster / 2);
ThisFATSecNum = (FATOffset / nBytesPerSector);
ThisFATEntOffset = (FATOffset % nBytesPerSector);
fat = *((WORD *) (pFileSysData + (ThisFATSecNum * nBytesPerSector) + ThisFATEntOffset));
if (nCluster & 0x0001)
fat = fat >> 4; /* Cluster number is ODD */
else
fat = fat & 0x0FFF; /* Cluster number is EVEN */
return fat;
break;
case FAT16:
FATOffset = (nCluster * 2);
//ThisFATSecNum = nReservedSectors + (FATOffset / nBytesPerSector);
//ThisFATEntOffset = (FATOffset % nBytesPerSector);
//if (!ReadOneSector(ThisFATSecNum))
// return NULL;
//fat = *((WORD *) &SectorBuffer[ThisFATEntOffset]);
fat = *((WORD *) (pFileSysData + FATOffset));
return fat;
break;
case FAT32:
//if (!ReadOneSector(ThisFATSecNum))
// return NULL;
//fat = *((DWORD *) &SectorBuffer[ThisFATEntOffset]) & 0x0FFFFFFF;
//return fat;
// This code manages the fat32 fat table entry cache
// The cache is at address FILESYSADDR which is 128k in size
// The first two sectors will contain an array of DWORDs that
// Specify what fat sector is cached. The first two DWORDs
// should be zero.
FATOffset = (nCluster * 4);
ThisFATSecNum = nReservedSectors + (FATOffset / nBytesPerSector);
ThisFATEntOffset = (FATOffset % nBytesPerSector);
// Now we go through our cache and see if we already have the sector cached
bEntryFound = FALSE;
for (Idx=2; Idx<256; Idx++)
{
if (((int*)pFat32FATCacheIndex)[Idx] == ThisFATSecNum)
{
bEntryFound = TRUE;
break;
}
}
if (bEntryFound)
{
// Get the fat entry
fat = (*((DWORD *) (pFat32FATCacheIndex +
(Idx * nBytesPerSector) + ThisFATEntOffset))) & 0x0FFFFFFF;
}
else
{
if (!ReadOneSector(ThisFATSecNum))
return NULL;
// Move each sector down in the cache to make room for new sector
for (Idx=255; Idx>2; Idx--)
{
memcpy(pFat32FATCacheIndex + (Idx * nBytesPerSector), pFat32FATCacheIndex + ((Idx - 1) * nBytesPerSector), nBytesPerSector);
((int*)pFat32FATCacheIndex)[Idx] = ((int*)pFat32FATCacheIndex)[Idx - 1];
}
// Insert it into the cache
memcpy(pFat32FATCacheIndex + (2 * nBytesPerSector), SectorBuffer, nBytesPerSector);
((int*)pFat32FATCacheIndex)[2] = ThisFATSecNum;
// Get the fat entry
fat = (*((DWORD *) (pFat32FATCacheIndex +
(2 * nBytesPerSector) + ThisFATEntOffset))) & 0x0FFFFFFF;
}
return fat;
break;
}
return NULL;
}
/*
* FATOpenFile()
* Tries to open the file 'name' and returns true or false
* for success and failure respectively
*/
BOOL FATOpenFile(char *szFileName, PFAT_STRUCT pFatStruct)
{
if(!FATLookupFile(szFileName, pFatStruct))
return FALSE;
/* Fill in file control information */
pFatStruct->dwCurrentCluster = pFatStruct->dwStartCluster;
pFatStruct->dwCurrentReadOffset = 0;
return TRUE;
}
/*
* FATReadCluster()
* Reads the specified cluster into memory
* and returns the number of bytes read
*/
int FATReadCluster(DWORD nCluster, char *cBuffer)
{
int nStartSector;
nStartSector = ((nCluster - 2) * nSectorsPerCluster) + nDataSectorStart;
ReadMultipleSectors(nStartSector, nSectorsPerCluster, cBuffer);
return (nSectorsPerCluster * nBytesPerSector);
}
/*
* FATRead()
* Reads nNumBytes from open file and
* returns the number of bytes read
*/
int FATRead(PFAT_STRUCT pFatStruct, int nNumBytes, char *cBuffer)
{
int nSectorWithinCluster;
int nOffsetWithinSector;
int nOffsetWithinCluster;
int nNum;
int nBytesRead = 0;
// If all the data is read return zero
if (pFatStruct->dwCurrentReadOffset >= pFatStruct->dwSize)
return 0;
// If they are trying to read more than there is to read
// then adjust the amount to read
if ((pFatStruct->dwCurrentReadOffset + nNumBytes) > pFatStruct->dwSize)
nNumBytes = pFatStruct->dwSize - pFatStruct->dwCurrentReadOffset;
while (nNumBytes)
{
// Check and see if the read offset is aligned to a cluster boundary
// if so great, if not then read the rest of the current cluster
if ((pFatStruct->dwCurrentReadOffset % (nSectorsPerCluster * nBytesPerSector)) != 0)
{
nSectorWithinCluster = ((pFatStruct->dwCurrentReadOffset / nBytesPerSector) % nSectorsPerCluster);
nOffsetWithinSector = (pFatStruct->dwCurrentReadOffset % nBytesPerSector);
nOffsetWithinCluster = (pFatStruct->dwCurrentReadOffset % (nSectorsPerCluster * nBytesPerSector));
// Read the cluster into the scratch area
FATReadCluster(pFatStruct->dwCurrentCluster, (char *)FATCLUSTERBUF);
nNum = (nSectorsPerCluster * nBytesPerSector) - (pFatStruct->dwCurrentReadOffset % (nSectorsPerCluster * nBytesPerSector));
if (nNumBytes >= nNum)
{
memcpy(cBuffer, (char *)(FATCLUSTERBUF + nOffsetWithinCluster), nNum);
nBytesRead += nNum;
cBuffer += nNum;
pFatStruct->dwCurrentReadOffset += nNum;
pFatStruct->dwCurrentCluster = FATGetFATEntry(pFatStruct->dwCurrentCluster);
nNumBytes -= nNum;
}
else
{
memcpy(cBuffer, (char *)(FATCLUSTERBUF + nOffsetWithinCluster), nNumBytes);
nBytesRead += nNumBytes;
cBuffer += nNumBytes;
pFatStruct->dwCurrentReadOffset += nNumBytes;
nNumBytes -= nNumBytes;
}
}
else
{
// Read the cluster into the scratch area
FATReadCluster(pFatStruct->dwCurrentCluster, (char *)FATCLUSTERBUF);
nNum = (nSectorsPerCluster * nBytesPerSector);
if (nNumBytes >= nNum)
{
memcpy(cBuffer, (char *)(FATCLUSTERBUF), nNum);
nBytesRead += nNum;
cBuffer += nNum;
pFatStruct->dwCurrentReadOffset += nNum;
pFatStruct->dwCurrentCluster = FATGetFATEntry(pFatStruct->dwCurrentCluster);
nNumBytes -= nNum;
}
else
{
memcpy(cBuffer, (char *)(FATCLUSTERBUF), nNumBytes);
nBytesRead += nNumBytes;
cBuffer += nNumBytes;
pFatStruct->dwCurrentReadOffset += nNumBytes;
nNumBytes -= nNumBytes;
}
}
}
return nBytesRead;
}
int FATfseek(PFAT_STRUCT pFatStruct, DWORD offset)
{
DWORD cluster;
int numclusters;
numclusters = offset / (nSectorsPerCluster * nBytesPerSector);
for (cluster=pFatStruct->dwStartCluster; numclusters > 0; numclusters--)
cluster = FATGetFATEntry(cluster);
pFatStruct->dwCurrentCluster = cluster;
pFatStruct->dwCurrentReadOffset = offset;
return 0;
}

View File

@@ -1,101 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "asmcode.h"
#include "miscboot.h"
#include "stdlib.h"
#include "fs.h"
#include "tui.h"
#include "linux.h"
void LoadAndBootLinux(int DriveNum, int Partition, char *vmlinuz, char *cmd_line)
{
FILE file;
char temp[260];
char bootsector[512];
char setup[2048];
int len;
BootDrive = DriveNum;
BootPartition = Partition;
if (!OpenDiskDrive(BootDrive, BootPartition))
{
MessageBox("Failed to open boot drive.");
return;
}
if (!OpenFile(vmlinuz, &file))
{
strcpy(temp, vmlinuz);
strcat(temp, " not found.");
MessageBox(temp);
return;
}
// Read boot sector
if (ReadFile(&file, 512, bootsector) != 512)
{
MessageBox("Disk Read Error");
return;
}
MessageBox("bootsector loaded");
// Read setup code
if (ReadFile(&file, 2048, setup) != 2048)
{
MessageBox("Disk Read Error");
return;
}
MessageBox("setup loaded");
// Read kernel code
len = GetFileSize(&file) - (2048 + 512);
//len = 0x200;
if (ReadFile(&file, len, (void*)0x100000) != len)
{
MessageBox("Disk Read Error");
return;
}
MessageBox("kernel loaded");
// Check for validity
if (*((WORD*)(bootsector + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
return;
}
if (*((DWORD*)(setup + 2)) != 0x53726448)
{
MessageBox("Invalid setup magic (\"HdrS\")");
return;
}
memcpy((void*)0x90000, bootsector, 512);
memcpy((void*)0x90200, setup, 2048);
RestoreScreen(ScreenBuffer);
showcursor();
gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToLinuxBootCode();
}

View File

@@ -1,27 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __LINUX_H
#define __LINUX_H
void JumpToLinuxBootCode(void); // Implemented in boot.S
void LoadAndBootLinux(int DriveNum, int Partition, char *vmlinuz, char *cmd_line);
#endif // defined __LINUX_H

View File

@@ -1,262 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
.text
.code16
#define ASM
#include "asmcode.h"
#include "multiboot.h"
/*
* Here we assume the kernel is loaded at 1mb
* This boots the kernel
*/
.code32
EXTERN(_boot_reactos)
call switch_to_real
.code16
/* Save cursor position */
movw $3,%ax //! Reset video mode
int $0x10
movb $10,%bl
movb $12,%ah
int $0x10
movw $0x1112,%ax // Use 8x8 font
xorb %bl,%bl
int $0x10
movw $0x1200,%ax // Use alternate print screen
movb $0x20,%bl
int $0x10
movb $1,%ah // Define cursor (scan lines 6 to 7)
movw $0x0607,%cx
int $0x10
movb $1,%ah
movw $0x600,%cx
int $0x10
movb $6,%ah // Scroll active page up
movb $0x32,%al // Clear 25 lines
movw $0,%cx // Upper left of scroll
movw $0x314F,%dx // Lower right of scroll
movb $(1*0x10+1),%bh // Use normal attribute on blanked line
int $0x10 // Video-IO
movw $0,%dx
movb $0,%dh
movb $2,%ah
movb $0,%bh
int $0x10
movw $0,%dx
movb $0,%dh
movb $2,%ah
movb $0,%bh
int $0x10
call _multi_boot
// Should never get here
cli
hlt
/*
* After you have setup the _mb_header and _mb_info structures
* then call this routine to transfer control to the kernel.
* This routine must be entered in 16-bit mode.
*/
.code16
EXTERN(_multi_boot)
cli
/*
* Setup various variables
*/
movw %ds,%bx
movzwl %bx,%eax
shll $4,%eax
addl %eax,kernel_gdtbase
/*
* Load the absolute address of the multiboot information structure
*/
movl $_mb_info,%ebx
/*
* load gdt
*/
lgdt kernel_gdtptr
/*
* Enter pmode and clear prefetch queue
*/
movl %cr0,%eax
orl $0x10001,%eax
movl %eax,%cr0
jmp next
next:
/*
* NOTE: This must be position independant (no references to
* non absolute variables)
*/
/*
* Initalize segment registers
*/
movw $KERNEL_DS,%ax
movw %ax,%ds
movw %ax,%ss
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
/*
* Initalize eflags
*/
pushl $0
popfl
/*
* Load the multiboot magic value into eax
*/
movl $0x2badb002,%eax
/*
* Jump to start of 32 bit code at 0xc0000000 + 0x1000
*/
pushl $KERNEL_CS
pushl _mb_entry_addr
lretl
//ljmpl $KERNEL_CS,$(0x0200000+0x1000)
//ljmpl $KERNEL_CS,(_mb_entry_addr)
//ljmpl $KERNEL_CS,$(KERNEL_BASE+0x1000)
.p2align 2 /* force 4-byte alignment */
kernel_gdt:
.word 0 // Zero descriptor
.word 0
.word 0
.word 0
.word 0xffff // Kernel code descriptor
.word 0x0000 //
.word 0x9a00 // base 0h limit 4gb
.word 0x00cf
.word 0xffff // Kernel data descriptor
.word 0x0000 //
.word 0x9200 // base 0h limit 4gb
.word 0x00cf
kernel_gdtptr:
.word (3*8)-1 /* Limit */
kernel_gdtbase:
.long kernel_gdt /* Base Address */
EXTERN(_mb_header)
_mb_magic:
.long 0 // unsigned long magic;
_mb_flags:
.long 0 // unsigned long flags;
_mb_checksum:
.long 0 // unsigned long checksum;
_mb_header_addr:
.long 0 // unsigned long header_addr;
_mb_load_addr:
.long 0 // unsigned long load_addr;
_mb_load_end_addr:
.long 0 // unsigned long load_end_addr;
_mb_bss_end_addr:
.long 0 // unsigned long bss_end_addr;
_mb_entry_addr:
.long 0 // unsigned long entry_addr;
//
// Boot information structure
//
EXTERN(_mb_info)
_multiboot_flags:
.long 0
_multiboot_mem_lower:
.long 0
_multiboot_mem_upper:
.long 0
_multiboot_boot_device:
.long 0
_multiboot_cmdline:
.long 0
_multiboot_mods_count:
.long 0
_multiboot_mods_addr:
.long 0
_multiboot_syms:
.rept 12
.byte 0
.endr
_multiboot_mmap_length:
.long 0
_multiboot_mmap_addr:
.long 0
_multiboot_drives_count:
.long 0
_multiboot_drives_addr:
.long 0
_multiboot_config_table:
.long 0
_multiboot_boot_loader_name:
.long 0
_multiboot_apm_table:
.long 0
EXTERN(_multiboot_modules)
.rept (64 * /*multiboot_module_size*/ 16)
.byte 0
.endr
EXTERN(_multiboot_module_strings)
.rept (64*256)
.byte 0
.endr
EXTERN(_multiboot_memory_map_descriptor_size)
.long 0
EXTERN(_multiboot_memory_map)
.rept (64 * /*sizeof(memory_map_t)*/24)
.byte 0
.endr
EXTERN(_multiboot_kernel_cmdline)
.rept 255
.byte 0
.endr

View File

@@ -1,198 +0,0 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
.text
.code16
#define ASM
#include "asmcode.h"
#include "multiboot.h"
.code32
EXTERN(_GetExtendedMemorySize)
//
// get extended memory size in KB
//
pushl %edx
pushl %ecx
pushl %ebx
call switch_to_real
.code16
movw $0xe801,%ax
int $0x15
jc .oldstylemem
cmpw $0,%ax
je .cmem
andl $0xffff,%ebx
shll $6,%ebx
andl $0xffff,%eax
add %ebx,%eax
jmp .done_mem
.cmem:
cmpw $0,%cx
je .oldstylemem
andl $0xffff,%edx
shll $6,%edx
andl $0xffff,%ecx
addl %ecx,%edx
movl %edx,%eax
jmp .done_mem
.oldstylemem:
// int 15h opt e801 don't work , try int 15h, option 88h
movb $0x88,%ah
int $0x15
cmp $0,%ax
je .cmosmem
movzwl %ax,%eax
jmp .done_mem
.cmosmem:
// int 15h opt 88h don't work , try read cmos
xorl %eax,%eax
movb $0x31,%al
outb %al,$0x70
inb $0x71,%al
andl $0xffff,%eax // clear carry
shll $8,%eax
.done_mem:
/* Save return value */
movl %eax,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
popl %ebx
popl %ecx
popl %edx
ret
.code32
EXTERN(_GetConventionalMemorySize)
//
// get conventional memory size in KB
//
pushl %edx
call switch_to_real
.code16
xorl %eax,%eax
int $0x12
/*xorl %eax,%eax
movb $0x30,%al
outb %al,$0x70
inb $0x71,%al
andl $0xffff,%eax*/ // clear carry
/* Save return value */
movl %eax,%edx
call switch_to_prot
.code32
/* Restore return value */
movl %edx,%eax
popl %edx
ret
.code32
_gbmm_mem_map_length:
.long 0
_gbmm_memory_map_addr:
.long 0
EXTERN(_GetBiosMemoryMap)
//
// Retrieve BIOS memory map if available
//
pushl %edx
pushl %ecx
pushl %ebx
pushl %edi
movl $0,_gbmm_mem_map_length
/* Get memory map address off stack */
movl 0x10(%esp),%eax
movl %eax,_gbmm_memory_map_addr
call switch_to_real
.code16
xorl %ebx,%ebx
movl _gbmm_memory_map_addr,%edi
.mmap_next:
movl $0x534D4150,%edx // 'SMAP'
movl $/*sizeof(memory_map_t)*/24,%ecx
movl 0xE820,%eax
int $0x15
jc .done_mmap
cmpl $0x534D4150,%eax // 'SMAP'
jne .done_mmap
addl $/*sizeof(memory_map_t)*/24,%edi
addl $/*sizeof(memory_map_t)*/24,_gbmm_mem_map_length
cmpl $0,%ebx
jne .mmap_next
.done_mmap:
call switch_to_prot
.code32
/* Get return value */
movl _gbmm_mem_map_length,%eax
popl %edi
popl %ebx
popl %ecx
popl %edx
ret

View File

@@ -1,281 +0,0 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "memory.h"
#include "stdlib.h"
#include "debug.h"
#define MEM_BLOCK_SIZE 256
typedef struct
{
BOOL MemBlockAllocated; // Is this block allocated or free
ULONG BlocksAllocated; // Block length, in multiples of 256 bytes
} MEMBLOCK, *PMEMBLOCK;
PVOID HeapBaseAddress = NULL;
ULONG HeapLengthInBytes = 0;
ULONG HeapMemBlockCount = 0;
PMEMBLOCK HeapMemBlockArray = NULL;
#ifdef DEBUG
ULONG AllocationCount = 0;
VOID VerifyHeap(VOID);
VOID IncrementAllocationCount(VOID);
VOID DecrementAllocationCount(VOID);
VOID MemAllocTest(VOID);
#endif DEBUG
VOID InitMemoryManager(PVOID BaseAddress, ULONG Length)
{
ULONG MemBlocks;
// Calculate how many memory blocks we have
MemBlocks = (Length / MEM_BLOCK_SIZE);
// Adjust the heap length so we can reserve
// enough storage space for the MEMBLOCK array
Length -= (MemBlocks * sizeof(MEMBLOCK));
// Initialize our tracking variables
HeapBaseAddress = BaseAddress;
HeapLengthInBytes = Length;
HeapMemBlockCount = (HeapLengthInBytes / MEM_BLOCK_SIZE);
HeapMemBlockArray = (PMEMBLOCK)(HeapBaseAddress + HeapLengthInBytes);
// Clear the memory
ZeroMemory(HeapBaseAddress, HeapLengthInBytes);
ZeroMemory(HeapMemBlockArray, (HeapMemBlockCount * sizeof(MEMBLOCK)));
#ifdef DEBUG
DebugPrint(DPRINT_MEMORY, "Memory Manager initialized. BaseAddress = 0x%x Length = 0x%x. %d blocks in heap.\n", BaseAddress, Length, HeapMemBlockCount);
//MemAllocTest();
#endif
}
PVOID AllocateMemory(ULONG NumberOfBytes)
{
ULONG BlocksNeeded;
ULONG Idx;
ULONG NumFree;
PVOID MemPointer;
#ifdef DEBUG
VerifyHeap();
#endif DEBUG
// Find out how many blocks it will take to
// satisfy this allocation
BlocksNeeded = ROUND_UP(NumberOfBytes, MEM_BLOCK_SIZE) / MEM_BLOCK_SIZE;
// Now loop through our array of blocks and
// see if we have enough space
for (Idx=0,NumFree=0; Idx<HeapMemBlockCount; Idx++)
{
// Check this block and see if it is already allocated
// If so reset our counter and continue the loop
if (HeapMemBlockArray[Idx].MemBlockAllocated)
{
NumFree = 0;
continue;
}
else
{
// It is free memory so lets increment our count
NumFree++;
}
// If we have found enough blocks to satisfy the request
// then we're done searching
if (NumFree >= BlocksNeeded)
{
break;
}
}
Idx++;
// If we don't have enough available mem
// then return NULL
if (NumFree < BlocksNeeded)
{
return NULL;
}
// Subtract the block count from Idx and we have
// the start block of the memory
Idx -= NumFree;
// Now we know which block to give them
MemPointer = HeapBaseAddress + (Idx * MEM_BLOCK_SIZE);
// Now loop through and mark all the blocks as allocated
for (NumFree=0; NumFree<BlocksNeeded; NumFree++)
{
HeapMemBlockArray[Idx + NumFree].MemBlockAllocated = TRUE;
HeapMemBlockArray[Idx + NumFree].BlocksAllocated = NumFree ? 0 : BlocksNeeded; // Mark only the first block with the count
}
#ifdef DEBUG
IncrementAllocationCount();
DebugPrint(DPRINT_MEMORY, "Allocated %d bytes (%d blocks) of memory starting at block %d. AllocationCount: %d\n", NumberOfBytes, BlocksNeeded, Idx, AllocationCount);
#endif DEBUG
// Now return the pointer
return MemPointer;
}
VOID FreeMemory(PVOID MemBlock)
{
ULONG BlockNumber;
ULONG BlockCount;
ULONG Idx;
#ifdef DEBUG
VerifyHeap();
// Make sure we didn't get a bogus pointer
if ((MemBlock < HeapBaseAddress) || (MemBlock > (HeapBaseAddress + HeapLengthInBytes)))
{
BugCheck1("Bogus memory pointer (0x%x) passed to FreeMemory()\n", MemBlock);
}
#endif DEBUG
// Find out the block number if the first
// block of memory they allocated
BlockNumber = (MemBlock - HeapBaseAddress) / MEM_BLOCK_SIZE;
BlockCount = HeapMemBlockArray[BlockNumber].BlocksAllocated;
#ifdef DEBUG
// Make sure we didn't get a bogus pointer
if ((BlockCount < 1) || (BlockCount > HeapMemBlockCount))
{
BugCheck1("Invalid block count in heap page header. HeapMemBlockArray[BlockNumber].BlocksAllocated = %d\n", HeapMemBlockArray[BlockNumber].BlocksAllocated);
}
#endif
// Loop through our array and mark all the
// blocks as free
for (Idx=BlockNumber; Idx<(BlockNumber + BlockCount); Idx++)
{
HeapMemBlockArray[Idx].MemBlockAllocated = FALSE;
HeapMemBlockArray[Idx].BlocksAllocated = 0;
}
#ifdef DEBUG
DecrementAllocationCount();
DebugPrint(DPRINT_MEMORY, "Freed %d blocks of memory starting at block %d. AllocationCount: %d\n", BlockCount, BlockNumber, AllocationCount);
#endif DEBUG
}
#ifdef DEBUG
VOID VerifyHeap(VOID)
{
ULONG Idx;
ULONG Idx2;
ULONG Count;
// Loop through the array and verify that
// everything is kosher
for (Idx=0; Idx<HeapMemBlockCount; Idx++)
{
// Check if this block is allocation
if (HeapMemBlockArray[Idx].MemBlockAllocated)
{
// This is the first block in the run so it
// had better have a length that is within range
if ((HeapMemBlockArray[Idx].BlocksAllocated < 1) || (HeapMemBlockArray[Idx].BlocksAllocated > (HeapMemBlockCount - Idx)))
{
BugCheck1("Allocation length out of range in heap table. HeapMemBlockArray[Idx].BlocksAllocated = %d\n", HeapMemBlockArray[Idx].BlocksAllocated);
}
// Now go through and verify that the rest of
// this run has the blocks marked allocated
// with a length of zero but don't check the
// first one because we already did
Count = HeapMemBlockArray[Idx].BlocksAllocated;
for (Idx2=1; Idx2<Count; Idx2++)
{
// Make sure it's allocated
if (HeapMemBlockArray[Idx + Idx2].MemBlockAllocated != TRUE)
{
BugCheck0("Heap table indicates hole in memory allocation. HeapMemBlockArray[Idx + Idx2].MemBlockAllocated != TRUE\n");
}
// Make sure the length is zero
if (HeapMemBlockArray[Idx + Idx2].BlocksAllocated != 0)
{
BugCheck0("Allocation chain has non-zero value in non-first block in heap table. HeapMemBlockArray[Idx + Idx2].BlocksAllocated != 0\n");
}
}
// Move on to the next run
Idx += Count;
}
else
{
// Nope, not allocated so make sure the length is zero
if (HeapMemBlockArray[Idx].BlocksAllocated != 0)
{
BugCheck0("Free block is start of memory allocation. HeapMemBlockArray[Idx].BlocksAllocated != 0\n");
}
}
}
}
VOID IncrementAllocationCount(VOID)
{
AllocationCount++;
}
VOID DecrementAllocationCount(VOID)
{
AllocationCount--;
}
VOID MemAllocTest(VOID)
{
PVOID MemPtr1;
PVOID MemPtr2;
PVOID MemPtr3;
PVOID MemPtr4;
PVOID MemPtr5;
MemPtr1 = AllocateMemory(4096);
printf("MemPtr1: 0x%x\n", (int)MemPtr1);
getch();
MemPtr2 = AllocateMemory(4096);
printf("MemPtr2: 0x%x\n", (int)MemPtr2);
getch();
MemPtr3 = AllocateMemory(4096);
printf("MemPtr3: 0x%x\n", (int)MemPtr3);
getch();
FreeMemory(MemPtr2);
getch();
MemPtr4 = AllocateMemory(2048);
printf("MemPtr4: 0x%x\n", (int)MemPtr4);
getch();
MemPtr5 = AllocateMemory(4096);
printf("MemPtr5: 0x%x\n", (int)MemPtr5);
getch();
}
#endif DEBUG

View File

@@ -1,38 +0,0 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __MEMORY_H
#define __MEMORY_H
#include "multiboot.h"
VOID InitMemoryManager(PVOID BaseAddress, ULONG Length);
PVOID AllocateMemory(ULONG NumberOfBytes);
VOID FreeMemory(PVOID MemBlock);
// These functions are implemented in mem.S
int GetExtendedMemorySize(void); // Returns extended memory size in KB
int GetConventionalMemorySize(void); // Returns conventional memory size in KB
int GetBiosMemoryMap(memory_map_t *mem_map); // Fills mem_map structure with BIOS memory map and returns length of memory map
#endif // defined __MEMORY_H

View File

@@ -1,192 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "stdlib.h"
#include "tui.h"
#include "menu.h"
#include "options.h"
static int nOSListBoxLeft;
static int nOSListBoxRight;
static int nOSListBoxTop;
static int nOSListBoxBottom;
static int nOSSelected = 0; // Currently selected OS (zero based)
int RunMenu(void)
{
int key;
int second;
BOOL bDone = FALSE;
if (nTimeOut > 0)
nTimeOut++; // Increment the timeout since 0 doesn't count for a second
// Initialise the menu
InitMenu();
// Update the menu
DrawMenu();
second = getsecond();
// Loop
do
{
// Check for a keypress
if (kbhit())
{
// Cancel the timeout
if (nTimeOut != -1)
{
nTimeOut = -1;
DrawMenu();
}
// Get the key
key = getch();
// Is it extended?
if (key == 0)
key = getch(); // Yes - so get the extended key
// Process the key
switch (key)
{
case KEY_UP:
if (nOSSelected)
{
nOSSelected--;
// Update the menu
DrawMenu();
}
break;
case KEY_DOWN:
if (nOSSelected < (nNumOS-1))
{
nOSSelected++;
// Update the menu
DrawMenu();
}
break;
case KEY_ENTER:
bDone = TRUE;
break;
case KEY_F8:
DoOptionsMenu();
DrawBackdrop();
DrawMenu();
break;
}
}
// Update the date & time
UpdateDateTime();
if (nTimeOut > 0)
{
if (getsecond() != second)
{
second = getsecond();
nTimeOut--;
// Update the menu
DrawMenu();
}
}
if (nTimeOut == 0)
bDone = TRUE;
}
while (!bDone);
return nOSSelected;
}
void InitMenu(void)
{
int i;
int height = 1; // Allow room for top & bottom borders
int width = 0;
for(i=0; i<nNumOS; i++)
{
height++;
if(strlen(OSList[i].name) > width)
width = strlen(OSList[i].name);
}
width += 18; // Allow room for left & right borders, plus 8 spaces on each side
// Calculate the OS list box area
nOSListBoxLeft = (nScreenWidth - width) / 2;
nOSListBoxRight = nOSListBoxLeft + width;
nOSListBoxTop = (nScreenHeight - height) / 2 + 1;
nOSListBoxBottom = nOSListBoxTop + height;
nOSSelected = 0;
}
void DrawMenu(void)
{
int i, j;
char text[260];
char temp[260];
int space, space_left, space_right;
// Update the status bar
DrawStatusText(" Use \x18\x19 to select, ENTER to boot. Press F8 for advanced options.");
DrawBox(nOSListBoxLeft, nOSListBoxTop, nOSListBoxRight, nOSListBoxBottom, D_VERT, D_HORZ, TRUE, TRUE, ATTR(cMenuFgColor, cMenuBgColor));
for(i=0; i<nNumOS; i++)
{
space = (nOSListBoxRight - nOSListBoxLeft - 2) - strlen(OSList[i].name);
space_left = (space / 2) + 1;
space_right = (space - space_left) + 1;
text[0] = '\0';
for(j=0; j<space_left; j++)
strcat(text, " ");
strcat(text, OSList[i].name);
for(j=0; j<space_right; j++)
strcat(text, " ");
if(i == nOSSelected)
{
DrawText(nOSListBoxLeft+1, nOSListBoxTop+1+i, text, ATTR(cSelectedTextColor, cSelectedTextBgColor));
}
else
{
DrawText(nOSListBoxLeft+1, nOSListBoxTop+1+i, text, ATTR(cTextColor, cMenuBgColor));
}
}
if (nTimeOut >= 0)
{
strcpy(text, "[ Time Remaining: ");
itoa(nTimeOut, temp, 10);
strcat(text, temp);
strcat(text, " ]");
DrawText(nOSListBoxRight - strlen(text) - 1, nOSListBoxBottom, text, ATTR(cMenuFgColor, cMenuBgColor));
}
}

View File

@@ -1,27 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __MENU_H
#define __MENU_H
int RunMenu(void);
void InitMenu(void);
void DrawMenu(void);
#endif // #defined __MENU_H

View File

@@ -1,230 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "asmcode.h"
#include "miscboot.h"
#include "stdlib.h"
#include "fs.h"
#include "tui.h"
#include "parseini.h"
void LoadAndBootBootSector(int nOSToBoot)
{
FILE file;
char name[260];
char value[260];
char szFileName[1024];
int i;
// Find all the message box settings and run them
for (i=1; i<=GetNumSectionItems(OSList[nOSToBoot].name); i++)
{
ReadSectionSettingByNumber(OSList[nOSToBoot].name, i, name, value);
if (stricmp(name, "MessageBox") == 0)
MessageBox(value);
if (stricmp(name, "MessageLine") == 0)
MessageLine(value);
}
if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", value))
{
MessageBox("Boot drive not specified for selected OS!");
return;
}
BootDrive = atoi(value);
BootPartition = 0;
if (ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", value))
BootPartition = atoi(value);
if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootSector", value))
{
MessageBox("Boot sector file not specified for selected OS!");
return;
}
if (!OpenDiskDrive(BootDrive, BootPartition))
{
MessageBox("Failed to open boot drive.");
return;
}
strcpy(szFileName, value);
if (!OpenFile(szFileName, &file))
{
strcat(value, " not found.");
MessageBox(value);
return;
}
// Read boot sector
if (ReadFile(&file, 512, (void*)0x7c00) != 512)
{
MessageBox("Disk Read Error");
return;
}
// Check for validity
if (*((WORD*)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
return;
}
RestoreScreen(ScreenBuffer);
showcursor();
gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
}
void LoadAndBootPartition(int nOSToBoot)
{
char name[260];
char value[260];
int head, sector, cylinder;
int offset;
int i;
// Find all the message box settings and run them
for (i=1; i<=GetNumSectionItems(OSList[nOSToBoot].name); i++)
{
ReadSectionSettingByNumber(OSList[nOSToBoot].name, i, name, value);
if (stricmp(name, "MessageBox") == 0)
MessageBox(value);
if (stricmp(name, "MessageLine") == 0)
MessageLine(value);
}
if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", value))
{
MessageBox("Boot drive not specified for selected OS!");
return;
}
BootDrive = atoi(value);
if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootPartition", value))
{
MessageBox("Boot partition not specified for selected OS!");
return;
}
BootPartition = atoi(value);
if (!biosdisk(_DISK_READ, BootDrive, 0, 0, 1, 1, SectorBuffer))
{
MessageBox("Disk Read Error");
return;
}
// Check for validity
if (*((WORD*)(SectorBuffer + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid partition table magic (0xaa55)");
return;
}
offset = 0x1BE + ((BootPartition-1) * 0x10);
// Check for valid partition
if (SectorBuffer[offset + 4] == 0)
{
MessageBox("Invalid boot partition");
return;
}
head = SectorBuffer[offset + 1];
sector = (SectorBuffer[offset + 2] & 0x3F);
cylinder = SectorBuffer[offset + 3];
if (SectorBuffer[offset + 2] & 0x80)
cylinder += 0x200;
if (SectorBuffer[offset + 2] & 0x40)
cylinder += 0x100;
// Read partition boot sector
if (!biosdisk(_DISK_READ, BootDrive, head, cylinder, sector, 1, (void*)0x7c00))
{
MessageBox("Disk Read Error");
return;
}
// Check for validity
if (*((WORD*)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
return;
}
RestoreScreen(ScreenBuffer);
showcursor();
gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
}
void LoadAndBootDrive(int nOSToBoot)
{
char name[260];
char value[260];
int i;
// Find all the message box settings and run them
for (i=1; i<=GetNumSectionItems(OSList[nOSToBoot].name); i++)
{
ReadSectionSettingByNumber(OSList[nOSToBoot].name, i, name, value);
if (stricmp(name, "MessageBox") == 0)
MessageBox(value);
if (stricmp(name, "MessageLine") == 0)
MessageLine(value);
}
if (!ReadSectionSettingByName(OSList[nOSToBoot].name, "BootDrive", value))
{
MessageBox("Boot drive not specified for selected OS!");
return;
}
BootDrive = atoi(value);
if (!biosdisk(_DISK_READ, BootDrive, 0, 0, 1, 1, (void*)0x7c00))
{
MessageBox("Disk Read Error");
return;
}
// Check for validity
if (*((WORD*)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
return;
}
RestoreScreen(ScreenBuffer);
showcursor();
gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
}

View File

@@ -1,29 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __BOOT_H
#define __BOOT_H
void JumpToBootCode(void); // Implemented in boot.S
void LoadAndBootBootSector(int nOSToBoot);
void LoadAndBootPartition(int nOSToBoot);
void LoadAndBootDrive(int nOSToBoot);
#endif // defined __BOOT_H

View File

@@ -1,157 +0,0 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "asmcode.h"
#include "stdlib.h"
#include "fs.h"
#include "multiboot.h"
#include "tui.h"
#include "parseini.h"
unsigned long next_module_load_base = 0;
BOOL MultiBootLoadKernel(FILE *KernelImage)
{
DWORD ImageHeaders[2048];
int Idx;
DWORD dwHeaderChecksum;
DWORD dwFileLoadOffset;
DWORD dwDataSize;
DWORD dwBssSize;
/*
* Load the first 8192 bytes of the kernel image
* so we can search for the multiboot header
*/
ReadFile(KernelImage, 8192, ImageHeaders);
/*
* Now find the multiboot header and copy it
*/
for (Idx=0; Idx<2048; Idx++)
{
// Did we find it?
if (ImageHeaders[Idx] == MULTIBOOT_HEADER_MAGIC)
{
// Yes, copy it and break out of this loop
memcpy(&mb_header, &ImageHeaders[Idx], sizeof(multiboot_header_t));
break;
}
}
/*
* If we reached the end of the 8192 bytes without
* finding the multiboot header then return error
*/
if (Idx == 2048)
{
MessageBox("No multiboot header found!");
return FALSE;
}
/*printf("multiboot header:\n");
printf("0x%x\n", mb_header.magic);
printf("0x%x\n", mb_header.flags);
printf("0x%x\n", mb_header.checksum);
printf("0x%x\n", mb_header.header_addr);
printf("0x%x\n", mb_header.load_addr);
printf("0x%x\n", mb_header.load_end_addr);
printf("0x%x\n", mb_header.bss_end_addr);
printf("0x%x\n", mb_header.entry_addr);
getch();*/
/*
* Calculate the checksum and make sure it matches
*/
dwHeaderChecksum = mb_header.magic;
dwHeaderChecksum += mb_header.flags;
dwHeaderChecksum += mb_header.checksum;
if (dwHeaderChecksum != 0)
{
MessageBox("Multiboot header checksum invalid!");
return FALSE;
}
/*
* Get the file offset, this should be 0, and move the file pointer
*/
dwFileLoadOffset = (Idx * sizeof(DWORD)) - (mb_header.header_addr - mb_header.load_addr);
fseek(KernelImage, dwFileLoadOffset);
/*
* Load the file image
*/
dwDataSize = (mb_header.load_end_addr - mb_header.load_addr);
ReadFile(KernelImage, dwDataSize, (void*)mb_header.load_addr);
/*
* Initialize bss area
*/
dwBssSize = (mb_header.bss_end_addr - mb_header.load_end_addr);
memset((void*)mb_header.load_end_addr, 0, dwBssSize);
next_module_load_base = ROUND_UP(mb_header.bss_end_addr, /*PAGE_SIZE*/4096);
return TRUE;
}
BOOL MultiBootLoadModule(FILE *ModuleImage, char *ModuleName)
{
DWORD dwModuleSize;
module_t* pModule;
char* ModuleNameString;
/*
* Get current module data structure and module name string array
*/
pModule = &multiboot_modules[mb_info.mods_count];
ModuleNameString = multiboot_module_strings[mb_info.mods_count];
dwModuleSize = GetFileSize(ModuleImage);
pModule->mod_start = next_module_load_base;
pModule->mod_end = next_module_load_base + dwModuleSize;
strcpy(ModuleNameString, ModuleName);
pModule->string = (unsigned long)ModuleNameString;
/*
* Load the file image
*/
ReadFile(ModuleImage, dwModuleSize, (void*)next_module_load_base);
next_module_load_base = ROUND_UP(pModule->mod_end, /*PAGE_SIZE*/4096);
mb_info.mods_count++;
return TRUE;
}
int GetBootPartition(char *OperatingSystemName)
{
int BootPartitionNumber = -1;
char value[1024];
if (ReadSectionSettingByName(OperatingSystemName, "BootPartition", value))
{
BootPartitionNumber = atoi(value);
}
return BootPartitionNumber;
}

View File

@@ -1,155 +0,0 @@
/* multiboot.h - the header for Multiboot */
/* Copyright (C) 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef __MULTIBOOT_H
#define __MULTIBOOT_H
/* Macros. */
/* The magic number for the Multiboot header. */
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
/* The flags for the Multiboot header. */
#define MULTIBOOT_HEADER_FLAGS 0x00010003
/* The magic number passed by a Multiboot-compliant boot loader. */
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/* The size of our stack (16KB). */
#define STACK_SIZE 0x4000
/* C symbol format. HAVE_ASM_USCORE is defined by configure. */
#ifdef HAVE_ASM_USCORE
# define EXT_C(sym) _ ## sym
#else
# define EXT_C(sym) sym
#endif
#define MB_INFO_FLAG_MEM_SIZE 0x00000001
#define MB_INFO_FLAG_BOOT_DEVICE 0x00000002
#define MB_INFO_FLAG_COMMAND_LINE 0x00000004
#define MB_INFO_FLAG_MODULES 0x00000008
#define MB_INFO_FLAG_AOUT_SYMS 0x00000010
#define MB_INFO_FLAG_ELF_SYMS 0x00000020
#define MB_INFO_FLAG_MEMORY_MAP 0x00000040
#define MB_INFO_FLAG_DRIVES 0x00000080
#define MB_INFO_FLAG_CONFIG_TABLE 0x00000100
#define MB_INFO_FLAG_BOOT_LOADER_NAME 0x00000200
#define MB_INFO_FLAG_APM_TABLE 0x00000400
#define MB_INFO_FLAG_GRAPHICS_TABLE 0x00000800
#ifndef ASM
/* Do not include here in boot.S. */
/* Types. */
/* The Multiboot header. */
typedef struct multiboot_header
{
unsigned long magic;
unsigned long flags;
unsigned long checksum;
unsigned long header_addr;
unsigned long load_addr;
unsigned long load_end_addr;
unsigned long bss_end_addr;
unsigned long entry_addr;
} multiboot_header_t;
/* The symbol table for a.out. */
typedef struct aout_symbol_table
{
unsigned long tabsize;
unsigned long strsize;
unsigned long addr;
unsigned long reserved;
} aout_symbol_table_t;
/* The section header table for ELF. */
typedef struct elf_section_header_table
{
unsigned long num;
unsigned long size;
unsigned long addr;
unsigned long shndx;
} elf_section_header_table_t;
/* The Multiboot information. */
typedef struct multiboot_info
{
unsigned long flags;
unsigned long mem_lower;
unsigned long mem_upper;
unsigned long boot_device;
unsigned long cmdline;
unsigned long mods_count;
unsigned long mods_addr;
union
{
aout_symbol_table_t aout_sym;
elf_section_header_table_t elf_sec;
} u;
unsigned long mmap_length;
unsigned long mmap_addr;
} multiboot_info_t;
/* The module structure. */
typedef struct module
{
unsigned long mod_start;
unsigned long mod_end;
unsigned long string;
unsigned long reserved;
} module_t;
/* The memory map. Be careful that the offset 0 is base_addr_low
but no size. */
typedef struct memory_map
{
//unsigned long size;
unsigned long base_addr_low;
unsigned long base_addr_high;
unsigned long length_low;
unsigned long length_high;
unsigned long type;
unsigned long reserved;
} memory_map_t;
multiboot_header_t mb_header; // Multiboot header structure defined in kernel image file
multiboot_info_t mb_info; // Multiboot info structure passed to kernel
char multiboot_kernel_cmdline[255]; // Command line passed to kernel
module_t multiboot_modules[64]; // Array to hold boot module info loaded for the kernel
char multiboot_module_strings[64][256]; // Array to hold module names
unsigned long multiboot_memory_map_descriptor_size;
memory_map_t multiboot_memory_map; // Memory map
void boot_reactos(void);
#include "fs.h" // Included FILE structure definition
BOOL MultiBootLoadKernel(FILE *KernelImage);
BOOL MultiBootLoadModule(FILE *ModuleImage, char *ModuleName);
int GetBootPartition(char *OperatingSystemName);
#endif /* ! ASM */
#endif // defined __MULTIBOOT_H

View File

@@ -1,395 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "stdlib.h"
#include "tui.h"
#include "options.h"
#include "miscboot.h"
void DoOptionsMenu(void)
{
int OptionsMenuItemCount = 1; // Count is 1 because we don't show the "Set ReactOS Boot Flags" menu item yet
char OptionsMenuItems[2][80] = { "Boot Wizard", "Set ReactOS Boot Flags" /* i.e. Safe Mode, Last Known Good Configuration */ };
int OptionsMenuItemSelected = 0;
while (OptionsMenuItemSelected != -1)
{
OptionsMenuItemSelected = RunOptionsMenu(OptionsMenuItems, OptionsMenuItemCount, OptionsMenuItemSelected, "[Advanced Options]");
switch (OptionsMenuItemSelected)
{
case 0:
DoDiskOptionsMenu();
break;
}
}
}
void DoDiskOptionsMenu(void)
{
char DiskMenuItems[25][80];
int DiskMenuItemCount = 0;
int FloppyDiskMenuItemCount = 0;
int HardDiskMenuItemCount = 0;
int DiskMenuItemSelected = 0;
char temp[255];
int i;
FloppyDiskMenuItemCount = (int)*((char *)((0x40 * 16) + 0x10)); // Get number of floppy disks from bios data area 40:10
if (FloppyDiskMenuItemCount & 1)
FloppyDiskMenuItemCount = (FloppyDiskMenuItemCount >> 6) + 1;
else
FloppyDiskMenuItemCount = 0;
HardDiskMenuItemCount = (int)*((char *)((0x40 * 16) + 0x75)); // Get number of hard disks from bios data area 40:75
DiskMenuItemCount = FloppyDiskMenuItemCount + HardDiskMenuItemCount;
for (i=0; i<FloppyDiskMenuItemCount; i++)
{
strcpy(DiskMenuItems[i], "Floppy Disk ");
itoa(i + 1, temp, 10);
strcat(DiskMenuItems[i], temp);
}
for (i=0; i<HardDiskMenuItemCount; i++)
{
strcpy(DiskMenuItems[i + FloppyDiskMenuItemCount], "Hard Disk ");
itoa(i + 1, temp, 10);
strcat(DiskMenuItems[i + FloppyDiskMenuItemCount], temp);
strcat(DiskMenuItems[i + FloppyDiskMenuItemCount], " (");
itoa((get_heads(i+0x80) * get_cylinders(i+0x80) * get_sectors(i+0x80)) / 2048, temp, 10);
strcat(DiskMenuItems[i + FloppyDiskMenuItemCount], temp);
strcat(DiskMenuItems[i + FloppyDiskMenuItemCount], " MB)");
}
DiskMenuItemSelected = 0;
while (DiskMenuItemSelected != -1)
{
DiskMenuItemSelected = RunOptionsMenu(DiskMenuItems, DiskMenuItemCount, DiskMenuItemSelected, "[Boot Wizard]");
if (DiskMenuItemSelected != -1)
{
if (DiskMenuItemSelected < FloppyDiskMenuItemCount)
DoBootOptionsMenu(DiskMenuItemSelected, DiskMenuItems[DiskMenuItemSelected]);
else
DoBootOptionsMenu((DiskMenuItemSelected - FloppyDiskMenuItemCount) + 0x80, DiskMenuItems[DiskMenuItemSelected]);
}
}
}
void DoBootOptionsMenu(int BootDriveNum, char *BootDriveText)
{
int BootOptionsMenuItemCount = 2;
char BootOptionsMenuItems[2][80] = { "Boot To ", "Pick A Boot Partition" };
int BootOptionsMenuItemSelected = 0;
strcat(BootOptionsMenuItems[0], BootDriveText);
while (BootOptionsMenuItemSelected != -1)
{
BootOptionsMenuItemSelected = RunOptionsMenu(BootOptionsMenuItems, BootOptionsMenuItemCount, BootOptionsMenuItemSelected, "[Boot Options]");
switch (BootOptionsMenuItemSelected)
{
case 0:
BootDrive = BootDriveNum;
if (!biosdisk(_DISK_READ, BootDrive, 0, 0, 1, 1, (void*)0x7c00))
{
MessageBox("Disk Read Error");
return;
}
// Check for validity
if (*((WORD*)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
return;
}
RestoreScreen(ScreenBuffer);
showcursor();
gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
break;
case 1:
if (BootDriveNum < 0x80)
{
MessageBox("This option is not available for a floppy disk.");
continue;
}
else
DoBootPartitionOptionsMenu(BootDriveNum);
break;
}
}
}
void DoBootPartitionOptionsMenu(int BootDriveNum)
{
struct
{
int partition_num;
int partition_type;
int head, sector, cylinder;
} BootPartitions[8];
int BootOptionsMenuItemCount = 0;
char BootOptionsMenuItems[8][80];
int BootOptionsMenuItemSelected = 0;
int head, sector, cylinder;
int offset;
int i;
char temp[25];
BootDrive = BootDriveNum;
if (!biosdisk(_DISK_READ, BootDrive, 0, 0, 1, 1, SectorBuffer))
{
MessageBox("Disk Read Error");
return;
}
// Check for validity
if (*((WORD*)(SectorBuffer + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid partition table magic (0xaa55)");
return;
}
offset = 0x1BE;
for (i=0; i<4; i++)
{
// Check for valid partition
if (SectorBuffer[offset + 4] != 0)
{
BootPartitions[BootOptionsMenuItemCount].partition_num = i;
BootPartitions[BootOptionsMenuItemCount].partition_type = SectorBuffer[offset + 4];
BootPartitions[BootOptionsMenuItemCount].head = SectorBuffer[offset + 1];
BootPartitions[BootOptionsMenuItemCount].sector = (SectorBuffer[offset + 2] & 0x3F);
BootPartitions[BootOptionsMenuItemCount].cylinder = SectorBuffer[offset + 3];
if (SectorBuffer[offset + 2] & 0x80)
BootPartitions[BootOptionsMenuItemCount].cylinder += 0x200;
if (SectorBuffer[offset + 2] & 0x40)
BootPartitions[BootOptionsMenuItemCount].cylinder += 0x100;
strcpy(BootOptionsMenuItems[BootOptionsMenuItemCount], "Boot To Partition ");
itoa(i+1, temp, 10);
strcat(BootOptionsMenuItems[BootOptionsMenuItemCount], temp);
strcat(BootOptionsMenuItems[BootOptionsMenuItemCount], " (Type: 0x");
itoa(BootPartitions[BootOptionsMenuItemCount].partition_type, temp, 16);
if (strlen(temp) < 2)
strcat(BootOptionsMenuItems[BootOptionsMenuItemCount], "0");
strcat(BootOptionsMenuItems[BootOptionsMenuItemCount], temp);
strcat(BootOptionsMenuItems[BootOptionsMenuItemCount], ")");
BootOptionsMenuItemCount++;
}
offset += 0x10;
}
while (BootOptionsMenuItemSelected != -1)
{
BootOptionsMenuItemSelected = RunOptionsMenu(BootOptionsMenuItems, BootOptionsMenuItemCount, BootOptionsMenuItemSelected, "[Boot Partition Options]");
if (BootOptionsMenuItemSelected != -1)
{
head = BootPartitions[BootOptionsMenuItemCount].head;
sector = BootPartitions[BootOptionsMenuItemCount].sector;
cylinder = BootPartitions[BootOptionsMenuItemCount].cylinder;
// Read partition boot sector
if (!biosdisk(_DISK_READ, BootDrive, head, cylinder, sector, 1, (void*)0x7c00))
{
MessageBox("Disk Read Error");
return;
}
// Check for validity
if (*((WORD*)(0x7c00 + 0x1fe)) != 0xaa55)
{
MessageBox("Invalid boot sector magic (0xaa55)");
return;
}
RestoreScreen(ScreenBuffer);
showcursor();
gotoxy(CursorXPos, CursorYPos);
stop_floppy();
JumpToBootCode();
}
}
}
int RunOptionsMenu(char OptionsMenuItems[][80], int OptionsMenuItemCount, int nOptionSelected, char *OptionsMenuTitle)
{
int key;
int second;
BOOL bDone = FALSE;
int nOptionsMenuBoxLeft;
int nOptionsMenuBoxRight;
int nOptionsMenuBoxTop;
int nOptionsMenuBoxBottom;
// Initialise the menu
InitOptionsMenu(&nOptionsMenuBoxLeft, &nOptionsMenuBoxTop, &nOptionsMenuBoxRight, &nOptionsMenuBoxBottom, OptionsMenuItemCount);
DrawBackdrop();
// Update the menu
DrawOptionsMenu(OptionsMenuItems, OptionsMenuItemCount, nOptionSelected, OptionsMenuTitle, nOptionsMenuBoxLeft, nOptionsMenuBoxTop, nOptionsMenuBoxRight, nOptionsMenuBoxBottom);
second = getsecond();
// Loop
do
{
// Check for a keypress
if (kbhit())
{
// Cancel the timeout
if (nTimeOut != -1)
{
nTimeOut = -1;
DrawOptionsMenu(OptionsMenuItems, OptionsMenuItemCount, nOptionSelected, OptionsMenuTitle, nOptionsMenuBoxLeft, nOptionsMenuBoxTop, nOptionsMenuBoxRight, nOptionsMenuBoxBottom);
}
// Get the key
key = getch();
// Is it extended?
if (key == 0)
key = getch(); // Yes - so get the extended key
// Process the key
switch (key)
{
case KEY_UP:
if (nOptionSelected)
{
nOptionSelected--;
// Update the menu
DrawOptionsMenu(OptionsMenuItems, OptionsMenuItemCount, nOptionSelected, OptionsMenuTitle, nOptionsMenuBoxLeft, nOptionsMenuBoxTop, nOptionsMenuBoxRight, nOptionsMenuBoxBottom);
}
break;
case KEY_DOWN:
if (nOptionSelected < (OptionsMenuItemCount - 1))
{
nOptionSelected++;
// Update the menu
DrawOptionsMenu(OptionsMenuItems, OptionsMenuItemCount, nOptionSelected, OptionsMenuTitle, nOptionsMenuBoxLeft, nOptionsMenuBoxTop, nOptionsMenuBoxRight, nOptionsMenuBoxBottom);
}
break;
case KEY_ENTER:
//MessageBox("The Advanced Options are still being implemented.");
bDone = TRUE;
break;
case KEY_ESC:
nOptionSelected = -1;
bDone = TRUE;
break;
}
}
// Update the date & time
UpdateDateTime();
if (nTimeOut > 0)
{
if (getsecond() != second)
{
second = getsecond();
nTimeOut--;
// Update the menu
DrawOptionsMenu(OptionsMenuItems, OptionsMenuItemCount, nOptionSelected, OptionsMenuTitle, nOptionsMenuBoxLeft, nOptionsMenuBoxTop, nOptionsMenuBoxRight, nOptionsMenuBoxBottom);
}
}
if (nTimeOut == 0)
bDone = TRUE;
}
while (!bDone);
return nOptionSelected;
}
void InitOptionsMenu(int *nOptionsMenuBoxLeft, int *nOptionsMenuBoxTop, int *nOptionsMenuBoxRight, int *nOptionsMenuBoxBottom, int OptionsMenuItemCount)
{
int height = OptionsMenuItemCount;
int width = 20;
height += 1; // Allow room for top & bottom borders
width += 18; // Allow room for left & right borders, plus 8 spaces on each side
// Calculate the OS list box area
*nOptionsMenuBoxLeft = (nScreenWidth - width) / 2;
*nOptionsMenuBoxRight = *nOptionsMenuBoxLeft + width;
*nOptionsMenuBoxTop = (nScreenHeight - height) / 2 + 1;
*nOptionsMenuBoxBottom = *nOptionsMenuBoxTop + height;
}
void DrawOptionsMenu(char OptionsMenuItems[][80], int OptionsMenuItemCount, int nOptionSelected, char *OptionsMenuTitle, int nOptionsMenuBoxLeft, int nOptionsMenuBoxTop, int nOptionsMenuBoxRight, int nOptionsMenuBoxBottom)
{
int i, j;
char text[260];
int space, space_left, space_right;
// Update the status bar
DrawStatusText(" Use \x18\x19 to select, then press ENTER. Press ESC to go back.");
DrawBox(nOptionsMenuBoxLeft, nOptionsMenuBoxTop, nOptionsMenuBoxRight, nOptionsMenuBoxBottom, D_VERT, D_HORZ, TRUE, TRUE, ATTR(cMenuFgColor, cMenuBgColor));
DrawText(nOptionsMenuBoxLeft + (((nOptionsMenuBoxRight - nOptionsMenuBoxLeft) - strlen(OptionsMenuTitle)) / 2) + 1, nOptionsMenuBoxTop, OptionsMenuTitle, ATTR(cMenuFgColor, cMenuBgColor));
for(i=0; i<OptionsMenuItemCount; i++)
{
space = (nOptionsMenuBoxRight - nOptionsMenuBoxLeft - 2) - strlen(OptionsMenuItems[i]);
space_left = (space / 2) + 1;
space_right = (space - space_left) + 1;
text[0] = '\0';
for(j=0; j<space_left; j++)
strcat(text, " ");
strcat(text, OptionsMenuItems[i]);
for(j=0; j<space_right; j++)
strcat(text, " ");
if(i == nOptionSelected)
{
DrawText(nOptionsMenuBoxLeft+1, nOptionsMenuBoxTop+1+i, text, ATTR(cSelectedTextColor, cSelectedTextBgColor));
}
else
{
DrawText(nOptionsMenuBoxLeft+1, nOptionsMenuBoxTop+1+i, text, ATTR(cTextColor, cMenuBgColor));
}
}
}

View File

@@ -1,31 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __OPTIONS_H
#define __OPTIONS_H
void DoOptionsMenu(void);
void DoDiskOptionsMenu(void);
void DoBootOptionsMenu(int BootDriveNum, char *BootDriveText);
void DoBootPartitionOptionsMenu(int BootDriveNum);
int RunOptionsMenu(char OptionsMenuItems[][80], int OptionsMenuItemCount, int nOptionSelected, char *OptionsMenuTitle);
void InitOptionsMenu(int *nOptionsMenuBoxLeft, int *nOptionsMenuBoxTop, int *nOptionsMenuBoxRight, int *nOptionsMenuBoxBottom, int OptionsMenuItemCount);
void DrawOptionsMenu(char OptionsMenuItems[][80], int OptionsMenuItemCount, int nOptionSelected, char *OptionsMenuTitle, int nOptionsMenuBoxLeft, int nOptionsMenuBoxTop, int nOptionsMenuBoxRight, int nOptionsMenuBoxBottom);
#endif // #defined __OPTIONS_H

View File

@@ -1,522 +0,0 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "parseini.h"
#include "tui.h"
#include "fs.h"
#include "stdlib.h"
#include "memory.h"
PUCHAR FreeLoaderIniFileData = NULL;
ULONG FreeLoaderIniFileSize = 0;
BOOL ParseIniFile(void)
{
int i;
char name[1024];
char value[1024];
FILE Freeldr_Ini; // File handle for freeldr.ini
// Open the boot drive for file access
if (!OpenDiskDrive(BootDrive, 0))
{
printf("Error opening boot drive for file access.\n");
return FALSE;
}
// Try to open freeldr.ini or fail
if (!OpenFile("freeldr.ini", &Freeldr_Ini))
{
printf("FREELDR.INI not found.\nYou need to re-install FreeLoader.\n");
return FALSE;
}
// Get the file size & allocate enough memory for it
FreeLoaderIniFileSize = GetFileSize(&Freeldr_Ini);
FreeLoaderIniFileData = AllocateMemory(FreeLoaderIniFileSize);
// If we are out of memory then return FALSE
if (FreeLoaderIniFileData == NULL)
{
printf("Out of memory while loading FREELDR.INI.\n");
return FALSE;
}
// Read freeldr.ini off the disk
ReadFile(&Freeldr_Ini, FreeLoaderIniFileSize, FreeLoaderIniFileData);
// Make sure the [FREELOADER] section exists
if (!GetNumSectionItems("FREELOADER"))
{
printf("Section [FREELOADER] not found in FREELDR.INI.\nYou need to re-install FreeLoader.\n");
return FALSE;
}
// Validate the settings in the [FREELOADER] section
for (i=1; i<=GetNumSectionItems("FREELOADER"); i++)
{
ReadSectionSettingByNumber("FREELOADER", i, name, value);
if (!IsValidSetting(name, value))
{
printf("Invalid setting in freeldr.ini.\nName: \"%s\", Value: \"%s\"\n", name, value);
printf("Press any key to continue.\n");
getch();
}
else
SetSetting(name, value);
}
return TRUE;
}
ULONG GetNextLineOfFileData(PUCHAR Buffer, ULONG BufferSize, ULONG CurrentOffset)
{
ULONG Idx;
// Loop through grabbing chars until we hit the end of the
// file or we encounter a new line char
for (Idx=0; (CurrentOffset < FreeLoaderIniFileSize); CurrentOffset++)
{
// If we haven't exceeded our buffer size yet
// then store another char
if (Idx < (BufferSize - 1))
{
Buffer[Idx++] = FreeLoaderIniFileData[CurrentOffset];
}
// Check for new line char
if (FreeLoaderIniFileData[CurrentOffset] == '\n')
{
CurrentOffset++;
break;
}
}
// Terminate the string
Buffer[Idx] = '\0';
// Get rid of newline & linefeed characters (if any)
if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r'))
Buffer[strlen(Buffer)-1] = '\0';
if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r'))
Buffer[strlen(Buffer)-1] = '\0';
// Send back new offset
return CurrentOffset;
}
ULONG GetOffsetOfFirstLineOfSection(PUCHAR SectionName)
{
char str[1024];
char real_section[1024];
ULONG freeldr_ini_offset;
BOOL SectionFound = FALSE;
// Get the real section name
strcpy(real_section, "[");
strcat(real_section, SectionName);
strcat(real_section, "]");
// Get to the beginning of the file
freeldr_ini_offset = 0;
// Find the section
while (freeldr_ini_offset < FreeLoaderIniFileSize)
{
// Read a line
freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
// Skip comments
if (str[0] == '#')
continue;
// Skip blank lines
if (!strlen(str))
continue;
// If it isn't a section header then continue on
if (str[0] != '[')
continue;
// Check and see if we found it
if (stricmp(str, real_section) == 0)
{
SectionFound = TRUE;
break;
}
}
// If we didn't find the section then we're outta here
if (!SectionFound)
return 0;
return freeldr_ini_offset;
}
ULONG GetNumSectionItems(PUCHAR SectionName)
{
UCHAR str[1024];
ULONG num_items = 0;
ULONG freeldr_ini_offset;
// Get to the beginning of the section
freeldr_ini_offset = GetOffsetOfFirstLineOfSection(SectionName);
// If the section wasn't found then exit
if (freeldr_ini_offset == 0)
{
return 0;
}
// Now count how many settings are in this section
while (freeldr_ini_offset < FreeLoaderIniFileSize)
{
// Read a line
freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
// Skip comments
if (str[0] == '#')
continue;
// Skip blank lines
if (!strlen(str))
continue;
// If we hit a new section then we're done
if (str[0] == '[')
break;
num_items++;
}
return num_items;
}
BOOL ReadSectionSettingByNumber(PUCHAR SectionName, ULONG SettingNumber, PUCHAR SettingName, PUCHAR SettingValue)
{
UCHAR str[1024];
ULONG num_items = 0;
ULONG i;
ULONG freeldr_ini_offset;
// Get to the beginning of the section
freeldr_ini_offset = GetOffsetOfFirstLineOfSection(SectionName);
// If the section wasn't found then exit
if (freeldr_ini_offset == 0)
{
return 0;
}
// Now find the setting we are looking for
while (freeldr_ini_offset < FreeLoaderIniFileSize)
{
// Read a line
freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
// Skip comments
if (str[0] == '#')
continue;
// Skip blank lines
if (!strlen(str))
continue;
// If we hit a new section then we're done
if (str[0] == '[')
break;
// Increment setting number
num_items++;
// Check and see if we found the setting
if (num_items == SettingNumber)
{
for (i=0; i<strlen(str); i++)
{
// Check and see if this character is the separator
if (str[i] == '=')
{
SettingName[i] = '\0';
strcpy(SettingValue, str+i+1);
return TRUE;
}
else
SettingName[i] = str[i];
}
}
}
return FALSE;
}
BOOL ReadSectionSettingByName(PUCHAR SectionName, PUCHAR SettingName, PUCHAR SettingValue)
{
UCHAR str[1024];
UCHAR temp[1024];
ULONG i;
ULONG freeldr_ini_offset;
// Get to the beginning of the section
freeldr_ini_offset = GetOffsetOfFirstLineOfSection(SectionName);
// If the section wasn't found then exit
if (freeldr_ini_offset == 0)
{
return 0;
}
// Now find the setting we are looking for
while (freeldr_ini_offset < FreeLoaderIniFileSize)
{
// Read a line
freeldr_ini_offset = GetNextLineOfFileData(str, 1024, freeldr_ini_offset);
// Skip comments
if (str[0] == '#')
continue;
// Skip blank lines
if (!strlen(str))
continue;
// If we hit a new section then we're done
if (str[0] == '[')
break;
// Extract the setting name
for (i=0; i<strlen(str); i++)
{
if (str[i] != '=')
temp[i] = str[i];
else
{
temp[i] = '\0';
break;
}
}
// Check and see if we found the setting
if (stricmp(temp, SettingName) == 0)
{
for (i=0; i<strlen(str); i++)
{
// Check and see if this character is the separator
if (str[i] == '=')
{
strcpy(SettingValue, str+i+1);
return TRUE;
}
}
}
}
return FALSE;
}
BOOL IsValidSetting(char *setting, char *value)
{
if(stricmp(setting, "MessageBox") == 0)
return TRUE;
else if(stricmp(setting, "MessageLine") == 0)
return TRUE;
else if(stricmp(setting, "TitleText") == 0)
return TRUE;
else if(stricmp(setting, "StatusBarColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "StatusBarTextColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "BackdropTextColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "BackdropColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "BackdropFillStyle") == 0)
{
if(IsValidFillStyle(value))
return TRUE;
}
else if(stricmp(setting, "TitleBoxTextColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "TitleBoxColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "MessageBoxTextColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "MessageBoxColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "MenuTextColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "MenuColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "TextColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "SelectedTextColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "SelectedColor") == 0)
{
if(IsValidColor(value))
return TRUE;
}
else if(stricmp(setting, "OS") == 0)
return TRUE;
else if(stricmp(setting, "TimeOut") == 0)
return TRUE;
/*else if(stricmp(setting, "") == 0)
return TRUE;
else if(stricmp(setting, "") == 0)
return TRUE;
else if(stricmp(setting, "") == 0)
return TRUE;
else if(stricmp(setting, "") == 0)
return TRUE;
else if(stricmp(setting, "") == 0)
return TRUE;
else if(stricmp(setting, "") == 0)
return TRUE;
else if(stricmp(setting, "") == 0)
return TRUE;*/
return FALSE;
}
void SetSetting(char *setting, char *value)
{
char v[260];
if(stricmp(setting, "TitleText") == 0)
strcpy(szTitleBoxTitleText, value);
else if(stricmp(setting, "StatusBarColor") == 0)
cStatusBarBgColor = TextToColor(value);
else if(stricmp(setting, "StatusBarTextColor") == 0)
cStatusBarFgColor = TextToColor(value);
else if(stricmp(setting, "BackdropTextColor") == 0)
cBackdropFgColor = TextToColor(value);
else if(stricmp(setting, "BackdropColor") == 0)
cBackdropBgColor = TextToColor(value);
else if(stricmp(setting, "BackdropFillStyle") == 0)
cBackdropFillStyle = TextToFillStyle(value);
else if(stricmp(setting, "TitleBoxTextColor") == 0)
cTitleBoxFgColor = TextToColor(value);
else if(stricmp(setting, "TitleBoxColor") == 0)
cTitleBoxBgColor = TextToColor(value);
else if(stricmp(setting, "MessageBoxTextColor") == 0)
cMessageBoxFgColor = TextToColor(value);
else if(stricmp(setting, "MessageBoxColor") == 0)
cMessageBoxBgColor = TextToColor(value);
else if(stricmp(setting, "MenuTextColor") == 0)
cMenuFgColor = TextToColor(value);
else if(stricmp(setting, "MenuColor") == 0)
cMenuBgColor = TextToColor(value);
else if(stricmp(setting, "TextColor") == 0)
cTextColor = TextToColor(value);
else if(stricmp(setting, "SelectedTextColor") == 0)
cSelectedTextColor = TextToColor(value);
else if(stricmp(setting, "SelectedColor") == 0)
cSelectedTextBgColor = TextToColor(value);
else if(stricmp(setting, "OS") == 0)
{
if(nNumOS >= 16)
{
printf("Error: you can only boot to at most 16 different operating systems.\n");
printf("Press any key to continue\n");
getch();
return;
}
if(!GetNumSectionItems(value))
{
printf("Error: OS \"%s\" listed.\n", value);
printf("It does not have it's own [section], or it is empty.\n");
printf("Press any key to continue\n");
getch();
return;
}
strcpy(OSList[nNumOS].name, value);
if (!ReadSectionSettingByName(value, "BootType", v))
{
printf("Unknown BootType for OS \"%s\"\n", value);
printf("Press any key to continue\n");
getch();
return;
}
if (stricmp(v, "ReactOS") == 0)
OSList[nNumOS].nOSType = OSTYPE_REACTOS;
else if (stricmp(v, "Linux") == 0)
OSList[nNumOS].nOSType = OSTYPE_LINUX;
else if (stricmp(v, "BootSector") == 0)
OSList[nNumOS].nOSType = OSTYPE_BOOTSECTOR;
else if (stricmp(v, "Partition") == 0)
OSList[nNumOS].nOSType = OSTYPE_PARTITION;
else if (stricmp(v, "Drive") == 0)
OSList[nNumOS].nOSType = OSTYPE_DRIVE;
else
{
printf("Unknown BootType for OS \"%s\"\n", value);
printf("Press any key to continue\n");
getch();
return;
}
nNumOS++;
}
else if(stricmp(setting, "TimeOut") == 0)
nTimeOut = atoi(value);
}

View File

@@ -1,33 +0,0 @@
/*
* FreeLoader
* Copyright (C) 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __PARSEINI_H
#define __PARSEINI_H
BOOL ParseIniFile(void);
ULONG GetNextLineOfFileData(PUCHAR Buffer, ULONG BufferSize, ULONG CurrentOffset); // Gets the next line of text (up to BufferSize) after CurrentOffset and returns the offset of the next line
ULONG GetOffsetOfFirstLineOfSection(PUCHAR SectionName); // Returns the offset of the first line in the section or zero if the section wasn't found
ULONG GetNumSectionItems(PUCHAR SectionName); // returns the number of items in a particular section (i.e. [FREELOADER])
BOOL ReadSectionSettingByNumber(PUCHAR SectionName, ULONG SettingNumber, PUCHAR SettingName, PUCHAR SettingValue); // Reads the num'th value from section
BOOL ReadSectionSettingByName(PUCHAR SectionName, PUCHAR SettingName, PUCHAR SettingValue); // Reads the value named name from section
BOOL IsValidSetting(char *setting, char *value);
void SetSetting(char *setting, char *value);
#endif // defined __PARSEINI_H

View File

@@ -1,266 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "asmcode.h"
#include "reactos.h"
#include "stdlib.h"
#include "fs.h"
#include "tui.h"
#include "multiboot.h"
#include "arcname.h"
#include "memory.h"
#include "parseini.h"
BOOL LoadReactOSKernel(PUCHAR OperatingSystemName);
BOOL LoadReactOSDrivers(PUCHAR OperatingSystemName);
void LoadAndBootReactOS(PUCHAR OperatingSystemName)
{
FILE file;
char name[1024];
char value[1024];
char szFileName[1024];
char szBootPath[256];
int i;
int nNumDriverFiles=0;
int nNumFilesLoaded=0;
char MsgBuffer[256];
/*
* Setup multiboot information structure
*/
mb_info.flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
mb_info.mem_lower = GetConventionalMemorySize();
mb_info.mem_upper = GetExtendedMemorySize();
mb_info.boot_device = 0xffffffff;
mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
mb_info.mods_count = 0;
mb_info.mods_addr = (unsigned long)multiboot_modules;
mb_info.mmap_length = GetBiosMemoryMap(&multiboot_memory_map);
if (mb_info.mmap_length)
{
mb_info.mmap_addr = (unsigned long)&multiboot_memory_map;
mb_info.flags |= MB_INFO_FLAG_MEMORY_MAP;
//printf("memory map length: %d\n", mb_info.mmap_length);
//printf("dumping memory map:\n");
//for (i=0; i<(mb_info.mmap_length / 4); i++)
//{
// printf("0x%x\n", ((unsigned long *)&multiboot_memory_map)[i]);
//}
//getch();
}
//printf("low_mem = %d\n", mb_info.mem_lower);
//printf("high_mem = %d\n", mb_info.mem_upper);
/*
* Make sure the system path is set in the .ini file
*/
if (!ReadSectionSettingByName(OperatingSystemName, "SystemPath", value))
{
MessageBox("System path not specified for selected operating system.");
return;
}
/*
* Verify system path
*/
if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
{
sprintf(MsgBuffer,"Invalid system path: '%s'", value);
MessageBox(MsgBuffer);
return;
}
/* set boot drive and partition */
((char *)(&mb_info.boot_device))[0] = (char)BootDrive;
((char *)(&mb_info.boot_device))[1] = (char)BootPartition;
/* copy ARC path into kernel command line */
strcpy(multiboot_kernel_cmdline, value);
/*
* Read the optional kernel parameters (if any)
*/
if (ReadSectionSettingByName(OperatingSystemName, "Options", value))
{
strcat(multiboot_kernel_cmdline, " ");
strcat(multiboot_kernel_cmdline, value);
}
/* append a backslash */
if ((strlen(szBootPath)==0) ||
szBootPath[strlen(szBootPath)] != '\\')
strcat(szBootPath, "\\");
/*
* Find the kernel image name
*/
if(!ReadSectionSettingByName(OperatingSystemName, "Kernel", value))
{
MessageBox("Kernel image file not specified for selected operating system.");
return;
}
DrawBackdrop();
DrawStatusText(" Loading...");
DrawProgressBar(0);
/*
* Try to open boot drive
*/
if (!OpenDiskDrive(BootDrive, BootPartition))
{
MessageBox("Failed to open boot drive.");
return;
}
/*
* Parse the ini file and count the kernel and drivers
*/
for (i=1; i<=GetNumSectionItems(OperatingSystemName); i++)
{
/*
* Read the setting and check if it's a driver
*/
ReadSectionSettingByNumber(OperatingSystemName, i, name, value);
if ((stricmp(name, "Kernel") == 0) || (stricmp(name, "Driver") == 0))
nNumDriverFiles++;
}
/*
* Find the kernel image name
* and try to load the kernel off the disk
*/
if(ReadSectionSettingByName(OperatingSystemName, "Kernel", value))
{
/*
* Set the name and try to open the PE image
*/
strcpy(szFileName, szBootPath);
strcat(szFileName, value);
if (!OpenFile(szFileName, &file))
{
strcat(value, " not found.");
MessageBox(value);
return;
}
/*
* Update the status bar with the current file
*/
strcpy(name, " Reading ");
strcat(name, value);
while (strlen(name) < 80)
strcat(name, " ");
DrawStatusText(name);
/*
* Load the kernel image
*/
MultiBootLoadKernel(&file);
nNumFilesLoaded++;
DrawProgressBar((nNumFilesLoaded * 100) / nNumDriverFiles);
}
/*
* Parse the ini file and load the kernel and
* load all the drivers specified
*/
for (i=1; i<=GetNumSectionItems(OperatingSystemName); i++)
{
/*
* Read the setting and check if it's a driver
*/
ReadSectionSettingByNumber(OperatingSystemName, i, name, value);
if (stricmp(name, "Driver") == 0)
{
/*
* Set the name and try to open the PE image
*/
strcpy(szFileName, szBootPath);
strcat(szFileName, value);
if (!OpenFile(szFileName, &file))
{
strcat(value, " not found.");
MessageBox(value);
return;
}
/*
* Update the status bar with the current file
*/
strcpy(name, " Reading ");
strcat(name, value);
while (strlen(name) < 80)
strcat(name, " ");
DrawStatusText(name);
/*
* Load the driver
*/
MultiBootLoadModule(&file, szFileName);
nNumFilesLoaded++;
DrawProgressBar((nNumFilesLoaded * 100) / nNumDriverFiles);
}
else if (stricmp(name, "MessageBox") == 0)
{
DrawStatusText(" Press ENTER to continue");
MessageBox(value);
}
else if (stricmp(name, "MessageLine") == 0)
MessageLine(value);
else if (stricmp(name, "ReOpenBootDrive") == 0)
{
if (!OpenDiskDrive(BootDrive, BootPartition))
{
MessageBox("Failed to open boot drive.");
return;
}
}
}
/*
* Clear the screen and redraw the backdrop and status bar
*/
DrawBackdrop();
DrawStatusText(" Press any key to boot");
/*
* Wait for user
*/
strcpy(name, "Kernel and Drivers loaded.\nPress any key to boot ");
strcat(name, OperatingSystemName);
strcat(name, ".");
//MessageBox(name);
RestoreScreen(ScreenBuffer);
/*
* Now boot the kernel
*/
stop_floppy();
boot_reactos();
}

View File

@@ -1,27 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ROSBOOT_H
#define __ROSBOOT_H
void LoadAndBootReactOS(PUCHAR OperatingSystemName);
#endif // defined __ROSBOOT_H

View File

@@ -1,380 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "stdlib.h"
/*
* print() - prints unformatted text to stdout
*/
void print(char *str)
{
int i;
for(i=0; i<strlen(str); i++)
putchar(str[i]);
}
/*
* convert_to_ascii() - converts a number to it's ascii equivalent
* from:
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1996 Erich Boleyn <erich@uruk.org>
*/
char *convert_to_ascii(char *buf, int c, ...)
{
unsigned long num = *((&c) + 1), mult = 10;
char *ptr = buf;
if (c == 'x')
mult = 16;
if ((num & 0x80000000uL) && c == 'd')
{
num = (~num)+1;
*(ptr++) = '-';
buf++;
}
do
{
int dig = num % mult;
*(ptr++) = ( (dig > 9) ? dig + 'a' - 10 : '0' + dig );
}
while (num /= mult);
/* reorder to correct direction!! */
{
char *ptr1 = ptr-1;
char *ptr2 = buf;
while (ptr1 > ptr2)
{
int c = *ptr1;
*ptr1 = *ptr2;
*ptr2 = c;
ptr1--;
ptr2++;
}
}
return ptr;
}
/*
* printf() - prints formatted text to stdout
* from:
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1996 Erich Boleyn <erich@uruk.org>
*/
void printf(char *format, ... )
{
int *dataptr = (int *) &format;
char c, *ptr, str[16];
dataptr++;
while ((c = *(format++)))
{
if (c != '%')
putchar(c);
else
switch (c = *(format++))
{
case 'd': case 'u': case 'x':
*convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0;
ptr = str;
while (*ptr)
putchar(*(ptr++));
break;
case 'c': putchar((*(dataptr++))&0xff); break;
case 's':
ptr = (char *)(*(dataptr++));
while ((c = *(ptr++)))
putchar(c);
break;
}
}
}
void sprintf(char *buffer, char *format, ... )
{
int *dataptr = (int *) &format;
char c, *ptr, str[16];
char *p = buffer;
dataptr++;
while ((c = *(format++)))
{
if (c != '%')
{
*p = c;
p++;
}
else
switch (c = *(format++))
{
case 'd': case 'u': case 'x':
*convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0;
ptr = str;
while (*ptr)
{
*p = *(ptr++);
p++;
}
break;
case 'c':
*p = (*(dataptr++))&0xff;
p++;
break;
case 's':
ptr = (char *)(*(dataptr++));
while ((c = *(ptr++)))
{
*p = c;
p++;
}
break;
}
}
*p=0;
}
int strlen(char *str)
{
int len;
for(len=0; str[len] != '\0'; len++);
return len;
}
char *itoa(int value, char *string, int radix)
{
if(radix == 16)
*convert_to_ascii(string, 'x', value) = 0;
else
*convert_to_ascii(string, 'd', value) = 0;
return string;
}
int toupper(int c)
{
if((c >= 'a') && (c <= 'z'))
c -= 32;
return c;
}
int tolower(int c)
{
if((c >= 'A') && (c <= 'Z'))
c += 32;
return c;
}
int memcmp(const void *buf1, const void *buf2, size_t count)
{
size_t i;
const char *buffer1 = buf1;
const char *buffer2 = buf2;
for(i=0; i<count; i++)
{
if(buffer1[i] == buffer2[i])
continue;
else
return (buffer1[i] - buffer2[i]);
}
return 0;
}
void *memcpy(void *dest, const void *src, size_t count)
{
size_t i;
char *buf1 = dest;
const char *buf2 = src;
for(i=0; i<count; i++)
buf1[i] = buf2[i];
return dest;
}
void *memset(void *dest, int c, size_t count)
{
size_t i;
char *buf1 = dest;
for(i=0; i<count; i++)
buf1[i] = c;
return dest;
}
char *strcpy(char *dest, char *src)
{
char *ret = dest;
while(*src)
*dest++ = *src++;
*dest = 0;
return ret;
}
char *strcat(char *dest, char *src)
{
char *ret = dest;
while(*dest)
dest++;
while(*src)
*dest++ = *src++;
*dest = 0;
return ret;
}
char *strchr(const char *s, int c)
{
char cc = c;
while (*s)
{
if (*s == cc)
return (char *)s;
s++;
}
if (cc == 0)
return (char *)s;
return 0;
}
int strcmp(const char *string1, const char *string2)
{
while(*string1 == *string2)
{
if(*string1 == 0)
return 0;
string1++;
string2++;
}
return *(unsigned const char *)string1 - *(unsigned const char *)(string2);
}
int stricmp(const char *string1, const char *string2)
{
while(tolower(*string1) == tolower(*string2))
{
if(*string1 == 0)
return 0;
string1++;
string2++;
}
return (int)tolower(*string1) - (int)tolower(*string2);
}
int _strnicmp(const char *string1, const char *string2, size_t length)
{
if (length == 0)
return 0;
do
{
if (toupper(*string1) != toupper(*string2++))
return toupper(*(unsigned const char *)string1) - toupper(*(unsigned const char *)--string2);
if (*string1++ == 0)
break;
}
while (--length != 0);
return 0;
}
char *fgets(char *string, int n, FILE *stream)
{
int i;
for(i=0; i<(n-1); i++)
{
if(feof(stream))
{
i++;
break;
}
ReadFile(stream, 1, string+i);
if(string[i] == '\n')
{
i++;
break;
}
}
string[i] = '\0';
return string;
}
int atoi(char *string)
{
int base;
int result = 0;
char *str;
if((string[0] == '0') && (string[1] == 'x'))
{
base = 16;
str = string + 2;
}
else
{
base = 10;
str = string;
}
while(1)
{
if((*str < '0') || (*str > '9'))
break;
result *= base;
result += (*str - '0');
str++;
}
return result;
}

View File

@@ -1,81 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __STDLIB_H
#define __STDLIB_H
#include "fs.h"
void putchar(int ch); // Implemented in asmcode.S
void clrscr(void); // Implemented in asmcode.S
int kbhit(void); // Implemented in asmcode.S
int getch(void); // Implemented in asmcode.S
void gotoxy(int x, int y); // Implemented in asmcode.S
int getyear(void); // Implemented in asmcode.S
int getday(void); // Implemented in asmcode.S
int getmonth(void); // Implemented in asmcode.S
int gethour(void); // Implemented in asmcode.S
int getminute(void); // Implemented in asmcode.S
int getsecond(void); // Implemented in asmcode.S
void hidecursor(void); // Implemented in asmcode.S
void showcursor(void); // Implemented in asmcode.S
int wherex(void); // Implemented in asmcode.S
int wherey(void); // Implemented in asmcode.S
int strlen(char *str);
char *strcpy(char *dest, char *src);
char *strcat(char *dest, char *src);
char *strchr(const char *s, int c);
int strcmp(const char *string1, const char *string2);
int stricmp(const char *string1, const char *string2);
int _strnicmp(const char *string1, const char *string2, size_t length);
char *itoa(int value, char *string, int radix);
int toupper(int c);
int tolower(int c);
int memcmp(const void *buf1, const void *buf2, size_t count);
void *memcpy(void *dest, const void *src, size_t count);
void *memset(void *dest, int c, size_t count);
char *fgets(char *string, int n, FILE *stream);
int atoi(char *string);
#define ZeroMemory(Destination, Length) memset(Destination, 0, Length)
void print(char *str);
void printf(char *fmt, ...);
void sprintf(char *buffer, char *format, ...);
char *convert_to_ascii(char *buf, int c, ...);
int biosdisk(int cmd, int drive, int head, int track, int sector, int nsects, void *buffer); // Implemented in asmcode.S
void stop_floppy(void); // Implemented in asmcode.S
int get_heads(int drive); // Implemented in asmcode.S
int get_cylinders(int drive); // Implemented in asmcode.S
int get_sectors(int drive); // Implemented in asmcode.S
/* Values for biosdisk() */
#define _DISK_RESET 0 // Unimplemented
#define _DISK_STATUS 1 // Unimplemented
#define _DISK_READ 2 // Reads a sector into memory
#define _DISK_WRITE 3 // Unimplemented
#define _DISK_VERIFY 4 // Unimplemented
#define _DISK_FORMAT 5 // Unimplemented
#endif // defined __STDLIB_H

View File

@@ -1,572 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "freeldr.h"
#include "stdlib.h"
#include "tui.h"
int nScreenWidth = 80; // Screen Width
int nScreenHeight = 25; // Screen Height
char cStatusBarFgColor = COLOR_BLACK; // Status bar foreground color
char cStatusBarBgColor = COLOR_CYAN; // Status bar background color
char cBackdropFgColor = COLOR_WHITE; // Backdrop foreground color
char cBackdropBgColor = COLOR_BLUE; // Backdrop background color
char cBackdropFillStyle = MEDIUM_FILL; // Backdrop fill style
char cTitleBoxFgColor = COLOR_WHITE; // Title box foreground color
char cTitleBoxBgColor = COLOR_RED; // Title box background color
char cMessageBoxFgColor = COLOR_WHITE; // Message box foreground color
char cMessageBoxBgColor = COLOR_BLUE; // Message box background color
char cMenuFgColor = COLOR_WHITE; // Menu foreground color
char cMenuBgColor = COLOR_BLUE; // Menu background color
char cTextColor = COLOR_YELLOW; // Normal text color
char cSelectedTextColor = COLOR_BLACK; // Selected text color
char cSelectedTextBgColor = COLOR_GRAY; // Selected text background color
char szTitleBoxTitleText[260] = "Boot Menu"; // Title box's title text
char szMessageBoxLineText[4000] = "";
void DrawBackdrop(void)
{
// Fill in the backdrop
FillArea(0, 0, nScreenWidth-1, nScreenHeight-1, cBackdropFillStyle, ATTR(cBackdropFgColor, cBackdropBgColor));
// Draw the title box
DrawBox(1, 1, nScreenWidth, 5, D_VERT, D_HORZ, TRUE, FALSE, ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
// Draw version
DrawText(3, 2, VERSION, ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
// Draw copyright
DrawText(3, 3, "by Brian Palmer", ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
DrawText(3, 4, "<brianp@sginet.com>", ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
// Draw help text
//DrawText(nScreenWidth-15, 4, /*"F1 for Help"*/"F8 for Options", ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
// Draw title
DrawText((nScreenWidth/2)-(strlen(szTitleBoxTitleText)/2), 3, szTitleBoxTitleText, ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
// Draw date
DrawText(nScreenWidth-9, 2, "01/02/03", ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
// Draw time
DrawText(nScreenWidth-9, 3, "10:12:34", ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
// Draw status bar
DrawStatusText("");
// Update the date & time
UpdateDateTime();
}
/*
* FillArea()
* This function assumes coordinates are zero-based
*/
void FillArea(int nLeft, int nTop, int nRight, int nBottom, char cFillChar, char cAttr /* Color Attributes */)
{
char *screen = (char *)SCREEN_MEM;
int i, j;
for(i=nTop; i<=nBottom; i++)
{
for(j=nLeft; j<=nRight; j++)
{
screen[((i*2)*nScreenWidth)+(j*2)] = cFillChar;
screen[((i*2)*nScreenWidth)+(j*2)+1] = cAttr;
}
}
}
/*
* DrawShadow()
* This function assumes coordinates are zero-based
*/
void DrawShadow(int nLeft, int nTop, int nRight, int nBottom)
{
char *screen = (char *)SCREEN_MEM;
int i;
// Shade the bottom of the area
if(nBottom < (nScreenHeight-1))
{
for(i=nLeft+2; i<=nRight; i++)
screen[(((nBottom+1)*2)*nScreenWidth)+(i*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK);
}
// Shade the right of the area
if(nRight < (nScreenWidth-1))
{
for(i=nTop+1; i<=nBottom; i++)
screen[((i*2)*nScreenWidth)+((nRight+1)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK);
}
if(nRight+1 < (nScreenWidth-1))
{
for(i=nTop+1; i<=nBottom; i++)
screen[((i*2)*nScreenWidth)+((nRight+2)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK);
}
// Shade the bottom right corner
if((nRight < (nScreenWidth-1)) && (nBottom < (nScreenHeight-1)))
screen[(((nBottom+1)*2)*nScreenWidth)+((nRight+1)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK);
if((nRight+1 < (nScreenWidth-1)) && (nBottom < (nScreenHeight-1)))
screen[(((nBottom+1)*2)*nScreenWidth)+((nRight+2)*2)+1] = ATTR(COLOR_GRAY, COLOR_BLACK);
}
/*
* DrawBox()
* This function assumes coordinates are one-based
*/
void DrawBox(int nLeft, int nTop, int nRight, int nBottom, int nVertStyle, int nHorzStyle, int bFill, int bShadow, char cAttr)
{
char cULCorner, cURCorner, cLLCorner, cLRCorner;
char cHorz, cVert;
nLeft--;
nTop--;
nRight--;
nBottom--;
cHorz = nHorzStyle;
cVert = nVertStyle;
if(nHorzStyle == HORZ)
{
if(nVertStyle == VERT)
{
cULCorner = UL;
cURCorner = UR;
cLLCorner = LL;
cLRCorner = LR;
}
else // nVertStyle == D_VERT
{
cULCorner = VD_UL;
cURCorner = VD_UR;
cLLCorner = VD_LL;
cLRCorner = VD_LR;
}
}
else // nHorzStyle == D_HORZ
{
if(nVertStyle == VERT)
{
cULCorner = HD_UL;
cURCorner = HD_UR;
cLLCorner = HD_LL;
cLRCorner = HD_LR;
}
else // nVertStyle == D_VERT
{
cULCorner = D_UL;
cURCorner = D_UR;
cLLCorner = D_LL;
cLRCorner = D_LR;
}
}
// Fill in box background
if(bFill)
FillArea(nLeft, nTop, nRight, nBottom, ' ', cAttr);
// Fill in corners
FillArea(nLeft, nTop, nLeft, nTop, cULCorner, cAttr);
FillArea(nRight, nTop, nRight, nTop, cURCorner, cAttr);
FillArea(nLeft, nBottom, nLeft, nBottom, cLLCorner, cAttr);
FillArea(nRight, nBottom, nRight, nBottom, cLRCorner, cAttr);
// Fill in left line
FillArea(nLeft, nTop+1, nLeft, nBottom-1, cVert, cAttr);
// Fill in top line
FillArea(nLeft+1, nTop, nRight-1, nTop, cHorz, cAttr);
// Fill in right line
FillArea(nRight, nTop+1, nRight, nBottom-1, cVert, cAttr);
// Fill in bottom line
FillArea(nLeft+1, nBottom, nRight-1, nBottom, cHorz, cAttr);
if(bShadow)
DrawShadow(nLeft, nTop, nRight, nBottom);
}
/*
* DrawText()
* This function assumes coordinates are one-based
*/
void DrawText(int nX, int nY, char *text, char cAttr)
{
char *screen = (char *)SCREEN_MEM;
int i, j;
nX--;
nY--;
// Draw the text
for(i=nX, j=0; text[j]; i++,j++)
{
screen[((nY*2)*nScreenWidth)+(i*2)] = text[j];
screen[((nY*2)*nScreenWidth)+(i*2)+1] = cAttr;
}
}
void DrawStatusText(char *text)
{
int i;
DrawText(1, nScreenHeight, text, ATTR(cStatusBarFgColor, cStatusBarBgColor));
for(i=strlen(text)+1; i<=nScreenWidth; i++)
DrawText(i, nScreenHeight, " ", ATTR(cStatusBarFgColor, cStatusBarBgColor));
}
void UpdateDateTime(void)
{
char date[260];
char time[260];
char temp[20];
int hour, minute, second, bPM=FALSE;
switch(getmonth())
{
case 1:
strcpy(date, "January ");
break;
case 2:
strcpy(date, "February ");
break;
case 3:
strcpy(date, "March ");
break;
case 4:
strcpy(date, "April ");
break;
case 5:
strcpy(date, "May ");
break;
case 6:
strcpy(date, "June ");
break;
case 7:
strcpy(date, "July ");
break;
case 8:
strcpy(date, "August ");
break;
case 9:
strcpy(date, "September ");
break;
case 10:
strcpy(date, "October ");
break;
case 11:
strcpy(date, "November ");
break;
case 12:
strcpy(date, "December ");
break;
}
itoa(getday(), temp, 10);
if((getday() == 1) || (getday() == 21) || (getday() == 31))
strcat(temp, "st");
else if((getday() == 2) || (getday() == 22))
strcat(temp, "nd");
else if((getday() == 3) || (getday() == 23))
strcat(temp, "rd");
else
strcat(temp, "th");
strcat(date, temp);
strcat(date, " ");
itoa(getyear(), temp, 10);
strcat(date, temp);
// Draw the date
DrawText(nScreenWidth-strlen(date)-1, 2, date, ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
hour = gethour();
if(hour > 12)
{
hour -= 12;
bPM = TRUE;
}
if (hour == 0)
hour = 12;
minute = getminute();
second = getsecond();
itoa(hour, temp, 10);
strcpy(time, " ");
strcat(time, temp);
strcat(time, ":");
itoa(minute, temp, 10);
if(minute < 10)
strcat(time, "0");
strcat(time, temp);
strcat(time, ":");
itoa(second, temp, 10);
if(second < 10)
strcat(time, "0");
strcat(time, temp);
if(bPM)
strcat(time, " PM");
else
strcat(time, " AM");
// Draw the time
DrawText(nScreenWidth-strlen(time)-1, 3, time, ATTR(cTitleBoxFgColor, cTitleBoxBgColor));
}
void SaveScreen(char *buffer)
{
char *screen = (char *)SCREEN_MEM;
int i;
for(i=0; i < (nScreenWidth * nScreenHeight * 2); i++)
buffer[i] = screen[i];
}
void RestoreScreen(char *buffer)
{
char *screen = (char *)SCREEN_MEM;
int i;
for(i=0; i < (nScreenWidth * nScreenHeight * 2); i++)
screen[i] = buffer[i];
}
void MessageBox(char *text)
{
int width = 8;
int height = 1;
int curline = 0;
int i , j, k;
int x1, x2, y1, y2;
char savebuffer[8000];
char temp[260];
char key;
SaveScreen(savebuffer);
strcat(szMessageBoxLineText, text);
// Find the height
for(i=0; i<strlen(szMessageBoxLineText); i++)
{
if(szMessageBoxLineText[i] == '\n')
height++;
}
// Find the width
for(i=0,j=0,k=0; i<height; i++)
{
while((szMessageBoxLineText[j] != '\n') && (szMessageBoxLineText[j] != 0))
{
j++;
k++;
}
if(k > width)
width = k;
k = 0;
j++;
}
// Calculate box area
x1 = (nScreenWidth - (width+2))/2;
x2 = x1 + width + 3;
y1 = ((nScreenHeight - height - 2)/2) + 1;
y2 = y1 + height + 4;
// Draw the box
DrawBox(x1, y1, x2, y2, D_VERT, D_HORZ, TRUE, TRUE, ATTR(cMessageBoxFgColor, cMessageBoxBgColor));
// Draw the text
for(i=0,j=0; i<strlen(szMessageBoxLineText)+1; i++)
{
if((szMessageBoxLineText[i] == '\n') || (szMessageBoxLineText[i] == 0))
{
temp[j] = 0;
j = 0;
DrawText(x1+2, y1+1+curline, temp, ATTR(cMessageBoxFgColor, cMessageBoxBgColor));
curline++;
}
else
temp[j++] = szMessageBoxLineText[i];
}
// Draw OK button
strcpy(temp, " OK ");
DrawText(x1+((x2-x1)/2)-3, y2-2, temp, ATTR(COLOR_BLACK, COLOR_GRAY));
for(;;)
{
if(kbhit())
{
key = getch();
if(key == KEY_EXTENDED)
key = getch();
if(key == KEY_ENTER)
break;
else if(key == KEY_SPACE)
break;
}
UpdateDateTime();
}
RestoreScreen(savebuffer);
UpdateDateTime();
strcpy(szMessageBoxLineText, "");
}
void MessageLine(char *text)
{
strcat(szMessageBoxLineText, text);
strcat(szMessageBoxLineText, "\n");
}
BOOL IsValidColor(char *color)
{
if(stricmp(color, "Black") == 0)
return TRUE;
else if(stricmp(color, "Blue") == 0)
return TRUE;
else if(stricmp(color, "Green") == 0)
return TRUE;
else if(stricmp(color, "Cyan") == 0)
return TRUE;
else if(stricmp(color, "Red") == 0)
return TRUE;
else if(stricmp(color, "Magenta") == 0)
return TRUE;
else if(stricmp(color, "Brown") == 0)
return TRUE;
else if(stricmp(color, "Gray") == 0)
return TRUE;
else if(stricmp(color, "DarkGray") == 0)
return TRUE;
else if(stricmp(color, "LightBlue") == 0)
return TRUE;
else if(stricmp(color, "LightGreen") == 0)
return TRUE;
else if(stricmp(color, "LightCyan") == 0)
return TRUE;
else if(stricmp(color, "LightRed") == 0)
return TRUE;
else if(stricmp(color, "LightMagenta") == 0)
return TRUE;
else if(stricmp(color, "Yellow") == 0)
return TRUE;
else if(stricmp(color, "White") == 0)
return TRUE;
return FALSE;
}
char TextToColor(char *color)
{
if(stricmp(color, "Black") == 0)
return COLOR_BLACK;
else if(stricmp(color, "Blue") == 0)
return COLOR_BLUE;
else if(stricmp(color, "Green") == 0)
return COLOR_GREEN;
else if(stricmp(color, "Cyan") == 0)
return COLOR_CYAN;
else if(stricmp(color, "Red") == 0)
return COLOR_RED;
else if(stricmp(color, "Magenta") == 0)
return COLOR_MAGENTA;
else if(stricmp(color, "Brown") == 0)
return COLOR_BROWN;
else if(stricmp(color, "Gray") == 0)
return COLOR_GRAY;
else if(stricmp(color, "DarkGray") == 0)
return COLOR_DARKGRAY;
else if(stricmp(color, "LightBlue") == 0)
return COLOR_LIGHTBLUE;
else if(stricmp(color, "LightGreen") == 0)
return COLOR_LIGHTGREEN;
else if(stricmp(color, "LightCyan") == 0)
return COLOR_LIGHTCYAN;
else if(stricmp(color, "LightRed") == 0)
return COLOR_LIGHTRED;
else if(stricmp(color, "LightMagenta") == 0)
return COLOR_LIGHTMAGENTA;
else if(stricmp(color, "Yellow") == 0)
return COLOR_YELLOW;
else if(stricmp(color, "White") == 0)
return COLOR_WHITE;
return COLOR_BLACK;
}
BOOL IsValidFillStyle(char *fill)
{
if(stricmp(fill, "Light") == 0)
return TRUE;
else if(stricmp(fill, "Medium") == 0)
return TRUE;
else if(stricmp(fill, "Dark") == 0)
return TRUE;
return FALSE;
}
char TextToFillStyle(char *fill)
{
if(stricmp(fill, "Light") == 0)
return LIGHT_FILL;
else if(stricmp(fill, "Medium") == 0)
return MEDIUM_FILL;
else if(stricmp(fill, "Dark") == 0)
return DARK_FILL;
return LIGHT_FILL;
}
void DrawProgressBar(int nPos)
{
int left, top, right, bottom;
int width = 50; // Allow for 50 "bars"
int height = 2;
int i;
if(nPos > 100)
nPos = 100;
left = (nScreenWidth - width - 4) / 2;
right = left + width + 3;
top = (nScreenHeight - height - 2) / 2;
top += 4;
bottom = top + height + 1;
// Draw the box
DrawBox(left, top, right, bottom, VERT, HORZ, TRUE, TRUE, ATTR(cMenuFgColor, cMenuBgColor));
// Draw the "Loading..." text
DrawText(70/2, top+1, "Loading...", ATTR(cTextColor, cMenuBgColor));
// Draw the percent complete
for(i=0; i<(nPos/2); i++)
DrawText(left+2+i, top+2, "\xDB", ATTR(cTextColor, cMenuBgColor));
// Draw the rest
for(; i<50; i++)
DrawText(left+2+i, top+2, "\xB2", ATTR(cTextColor, cMenuBgColor));
UpdateDateTime();
}

View File

@@ -1,162 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __TUI_H
#define __TUI_H
#define SCREEN_MEM 0xB8000
extern int nScreenWidth; // Screen Width
extern int nScreenHeight; // Screen Height
extern char cStatusBarFgColor; // Status bar foreground color
extern char cStatusBarBgColor; // Status bar background color
extern char cBackdropFgColor; // Backdrop foreground color
extern char cBackdropBgColor; // Backdrop background color
extern char cBackdropFillStyle; // Backdrop fill style
extern char cTitleBoxFgColor; // Title box foreground color
extern char cTitleBoxBgColor; // Title box background color
extern char cMessageBoxFgColor; // Message box foreground color
extern char cMessageBoxBgColor; // Message box background color
extern char cMenuFgColor; // Menu foreground color
extern char cMenuBgColor; // Menu background color
extern char cTextColor; // Normal text color
extern char cSelectedTextColor; // Selected text color
extern char cSelectedTextBgColor; // Selected text background color
extern char szTitleBoxTitleText[260]; // Title box's title text
// Fills the entire screen with a backdrop
void DrawBackdrop(void);
// Fills the area specified with cFillChar and cAttr
void FillArea(int nLeft, int nTop, int nRight, int nBottom, char cFillChar, char cAttr /* Color Attributes */);
// Draws a shadow on the bottom and right sides of the area specified
void DrawShadow(int nLeft, int nTop, int nRight, int nBottom);
// Draws a box around the area specified
void DrawBox(int nLeft, int nTop, int nRight, int nBottom, int nVertStyle, int nHorzStyle, int bFill, int bShadow, char cAttr);
// Draws text at coordinates specified
void DrawText(int nX, int nY, char *text, char cAttr);
// Draws text at the very bottom line on the screen
void DrawStatusText(char *text);
// Updates the date and time
void UpdateDateTime(void);
// Saves the screen so that it can be restored later
void SaveScreen(char *buffer);
// Restores the screen from a previous save
void RestoreScreen(char *buffer);
// Displays a message box on the screen with an ok button
void MessageBox(char *text);
// Adds a line of text to the message box buffer
void MessageLine(char *text);
// Returns true if color is valid
BOOL IsValidColor(char *color);
// Converts the text color into it's equivalent color value
char TextToColor(char *color);
// Returns true if fill is valid
BOOL IsValidFillStyle(char *fill);
// Converts the text fill into it's equivalent fill value
char TextToFillStyle(char *fill);
// Draws the progress bar showing nPos percent filled
void DrawProgressBar(int nPos);
/*
* Combines the foreground and background colors into a single attribute byte
*/
#define ATTR(cFore, cBack) ((cBack << 4)|cFore)
/*
* Fill styles for DrawBackdrop()
*/
#define LIGHT_FILL 0xB0
#define MEDIUM_FILL 0xB1
#define DARK_FILL 0xB2
/*
* Screen colors
*/
#define COLOR_BLACK 0
#define COLOR_BLUE 1
#define COLOR_GREEN 2
#define COLOR_CYAN 3
#define COLOR_RED 4
#define COLOR_MAGENTA 5
#define COLOR_BROWN 6
#define COLOR_GRAY 7
#define COLOR_DARKGRAY 8
#define COLOR_LIGHTBLUE 9
#define COLOR_LIGHTGREEN 10
#define COLOR_LIGHTCYAN 11
#define COLOR_LIGHTRED 12
#define COLOR_LIGHTMAGENTA 13
#define COLOR_YELLOW 14
#define COLOR_WHITE 15
/* Add COLOR_BLINK to a background to cause blinking */
#define COLOR_BLINK 8
/*
* Defines for IBM box drawing characters
*/
#define HORZ (0xc4) /* Single horizontal line */
#define D_HORZ (0xcd) /* Double horizontal line.*/
#define VERT (0xb3) /* Single vertical line */
#define D_VERT (0xba) /* Double vertical line. */
/* Definitions for corners, depending on HORIZ and VERT */
#define UL (0xda)
#define UR (0xbf) /* HORZ and VERT */
#define LL (0xc0)
#define LR (0xd9)
#define D_UL (0xc9)
#define D_UR (0xbb) /* D_HORZ and D_VERT */
#define D_LL (0xc8)
#define D_LR (0xbc)
#define HD_UL (0xd5)
#define HD_UR (0xb8) /* D_HORZ and VERT */
#define HD_LL (0xd4)
#define HD_LR (0xbe)
#define VD_UL (0xd6)
#define VD_UR (0xb7) /* HORZ and D_VERT */
#define VD_LL (0xd3)
#define VD_LR (0xbd)
// Key codes
#define KEY_EXTENDED 0x00
#define KEY_ENTER 0x0D
#define KEY_SPACE 0x20
#define KEY_UP 0x48
#define KEY_DOWN 0x50
#define KEY_LEFT 0x4B
#define KEY_RIGHT 0x4D
#define KEY_ESC 0x1B
#define KEY_F1 0x3B
#define KEY_F2 0x3C
#define KEY_F3 0x3D
#define KEY_F4 0x3E
#define KEY_F5 0x3F
#define KEY_F6 0x40
#define KEY_F7 0x41
#define KEY_F8 0x42
#define KEY_F9 0x43
#define KEY_F10 0x44
#endif // #defined __TUI_H

View File

@@ -1,5 +0,0 @@
cd bootsect
call install.bat
cd..
copy freeldr.sys a:\FREELDR.SYS
copy freeldr.ini a:\FREELDR.INI

View File

@@ -1,18 +0,0 @@
FreeLoader notes
To build FreeLoader you will need DJGPP because Mingw32 doesn't support 16-bit code
FreeLoader does not currently work with extended partitions.
Linux booting support needs to be added.
ext2 filesystem support needs to be added.
Current memory layout:
0000:0000 - 0000:0FFF: Interrupt vector table & BIOS data
0000:1000 - 0000:6FFF: Real mode stack area
0000:7000 - xxxx:xxxx: FreeLoader program & data area
xxxx:xxxx - 6000:0000: Protected mode stack area & heap
6000:0000 - 6000:C000: Filesystem data buffer
6000:C000 - 7000:0000: FREELDR.INI loaded here
7000:0000 - 7000:FFFF: scratch area for any function's use (ie sector buffer for biosdisk()) - can be overwritten by any function
8000:0000 - 9000:FFFF: fat table entry buffer
A000:0000 - FFFF:FFFF: reserved

View File

@@ -1,4 +1,4 @@
/* $Id: create.c,v 1.30 2001/08/01 10:12:33 hbirr Exp $
/* $Id: create.c,v 1.29 2001/07/25 08:58:21 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -69,7 +69,7 @@ void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName)
{
pName [toIndex++] = L'.';
fromIndex = 0;
while (fromIndex < 3 && pExtension [fromIndex] != ' ')
while (fromIndex < 3 && pBasename [fromIndex] != ' ')
{
pName [toIndex++] = pExtension [fromIndex++];
}

View File

@@ -1,4 +1,4 @@
/* $Id: direntry.c,v 1.4 2001/08/01 15:59:24 hbirr Exp $
/* $Id: direntry.c,v 1.3 2001/07/28 07:05:56 hbirr Exp $
*
*
* FILE: DirEntry.c
@@ -125,8 +125,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
cacheSegment);
return STATUS_NO_MORE_ENTRIES;
}
else if (vfatIsDirEntryLongName (&fatDirEntry [indexInPage])
&& !vfatIsDirEntryDeleted (&fatDirEntry [indexInPage]))
else if (vfatIsDirEntryLongName (&fatDirEntry [indexInPage]))
{
DPRINT (" long name entry found at %d\n", *pDirectoryIndex);
longNameEntry = (slot *) currentPage;
@@ -144,7 +143,7 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
DPRINT (" longName: [%S]\n", pLongFileName);
cpos = 0;
while ((longNameEntry [indexInPage].id != 0x41) &&
while ((longNameEntry [indexInPage].id != 0x41) &&
(longNameEntry [indexInPage].id != 0x01) &&
(longNameEntry [indexInPage].attr > 0))
{
@@ -162,8 +161,8 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
{
return status;
}
status = vfatRequestAndValidateRegion (pDeviceExt,
pDirectoryFCB,
status = vfatRequestAndValidateRegion (pDeviceExt,
pDirectoryFCB,
pageNumber * CACHEPAGESIZE(pDeviceExt),
(PVOID *) &currentPage,
&cacheSegment,
@@ -204,8 +203,8 @@ vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
{
return status;
}
status = vfatRequestAndValidateRegion (pDeviceExt,
pDirectoryFCB,
status = vfatRequestAndValidateRegion (pDeviceExt,
pDirectoryFCB,
pageNumber * CACHEPAGESIZE(pDeviceExt),
(PVOID *) &currentPage,
&cacheSegment,

View File

@@ -1,115 +0,0 @@
/*
* fcntl.h
*
* Access constants for _open. Note that the permissions constants are
* in sys/stat.h (ick).
*
* This code is part of the Mingw32 package.
*
* Contributors:
* Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Revision: 1.4 $
* $Author: ariadne $
* $Date: 1999/03/22 20:48:08 $
*
*/
/* Appropriated for Reactos Crtdll by Ariadne */
/* added _O_RANDOM_O_SEQUENTIAL _O_SHORT_LIVED*/
/* changed fmode_dll */
#ifndef _FCNTL_H_
#define _FCNTL_H_
/*
* It appears that fcntl.h should include io.h for compatibility...
*/
#include <io.h>
/*
* This variable determines the default file mode.
* TODO: Which flags work?
*/
#if __MSVCRT__
extern unsigned int* __imp__fmode;
#define _fmode (*__imp__fmode)
#else
/* CRTDLL */
extern unsigned int* _fmode_dll;
#define _fmode (*_fmode_dll)
#endif
/* Specifiy one of these flags to define the access mode. */
#define _O_RDONLY 0
#define _O_WRONLY 1
#define _O_RDWR 2
/* Mask for access mode bits in the _open flags. */
#define _O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
#define _O_APPEND 0x0008 /* Writes will add to the end of the file. */
#define _O_CREAT 0x0100 /* Create the file if it does not exist. */
#define _O_TRUNC 0x0200 /* Truncate the file if it does exist. */
#define _O_EXCL 0x0400 /* Open only if the file does not exist. */
/* NOTE: Text is the default even if the given _O_TEXT bit is not on. */
#define _O_TEXT 0x4000 /* CR-LF in file becomes LF in memory. */
#define _O_BINARY 0x8000 /* Input and output is not translated. */
#define _O_RAW _O_BINARY
#define _O_TEMPORARY 0x0040 /* Make the file dissappear after closing.
* WARNING: Even if not created by _open! */
#define _O_RANDOM 0x0010
#define _O_SEQUENTIAL _O_RANDOM
#define _O_SHORT_LIVED 0x1000
#ifndef __STRICT_ANSI__
#ifndef _NO_OLDNAMES
/* POSIX/Non-ANSI names for increased portability */
#define O_RDONLY _O_RDONLY
#define O_WRONLY _O_WRONLY
#define O_RDWR _O_RDWR
#define O_ACCMODE _O_ACCMODE
#define O_APPEND _O_APPEND
#define O_CREAT _O_CREAT
#define O_TRUNC _O_TRUNC
#define O_EXCL _O_EXCL
#define O_TEXT _O_TEXT
#define O_BINARY _O_BINARY
#define O_TEMPORARY _O_TEMPORARY
#define O_RANDOM _O_RANDOM
#define O_SEQUENTIAL _O_RANDOM
#define O_SHORT_LIVED _O_SHORT_LIVED
#endif /* Not _NO_OLDNAMES */
#ifdef __cplusplus
extern "C" {
#endif
int _setmode (int nHandle, int nAccessMode);
#ifndef _NO_OLDNAMES
int setmode (int nHandle, int nAccessMode);
#endif /* Not _NO_OLDNAMES */
#ifdef __cplusplus
}
#endif
#endif /* Not __STRICT_ANSI__ */
#endif /* Not _FCNTL_H_ */

View File

@@ -1,151 +0,0 @@
#ifndef __INCLUDE_INTERNAL_PORT_H
#define __INCLUDE_INTERNAL_PORT_H
#include <napi/lpc.h>
typedef
struct _EPORT
{
KSPIN_LOCK Lock;
KEVENT Event;
ULONG State;
struct _EPORT * OtherPort;
ULONG QueueLength;
LIST_ENTRY QueueListHead;
ULONG ConnectQueueLength;
LIST_ENTRY ConnectQueueListHead;
ULONG MaxDataLength;
ULONG MaxConnectInfoLength;
} EPORT, * PEPORT;
typedef struct _EPORT_TERMINATION_REQUEST
{
LIST_ENTRY ThreadListEntry;
PEPORT Port;
} EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST;
NTSTATUS
STDCALL
LpcRequestPort (
PEPORT Port,
PLPC_MESSAGE LpcMessage
);
NTSTATUS
STDCALL
LpcSendTerminationPort (
PEPORT Port,
TIME CreationTime
);
/* Port Object Access */
#define PORT_ALL_ACCESS (0x1)
/* EPORT.State */
#define EPORT_INACTIVE (0)
#define EPORT_WAIT_FOR_CONNECT (1)
#define EPORT_WAIT_FOR_ACCEPT (2)
#define EPORT_WAIT_FOR_COMPLETE_SRV (3)
#define EPORT_WAIT_FOR_COMPLETE_CLT (4)
#define EPORT_CONNECTED_CLIENT (5)
#define EPORT_CONNECTED_SERVER (6)
#define EPORT_DISCONNECTED (7)
typedef
struct _QUEUEDMESSAGE
{
PEPORT Sender;
LIST_ENTRY QueueListEntry;
LPC_MESSAGE Message;
UCHAR MessageData [MAX_MESSAGE_DATA];
} QUEUEDMESSAGE, *PQUEUEDMESSAGE;
/* Code in ntoskrnl/lpc/close.c */
VOID
NiClosePort (
PVOID ObjectBody,
ULONG HandleCount
);
VOID
NiDeletePort (
IN PVOID ObjectBody
);
/* Code in ntoskrnl/lpc/queue.c */
VOID
STDCALL
EiEnqueueConnectMessagePort (
IN OUT PEPORT Port,
IN PQUEUEDMESSAGE Message
);
VOID
STDCALL
EiEnqueueMessagePort (
IN OUT PEPORT Port,
IN PQUEUEDMESSAGE Message
);
PQUEUEDMESSAGE
STDCALL
EiDequeueConnectMessagePort (
IN OUT PEPORT Port
);
PQUEUEDMESSAGE
STDCALL
EiDequeueMessagePort (
IN OUT PEPORT Port
);
/* Code in ntoskrnl/lpc/create.c */
NTSTATUS
NiCreatePort (
PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes
);
/* Code in ntoskrnl/lpc/port.c */
NTSTATUS
STDCALL
NiInitializePort (
IN OUT PEPORT Port
);
NTSTATUS
NiInitPort (
VOID
);
extern POBJECT_TYPE ExPortType;
extern ULONG EiNextLpcMessageId;
/* Code in ntoskrnl/lpc/reply.c */
NTSTATUS
STDCALL
EiReplyOrRequestPort (
IN PEPORT Port,
IN PLPC_MESSAGE LpcReply,
IN ULONG MessageType,
IN PEPORT Sender
);
#endif /* __INCLUDE_INTERNAL_PORT_H */

View File

@@ -1,193 +0,0 @@
/*
* stdlib.h
*
* Definitions for common types, variables, and functions.
*
* This file is part of the Mingw32 package.
*
* Contributors:
* Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Revision: 1.5 $
* $Author: ariadne $
* $Date: 1999/03/22 20:48:08 $
*
*/
/* Appropriated for Reactos Crtdll by Ariadne */
/* added splitpath */
/* changed definition of environ and argc */
#ifndef _STDLIB_H_
#define _STDLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* This seems like a convenient place to declare these variables, which
* give programs using WinMain (or main for that matter) access to main-ish
* argc and argv. environ is a pointer to a table of environment variables.
* NOTE: Strings in _argv and environ are ANSI strings.
*/
extern int* __argc_dll;
extern char*** __argv_dll;
extern char*** _environ_dll;
#define __argc (*__argc_dll)
#define __argv (*__argv_dll)
#define _environ (*_environ_dll)
#define __need_size_t
#define __need_wchar_t
#define __need_NULL
#include <stddef.h>
#ifdef __GNUC__
#define _ATTRIB_NORETURN __attribute__ ((noreturn))
#else /* Not __GNUC__ */
#define _ATTRIB_NORETURN
#endif /* __GNUC__ */
double atof (const char* szNumber);
int atoi (const char* szNumber);
long atol (const char* szNumber);
double strtod (const char* szNumber, char** pszAfterNumber);
double wcstod (const wchar_t* wsNumber, wchar_t** pwsAfterNumber);
long strtol (const char* szNumber, char** pszAfterNumber, int nBase);
long wcstol (const wchar_t* wsNumber, wchar_t** pwsAfterNumber, int nBase);
unsigned long strtoul (const char* szNumber, char** pszAfterNumber,
int nBase);
unsigned long wcstoul (const wchar_t* wsNumber, wchar_t** pwsAfterNumber,
int nBase);
size_t wcstombs (char* mbsDest, const wchar_t* wsConvert, size_t size);
int wctomb (char* mbDest, wchar_t wc);
int mblen (const char* mbs, size_t sizeString);
size_t mbstowcs (wchar_t* wcaDest, const char* mbsConvert,
size_t size);
int mbtowc (wchar_t* wcDest, const char* mbConvert, size_t size);
/*
* RAND_MAX is the maximum value that may be returned by rand.
* The minimum is zero.
*/
#define RAND_MAX 0x7FFF
int rand (void);
void srand (unsigned int nSeed);
void* calloc (size_t sizeObjCnt, size_t sizeObject);
void* malloc (size_t sizeObject);
void* realloc (void* pObject, size_t sizeNew);
void free (void* pObject);
/* These values may be used as exit status codes. */
#define EXIT_SUCCESS 0
#define EXIT_FAILURE -1
void abort (void) _ATTRIB_NORETURN;
void exit (int nStatus) _ATTRIB_NORETURN;
int atexit (void (*pfuncExitProcessing)(void));
int system (const char* szCommand); // impl in process
char* getenv (const char* szVarName); // impl in stdio
typedef int (*_pfunccmp_t)(const void*, const void*);
void* bsearch (const void* pKey, const void* pBase, size_t cntObjects,
size_t sizeObject, _pfunccmp_t pfuncCmp);
void qsort (const void* pBase, size_t cntObjects, size_t sizeObject,
_pfunccmp_t pfuncCmp);
int abs (int n);
long labs (long n);
/*
* div_t and ldiv_t are structures used to return the results of div and
* ldiv.
*
* NOTE: div and ldiv appear not to work correctly unless
* -fno-pcc-struct-return is specified. This is included in the
* mingw32 specs file.
*/
typedef struct { int quot, rem; } div_t;
typedef struct { long quot, rem; } ldiv_t;
typedef struct { long long quot, rem; } lldiv_t;
div_t div (int nNumerator, int nDenominator);
ldiv_t ldiv (long lNumerator, long lDenominator);
lldiv_t lldiv (long long lNumerator, long long lDenominator);
#ifndef __STRICT_ANSI__
/*
* NOTE: Officially the three following functions are obsolete. The Win32 API
* functions SetErrorMode, Beep and Sleep are their replacements.
*/
void _beep (unsigned int, unsigned int);
void _seterrormode (int nMode);
void _sleep (unsigned long ulTime);
void _exit (int nStatus) _ATTRIB_NORETURN;
int _putenv (const char* szNameEqValue);
void _searchenv (const char* szFileName, const char* szVar,
char* szFullPathBuf);
void _splitpath( const char *path, char *drive, char *dir,
char *fname, char *ext );
char* _itoa (int nValue, char* sz, int nRadix);
char* _ltoa (long lnValue, char* sz, int nRadix);
char* _ecvt (double dValue, int nDig, int* pnDec, int* pnSign);
char* _fcvt (double dValue, int nDig, int* pnDec, int* pnSign);
char* _gcvt (double dValue, int nDec, char* caBuf);
char* _fullpath (char* caBuf, const char* szPath, size_t sizeMax);
#ifndef _NO_OLDNAMES
#define beep _beep
#define seterrormode _seterrormode
#define sleep _sleep
#define putenv _putenv
#define searchenv _searchenv
#define splitpath _splitpath
#define itoa _itoa
#define ltoa _ltoa
#define ecvt _ecvt
#define fcvt _fcvt
#define gcvt _gcvt
#endif /* Not _NO_OLDNAMES */
#endif /* Not __STRICT_ANSI__ */
/*
* Undefine the no return attribute used in some function definitions
*/
#undef _ATTRIB_NORETURN
#ifdef __cplusplus
}
#endif
#endif /* _STDLIB_H_ */

View File

@@ -98,7 +98,6 @@ _filbuf(FILE *f)
return EOF;
}
f->_cnt--;
return *f->_ptr++ & 0377;
}

View File

@@ -1,4 +1,4 @@
/* $Id: find.c,v 1.28 2001/08/01 19:26:41 hbirr Exp $
/* $Id: find.c,v 1.27 2000/08/05 18:01:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@@ -398,12 +398,11 @@ FindFirstFileW (
lpFindFileData->nFileSizeLow = IData->FileInfo.EndOfFile.u.LowPart;
memcpy (lpFindFileData->cFileName,
IData->FileInfo.FileName,
IData->FileInfo.FileNameLength * sizeof(WCHAR));
lpFindFileData->cFileName[IData->FileInfo.FileNameLength] = 0;
IData->FileInfo.FileNameLength);
memcpy (lpFindFileData->cAlternateFileName,
IData->FileInfo.ShortName,
IData->FileInfo.ShortNameLength * sizeof(WCHAR));
lpFindFileData->cAlternateFileName[IData->FileInfo.ShortNameLength] = 0;
IData->FileInfo.ShortNameLength);
return IData;
}
@@ -439,12 +438,11 @@ FindNextFileW (
lpFindFileData->nFileSizeLow = IData->FileInfo.EndOfFile.u.LowPart;
memcpy (lpFindFileData->cFileName,
IData->FileInfo.FileName,
IData->FileInfo.FileNameLength * sizeof(WCHAR));
lpFindFileData->cFileName[IData->FileInfo.FileNameLength] = 0;
IData->FileInfo.FileNameLength);
memcpy (lpFindFileData->cAlternateFileName,
IData->FileInfo.ShortName,
IData->FileInfo.ShortNameLength * sizeof(WCHAR));
lpFindFileData->cAlternateFileName[IData->FileInfo.ShortNameLength] = 0;
IData->FileInfo.ShortNameLength);
return TRUE;
}

View File

@@ -98,7 +98,6 @@ _filbuf(FILE *f)
return EOF;
}
f->_cnt--;
return *f->_ptr++ & 0377;
}

View File

@@ -1,142 +0,0 @@
#
# Global makefile
#
#
# Select your host
#
#HOST = mingw32-linux
#HOST = djgpp-msdos
HOST = mingw32-windows
include rules.mak
#
# Required to run the system
#
COMPONENTS = iface_native ntoskrnl
#DLLS = ntdll kernel32 crtdll user32 fmifs gdi32
DLLS = ntdll kernel32 crtdll fmifs gdi32
#DLLS = crtdll mingw32
SUBSYS = win32k
#
# Select the server(s) you want to build
#
SERVERS = win32
# SERVERS = posix linux os2
#
# Select the loader(s) you want to build
#
LOADERS = dos
# LOADERS = boot
#
# Select the device drivers and filesystems you want
#
DEVICE_DRIVERS = blue ide keyboard mouse null parallel serial vidport
# DEVICE_DRIVERS = beep event floppy ide_test sound test test1
FS_DRIVERS = vfat
# FS_DRIVERS = minix ext2 template
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS)
APPS = args hello shell test cat bench
# APPS = cmd
all: $(COMPONENTS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES) $(APPS)
.PHONY: all
clean: $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \
$(KERNEL_SERVICES:%=%_clean) $(APPS:%=%_clean)
.PHONY: clean
#
# Applications
#
$(APPS): %:
make -C apps/$*
$(APPS:%=%_clean): %_clean:
make -C apps/$* clean
.PHONY: $(APPS) $(APPS:%=%_clean)
#
# Interfaces
#
iface_native:
make -C iface/native
iface_native_clean:
make -C iface/native clean
.PHONY: iface_native iface_native_clean
#
# Device driver rules
#
$(DEVICE_DRIVERS): %:
make -C services/dd/$*
$(DEVICE_DRIVERS:%=%_clean): %_clean:
make -C services/dd/$* clean
.PHONY: $(DEVICE_DRIVERS) $(DEVICE_DRIVERS:%=%_clean)
$(FS_DRIVERS): %:
make -C services/fs/$*
$(FS_DRIVERS:%=%_clean): %_clean:
make -C services/fs/$* clean
.PHONY: $(FS_DRIVERS) $(FS_DRIVERS:%=%_clean)
#
# Kernel loaders
#
$(LOADERS): %:
make -C loaders/$*
$(LOADERS:%=%_clean): %_clean:
make -C loaders/$* clean
.PHONY: $(LOADERS) $(LOADERS:%=%_clean)
#
# Required system components
#
ntoskrnl:
make -C ntoskrnl
ntoskrnl_clean:
make -C ntoskrnl clean
.PHONY: ntoskrnl ntoskrnl_clean
#
# Required DLLs
#
$(DLLS): %:
make -C lib/$*
$(DLLS:%=%_clean): %_clean:
make -C lib/$* clean
.PHONY: $(DLLS) $(DLLS:%=%_clean)
#
# Kernel Subsystems
#
$(SUBSYS): %:
make -C subsys/$*
$(SUBSYS:%=%_clean): %_clean:
make -C lib/$* clean
.PHONY: $(SUBSYS) $(SUBSYS:%=%_clean)

View File

@@ -1,4 +1,4 @@
/* $Id: bus.c,v 1.9 2001/08/01 10:39:50 ekohl Exp $
/* $Id: bus.c,v 1.8 2001/06/13 22:17:01 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -160,8 +160,8 @@ HalpInitBusHandlers(VOID)
0);
if (BusHandler == NULL)
return;
BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData;
BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData;
// BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData;
// BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData;
/* add isa bus handler */
BusHandler = HalpAllocateBusHandler(Isa,

View File

@@ -11,9 +11,8 @@
#include <ddk/ntddk.h>
#include <string.h>
#include <internal/hal/mps.h>
#include <internal/hal/bus.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* MACROS and CONSTANTS ******************************************************/
@@ -36,69 +35,36 @@
/* FUNCTIONS *****************************************************************/
static UCHAR
HalpQueryCMOS(UCHAR Reg)
static BYTE
HalQueryCMOS (BYTE Reg)
{
UCHAR Val;
ULONG Flags;
BYTE Val;
ULONG Flags;
Reg |= 0x80;
pushfl(Flags);
__asm__("cli\n"); // AP unsure as to whether to do this here
WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
Val = READ_PORT_UCHAR((PUCHAR)0x71);
WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
popfl(Flags);
Reg |= 0x80;
pushfl(Flags);
__asm__("cli\n"); // AP unsure as to whether to do this here
WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
Val = READ_PORT_UCHAR((PUCHAR)0x71);
WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
popfl(Flags);
return(Val);
return(Val);
}
static VOID
HalpSetCMOS(UCHAR Reg,
UCHAR Val)
HalSetCMOS (BYTE Reg, BYTE Val)
{
ULONG Flags;
ULONG Flags;
Reg |= 0x80;
pushfl(Flags);
__asm__("cli\n"); // AP unsure as to whether to do this here
WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
WRITE_PORT_UCHAR((PUCHAR)0x71, Val);
WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
popfl(Flags);
}
static UCHAR
HalpQueryECMOS(USHORT Reg)
{
UCHAR Val;
ULONG Flags;
pushfl(Flags);
__asm__("cli\n"); // AP unsure as to whether to do this here
WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
Val = READ_PORT_UCHAR((PUCHAR)0x76);
popfl(Flags);
return(Val);
}
static VOID
HalpSetECMOS(USHORT Reg,
UCHAR Val)
{
ULONG Flags;
pushfl(Flags);
__asm__("cli\n"); // AP unsure as to whether to do this here
WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
WRITE_PORT_UCHAR((PUCHAR)0x76, Val);
popfl(Flags);
Reg |= 0x80;
pushfl(Flags);
__asm__("cli\n"); // AP unsure as to whether to do this here
WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
WRITE_PORT_UCHAR((PUCHAR)0x71, Val);
WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
popfl(Flags);
}
@@ -106,16 +72,16 @@ VOID STDCALL
HalQueryRealTimeClock(PTIME_FIELDS Time)
{
/* check 'Update In Progress' bit */
while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP)
while (HalQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP)
;
Time->Second = BCD_INT(HalpQueryCMOS (0));
Time->Minute = BCD_INT(HalpQueryCMOS (2));
Time->Hour = BCD_INT(HalpQueryCMOS (4));
Time->Weekday = BCD_INT(HalpQueryCMOS (6));
Time->Day = BCD_INT(HalpQueryCMOS (7));
Time->Month = BCD_INT(HalpQueryCMOS (8));
Time->Year = BCD_INT(HalpQueryCMOS (9));
Time->Second = BCD_INT(HalQueryCMOS (0));
Time->Minute = BCD_INT(HalQueryCMOS (2));
Time->Hour = BCD_INT(HalQueryCMOS (4));
Time->Weekday = BCD_INT(HalQueryCMOS (6));
Time->Day = BCD_INT(HalQueryCMOS (7));
Time->Month = BCD_INT(HalQueryCMOS (8));
Time->Year = BCD_INT(HalQueryCMOS (9));
if (Time->Year > 80)
Time->Year += 1900;
@@ -124,7 +90,7 @@ HalQueryRealTimeClock(PTIME_FIELDS Time)
#if 0
/* Century */
Time->Year += BCD_INT(HalpQueryCMOS (RTC_REGISTER_CENTURY)) * 100;
Time->Year += BCD_INT(HalQueryCMOS (RTC_REGISTER_CENTURY)) * 100;
#endif
#ifndef NDEBUG
@@ -146,20 +112,20 @@ VOID STDCALL
HalSetRealTimeClock(PTIME_FIELDS Time)
{
/* check 'Update In Progress' bit */
while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP)
while (HalQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP)
;
HalpSetCMOS (0, INT_BCD(Time->Second));
HalpSetCMOS (2, INT_BCD(Time->Minute));
HalpSetCMOS (4, INT_BCD(Time->Hour));
HalpSetCMOS (6, INT_BCD(Time->Weekday));
HalpSetCMOS (7, INT_BCD(Time->Day));
HalpSetCMOS (8, INT_BCD(Time->Month));
HalpSetCMOS (9, INT_BCD(Time->Year % 100));
HalSetCMOS (0, INT_BCD(Time->Second));
HalSetCMOS (2, INT_BCD(Time->Minute));
HalSetCMOS (4, INT_BCD(Time->Hour));
HalSetCMOS (6, INT_BCD(Time->Weekday));
HalSetCMOS (7, INT_BCD(Time->Day));
HalSetCMOS (8, INT_BCD(Time->Month));
HalSetCMOS (9, INT_BCD(Time->Year % 100));
#if 0
/* Century */
HalpSetCMOS (RTC_REGISTER_CENTURY, INT_BCD(Time->Year / 100));
HalSetCMOS (RTC_REGISTER_CENTURY, INT_BCD(Time->Year / 100));
#endif
}
@@ -174,7 +140,7 @@ HalGetEnvironmentVariable(PCH Name,
return FALSE;
}
if (HalpQueryCMOS(RTC_REGISTER_B) & 0x01)
if (HalQueryCMOS(RTC_REGISTER_B) & 0x01)
{
strncpy(Value, "FALSE", ValueLength);
}
@@ -191,117 +157,27 @@ BOOLEAN STDCALL
HalSetEnvironmentVariable(PCH Name,
PCH Value)
{
UCHAR Val;
UCHAR Val;
if (_stricmp(Name, "LastKnownGood") != 0)
return FALSE;
if (_stricmp(Name, "LastKnownGood") != 0)
{
return FALSE;
}
Val = HalpQueryCMOS(RTC_REGISTER_B);
Val = HalQueryCMOS(RTC_REGISTER_B);
if (_stricmp(Value, "TRUE") == 0)
HalpSetCMOS(RTC_REGISTER_B, Val | 0x01);
else if (_stricmp(Value, "FALSE") == 0)
HalpSetCMOS(RTC_REGISTER_B, Val & ~0x01);
else
return FALSE;
if (_stricmp(Value, "TRUE") == 0)
{
HalSetCMOS(RTC_REGISTER_B, Val | 0x01);
}
else if (_stricmp(Value, "FALSE") == 0)
{
HalSetCMOS(RTC_REGISTER_B, Val & ~0x01);
}
else
{
return FALSE;
}
return TRUE;
}
ULONG STDCALL
HalpGetCmosData(PBUS_HANDLER BusHandler,
ULONG BusNumber,
ULONG SlotNumber,
PVOID Buffer,
ULONG Offset,
ULONG Length)
{
PUCHAR Ptr = Buffer;
ULONG Address = SlotNumber;
ULONG Len = Length;
DPRINT("HalpGetCmosData() called.\n");
DPRINT(" BusNumber %lu\n", BusNumber);
DPRINT(" SlotNumber %lu\n", SlotNumber);
DPRINT(" Offset 0x%lx\n", Offset);
DPRINT(" Length 0x%lx\n", Length);
if (Length == 0)
return 0;
if (BusNumber == 0)
{
/* CMOS */
while ((Len > 0) && (Address < 0x100))
{
*Ptr = HalpQueryCMOS((UCHAR)Address);
Ptr = Ptr + 1;
Address++;
Len--;
}
}
else if (BusNumber == 1)
{
/* Extended CMOS */
while ((Len > 0) && (Address < 0x1000))
{
*Ptr = HalpQueryECMOS((USHORT)Address);
Ptr = Ptr + 1;
Address++;
Len--;
}
}
return(Length - Len);
}
ULONG STDCALL
HalpSetCmosData(PBUS_HANDLER BusHandler,
ULONG BusNumber,
ULONG SlotNumber,
PVOID Buffer,
ULONG Offset,
ULONG Length)
{
PUCHAR Ptr = (PUCHAR)Buffer;
ULONG Address = SlotNumber;
ULONG Len = Length;
DPRINT("HalpSetCmosData() called.\n");
DPRINT(" BusNumber %lu\n", BusNumber);
DPRINT(" SlotNumber %lu\n", SlotNumber);
DPRINT(" Offset 0x%lx\n", Offset);
DPRINT(" Length 0x%lx\n", Length);
if (Length == 0)
return 0;
if (BusNumber == 0)
{
/* CMOS */
while ((Len > 0) && (Address < 0x100))
{
HalpSetCMOS((UCHAR)Address, *Ptr);
Ptr = Ptr + 1;
Address++;
Len--;
}
}
else if (BusNumber == 1)
{
/* Extended CMOS */
while ((Len > 0) && (Address < 0x1000))
{
HalpSetECMOS((USHORT)Address, *Ptr);
Ptr = Ptr + 1;
Address++;
Len--;
}
}
return(Length - Len);
}
/* EOF */

View File

@@ -99,23 +99,6 @@ HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
PULONG AddressSpace,
PPHYSICAL_ADDRESS TranslatedAddress);
/* time.c */
ULONG STDCALL
HalpGetCmosData(PBUS_HANDLER BusHandler,
ULONG BusNumber,
ULONG SlotNumber,
PVOID Buffer,
ULONG Offset,
ULONG Length);
ULONG STDCALL
HalpSetCmosData(PBUS_HANDLER BusHandler,
ULONG BusNumber,
ULONG SlotNumber,
PVOID Buffer,
ULONG Offset,
ULONG Length);
#endif /* __INTERNAL_HAL_BUS_H */
/* EOF */

View File

@@ -1,45 +0,0 @@
/*
*
*/
#ifndef __INTERNAL_HAL_HAL_H
#define __INTERNAL_HAL_HAL_H
#include <ddk/service.h>
#include <internal/ntoskrnl.h>
/*
* FUNCTION: Probes for a BIOS32 extension
*/
VOID Hal_bios32_probe(VOID);
/*
* FUNCTION: Determines if a a bios32 service is present
*/
BOOLEAN Hal_bios32_is_service_present(ULONG service);
VOID HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID HalResetDisplay (VOID);
VOID HalpInitBusHandlers (VOID);
/* irql.c */
VOID HalpInitPICs(VOID);
/* udelay.c */
VOID HalpCalibrateStallExecution(VOID);
/* pci.c */
VOID HalpInitPciBus (VOID);
struct _ADAPTER_OBJECT {
int Channel;
PVOID PagePort;
PVOID CountPort;
PVOID OffsetPort;
KSPIN_LOCK SpinLock;
PVOID Buffer;
BOOLEAN Inuse;
};
#endif /* __INTERNAL_HAL_HAL_H */

View File

@@ -6,7 +6,7 @@
HOST = mingw32-windows
# uncomment if you use bochs and it displays only 30 rows
#BOCHS_30ROWS = yes
# BOCHS_30ROWS = yes
ifeq ($(HOST),mingw32-linux)
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
@@ -73,8 +73,6 @@ RC = $(PREFIX)windres
RCINC = --include-dir $(PATH_TO_TOP)/include
OBJCOPY = $(PREFIX)objcopy
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.cc
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.c

View File

@@ -1,4 +1,4 @@
/* $Id: conio.c,v 1.22 2001/07/31 20:47:44 ea Exp $
/* $Id: conio.c,v 1.20 2001/07/30 11:56:54 ea Exp $
*
* reactos/subsys/csrss/api/conio.c
*
@@ -224,15 +224,28 @@ NTSTATUS CsrReadConsole(PCSRSS_PROCESS_DATA ProcessData,
(b)->Buffer[(o)++]=(c);\
(b)->Buffer[(o)++]=(a);
static DWORD FASTCALL
ComputeOffsetBuffer (
PCSRSS_SCREEN_BUFFER Buff,
DWORD LogicalX,
DWORD LogicalY
)
{
/* 2 == sizeof (cell) */
return (2 * ((LogicalY * Buff->MaxX) + LogicalX));
}
static VOID FASTCALL
ClearLineBuffer (
PCSRSS_SCREEN_BUFFER Buff,
DWORD StartX
DWORD StartX,
DWORD StopX
)
{
DWORD Offset = 2 * ((Buff->CurrentY * Buff->MaxX) + StartX);
DWORD LogicalX = StartX;
DWORD Offset = ComputeOffsetBuffer (Buff, LogicalX, Buff->CurrentY);
for ( ; StartX < Buff->MaxX; StartX ++ )
for ( ; LogicalX < StopX; LogicalX ++ )
{
/* Fill the cell: Offset is incremented by the macro */
SET_CELL_BUFFER(Buff,Offset,' ',Buff->DefaultAttrib)
@@ -261,10 +274,10 @@ NTSTATUS CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length
{
Buff->CurrentY = 0;
}
ClearLineBuffer (Buff, 0);
ClearLineBuffer (Buff, 0, Buff->MaxX);
break;
/* --- BS --- */
case '\b':
case '\b': {
if( Buff->CurrentX == 0 )
{
/* slide viewable screen up */
@@ -284,20 +297,13 @@ NTSTATUS CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length
}
else
Buff->CurrentX--;
Offset = 2 * ((Buff->CurrentY * Buff->MaxX) + Buff->CurrentX);
Offset = ComputeOffsetBuffer (Buff, Buff->CurrentX, Buff->CurrentY);
SET_CELL_BUFFER(Buff,Offset,' ',Buff->DefaultAttrib);
break;
/* --- CR --- */
case '\r':
Buff->CurrentX = 0;
break;
/* --- TAB --- */
case '\t':
CsrpWriteConsole(Buff, " ", (8 - (Buff->CurrentX % 8)), Attrib);
break;
}
/* --- */
default:
Offset = 2 * (((Buff->CurrentY * Buff->MaxX)) + Buff->CurrentX);
Offset = ComputeOffsetBuffer (Buff, Buff->CurrentX, Buff->CurrentY);
Buff->Buffer[Offset ++] = Buffer[ i ];
if( Attrib )
Buff->Buffer[Offset] = Buff->DefaultAttrib;
@@ -311,11 +317,11 @@ NTSTATUS CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length
/* if end of buffer, wrap back to beginning */
Buff->CurrentY = 0;
/* clear new line */
ClearLineBuffer (Buff, 0);
ClearLineBuffer (Buff, 0, Buff->MaxX);
}
else {
/* clear new line */
ClearLineBuffer (Buff, 0);
ClearLineBuffer (Buff, 0, Buff->MaxX);
}
/* slide the viewable screen */
if( (Buff->CurrentY - Buff->ShowY) == PhysicalConsoleSize.Y )
@@ -376,7 +382,7 @@ NTSTATUS CsrInitConsoleScreenBuffer( PCSRSS_SCREEN_BUFFER Console )
/* initialize buffer to be empty with default attributes */
for( ; Console->CurrentY < Console->MaxY; Console->CurrentY++ )
{
ClearLineBuffer (Console, 0);
ClearLineBuffer (Console, 0, Console->MaxX);
}
Console->CursorInfo.bVisible = TRUE;
Console->CursorInfo.dwSize = 5;

View File

@@ -1,87 +0,0 @@
#
# Global makefile for the ROSAPPS package
#
#
# Select your host
#
#HOST = djgpp-msdos
HOST = mingw32-windows
include rules.mak
#
# Available applications
#
APPS = cmd cmdutils notevil sysutils dflat32
all: $(APPS)
.PHONY: all
clean: $(APPS:%=%_clean)
.PHONY: clean
floppy: make_floppy_dirs $(APPS:%=%_floppy)
dist: clean_dist_dir make_dist_dirs $(APPS:%=%_dist)
.PHONY: dist
#
# Applications
#
$(APPS): %:
make -C $*
$(APPS:%=%_clean): %_clean:
make -C $* clean
$(APPS:%=%_floppy): %_floppy:
make -C $* floppy
$(APPS:%=%_dist): %_dist:
make -C $* dist
.PHONY: $(APPS) $(APPS:%=%_clean) $(APPS:%=%_floppy) $(APPS:%=%_dist)
#
# Make an install floppy
#
install: all
./install.sh /mnt/hda1
make_floppy_dirs:
ifeq ($(DOSCLI),yes)
mkdir $(FLOPPY_DIR)\apps
else
mkdir $(FLOPPY_DIR)/apps
endif
.PHONY: make_floppy_dirs
#
# Make a distribution saveset
#
clean_dist_dir:
ifeq ($(DOSCLI),yes)
# $(RM) $(DIST_DIR)\apps\*.*
# $(RMDIR) $(DIST_DIR)\apps
# $(RMDIR) $(DIST_DIR)
else
$(RM) -r $(DIST_DIR)
endif
make_dist_dirs:
ifeq ($(DOSCLI),yes)
mkdir $(DIST_DIR)
mkdir $(DIST_DIR)\apps
else
mkdir $(DIST_DIR)
mkdir $(DIST_DIR)/apps
endif
.PHONY: clean_dist_dir make_dist_dirs
# EOF

View File

@@ -1 +0,0 @@
cmd.coff

View File

@@ -1,356 +0,0 @@
/*
* ALIAS.C - alias administration module.
*
*
* History:
*
* 02/02/1996 (Oliver Mueller)
* started.
*
* 02/03/1996 (Oliver Mueller)
* Added sorting algorithm and case sensitive substitution by using
* partstrupr().
*
* 27 Jul 1998 John P. Price
* added config.h include
* added ifdef's to disable aliases
*
* 09-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Fixed crash when removing an alias in DeleteAlias().
* Added help text ("/?").
*
* 14-Jan-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Clean up and Unicode safe!
*
* 24-Jan-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Redirection safe!
*/
#include "config.h"
#ifdef FEATURE_ALIASES
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "cmd.h"
typedef struct tagALIAS
{
struct tagALIAS *next;
LPTSTR lpName;
LPTSTR lpSubst;
DWORD dwUsed;
} ALIAS, *LPALIAS;
static LPALIAS lpFirst = NULL;
static LPALIAS lpLast = NULL;
static DWORD dwUsed = 0;
/* module internal functions */
/* strlwr only for first word in string */
static VOID
partstrlwr (LPTSTR str)
{
LPTSTR c = str;
while (*c && !_istspace (*c) && *c != _T('='))
{
*c = _totlower (*c);
c++;
}
}
static VOID
PrintAlias (VOID)
{
LPALIAS ptr = lpFirst;
while (ptr)
{
ConOutPrintf (_T("%s=%s\n"), ptr->lpName, ptr->lpSubst);
ptr = ptr->next;
}
}
static VOID
DeleteAlias (LPTSTR pszName)
{
LPALIAS ptr = lpFirst;
LPALIAS prev = NULL;
while (ptr)
{
if (!_tcsicmp (ptr->lpName, pszName))
{
if (prev)
prev->next = ptr->next;
else
lpFirst = ptr->next;
free (ptr->lpName);
free (ptr->lpSubst);
free (ptr);
return;
}
prev = ptr;
ptr = ptr->next;
}
}
static VOID
AddAlias (LPTSTR name, LPTSTR subst)
{
LPALIAS ptr = lpFirst;
LPALIAS prev, entry;
LPTSTR s;
while (ptr)
{
if (!_tcsicmp (ptr->lpName, name))
{
s = (LPTSTR)malloc ((_tcslen (subst) + 1)*sizeof(TCHAR));
if (!s)
{
error_out_of_memory ();
return;
}
free (ptr->lpSubst);
ptr->lpSubst = s;
_tcscpy (ptr->lpSubst, subst);
return;
}
ptr = ptr->next;
}
ptr = (LPALIAS)malloc (sizeof (ALIAS));
if (!ptr)
return;
ptr->next = 0;
ptr->lpName = (LPTSTR)malloc ((_tcslen (name) + 1)*sizeof(TCHAR));
if (!ptr->lpName)
{
error_out_of_memory ();
free (ptr);
return;
}
_tcscpy (ptr->lpName, name);
ptr->lpSubst = (LPTSTR)malloc ((_tcslen (subst) + 1)*sizeof(TCHAR));
if (!ptr->lpSubst)
{
error_out_of_memory ();
free (ptr->lpName);
free (ptr);
return;
}
_tcscpy (ptr->lpSubst, subst);
/* it's necessary for recursive substitution */
partstrlwr (ptr->lpSubst);
ptr->dwUsed = 0;
/* Alias table must be sorted!
* Here a little example:
* command line = "ls -c"
* If the entries are
* ls=dir
* ls -c=ls /w
* command line will be expanded to "dir -c" which is not correct.
* If the entries are sortet as
* ls -c=ls /w
* ls=dir
* it will be expanded to "dir /w" which is a valid DOS command.
*/
entry = lpFirst;
prev = 0;
while (entry)
{
if (_tcsicmp (ptr->lpName, entry->lpName) > 0)
{
if (prev)
{
prev->next = ptr;
ptr->next = entry;
}
else
{
ptr->next = entry;
lpFirst = ptr;
}
return;
}
prev = entry;
entry = entry->next;
}
/* The new entry is the smallest (or the first) and must be
* added to the end of the list.
*/
if (!lpFirst)
lpFirst = ptr;
else
lpLast->next = ptr;
lpLast = ptr;
return;
}
VOID InitializeAlias (VOID)
{
lpFirst = NULL;
lpLast = NULL;
dwUsed = 0;
}
VOID DestroyAlias (VOID)
{
if (lpFirst == NULL)
return;
while (lpFirst->next != NULL)
{
lpLast = lpFirst;
lpFirst = lpLast->next;
free (lpLast->lpName);
free (lpLast->lpSubst);
free (lpLast);
}
free (lpFirst->lpName);
free (lpFirst->lpSubst);
free (lpFirst);
lpFirst = NULL;
lpLast = NULL;
dwUsed = 0;
}
/* specified routines */
VOID ExpandAlias (LPTSTR cmd, INT maxlen)
{
unsigned n = 0,
m,
i,
len;
short d = 1;
LPALIAS ptr = lpFirst;
dwUsed++;
if (dwUsed == 0)
{
while (ptr)
ptr->dwUsed = 0;
ptr = lpFirst;
dwUsed = 1;
}
/* skipping white spaces */
while (_istspace (cmd[n]))
n++;
partstrlwr (&cmd[n]);
if (!_tcsncmp (&cmd[n], _T("NOALIAS"), 7) &&
(_istspace (cmd[n + 7]) || cmd[n + 7] == _T('\0')))
{
memmove (cmd, &cmd[n + 7], (_tcslen (&cmd[n + 7]) + 1) * sizeof (TCHAR));
return;
}
/* substitution loop */
while (d)
{
d = 0;
while (ptr)
{
len = _tcslen (ptr->lpName);
if (!_tcsncmp (&cmd[n], ptr->lpName, len) &&
(_istspace (cmd[n + len]) || cmd[n + len] == _T('\0')) &&
ptr->dwUsed != dwUsed)
{
m = _tcslen (ptr->lpSubst);
if ((int)(_tcslen (cmd) - len + m - n) > maxlen)
{
ConErrPrintf (_T("Command line too long after alias expansion!\n"));
/* the parser won't cause any problems with an empty line */
cmd[0] = _T('\0');
}
else
{
memmove (&cmd[m], &cmd[n + len], (_tcslen(&cmd[n + len]) + 1) * sizeof (TCHAR));
for (i = 0; i < m; i++)
cmd[i] = ptr->lpSubst[i];
ptr->dwUsed = dwUsed;
/* whitespaces are removed! */
n = 0;
d = 1;
}
}
ptr = ptr->next;
}
}
}
INT CommandAlias (LPTSTR cmd, LPTSTR param)
{
LPTSTR ptr;
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Sets, removes or shows aliases.\n"
"\n"
"ALIAS [alias=[command]]\n"
"\n"
" alias Name for an alias.\n"
" command Text to be substituted for an alias.\n"
"\n"
// "For example:\n"
"To list all aliases:\n"
" ALIAS\n\n"
"To set a new or replace an existing alias:\n"
" ALIAS da=dir a:\n\n"
"To remove an alias from the alias list:\n"
" ALIAS da="
// "Type ALIAS without a parameter to display the alias list.\n"
));
return 0;
}
if (param[0] == _T('\0'))
{
PrintAlias ();
return 0;
}
/* error if no '=' found */
if ((ptr = _tcschr (param, _T('='))) == 0)
return 1;
/* Split rest into name and substitute */
*ptr++ = _T('\0');
partstrlwr (param);
if (ptr[0] == _T('\0'))
DeleteAlias (param);
else
AddAlias (param, ptr);
return 0;
}
#endif

View File

@@ -1,356 +0,0 @@
/*
* ATTRIB.C - attrib internal command.
*
*
* History:
*
* 04-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* started
*
* 09-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* implementation works, except recursion ("attrib /s").
*
* 05-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* major rewrite.
* fixed recursion ("attrib /s").
* started directory support ("attrib /s /d").
* updated help text.
*
* 14-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode ready!
*
* 19-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Redirection ready!
*
* 21-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added check for invalid filenames.
*
* 23-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added handling of multiple filenames.
*/
#include "config.h"
#ifdef INCLUDE_CMD_ATTRIB
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <ctype.h>
#include "cmd.h"
static VOID
PrintAttribute (LPTSTR pszPath, LPTSTR pszFile, BOOL bRecurse)
{
WIN32_FIND_DATA findData;
HANDLE hFind;
TCHAR szFullName[MAX_PATH];
LPTSTR pszFileName;
/* prepare full file name buffer */
_tcscpy (szFullName, pszPath);
pszFileName = szFullName + _tcslen (szFullName);
/* display all subdirectories */
if (bRecurse)
{
/* append file name */
_tcscpy (pszFileName, pszFile);
hFind = FindFirstFile (szFullName, &findData);
if (hFind == INVALID_HANDLE_VALUE)
{
ErrorMessage (GetLastError (), pszFile);
return;
}
do
{
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
continue;
if (!_tcscmp (findData.cFileName, _T(".")) ||
!_tcscmp (findData.cFileName, _T("..")))
continue;
_tcscpy (pszFileName, findData.cFileName);
_tcscat (pszFileName, _T("\\"));
PrintAttribute (szFullName, pszFile, bRecurse);
}
while (FindNextFile (hFind, &findData));
FindClose (hFind);
}
/* append file name */
_tcscpy (pszFileName, pszFile);
/* display current directory */
hFind = FindFirstFile (szFullName, &findData);
if (hFind == INVALID_HANDLE_VALUE)
{
ErrorMessage (GetLastError (), pszFile);
return;
}
do
{
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue;
_tcscpy (pszFileName, findData.cFileName);
ConOutPrintf (_T("%c %c%c%c %s\n"),
(findData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ? _T('A') : _T(' '),
(findData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? _T('S') : _T(' '),
(findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? _T('H') : _T(' '),
(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? _T('R') : _T(' '),
szFullName);
}
while (FindNextFile (hFind, &findData));
FindClose (hFind);
}
static VOID
ChangeAttribute (LPTSTR pszPath, LPTSTR pszFile, DWORD dwMask,
DWORD dwAttrib, BOOL bRecurse, BOOL bDirectories)
{
WIN32_FIND_DATA findData;
HANDLE hFind;
DWORD dwAttribute;
TCHAR szFullName[MAX_PATH];
LPTSTR pszFileName;
/* prepare full file name buffer */
_tcscpy (szFullName, pszPath);
pszFileName = szFullName + _tcslen (szFullName);
/* change all subdirectories */
if (bRecurse)
{
/* append file name */
_tcscpy (pszFileName, _T("*.*"));
hFind = FindFirstFile (szFullName, &findData);
if (hFind == INVALID_HANDLE_VALUE)
{
ErrorMessage (GetLastError (), pszFile);
return;
}
do
{
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (!_tcscmp (findData.cFileName, _T(".")) ||
!_tcscmp (findData.cFileName, _T("..")))
continue;
_tcscpy (pszFileName, findData.cFileName);
_tcscat (pszFileName, _T("\\"));
ChangeAttribute (szFullName, pszFile, dwMask,
dwAttrib, bRecurse, bDirectories);
}
}
while (FindNextFile (hFind, &findData));
FindClose (hFind);
}
/* append file name */
_tcscpy (pszFileName, pszFile);
hFind = FindFirstFile (szFullName, &findData);
if (hFind == INVALID_HANDLE_VALUE)
{
ErrorMessage (GetLastError (), pszFile);
return;
}
do
{
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue;
_tcscpy (pszFileName, findData.cFileName);
dwAttribute = GetFileAttributes (szFullName);
if (dwAttribute != 0xFFFFFFFF)
{
dwAttribute = (dwAttribute & ~dwMask) | dwAttrib;
SetFileAttributes (szFullName, dwAttribute);
}
}
while (FindNextFile (hFind, &findData));
FindClose (hFind);
}
INT CommandAttrib (LPTSTR cmd, LPTSTR param)
{
LPTSTR *arg;
INT argc, i;
TCHAR szPath[MAX_PATH];
TCHAR szFileName [MAX_PATH];
BOOL bRecurse = FALSE;
BOOL bDirectories = FALSE;
DWORD dwAttrib = 0;
DWORD dwMask = 0;
/* initialize strings */
szPath[0] = _T('\0');
szFileName[0] = _T('\0');
/* print help */
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Displays or changes file attributes.\n\n"
"ATTRIB [+R | -R] [+A | -A] [+S | -S] [+H | -H] file ...\n"
" [/S [/D]]\n\n"
" + Sets an attribute\n"
" - Clears an attribute\n"
" R Read-only file attribute\n"
" A Archive file attribute\n"
" S System file attribute\n"
" H Hidden file attribute\n"
" /S Processes matching files in the current directory\n"
" and all subdirectories\n"
" /D Processes direcories as well\n\n"
"Type ATTRIB without a parameter to display the attributes of all files."));
return 0;
}
/* build parameter array */
arg = split (param, &argc);
/* check for options */
for (i = 0; i < argc; i++)
{
if (_tcsicmp (arg[i], _T("/s")) == 0)
bRecurse = TRUE;
else if (_tcsicmp (arg[i], _T("/d")) == 0)
bDirectories = TRUE;
}
/* create attributes and mask */
for (i = 0; i < argc; i++)
{
if (*arg[i] == _T('+'))
{
if (_tcslen (arg[i]) != 2)
{
error_invalid_parameter_format (arg[i]);
freep (arg);
return -1;
}
switch ((TCHAR)_totupper (arg[i][1]))
{
case _T('A'):
dwMask |= FILE_ATTRIBUTE_ARCHIVE;
dwAttrib |= FILE_ATTRIBUTE_ARCHIVE;
break;
case _T('H'):
dwMask |= FILE_ATTRIBUTE_HIDDEN;
dwAttrib |= FILE_ATTRIBUTE_HIDDEN;
break;
case _T('R'):
dwMask |= FILE_ATTRIBUTE_READONLY;
dwAttrib |= FILE_ATTRIBUTE_READONLY;
break;
case _T('S'):
dwMask |= FILE_ATTRIBUTE_SYSTEM;
dwAttrib |= FILE_ATTRIBUTE_SYSTEM;
break;
default:
error_invalid_parameter_format (arg[i]);
freep (arg);
return -1;
}
}
else if (*arg[i] == _T('-'))
{
if (_tcslen (arg[i]) != 2)
{
error_invalid_parameter_format (arg[i]);
freep (arg);
return -1;
}
switch ((TCHAR)_totupper (arg[i][1]))
{
case _T('A'):
dwMask |= FILE_ATTRIBUTE_ARCHIVE;
dwAttrib &= ~FILE_ATTRIBUTE_ARCHIVE;
break;
case _T('H'):
dwMask |= FILE_ATTRIBUTE_HIDDEN;
dwAttrib &= ~FILE_ATTRIBUTE_HIDDEN;
break;
case _T('R'):
dwMask |= FILE_ATTRIBUTE_READONLY;
dwAttrib &= ~FILE_ATTRIBUTE_READONLY;
break;
case _T('S'):
dwMask |= FILE_ATTRIBUTE_SYSTEM;
dwAttrib &= ~FILE_ATTRIBUTE_SYSTEM;
break;
default:
error_invalid_parameter_format (arg[i]);
freep (arg);
return -1;
}
}
}
if (argc == 0)
{
DWORD len;
len = GetCurrentDirectory (MAX_PATH, szPath);
if (szPath[len-1] != _T('\\'))
{
szPath[len] = _T('\\');
szPath[len + 1] = 0;
}
_tcscpy (szFileName, _T("*.*"));
PrintAttribute (szPath, szFileName, bRecurse);
freep (arg);
return 0;
}
/* get full file name */
for (i = 0; i < argc; i++)
{
if ((*arg[i] != _T('+')) && (*arg[i] != _T('-')) && (*arg[i] != _T('/')))
{
LPTSTR p;
GetFullPathName (arg[i], MAX_PATH, szPath, NULL);
p = _tcsrchr (szPath, _T('\\')) + 1;
_tcscpy (szFileName, p);
*p = _T('\0');
if (dwMask == 0)
PrintAttribute (szPath, szFileName, bRecurse);
else
ChangeAttribute (szPath, szFileName, dwMask,
dwAttrib, bRecurse, bDirectories);
}
}
freep (arg);
return 0;
}
#endif /* INCLUDE_CMD_ATTRIB */

View File

@@ -1,450 +0,0 @@
/* $Id: batch.c,v 1.4 2001/02/28 22:33:23 ekohl Exp $
*
* BATCH.C - batch file processor for CMD.EXE.
*
*
* History:
*
* ??/??/?? (Evan Jeffrey)
* started.
*
* 15 Jul 1995 (Tim Norman)
* modes and bugfixes.
*
* 08 Aug 1995 (Matt Rains)
* i have cleaned up the source code. changes now bring this
* source into guidelines for recommended programming practice.
*
* i have added some constants to help making changes easier.
*
* 29 Jan 1996 (Steffan Kaiser)
* made a few cosmetic changes
*
* 05 Feb 1996 (Tim Norman)
* changed to comply with new first/rest calling scheme
*
* 14 Jun 1997 (Steffen Kaiser)
* bug fixes. added error level expansion %?. ctrl-break handling
*
* 16 Jul 1998 (Hans B Pufal)
* Totally reorganised in conjunction with COMMAND.C (cf) to
* implement proper BATCH file nesting and other improvements.
*
* 16 Jul 1998 (John P Price <linux-guru@gcfl.net>)
* Seperated commands into individual files.
*
* 19 Jul 1998 (Hans B Pufal) [HBP_001]
* Preserve state of echo flag across batch calls.
*
* 19 Jul 1998 (Hans B Pufal) [HBP_002]
* Implementation of FOR command
*
* 20-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added error checking after malloc calls
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 02-Aug-1998 (Hans B Pufal) [HBP_003]
* Fixed bug in ECHO flag restoration at exit from batch file
*
* 26-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Replaced CRT io functions by Win32 io functions.
* Unicode safe!
*
* 23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.es>)
* Fixes made to get "for" working.
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmd.h"
#include "batch.h"
/* The stack of current batch contexts.
* NULL when no batch is active
*/
LPBATCH_CONTEXT bc = NULL;
BOOL bEcho = TRUE; /* The echo flag */
/* Buffer for reading Batch file lines */
TCHAR textline[BATCH_BUFFSIZE];
/*
* Returns a pointer to the n'th parameter of the current batch file.
* If no such parameter exists returns pointer to empty string.
* If no batch file is current, returns NULL
*
*/
LPTSTR FindArg (INT n)
{
LPTSTR pp;
#ifdef _DEBUG
DebugPrintf ("FindArg: (%d)\n", n);
#endif
if (bc == NULL)
return NULL;
n += bc->shiftlevel;
pp = bc->params;
/* Step up the strings till we reach the end */
/* or the one we want */
while (*pp && n--)
pp += _tcslen (pp) + 1;
return pp;
}
/*
* Batch_params builds a parameter list in newlay allocated memory.
* The parameters consist of null terminated strings with a final
* NULL character signalling the end of the parameters.
*
*/
LPTSTR BatchParams (LPTSTR s1, LPTSTR s2)
{
LPTSTR dp = (LPTSTR)malloc ((_tcslen(s1) + _tcslen(s2) + 3) * sizeof (TCHAR));
/* JPP 20-Jul-1998 added error checking */
if (dp == NULL)
{
error_out_of_memory();
return NULL;
}
if (s1 && *s1)
{
s1 = stpcpy (dp, s1);
*s1++ = _T('\0');
}
else
s1 = dp;
while (*s2)
{
if (_istspace (*s2) || _tcschr (_T(",;"), *s2))
{
*s1++ = _T('\0');
s2++;
while (*s2 && _tcschr (_T(" ,;"), *s2))
s2++;
continue;
}
if ((*s2 == _T('"')) || (*s2 == _T('\'')))
{
TCHAR st = *s2;
do
*s1++ = *s2++;
while (*s2 && (*s2 != st));
}
*s1++ = *s2++;
}
*s1++ = _T('\0');
*s1 = _T('\0');
return dp;
}
/*
* If a batch file is current, exits it, freeing the context block and
* chaining back to the previous one.
*
* If no new batch context is found, sets ECHO back ON.
*
* If the parameter is non-null or not empty, it is printed as an exit
* message
*/
VOID ExitBatch (LPTSTR msg)
{
#ifdef _DEBUG
DebugPrintf ("ExitBatch: (\'%s\')\n", msg);
#endif
if (bc != NULL)
{
LPBATCH_CONTEXT t = bc;
if (bc->hBatchFile)
{
CloseHandle (bc->hBatchFile);
bc->hBatchFile = INVALID_HANDLE_VALUE;
}
if (bc->params)
free(bc->params);
if (bc->forproto)
free(bc->forproto);
if (bc->ffind)
free(bc->ffind);
/* Preserve echo state across batch calls */
bEcho = bc->bEcho;
bc = bc->prev;
free(t);
}
if (msg && *msg)
ConOutPrintf ("%s\n", msg);
}
/*
* Start batch file execution
*
* The firstword parameter is the full filename of the batch file.
*
*/
BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param)
{
HANDLE hFile;
hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
#ifdef _DEBUG
DebugPrintf ("Batch: (\'%s\', \'%s\', \'%s\') hFile = %x\n",
fullname, firstword, param, hFile);
#endif
if (hFile == INVALID_HANDLE_VALUE)
{
ConErrPrintf (_T("Error opening batch file\n"));
return FALSE;
}
/* Kill any and all FOR contexts */
while (bc && bc->forvar)
ExitBatch (NULL);
if (bc == NULL)
{
/* No curent batch file, create a new context */
LPBATCH_CONTEXT n = (LPBATCH_CONTEXT)malloc (sizeof(BATCH_CONTEXT));
if (n == NULL)
{
error_out_of_memory ();
return FALSE;
}
n->prev = bc;
bc = n;
}
else if (bc->hBatchFile != INVALID_HANDLE_VALUE)
{
/* Then we are transferring to another batch */
CloseHandle (bc->hBatchFile);
bc->hBatchFile = INVALID_HANDLE_VALUE;
free (bc->params);
}
bc->hBatchFile = hFile;
bc->bEcho = bEcho; /* Preserve echo across batch calls */
bc->shiftlevel = 0;
bc->ffind = NULL;
bc->forvar = _T('\0');
bc->forproto = NULL;
bc->params = BatchParams (firstword, param);
#ifdef _DEBUG
DebugPrintf ("Batch: returns TRUE\n");
#endif
return TRUE;
}
/*
* Read and return the next executable line form the current batch file
*
* If no batch file is current or no further executable lines are found
* return NULL.
*
* Here we also look out for FOR bcontext structures which trigger the
* FOR expansion code.
*
* Set eflag to 0 if line is not to be echoed else 1
*/
LPTSTR ReadBatchLine (LPBOOL bLocalEcho)
{
LPTSTR first;
LPTSTR ip;
/* No batch */
if (bc == NULL)
return NULL;
#ifdef _DEBUG
DebugPrintf ("ReadBatchLine ()\n");
#endif
while (1)
{
/* User halt */
if (CheckCtrlBreak (BREAK_BATCHFILE))
{
while (bc)
ExitBatch (NULL);
return NULL;
}
/* No batch */
if (bc == NULL)
return NULL;
/* If its a FOR context... */
if (bc->forvar)
{
LPTSTR sp = bc->forproto; /* pointer to prototype command */
LPTSTR dp = textline; /* Place to expand protoype */
LPTSTR fv = FindArg (0); /* Next list element */
/* End of list so... */
if ((fv == NULL) || (*fv == _T('\0')))
{
/* just exit this context */
ExitBatch (NULL);
continue;
}
if (_tcscspn (fv, _T("?*")) == _tcslen (fv))
{
/* element is wild file */
bc->shiftlevel++; /* No use it and shift list */
}
else
{
/* Wild file spec, find first (or next) file name */
if (bc->ffind)
{
/* First already done so do next */
fv = FindNextFile (bc->hFind, bc->ffind) ? bc->ffind->cFileName : NULL;
}
else
{
/* For first find, allocate a find first block */
if ((bc->ffind = (LPWIN32_FIND_DATA)malloc (sizeof (WIN32_FIND_DATA))) == NULL)
{
error_out_of_memory();
return NULL;
}
bc->hFind = FindFirstFile (fv, bc->ffind);
fv = !(bc->hFind==INVALID_HANDLE_VALUE) ? bc->ffind->cFileName : NULL;
}
if (fv == NULL)
{
/* Null indicates no more files.. */
free (bc->ffind); /* free the buffer */
bc->ffind = NULL;
bc->shiftlevel++; /* On to next list element */
continue;
}
}
/* At this point, fv points to parameter string */
while (*sp)
{
if ((*sp == _T('%')) && (*(sp + 1) == bc->forvar))
{
/* replace % var */
dp = stpcpy (dp, fv);
sp += 2;
}
else
{
/* Else just copy */
*dp++ = *sp++;
}
}
*dp = _T('\0');
*bLocalEcho = bEcho;
return textline;
}
if (!FileGetString (bc->hBatchFile, textline, sizeof (textline)))
{
#ifdef _DEBUG
DebugPrintf (_T("ReadBatchLine(): Reached EOF!\n"));
#endif
/* End of file.... */
ExitBatch (NULL);
if (bc == NULL)
return NULL;
continue;
}
#ifdef _DEBUG
DebugPrintf (_T("ReadBatchLine(): textline: \'%s\'\n"), textline);
#endif
/* Strip leading spaces and trailing space/control chars */
for (first = textline; _istspace (*first); first++)
;
for (ip = first + _tcslen (first) - 1; _istspace (*ip) || _istcntrl (*ip); ip--)
;
*++ip = _T('\0');
/* ignore labels and empty lines */
if (*first == _T(':') || *first == 0)
continue;
if (*first == _T('@'))
{
/* don't echo this line */
do
first++;
while (_istspace (*first));
*bLocalEcho = 0;
}
else
*bLocalEcho = bEcho;
break;
}
return first;
}
/* EOF */

View File

@@ -1,43 +0,0 @@
/*
* BATCH.H - A structure to preserve the context of a batch file
*
*
*/
#ifndef _BATCH_H_INCLUDED_
#define _BATCH_H_INCLUDED_
typedef struct tagBATCHCONTEXT
{
struct tagBATCHCONTEXT *prev;
LPWIN32_FIND_DATA ffind;
HANDLE hBatchFile;
LPTSTR forproto;
LPTSTR params;
INT shiftlevel;
BOOL bEcho; /* Preserve echo flag across batch calls */
HANDLE hFind; /* Preserve find handle when doing a for */
TCHAR forvar;
} BATCH_CONTEXT, *LPBATCH_CONTEXT;
/* The stack of current batch contexts.
* NULL when no batch is active
*/
extern LPBATCH_CONTEXT bc;
extern BOOL bEcho; /* The echo flag */
#define BATCH_BUFFSIZE 2048
extern TCHAR textline[BATCH_BUFFSIZE]; /* Buffer for reading Batch file lines */
LPTSTR FindArg (INT);
LPTSTR BatchParams (LPTSTR, LPTSTR);
VOID ExitBatch (LPTSTR);
BOOL Batch (LPTSTR, LPTSTR, LPTSTR);
LPTSTR ReadBatchLine (LPBOOL);
#endif /* _BATCH_H_INCLUDED_ */

View File

@@ -1,57 +0,0 @@
/*
* BEEP.C - beep internal command.
*
*
* History:
*
* 16 Jul 1998 (Hans B Pufal)
* started.
*
* 16 Jul 1998 (John P Price)
* Separated commands into individual files.
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 14-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added help text ("beep /?").
* Unicode ready!
*
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Redirection ready!
*/
#include "config.h"
#ifdef INCLUDE_CMD_BEEP
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include "cmd.h"
#include "batch.h"
INT cmd_beep (LPTSTR cmd, LPTSTR param)
{
if (_tcsncmp (param, _T("/?"), 2) == 0)
{
ConOutPuts (_T("Beep the speaker.\n\nBEEP"));
return 0;
}
#if 0
/* check if run in batch mode */
if (bc == NULL)
return 1;
#endif
#ifdef __REACTOS__
Beep (440, 50);
#else
MessageBeep (-1);
#endif
return 0;
}
#endif

View File

@@ -1,15 +0,0 @@
**** Please report bugs to ekohl@rz-online.de! ****
Known bugs in CMD version 0.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o let set work with or without the '=' sign. People like it that way.
(I don't know, if I should really fix this?)
o command.com ignores control-c and control-break, which makes it difficult
to quit typing a long file, among other things
o "alias v = dir" doesn't work because of the spaces.
**** Please report bugs to ekohl@rz-online.de! ****

View File

@@ -1,95 +0,0 @@
/* $Id: call.c,v 1.3 1999/10/03 22:20:33 ekohl Exp $
*
* CALL.C - call internal batch command.
*
*
* History:
*
* 16 Jul 1998 (Hans B Pufal)
* started.
*
* 16 Jul 1998 (John P Price)
* Seperated commands into individual files.
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 04-Aug-1998 (Hans B Pufal)
* added lines to initialize for pointers (HBP004) This fixed the
* lock-up that happened sometimes when calling a batch file from
* another batch file.
*
* 07-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added help text ("call /?") and cleaned up.
*
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode and redirection safe!
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cmd.h"
#include "batch.h"
/*
* Perform CALL command.
*
* Allocate a new batch context and add it to the current chain.
* Call parsecommandline passing in our param string
* If No batch file was opened then remove our newly allocted
* context block.
*/
INT cmd_call (LPTSTR cmd, LPTSTR param)
{
LPBATCH_CONTEXT n = NULL;
#ifdef _DEBUG
DebugPrintf ("cmd_call: (\'%s\',\'%s\')\n", cmd, param);
#endif
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Calls one batch program from another.\n\n"
"CALL [drive:][path]filename [batch-parameter]\n\n"
" batch-parameter Specifies any command-line information required by the\n"
" batch program."));
return 0;
}
n = (LPBATCH_CONTEXT)malloc (sizeof (BATCH_CONTEXT));
if (n == NULL)
{
error_out_of_memory ();
return 1;
}
n->prev = bc;
bc = n;
bc->hBatchFile = INVALID_HANDLE_VALUE;
bc->params = NULL;
bc->shiftlevel = 0;
bc->forvar = 0; /* HBP004 */
bc->forproto = NULL; /* HBP004 */
ParseCommandLine (param);
/* Wasn't a batch file so remove conext */
if (bc->hBatchFile == INVALID_HANDLE_VALUE)
{
bc = bc->prev;
free (n);
}
return 0;
}
/* EOF */

View File

@@ -1,85 +0,0 @@
/*
* CHCP.C - chcp internal command.
*
*
* History:
*
* 23-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Started.
*
*/
#include "config.h"
#ifdef INCLUDE_CMD_CHCP
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <string.h>
#include "cmd.h"
INT CommandChcp (LPTSTR cmd, LPTSTR param)
{
LPTSTR *arg;
INT args;
UINT uOldCodePage;
UINT uNewCodePage;
/* print help */
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Displays or sets the active code page number.\n\n"
"CHCP [nnn]\n\n"
" nnn Specifies the active code page number.\n\n"
"Type CHCP without a parameter to display the active code page number."));
return 0;
}
if (args == 0)
{
/* display active code page number */
ConOutPrintf ("Active code page: %u\n", GetConsoleCP ());
return 0;
}
if (args >= 2)
{
/* too many parameters */
ConErrPrintf ("Invalid parameter format - %s\n", param);
return 1;
}
/* get parameters */
arg = split (param, &args);
/* save old code page */
uOldCodePage = GetConsoleCP ();
uNewCodePage = (UINT)_ttoi (arg[0]);
if (uNewCodePage == 0)
{
ConErrPrintf ("Parameter format incorrect - %s\n", arg[0]);
freep (arg);
return 1;
}
if (!SetConsoleCP (uNewCodePage))
{
ConErrPrintf ("Invalid code page\n");
}
else
{
SetConsoleOutputCP (uNewCodePage);
InitLocale ();
}
freep (arg);
return 0;
}
#endif /* INCLUDE_CMD_CHCP */

View File

@@ -1,331 +0,0 @@
/*
* CHOICE.C - internal command.
*
*
* History:
*
* 12 Aug 1999 (Eric Kohl)
* started.
*
* 01 Sep 1999 (Eric Kohl)
* Fixed help text.
*
* 26 Sep 1999 (Paolo Pantaleo)
* Fixed timeout.
*/
#include "config.h"
#ifdef INCLUDE_CMD_CHOICE
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <tchar.h>
#include "cmd.h"
#include "batch.h"
#define GC_TIMEOUT -1
#define GC_NOKEY 0 //an event occurred but it wasn't a key pressed
#define GC_KEYREAD 1 //a key has been read
static INT
GetCharacterTimeout (LPTCH ch, DWORD dwMilliseconds)
{
//--------------------------------------------
// Get a character from standard input but with a timeout.
// The function will wait a limited amount
// of time, then the function returns GC_TIMEOUT.
//
// dwMilliseconds is the timeout value, that can
// be set to INFINITE, so the function works like
// stdio.h's getchar()
HANDLE hInput;
DWORD dwRead;
INPUT_RECORD lpBuffer;
hInput = GetStdHandle (STD_INPUT_HANDLE);
//if the timeout experied return GC_TIMEOUT
if (WaitForSingleObject (hInput, dwMilliseconds) == WAIT_TIMEOUT)
return GC_TIMEOUT;
//otherwise get the event
ReadConsoleInput (hInput, &lpBuffer, 1, &dwRead);
//if the event is a key pressed
if ((lpBuffer.EventType == KEY_EVENT) &&
(lpBuffer.Event.KeyEvent.bKeyDown == TRUE))
{
//read the key
#ifdef _UNICODE
*ch = lpBuffer.Event.KeyEvent.uChar.UnicodeChar;
#else
*ch = lpBuffer.Event.KeyEvent.uChar.AsciiChar;
#endif
return GC_KEYREAD;
}
//else return no key
return GC_NOKEY;
}
static INT
IsKeyInString (LPTSTR lpString, TCHAR cKey, BOOL bCaseSensitive)
{
LPTCH p = lpString;
INT val = 0;
while (*p)
{
if (bCaseSensitive)
{
if (*p == cKey)
return val;
}
else
{
if (_totlower (*p) == _totlower (cKey))
return val;
}
val++;
p++;
}
return -1;
}
INT
CommandChoice (LPTSTR cmd, LPTSTR param)
{
LPTSTR lpOptions = "YN";
LPTSTR lpText = NULL;
BOOL bNoPrompt = FALSE;
BOOL bCaseSensitive = FALSE;
BOOL bTimeout = FALSE;
INT nTimeout = 0;
TCHAR cDefault = _T('\0');
INPUT_RECORD ir;
LPTSTR p, np;
LPTSTR *arg;
INT argc;
INT i;
INT val;
INT GCret;
TCHAR Ch;
DWORD amount,clk;
if (_tcsncmp (param, _T("/?"), 2) == 0)
{
ConOutPuts (_T("Waits for the user to choose one of a set of choices.\n"
"\n"
"CHOICE [/C[:]choices][/N][/S][/T[:]c,nn][text]\n"
"\n"
" /C[:]choices Specifies allowable keys. Default is YN.\n"
" /N Do not display choices and ? at the end of the prompt string.\n"
" /S Treat choice keys as case sensitive.\n"
" /T[:]c,nn Default choice to c after nn seconds.\n"
" text Prompt string to display.\n"
"\n"
"ERRORLEVEL is set to offset of key user presses in choices."));
return 0;
}
/* retrieve text */
p = param;
while (TRUE)
{
if (*p == _T('\0'))
break;
if (*p != _T('/'))
{
lpText = p;
break;
}
np = _tcschr (p, _T(' '));
if (!np)
break;
p = np + 1;
}
/* build parameter array */
arg = split (param, &argc);
/* evaluate arguments */
if (argc > 0)
{
for (i = 0; i < argc; i++)
{
if (_tcsnicmp (arg[i], _T("/c"), 2) == 0)
{
if (arg[i][2] == _T(':'))
lpOptions = &arg[i][3];
else
lpOptions = &arg[i][2];
if (_tcslen (lpOptions) == 0)
{
ConErrPuts (_T("Invalid option. Expected format: /C[:]options"));
freep (arg);
return 1;
}
}
else if (_tcsnicmp (arg[i], _T("/n"), 2) == 0)
{
bNoPrompt = TRUE;
}
else if (_tcsnicmp (arg[i], _T("/s"), 2) == 0)
{
bCaseSensitive = TRUE;
}
else if (_tcsnicmp (arg[i], _T("/t"), 2) == 0)
{
LPTSTR s;
if (arg[i][2] == _T(':'))
{
cDefault = arg[i][3];
s = &arg[i][4];
}
else
{
cDefault = arg[i][2];
s = &arg[i][3];
}
if (*s != _T(','))
{
ConErrPuts (_T("Invalid option. Expected format: /T[:]c,nn"));
freep (arg);
return 1;
}
s++;
nTimeout = _ttoi(s);
bTimeout = TRUE;
}
else if (arg[i][0] == _T('/'))
{
ConErrPrintf (_T("Illegal Option: %s"), arg[i]);
freep (arg);
return 1;
}
}
}
/* print text */
if (lpText)
ConOutPrintf (_T("%s"), lpText);
/* print options */
if (bNoPrompt == FALSE)
{
ConOutPrintf (_T("[%c"), lpOptions[0]);
for (i = 1; (unsigned)i < _tcslen (lpOptions); i++)
ConOutPrintf (_T(",%c"), lpOptions[i]);
ConOutPrintf (_T("]?"));
}
ConInFlush ();
if(!bTimeout)
{
while (TRUE)
{
ConInKey (&ir);
val = IsKeyInString (lpOptions,
#ifdef _UNICODE
ir.Event.KeyEvent.uChar.UnicodeChar,
#else
ir.Event.KeyEvent.uChar.AsciiChar,
#endif /* _UNICODE */
bCaseSensitive);
if (val >= 0)
{
ConOutPrintf (_T("%c\n"), lpOptions[val]);
nErrorLevel = val + 1;
break;
}
Beep (440, 50);
}
freep (arg);
return 0;
}
clk = GetTickCount ();
amount = nTimeout*1000;
loop:
GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk));
switch (GCret)
{
case GC_TIMEOUT:
#ifdef _DEBUG
DebugPrintf (_T("GC_TIMEOUT\n"));
DebugPrintf (_T("elapsed %d msecs\n"), GetTickCount () - clk);
#endif /* _DEBUG */
break;
case GC_NOKEY:
#ifdef _DEBUG
DebugPrintf(_T("GC_NOKEY\n"));
DebugPrintf(_T("elapsed %d msecs\n"), GetTickCount () - clk);
#endif /* _DEBUG */
goto loop;
case GC_KEYREAD:
#ifdef _DEBUG
DebugPrintf(_T("GC_KEYREAD\n"));
DebugPrintf(_T("elapsed %d msecs\n"), GetTickCount () - clk);
DebugPrintf(_T("read %c"), Ch);
#endif /* _DEBUG */
if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1)
{
Beep (440, 50);
goto loop;
}
cDefault=Ch;
break;
}
#ifdef _DEBUG
DebugPrintf(_T("exiting wait loop after %d msecs\n"),
GetTickCount () - clk);
#endif /* _DEBUG */
val = IsKeyInString (lpOptions, cDefault, bCaseSensitive);
ConOutPrintf (_T("%c\n"), lpOptions[val]);
nErrorLevel = val + 1;
freep (arg);
#ifdef _DEBUG
DebugPrintf (_T("ErrorLevel: %d\n"), nErrorLevel);
#endif /* _DEBUG */
return 0;
}
#endif /* INCLUDE_CMD_CHOICE */
/* EOF */

View File

@@ -1,65 +0,0 @@
/*
* CLS.C - clear screen internal command.
*
*
* History:
*
* 07/27/1998 (John P. Price)
* started.
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 04-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Changed to Win32 console app.
*
* 08-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added help text ("/?").
*
* 14-Jan-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode ready!
*
* 20-Jan-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Redirection ready!
*/
#include "config.h"
#ifdef INCLUDE_CMD_CLS
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include "cmd.h"
INT cmd_cls (LPTSTR cmd, LPTSTR param)
{
DWORD dwWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
COORD coPos;
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Clears the screen.\n\nCLS"));
return 0;
}
GetConsoleScreenBufferInfo (hOut, &csbi);
coPos.X = 0;
coPos.Y = 0;
FillConsoleOutputAttribute (hOut, wColor,
(csbi.dwSize.X)*(csbi.dwSize.Y),
coPos, &dwWritten);
FillConsoleOutputCharacter (hOut, _T(' '),
(csbi.dwSize.X)*(csbi.dwSize.Y),
coPos, &dwWritten);
SetConsoleCursorPosition (hOut, coPos);
bIgnoreEcho = TRUE;
return 0;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,415 +0,0 @@
/* $Id: cmd.h,v 1.21 2001/02/03 10:37:51 ekohl Exp $
*
* CMD.H - header file for the modules in CMD.EXE
*
*
* History:
*
* 7-15-95 Tim Norman
* started
*
* 06/29/98 (Rob Lake)
* Moved error messages in here
*
* 07/12/98 (Rob Lake)
* Moved more error messages here.
*
* 30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* Added compile date to version.
*
* 26-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Introduced a new version string.
* Thanks to Emanuele Aliberti!
*/
#ifndef _CMD_H_INCLUDED_
#define _CMD_H_INCLUDED_
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include "cmdver.h"
#ifdef _MSC_VER
#define SHELLVER "Version " CMD_VER " [" __DATE__ ", msc]"
#else
#ifdef __LCC__
#define SHELLVER "Version " CMD_VER " [" __DATE__ ", lcc-win32]"
#else
#define SHELLVER "Version " CMD_VER " [" __DATE__ "]"
#endif
#endif
#define BREAK_BATCHFILE 1
#define BREAK_OUTOFBATCH 2
#define BREAK_INPUT 3
#define BREAK_IGNORE 4
/* define some error messages */
#define NOENVERR "ERROR: no environment"
#define INVALIDDRIVE "ERROR: invalid drive"
#define INVALIDFUNCTION "ERROR: invalid function"
#define ACCESSDENIED "ERROR: access denied"
#define BADENVIROMENT "ERROR: bad enviroment"
#define BADFORMAT "ERROR: bad format"
#define ERROR_E2BIG "ERROR: Argument list too long"
#define ERROR_EINVAL "ERROR: Invalid argument"
#define SHELLINFO "ReactOS Command Line Interpreter"
#define D_ON "on"
#define D_OFF "off"
/* command line buffer length */
#ifdef __REACTOS__
#define CMDLINE_LENGTH 512
#else
#define CMDLINE_LENGTH 8192
//#define CMDLINE_LENGTH 1024
#endif
/* global variables */
extern HANDLE hOut;
extern HANDLE hIn;
extern WORD wColor;
extern WORD wDefColor;
extern BOOL bCtrlBreak;
extern BOOL bIgnoreEcho;
extern BOOL bExit;
extern INT nErrorLevel;
extern SHORT maxx;
extern SHORT maxy;
extern OSVERSIONINFO osvi;
/* Prototypes for ALIAS.C */
VOID InitializeAlias (VOID);
VOID DestroyAlias (VOID);
VOID ExpandAlias (LPTSTR, INT);
INT CommandAlias (LPTSTR, LPTSTR);
/* Prototypes for ATTRIB.C */
INT CommandAttrib (LPTSTR, LPTSTR);
/* Prototypes for BEEP.C */
INT cmd_beep (LPTSTR, LPTSTR);
/* Prototypes for CALL.C */
INT cmd_call (LPTSTR, LPTSTR);
/* Prototypes for CHCP.C */
INT CommandChcp (LPTSTR, LPTSTR);
/* Prototypes for CHOICE.C */
INT CommandChoice (LPTSTR, LPTSTR);
/* Prototypes for CLS.C */
INT cmd_cls (LPTSTR, LPTSTR);
/* Prototypes for CMD.C */
VOID ParseCommandLine (LPTSTR);
VOID AddBreakHandler (VOID);
VOID RemoveBreakHandler (VOID);
/* Prototypes for CMDINPUT.C */
VOID ReadCommand (LPTSTR, INT);
/* Prototypes for CMDTABLE.C */
#define CMD_SPECIAL 1
#define CMD_BATCHONLY 2
#define CMD_HIDE 4
typedef struct tagCOMMAND
{
LPTSTR name;
INT flags;
INT (*func) (LPTSTR, LPTSTR);
} COMMAND, *LPCOMMAND;
extern COMMAND cmds[]; /* The internal command table */
VOID PrintCommandList (VOID);
/* Prototypes for COLOR.C */
VOID SetScreenColor(WORD wArgColor, BOOL bFill);
INT CommandColor (LPTSTR, LPTSTR);
/* Prototypes for CONSOLE.C */
#ifdef _DEBUG
VOID DebugPrintf (LPTSTR, ...);
#endif /* _DEBUG */
VOID ConInDummy (VOID);
VOID ConInDisable (VOID);
VOID ConInEnable (VOID);
VOID ConInFlush (VOID);
VOID ConInKey (PINPUT_RECORD);
VOID ConInString (LPTSTR, DWORD);
VOID ConOutChar (TCHAR);
VOID ConOutPuts (LPTSTR);
VOID ConOutPrintf (LPTSTR, ...);
VOID ConErrChar (TCHAR);
VOID ConErrPuts (LPTSTR);
VOID ConErrPrintf (LPTSTR, ...);
SHORT GetCursorX (VOID);
SHORT GetCursorY (VOID);
VOID GetCursorXY (PSHORT, PSHORT);
VOID SetCursorXY (SHORT, SHORT);
VOID GetScreenSize (PSHORT, PSHORT);
VOID SetCursorType (BOOL, BOOL);
/* Prototypes for COPY.C */
INT cmd_copy (LPTSTR, LPTSTR);
/* Prototypes for DATE.C */
INT cmd_date (LPTSTR, LPTSTR);
/* Prototypes for DEL.C */
INT CommandDelete (LPTSTR, LPTSTR);
/* Prototypes for DELAY.C */
INT CommandDelay (LPTSTR, LPTSTR);
/* Prototypes for DIR.C */
INT CommandDir (LPTSTR, LPTSTR);
/* Prototypes for DIRSTACK.C */
VOID InitDirectoryStack (VOID);
VOID DestroyDirectoryStack (VOID);
INT GetDirectoryStackDepth (VOID);
INT CommandPushd (LPTSTR, LPTSTR);
INT CommandPopd (LPTSTR, LPTSTR);
INT CommandDirs (LPTSTR, LPTSTR);
/* Prototypes for ECHO.C */
INT CommandEcho (LPTSTR, LPTSTR);
INT CommandEchos (LPTSTR, LPTSTR);
INT CommandEchoerr (LPTSTR, LPTSTR);
INT CommandEchoserr (LPTSTR, LPTSTR);
/* Prototypes for ERROR.C */
VOID ErrorMessage (DWORD, LPTSTR, ...);
VOID error_no_pipe (VOID);
VOID error_bad_command (VOID);
VOID error_invalid_drive (VOID);
VOID error_req_param_missing (VOID);
VOID error_sfile_not_found (LPTSTR);
VOID error_file_not_found (VOID);
VOID error_path_not_found (VOID);
VOID error_too_many_parameters (LPTSTR);
VOID error_invalid_switch (TCHAR);
VOID error_invalid_parameter_format (LPTSTR);
VOID error_out_of_memory (VOID);
VOID error_syntax (LPTSTR);
VOID msg_pause (VOID);
/* Prototypes for FILECOMP.C */
#ifdef FEATURE_UNIX_FILENAME_COMPLETION
VOID CompleteFilename (LPTSTR, INT);
INT ShowCompletionMatches (LPTSTR, INT);
#endif
#ifdef FEATURE_4NT_FILENAME_COMPLETION
#endif
/* Prototypes for FOR.C */
INT cmd_for (LPTSTR, LPTSTR);
/* Prototypes for FREE.C */
INT CommandFree (LPTSTR, LPTSTR);
/* Prototypes for GOTO.C */
INT cmd_goto (LPTSTR, LPTSTR);
/* Prototypes for HISTORY.C */
#ifdef FEATURE_HISTORY
VOID History (INT, LPTSTR);/*add entries browse history*/
VOID History_move_to_bottom(VOID);/*F3*/
VOID InitHistory(VOID);
VOID CleanHistory(VOID);
VOID History_del_current_entry(LPTSTR str);/*CTRL-D*/
INT CommandHistory (LPTSTR cmd, LPTSTR param);
#endif
/* Prototypes for INTERNAL.C */
VOID InitLastPath (VOID);
VOID FreeLastPath (VOID);
INT cmd_chdir (LPTSTR, LPTSTR);
INT cmd_mkdir (LPTSTR, LPTSTR);
INT cmd_rmdir (LPTSTR, LPTSTR);
INT CommandExit (LPTSTR, LPTSTR);
INT CommandRem (LPTSTR, LPTSTR);
INT CommandShowCommands (LPTSTR, LPTSTR);
/* Prototypes for LABEL.C */
INT cmd_label (LPTSTR, LPTSTR);
/* Prototypes for LOCALE.C */
extern TCHAR cDateSeparator;
extern INT nDateFormat;
extern TCHAR cTimeSeparator;
extern INT nTimeFormat;
extern TCHAR aszDayNames[7][8];
extern TCHAR cThousandSeparator;
extern TCHAR cDecimalSeparator;
extern INT nNumberGroups;
VOID InitLocale (VOID);
VOID PrintDate (VOID);
VOID PrintTime (VOID);
/* Prototypes for MEMORY.C */
INT CommandMemory (LPTSTR, LPTSTR);
/* Prototypes for MISC.C */
TCHAR cgetchar (VOID);
BOOL CheckCtrlBreak (INT);
LPTSTR *split (LPTSTR, LPINT);
VOID freep (LPTSTR *);
LPTSTR stpcpy (LPTSTR, LPTSTR);
BOOL IsValidPathName (LPCTSTR);
BOOL IsValidFileName (LPCTSTR);
BOOL IsValidDirectory (LPCTSTR);
BOOL FileGetString (HANDLE, LPTSTR, INT);
#ifndef __REACTOS__
HWND GetConsoleWindow(VOID);
#endif
#define PROMPT_NO 0
#define PROMPT_YES 1
#define PROMPT_ALL 2
#define PROMPT_BREAK 3
INT PagePrompt (VOID);
INT FilePromptYN (LPTSTR, ...);
INT FilePromptYNA (LPTSTR, ...);
/* Prototypes for MOVE.C */
INT cmd_move (LPTSTR, LPTSTR);
/* Prototypes for MSGBOX.C */
INT CommandMsgbox (LPTSTR, LPTSTR);
/* Prototypes from PATH.C */
INT cmd_path (LPTSTR, LPTSTR);
/* Prototypes from PROMPT.C */
VOID PrintPrompt (VOID);
INT cmd_prompt (LPTSTR, LPTSTR);
/* Prototypes for REDIR.C */
#define INPUT_REDIRECTION 1
#define OUTPUT_REDIRECTION 2
#define OUTPUT_APPEND 4
#define ERROR_REDIRECTION 8
#define ERROR_APPEND 16
INT GetRedirection (LPTSTR, LPTSTR, LPTSTR, LPTSTR, LPINT);
/* Prototypes for REN.C */
INT cmd_rename (LPTSTR, LPTSTR);
/* Prototypes for SCREEN.C */
INT CommandScreen (LPTSTR, LPTSTR);
/* Prototypes for SET.C */
INT cmd_set (LPTSTR, LPTSTR);
/* Prototypes for START.C */
INT cmd_start (LPTSTR, LPTSTR);
/* Prototypes for STRTOCLR.C */
BOOL StringToColor (LPWORD, LPTSTR *);
/* Prototypes for TIME.C */
INT cmd_time (LPTSTR, LPTSTR);
/* Prototypes for TIMER.C */
INT CommandTimer (LPTSTR cmd, LPTSTR param);
/* Prototypes for TITLE.C */
INT cmd_title (LPTSTR, LPTSTR);
/* Prototypes for TYPE.C */
INT cmd_type (LPTSTR, LPTSTR);
/* Prototypes for VER.C */
VOID ShortVersion (VOID);
INT cmd_ver (LPTSTR, LPTSTR);
/* Prototypes for VERIFY.C */
INT cmd_verify (LPTSTR, LPTSTR);
/* Prototypes for VOL.C */
INT cmd_vol (LPTSTR, LPTSTR);
/* Prototypes for WHERE.C */
BOOL SearchForExecutable (LPCTSTR, LPTSTR);
/* Prototypes for WINDOW.C */
INT CommandActivate (LPTSTR, LPTSTR);
INT CommandWindow (LPTSTR, LPTSTR);
/* The MSDOS Batch Commands [MS-DOS 5.0 User's Guide and Reference p359] */
int cmd_if(char *, char *);
int cmd_pause(char *, char *);
int cmd_shift(char *, char *);
#endif /* _CMD_H_INCLUDED_ */

View File

@@ -1,40 +0,0 @@
#include "../../reactos/include/defines.h"
#include "../../reactos/include/reactos/resource.h"
#include "cmdver.h"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "ReactOS Command Processor\0"
VALUE "FileVersion", CMD_VER_RC
VALUE "InternalName", "cmd\0"
VALUE "OriginalCopyright", "Copyright (C) 1994-1998 Tim Norman and others\0"
VALUE "LegalCopyright", "Copyright (C) 1998-2000 Eric Kohl\0"
VALUE "OriginalFilename", "cmd.exe\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@@ -1,513 +0,0 @@
/*
* CMDINPUT.C - handles command input (tab completion, history, etc.).
*
*
* History:
*
* 01/14/95 (Tim Norman)
* started.
*
* 08/08/95 (Matt Rains)
* i have cleaned up the source code. changes now bring this source
* into guidelines for recommended programming practice.
* i have added some constants to help making changes easier.
*
* 12/12/95 (Tim Norman)
* added findxy() function to get max x/y coordinates to display
* correctly on larger screens
*
* 12/14/95 (Tim Norman)
* fixed the Tab completion code that Matt Rains broke by moving local
* variables to a more global scope and forgetting to initialize them
* when needed
*
* 8/1/96 (Tim Norman)
* fixed a bug in tab completion that caused filenames at the beginning
* of the command-line to have their first letter truncated
*
* 9/1/96 (Tim Norman)
* fixed a silly bug using printf instead of fputs, where typing "%i"
* confused printf :)
*
* 6/14/97 (Steffan Kaiser)
* ctrl-break checking
*
* 6/7/97 (Marc Desrochers)
* recoded everything! now properly adjusts when text font is changed.
* removed findxy(), reposition(), and reprint(), as these functions
* were inefficient. added goxy() function as gotoxy() was buggy when
* the screen font was changed. the printf() problem with %i on the
* command line was fixed by doing printf("%s",str) instead of
* printf(str). Don't ask how I find em just be glad I do :)
*
* 7/12/97 (Tim Norman)
* Note: above changes pre-empted Steffan's ctrl-break checking.
*
* 7/7/97 (Marc Desrochers)
* rewrote a new findxy() because the new dir() used it. This
* findxy() simply returns the values of *maxx *maxy. In the
* future, please use the pointers, they will always be correct
* since they point to BIOS values.
*
* 7/8/97 (Marc Desrochers)
* once again removed findxy(), moved the *maxx, *maxy pointers
* global and included them as externs in command.h. Also added
* insert/overstrike capability
*
* 7/13/97 (Tim Norman)
* added different cursor appearance for insert/overstrike mode
*
* 7/13/97 (Tim Norman)
* changed my code to use _setcursortype until I can figure out why
* my code is crashing on some machines. It doesn't crash on mine :)
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 28-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* put ifdef's around filename completion code.
*
* 30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* moved filename completion code to filecomp.c
* made second TAB display list of filename matches
*
* 31-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* Fixed bug where if you typed something, then hit HOME, then tried
* to type something else in insert mode, it crashed.
*
* 07-Aug-1998 (John P Price <linux-guru@gcfl.net>)
* Fixed carrage return output to better match MSDOS with echo
* on or off.(marked with "JPP 19980708")
*
* 13-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added insert/overwrite cursor.
*
* 25-Jan-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Replaced CRT io functions by Win32 console io functions.
* This can handle <Shift>-<Tab> for 4NT filename completion.
* Unicode and redirection safe!
*
* 04-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Fixed input bug. A "line feed" character remained in the keyboard
* input queue when you pressed <RETURN>. This sometimes caused
* some very strange effects.
* Fixed some command line editing annoyances.
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include "cmd.h"
#include "batch.h"
SHORT maxx;
SHORT maxy;
/*
* global command line insert/overwrite flag
*/
static BOOL bInsert = TRUE;
static VOID
ClearCommandLine (LPTSTR str, INT maxlen, SHORT orgx, SHORT orgy)
{
INT count;
SetCursorXY (orgx, orgy);
for (count = 0; count < (INT)_tcslen (str); count++)
ConOutChar (_T(' '));
_tcsnset (str, _T('\0'), maxlen);
SetCursorXY (orgx, orgy);
}
/* read in a command line */
VOID ReadCommand (LPTSTR str, INT maxlen)
{
SHORT orgx; /* origin x/y */
SHORT orgy;
SHORT curx; /*current x/y cursor position*/
SHORT cury;
INT count; /*used in some for loops*/
INT current = 0; /*the position of the cursor in the string (str)*/
INT charcount = 0;/*chars in the string (str)*/
INPUT_RECORD ir;
WORD wLastKey = 0;
TCHAR ch;
BOOL bContinue=FALSE;/*is TRUE the second case will not be executed*/
/* get screen size */
GetScreenSize (&maxx, &maxy);
/* JPP 19980807 - if echo off, don't print prompt */
if (bEcho)
PrintPrompt();
GetCursorXY (&orgx, &orgy);
memset (str, 0, maxlen * sizeof (TCHAR));
SetCursorType (bInsert, TRUE);
do
{
ConInKey (&ir);
if (ir.Event.KeyEvent.dwControlKeyState &
(RIGHT_ALT_PRESSED|RIGHT_ALT_PRESSED|
RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED) )
{
switch (ir.Event.KeyEvent.wVirtualKeyCode)
{
#ifdef FEATURE_HISTORY
case 'K':
/*add the current command line to the history*/
if (ir.Event.KeyEvent.dwControlKeyState &
(LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
{
if (str[0])
History(0,str);
ClearCommandLine (str, maxlen, orgx, orgy);
current = charcount = 0;
bContinue=TRUE;
break;
}
case 'D':
/*delete current history entry*/
if (ir.Event.KeyEvent.dwControlKeyState &
(LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
{
ClearCommandLine (str, maxlen, orgx, orgy);
History_del_current_entry(str);
current = charcount = _tcslen (str);
ConOutPrintf (_T("%s"), str);
bContinue=TRUE;
break;
}
#endif/*FEATURE_HISTORY*/
}
}
//if (bContinue)
// continue;
switch (ir.Event.KeyEvent.wVirtualKeyCode)
{
case VK_BACK:
/* <BACKSPACE> - delete character to left of cursor */
if (current > 0 && charcount > 0)
{
if (current == charcount)
{
/* if at end of line */
str[current - 1] = _T('\0');
if (GetCursorX () != 0)
{
ConOutPrintf ("\b \b");
}
else
{
SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1));
ConOutChar (_T(' '));
SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1));
}
}
else
{
for (count = current - 1; count < charcount; count++)
str[count] = str[count + 1];
if (GetCursorX () != 0)
SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ());
else
SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1));
GetCursorXY (&curx, &cury);
ConOutPrintf (_T("%s "), &str[current - 1]);
SetCursorXY (curx, cury);
}
charcount--;
current--;
}
break;
case VK_INSERT:
/* toggle insert/overstrike mode */
bInsert ^= TRUE;
SetCursorType (bInsert, TRUE);
break;
case VK_DELETE:
/* delete character under cursor */
if (current != charcount && charcount > 0)
{
for (count = current; count < charcount; count++)
str[count] = str[count + 1];
charcount--;
GetCursorXY (&curx, &cury);
ConOutPrintf (_T("%s "), &str[current]);
SetCursorXY (curx, cury);
}
break;
case VK_HOME:
/* goto beginning of string */
if (current != 0)
{
SetCursorXY (orgx, orgy);
current = 0;
}
break;
case VK_END:
/* goto end of string */
if (current != charcount)
{
SetCursorXY (orgx, orgy);
ConOutPrintf (_T("%s"), str);
current = charcount;
}
break;
case VK_TAB:
#ifdef FEATURE_UNIX_FILENAME_COMPLETION
/* expand current file name */
if (current == charcount) /* only works at end of line*/
{
if (wLastKey != VK_TAB)
{
/* if first TAB, complete filename*/
CompleteFilename (str, charcount);
charcount = _tcslen (str);
current = charcount;
SetCursorXY (orgx, orgy);
ConOutPrintf (_T("%s"), str);
if ((_tcslen (str) > (USHORT)(maxx - orgx)) && (orgy == maxy + 1))
orgy--;
}
else
{
/*if second TAB, list matches*/
if (ShowCompletionMatches (str, charcount))
{
PrintPrompt ();
GetCursorXY (&orgx, &orgy);
ConOutPrintf (_T("%s"), str);
}
}
}
else
{
#ifdef __REACTOS__
Beep (440, 50);
#else
MessageBeep (-1);
#endif
}
#endif
#ifdef FEATURE_4NT_FILENAME_COMPLETION
/* this is not implemented yet */
if (ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED)
{
/* get previous match */
}
else
{
/* get next match */
}
#endif
break;
case VK_RETURN:
/* end input, return to main */
#ifdef FEATURE_HISTORY
/* add to the history */
if (str[0])
History (0, str);
#endif
ConInDummy ();
ConOutChar (_T('\n'));
break;
case VK_ESCAPE:
/* clear str Make this callable! */
ClearCommandLine (str, maxlen, orgx, orgy);
current = charcount = 0;
break;
#ifdef FEATURE_HISTORY
case VK_F3:
History_move_to_bottom();
#endif
case VK_UP:
#ifdef FEATURE_HISTORY
/* get previous command from buffer */
ClearCommandLine (str, maxlen, orgx, orgy);
History (-1, str);
current = charcount = _tcslen (str);
ConOutPrintf (_T("%s"), str);
#endif
break;
case VK_DOWN:
#ifdef FEATURE_HISTORY
/* get next command from buffer */
ClearCommandLine (str, maxlen, orgx, orgy);
History (1, str);
current = charcount = _tcslen (str);
ConOutPrintf (_T("%s"), str);
#endif
break;
case VK_LEFT:
/* move cursor left */
if (current > 0)
{
current--;
if (GetCursorX () == 0)
SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1));
else
SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ());
}
else
{
#ifdef __REACTOS__
Beep (440, 50);
#else
MessageBeep (-1);
#endif
}
break;
case VK_RIGHT:
/* move cursor right */
if (current != charcount)
{
current++;
if (GetCursorX () == maxx - 1)
SetCursorXY (0, (SHORT)(GetCursorY () + 1));
else
SetCursorXY ((SHORT)(GetCursorX () + 1), GetCursorY ());
}
break;
#if 0
#ifdef FEATURE_HISTORY
/*!!!WARNING!!!*/
/*this will only work as long as the two if statement
evaluates the same expression and a break is included
in each if statement.
This can be used for any combination using CTRL.
For other combinations is needed another system*/
case 'K':
/*add the current command line to the history*/
if (ir.Event.KeyEvent.dwControlKeyState &
(LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
{
if (str[0])
History(0,str);
ClearCommandLine (str, maxlen, orgx, orgy);
current = charcount = 0;
break;
}
case 'D':
if (ir.Event.KeyEvent.dwControlKeyState &
(LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
{
ClearCommandLine (str, maxlen, orgx, orgy);
History_del_current_entry(str);
current = charcount = _tcslen (str);
ConOutPrintf (_T("%s"), str);
break;
}
#endif/*FEATURE_HISTORY*/
#endif/*0*/
default:
#ifdef _UNICODE
ch = ir.Event.KeyEvent.uChar.UnicodeChar;
if ((ch >= 32 && ch <= 255) && (charcount != (maxlen - 2)))
#else
ch = ir.Event.KeyEvent.uChar.AsciiChar;
if (ch >= 32 && (charcount != (maxlen - 2)))
#endif /* _UNICODE */
{
/* insert character into string... */
if (bInsert && current != charcount)
{
for (count = charcount; count > current; count--)
str[count] = str[count - 1];
str[current++] = ch;
if (GetCursorX () == maxx - 1)
{
curx = 0;
cury = GetCursorY () + 1;
}
else
{
GetCursorXY (&curx, &cury);
curx++;
}
ConOutPrintf (_T("%s"), &str[current - 1]);
if ((_tcslen (str) > (USHORT)(maxx - orgx)) && (orgy == maxy + 1))
cury--;
SetCursorXY (curx, cury);
charcount++;
}
else
{
if (current == charcount)
charcount++;
str[current++] = ch;
ConOutChar (ch);
}
if ((_tcslen (str) > (USHORT)(maxx - orgx)) && (orgy == maxy + 1))
orgy--;
}
#if 0
else
{
#ifdef __REACTOS__
Beep (440, 100);
#else
MessageBeep (-1);
#endif
}
#endif
break;
}
wLastKey = ir.Event.KeyEvent.wVirtualKeyCode;
}
while (ir.Event.KeyEvent.wVirtualKeyCode != VK_RETURN);
SetCursorType (bInsert, TRUE);
}

View File

@@ -1,263 +0,0 @@
/*
* CMDTABLE.C - table of internal commands.
*
*
* History:
*
* 16 Jul 1998 (Hans B Pufal)
* started.
* New file to keep the internal command table. I plan on
* getting rid of the table real soon now and replacing it
* with a dynamic mechnism.
*
* 27 Jul 1998 John P. Price
* added config.h include
*
* 21-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode ready!
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include "cmd.h"
/* a list of all the internal commands, associating their command names */
/* to the functions to process them */
COMMAND cmds[] =
{
{_T("?"), 0, CommandShowCommands},
#ifdef INCLUDE_CMD_ACTIVATE
{_T("activate"), 0, CommandActivate},
#endif
#ifdef FEATURE_ALIASES
{_T("alias"), 0, CommandAlias},
#endif
#ifdef INCLUDE_CMD_ATTRIB
{_T("attrib"), 0, CommandAttrib},
#endif
#ifdef INCLUDE_CMD_BEEP
{_T("beep"), 0, cmd_beep},
#endif
{_T("call"), CMD_BATCHONLY, cmd_call},
#ifdef INCLUDE_CMD_CHDIR
{_T("cd"), CMD_SPECIAL, cmd_chdir},
{_T("chdir"), CMD_SPECIAL, cmd_chdir},
#endif
#ifdef INCLUDE_CMD_CHCP
{_T("chcp"), 0, CommandChcp},
#endif
#ifdef INCLUDE_CMD_CHOICE
{_T("choice"), 0, CommandChoice},
#endif
#ifdef INCLUDE_CMD_CLS
{_T("cls"), 0, cmd_cls},
#endif
#ifdef INCLUDE_CMD_COLOR
{_T("color"), 0, CommandColor},
#endif
#ifdef INCLUDE_CMD_COPY
{_T("copy"), 0, cmd_copy},
#endif
#ifdef INCLUDE_CMD_DATE
{_T("date"), 0, cmd_date},
#endif
#ifdef INCLUDE_CMD_DEL
{_T("del"), 0, CommandDelete},
{_T("delete"), 0, CommandDelete},
#endif
#ifdef INCLUDE_CMD_DELAY
{_T("delay"), 0, CommandDelay},
#endif
#ifdef INCLUDE_CMD_DIR
{_T("dir"), CMD_SPECIAL, CommandDir},
#endif
#ifdef FEATURE_DIRECTORY_STACK
{_T("dirs"), 0, CommandDirs},
#endif
{_T("echo"), 0, CommandEcho},
{_T("echo."), CMD_HIDE, CommandEcho},
{_T("echos"), 0, CommandEchos},
{_T("echoerr"), 0, CommandEchoerr},
{_T("echoerr."), CMD_HIDE, CommandEchoerr},
{_T("echoserr"), 0, CommandEchoserr},
#ifdef INCLUDE_CMD_DEL
{_T("erase"), 0, CommandDelete},
#endif
{_T("exit"), 0, CommandExit},
{_T("for"), 0, cmd_for},
#ifdef INCLUDE_CMD_FREE
{_T("free"), 0, CommandFree},
#endif
{_T("goto"), CMD_BATCHONLY, cmd_goto},
#ifdef FEATURE_HISTORY
{_T("history"), 0, CommandHistory},
#endif
{_T("if"), 0, cmd_if},
#ifdef INCLUDE_CMD_LABEL
{_T("label"), 0, cmd_label},
#endif
#ifdef INCLUDE_CMD_MEMORY
{_T("memory"), 0, CommandMemory},
#endif
#ifdef INCLUDE_CMD_MKDIR
{_T("md"), CMD_SPECIAL, cmd_mkdir},
{_T("mkdir"), CMD_SPECIAL, cmd_mkdir},
#endif
#ifdef INCLUDE_CMD_MOVE
{_T("move"), 0, cmd_move},
#endif
#ifdef INCLUDE_CMD_MSGBOX
{_T("msgbox"), 0, CommandMsgbox},
#endif
#ifdef INCLUDE_CMD_PATH
{_T("path"), 0, cmd_path},
#endif
#ifdef INCLUDE_CMD_PAUSE
{_T("pause"), 0, cmd_pause},
#endif
#ifdef FEATURE_DIRECTORY_STACK
{_T("popd"), 0, CommandPopd},
#endif
#ifdef INCLUDE_CMD_PROMPT
{_T("prompt"), 0, cmd_prompt},
#endif
#ifdef FEATURE_DIRECTORY_STACK
{_T("pushd"), 0, CommandPushd},
#endif
#ifdef INCLUDE_CMD_RMDIR
{_T("rd"), CMD_SPECIAL, cmd_rmdir},
#endif
#ifdef INCLUDE_CMD_REM
{_T("rem"), 0, CommandRem},
#endif
#ifdef INCLUDE_CMD_RENAME
{_T("ren"), 0, cmd_rename},
{_T("rename"), 0, cmd_rename},
#endif
#ifdef INCLUDE_CMD_RMDIR
{_T("rmdir"), CMD_SPECIAL, cmd_rmdir},
#endif
#ifdef INCLUDE_CMD_SCREEN
{_T("screen"), 0, CommandScreen},
#endif
#ifdef INCLUDE_CMD_SET
{_T("set"), 0, cmd_set},
#endif
{_T("shift"), CMD_BATCHONLY, cmd_shift},
#ifdef INCLUDE_CMD_START
{_T("start"), 0, cmd_start},
#endif
#ifdef INCLUDE_CMD_TIME
{_T("time"), 0, cmd_time},
#endif
#ifdef INCLUDE_CMD_TIMER
{_T("timer"), 0, CommandTimer},
#endif
#ifdef INCLUDE_CMD_TITLE
{_T("title"), 0, cmd_title},
#endif
#ifdef INCLUDE_CMD_TYPE
{_T("type"), 0, cmd_type},
#endif
#ifdef INCLUDE_CMD_VER
{_T("ver"), 0, cmd_ver},
#endif
#ifdef INCLUDE_CMD_VERIFY
{_T("verify"), 0, cmd_verify},
#endif
#ifdef INCLUDE_CMD_VOL
{_T("vol"), 0, cmd_vol},
#endif
#ifdef INCLUDE_CMD_WINDOW
{_T("window"), 0, CommandWindow},
#endif
{NULL, 0, NULL}
};
VOID PrintCommandList (VOID)
{
LPCOMMAND cmdptr;
INT y;
y = 0;
cmdptr = cmds;
while (cmdptr->name)
{
if (!(cmdptr->flags & CMD_HIDE))
{
if (++y == 8)
{
ConOutPuts (cmdptr->name);
y = 0;
}
else
{
ConOutPrintf (_T("%-10s"), cmdptr->name);
}
}
cmdptr++;
}
if (y != 0)
ConOutChar ('\n');
}
/* EOF */

View File

@@ -1,2 +0,0 @@
#define CMD_VER "0.1.1"
#define CMD_VER_RC CMD_VER"\0"

View File

@@ -1,131 +0,0 @@
/* $Id: color.c,v 1.4 1999/12/04 14:54:50 ekohl Exp $
*
* COLOR.C - color internal command.
*
*
* History:
*
* 13-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Started.
*
* 19-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode ready!
*
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Redirection ready!
*
* 14-Oct-1999 (Paolo Pantaleo <paolopan@freemail.it>)
* 4nt's syntax implemented
*/
#include "config.h"
#ifdef INCLUDE_CMD_COLOR
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include "cmd.h"
static VOID ColorHelp (VOID)
{
ConOutPuts (_T(
"Sets the default foreground and background colors.\n"
"\n"
"COLOR [attr [/F]] \n\n"
" attr Specifies color attribute of console output\n"
" /F fill the console with color attribute\n"
"\n"
"There are three ways to specify the colors:"
));
ConOutPuts (_T(
"\n"
"1) [bright] name on [bright] name (only the first three letters are required)\n"
"2) decimal on decimal\n"
"3) two hex digits\n"
"\n"
"Colors are:"
));
ConOutPuts (_T(
"dec hex name dec hex name\n"
"0 0 Black 8 8 Gray(Bright black)\n"
"1 1 Blue 9 9 Bright Blue\n"
"2 2 Green 10 A Bright Green\n"
"3 3 Cyan 11 B Bright Cyan\n"
"4 4 Red 12 C Bright Red\n"
"5 5 Magenta 13 D Bright Magenta\n"
"6 6 Yellow 14 E Bright Yellow\n"
"7 7 White 15 F Bright White"));
}
VOID SetScreenColor (WORD wColor, BOOL bFill)
{
DWORD dwWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
COORD coPos;
if (bFill == TRUE)
{
GetConsoleScreenBufferInfo (hOut, &csbi);
coPos.X = 0;
coPos.Y = 0;
FillConsoleOutputAttribute (hOut,
(WORD)(wColor & 0x00FF),
(csbi.dwSize.X)*(csbi.dwSize.Y),
coPos,
&dwWritten);
}
SetConsoleTextAttribute (hOut, (WORD)(wColor & 0x00FF));
}
/*
* color
*
* internal dir command
*/
INT CommandColor (LPTSTR first, LPTSTR rest)
{
if (_tcsncmp (rest, _T("/?"), 2) == 0)
{
ColorHelp ();
return 0;
}
if (rest[0] == _T('\0'))
{
/* set default color */
wColor = wDefColor;
SetScreenColor (wColor, TRUE);
return 0;
}
if (StringToColor (&wColor, &rest) == FALSE)
{
ConErrPuts("error in color specification");
return 1;
}
ConErrPrintf ("Color %x\n", wColor);
if ((wColor & 0xF) == (wColor &0xF0) >> 4)
{
ConErrPuts (_T("same colors error!"));
return 1;
}
/* set color */
SetScreenColor (wColor,
(_tcsstr (rest,"/F") || _tcsstr (rest,"/f")));
return 0;
}
#endif /* INCLUDE_CMD_COLOR */
/* EOF */

View File

@@ -1,106 +0,0 @@
/*
* CONFIG.H - Used to configure what will be compiled into the shell.
*
*
* History:
*
* 27 Jul 1998 - John P. Price
* started.
*
*/
/* Define only if used under ReactOS */
#define __REACTOS__
#ifndef _CONFIG_H_INCLUDED_
#define _CONFIG_H_INCLUDED_
#ifndef __REACTOS__
#define WIN32_LEAN_AND_MEAN
#endif /* __REACTOS__ */
/* Define to enable debugging code */
//#define _DEBUG
/* Define to enable the alias command, and aliases.*/
#define FEATURE_ALIASES
/* Define to enable history */
#define FEATURE_HISTORY
/*Define to enable history wrap (4nt's style)*/
#define WRAP_HISTORY
/* Define one of these to enable filename completion */
#define FEATURE_UNIX_FILENAME_COMPLETION
/* #define FEATURE_4NT_FILENAME_COMPLETION */
/* Define to enable the directory stack */
#define FEATURE_DIRECTORY_STACK
/* Define to activate redirections and piping */
#define FEATURE_REDIRECTION
/* Define one of these to select the used locale. */
/* (date and time formats etc.) used in DATE, TIME, */
/* DIR, PROMPT etc. */
#ifdef __REACTOS__
#define LOCALE_DEFAULT
#else
#define LOCALE_WINDOWS /* System locale */
/* #define LOCALE_GERMAN */ /* German locale */
/* #define LOCALE_DEFAULT */ /* United States locale */
#endif
#ifndef __REACTOS__
#define INCLUDE_CMD_ACTIVATE
#endif
#define INCLUDE_CMD_ATTRIB
#define INCLUDE_CMD_CHCP
#define INCLUDE_CMD_CHDIR
#define INCLUDE_CMD_CHOICE
#define INCLUDE_CMD_CLS
#define INCLUDE_CMD_COLOR
#define INCLUDE_CMD_COPY
#define INCLUDE_CMD_DATE
#define INCLUDE_CMD_DEL
#define INCLUDE_CMD_DELAY
#define INCLUDE_CMD_DIR
#define INCLUDE_CMD_FREE
#define INCLUDE_CMD_LABEL
#define INCLUDE_CMD_MEMORY
#define INCLUDE_CMD_MKDIR
#define INCLUDE_CMD_MOVE
#ifndef __REACTOS__
#define INCLUDE_CMD_MSGBOX
#endif
#define INCLUDE_CMD_PATH
#define INCLUDE_CMD_PROMPT
#define INCLUDE_CMD_RMDIR
#define INCLUDE_CMD_RENAME
#define INCLUDE_CMD_SCREEN
#define INCLUDE_CMD_SET
#define INCLUDE_CMD_START
#define INCLUDE_CMD_TIME
#define INCLUDE_CMD_TIMER
#define INCLUDE_CMD_TITLE
#define INCLUDE_CMD_TYPE
#define INCLUDE_CMD_VER
#define INCLUDE_CMD_REM
#define INCLUDE_CMD_PAUSE
#define INCLUDE_CMD_BEEP
#define INCLUDE_CMD_VERIFY
#define INCLUDE_CMD_VOL
#ifndef __REACTOS__
#define INCLUDE_CMD_WINDOW
#endif
#endif /* _CONFIG_H_INCLUDED_ */

View File

@@ -1,302 +0,0 @@
/* $Id: console.c,v 1.13 1999/12/15 00:50:41 ekohl Exp $
*
* CONSOLE.C - console input/output functions.
*
*
* History:
*
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* started
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "cmd.h"
#define OUTPUT_BUFFER_SIZE 4096
#ifdef _DEBUG
VOID DebugPrintf (LPTSTR szFormat, ...)
{
TCHAR szOut[OUTPUT_BUFFER_SIZE];
va_list arg_ptr;
DWORD dwWritten;
va_start (arg_ptr, szFormat);
_vstprintf (szOut, szFormat, arg_ptr);
va_end (arg_ptr);
WriteFile (GetStdHandle (STD_ERROR_HANDLE),
szOut,
_tcslen(szOut) * sizeof(TCHAR),
&dwWritten,
NULL);
#if 0
OutputDebugString (szOut);
#endif
}
#endif /* _DEBUG */
VOID ConInDisable (VOID)
{
HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
DWORD dwMode;
GetConsoleMode (hInput, &dwMode);
dwMode &= ~ENABLE_PROCESSED_INPUT;
SetConsoleMode (hInput, dwMode);
}
VOID ConInEnable (VOID)
{
HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
DWORD dwMode;
GetConsoleMode (hInput, &dwMode);
dwMode |= ENABLE_PROCESSED_INPUT;
SetConsoleMode (hInput, dwMode);
}
VOID ConInDummy (VOID)
{
HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
INPUT_RECORD dummy;
DWORD dwRead;
#ifdef _DEBUG
if (hInput == INVALID_HANDLE_VALUE)
DebugPrintf ("Invalid input handle!!!\n");
#endif /* _DEBUG */
ReadConsoleInput (hInput, &dummy, 1, &dwRead);
}
VOID ConInFlush (VOID)
{
FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE));
}
VOID ConInKey (PINPUT_RECORD lpBuffer)
{
HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
DWORD dwRead;
#ifdef _DEBUG
if (hInput == INVALID_HANDLE_VALUE)
DebugPrintf ("Invalid input handle!!!\n");
#endif /* _DEBUG */
do
{
ReadConsoleInput (hInput, lpBuffer, 1, &dwRead);
if ((lpBuffer->EventType == KEY_EVENT) &&
(lpBuffer->Event.KeyEvent.bKeyDown == TRUE))
break;
}
while (TRUE);
}
VOID ConInString (LPTSTR lpInput, DWORD dwLength)
{
DWORD dwOldMode;
DWORD dwRead;
HANDLE hFile;
LPTSTR p;
DWORD i;
ZeroMemory (lpInput, dwLength * sizeof(TCHAR));
hFile = GetStdHandle (STD_INPUT_HANDLE);
GetConsoleMode (hFile, &dwOldMode);
SetConsoleMode (hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
ReadFile (hFile, lpInput, dwLength, &dwRead, NULL);
p = lpInput;
for (i = 0; i < dwRead; i++, p++)
{
if (*p == _T('\x0d'))
{
*p = _T('\0');
break;
}
}
SetConsoleMode (hFile, dwOldMode);
}
VOID ConOutChar (TCHAR c)
{
DWORD dwWritten;
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE),
&c,
sizeof(TCHAR),
&dwWritten,
NULL);
}
VOID ConOutPuts (LPTSTR szText)
{
DWORD dwWritten;
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE),
szText,
_tcslen(szText) * sizeof(TCHAR),
&dwWritten,
NULL);
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE),
_T("\n"),
sizeof(TCHAR),
&dwWritten,
NULL);
}
VOID ConOutPrintf (LPTSTR szFormat, ...)
{
TCHAR szOut[OUTPUT_BUFFER_SIZE];
DWORD dwWritten;
va_list arg_ptr;
va_start (arg_ptr, szFormat);
_vstprintf (szOut, szFormat, arg_ptr);
va_end (arg_ptr);
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE),
szOut,
_tcslen(szOut) * sizeof(TCHAR),
&dwWritten,
NULL);
}
VOID ConErrChar (TCHAR c)
{
DWORD dwWritten;
WriteFile (GetStdHandle (STD_ERROR_HANDLE),
&c,
sizeof(TCHAR),
&dwWritten,
NULL);
}
VOID ConErrPuts (LPTSTR szText)
{
DWORD dwWritten;
WriteFile (GetStdHandle (STD_ERROR_HANDLE),
szText,
_tcslen(szText) * sizeof(TCHAR),
&dwWritten,
NULL);
WriteFile (GetStdHandle (STD_ERROR_HANDLE),
_T ("\n"),
sizeof(TCHAR),
&dwWritten,
NULL);
}
VOID ConErrPrintf (LPTSTR szFormat, ...)
{
TCHAR szOut[OUTPUT_BUFFER_SIZE];
DWORD dwWritten;
va_list arg_ptr;
va_start (arg_ptr, szFormat);
_vstprintf (szOut, szFormat, arg_ptr);
va_end (arg_ptr);
WriteFile (GetStdHandle (STD_ERROR_HANDLE),
szOut,
_tcslen(szOut) * sizeof(TCHAR),
&dwWritten,
NULL);
}
VOID SetCursorXY (SHORT x, SHORT y)
{
COORD coPos;
coPos.X = x;
coPos.Y = y;
SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), coPos);
}
VOID GetCursorXY (PSHORT x, PSHORT y)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi);
*x = csbi.dwCursorPosition.X;
*y = csbi.dwCursorPosition.Y;
}
SHORT GetCursorX (VOID)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi);
return csbi.dwCursorPosition.X;
}
SHORT GetCursorY (VOID)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi);
return csbi.dwCursorPosition.Y;
}
VOID GetScreenSize (PSHORT maxx, PSHORT maxy)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi);
if (maxx)
*maxx = csbi.dwSize.X;
if (maxy)
*maxy = csbi.dwSize.Y;
}
VOID SetCursorType (BOOL bInsert, BOOL bVisible)
{
CONSOLE_CURSOR_INFO cci;
cci.dwSize = bInsert ? 10 : 99;
cci.bVisible = bVisible;
SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cci);
}
/* EOF */

View File

@@ -1,755 +0,0 @@
/* $Id: copy.c,v 1.7 2000/04/08 14:50:47 ekohl Exp $
*
* COPY.C -- copy internal command.
*
*
* History:
*
* 01-Aug-98 (Rob Lake z63rrl@morgan.ucs.mun.ca)
* started
*
* 13-Aug-1998 (John P. Price)
* fixed memory leak problem in copy function.
* fixed copy function so it would work with wildcards in the source
*
* 13-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added COPY command to CMD.
*
* 26-Jan-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Replaced CRT io functions by Win32 io functions.
*
* 27-Oct-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Disabled prompting when used in batch mode.
*/
#include "config.h"
#ifdef INCLUDE_CMD_COPY
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmd.h"
#include "batch.h"
#define VERIFY 1 /* VERIFY Switch */
#define BINARY 2 /* File is to be copied as BINARY */
#define ASCII 4 /* File is to be copied as ASCII */
#define PROMPT 8 /* Prompt before overwriting files */
#define NPROMPT 16 /* Do not prompt before overwriting files */
#define HELP 32 /* Help was asked for */
#define SOURCE 128 /* File is a source */
typedef struct tagFILES
{
struct tagFILES *next;
TCHAR szFile[MAX_PATH];
DWORD dwFlag; /* BINARY -xor- ASCII */
} FILES, *LPFILES;
static BOOL DoSwitches (LPTSTR, LPDWORD);
static BOOL AddFile (LPFILES, char *, int *, int *, LPDWORD);
static BOOL AddFiles (LPFILES, char *, int *, int *, int *, LPDWORD);
static BOOL GetDestination (LPFILES, LPFILES);
static INT ParseCommand (LPFILES, int, char **, LPDWORD);
static VOID DeleteFileList (LPFILES);
static INT Overwrite (LPTSTR);
static BOOL
IsDirectory (LPTSTR fn)
{
if (!IsValidFileName (fn))
return FALSE;
return (GetFileAttributes (fn) & FILE_ATTRIBUTE_DIRECTORY);
}
static BOOL
DoSwitches (LPTSTR arg, LPDWORD lpdwFlags)
{
if (!_tcsicmp (arg, _T("/-Y")))
{
*lpdwFlags |= PROMPT;
*lpdwFlags &= ~NPROMPT;
return TRUE;
}
else if (_tcslen (arg) > 2)
{
error_too_many_parameters ("");
return FALSE;
}
switch (_totupper (arg[1]))
{
case _T('V'):
*lpdwFlags |= VERIFY;
break;
case _T('A'):
*lpdwFlags |= ASCII;
*lpdwFlags &= ~BINARY;
break;
case _T('B'):
*lpdwFlags |= BINARY;
*lpdwFlags &= ~ASCII;
break;
case _T('Y'):
*lpdwFlags &= ~PROMPT;
*lpdwFlags |= NPROMPT;
break;
default:
error_invalid_switch (arg[1]);
return FALSE;
}
return TRUE;
}
static BOOL
AddFile (LPFILES f, char *arg, int *source, int *dest, LPDWORD flags)
{
if (*dest)
{
error_too_many_parameters ("");
return FALSE;
}
if (*source)
{
*dest = 1;
f->dwFlag = 0;
}
else
{
*source = 1;
f->dwFlag = SOURCE;
}
_tcscpy(f->szFile, arg);
f->dwFlag |= *flags & ASCII ? ASCII : BINARY;
if ((f->next = (LPFILES)malloc (sizeof (FILES))) == NULL)
{
error_out_of_memory ();
return FALSE;
}
f = f->next;
f->dwFlag = 0;
f->next = NULL;
return TRUE;
}
static BOOL
AddFiles (LPFILES f, char *arg, int *source, int *dest,
int *count, LPDWORD flags)
{
char t[128];
int j;
int k;
if (*dest)
{
error_too_many_parameters ("");
return FALSE;
}
j = 0;
k = 0;
while (arg[j] == _T('+'))
j++;
while (arg[j] != _T('\0'))
{
t[k] = arg[j++];
if (t[k] == '+' || arg[j] == _T('\0'))
{
if (!k)
continue;
if (arg[j] == _T('\0') && t[k] != _T('+'))
k++;
t[k] = _T('\0');
*count += 1;
_tcscpy (f->szFile, t);
*source = 1;
if (*flags & ASCII)
f->dwFlag |= *flags | SOURCE | ASCII;
else
f->dwFlag |= *flags | BINARY | SOURCE;
if ((f->next = (LPFILES)malloc (sizeof (FILES))) == NULL)
{
error_out_of_memory ();
return FALSE;
}
f = f->next;
f->next = NULL;
k = 0;
f->dwFlag = 0;
continue;
}
k++;
}
if (arg[--j] == _T('+'))
*source = 0;
return 1;
}
static BOOL
GetDestination (LPFILES f, LPFILES dest)
{
LPFILES p = NULL;
LPFILES start = f;
while (f->next != NULL)
{
p = f;
f = f->next;
}
f = p;
if ((f->dwFlag & SOURCE) == 0)
{
free (p->next);
p->next = NULL;
_tcscpy (dest->szFile, f->szFile);
dest->dwFlag = f->dwFlag;
dest->next = NULL;
f = start;
return TRUE;
}
return FALSE;
}
static INT
ParseCommand (LPFILES f, int argc, char **arg, LPDWORD lpdwFlags)
{
INT i;
INT dest;
INT source;
INT count;
dest = 0;
source = 0;
count = 0;
for (i = 0; i < argc; i++)
{
if (arg[i][0] == _T('/'))
{
if (!DoSwitches (arg[i], lpdwFlags))
return -1;
}
else
{
if (!_tcscmp(arg[i], _T("+")))
source = 0;
else if (!_tcschr(arg[i], _T('+')) && source)
{
if (!AddFile(f, arg[i], &source, &dest, lpdwFlags))
return -1;
f = f->next;
count++;
}
else
{
if (!AddFiles(f, arg[i], &source, &dest, &count, lpdwFlags))
return -1;
while (f->next != NULL)
f = f->next;
}
}
}
#ifdef _DEBUG
DebugPrintf ("ParseCommand: flags has %s\n",
*lpdwFlags & ASCII ? "ASCII" : "BINARY");
#endif
return count;
}
static VOID
DeleteFileList (LPFILES f)
{
LPFILES temp;
while (f != NULL)
{
temp = f;
f = f->next;
free (temp);
}
}
static INT
Overwrite (LPTSTR fn)
{
TCHAR inp[10];
LPTSTR p;
ConOutPrintf (_T("Overwrite %s (Yes/No/All)? "), fn);
ConInString (inp, 10);
ConOutPuts (_T(""));
_tcsupr (inp);
for (p = inp; _istspace (*p); p++)
;
if (*p != _T('Y') && *p != _T('A'))
return 0;
if (*p == _T('A'))
return 2;
return 1;
}
#define BUFF_SIZE 16384 /* 16k = max buffer size */
int copy (LPTSTR source, LPTSTR dest, int append, LPDWORD lpdwFlags)
{
FILETIME srctime;
HANDLE hFileSrc;
HANDLE hFileDest;
LPBYTE buffer;
DWORD dwAttrib;
DWORD dwRead;
DWORD dwWritten;
DWORD i;
BOOL bEof = FALSE;
#ifdef _DEBUG
DebugPrintf ("checking mode\n");
#endif
dwAttrib = GetFileAttributes (source);
hFileSrc = CreateFile (source, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL);
if (hFileSrc == INVALID_HANDLE_VALUE)
{
ConErrPrintf (_T("Error: Cannot open source - %s!\n"), source);
return 0;
}
#ifdef _DEBUG
DebugPrintf (_T("getting time\n"));
#endif
GetFileTime (hFileSrc, &srctime, NULL, NULL);
#ifdef _DEBUG
DebugPrintf (_T("copy: flags has %s\n"),
*lpdwFlags & ASCII ? "ASCII" : "BINARY");
#endif
if (!IsValidFileName (dest))
{
#ifdef _DEBUG
DebugPrintf (_T("opening/creating\n"));
#endif
hFileDest =
CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
}
else if (!append)
{
if (!_tcscmp (dest, source))
{
ConErrPrintf (_T("Error: Can't copy onto itself!\n"));
CloseHandle (hFileSrc);
return 0;
}
#ifdef _DEBUG
DebugPrintf (_T("SetFileAttributes (%s, FILE_ATTRIBUTE_NORMAL);\n"), dest);
#endif
SetFileAttributes (dest, FILE_ATTRIBUTE_NORMAL);
#ifdef _DEBUG
DebugPrintf (_T("DeleteFile (%s);\n"), dest);
#endif
DeleteFile (dest);
hFileDest =
CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
}
else
{
LONG lFilePosHigh = 0;
if (!_tcscmp (dest, source))
{
CloseHandle (hFileSrc);
return 0;
}
#ifdef _DEBUG
DebugPrintf (_T("opening/appending\n"));
#endif
hFileDest =
CreateFile (dest, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
SetFilePointer (hFileDest, 0, &lFilePosHigh,FILE_END);
}
if (hFileDest == INVALID_HANDLE_VALUE)
{
CloseHandle (hFileSrc);
error_path_not_found ();
return 0;
}
buffer = (LPBYTE)malloc (BUFF_SIZE);
if (buffer == NULL)
{
CloseHandle (hFileDest);
CloseHandle (hFileSrc);
error_out_of_memory ();
return 0;
}
do
{
ReadFile (hFileSrc, buffer, BUFF_SIZE, &dwRead, NULL);
if (*lpdwFlags & ASCII)
{
for (i = 0; i < dwRead; i++)
{
if (((LPTSTR)buffer)[i] == 0x1A)
{
bEof = TRUE;
break;
}
}
dwRead = i;
}
if (dwRead == 0)
break;
WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL);
if (dwWritten != dwRead)
{
ConErrPrintf (_T("Error writing destination!\n"));
free (buffer);
CloseHandle (hFileDest);
CloseHandle (hFileSrc);
return 0;
}
}
while (dwRead && !bEof);
#ifdef _DEBUG
DebugPrintf (_T("setting time\n"));
#endif
SetFileTime (hFileDest, &srctime, NULL, NULL);
if (*lpdwFlags & ASCII)
{
((LPTSTR)buffer)[0] = 0x1A;
((LPTSTR)buffer)[1] = _T('\0');
#ifdef _DEBUG
DebugPrintf (_T("appending ^Z\n"));
#endif
WriteFile (hFileDest, buffer, sizeof(TCHAR), &dwWritten, NULL);
}
free (buffer);
CloseHandle (hFileDest);
CloseHandle (hFileSrc);
#ifdef _DEBUG
DebugPrintf (_T("setting mode\n"));
#endif
SetFileAttributes (dest, dwAttrib);
return 1;
}
static INT
SetupCopy (LPFILES sources, char **p, BOOL bMultiple,
char *drive_d, char *dir_d, char *file_d,
char *ext_d, int *append, LPDWORD lpdwFlags)
{
WIN32_FIND_DATA find;
char drive_s[_MAX_DRIVE];
CHAR dir_s[_MAX_DIR];
char file_s[_MAX_FNAME];
char ext_s[_MAX_EXT];
char from_merge[_MAX_PATH];
LPTSTR real_source;
LPTSTR real_dest;
INT nCopied = 0;
BOOL bAll = FALSE;
BOOL bDone;
HANDLE hFind;
#ifdef _DEBUG
DebugPrintf (_T("SetupCopy\n"));
#endif
real_source = (LPTSTR)malloc (MAX_PATH);
real_dest = (LPTSTR)malloc (MAX_PATH);
if (!real_source || !real_dest)
{
error_out_of_memory ();
DeleteFileList (sources);
free (real_source);
free (real_dest);
freep (p);
return 0;
}
while (sources->next != NULL)
{
_splitpath (sources->szFile, drive_s, dir_s, file_s, ext_s);
hFind = FindFirstFile (sources->szFile, &find);
if (hFind == INVALID_HANDLE_VALUE)
{
error_file_not_found();
freep(p);
free(real_source);
free(real_dest);
return 0;
}
do
{
if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
goto next;
_makepath(from_merge, drive_d, dir_d, file_d, ext_d);
if (from_merge[_tcslen(from_merge) - 1] == _T('\\'))
from_merge[_tcslen(from_merge) - 1] = 0;
if (IsDirectory (from_merge))
{
bMultiple = FALSE;
_tcscat (from_merge, _T("\\"));
_tcscat (from_merge, find.cFileName);
}
else
bMultiple = TRUE;
_tcscpy (real_dest, from_merge);
_makepath (real_source, drive_s, dir_s, find.cFileName, NULL);
#ifdef _DEBUG
DebugPrintf (_T("copying %s -> %s (%sappending%s)\n"),
real_source, real_dest,
*append ? "" : "not ",
sources->dwFlag & ASCII ? ", ASCII" : ", BINARY");
#endif
if (IsValidFileName (real_dest) && !bAll)
{
/* Don't prompt in a batch file */
if (bc != NULL)
{
bAll = TRUE;
}
else
{
int over;
over = Overwrite (real_dest);
if (over == 2)
bAll = TRUE;
else if (over == 0)
goto next;
else if (bMultiple)
bAll = TRUE;
}
}
if (copy (real_source, real_dest, *append, lpdwFlags))
nCopied++;
next:
bDone = FindNextFile (hFind, &find);
if (bMultiple)
*append = 1;
}
while (bDone);
FindClose (hFind);
sources = sources->next;
}
free (real_source);
free (real_dest);
return nCopied;
}
INT cmd_copy (LPTSTR first, LPTSTR rest)
{
char **p;
char drive_d[_MAX_DRIVE];
char dir_d[_MAX_DIR];
char file_d[_MAX_FNAME];
char ext_d[_MAX_EXT];
int argc;
int append;
int files;
int copied;
LPFILES sources = NULL;
LPFILES start = NULL;
FILES dest;
BOOL bMultiple;
BOOL bWildcards;
BOOL bDestFound;
DWORD dwFlags = 0;
if (!_tcsncmp (rest, _T("/?"), 2))
{
ConOutPuts (_T("Copies one or more files to another location.\n"
"\n"
"COPY [/V][/Y|/-Y][/A|/B] source [/A|/B]\n"
" [+ source [/A|/B] [+ ...]] [destination [/A|/B]]\n"
"\n"
" source Specifies the file or files to be copied.\n"
" /A Indicates an ASCII text file.\n"
" /B Indicates a binary file.\n"
" destination Specifies the directory and/or filename for the new file(s).\n"
" /V Verifies that new files are written correctly.\n"
" /Y Suppresses prompting to confirm you want to overwrite an\n"
" existing destination file.\n"
" /-Y Causes prompting to confirm you want to overwrite an\n"
" existing destination file.\n"
"\n"
"The switch /Y may be present in the COPYCMD environment variable.\n"
"..."));
return 1;
}
p = split (rest, &argc);
if (argc == 0)
{
error_req_param_missing ();
return 0;
}
sources = (LPFILES)malloc (sizeof (FILES));
if (!sources)
{
error_out_of_memory ();
return 0;
}
sources->next = NULL;
sources->dwFlag = 0;
if ((files = ParseCommand (sources, argc, p, &dwFlags)) == -1)
{
DeleteFileList (sources);
freep (p);
return 0;
}
else if (files == 0)
{
error_req_param_missing();
DeleteFileList (sources);
freep (p);
return 0;
}
start = sources;
bDestFound = GetDestination (sources, &dest);
if (bDestFound)
{
_splitpath (dest.szFile, drive_d, dir_d, file_d, ext_d);
if (IsDirectory (dest.szFile))
{
_tcscat (dir_d, file_d);
_tcscat (dir_d, ext_d);
file_d[0] = _T('\0');
ext_d[0] = _T('\0');
}
}
if (_tcschr (dest.szFile, _T('*')) || _tcschr (dest.szFile, _T('?')))
bWildcards = TRUE;
else
bWildcards = FALSE;
if (strchr(rest, '+'))
bMultiple = TRUE;
else
bMultiple = FALSE;
append = 0;
copied = 0;
if (bDestFound && !bWildcards)
{
copied = SetupCopy (sources, p, bMultiple, drive_d, dir_d, file_d, ext_d, &append, &dwFlags);
}
else if (bDestFound && bWildcards)
{
ConErrPrintf (_T("Error: Not implemented yet!\n"));
DeleteFileList (sources);
freep (p);
return 0;
}
else if (!bDestFound && !bMultiple)
{
_splitpath (sources->szFile, drive_d, dir_d, file_d, ext_d);
if (IsDirectory (sources->szFile))
{
_tcscat (dir_d, file_d);
_tcscat (dir_d, ext_d);
file_d[0] = _T('\0');
ext_d[0] = _T('\0');
}
copied = SetupCopy (sources, p, FALSE, "", "", file_d, ext_d, &append, &dwFlags);
}
else
{
_splitpath(sources->szFile, drive_d, dir_d, file_d, ext_d);
if (IsDirectory (sources->szFile))
{
_tcscat (dir_d, file_d);
_tcscat (dir_d, ext_d);
file_d[0] = _T('\0');
ext_d[0] = _T('\0');
}
ConOutPuts (sources->szFile);
append = 1;
copied = SetupCopy (sources->next, p, bMultiple, drive_d, dir_d, file_d, ext_d, &append, &dwFlags) + 1;
}
DeleteFileList (sources);
freep (p);
ConOutPrintf (_T(" %d file(s) copied\n"), copied);
return 1;
}
#endif /* INCLUDE_CMD_COPY */
/* EOF */

View File

@@ -1,261 +0,0 @@
/*
* DATE.C - date internal command.
*
*
* History:
*
* 08 Jul 1998 (John P. Price)
* started.
*
* 20 Jul 1998 (John P. Price)
* corrected number of days for December from 30 to 31.
* (Thanx to Steffen Kaiser for bug report)
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 29-Jul-1998 (Rob Lake)
* fixed stand-alone mode.
* Added Pacific C compatible dos_getdate functions
*
* 09-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added locale support
*
* 23-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode and redirection safe!
*
* 04-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Fixed date input bug.
*/
#include "config.h"
#ifdef INCLUDE_CMD_DATE
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <ctype.h>
#include "cmd.h"
static WORD awMonths[2][13] =
{
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
static VOID
PrintDateString (VOID)
{
switch (nDateFormat)
{
case 0: /* mmddyy */
default:
ConOutPrintf (_T("\nEnter new date (mm%cdd%cyyyy): "),
cDateSeparator, cDateSeparator);
break;
case 1: /* ddmmyy */
ConOutPrintf (_T("\nEnter new date (dd%cmm%cyyyy): "),
cDateSeparator, cDateSeparator);
break;
case 2: /* yymmdd */
ConOutPrintf (_T("\nEnter new date (yyyy%cmm%cdd): "),
cDateSeparator, cDateSeparator);
break;
}
}
static BOOL
ReadNumber (LPTSTR *s, LPWORD lpwValue)
{
if (_istdigit (**s))
{
while (_istdigit (**s))
{
*lpwValue = *lpwValue * 10 + **s - _T('0');
(*s)++;
}
return TRUE;
}
return FALSE;
}
static BOOL
ReadSeparator (LPTSTR *s)
{
if (**s == _T('/') || **s == _T('-') || **s == cDateSeparator)
{
(*s)++;
return TRUE;
}
return FALSE;
}
static BOOL
ParseDate (LPTSTR s)
{
SYSTEMTIME d;
unsigned char leap;
LPTSTR p = s;
if (!*s)
return TRUE;
GetLocalTime (&d);
d.wYear = 0;
d.wDay = 0;
d.wMonth = 0;
switch (nDateFormat)
{
case 0: /* mmddyy */
default:
if (!ReadNumber (&p, &d.wMonth))
return FALSE;
if (!ReadSeparator (&p))
return FALSE;
if (!ReadNumber (&p, &d.wDay))
return FALSE;
if (!ReadSeparator (&p))
return FALSE;
if (!ReadNumber (&p, &d.wYear))
return FALSE;
break;
case 1: /* ddmmyy */
if (!ReadNumber (&p, &d.wDay))
return FALSE;
if (!ReadSeparator (&p))
return FALSE;
if (!ReadNumber (&p, &d.wMonth))
return FALSE;
if (!ReadSeparator (&p))
return FALSE;
if (!ReadNumber (&p, &d.wYear))
return FALSE;
break;
case 2: /* yymmdd */
if (!ReadNumber (&p, &d.wYear))
return FALSE;
if (!ReadSeparator (&p))
return FALSE;
if (!ReadNumber (&p, &d.wMonth))
return FALSE;
if (!ReadSeparator (&p))
return FALSE;
if (!ReadNumber (&p, &d.wDay))
return FALSE;
break;
}
/* if only entered two digits: */
/* assume 2000's if value less than 80 */
/* assume 1900's if value greater or equal 80 */
if (d.wYear <= 99)
{
if (d.wYear >= 80)
d.wYear = 1900 + d.wYear;
else
d.wYear = 2000 + d.wYear;
}
leap = (!(d.wYear % 4) && (d.wYear % 100)) || !(d.wYear % 400);
if ((d.wMonth >= 1 && d.wMonth <= 12) &&
(d.wDay >= 1 && d.wDay <= awMonths[leap][d.wMonth]) &&
(d.wYear >= 1980 && d.wYear <= 2099))
{
SetLocalTime (&d);
return TRUE;
}
return FALSE;
}
INT cmd_date (LPTSTR cmd, LPTSTR param)
{
LPTSTR *arg;
INT argc;
INT i;
BOOL bPrompt = TRUE;
INT nDateString = -1;
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Displays or sets the date.\n\n"
"DATE [/T][date]\n\n"
" /T display only\n\n"
"Type DATE without parameters to display the current date setting and\n"
"a prompt for a new one. Press ENTER to keep the same date."));
return 0;
}
/* build parameter array */
arg = split (param, &argc);
/* check for options */
for (i = 0; i < argc; i++)
{
if (_tcsicmp (arg[i], _T("/t")) == 0)
bPrompt = FALSE;
if ((*arg[i] != _T('/')) && (nDateString == -1))
nDateString = i;
}
if (nDateString == -1)
PrintDate ();
if (!bPrompt)
{
freep (arg);
return 0;
}
if (nDateString == -1)
{
while (TRUE) /* forever loop */
{
TCHAR s[40];
PrintDateString ();
ConInString (s, 40);
#ifdef _DEBUG
DebugPrintf ("\'%s\'\n", s);
#endif
while (*s && s[_tcslen (s) - 1] < ' ')
s[_tcslen (s) - 1] = '\0';
if (ParseDate (s))
{
freep (arg);
return 0;
}
ConErrPuts ("Invalid date.");
}
}
else
{
if (ParseDate (arg[nDateString]))
{
freep (arg);
return 0;
}
ConErrPuts ("Invalid date.");
}
freep (arg);
return 0;
}
#endif

View File

@@ -1,348 +0,0 @@
/*
* DEL.C - del internal command.
*
*
* History:
*
* 06/29/98 (Rob Lake rlake@cs.mun.ca)
* rewrote del to support wildcards
* added my name to the contributors
*
* 07/13/98 (Rob Lake)
* fixed bug that caused del not to delete file with out
* attribute. moved set, del, ren, and ver to there own files
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 09-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
* Fixed command line parsing bugs.
*
* 21-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
* Started major rewrite using a new structure.
*
* 03-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
* First working version.
*
* 30-Mar-1999 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
* Added quiet ("/Q"), wipe ("/W") and zap ("/Z") option.
*
* 06-Nov-1999 (Eric Kohl <ekohl@abo.rhein-zeiung.de>)
* Little fix to keep DEL quiet inside batch files.
*/
#include "config.h"
#ifdef INCLUDE_CMD_DEL
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmd.h"
#include "batch.h"
enum
{
DEL_ATTRIBUTES = 0x001, /* /A : not implemented */
DEL_ERROR = 0x002, /* /E : not implemented */
DEL_NOTHING = 0x004, /* /N */
DEL_PROMPT = 0x008, /* /P : not implemented */
DEL_QUIET = 0x010, /* /Q */
DEL_SUBDIR = 0x020, /* /S : not implemented */
DEL_TOTAL = 0x040, /* /T */
DEL_WIPE = 0x080, /* /W */
DEL_EMPTYDIR = 0x100, /* /X : not implemented */
DEL_YES = 0x200, /* /Y : not implemented */
DEL_ZAP = 0x400 /* /Z */
};
static BOOL
RemoveFile (LPTSTR lpFileName, DWORD dwFlags)
{
if (dwFlags & DEL_WIPE)
{
/* FIXME: Wipe the given file */
}
return DeleteFile (lpFileName);
}
INT CommandDelete (LPTSTR cmd, LPTSTR param)
{
TCHAR szFullPath[MAX_PATH];
LPTSTR pFilePart;
LPTSTR *arg = NULL;
INT args;
INT i;
INT nEvalArgs = 0; /* nunber of evaluated arguments */
DWORD dwFlags = 0;
DWORD dwFiles = 0;
HANDLE hFile;
WIN32_FIND_DATA f;
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Deletes one or more files.\n"
"\n"
"DEL [/N /P /T /Q /W /Z] file ...\n"
"DELETE [/N /P /T /Q /W /Z] file ...\n"
"ERASE [/N /P /T /Q /W /Z] file ...\n"
"\n"
" file Specifies the file(s) to delete.\n"
"\n"
" /N Nothing.\n"
" /P Prompts for confirmation before deleting each file.\n"
" (Not implemented yet!)\n"
" /T Display total number of deleted files and freed disk space.\n"
" /Q Quiet.\n"
" /W Wipe. Overwrite the file with zeros before deleting it.\n"
" /Z Zap (delete hidden, read-only and system files).\n"));
return 0;
}
arg = split (param, &args);
if (args > 0)
{
/* check for options anywhere in command line */
for (i = 0; i < args; i++)
{
if (*arg[i] == _T('/'))
{
if (_tcslen (arg[i]) >= 2)
{
switch (_totupper (arg[i][1]))
{
case _T('N'):
dwFlags |= DEL_NOTHING;
break;
case _T('P'):
dwFlags |= DEL_PROMPT;
break;
case _T('Q'):
dwFlags |= DEL_QUIET;
break;
case _T('S'):
dwFlags |= DEL_SUBDIR;
break;
case _T('T'):
dwFlags |= DEL_TOTAL;
break;
case _T('W'):
dwFlags |= DEL_WIPE;
break;
case _T('Z'):
dwFlags |= DEL_ZAP;
break;
}
}
nEvalArgs++;
}
}
/* there are only options on the command line --> error!!! */
if (args == nEvalArgs)
{
error_req_param_missing ();
freep (arg);
return 1;
}
/* keep quiet within batch files */
if (bc != NULL)
dwFlags |= DEL_QUIET;
/* check for filenames anywhere in command line */
for (i = 0; i < args; i++)
{
if (!_tcscmp (arg[i], _T("*")) ||
!_tcscmp (arg[i], _T("*.*")))
{
INT res;
res = FilePromptYN (_T("All files in directory will be deleted!\n"
"Are you sure (Y/N)?"));
if ((res == PROMPT_NO) ||
(res == PROMPT_BREAK))
break;
}
if (*arg[i] != _T('/'))
{
#ifdef _DEBUG
ConErrPrintf (_T("File: %s\n"), arg[i]);
#endif
if (_tcschr (arg[i], _T('*')) || _tcschr (arg[i], _T('?')))
{
/* wildcards in filespec */
#ifdef _DEBUG
ConErrPrintf (_T("Wildcards!\n\n"));
#endif
GetFullPathName (arg[i],
MAX_PATH,
szFullPath,
&pFilePart);
#ifdef _DEBUG
ConErrPrintf (_T("Full path: %s\n"), szFullPath);
ConErrPrintf (_T("File part: %s\n"), pFilePart);
#endif
hFile = FindFirstFile (szFullPath, &f);
if (hFile == INVALID_HANDLE_VALUE)
{
error_file_not_found ();
freep (arg);
return 0;
}
do
{
/* ignore "." and ".." */
if (!_tcscmp (f.cFileName, _T(".")) ||
!_tcscmp (f.cFileName, _T("..")))
continue;
_tcscpy (pFilePart, f.cFileName);
#ifdef _DEBUG
ConErrPrintf (_T("Full filename: %s\n"), szFullPath);
#endif
if (!(dwFlags & DEL_QUIET) && !(dwFlags & DEL_TOTAL))
ConErrPrintf (_T("Deleting: %s\n"), szFullPath);
/* delete the file */
if (!(dwFlags & DEL_NOTHING))
{
if (RemoveFile (szFullPath, dwFlags))
{
dwFiles++;
}
else
{
if (dwFlags & DEL_ZAP)
{
if (SetFileAttributes (szFullPath, 0))
{
if (RemoveFile (szFullPath, dwFlags))
{
dwFiles++;
}
else
{
ErrorMessage (GetLastError(), _T(""));
}
}
else
{
ErrorMessage (GetLastError(), _T(""));
}
}
else
{
ErrorMessage (GetLastError(), _T(""));
}
}
}
}
while (FindNextFile (hFile, &f));
FindClose (hFile);
}
else
{
/* no wildcards in filespec */
#ifdef _DEBUG
ConErrPrintf (_T("No Wildcards!\n"));
#endif
GetFullPathName (arg[i],
MAX_PATH,
szFullPath,
&pFilePart);
#ifdef _DEBUG
ConErrPrintf (_T("Full path: %s\n"), szFullPath);
#endif
if (!(dwFlags & DEL_QUIET) && !(dwFlags & DEL_TOTAL))
ConOutPrintf (_T("Deleting %s\n"), szFullPath);
if (!(dwFlags & DEL_NOTHING))
{
if (RemoveFile (szFullPath, dwFlags))
{
dwFiles++;
}
else
{
if (dwFlags & DEL_ZAP)
{
if (SetFileAttributes (szFullPath, 0))
{
if (RemoveFile (szFullPath, dwFlags))
{
dwFiles++;
}
else
{
ErrorMessage (GetLastError(), _T(""));
}
}
else
{
ErrorMessage (GetLastError(), _T(""));
}
}
else
{
ErrorMessage (GetLastError(), _T(""));
}
}
}
}
}
}
}
else
{
/* only command given */
error_req_param_missing ();
freep (arg);
return 1;
}
freep (arg);
if (!(dwFlags & DEL_QUIET))
{
if (dwFiles == 0)
ConOutPrintf (_T(" 0 files deleted\n"));
else
ConOutPrintf (_T(" %lu file%s deleted\n"),
dwFiles,
(dwFiles == 1) ? "" : "s");
}
return 0;
}
#endif

View File

@@ -1,58 +0,0 @@
/*
* DELAY.C - internal command.
*
* clone from 4nt delay command
*
* 30 Aug 1999
* started - Paolo Pantaleo <paolopan@freemail.it>
*
*
*/
#include "config.h"
#ifdef INCLUDE_CMD_DELAY
#include <tchar.h>
#include <windows.h>
#include <stdlib.h>
#include "cmd.h"
INT CommandDelay (LPTSTR cmd, LPTSTR param)
{
DWORD val;
DWORD mul=1000;
if (_tcsncmp (param, _T("/?"), 2) == 0)
{
ConOutPuts(_T(
"pause for n seconds or milliseconds"
"\n"
"DELAY [/m]n\n"
"\n"
" /m specifiy than n are milliseconds\n"
" otherwise n are seconds"));
return 0;
}
if (*param==0)
{
error_req_param_missing ();
return 1;
}
if (_tcsnicmp(param,"/m",2) == 0)
{
mul = 1;
param += 2;
}
val = atoi(param);
Sleep(val*mul);
return 0;
}
#endif /* INCLUDE_CMD_DELAY */

File diff suppressed because it is too large Load Diff

View File

@@ -1,237 +0,0 @@
/*
* DIRSTACK.C - pushd / pop (directory stack) internal commands.
*
*
* History:
*
* 14-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Implemented PUSHD and POPD command.
*
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode and redirection safe!
*
* 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added DIRS command.
*/
#include "config.h"
#ifdef FEATURE_DIRECTORY_STACK
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include "cmd.h"
typedef struct tagDIRENTRY
{
struct tagDIRENTRY *prev;
struct tagDIRENTRY *next;
LPTSTR pszPath;
} DIRENTRY, *LPDIRENTRY;
static INT nStackDepth;
static LPDIRENTRY lpStackTop;
static LPDIRENTRY lpStackBottom;
static INT
PushDirectory (LPTSTR pszPath)
{
LPDIRENTRY lpDir;
lpDir = (LPDIRENTRY)malloc (sizeof (DIRENTRY));
if (!lpDir)
{
error_out_of_memory ();
return -1;
}
lpDir->prev = NULL;
if (lpStackTop == NULL)
{
lpDir->next = NULL;
lpStackBottom = lpDir;
}
else
{
lpDir->next = lpStackTop;
lpStackTop->prev = lpDir;
}
lpStackTop = lpDir;
lpDir->pszPath = (LPTSTR)malloc ((_tcslen(pszPath)+1)*sizeof(TCHAR));
if (!lpDir->pszPath)
{
free (lpDir);
error_out_of_memory ();
return -1;
}
_tcscpy (lpDir->pszPath, pszPath);
nStackDepth++;
return 0;
}
static VOID
PopDirectory (VOID)
{
LPDIRENTRY lpDir;
if (nStackDepth == 0)
return;
lpDir = lpStackTop;
lpStackTop = lpDir->next;
if (lpStackTop != NULL)
lpStackTop->prev = NULL;
else
lpStackBottom = NULL;
free (lpDir->pszPath);
free (lpDir);
nStackDepth--;
}
static VOID
GetDirectoryStackTop (LPTSTR pszPath)
{
if (lpStackTop)
_tcsncpy (pszPath, lpStackTop->pszPath, MAX_PATH);
else
*pszPath = _T('\0');
}
/*
* initialize directory stack
*/
VOID InitDirectoryStack (VOID)
{
nStackDepth = 0;
lpStackTop = NULL;
lpStackBottom = NULL;
}
/*
* destroy directory stack
*/
VOID DestroyDirectoryStack (VOID)
{
while (nStackDepth)
PopDirectory ();
}
INT GetDirectoryStackDepth (VOID)
{
return nStackDepth;
}
/*
* pushd command
*/
INT CommandPushd (LPTSTR first, LPTSTR rest)
{
TCHAR curPath[MAX_PATH];
TCHAR newPath[MAX_PATH];
BOOL bChangePath = FALSE;
if (!_tcsncmp (rest, _T("/?"), 2))
{
ConOutPuts (_T("Stores the current directory for use by the POPD command, then\n"
"changes to the specified directory.\n\n"
"PUSHD [path | ..]\n\n"
" path Specifies the directory to make the current directory"));
return 0;
}
if (rest[0] != _T('\0'))
{
GetFullPathName (rest, MAX_PATH, newPath, NULL);
bChangePath = IsValidPathName (newPath);
}
GetCurrentDirectory (MAX_PATH, curPath);
if (PushDirectory (curPath))
return 0;
if (bChangePath)
SetCurrentDirectory (newPath);
return 0;
}
/*
* popd command
*/
INT CommandPopd (LPTSTR first, LPTSTR rest)
{
TCHAR szPath[MAX_PATH];
if (!_tcsncmp(rest, _T("/?"), 2))
{
ConOutPuts (_T("Changes to the directory stored by the PUSHD command.\n\n"
"POPD"));
return 0;
}
if (GetDirectoryStackDepth () == 0)
return 0;
GetDirectoryStackTop (szPath);
PopDirectory ();
SetCurrentDirectory (szPath);
return 0;
}
/*
* dirs command
*/
INT CommandDirs (LPTSTR first, LPTSTR rest)
{
LPDIRENTRY lpDir;
if (!_tcsncmp(rest, _T("/?"), 2))
{
ConOutPuts (_T("Prints the contents of the directory stack.\n"
"\n"
"DIRS"));
return 0;
}
lpDir = lpStackBottom;
if (lpDir == NULL)
{
ConOutPuts (_T("Directory stack empty"));
return 0;
}
while (lpDir != NULL)
{
ConOutPuts (lpDir->pszPath);
lpDir = lpDir->prev;
}
return 0;
}
#endif /* FEATURE_DIRECTORY_STACK */

View File

@@ -1,148 +0,0 @@
/* $Id: echo.c,v 1.4 2000/07/19 06:58:13 ekohl Exp $
*
* ECHO.C - internal echo commands.
*
*
* History:
*
* 16 Jul 1998 (Hans B Pufal)
* Started.
*
* 16 Jul 1998 (John P Price)
* Separated commands into individual files.
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* Added config.h include
*
* 08-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added help text ("/?").
*
* 19-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode and redirection ready!
*
* 13-Jul-2000 (Eric Kohl <ekohl@rz-online.de>)
* Implemented 'echo.' and 'echoerr.'.
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include "cmd.h"
#include "batch.h"
INT CommandEcho (LPTSTR cmd, LPTSTR param)
{
#ifdef _DEBUG
DebugPrintf ("CommandEcho '%s' : '%s'\n", cmd, param);
#endif
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts ("Displays a message or switches command echoing on or off.\n"
"\n"
" ECHO [ON | OFF]\n"
" ECHO [message]\n"
" ECHO. prints an empty line\n"
"\n"
"Type ECHO without a parameter to display the current ECHO setting.");
return 0;
}
if (_tcsicmp (cmd, _T("echo.")) == 0)
{
if (param[0] == 0)
ConOutChar (_T('\n'));
else
ConOutPuts (param);
}
else
{
if (_tcsicmp (param, D_OFF) == 0)
bEcho = FALSE;
else if (_tcsicmp (param, D_ON) == 0)
bEcho = TRUE;
else if (*param)
ConOutPuts (param);
else
ConOutPrintf (_T("ECHO is %s\n"), bEcho ? D_ON : D_OFF);
}
return 0;
}
INT CommandEchos (LPTSTR cmd, LPTSTR param)
{
#ifdef _DEBUG
DebugPrintf ("CommandEchos '%s' : '%s'\n", cmd, param);
#endif
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts ("Display a messages without trailing carridge return and line feed.\n"
"\n"
" ECHOS message");
return 0;
}
if (*param)
ConOutPrintf ("%s", param);
return 0;
}
INT CommandEchoerr (LPTSTR cmd, LPTSTR param)
{
#ifdef _DEBUG
DebugPrintf ("CommandEchoerr '%s' : '%s'\n", cmd, param);
#endif
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts ("Displays a message to the standard error.\n"
"\n"
" ECHOERR message\n"
" ECHOERR. prints an empty line");
return 0;
}
if (_tcsicmp (cmd, _T("echoerr.")) == 0)
{
if (param[0] == 0)
ConErrChar (_T('\n'));
else
ConErrPuts (param);
}
else if (*param)
{
ConErrPuts (param);
}
return 0;
}
INT CommandEchoserr (LPTSTR cmd, LPTSTR param)
{
#ifdef _DEBUG
DebugPrintf ("CommandEchoserr '%s' : '%s'\n", cmd, param);
#endif
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts ("Prints a messages to standard error output without trailing carridge return and line feed.\n"
"\n"
" ECHOSERR message");
return 0;
}
if (*param)
ConOutPrintf (_T("%s"), param);
return 0;
}
/* EOF */

View File

@@ -1,175 +0,0 @@
/*
* ERROR.C - error reporting functions.
*
*
* History:
*
* 07/12/98 (Rob Lake)
* started
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 24-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Redirection safe!
*
* 02-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Use FormatMessage() for error reports.
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdarg.h>
#include "cmd.h"
#define INVALID_SWITCH _T("Invalid switch - /%c\n")
#define TOO_MANY_PARAMETERS _T("Too many parameters - %s\n")
#define PATH_NOT_FOUND _T("Path not found\n")
#define FILE_NOT_FOUND _T("File not found\n")
#define REQ_PARAM_MISSING _T("Required parameter missing\n")
#define INVALID_DRIVE _T("Invalid drive specification\n")
#define INVALID_PARAM_FORMAT _T("Invalid parameter format - %s\n")
#define BADCOMMAND _T("Bad command or filename\n")
#define OUT_OF_MEMORY _T("Out of memory error.\n")
#define CANNOTPIPE _T("Error! Cannot pipe! Cannot open temporary file!\n")
#define D_PAUSEMSG _T("Press any key to continue . . .")
VOID ErrorMessage (DWORD dwErrorCode, LPTSTR szFormat, ...)
{
TCHAR szMessage[1024];
LPTSTR szError;
va_list arg_ptr;
if (dwErrorCode == ERROR_SUCCESS)
return;
va_start (arg_ptr, szFormat);
_vstprintf (szMessage, szFormat, arg_ptr);
va_end (arg_ptr);
#ifndef __REACTOS__
if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&szError, 0, NULL))
{
ConErrPrintf (_T("%s %s\n"), szError, szMessage);
LocalFree (szError);
return;
}
else
{
ConErrPrintf (_T("Unknown error! Error code: 0x%lx\n"), dwErrorCode);
return;
}
#else
switch (dwErrorCode)
{
case ERROR_FILE_NOT_FOUND:
szError = _T("File not found --");
break;
case ERROR_PATH_NOT_FOUND:
szError = _T("Path not found --");
break;
default:
ConErrPrintf (_T("Unknown error! Error code: 0x%lx\n"), dwErrorCode);
return;
}
ConErrPrintf (_T("%s %s\n"), szError, szMessage);
#endif
}
VOID error_invalid_switch (TCHAR ch)
{
ConErrPrintf (INVALID_SWITCH, ch);
}
VOID error_too_many_parameters (LPTSTR s)
{
ConErrPrintf (TOO_MANY_PARAMETERS, s);
}
VOID error_path_not_found (VOID)
{
ConErrPrintf (PATH_NOT_FOUND);
}
VOID error_file_not_found (VOID)
{
ConErrPrintf (FILE_NOT_FOUND);
}
VOID error_sfile_not_found (LPTSTR f)
{
ConErrPrintf (FILE_NOT_FOUND _T(" - %s\n"), f);
}
VOID error_req_param_missing (VOID)
{
ConErrPrintf (REQ_PARAM_MISSING);
}
VOID error_invalid_drive (VOID)
{
ConErrPrintf (INVALID_DRIVE);
}
VOID error_bad_command (VOID)
{
ConErrPrintf (BADCOMMAND);
}
VOID error_no_pipe (VOID)
{
ConErrPrintf (CANNOTPIPE);
}
VOID error_out_of_memory (VOID)
{
ConErrPrintf (OUT_OF_MEMORY);
}
VOID error_invalid_parameter_format (LPTSTR s)
{
ConErrPrintf (INVALID_PARAM_FORMAT, s);
}
VOID error_syntax (LPTSTR s)
{
if (s)
ConErrPrintf (_T("Syntax error - %s\n"), s);
else
ConErrPrintf (_T("Syntax error.\n"));
}
VOID msg_pause (VOID)
{
ConOutPuts (D_PAUSEMSG);
}

View File

@@ -1,285 +0,0 @@
/*
* FILECOMP.C - handles filename completion.
*
*
* Comments:
*
* 30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* moved from command.c file
* made second TAB display list of filename matches
* made filename be lower case if last character typed is lower case
*
* 25-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Cleanup. Unicode safe!
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "cmd.h"
#ifdef FEATURE_UNIX_FILENAME_COMPLETION
VOID CompleteFilename (LPTSTR str, INT charcount)
{
WIN32_FIND_DATA file;
HANDLE hFile;
INT curplace = 0;
INT start;
INT count;
BOOL found_dot = FALSE;
BOOL perfectmatch = TRUE;
TCHAR path[MAX_PATH];
TCHAR fname[MAX_PATH];
TCHAR maxmatch[MAX_PATH] = _T("");
TCHAR directory[MAX_PATH];
LPCOMMAND cmds_ptr;
/* expand current file name */
count = charcount - 1;
if (count < 0)
count = 0;
/* find front of word */
while (count > 0 && str[count] != _T(' '))
count--;
/* if not at beginning, go forward 1 */
if (str[count] == _T(' '))
count++;
start = count;
/* extract directory from word */
_tcscpy (directory, &str[start]);
curplace = _tcslen (directory) - 1;
while (curplace >= 0 && directory[curplace] != _T('\\') &&
directory[curplace] != _T(':'))
{
directory[curplace] = 0;
curplace--;
}
_tcscpy (path, &str[start]);
/* look for a '.' in the filename */
for (count = _tcslen (directory); path[count] != _T('\0'); count++)
{
if (path[count] == _T('.'))
{
found_dot = TRUE;
break;
}
}
if (found_dot)
_tcscat (path, _T("*"));
else
_tcscat (path, _T("*.*"));
/* current fname */
curplace = 0;
hFile = FindFirstFile (path, &file);
if (hFile != INVALID_HANDLE_VALUE)
{
/* find anything */
do
{
/* ignore "." and ".." */
if (!_tcscmp (file.cFileName, _T(".")) ||
!_tcscmp (file.cFileName, _T("..")))
continue;
_tcscpy (fname, file.cFileName);
if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
_tcscat (fname, _T("\\"));
else
_tcscat (fname, _T(" "));
if (!maxmatch[0] && perfectmatch)
{
_tcscpy(maxmatch, fname);
}
else
{
for (count = 0; maxmatch[count] && fname[count]; count++)
{
if (tolower(maxmatch[count]) != tolower(fname[count]))
{
perfectmatch = FALSE;
maxmatch[count] = 0;
break;
}
}
}
}
while (FindNextFile (hFile, &file));
FindClose (hFile);
if( perfectmatch )
{
str[start] = '\"';
_tcscpy (&str[start+1], directory);
_tcscat (&str[start], maxmatch);
_tcscat (&str[start], "\"" );
}
else
#ifdef __REACTOS__
Beep (440, 50);
#else
MessageBeep (-1);
#endif
}
else
{
/* no match found - search for internal command */
for (cmds_ptr = cmds; cmds_ptr->name; cmds_ptr++)
{
if (!_tcsnicmp (&str[start], cmds_ptr->name,
_tcslen (&str[start])))
{
/* return the mach only if it is unique */
if (_tcsnicmp (&str[start], (cmds_ptr+1)->name, _tcslen (&str[start])))
_tcscpy (&str[start], cmds_ptr->name);
break;
}
}
#ifdef __REACTOS__
Beep (440, 50);
#else
MessageBeep (-1);
#endif
}
}
/*
* returns 1 if at least one match, else returns 0
*/
BOOL ShowCompletionMatches (LPTSTR str, INT charcount)
{
WIN32_FIND_DATA file;
HANDLE hFile;
BOOL found_dot = FALSE;
INT curplace = 0;
INT start;
INT count;
TCHAR path[MAX_PATH];
TCHAR fname[MAX_PATH];
TCHAR directory[MAX_PATH];
/* expand current file name */
count = charcount - 1;
if (count < 0)
count = 0;
/* find front of word */
while (count > 0 && str[count] != _T(' '))
count--;
/* if not at beginning, go forward 1 */
if (str[count] == _T(' '))
count++;
start = count;
/* extract directory from word */
_tcscpy (directory, &str[start]);
curplace = _tcslen (directory) - 1;
while (curplace >= 0 &&
directory[curplace] != _T('\\') &&
directory[curplace] != _T(':'))
{
directory[curplace] = 0;
curplace--;
}
_tcscpy (path, &str[start]);
/* look for a . in the filename */
for (count = _tcslen (directory); path[count] != _T('\0'); count++)
{
if (path[count] == _T('.'))
{
found_dot = TRUE;
break;
}
}
if (found_dot)
_tcscat (path, _T("*"));
else
_tcscat (path, _T("*.*"));
/* current fname */
curplace = 0;
hFile = FindFirstFile (path, &file);
if (hFile != INVALID_HANDLE_VALUE)
{
/* find anything */
ConOutChar (_T('\n'));
count = 0;
do
{
/* ignore . and .. */
if (!_tcscmp (file.cFileName, _T(".")) ||
!_tcscmp (file.cFileName, _T("..")))
continue;
if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
_stprintf (fname, _T("[%s]"), file.cFileName);
else
_tcscpy (fname, file.cFileName);
ConOutPrintf (_T("%-14s"), fname);
if (++count == 5)
{
ConOutChar (_T('\n'));
count = 0;
}
}
while (FindNextFile (hFile, &file));
FindClose (hFile);
if (count)
ConOutChar (_T('\n'));
}
else
{
/* no match found */
#ifdef __REACTOS__
Beep (440, 50);
#else
MessageBeep (-1);
#endif
return FALSE;
}
return TRUE;
}
#endif
#ifdef FEATURE_4NT_FILENAME_COMPLETION
//static VOID BuildFilenameMatchList (...)
// VOID CompleteFilenameNext (LPTSTR, INT)
// VOID CompleteFilenamePrev (LPTSTR, INT)
// VOID RemoveFilenameMatchList (VOID)
#endif

View File

@@ -1,61 +0,0 @@
Archive Contents
~~~~~~~~~~~~~~~~
bugs.txt Bug List
files.txt This file list
history.txt History of the shell development
license.txt GNU license - applies to all files named here
readme.txt General shell info
todo.txt What I have to do
wishlist.txt Wish List
makefile experimental makefile
makefile.lcc makefile for lcc-win
alias.c Alias code
alias.h Alias header file
attrib.c Implements attrib command
batch.c Batch file interpreter
beep.c Implements beep command
call.c Implements call command
chcp.c Implements chcp command
choice.c Implements choice command
cls.c Implements cls command
cmdinput.c Command-line input functions
cmdtable.c Table of available internal commands
cmd.c Main code for command-line interpreter
cmd.h Command header file
color.c Implements color command
console.c Windows console handling code
copy.c Implements copy command
date.c Implements date command
del.c Implements del command
dir.c Directory listing code
dirstack.c Directory stack code (PUSHD and POPD)
echo.c Implements echo command
error.c Error Message Routines
filecomp.c Filename completion functions
for.c Implements for command
free.c Implements free command
goto.c Implements goto command
history.c Command-line history handling
if.c Implements if command
internal.c Internal commands (DIR, RD, etc)
label.c Implements label command
locale.c Locale handling code
memory.c Implements memory command
misc.c Misc. Functions
msgbox.c Implements msgbox command
move.c Implements move command
path.c Implements path command
pause.c Implements pause command
prompt.c Prompt handling functions
redir.c Redirection and piping parsing functions
ren.c Implements rename command
set.c Implements set command
shift.c Implements shift command
time.c Implements time command
timer.c Implements timer command
type.c Implements type command
ver.c Implements ver command
where.c Code to search path for executables
verify.c Implements verify command

View File

@@ -1,157 +0,0 @@
/*
* FOR.C - for internal batch command.
*
*
* History:
*
* 16-Jul-1998 (Hans B Pufal)
* Started.
*
* 16-Jul-1998 (John P Price)
* Seperated commands into individual files.
*
* 19-Jul-1998 (Hans B Pufal)
* Implementation of FOR.
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* Added config.h include.
*
* 20-Jan-1999 (Eric Kohl)
* Unicode and redirection safe!
*
* 01-Sep-1999 (Eric Kohl)
* Added help text.
*
* 23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.se>)
* Implemented preservation of echo flag. Some other for related
* code in other files fixed, too.
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmd.h"
#include "batch.h"
/*
* Perform FOR command.
*
* First check syntax is correct : FOR %v IN ( <list> ) DO <command>
* v must be alphabetic, <command> must not be empty.
*
* If all is correct build a new bcontext structure which preserves
* the necessary information so that readbatchline can expand
* each the command prototype for each list element.
*
* You might look on a FOR as being a called batch file with one line
* per list element.
*/
INT cmd_for (LPTSTR cmd, LPTSTR param)
{
LPBATCH_CONTEXT lpNew;
LPTSTR pp;
TCHAR var;
#ifdef _DEBUG
DebugPrintf ("cmd_for (\'%s\', \'%s\'\n", cmd, param);
#endif
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Runs a specified command for each file in a set of files\n"
"\n"
"FOR %variable IN (set) DO command [parameters]\n"
"\n"
" %variable Specifies a replaceable parameter.\n"
" (set) Specifies a set of one or more files. Wildcards may be used.\n"
" command Specifies the command to carry out for each file.\n"
" parameters Specifies parameters or switches for the specified command.\n"
"\n"
"To user the FOR comamnd in a batch program, specify %%variable instead of\n"
"%variable."));
return 0;
}
/* Check that first element is % then an alpha char followed by space */
if ((*param != _T('%')) || !_istalpha (*(param + 1)) || !_istspace (*(param + 2)))
{
error_syntax (_T("bad variable specification."));
return 1;
}
param++;
var = *param++; /* Save FOR var name */
while (_istspace (*param))
param++;
/* Check next element is 'IN' */
if ((_tcsnicmp (param, _T("in"), 2) != 0) || !_istspace (*(param + 2)))
{
error_syntax (_T("'in' missing in for statement."));
return 1;
}
param += 2;
while (_istspace (*param))
param++;
/* Folowed by a '(', find also matching ')' */
if ((*param != _T('(')) || (NULL == (pp = _tcsrchr (param, _T(')')))))
{
error_syntax (_T("no brackets found."));
return 1;
}
*pp++ = _T('\0');
param++; /* param now points at null terminated list */
while (_istspace (*pp))
pp++;
/* Check DO follows */
if ((_tcsnicmp (pp, _T("do"), 2) != 0) || !_istspace (*(pp + 2)))
{
error_syntax (_T("'do' missing."));
return 1;
}
pp += 2;
while (_istspace (*pp))
pp++;
/* Check that command tail is not empty */
if (*pp == _T('\0'))
{
error_syntax (_T("no command after 'do'."));
return 1;
}
/* OK all is correct, build a bcontext.... */
lpNew = (LPBATCH_CONTEXT)malloc (sizeof (BATCH_CONTEXT));
lpNew->prev = bc;
bc = lpNew;
bc->hBatchFile = INVALID_HANDLE_VALUE;
bc->ffind = NULL;
bc->params = BatchParams (_T(""), param); /* Split out list */
bc->shiftlevel = 0;
bc->forvar = var;
bc->forproto = _tcsdup (pp);
if (bc->prev)
bc->bEcho = bc->prev->bEcho;
else
bc->bEcho = bEcho;
return 0;
}
/* EOF */

View File

@@ -1,165 +0,0 @@
/*
* FREE.C - internal command.
*
*
* History:
*
* 01-Sep-1999 (Eric Kohl)
* Started.
*/
#include "config.h"
#ifdef INCLUDE_CMD_FREE
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "cmd.h"
/*
* convert
*
* insert commas into a number
*/
static INT
ConvertULargeInteger (ULARGE_INTEGER num, LPTSTR des, INT len)
{
TCHAR temp[32];
INT c = 0;
INT n = 0;
if (num.QuadPart == 0)
{
des[0] = _T('0');
des[1] = _T('\0');
n = 1;
}
else
{
temp[31] = 0;
while (num.QuadPart > 0)
{
if (((c + 1) % (nNumberGroups + 1)) == 0)
temp[30 - c++] = cThousandSeparator;
temp[30 - c++] = (TCHAR)(num.QuadPart % 10) + _T('0');
num.QuadPart /= 10;
}
for (n = 0; n <= c; n++)
des[n] = temp[31 - c + n];
}
return n;
}
static VOID
PrintDiskInfo (LPTSTR szDisk)
{
TCHAR szRootPath[4] = "A:\\";
TCHAR szDrive[2] = "A";
TCHAR szVolume[64];
TCHAR szSerial[10];
TCHAR szTotal[40];
TCHAR szUsed[40];
TCHAR szFree[40];
DWORD dwSerial;
ULARGE_INTEGER uliSize;
DWORD dwSecPerCl;
DWORD dwBytPerSec;
DWORD dwFreeCl;
DWORD dwTotCl;
if (_tcslen (szDisk) < 2 || szDisk[1] != _T(':'))
{
ConErrPrintf (_T("Invalid drive %s\n"), szDisk);
return;
}
szRootPath[0] = szDisk[0];
szDrive[0] = _totupper (szRootPath[0]);
if (!GetVolumeInformation (szRootPath, szVolume, 64, &dwSerial,
NULL, NULL, NULL, 0))
{
ConErrPrintf (_T("Invalid drive %s:\n"), szDrive);
return;
}
if (szVolume[0] == _T('\0'))
_tcscpy (szVolume, _T("unlabeled"));
_stprintf (szSerial,
_T("%04X-%04X"),
HIWORD(dwSerial),
LOWORD(dwSerial));
if (!GetDiskFreeSpace (szRootPath, &dwSecPerCl,
&dwBytPerSec, &dwFreeCl, &dwTotCl))
{
ConErrPrintf (_T("Invalid drive %s:\n"), szDrive);
return;
}
uliSize.QuadPart = dwSecPerCl * dwBytPerSec * dwTotCl;
ConvertULargeInteger (uliSize, szTotal, 40);
uliSize.QuadPart = dwSecPerCl * dwBytPerSec * (dwTotCl - dwFreeCl);
ConvertULargeInteger (uliSize, szUsed, 40);
uliSize.QuadPart = dwSecPerCl * dwBytPerSec * dwFreeCl;
ConvertULargeInteger (uliSize, szFree, 40);
ConOutPrintf (_T("\n"
" Volume in drive %s is %-11s Serial number is %s\n"
" %16s bytes total disk space\n"
" %16s bytes used\n"
" %16s bytes free\n"),
szDrive, szVolume, szSerial,
szTotal, szUsed, szFree);
}
INT CommandFree (LPTSTR cmd, LPTSTR param)
{
LPTSTR szParam;
TCHAR szDefPath[MAX_PATH];
INT argc, i;
LPTSTR *arg;
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Displays drive information.\n"
"\n"
"FREE [drive: ...]"));
return 0;
}
if (!param || *param == _T('\0'))
{
GetCurrentDirectory (MAX_PATH, szDefPath);
szDefPath[2] = _T('\0');
szParam = szDefPath;
}
else
szParam = param;
arg = split (szParam, &argc);
for (i = 0; i < argc; i++)
PrintDiskInfo (arg[i]);
freep (arg);
return 0;
}
#endif /* INCLUDE_CMD_FREE */
/* EOF */

View File

@@ -1,109 +0,0 @@
/*
* GOTO.C - goto internal batch command.
*
* History:
*
* 16 Jul 1998 (Hans B Pufal)
* started.
*
* 16 Jul 1998 (John P Price)
* Seperated commands into individual files.
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 28 Jul 1998 (Hans B Pufal) [HBP_003]
* Terminate label on first space character, use only first 8 chars of
* label string
*
* 24-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode and redirection safe!
*
* 27-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added help text ("/?").
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <ctype.h>
#include "cmd.h"
#include "batch.h"
/*
* Perform GOTO command.
*
* Only valid if batch file current.
*
*/
INT cmd_goto (LPTSTR cmd, LPTSTR param)
{
LPTSTR tmp;
LONG lNewPosHigh;
#ifdef _DEBUG
DebugPrintf ("cmd_goto (\'%s\', \'%s\'\n", cmd, param);
#endif
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Directs CMD to a labeled line in a batch script.\n"
"\n"
"GOTO label\n"
"\n"
" label Specifies a text string used in a batch script as a label.\n"
"\n"
"You type a label on a line by itself, beginning with a colon."));
return 0;
}
/* if not in batch -- error!! */
if (bc == NULL)
{
return 1;
}
if (*param == _T('\0'))
{
ExitBatch (_T("No label specified for GOTO\n"));
return 1;
}
/* terminate label at first space char */
tmp = param;
while (*tmp && !_istspace (*tmp))
tmp++;
*tmp = _T('\0');
/* set file pointer to the beginning of the batch file */
lNewPosHigh = 0;
SetFilePointer (bc->hBatchFile, 0, &lNewPosHigh, FILE_BEGIN);
while (FileGetString (bc->hBatchFile, textline, sizeof(textline)))
{
/* Strip out any trailing spaces or control chars */
tmp = textline + _tcslen (textline) - 1;
while (_istcntrl (*tmp) || _istspace (*tmp))
tmp--;
*(tmp + 1) = _T('\0');
/* Then leading spaces... */
tmp = textline;
while (_istspace (*tmp))
tmp++;
/* use only 1st 8 chars of label */
if ((*tmp == _T(':')) && (_tcsncmp (++tmp, param, 8) == 0))
return 0;
}
ConErrPrintf (_T("Label '%s' not found\n"), param);
ExitBatch (NULL);
return 1;
}

View File

@@ -1,526 +0,0 @@
/*
* HISTORY.C - command line history.
*
*
* History:
*
* 14/01/95 (Tim Norman)
* started.
*
* 08/08/95 (Matt Rains)
* i have cleaned up the source code. changes now bring this source
* into guidelines for recommended programming practice.
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 25-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Cleanup!
* Unicode and redirection safe!
*
* 25-Jan-1999 (Paolo Pantaleo <paolopan@freemail.it>)
* Added lots of comments (beginning studying the source)
* Added command.com's F3 support (see cmdinput.c)
*
*/
/*
* HISTORY.C - command line history. Second version
*
*
* History:
*
* 06/12/99 (Paolo Pantaleo <paolopan@freemail.it>)
* started.
*
*/
#include "config.h"
#ifdef FEATURE_HISTORY
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmd.h"
typedef struct tagHISTORY
{
struct tagHISTORY *prev;
struct tagHISTORY *next;
LPTSTR string;
} HIST_ENTRY, * LPHIST_ENTRY;
static INT size,
max_size=100;
static LPHIST_ENTRY Top;
static LPHIST_ENTRY Bottom;
static LPHIST_ENTRY curr_ptr=0;
VOID InitHistory(VOID);
VOID History_move_to_bottom(VOID);
VOID History (INT dir, LPTSTR commandline);
VOID CleanHistory(VOID);
VOID History_del_current_entry(LPTSTR str);
/*service functions*/
static VOID del(LPHIST_ENTRY item);
static VOID add_at_bottom(LPTSTR string);
/*VOID add_before_last(LPTSTR string);*/
VOID set_size(INT new_size);
INT CommandHistory (LPTSTR cmd, LPTSTR param)
{
LPTSTR tmp;
INT tmp_int;
LPHIST_ENTRY h_tmp;
TCHAR szBuffer[2048];
tmp=_tcschr(param,_T('/'));
if (tmp)
{
param=tmp;
switch (_totupper(param[1]))
{
case _T('F'):/*delete history*/
CleanHistory();InitHistory();
break;
case _T('R'):/*read history from standard in*/
//hIn=GetStdHandle (STD_INPUT_HANDLE);
for(;;)
{
ConInString(szBuffer,sizeof(szBuffer)/sizeof(TCHAR));
if (*szBuffer!=_T('\0'))
History(0,szBuffer);
else
break;
}
break;
case _T('A'):/*add an antry*/
History(0,param+2);
break;
case _T('S'):/*set history size*/
if ((tmp_int=_ttoi(param+2)))
set_size(tmp_int);
break;
default:
return 1;
}
}
else
{
for(h_tmp=Top->prev;h_tmp!=Bottom;h_tmp=h_tmp->prev)
ConErrPuts(h_tmp->string);
}
return 0;
}
VOID set_size(INT new_size)
{
while(new_size<size)
del(Top->prev);
max_size=new_size;
}
VOID InitHistory(VOID)
{
size=0;
Top = malloc(sizeof(HIST_ENTRY));
Bottom = malloc(sizeof(HIST_ENTRY));
Top->prev = Bottom;
Top->next = NULL;
Top->string = NULL;
Bottom->prev = NULL;
Bottom->next = Top;
Bottom->string = NULL;
curr_ptr=Bottom;
}
VOID CleanHistory(VOID)
{
while (Bottom->next!=Top)
del(Bottom->next);
free(Top);
free(Bottom);
}
VOID History_del_current_entry(LPTSTR str)
{
LPHIST_ENTRY tmp;
if (size==0)
return;
if(curr_ptr==Bottom)
curr_ptr=Bottom->next;
if(curr_ptr==Top)
curr_ptr=Top->prev;
tmp=curr_ptr;
curr_ptr=curr_ptr->prev;
del(tmp);
History(-1,str);
}
static
VOID del(LPHIST_ENTRY item)
{
if( item==NULL || item==Top || item==Bottom )
{
#ifdef _DEBUG
DebugPrintf("del in " __FILE__ ": retrning\n"
"item is 0x%08x (Bottom is0x%08x)\n",
item, Bottom);
#endif
return;
}
/*free string's mem*/
if (item->string)
free(item->string);
/*set links in prev and next item*/
item->next->prev=item->prev;
item->prev->next=item->next;
free(item);
size--;
}
#if 0
static
VOID add_before_last(LPTSTR string)
{
LPHIST_ENTRY tmp,before,after;
/*delete first entry if maximum number of entries is reached*/
while(size>=max_size)
del(Top->prev);
while (_istspace(*string))
string++;
if (*string==_T('\0'))
return;
/*allocte entry and string*/
tmp=malloc(sizeof(HIST_ENTRY));
tmp->string=malloc(_tcslen(string)+1);
_tcscpy(tmp->string,string);
/*set links*/
before=Bottom->next;
after=before->next;
tmp->prev=before;
tmp->next=after;
after->prev=tmp;
before->next=tmp;
/*set new size*/
size++;
}
#endif/*0*/
static
VOID add_at_bottom(LPTSTR string)
{
LPHIST_ENTRY tmp;
/*delete first entry if maximum number of entries is reached*/
while(size>=max_size)
del(Top->prev);
while (_istspace(*string))
string++;
if (*string==_T('\0'))
return;
/*if new entry is the same than the last do not add it*/
if(size)
if(_tcscmp(string,Bottom->next->string)==0)
return;
/*fill bottom with string, it will become Bottom->next*/
Bottom->string=malloc(_tcslen(string)+1);
_tcscpy(Bottom->string,string);
/*save Bottom value*/
tmp=Bottom;
/*create new void Bottom*/
Bottom=malloc(sizeof(HIST_ENTRY));
Bottom->next=tmp;
Bottom->prev=NULL;
Bottom->string=NULL;
tmp->prev=Bottom;
/*set new size*/
size++;
}
VOID History_move_to_bottom(VOID)
{
curr_ptr=Bottom;
}
VOID History (INT dir, LPTSTR commandline)
{
if(dir==0)
{
add_at_bottom(commandline);
curr_ptr=Bottom;
return;
}
if (size==0)
{
commandline[0]=_T('\0');
return;
}
if(dir<0)/*key up*/
{
if (curr_ptr->next==Top || curr_ptr==Top)
{
#ifdef WRAP_HISTORY
curr_ptr=Bottom;
#else
curr_ptr=Top;
commandline[0]=_T('\0');
return;
#endif
}
curr_ptr = curr_ptr->next;
if(curr_ptr->string)
_tcscpy(commandline,curr_ptr->string);
}
if(dir>0)
{
if (curr_ptr->prev==Bottom || curr_ptr==Bottom)
{
#ifdef WRAP_HISTORY
curr_ptr=Top;
#else
curr_ptr=Bottom;
commandline[0]=_T('\0');
return;
#endif
}
curr_ptr=curr_ptr->prev;
if(curr_ptr->string)
_tcscpy(commandline,curr_ptr->string);
}
}
#if 0
LPTSTR history = NULL; /*buffer to sotre all the lines*/
LPTSTR lines[MAXLINES]; /*array of pointers to each line(entry)*/
/*located in history buffer*/
INT curline = 0; /*the last line recalled by user*/
INT numlines = 0; /*number of entries, included the last*/
/*empty one*/
INT maxpos = 0; /*index of last byte of last entry*/
VOID History (INT dir, LPTSTR commandline)
{
INT count; /*used in for loops*/
INT length; /*used in the same loops of count*/
/*both to make room when is full
either history or lines*/
/*first time History is called allocate mem*/
if (!history)
{
history = malloc (history_size * sizeof (TCHAR));
lines[0] = history;
history[0] = 0;
}
if (dir > 0)
{
/* next command */
if (curline < numlines)
{
curline++;
}
if (curline == numlines)
{
commandline[0] = 0;
}
else
{
_tcscpy (commandline, lines[curline]);
}
}
else if (dir < 0)
{
/* prev command */
if (curline > 0)
{
curline--;
}
_tcscpy (commandline, lines[curline]);
}
else
{
/* add to history */
/* remove oldest string until there's enough room for next one */
/* strlen (commandline) must be less than history_size! */
while ((maxpos + (INT)_tcslen (commandline) + 1 > history_size) || (numlines >= MAXLINES))
{
length = _tcslen (lines[0]) + 1;
for (count = 0; count < maxpos && count + (lines[1] - lines[0]) < history_size; count++)
{
history[count] = history[count + length];
}
maxpos -= length;
for (count = 0; count <= numlines && count < MAXLINES; count++)
{
lines[count] = lines[count + 1] - length;
}
numlines--;
#ifdef DEBUG
ConOutPrintf (_T("Reduced size: %ld lines\n"), numlines);
for (count = 0; count < numlines; count++)
{
ConOutPrintf (_T("%d: %s\n"), count, lines[count]);
}
#endif
}
/*copy entry in the history bufer*/
_tcscpy (lines[numlines], commandline);
numlines++;
/*set last lines[numlines] pointer next the end of last, valid,
just setted entry (the two lines above)*/
lines[numlines] = lines[numlines - 1] + _tcslen (commandline) + 1;
maxpos += _tcslen (commandline) + 1;
/* last line, empty */
curline = numlines;
}
return;
}
#endif
#endif //#if 0

View File

@@ -1,367 +0,0 @@
FreeDOS Command Line Interface Development History
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11/11/94 version 0.01
~~~~~~~~~~~~~~~~~~~~~
o initial release.
01/01/95 version 0.10
~~~~~~~~~~~~~~~~~~~~~
o removed some scaffolding.
o modified CD.
o added tab file completion.
o added command line history.
01/15/95 version 0.20
~~~~~~~~~~~~~~~~~~~~~
o formatted all existing source modules.
o added prompt support.
o added drive selection.
o added dir command.
o started this development log.
08/06/95 prerelease of version 0.30
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o reorganized code into separate source modules.
o added batch processing support (thanks to Evan Jeffrey).
o added exec code (thanks to Steffan Kaiser).
o removed environment handling (thanks again to Steffan Kaiser)
[ 08/08/95 -- Matt Rains ]
o formatted this development log.
o formatted all existing source modules so that they comply with recommended
programming practice.
o added MD command.
o added RD command.
o added VER command.
o replaced CD command.
o modified DIR command.
o DIR now called regardless of other DIR.??? files. this is done because of
exec() problems.
12/10/95 version 0.30
~~~~~~~~~~~~~~~~~~~~~
o used Borland's spawnve to fix exec problem
o fixed CD again so you don't need a space after it
o couple of spelling fixes
12/14/95 version 0.31
~~~~~~~~~~~~~~~~~~~~~
o modified cmdinput.c to work with non-standard screen sizes (see 28.com)
o fixed a bug in history.c that made it not work when you hit the up arrow
on the first line
o fixed DIR to work a little more like MS-DOS's DIR (see internal.c)
o fixed some code in where.c to make things a bit more efficient and nicer
01/06/96 version 0.40 (never released)
~~~~~~~~~~~~~~~~~~~~~
o added redirection and piping support!!! (see redir.c and command.c)
o fixed a stupid pointer problem in where.c that was causing LOTS of
problems in the strangest places...
o added day of the week support to prompt.c (oops, that was already supposed
to be there! :)
o fixed and reorganized the EXEC code!!! Thanks to Svante Frey!
o reorganized command.c and internal.c to handle parsing internal commands
more efficiently and consistently.
o changed the behavior of MD, CD, RD to work without spaces (e.g. CD\DOS)
o small changes here and there to make it work with redirection/piping
(e.g. DIR only pauses if you're not doing redirection)
01/17/96 version 0.50
~~~~~~~~~~~~~~~~~~~~~
Version 0.40 was never released because I was home on Christmas vacation,
and I couldn't upload it. By the time I got back to school, I had the
LOADHIGH patch from Svante Frey, so I decided to jump up to 0.50 without any
release of 0.40... - Tim Norman
o LOADHIGH/LOADFIX/LH support added!!!! Many thanks go to Svante Frey!
o bug fixed in command parsing that didn't handle / switches correctly...
o removed debugging output from history.c
07/26/96 version 0.60
~~~~~~~~~~~~~~~~~~~~~
Lots of internal changes here... Not much added to the interface.
o Changed internals to use first,rest parameters instead of arrays of params
o Fixed some bugs
o Some other things I don't remember :)
07/26/96 version 0.61
~~~~~~~~~~~~~~~~~~~~~
Bugfixes
o Added hook to the PATH command
o Fixed CD.. bug
08/27/96 version 0.70
~~~~~~~~~~~~~~~~~~~~~
Finally added Oliver Mueller's ALIAS command! Also numerous bug fixes.
o Added ALIAS command
o Removed support for - as a switch in LOADHIGH.C
o Bugfixes in BATCH.C. %0 was returning garbage
o Removed lots of unused variables, reducing # of warnings when compiling
o Other miscellaneous code clean-ups
o Changed WHERE.C to use a little less memory
06/14/97 version 0.71
~~~~~~~~~~~~~~~~~~~~~
Lots of bug fixes, plus some additional features.
o New DIR command. Now more like MS-DOS's DIR. /p supported, /s coming soon
o bug fix in internal.c - parse_firstarg
o Rewrote parser in batch.c (Steffan Kaiser)
o Ctrl-Break checking in various places (Steffan Kaiser)
o Error level setting/checking (%? in batch files) (Steffan Kaiser)
o bug fix in cmdinput.c ("%i" on command-line caused weird behavior)
o bug fix in where.c (first item in path wasn't searched)
07/12/97 version 0.72
~~~~~~~~~~~~~~~~~~~~~
More bug fixes and code cleanup
o Rewrote cmdinput.c to be more efficient (Marc Desrochers)
o Added insert/overstrike modes (Marc Desrochers)
o Replaced findxy() with pointers into BIOS (maxx, maxy) (Marc Desrochers)
o Fixed bug that disallowed listing of root directories
o Fixed bug that didn't search the first path (again!)
07/13/97 version 0.72b
~~~~~~~~~~~~~~~~~~~~~~
Disabled a feature that caused a crash on some machines.
o Replaced setcursor calls in cmdinput.c with _setcursortype
o Added dir.c to the distribution (was left out in 0.72)
07/01/98 version 0.73 (Rob Lake)
~~~~~~~~~~~~~~~~~~~~~~
o New DIR commands supported: /S, /B, /L, /A and /W.
(/R changed to /S). Also /? added.
o Supports DIRCMD in environment.
o Supports turning off commands with hyphen (ex. /-S
turns off recursive listing)
o Changed error messages for DIR and DEL to more MS-DOS'ish
o Moved error messages from DIR.C and DEL.C to COMMAND.H
(more may go there soon)
o Fixed bug that caused dir *.ext/X not to work (no spaces
between filespec and slash)
o Added wildcard support for DEL command
o Added prompt and help switch for DEL command, /P and /?
respectively.
o Added support for /C when envoking the shell
o Added /P support when Kernel loads shell. This means
the shell now is permanent and runs the autoexec.bat
(/E is not implemented)
o Added my name (Rob Lake) to the developer listing
o Changed version routine to print out copyright notice
with no args, and with appropriate switches, warranty
and redistribution notices and developer listing
07/08/1998 version 0.74 (John P. Price (linux-guru@gcfl.net))
~~~~~~~~~~~~~~~~~~~~~~~~
COMMAND.C/COMMAND.H:
o Now sets COMSPEC environment variable
o misc clean up and optimization
o added date, time and type commands
o changed to using spawnl instead of exec. exec does not copy the
environment to the child process!
DIR.C
o removed extra returns; closer to MSDOS
o fixed wide display so that an extra return is not displayed when
there is five filenames in the last line.
ENVIRON.C
o commented out show_environment function. Not used anymore.
INTERAL.C
o removed call to show_environment in set command.
o moved test for syntax before allocating memory in set command.
o misc clean up and optimization.
o created DATE.C
o created TIME.C
o created TYPE.C
07/08/1998 version 0.74b (John P. Price (linux-guru@gcfl.net))
~~~~~~~~~~~~~~~~~~~~~~~~
COMMAND.C
o fixed call to spawnl so that it would pass command line arguments
correctly.
07/12/98 version 0.74c (Rob Lake rlake@cs.mun.ca)
~~~~~~~~~~~~~~~~~~~~~~
Various Files:
o removed redundant use of error message defines and moved
error printing calls to ERROR.C to reduced program size.
o created MISC.C
o created ERR_HAND.C/H
o created ERROR.C
07/13/98 version 0.74d (Rob Lake rlake@cs.mun.ca)
~~~~~~~~~~~~~~~~~~~~~~
INTERNAL.C
o removed most of the commands and placed them in there own file
-- del, ren, set and ver
o created DEL.C, REN.C SET.C and VER.C
o fixed bug that caused del not to delete files with no attributes
o the critical error handler count number of times called, autofails
at 5 calls
16 Jul 1998 (Hans B Pufal <hansp@digiweb.com>)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
batch.c
A new version, implements CALL, ECHO, GOT, IF, PAUSE, SHIFT and
BEEP. There is a stub for FOR but that's all.
cmdtable.c
New file to keep the internal command table. I plan on getting rid
of the table real soon now and replacing it with a dynamic
mechanism.
command.c
A new (improved ;) version. Conforms closely to MS-DOS specs.
Cleaned up (and fixed) the redirection handler.
command.h
Version D with changes. Look for the HBP tag.
redir.c
Modified file, now supports append redirects.
16 Jul 1998 (Rob Lake rlake@cs.mun.ca)
~~~~~~~~~~~~~~~~~~~~~~
Added TRUENAME command.
19 Jul 1998 (Hans B Pufal) <hansp@digiweb.com>)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Preserve state of echo flag across batch calls.
o Implementation of FOR command
20 Jul 1998 (John P Price <linux-guru@gcfl.net>)
~~~~~~~~~~~~~~~~~~~~~~
o Fixed bug in DATE.C.
o Fixed bug in LH.ASM.
o Separated commands into individual files.
28 Jul 1998 (John P Price <linux-guru@gcfl.net>)
~~~~~~~~~~~~~~~~~~~~~~
o Added CLS command.
o Put ifdef's around all commands and added include file config.h
Now you can define exact what commands you want to include in
command.com.
o Also added ifdefs for optional features: aliases, command history
and filename completion.
o Added display of available internal commands and options at startup.
29 Jul 1998 (Rob Lake rlake@cs.mun.ca)
~~~~~~~~~~~~~~~~~~~~~~
o changed date.c and time.c, and wrote datefunc.c and timefunc.c to
impliment _dos_getdate, _dos_setdate, _dos_gettime and _dos_settime.
This is the first of many steps to make the shell compatible under
Pacific C.
30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
~~~~~~~~~~~~~~~~~~~~~~
o Changed filename completion so that a second TAB displays a list of
matching filenames!
o made filename be lower case if last character typed is lower case.
o Moved filename completion code to filecomp.c.
o Change ver command to display email address to report bugs, and the
web page address for updates.
o fixed so that it find_which returns NULL if filename is not
executable (does not have .bat, .com, or .exe extension). Before
command would to execute any file with any extension. (opps!)
30-Jul-1998 (John P Price <linux-guru@gcfl.net>)
~~~~~~~~~~~~~~~~~~~~~~
o Fixed bug where if you typed something, then hit HOME, then tried to
type something else in insert mode, it locked up.
o Changed default insert mode to on. There should be a way to change
this. Maybe options to doskey command.
o Added VERIFY command
02-Aug-1998 (Hans B Pufal) <hansp@digiweb.com>)
~~~~~~~~~~~~~~~~~~~~~~
o batch.c: Fixed bug in ECHO flag restoration at exit from batch file
o command.c: Fixed return value when called with /C option
o Terminate label on first space character, use only first 8 chars of
label string
04-Aug-1998 (Hans B Pufal) <hansp@digiweb.com>)
~~~~~~~~~~~~~~~~~~~~~~
o call.c: added lines to initialize for pointers. This fixed the
lock-up that happened sometimes when calling a batch file from
another batch file.
07-Aug-1998 (John P Price <linux-guru@gcfl.net>)
~~~~~~~~~~~~~~~~~~~~~~
o Fixed carrage return output to better match MSDOS with echo on or off.
07-Dec-1998 ReactOS CMD version 0.0.1 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o First test release.
o Added internal ATTRIB command.
11-Dec-1998 ReactOS CMD version 0.0.2 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Fixed bug in ALIAS. CMD crashed when you tried to remove an alias.
o Fixed bug in split(). Added freep(). This fixed the DEL command.
o Improved ATTRIB command.
o Added most help texts.
o Fixed recursive DIR ("dir /s").
o Fixed DATE and TIME command. Now they accept values when used
without parameter.
o Implemented LABEL command.
05-Jan-1999 ReactOS CMD version 0.0.3 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Added COLOR command and "/t" option.
o Cursor shows insert/overwrite mode.
o COMSPEC environment variable is set upon startup.
o Started COPY command.
o Started MOVE command.
o Added directory stack (PUSHD and POPD commands).
o Added support for file names or paths that contain spaces
(quoted paths / file names).
o Added recursion to ATTRIB command.
o Added locale support for DIR, DATE, TIME and PROMPT.
o Fixed VERIFY.
10-Feb-1999 ReactOS CMD version 0.0.4 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o "?" lists all available commands.
o Most commands are unicode and redirection aware now.
o Input-, Output- and Error-Redirections works with most commands.
o ATTRIB and DEL can handle multiple filenames now.
o Fixed handling of environment variables.
o Added CHCP command.
o Fixed keyboard input bug.
o Rewrote DEL and MOVE commands.
28-Dec-1999 ReactOS CMD version 0.1 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Cleaned up DIR command.
o Searching for executables in the right order.
o Fixed some little but nasty bugs.
o Added TITLE command. Thanks to Emanuele Aliberti!
o Added "/Q", "/W" and "/Z" options to DEL command.
o Added CHOICE, TIMER, FREE and MEMORY commands.
o Added MSGBOX command (not available under ReactOS).
o Added and fixed missing help texts.
o Fixed bugs in MD and RD that crashed cmd when no directory was specified.
o Improved history support.
o Improved COLOR command.
09-Apr-2000 ReactOS CMD version 0.1 (EricKohl <ekohl@rz-online.de>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Fixed bug in COPY command. CMD crashed if source file didn't exist.
13-Jul-2000 ReactOS CMD version 0.1.1 (EricKohl <ekohl@rz-online.de>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
o Implemented 'ECHO.' and 'ECHOERR.' commands.

View File

@@ -1,212 +0,0 @@
/*
* IF.C - if internal batch command.
*
*
* History:
*
* 16 Jul 1998 (Hans B Pufal)
* started.
*
* 16 Jul 1998 (John P Price)
* Seperated commands into individual files.
*
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
* added config.h include
*
* 07-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Added help text ("if /?") and cleaned up.
*
* 21-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Unicode and redirection ready!
*
* 01-Sep-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
* Fixed help text.
*
* 17-Feb-2001 (ea)
* IF DEFINED variable command
*/
#include "config.h"
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <ctype.h>
#include "cmd.h"
#include "batch.h"
#define X_EXEC 1
#define X_EMPTY 0x80
INT cmd_if (LPTSTR cmd, LPTSTR param)
{
INT x_flag = 0; /* when set cause 'then' clause to be executed */
LPTSTR pp;
#ifdef _DEBUG
DebugPrintf ("cmd_if: (\'%s\', \'%s\'\n", cmd, param);
#endif
if (!_tcsncmp (param, _T("/?"), 2))
{
ConOutPuts (_T("Performs conditional processing in batch programs.\n"
"\n"
" IF [NOT] ERRORLEVEL number command\n"
" IF [NOT] string1==string2 command\n"
" IF [NOT] EXIST filename command\n"
" IF [NOT] DEFINED variable command\n"
"\n"
"NOT Specifies that CMD should carry out the command only if\n"
" the condition is false\n"
"ERRORLEVEL number Specifies a true condition if the last program run returned\n"
" an exit code equal or greater than the number specified.\n"
"command Specifies the command to carry out if the condition is met.\n"
"string1==string2 Specifies a true condition if the specified text strings\n"
" match.\n"
"EXIST filename Specifies a true condition if the specified filename exists.\n"
"DEFINED variable Specifies a true condition if the specified variable is\n"
" defined."));
return 0;
}
/* First check if param string begins with word 'not' */
if (!_tcsnicmp (param, _T("not"), 3) && _istspace (*(param + 3)))
{
x_flag = X_EXEC; /* Remember 'NOT' */
param += 3; /* Step over 'NOT' */
while (_istspace (*param)) /* And subsequent spaces */
param++;
}
/* Check for 'exist' form */
if (!_tcsnicmp (param, _T("exist"), 5) && _istspace (*(param + 5)))
{
param += 5;
while (_istspace (*param))
param++;
pp = param;
while (*pp && !_istspace (*pp))
pp++;
if (*pp)
{
WIN32_FIND_DATA f;
HANDLE hFind;
*pp++ = _T('\0');
hFind = FindFirstFile (param, &f);
x_flag ^= (hFind == INVALID_HANDLE_VALUE) ? 0 : X_EXEC;
if (hFind != INVALID_HANDLE_VALUE)
{
FindClose (hFind);
}
}
else
return 0;
}
/* Check for 'defined' form */
else if (!_tcsnicmp (param, _T("defined"), 7) && _istspace (*(param + 7)))
{
TCHAR Value [1];
INT ValueSize = 0;
param += 7;
/* IF [NOT] DEFINED var COMMAND */
/* ^ */
while (_istspace (*param))
param++;
/* IF [NOT] DEFINED var COMMAND */
/* ^ */
pp = param;
while (*pp && !_istspace (*pp))
pp++;
/* IF [NOT] DEFINED var COMMAND */
/* ^ */
if (*pp)
{
*pp++ = _T('\0');
ValueSize = GetEnvironmentVariable(param, Value, sizeof Value);
x_flag ^= (0 == ValueSize)
? 0
: X_EXEC;
x_flag |= X_EMPTY;
}
else
return 0;
}
/* Check for 'errorlevel' form */
else if (!_tcsnicmp (param, _T("errorlevel"), 10) && _istspace (*(param + 10)))
{
INT n = 0;
pp = param + 10;
while (_istspace (*pp))
pp++;
while (_istdigit (*pp))
n = n * 10 + (*pp++ - _T('0'));
x_flag ^= (nErrorLevel < n) ? 0 : X_EXEC;
x_flag |= X_EMPTY; /* Syntax error if comd empty */
}
/* Check that '==' is present, syntax error if not */
else if (NULL == (pp = _tcsstr (param, _T("=="))))
{
error_syntax (NULL);
return 1;
}
else
{
/* Change first '='to space to terminate comparison loop */
*pp = _T(' '); /* Need a space to terminate comparison loop */
pp += 2; /* over '==' */
while (_istspace (*pp)) /* Skip subsequent spaces */
pp++;
_tcscat (pp, _T(" ")); /* Add one space to ensure comparison ends */
while (*param == *pp) /* Comparison loop */
{
if (_istspace (*param)) /* Terminates on space */
break;
param++, pp++;
}
if (x_flag ^= (*param != *pp) ? 0 : X_EXEC)
{
while (*pp && !_istspace (*pp)) /* Find first space, */
pp++;
x_flag |= X_EMPTY;
}
}
if (x_flag & X_EMPTY)
{
while (_istspace (*pp)) /* Then skip spaces */
pp++;
if (*pp == _T('\0')) /* If nothing left then syntax err */
{
error_syntax (NULL);
return 1;
}
}
if (x_flag & X_EXEC)
{
ParseCommandLine (pp);
}
return 0;
}

Some files were not shown because too many files have changed in this diff Show More