Compare commits

..

9 Commits

Author SHA1 Message Date
The ReactOS Team
efb17a2783 This commit was manufactured by cvs2svn to create tag 'krnl0011'.
svn path=/tags/krnl0011/; revision=41
1998-09-13 15:55:55 +00:00
Rex Jolliff
5c1b8a026c Import of KRNL0011
svn path=/branches/ros/; revision=39
1998-09-13 15:55:55 +00:00
The ReactOS Team
02b00d9c04 This commit was manufactured by cvs2svn to create branch 'ros'.
svn path=/branches/ros/; revision=38
1998-09-13 15:55:55 +00:00
Rex Jolliff
935b7c2953 upgrade to krnl0010
svn path=/branches/ros/; revision=30
1998-09-05 17:34:23 +00:00
The ReactOS Team
1b7327da76 This commit was manufactured by cvs2svn to create branch 'ros'.
svn path=/branches/ros/; revision=29
1998-09-05 17:34:23 +00:00
Rex Jolliff
f77c44657c Import of KRNL0009
svn path=/branches/ros/; revision=21
1998-08-28 23:24:42 +00:00
The ReactOS Team
df0328b7cc This commit was manufactured by cvs2svn to create branch 'ros'.
svn path=/branches/ros/; revision=20
1998-08-28 23:24:42 +00:00
Rex Jolliff
94c8483b04 A much Needed Update
svn path=/branches/ros/; revision=10
1998-08-25 04:27:41 +00:00
The ReactOS Team
fc7e59ce74 This commit was manufactured by cvs2svn to create branch 'ros'.
svn path=/branches/ros/; revision=9
1998-08-25 04:27:41 +00:00
725 changed files with 14380 additions and 63245 deletions

View File

@@ -1,6 +0,0 @@
8/12/98: Corrected bug in shell (Read two keypresses and assumed they
where the key going up and down respectively)
Corrected race in dpc handling
Took out cleanup sections in ZwReadFile (now handled by the APC)
Disabled broken code in kernel32

View File

@@ -1,14 +0,0 @@
0.0.14 (so far):
0.0.13: Mostly bugfixes (I think)
0.0.12: Added support for multiple processes (not really tested)
System calls
kernel32 now compiles (only as a static library)
Fixed invalid tss bug (hopefully)
Added section support
Added some of the ZwxxxVirtual calls
Added prototype caching functions (only the Minix fsd actually
uses them)
Added handle access and type checking
Prototype APC implementation (no support for user APCs)

View File

@@ -1,33 +0,0 @@
#include <windows.h>
extern int main(int args, char* argv[], char* environ[]);
static unsigned int _argc = 0;
static char** _argv = NULL;
static char** _environ = NULL;
int mainCRTStartup(PWSTR args)
{
int nRet;
// SetUnhandledExceptionFilter(NULL);
// _fpreset();
// __GetMainArgs(&_argc, &_argv, &_environ, 0);
nRet = main(_argc, _argv, _environ);
// _cexit();
ExitProcess(nRet);
}
int WinMainCRTStartup()
{
return mainCRTStartup(NULL);
}
void __main(void)
{
}

View File

@@ -1,35 +0,0 @@
#include <internal/mmhal.h>
#include <ddk/ntddk.h>
#include <stdarg.h>
#include <string.h>
HANDLE OutputHandle;
HANDLE InputHandle;
void debug_printf(char* fmt, ...)
{
va_list args;
char buffer[255];
va_start(args,fmt);
vsprintf(buffer,fmt,args);
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
va_end(args);
}
void main(int argc, char* argv[])
{
int i;
AllocConsole();
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
for (i=0; i<argc; i++)
{
debug_printf("Args: '%s'\n",argv[i]);
}
}

View File

@@ -1,10 +0,0 @@
all: args.exe
OBJECTS= ../common/crt0.o args.o
LIBS= ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a
args.exe: $(OBJECTS) $(LIBS)
$(CC) -specs=../../specs $(OBJECTS) $(LIBS) -lgcc -o args.exe
$(NM) --numeric-sort args.exe > args.sym
include ../../rules.mak

View File

@@ -1,7 +0,0 @@
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Hello world\n");
return(0);
}

View File

@@ -1,8 +0,0 @@
all: hello.exe
OBJECTS = hello.o
hello.exe: $(OBJECTS) $(LIBS)
$(CC) $(OBJECTS) -o hello.exe
include ../../rules.mak

View File

@@ -1,158 +0,0 @@
#include <stdarg.h>
#include <windows.h>
HANDLE stdin;
HANDLE stdout;
void Console_puts(char* str)
{
ULONG nchar;
WriteConsole(stdout,
str,
strlen(str),
&nchar,
NULL);
}
void Console_printf(char* fmt, ...)
{
char buffer[255];
va_list vargs;
va_start(vargs,fmt);
vsprintf(buffer,fmt,vargs);
Console_puts(buffer);
va_end(vargs);
}
void Console_getline(PCH Prompt, PCH Output, DWORD OutputLength)
{
char ch;
DWORD nbytes;
Console_puts(Prompt);
ReadConsole(stdin,
Output,
OutputLength,
&nbytes,
NULL);
Output[nbytes-2]=0;
}
void func_cd(char* s)
{
Console_printf("Changing directory to %s\n",s);
if (!SetCurrentDirectory(s))
{
Console_puts("Failed to change to directory\n");
}
}
void func_dir(char* s)
{
HANDLE shandle;
WIN32_FIND_DATA FindData;
shandle = FindFirstFile("*.*",&FindData);
if (shandle==INVALID_HANDLE_VALUE)
{
return;
}
do
{
Console_printf("Scanning %s\n",FindData.cFileName);
} while(FindNextFile(shandle,&FindData));
}
int is_builtin(char* name, char* args)
{
if (strcmp(name,"dir")==0)
{
func_dir(args);
return(1);
}
if (strcmp(name,"cd")==0)
{
func_cd(args);
return(1);
}
return(0);
}
int process_command(char* str)
{
char* name;
char* args;
PROCESS_INFORMATION pi;
STARTUPINFO si;
char process_arg[255];
if (strcmp(str,"exit")==0)
{
return(1);
}
name = strtok(str," \t");
args = strtok(NULL,"");
if (is_builtin(name,args))
{
return(0);
}
memset(&si,0,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);
si.lpTitle=strdup(name);
strcpy(process_arg,name);
strcat(process_arg," ");
if(args!=NULL)
{
strcat(process_arg,args);
}
Console_printf("name '%s' process_arg '%s'\n",name,process_arg);
if (!CreateProcess(NULL,process_arg,NULL,NULL,FALSE,
CREATE_NEW_CONSOLE,
NULL,NULL,&si,&pi))
{
Console_printf("Failed to execute process\n");
}
return(0);
}
void build_prompt(char* prompt)
{
int len;
len = GetCurrentDirectory(255,prompt);
strcat(prompt,">");
}
void command_loop()
{
char line[255];
char prompt[255];
int do_exit = 0;
while (!do_exit)
{
build_prompt(prompt);
Console_getline(prompt,line,255);
Console_printf("Processing command '%s'\n",line);
do_exit = process_command(line);
}
}
int STDCALL WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
{
AllocConsole();
stdin = GetStdHandle(STD_INPUT_HANDLE);
stdout = GetStdHandle(STD_OUTPUT_HANDLE);
command_loop();
return 0;
}

View File

@@ -1,12 +0,0 @@
all: cmd.bin
OBJECTS = ../common/crt0.o cmd.o
LIBS = ../../lib/mingw32/mingw32.a ../../lib/crtdll/crtdll.a \
../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a
cmd.bin: $(OBJECTS)
$(LD) -Ttext 0x10000 $(OBJECTS) $(LIBS) -o cmd.exe
$(OBJCOPY) -O binary cmd.exe cmd.bin
include ../../rules.mak

View File

@@ -1,10 +0,0 @@
all: shell.exe
OBJECTS= ../common/crt0.o shell.o
LIBS= ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a
shell.exe: $(OBJECTS) $(LIBS)
$(CC) -specs=../../specs $(OBJECTS) $(LIBS) -lgcc -o shell.exe
$(NM) --numeric-sort shell.exe > shell.sym
include ../../rules.mak

View File

@@ -1,221 +0,0 @@
#include <internal/mmhal.h>
#include <ddk/ntddk.h>
#include <stdarg.h>
#include <string.h>
HANDLE InputHandle, OutputHandle;
void debug_printf(char* fmt, ...)
{
va_list args;
char buffer[255];
va_start(args,fmt);
vsprintf(buffer,fmt,args);
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
va_end(args);
}
void ExecuteCd(char* cmdline)
{
if (!SetCurrentDirectoryA(cmdline))
{
debug_printf("Invalid directory\n");
}
}
void ExecuteDir(char* cmdline)
{
HANDLE shandle;
WIN32_FIND_DATA FindData;
int nFile=0,nRep=0;
TIME_FIELDS fTime;
shandle = FindFirstFile("*",&FindData);
if (shandle==INVALID_HANDLE_VALUE)
{
debug_printf("Invalid directory\n");
return;
}
do
{
debug_printf("%-15.15s",FindData.cAlternateFileName);
if(FindData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
debug_printf("<REP> "),nRep++;
else
debug_printf(" %10d ",FindData.nFileSizeLow),nFile++;
// RtlTimeToTimeFields(&FindData.ftLastWriteTime ,&fTime);
// debug_printf("%02d/%02d/%04d %02d:%02d:%02d "
// ,fTime.Month,fTime.Day,fTime.Year
// ,fTime.Hour,fTime.Minute,fTime.Second);
debug_printf("%s\n",FindData.cFileName);
} while(FindNextFile(shandle,&FindData));
debug_printf("\n %d files\n %d directories\n\n",nFile,nRep);
FindClose(shandle);
}
void ExecuteType(char* cmdline)
{
HANDLE FileHandle;
char c;
DWORD Result;
FileHandle = CreateFile(cmdline,
FILE_GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (FileHandle == NULL)
{
debug_printf("Unknown file\n");
return;
}
while (ReadFile(FileHandle,
&c,
1,
&Result,
NULL))
{
debug_printf("%c",c);
c = 0;
}
CloseHandle(FileHandle);
}
int ExecuteProcess(char* name, char* cmdline)
{
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo;
char arguments;
BOOL ret;
memset(&StartupInfo,0,sizeof(StartupInfo));
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.lpTitle = name;
ret = CreateProcessA(name,
cmdline,
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
if (ret)
{
WaitForSingleObject(ProcessInformation.hProcess,INFINITE);
}
return(ret);
}
void ExecuteCommand(char* line)
{
char* cmd;
char* tail;
if (isalpha(line[0]) && line[1] == ':' && line[2] == 0)
{
line[2] = '\\';
line[3] = 0;
SetCurrentDirectoryA(line);
return;
}
tail = line;
while ((*tail)!=' ' && (*tail)!=0)
{
tail++;
}
if ((*tail)==' ')
{
*tail = 0;
tail++;
}
cmd = line;
if (cmd==NULL)
{
return;
}
if (strcmp(cmd,"cd")==0)
{
ExecuteCd(tail);
return;
}
if (strcmp(cmd,"dir")==0)
{
ExecuteDir(tail);
return;
}
if (strcmp(cmd,"type")==0)
{
ExecuteType(tail);
return;
}
if (strcmp(cmd,"exit")==0)
{
ExitProcess(0);
return;
}
if (ExecuteProcess(cmd,tail))
{
return;
}
debug_printf("Unknown command\n");
}
void ReadLine(char* line)
{
KEY_EVENT_RECORD KeyEvent;
DWORD Result;
UCHAR CurrentDir[255];
char ch;
GetCurrentDirectoryA(255,CurrentDir);
debug_printf(CurrentDir);
do
{
if (!ReadConsoleA(InputHandle,
&ch,
1,
&Result,
NULL))
{
debug_printf("Failed to read from console\n");
for(;;);
}
debug_printf("%c", ch);
*line = ch;
line++;
} while (ch != '\n');
line--;
*line = 0;
}
void main()
{
static char line[255];
AllocConsole();
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
debug_printf("Shell Starting...\n");
SetCurrentDirectoryA("C:\\");
for(;;)
{
ReadLine(line);
ExecuteCommand(line);
}
}

View File

@@ -1 +1 @@
loadros kimage.bin ide.o vfatfsd.o keyboard.o
loaders\dos\loadros ntoskrnl\kimage.bin %1 %2 %3 %4

View File

@@ -1,40 +0,0 @@
@ECHO OFF
:
: copy files to HD...
:
COPY /Y BLUE.SYS C:\reactos\system\drivers\blue.SYS
COPY /Y KEYBOARD.SYS C:\reactos\system\drivers\KEYBOARD.SYS
COPY /Y NTDLL.DLL C:\reactos\system\NTDLL.DLL
: COPY /Y CRTDLL.DLL C:\reactos\system\CRTDLL.DLL
COPY /Y SHELL.EXE C:\reactos\system\SHELL.EXE
:
: present a menu to the booter...
:
ECHO 1) Keyboard,IDE,VFatFSD
ECHO 2) IDE,VFatFSD
ECHO 3) No Drivers
CHOICE /C:123 /T:2,3 "Select kernel boot config"
IF ERRORLEVEL 3 GOTO :L3
IF ERRORLEVEL 2 GOTO :L2
:L1
CLS
LOADROS NTOSKRNL.EXE KEYBOARD.O IDE.SYS VFATFSD.SYS
GOTO :END
:L2
CLS
LOADROS NTOSKRNL.EXE IDE.SYS VFATFSD.SYS
GOTO :END
:L3
CLS
LOADROS NTOSKRNL.EXE
GOTO :END
:END
EXIT

View File

@@ -1,94 +0,0 @@
This is the file "copying.dj". It does NOT apply to any sources or
binaries copyrighted by UCB Berkeley, the Free Software Foundation, or
any other agency besides DJ Delorie and others who have agreed to
allow their sources to be distributed under these terms.
Copyright Information for sources and executables that are marked
Copyright (C) DJ Delorie
7 Kim Lane
Rochester NH 03867-2954
This document is Copyright (C) DJ Delorie and may be distributed
verbatim, but changing it is not allowed.
Source code copyright DJ Delorie is distributed under the terms of the
GNU General Public Licence, with the following exceptions:
* Sources used to build crt0.o, gcrt0.o, libc.a, libdbg.a, and
libemu.a are distributed under the terms of the GNU Library General
Public License, rather than the GNU GPL.
* Any existing copyright or authorship information in any given source
file must remain intact. If you modify a source file, a notice to that
effect must be added to the authorship information in the source file.
* Runtime binaries, as provided by DJ in DJGPP, may be distributed
without sources ONLY if the recipient is given sufficient information
to obtain a copy of djgpp themselves. This primarily applies to
go32-v2.exe, emu387.dxe, and stubedit.exe.
* Runtime objects and libraries, as provided by DJ in DJGPP, when
linked into an application, may be distributed without sources ONLY
if the recipient is given sufficient information to obtain a copy of
djgpp themselves. This primarily applies to crt0.o and libc.a.
-----
Changes to source code copyright BSD or FSF by DJ Delorie fall under
the terms of the original copyright.
A copy of the files "COPYING" and "COPYING.LIB" are included with this
document. If you did not receive a copy of these files, you may
obtain one from whence this document was obtained, or by writing:
Free Software Foundation
675 Mass Ave
Cambridge, MA 02139
USA

340
reactos/copying_rex Normal file
View File

@@ -0,0 +1,340 @@
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,22 +0,0 @@
DIRECTORIES
system : compiled versions of the various system components and
libraries
ntoskrnl : kernel source
ntoskrnl/hal : hardware abstraction layer source
ntoskrnl/mm : memory managment subsystem source
ntoskrnl/io : IO manager subsystem source
ntoskrnl/ke : kernel source
include : win32 headers
include/internal : kernel private header files
include/ntdll : system library private header files
include/kernel32 : system library private header files
include/ddk : header files for modules
lib/ntdll : NT dll source
lib/kernel32 : kernel32 source
doc : documentation
loaders/dos : DOS based loader
loaders/boot : boot loader
services : various services (device drivers, filesystems etc)
services/dd : device drivers
services/fs : file systems

View File

@@ -1,130 +0,0 @@
* Introduction
Having successfully built ReactOS and been amazed by what it does, you're
now desperate to fill in some of the omissions, this document shows you how.
* Prerequisites
A working knowledge of NT driver development is useful for understanding the
kernel and some of its abstractions. The NT4 ddk is available for free
download from http://www.microsoft.com/hwdev/. The Windows 98 and Windows
2000 DDKs are also available but the NT4 one is the most useful. See
Legal Stuff below however.
There are a number of books on NT driver development, I would recommend
'Windows NT Device Driver Development' (http://www.osr.com/book/) since OSR
seem to know their stuff. There is only one book on NT filesystem
development 'Windows NT File System Internals'. Please don't buy any of
these books unless you need to, and can afford it.
These mailing lists and newsgroups are useful for NT internals related
questions,
ntfsd@atria.com, ntdev@atria.com
(subscribe by email to majordomo@atria.com)
comp.os.????
microsoft.public.????
* Style
There is no coding style used for ReactOS, however the following guidelines
make things easier
Include information at the top of a module about its purpose, contact
information for its programmer and any useful notes.
Include a comment by each non-trival function describing its arguments,
purpose and any other notes.
Update the documentation in this directory
These guidelines are an ideal, no one manages to implement them all the
time, straightforward working code is probably just as good.
* Debugging
Debugging kernel-mode code is tricky, these are some snippets
DbgPrint writes a message to the console using a printf style format
string. The DPRINT macro (defined in internal/debug.h) expands to
DbgPrint unless NDEBUG is defined, this is useful for having copious
output from a module only when a problem is being debugging. DPRINT
also prefixes the message with the file and line number to make it
easier to see where output is coming from. DbgPrint can be used at any
point including in interrupt handlers.
There are options in ntoskrnl/hal/x86/printk.c for copying DbgPrint
output to a serial device (parallel support should also be added). This
can be useful if a lot of output is being generated.
It should be possible to include support for debugging the kernel with
gdb over a serial line. Bochs (a shareware CPU emulator) is also useful
for debugging the kernel, I wrote some patches to allow capture of console
output from within bochs to file and for debugging a kernel running
under bochs with gdb. Contact me (welch@cwcom.net) if you're are
interested.
If CPU reports an exception not handled by the kernel (any page fault
not part of virtual memory support or any other exception) the kernel
will display output like this and halt
General Protection Fault Exception: 13(0)
CS:EIP xxxxxxxx:xxxxxxx
DS xxxx ES xxxx FS xxxx GS xxxxx
EAX: xxxx EBX: xxxx
....
EDI: xxxx EFLAGS: xxxx ESP: xxxx
cr2: xxxx
Stack: xxxx xxxx xxxx ...
....
Frames: xxxx xxxx xxxx ...
....
The fault type will usually be either 'General Protection' or
'Page Fault', see your Intel manual for the more exotic types. The
'EIP' number is the address of the faulting instruction. If the 'CS'
number is 0x20 then the exception occured in kernel mode, if it is 0x11
then the exception occurred in user mode. 'cr2' is the address that the
faulting instruction was trying to access, if the exception was a page
fault. The number printed after 'Frames' are any addresses on the stack
that look like function addresses.
If the kernel detects a serious problem that it will bug check, displaying
output like this
Bug detected (code x, param x x x x)
Frames: xxx xxxx xxxx
....
Again the numbers printed after 'Frames' are any addresses on the stack
that look like function addresss. Usually the kernel will also print a
message describing the problem in more detail, the bug check code isn't
very useful at the moment.
* Contacts
There is a mailing list for kernel development,
ros-kernel@sid-dis.com
The main developers use a cvs account to coordinate changes, ask
rex (rex@lvcablemodem.com) for an account if you are going to be adding
a lot of code. Smaller patches can go to the mailing list or to the
relevant developer (usually the comment at the top of a module will have
an email address). Regular snapshots are made available for download,
see the mailing list for announcements.
* Legal stuff
The ReactOS project is GPL'ed, please make sure any code submitted is
compatible with this.
The NT4 ddk license agreement allows its usage for developing nt drivers
only. Legally therefore it can not be used to develop ReactOS, neither the
documentation or the sample code. I'm not a lawyer, but I doubt the
effiacy of 'shrinkwrap licenses' particularly on freely downloadable
software. The only precendent I know of, in a Scottish court, didn't
upload this type of license.
Also the 'fair use' section of copyright law allows the 'quoting' of small
sections from copyrighted documents, e.g. Windows API or DDK documentation

View File

@@ -1,6 +0,0 @@
HACKING: Some notes for adding code to ReactOS
DIRS: Explanation of directory layout
INTERNALS: Some notes on kernel internals
TODO: Bugs and omissions, big and little things that need to be done
NOTES: Unsorted material, some of it is redundant
BUGLIST: Known bugs, please update when you find one

View File

@@ -1,43 +0,0 @@
A collection of articles on kernel internals, please add to this
------------------------------------------------------------------------------
IRQ level
------------------------------------------------------------------------------
IRQ level (IRQL) is a per-processor state in ReactOS used to coordinate
execution between ISRs and between threads. There are several levels
PASSIVE_LEVEL, APC_LEVEL: The normal level for user mode and most
kernel mode code. At the moment APC_LEVEL is unused.
DISPATCH_LEVEL: At this level all irqs are still allowed but thread
rescheduling on the current processor is disabled. This is used by
the spinlock synchronization primitive to implement its uniprocessor
semantics (multiprocessor is more complex). It is also used for some
other forms of synchronization, DPCs for example. Many APIs are
unavailable at this IRQL, usually those that might have to wait. It
is recommended that you don't spend too much time at this IRQL
otherwise system responsiveness will be reduced.
> DISPATCH_LEVEL: Each irq is assigned a priority (which will be
greater than DISPATCH_LEVEL). At an irq's priority level that irq,
lower priority irqs and thread rescheduling are disabled. Higher
priority irqs can still run. Very few APIs are available at IRQLs
greater than DISPATCH_LEVEL.
HIGH_LEVEL: All irqs are disabled.
-------------------------------------------------------------------------------
DPCs
-------------------------------------------------------------------------------
It is a design goal not to spend too much time in ISRs, for this reason
ISRs should postpone most processing till it can run at a lower IRQL. The
mechanism for this is a Delayed Procedure Call (DPC). When a DPC object is
created, it is associated with a function. The DPC object can then be inserted
in the DPC queue from an ISR. If the IRQL on return from the ISR is less than
DISPATCH_LEVEL the DPC queue will be drained, otherwise this will happen when
the IRQL level drops below DISPATCH_LEVEL or the processor becomes idle. When
the DPC queue is drained each DPC object is removed and the associated
function is called at DISPATCH_LEVEL. A DPC object can only be inserted once,
further insertions before it is removed will have no effect.

140
reactos/doc/api.txt Normal file
View File

@@ -0,0 +1,140 @@
This file attempts to document the functions made publically available by
the various subsystems.
* Formatted I/O operations *
NAME: int vsprintf(char *buf, const char *fmt, va_list args)
NAME: int sprintf(char* buf, const char* fmt, ...)
WHERE: internal/kernel.h
FUNCTION: The same as the standard c library versions
* PIO operations *
NAME: in[b/w/l](port)
WHERE: internal/io.h
FUNCTION: Read an IO port of the specified size (byte/word or long)
RETURNS: The value read
NAME: out[b/w/l](port,val)
WHERE: internal/io.h
FUNCTION: Write an IO port of the specified size (byte/word or long)
NAME: in_p[b/w/l](port)
WHERE: internal/io.h
FUNCTION: Read an IO port of the specified size (byte/word or long) with
a pause
RETURNS: The value read
NAME: out_p[b/w/l](port,val)
WHERE: internal/io.h
FUNCTION: Write an IO port of the specified size (byte/word or long) with
a pause
* Bit operations *
NAME: int set_bit(int nr, void* addr)
NAME: int clear_bit(int nr, void* addr)
NAME: int change_bit(int nr, void* addr)
WHERE: internal/bitops.h>
FUNCTION: Operate on a bit in the word pointed to by addr
RETURN: 0 if the bit was cleared before the operations
non-zero otherwise
* Debugging functions *
NAME: DPRINT(fmt,....)
WHERE: internal/debug.h
FUNCTION: Outputs a string to the console if NDEBUG isn't defined before
including internal/debug.h, a NOP otherwise
ARGUMENTS: The same as printf
NAME: printk
WHERE: internal/kernel.h
FUNCTION: Outputs a string to the console
ARGUMENTS: The same as printf
* Memory managment functions *
NAME: unsigned int physical_to_linear(unsigned int paddr)
WHERE: hal/page.h
FUNCTION: Converts a physical address to a linear one
RECEIVES:
paddr = the physical address to convert
RETURNS: A virtual address where the memory at that physical address can be
accessed
NAME: void* ExAllocatePool(unsigned int size, unsigned int type = 0);
WHERE: internal/pool.h
FUNCTION: Allocates a block of memory
RECEIVES:
size = the size of the block to allocate
type = will be whether to allocate pagable memory
RETURNS: The address of the block
NOTE: This isn't interrupt safe
NAME: void ExFreePool(void* block)
WHERE: internal/pool.h
FUNCTION: Frees a block of memory
NAME: void free_page(unsigned int physical_base, unsigned int nr = 1)
WHERE: internal/mm.h
FUNCTION: Adds a continuous range of physical memory to the free list
NAME: unsigned int get_free_page(void)
WHERE: internal/mm.h
FUNCTION: Gets a free page
RETURNS: Its physical address
NAME: unsigned int get_page_physical_address(unsigned int vaddr)
WHERE: internal/mm.h
FUNCTION: Gets the physical address of a page
NAME: void mark_page_not_writable(unsigned int vaddr)
WHERE: internal/mm.h
FUNCTION: Prevent writing the page
* DMA functions *
NAME: unsigned int get_dma_page(unsigned int max_address)
WHERE: internal/mm.h
FUNCTION: Gets a page with a restricted physical address i.e. suitable for
dma
RETURNS: The physical address of the page
NAME: void disable_dma(unsigned int dmanr)
WHERE: internal/dma.h
FUNCTION: Disables the specified dma channel
NAME: void enable_dma(unsigned int dmanr)
WHERE: internal/dma.h
FUNCTION: Enables the specified dma channel
NAME: void clear_dma_ff(unsigned int dmanr)
WHERE: internal/dma.h
FUNCTION: Clear the dma flip-flop
NAME: void set_dma_mode(unsigned int dmanr, char mode)
WHERE: internal/dma.h
FUNCTION: Sets the type of dma transfer
NAME: void set_dma_page(unsigned int dmanr, char pagenr)
WHERE: internal/dma.h
FUNCTION: Set only the page register bits of the transfer address
NAME: void set_dma_addr(unsigned int dmanr, unsigned int a)
WHERE: internal/dma.h
FUNCTION: Set the transfer address for dma
NOTE: Assumes flip-flop is clear
NAME: void set_dma_count(unsigned int dmanr, unsigned int count)
WHERE: internal/dma.h
FUNCTION: Sets the size of the transfer
ARGUMENTS:
count = the number of bytes to transfer
NOTE: Count must be even for channels 5-7
NAME: int get_dma_residue(unsigned int dmanr)
WHERE: internal/dma.h
FUNCTION: Gets the residue remaining after a dma transfer on the channel

2
reactos/doc/buglist Normal file
View File

@@ -0,0 +1,2 @@
* Kernel bugs not fixed

27
reactos/doc/ddkfuncs.txt Normal file
View File

@@ -0,0 +1,27 @@
This is a list of the functions documented in the ddk that have been
implemented
IoAllocateController
IoFreeController
IoCreateController
IoDeleteController
IoStartNextPacket
IoStartNextPacketByKey
IoStartPacket
IoSizeOfIrp
IoMarkIrpPending
IoFreeIrp
IoConnectInterrupt
IoDisconnectInterrupt
IoGetCurrentIrpStackLocation
IoGetNextIrpStackLocation
IoRequestDpc
IoInitializeDpc
IoInitializeTimer
IoStartTimer
IoStopTimer
Partially implemented
IoCreateDevice
IoCallDriver

19
reactos/doc/debug.txt Normal file
View File

@@ -0,0 +1,19 @@
Some notes on debugging the ReactOS kernel
------------------------------------------
* Interpreting crashes
If the kernel causes a fatal cpu fault then it will print out a message and
halt. This message contains important information for debugging the problem,
look for these lines
Exception: xx(yy)
CS:EIP 20:zzzzzzzzzzzz
Here xx is the type of error, usually either 14 or 13 and yy is the error
code. Generally error codes 13 and 14 both mean the kernel tried to access
some memory in an invalid way. zzzzzzzzz is the address of the erronous
instruction.
* Debugging with bochs

114
reactos/doc/faq.txt Normal file
View File

@@ -0,0 +1,114 @@
Kernel Development FAQ (for v0.0.7)
This attempts to answer some of the common questions people developing for
the kernel might want to ask (or at least what I think they should ask).
Obviously I can only detail those parts which I have written so other
developers please fill in the gaps.
Q: What is this, what are you people, what's going on
A: This is the ReactOS, an operating system intended as a clone of windows
NT. See the project website (http://www.sid-dis.com/reactos/) for more details.
Q: Why ReactOS
A: To condemn Bill Gates to penury.
Q: What do I need to compile the kernel
A: DJGPP, get it from http://www.delorie.com/djgpp
Q: How do I compile the kernel
A: Unpack the zip. It is important not to install the kernel in the same
directory as a previous version, this has caused a bit of confusion in the
past. Edit the makefile in the top level directory, in particular select the
correct host to build from. Then run make in the top directory
Q: What files are created when I make the kernel
A: The following files are created in the kernel directory
kimage = the kernel as a coff executable
kimage.bin = the kernel as a raw binary image
kernel.sym = a list of the kernel symbols
Q: How do I load the kernel
A: Run the boot.bat batch file.
Q: Does it boot from disk
A: Not at the moment.
Q: When I run the kernel it crashes
A: The kernel (at the moment) can only be loaded from a clean system. That
is one without EMM386 or any version of windows loaded. A quick way to
ensure this (if you have windows 95) is to set the program to run in msdos
mode and specify an empty config.sys and autoexec.bat. See the windows help
for more information.
If you do that and the problem persists then contact the kernel team
(ros-kernel@sid-dis.com) as it is probably a bug in the kernel
Q6: How do I load a module with the kernel
A: Add the names of any modules to be loaded to the command line of boot.bat.
Q7: I want to add code to the kernel, how do I get it to be compiled
A: You will need to edit the Makefile in kernel directory. There should be
a statement like this
OBJECTS = hal/head.o hal/exp.o kernel/vsprintf.o \
....
kernel/irqhand.o hal/page.o mm/virtual.o kernel/error.o \
kernel/exports.o kernel/module.o
Add the name of the object file (the file produced when your code is
compiled) to the end of the statement (in this case after kernel/module.o).
If you need to go onto a new line then add a slash to the end of the
previous line. It is also very important to use an editor which preserves
tabs.
Q8: I want to add code to the kernel, how do I make it official
A: Contact the kernel mailing list ros-kernel@sid-dis.com or our coordinator
dwinkley@whitworth.edu. If it is for a specific section then the kernel
website (http://www.geocities.com/SiliconValley/Peaks/1957) has a list of
those working on individual areas, you might what to contact one of them
instead.
Q9: What header files should I use
A: Don't include the usual DJGPP headers like stdio.h unless you are using
something compiler based like stdargs.h. To use the DJGPP headers requires
linking with libc which is useless in kernel mode.
All the header files are in the top-level include directory which is laid
out like this
include = general win32 api declarations
include/internal = private kernel headers
include/internal/hal = HAL headers
include/ddk = header files with declarations for modules
There should be a file called api.txt which documents all of the functions
(and which header files they need).
Q11: I want to export my function for modules to use, how do I do that
A: Add the function to the list in kernel/exports.lst, then remake the
kernel. Note the function must be declared as extern "C".
Q12: I want to make my functions part of the kernel interface to user mode,
A: That section isn't finished yet, though it will probably mean adding a
pointer to the function and the size of its parameters to a internal table
somewhere.
Q14: I want to write a module, what are the guidelines
A: See modules.txt in this directory
Q15: I want to write an ISR (interrupt service routine)
A: See irq.txt in this directory
Q16: I want to use DMA
A: Firstly this answer covers only DMA via the dma chips *not*
busmaster DMA.
To program the dma chip use the functions in internal/dma.h (look in api.txt
for details). PC DMA can only go to memory with a physical address below
1mb (or 16mb on some systems), use the get_dma_page to allocate this kind
of memory.
Q17: You haven't answered my question
A: Send your questions to ros-kernel@sid-dis.com
- David Welch (welch@mcmail.com)

View File

@@ -0,0 +1,10 @@
This document describes the implementation of the memory managment
* ReactOS memory map
0x00000000 - 0xc0000000 = User memory
0xc0000000 - 0xd0000000 = Kernel memory
0xd0000000 - 0xffffffff = Identify map of physical memory
*

1253
reactos/doc/internal/pe.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
This contains documentation describing the internals of the various kernel
subsystems and a few other useful bits of information.

135
reactos/doc/irq.txt Normal file
View File

@@ -0,0 +1,135 @@
** Introduction
This attempts to document the ReactOS irq handling. As of v0.0.8 this has
changed to be more nt like, I will attempt to summarize the new
implementation for those unavailable with nt device driver writing. Note,
ReactOS doesn't have an exact implementation but the omissions are, except
where noted, not user visible.
** Steps in grabbing an irq vector
* Call HalConnectInterrupt
PROTOTYPE:
ULONG HalGetInterruptVector(INTERFACE_TYPE InterfaceType,
ULONG BusNumber,
ULONG BusInterruptLevel,
ULONG BusInterruptVector,
OUT PKIRQL Irql,
OUT PKAFFINITY Affinity)
PURPOSE:
Translates a bus dependant interrupt vector to a system vector
ARGUMENTS:
InterfaceType = Type of bus to which the device to receive interrupts
from is connected to. Currently only 'Internal' is
recognized
BusNumber = Number of the bus the device is connected to
(currently ignored)
BusInterruptLevel = Bus specific interrupt level (currently ignored)
BusInterruptVector = Bus specific vector. Currently this is the same
as the normal vector (09 is the keyboard vector
for example)
Irql = On return contains the DIRQL for the vector
Affinity = On return contains the affinity mask for the vector
(currently unimplemented)
RETURNS:
The system mapped vector
* Call IoConnectInterrupt
PROTOTYPE:
NTSTATUS IoConnectInterrupt(OUT PKINTERRUPT* InterruptObject,
PKSERVICE_ROUTINE ServiceRoutine,
PVOID ServiceContext,
PKSPIN_LOCK SpinLock,
ULONG Vector,
KIRQL Irql,
KIRQL SynchronizeIrql,
KINTERRUPT_MODE InterruptMode,
BOOLEAN ShareVector,
KAFFINITY ProcessorEnableMask,
BOOLEAN FloatingSave)
PURPOSE:
Connect a service routine to an interrupt vector
ARGUMENTS:
InterruptObject = Points to an object describes the interrupt on
return
ServiceRoutine = Function to be called when the device interrupts
ServiceContext = Parameters to be passed to the service routine
SpinLock = Should be NULL
Vector = System mapped vector returned from HalGetInterruptVector
Irql = DIRQL returned from HalGetInterruptVector
SynchronizeIrql = Should be the same as Irql
InterruptMode = Device interrupt type (currently ignored)
ShareVector = True if the interrupt vector can shared
ProcessorEnableMask = Currently ignored
FloatingSave = Should be false
RETURNS: Status
* Sample code for snarfing an interrupt vector
void grab_my_irq()
{
ULONG MappedIrq;
KIRQL Dirql;
KAFFINITY Affinity;
PKINTERRUPT IrqObject;
MappedIrq = HalGetInterruptVector(Internal,
0,
0,
MY_VECTOR,
&Dirql,
&Affinity);
IoConnectInterrupt(&IrqObject,
my_irq_service_routine,
my_context,
NULL,
MappedIrq,
Dirql,
Dirql,
0,
FALSE, // Not sharable
Affinity,
FALSE);
}
** Designing an interrupt service routine
An interrupt service routine should have the following prototype
BOOLEAN my_irq_service_routine(PKINTERRUPT Interrupt,
PVOID ServiceContext);
ARGUMENTS:
Interrupt = The same as the object returned from the
IoConnectInterrupt
ServiceContext = A user defined parameters
(passed to IoConnectInterrupt)
RETURNS:
True if it handled the interrupt, false if it should be passed onto
other devices sharing the same vector
NOTES:
While an isr is executing all devices of a lower or equal priority
can't interrupt. For this reason it is important that an isr
should complete in a short an interval as possible. The set of
routines an isr can call is also restricted.

21
reactos/doc/irql.txt Normal file
View File

@@ -0,0 +1,21 @@
This document describes the state of a uniprocessor PC at each of the IRQ
levels supported by the ReactOS kernel
PASSIVE_LEVEL: IF bit clear in the processor flags
All irqs umasked at the PIC
APC_LEVEL: Unknown
WAKE_LEVEL: Unknown
DISPATCH_LEVEL: IF bit clear in the processor flags
All irqs umasked at the PIC
Thread dispatching disabled
DIRQL (Device specific IRQ level):
IF bit clear in the processor flags
Device's irq and all lower priority irqs masked at the PIC
Thread dispatching disabled
HIGH_LEVEL: IF bit set in the processor flags
All irqs masked at the PIC
Thread dispatching disabled

33
reactos/doc/modules.txt Normal file
View File

@@ -0,0 +1,33 @@
** Introduction
This is (an incomplete) guide to writing device drivers (and other kernel
extensions) for ReactOS.
** Setting up the build environment
Create a new subdirectory in the modules directory and copy one of the
existing module makefiles into it. Customize the makefile to compile the
source files for the module. Note: generally it is not necessary to specify
the compiler or compiler flags to use.
** Initializing a module
On loading the kernel will call the module function
PROTOTYPE:
NTSTATUS ModuleEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
PURPOSE:
Initializing the module
ARGUMENTS:
DriverObject = Pointer to an object describing the driver
RegistryPath = Currently NULL
RETURNS:
STATUS_SUCCESS = If the module initialized successfully

View File

@@ -1,687 +0,0 @@
*** This file contains messages I've culled off the net as well
as previous discussions all of which have useful info on fixes
that need to be added to ReactOS. messages are between five
dashes on a line by themselves. If you implement the fix
reffered to in a message, feel free to delete it from the file.
Rex ***
-----
Yes with DPCs, KeDrainDpcQueue should go to HIGH_LEVEL because
it needs to synchronize with KeInsertDpcQueue. Also the idle thread
should run at DISPATCH_LEVEL and regularly drain the dpc queue, that
way if an irq happens and the dpc can't be executed immediately it
will be executed as soon as the processor is idle rather than
waiting for the next timer tick
-----
About the console driver, I think it might be quite useful to have a simple
way for apps to print to the screen for debugging. But when the kernel is more
stable, console handling should be moved to user level because console printing
needs to know about windows and so on which can only be done at user level.
-----
Subject: Re: IMSAMP-how to avoid rebooting?
Date: 9 Nov 1998 00:40:32 -0000
From: Charles Bryant <n51190709.ch@chch.demon.co.uk>
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
References: 1, 2 , 3 , 4
In article <un264wzle.fsf@xxx.yyy.zzz>, David C. <qqqq@xxx.yyy.zzz> wrote:
>The reason it won't unload when something is bound to it is the same
>reason you can't unload any other driver that has an open client. If
>you install any driver, and have a user program (or another driver) open
>a handle to it, and then give the "net stop" command to unload it,
>you'll find that the unload will be delayed until the user program
>closes its handle.
When developing a driver I found this to be a considerable nuisance.
Frequently a bug would leave an IRP stuck in the driver and I
couldn't unload and reload a fixed version. While reading NTDDK.H I
found a suspicious constant and discovered that the Flags field in
the device (the one which you OR in DO_BUFFERED_IO or DO_DIRECT_IO)
has a bit called DO_UNLOAD_PENDING. By experiment I confirmed that
this bit is set when you do 'net stop', so a driver can check it
periodically (e.g. from a timer DPC every ten seconds) and cancel all
queued IRPs if it is found to be set.
Since this is not documented anywhere that I can find, it might be
unwise to rely on it for production code, but it is very useful for
debugging. Maybe someone with internals knowledge can comment on the
reliability of it.
-----
Subject: Re: Kernel bugs
Date: Fri, 23 Oct 1998 12:08:36 -0700
From: rex <rex@lvcablemodem.com>
To: Jason Filby <jasonfilby@yahoo.com>
References: 1
Jason Filby wrote:
> Hi,
>
> Ok -- here's most of what I get when I press a key:
>
> Page fault detected at address 1fd4 with eip c042f794
> Recursive page fault detected
> Exception 14(2)
> CS:EIP 20:c042f794
>
> Rex -- do you know of anyway to find out which function in what file
> is causing the exception? I know that for problems in the kernel, you
> just look in the ntoskrnl\kernel.sym file and find the EIP value which
> matches the one given in the exception debug text. But what about
> modules? How can we track exceptions that occur in functions in modules?
>
I know this is a little belated, but I thought I'd take astab at answering
this anyway. add an option to the
makefile for the module to generate a listing file with
symbol information. Then, on a boot test, note the
address that the module is loaded at, and subtract
this from the EIP value. add any offset used in the
module link specification (I dont think there currently
is one), and look for the last symbol with a lower
address offset.
Brian, I have an idea on how to make this exception
dump information a little more useful. We should
have the load information for the load modules
in memory somewhere. Perhaps the exception
dump could check offending addresses to see if
they lie in the kernel or in a module, and if they
lie in a module the proper offset could be subtracted
and this number could be displayed seperately. If
I get a chance today, I'll make this change and send
it to ya.
Rex.
-----
Subject: [ros-kernel] Pet peeve of the week
Resent-Date: Sun, 25 Oct 1998 11:57:40 -0600
Resent-From: ros-kernel@sid-dis.com
Date: Sun, 25 Oct 1998 09:53:48 -0800
From: rex <rex@lvcablemodem.com>
Reply-To: <ros-kernel@sid-dis.com>
To: ReactOS Kernel Forum <ros-kernel@sid-dis.com>
Hi all,
I guess it's about time to start another mailstorm
on the list. :)
I have a suggestion for a change to the kernel.
It not a very big change, and I hope everyone
will agree that it makes sense.
There is a structure used in many places in the
kernel called LARGE_INTEGER. the is also
a version called ULARGE_INTEGER, but it
is not used at all as far as I can tell. this structure
is equivalent to a long long int. You can literally
cast a pointer to a LARGE_INTEGER to a
long long int and all manipulation will work
seemlessly. My suggestion is that we replace the
use of this structure with long long ints. Even
microsoft, in their infinite wisdom, has made this
suggestion in the DDK documentation. If you're
wondering where, look at the RTL functions
that manipulate LARGE_INTEGER structs.
Replacing LI's with long long ints will work
because they are binary compatable. All software
compiled to use LI's will manipulate long long ints
correctly and vice versa. There is one problem
with this suggestion: the LARGE_INTEGER type
is a structure containing 2 members. Any code
that accesses the structure by members will break.
I think the kernel side impact is minimal, and is
worth the change. However, the structure is used
in several of the Win32 API functions, and needs
to remain there. I think we build a conditionally
compiled version of the LARGE_INTEGER type.
In kernel mode code (the kernel proper and drivers)
the LARGE INTEGER will be the following:
typedef long long int LARGE_INTEGER,
*PLARGE_INTEGER;
typedef unsigned long long int ULARGE_INTEGER,
*PULARGE_INTEGER;
and in user mode code it will expand out to the
current definition (which by the way, is not
strictly correct, but can't be because it uses a
MS compiler extension).
Brian, I would be willing to make the conversion
to those kernel modules that needed it, and of
course to the IDE driver if we want to go forward
with the change.
Lastly, I'll mention what made me consider this.
I was fixing the timer routines, and two of the
three problems turned out to be related to LI
conversion problems.
Rex.
-----
Subject: Re: [ros-kernel] Pet peeve of the week
Date: Thu, 29 Oct 1998 19:10:37 +0100
From: Boudewijn <ariadne@xs4all.nl>
To: rex@lvcablemodem.com
References: 1
Hai Rex
I think it is a good idea to wrap a makro around the member access
to large integers.
I haven't tested this, but do you think this is a good sugestion ?
#ifdef COMPILER_LARGE_INTEGERS
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( ( LargeInteger >>
32) )
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) ( (LargeInteger &
0xFFFFFFFF) )
#define SET_LARGE_INTEGER_HIGH_PART(LargeInteger,Signed_Long) (
LargeInteger |= ( ((LARGE_INTEGER)Signed_Long) << 32 ) )
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) (
LargeInteger |= Unsigned_Long )
#else
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( (
LargeInteger.HighPart) )
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) (
(LargeInteger.LowPart) )
#define SET_LARGE_INTEGER_HIGH_PART(LargeInteger,Signed_Long) (
LargeInteger.HighPart= Signed_Long )
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) (
LargeInteger.LowPart = Unsigned_Long )
#endif
Boudewijn
-----
Subject: Re: Question on "Sending buffers on the stack to asynchronous DeviceIoControl with buffered I/O"
Date: Mon, 16 Nov 1998 11:24:57 -0800
From: "-Paul" <paulsan@microsoftSPAM.com>
Organization: Microsoft Corp.
Newsgroups: microsoft.public.win32.programmer.kernel, comp.os.ms-windows.programmer.nt.kernel-mode
References: 1
Radu, I post the following information occassionally for questions such as
yours. I hope it helps.
-Paul
Here is an explanation of buffers and DeviceIoControl.
First, here are the parameters,
BOOL DeviceIoControl(
HANDLE hDevice, // handle to device of interest
DWORD dwIoControlCode, // control code of operation to perform
LPVOID lpInBuffer, // pointer to buffer to supply input data
DWORD nInBufferSize, // size of input buffer
LPVOID lpOutBuffer, // pointer to buffer to receive output data
DWORD nOutBufferSize, // size of output buffer
LPDWORD lpBytesReturned, // pointer to variable to receive output byte
count
LPOVERLAPPED lpOverlapped // pointer to overlapped structure for
asynchronous operation
);
METHOD_BUFFERED
user-mode perspective
lpInBuffer - optional, contains data that is written to the driver
lpOutBuffer - optional, contains data that is read from the driver after
the call has completed
lpInBuffer and lpOutBuffer can be two buffers or a single shared buffer.
If a shared buffer, lpInBuffer is overwritten by lpOutBuffer.
I/O Manager perspective
examines nInBufferSize and nOutBufferSize. Allocates memory from non-paged
pool and puts the address of this pool in Irp->AssociatedIrp.SystemBuffer.
The size of this buffer is equal to the size of the larger of the two
bufferes. This buffer is accessible at any IRQL.
copies nInBufferSize to irpSp->Parameters.DeviceIoControl.InputBufferLength
copies nOutBufferSize to
irpSp->Parameters.DeviceIoControl.OutputBufferLength
copies contents of lpInBuffer to SystemBuffer allocated above
calls your driver
Device Driver perspective
you have one buffer, Irp->AssociatedIrp.SystemBuffer. You read input data
from this buffer and you write output data to the same buffer, overwriting
the input data.
Before calling IoCompleteRequest, you must
- set IoStatus.Status to an approriate NtStatus
- if IoStatus.Status == STATUS_SUCCESS
set IoStatus.Information to the
number of bytes you want copied
from the SystemBuffer back into
lpOutBuffer.
I/O Manager Completion Routine perspective
looks at IoStatus block, if IoStatus.Status = STATUS_SUCCESS, copies the
number of bytes specified by IoStatus.Information from
Irp->AssociatedIrp.SystemBuffer into lpOutBuffer
completes the request
METHOD_IN_DIRECT
user-mode perspective
lpInBuffer - optional, contains data that is written to the driver. This
buffer is used in the exact same fashion as METHOD_BUFFERED. To avoid
confusion, mentally rename this buffer to lpControlBuffer. This is
typically a small, optional buffer that might contain a control structure
with useful information for the device driver. This buffer is smal and is
double buffered.
lpOutBuffer - NOT OPTIONAL, This LARGE buffer contains data that is read by
the driver. To avoid confusion, mentally rename this buffer to
lpDataTransferBuffer. This is physically the same buffer that the device
driver will read from. There is no double buffering. Technically, this
buffer is still optional, but since you are using this buffering method,
what would be the point???
I/O Manager perspective
If lpInBuffer exists, allocates memory from non-paged pool and puts the
address of this pool in Irp->AssociatedIrp.SystemBuffer. This buffer is
accessible at any IRQL.
copies nInBufferSize to irpSp->Parameters.DeviceIoControl.InputBufferLength
copies nOutBufferSize to
irpSp->Parameters.DeviceIoControl.OutputBufferLength
copies contents of lpInBuffer to SystemBuffer allocated above
So far this is completely identical to METHOD_BUFFERED. Most likely
lpInBuffer (mentally renamed to lpControlBuffer) is very small in size.
For lpOutBuffer (mentally renamed to lpDataTransferBuffer), an MDL is
allocated. lpOutBuffer is probed and locked into memory. Then, the user
buffer virtual addresses are checked to be sure they are readable in the
caller's access mode.
The MDL is address is stored in Irp->MdlAddress.
Your driver is called.
Device Driver perspective
The device driver can read the copy of lpOutBuffer via
Irp->AssociatedIrp.SystemBuffer. Anything written by the device driver to
this buffer is lost. The I/O Manager does not copy any data back to the
user-mode buffers as it did in the completion routine for METHOD_BUFFERED.
Art Baker's book is wrong in this respect (page 168, "data going from the
driver back to the caller is passed through an intermediate system-space
buffer" and page 177, "When the IOCTL IRP is completed, the contents of the
system buffer will be copied back into the callers original output buffer".
The device driver accesses the Win32 buffer directly via Irp->MdlAddress.
The driver uses whatever Mdl API's to read the buffer. Usually, this
buffer is to be written to some mass storage media or some similar
operation. Since this is a large data transfer, assume a completion
routine is required.
mark the Irp pending
queue it
return status pending
Device Driver Completion Routine perspective
standard completion routine operations
set IoStatus.Status to an approriate NtStatus
IoStatus.Information is not needed
completete the request
I/O Manager Completion Routine perspective
standard I/O Manager completion routine operations
unmap the pages
deallocate the Mdl
complete the request
METHOD_OUT_DIRECT
user-mode perspective
lpInBuffer - optional, contains data that is written to the driver. This
buffer is used in the exact same fashion as METHOD_BUFFERED. To avoid
confusion, mentally rename this buffer to lpControlBuffer. This is
typically a small, optional buffer that might contain a control structure
with useful information for the device driver. This buffer is smal and is
double buffered.
lpOutBuffer - NOT OPTIONAL, This LARGE buffer contains data that is written
by the driver and read by the wer-mode application when the request is
completed. To avoid confusion, mentally rename this buffer to
lpDataTransferBuffer. This is physically the same buffer that the device
driver will write to. There is no double buffering. Technically, this
buffer is still optional, but since you are using this buffering method,
what would be the point???
I/O Manager perspective
If lpInBuffer exists, allocates memory from non-paged pool and puts the
address of this pool in Irp->AssociatedIrp.SystemBuffer. This buffer is
accessible at any IRQL.
copies nInBufferSize to irpSp->Parameters.DeviceIoControl.InputBufferLength
copies nOutBufferSize to
irpSp->Parameters.DeviceIoControl.OutputBufferLength
copies contents of lpInBuffer to SystemBuffer allocated above
So far this is completely identical to METHOD_BUFFERED. Most likely
lpInBuffer (mentally renamed to lpControlBuffer) is very small in size.
For lpOutBuffer (mentally renamed to lpDataTransferBuffer), an MDL is
allocated. lpOutBuffer is probed and locked into memory. Then the user
buffer's addresses are checked to make sure the caller could write to them
in the caller's access mode.
The MDL is address is stored in Irp->MdlAddress.
Your driver is called.
Device Driver perspective
The device driver can read the copy of lpOutBuffer via
Irp->AssociatedIrp.SystemBuffer. Anything written by the device driver to
this buffer is lost.
The device driver accesses the Win32 buffer directly via Irp->MdlAddress.
The driver uses whatever Mdl API's to write data to the buffer. Usually,
this buffer is to be read from some mass storage media or some similar
operation. Since this is a large data transfer, assume a completion
routine is required.
mark the Irp pending
queue it
return status pending
Device Driver Completion Routine perspective
standard completion routine operations
set IoStatus.Status to an approriate NtStatus
IoStatus.Information is not needed
completete the request
I/O Manager Completion Routine perspective
standard I/O Manager completion routine operations
unmap the pages
deallocate the Mdl
complete the request
METHOD_NEITHER
I/O Manager perspective
Irp->UserBuffer = lpOutputBuffer;
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = lpInputBuffer;
No comments here. Don't use METHOD_DIRECT unless you know what you are
doing. Simple rule.
If your IOCtl involves no data transfer buffers, then METHOD_NEITHER is the
fastest path through the I/O Manager that involves an Irp.
Final Comment
Don't touch Irp->UserBuffer. This is a bookmark for the I/O Manager. Two
major problems can occur. 1 - page fault at high IRQL, or 2 - you write
something to Irp->UserBuffer and the I/O Manager overwrites you in its
completion routine. File systems access Irp->UserBuffer, but FSD writers
know all of the above and know when it is safe to touch Irp->UserBuffer.
Radu Woinaroski wrote in message <364F8F6E.2434B010@scitec.com.au>...
>Hello,
>
>I have a kernel-mode device driver that accepts a number of IoControl
>commands that use buffered data transfer (METHOD_BUFFERED).
>
>A user mode API provides a higher level access then the DeviceIoControl
>function.
>
>The function is implemented like that
>
>BOOL
Something(
> HANDLE hDevice ,
> int param1,
> int param2,
> DWORD * pReturn,
> LPOVERLAPPED pOverlapped)
>{
> // here a data buffer on the stack sent to asynchronous DeviceIoControl
>call
> int aDataIn[2];
> aDataIn[0] = param1;
> aDataIn[1] = param2;
>
> return DeviceIoControl(
> hDevice,
> DO_SOMETHING_IO,
> aDataIn,
> sizeof(int)*2,
> pReturn,
> sizeof(DWORD),
> pOverlapped);
>}
>
>The aDataIn buffer will not exist after DeviceIoControl returns (and
>when the I/O operation terminates). I know that for buffered IO the
>input data buffer is copyed by de IOManager to a nonpaged-pool area
>before passing the request to driver dispatch routine (DeviceControl).
>At the point of calling the dispatch routine (DeviceControl) the driver
>runs in the context of the calling thread so DeviceIoControl hasn't
>returned yet (?? or so I think) so aDataI
n will still be valid at the
>time IOManager copyes it to its buffer. So, this apears to work ok (at
>least in my opinion).
>
>Does I/O Manager use the Input buffer from the call to the Win32
>DeviceIoControl any where else after the first copy ?
>
>Is there any reason why this approach (passing a buffer on the stack to
>a asynchronous DeviceIoControl that uses buffered I/O) wouldn't work ?
>
>Allocating buffers from heap and deleting them on IO completion while
>managing asynchronous IO seems too much work ;-) .
>
>Thanks in advance for your opinions
>Radu W.
>
>--
>Radu Woinaroski
>Scitec
>Sydney, Australia
>Radu.Woinaroski@scitec.com.au
-----
Subject: Re: PCI ISR problem
Date: Fri, 20 Nov 1998 18:04:48 GMT
From: jeh@cmkrnl.com (Jamie Hanrahan)
Organization: Kernel Mode Systems, San Diego, CA
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
References: 1
On Thu, 19 Nov 1998 15:46:13 -0600, Eric Gardiner
<eric.gardiner@natinst.com> wrote:
>I'm having problems with NT4 not hooking the interrupt line indicated by
>a PCI device. Here's what I'm doing:
>
>1) Enumerating the PCI buses on the system (using HalGetBusData) until
>I find my device.
>2) Once my device is found, I read the "Interrupt Line Register" in the
>device's PCI config space to determine what interrupt level to pass to
>HalGetInterruptVector.
Whups! No. Call HalAssignSlotResources and look at the returned
CM_RESOURCE_LIST to find the vector, level, port addresses, etc., for
your device. (Then pass the returned CM_RESOURCE_LIST to ExFreePool.)
See Knowledge Base article Q152044.
--- Jamie Hanrahan, Kernel Mode Systems, San Diego CA (jeh@cmkrnl.com)
Drivers, internals, networks, applications, and training for VMS and Windows NT
NT kernel driver FAQ, links, and other information: http://www.cmkrnl.com/
Please post replies, followups, questions, etc., in news, not via e-mail.
-----
Subject: Re: IRP canceling
Date: Mon, 23 Nov 1998 09:05:47 -0500
From: Walter Oney <waltoney@oneysoft.com>
Organization: Walter Oney Software
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
References: 1
Seol,Keun Seok wrote:
> But, if the IRP was the CurrentIrp of the Device Object,
> the Driver's Start I/O routine will try to process the IRP.
> In the DDK help, the Start I/O routine MUST check the current IRP's
> Cancel bit.
> If set, Start I/O routine must just return.
>
> But I think that the IRP already completed should not be accessed.
You're absolutely right. I recommend the following code in a standard
StartIo routine to avoid the problem you point out:
VOID StartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
KIRQL oldirql;
IoAcquireCancelSpinLock(&oldirql);
if (Irp != DeviceObject->CurrentIrp || Irp->Cancel)
{
IoReleaseCancelSpinLock(oldirql);
return;
}
else
{
IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(oldirql);
}
. . .
}
This dovetails with a standard cancel routine:
VOID CancelRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
if (DeviceObject->CurrentIrp == Irp)
{
IoReleaseCancelSpinLock(Irp->CancelIrql);
IoStartNextPacket(DeviceObject, TRUE);
}
else
{
KeRemoveEntryDeviceQueue(&DeviceObject->DeviceQueue,
&Irp->Tail.Overlay.DeviceQueueEntry);
IoReleaseCancelSpinLock(Irp->CancelIrql);
}
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
You need to remember that the C language specification requires that
evaluation of boolean operators short circuit when the result is known.
So, if StartIo discovers that the Irp it got as an argument is not the
same as CurrentIrp, it will not attempt to evaulate Irp->Cancel.
Now, as to why this works: StartIo gets called either by IoStartPacket
or IoStartNextPacket. Each of them will grab the cancel spin lock and
set CurrentIrp, then release the spin lock and call StartIo. If someone
should sneak in on another CPU and cancel this very same IRP, your
cancel routine will immediately release the spin lock and call
IoStartNextPacket. One of two things will then happen. IoStartNextPacket
may succeed in getting the cancel spin lock, whereupon it will nullify
the CurrentIrp pointer. If another IRP is on the queue, it will remove
it from the queue, set CurrentIrp to point to this *new* IRP, release
the spin lock, and call StartIo. [You now have two instances of StartIo
running on two different CPUs for two different IRPs, but it's not a
problem because they won't be able to interfere with each other.]
Meanwhile, your original instance of StartIo gets the cancel spin lock
and sees that CurrentIrp is not equal to the IRP pointer it got as an
argument, so it gives up.
The second way this could play out is that StartIo gets the cancel lock
before IoStartNextPacket does. In this case, CurrentIrp is still
pointing to the IRP that's in the process of being cancelled and that
StartIo got as an argument. But this IRP hasn't been completed yet (the
CPU that's running your cancel routine is spinning inside
IoStartNextPacket and therefore hasn't gotten to calling
IoCompleteRequest yet), so no-one will have been able to call IoFreeIrp
to make your pointer invalid.
People may tell you that you should be using your own queues for IRPs so
you can avoid bottlenecking the system on the global cancel spin lock.
That's true enough, but doing it correctly with Plug and Play and Power
management things in the way is gigantically complicated. There's a
sample in the NT 5 beta-2 DDK called CANCEL that shows how to manage
your own queue if you don't worry about PNP and POWER. I hear tell of an
upcoming MSJ article by a Microsoft developer that may solve the
complete problem.
-----
Subject: ANNOUNCE: ALINK v1.5
Date: 16 Nov 1998 16:36:05 GMT
From: anthony_w@my-dejanews.com
Organization: Deja News - The Leader in Internet Discussion
Newsgroups: comp.os.ms-windows.programmer.win32, comp.lang.asm.x86, comp.os.msdos.programmer
ALINK is a freeware linker, creating MSDOS COM and EXE files and Win32 PE EXE
and DLL files from OMF format OBJ and LIB files, win32-COFF format OBJ files,
and win32 RES files.
NEW for version 1.5:
Win32 COFF object file support.
Download it now from my home page.
Anthony
--
anthony_w@geocities.com
http://www.geocities.com/SiliconValley/Network/4311/index.html
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
-----

View File

@@ -1,51 +1,31 @@
* Function groups totally or partially unimplemented
* Kernel things implemented [exceptions in brackets]
Dma functions (see hal/x86/dma.c)
PCI interface functions (see hal/x86/bios32.c, hal/x86/pci.c)
HalExamineMbr
Locale support (see ex/locale.c)
Shutdown support (see ex/power.c)
Zw(Set/Get)SystemInformation (see ex/sysinfo.c)
Adapter functions (see io/adapter.c)
Io cancelation support (see io/cancel, et al)
Directory change notification (see io/dir.c)
Error logging (see io/errlog.c)
Buffer flushing (see io/flush.c)
Io completion ports (see io/iocomp.c)
DeviceIoControl support (see io/ioctrl.c)
File locking (see io/lock.c)
Mailslots (see io/mailslot.c)
Named pipes (see io/npipe.c)
Hardware resource management (see io/resource.c)
File access checking (see io/share.c)
APCs to user-mode (see ke/apc.c, ke/apchelp.asm)
Exception support (see ke/catch.c)
Mutex support (see ke/mutex.c)
Semaphore support (see ke/sem.c)
Timer support (see ke/timer.c)
Properly calibrate delay loop (see ke/timer.c)
Waiting for multiple objects (see ke/wait.c)
Single linked lists (see rtl/slist.c)
Sequenced lists (see rtl/seqlist.c)
* Verify implementation
Spinlocks [Uniprocessor only]
IRQ levels [Not APC_LEVEL or WAKE_LEVEL, uniprocessor only]
ISRs [Partial, uniprocessor only]
Timers [Untested]
DPCs [Untested]
Objects [Partial]
Namespace [Partial]
Handle tables [One process only]
Threads [Some initial work]
RTL list functions [All except sequenced lists]
Zones [Untested]
Memory pool [Working but semantics partially incompatiable]
Device objects [Some but no support for layering]
IRP [Partial]
Memory sections [Partial, no file mappings]
PCI interface [Probes but no support]
CreateFile API [Device only]
ReadFile/WriteFile API [Device only]
MDL functions [Untested]
Fast mutexes (see ex/fmutex.c)
* Major areas
* Kernel things unimplemented (partial)
Security support (see se/*.c)
Registry support (see cm/*.c)
Paging support
File system cache support
SCSI miniport driver
Network support
Video drivers
USER and GDI modules
* Drivers
NTFS, EXT2 filesystems
Many others (use oem's where possible)
* For the future
DOS, Win16, POSIX subsystems
Add support for source level debugging to Bochs
Support for remote debugging
Process managment
Dispatcher objects (Mutex, Semaphore etc)
Investigate user and kernel mode APCs
Asynchronous I/O
Optimization

16
reactos/doc/wstring.txt Normal file
View File

@@ -0,0 +1,16 @@
subject wstring.zip
author Boudewijn Dekker
date 06-06-98
I wrote some inline wide character string functions. It are modified version
of the ones in string.h. I added four more function nl stricmp, strnicmp,
wcsicmp, and wcsnicmp. These are the case insensitive variants of
strcmp, strncmp and wcscmp, wcsncmp. I tested all the functions but I
would urge anyone to tested again. I removed an extern specifier
__wcstok and strtok cause I it caused an compilation error when
using strtok or wcstok. Please could someone see if this correct.
I also used these string functions in lstring api functions.
Boudewijn Dekker

View File

@@ -1,4 +0,0 @@
base.tmp
junk.tmp
temp.exp

View File

@@ -1,155 +0,0 @@
#include <internal/mmhal.h>
#include <internal/halio.h>
#include <ddk/ntddk.h>
#include <string.h>
#include <internal/string.h>
#include <defines.h>
//#define NDEBUG
#include <internal/debug.h>
#define FSCTL_GET_CONSOLE_SCREEN_BUFFER_INFO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 254, DO_DIRECT_IO, FILE_READ_ACCESS|FILE_WRITE_ACCESS)
#define FSCTL_SET_CONSOLE_SCREEN_BUFFER_INFO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 255, DO_DIRECT_IO, FILE_READ_ACCESS|FILE_WRITE_ACCESS)
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
VOID ScrStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
}
NTSTATUS ScrDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
ULONG ControlCode;
NTSTATUS Status;
char *UserBuf = Irp->UserBuffer;
int i;
switch (stk->MajorFunction)
{
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
Status = STATUS_SUCCESS;
break;
case IRP_MJ_WRITE:
for(i=0;i<stk->Parameters.Write.Length;i++)
__putchar(UserBuf[i]);
Status = STATUS_SUCCESS;
break;
case IRP_MJ_DEVICE_CONTROL:
ControlCode = stk->Parameters.DeviceIoControl.IoControlCode;
if ( ControlCode == FSCTL_GET_CONSOLE_SCREEN_BUFFER_INFO ) {
// printk("get console screen buffer info\n");
ConsoleScreenBufferInfo.dwCursorPosition.X=__wherex();
ConsoleScreenBufferInfo.dwCursorPosition.Y=__wherey();
__getscreensize(&ConsoleScreenBufferInfo.dwSize.X, &ConsoleScreenBufferInfo.dwSize.Y );
memcpy(UserBuf,&ConsoleScreenBufferInfo,sizeof(CONSOLE_SCREEN_BUFFER_INFO));
Status = STATUS_SUCCESS;
}
else if ( ControlCode == FSCTL_SET_CONSOLE_SCREEN_BUFFER_INFO ) {
// printk("set console screen buffer info\n");
memcpy(&ConsoleScreenBufferInfo,UserBuf,sizeof(CONSOLE_SCREEN_BUFFER_INFO));
__goxy(ConsoleScreenBufferInfo.dwCursorPosition.X,ConsoleScreenBufferInfo.dwCursorPosition.Y);
Status = STATUS_SUCCESS;
}
break;
default:
Status = STATUS_NOT_IMPLEMENTED;
break;
}
IoCompleteRequest(Irp, Status);
// DPRINT("Status %d\n",Status);
return(Status);
}
/*
* Module entry point
*/
STDCALL NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
ANSI_STRING adevice_name;
UNICODE_STRING device_name;
ANSI_STRING asymlink_name;
UNICODE_STRING symlink_name;
DbgPrint("Screen Driver 0.0.4\n");
DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = ScrDispatch;
DriverObject->DriverStartIo = ScrStartIo;
//ScrSwitchToBlueScreen();
RtlInitAnsiString(&adevice_name,"\\Device\\BlueScreen");
RtlAnsiStringToUnicodeString(&device_name,&adevice_name,TRUE);
IoCreateDevice(DriverObject,0,&device_name,FILE_DEVICE_SCREEN,0,
TRUE,&DeviceObject);
RtlInitAnsiString(&asymlink_name,"\\??\\BlueScreen");
RtlAnsiStringToUnicodeString(&symlink_name,&asymlink_name,TRUE);
IoCreateSymbolicLink(&symlink_name,&device_name);
return(STATUS_SUCCESS);
}
/* FUNCTIONS ***************************************************************/
void ScrSwitchToBlueScreen(void)
/*
* FUNCTION: Switches the monitor to text mode and writes a blue background
* NOTE: This function is entirely self contained and can be used from any
* graphics mode.
*/
{
/*
* Reset the cursor position
*/
ConsoleScreenBufferInfo.dwCursorPosition.X=__wherex();
ConsoleScreenBufferInfo.dwCursorPosition.Y=__wherey();
__getscreensize(&ConsoleScreenBufferInfo.dwSize.X, &ConsoleScreenBufferInfo.dwSize.Y );
/*
* This code section is taken from the sample routines by
* Jeff Morgan (kinfira@hotmail.com)
*/
}

View File

@@ -1,23 +0,0 @@
#
#
#
all: blue.sys
.phony: all
OBJECTS = blue.o ../../../ntoskrnl/ntoskrnl.a
blue.sys: $(OBJECTS)
$(CC) -specs=../../svc_specs -mdll -o junk.tmp -Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ -Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp $(OBJECTS)
- $(RM) junk.tmp
$(DLLTOOL) --dllname blue.sys --base-file base.tmp \
--output-exp temp.exp
- $(RM) base.tmp
$(CC) --verbose -Wl,--image-base,0x10000 -Wl,-e,_DriverEntry@8 \
-specs=../../svc_specs -mdll -o blue.sys $(OBJECTS) -Wl,temp.exp
- $(RM) temp.exp

View File

@@ -1,2 +0,0 @@
DIRS=exe \
sys

View File

@@ -1,168 +0,0 @@
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
EventTest.c
Abstract:
Simple console test app demonstrating how a Win32 app can share
an event object with a kernel-mode driver. For more information
on using Event Objects at the application level see the Win32 SDK.
Author:
Jeff Midkiff (jeffmi) 23-Jul-96
Enviroment:
User Mode
Revision History:
--*/
//
// INCLUDES
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <winioctl.h>
#include <conio.h>
#include "event.h"
//
// MAIN
//
void __cdecl
main(
int argc,
char ** argv
)
{
BOOL bStatus;
HANDLE hDevice;
ULONG ulReturnedLength;
SET_EVENT setEvent;
FLOAT fDelay;
if ( (argc < 2) || (argv[1] == NULL) ) {
printf("event <delay>\n");
printf("\twhere <delay> = time to delay the event signal in seconds.\n");
exit(0);
}
sscanf( argv[1], "%f", &fDelay );
//
// open the device
//
hDevice = CreateFile(
"\\\\.\\EVENT", // lpFileName
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDistribution
0, // dwFlagsAndAttributes
NULL // hTemplateFile
);
if (hDevice == INVALID_HANDLE_VALUE) {
printf("CreateFile error = %d\n", GetLastError() );
exit(0);
}
//
// set the event signal delay
//
setEvent.DueTime.QuadPart = -((LONGLONG)(fDelay * 10.0E6));// use relative time for this sample
//
// test the driver for bad event handles
//
setEvent.hEvent = NULL;
bStatus = DeviceIoControl(
hDevice, // Handle to device
IOCTL_SET_EVENT, // IO Control code
&setEvent, // Input Buffer to driver.
SIZEOF_SETEVENT, // Length of input buffer in bytes.
NULL, // Output Buffer from driver.
0, // Length of output buffer in bytes.
&ulReturnedLength, // Bytes placed in buffer.
NULL // synchronous call
);
if ( !bStatus ) {
printf("Bad handle TEST returned code %d.\n\n", GetLastError() );
} else {
printf("we should never get here\n");
exit(0);
}
//
//
//
setEvent.hEvent = CreateEvent(
NULL, // lpEventAttributes
TRUE, // bManualReset
FALSE, // bInitialState
NULL // lpName
);
if ( !setEvent.hEvent ) {
printf("CreateEvent error = %d\n", GetLastError() );
} else {
printf("Event HANDLE = 0x%x\n", setEvent.hEvent );
printf("Press any key to exit.\n");
while( !_kbhit() ) {
bStatus = DeviceIoControl(
hDevice, // Handle to device
IOCTL_SET_EVENT, // IO Control code
&setEvent, // Input Buffer to driver.
SIZEOF_SETEVENT, // Length of input buffer in bytes.
NULL, // Output Buffer from driver.
0, // Length of output buffer in bytes.
&ulReturnedLength, // Bytes placed in buffer.
NULL // synchronous call
);
if ( !bStatus ) {
printf("Ioctl failed with code %d\n", GetLastError() );
break;
} else {
printf("Waiting for Event...\n");
WaitForSingleObject(setEvent.hEvent,
INFINITE );
printf("Event signalled.\n\n");
ResetEvent( setEvent.hEvent);
//printf("Event reset.\n");
}
}
}
//
// close the driver
//
if ( !CloseHandle(hDevice) ) {
printf("Failed to close device.\n");
}
exit(0);
}
// EOF

View File

@@ -1,7 +0,0 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def

View File

@@ -1,10 +0,0 @@
TARGETNAME=event
TARGETPATH=$(BASEDIR)\lib
TARGETTYPE=PROGRAM
INCLUDES=..\sys
SOURCES=eventtest.c
UMTYPE=console
UMBASE=0x100000

View File

@@ -1,50 +0,0 @@
This sample demonstrates one way that a Windows NT kernel-mode device driver
can share and explicitly signal an Event Object with a Win32 application.
It is composed of two parts, a Windows NT kernel-mode device driver and a Win32
console test application. Both are built using the Windows NT DDK.
Instructions:
-------------
1) Build the driver and test application in either the FREE or CHECKED build environment:
BLD
Both the driver and application are put in %NTDDK%\LIB\*\FREE | CHECKED on your build machine.
2) Copy the newly built driver to your Target machine's %SystemRoot%\system32\drivers
directory. Copy the newly built application to your target machine.
Also copy the EVENT.INI file to your Target machine.
3) Update the Target machine's Registry by running REGINI.EXE on the EVENT.INI file, i.e.:
REGINI EVENT.INI
This adds a driver key under the
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services tree in the Registry.
You can verify this by running REGEDIT32.EXE and looking at the \Event key.
4) Reboot the Target machine for the Registry changes to take effect.
Your driver will not load until you reboot.
5) Load the driver from the command line:
NET START EVENT
6) Run the test app from the command line:
EVENT <DELAY>
where DELAY = time to delay the Event signal in seconds.
7) Unload the driver from the command line:
NET STOP EVENT

View File

@@ -1,447 +0,0 @@
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
Event.c
Abstract:
This sample demonstrates one way that a Windows NT kernel-mode driver
can share and explicitly signal an Event Object with a Win32 application.
This sample uses the following method:
The application creates an event object using CreateEvent().
The app passes the event handle to the driver in a private IOCTL.
The driver is running in the app's thread context during the IOCTL so
there is a valid user-mode handle at that time.
The driver dereferences the user-mode handle into system space & saves
the new system handle for later use.
The driver signals the event via KeSetEvent() at IRQL <= DISPATCH_LEVEL.
The driver MUST delete any driver references to the event object at
Unload time.
An alternative method would be to create a named event in the driver via
IoCreateNotificationEvent and then open the event in user mode. This API
however is new to Windows NT 4.0 so you can not use this method in your
NT 3.5x drivers.
Note that this sample's event can be signalled (almost) at will from within
the driver. A different event signal can be set when the driver is setup to
do asynchronous I/O, and it is opened with FILE_FLAG_OVERLAPPED, and an
event handle is passed down in an OVERLAPPED struct from the app's Read,
Write, or DeviceIoControl. This different event signal is set by the I/O
Manager when the driver calls IoCompleteRequest on a pending Irp. This type
of Irp completion signal is not the purpose of this sample, hence the lack of
Irp queing.
Author:
Jeff Midkiff (jeffmi) 23-Jul-96
Enviroment:
Kernel Mode Only
Revision History:
--*/
//
// INCLUDES
//
#include "ntddk.h"
#include "event.h"
//
// DEFINES
//
#define USER_NAME L"\\DosDevices\\EVENT"
#define SYSTEM_NAME L"\\Device\\EVENT"
//
// DATA
//
typedef struct _DEVICE_EXTENSION {
KDPC Dpc;
KTIMER Timer;
HANDLE hEvent;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
//
// PROTOS
//
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
Unload(
IN PDRIVER_OBJECT DriverObject
);
NTSTATUS
Dispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
CustomTimerDPC(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
This routine gets called by the system to initialize the driver.
Arguments:
DriverObject - the system supplied driver object.
RegistryPath - the system supplied registry path for this driver.
Return Value:
NTSTATUS
--*/
{
PDEVICE_OBJECT pDeviceObject;
PDEVICE_EXTENSION pDeviceExtension;
UNICODE_STRING usSystemName;
UNICODE_STRING usUserName;
NTSTATUS status;
KdPrint(("Event!DriverEntry - IN\n"));
//
// create the device object
//
RtlInitUnicodeString( &usSystemName, SYSTEM_NAME );
status = IoCreateDevice(
DriverObject, // DriverObject
sizeof( DEVICE_EXTENSION ), // DeviceExtensionSize
&usSystemName, // DeviceName
FILE_DEVICE_UNKNOWN, // DeviceType
0, // DeviceCharacteristics
TRUE, // Exclusive
&pDeviceObject // DeviceObject
);
if ( !NT_SUCCESS(status) ) {
KdPrint(("\tIoCreateDevice returned 0x%x\n", status));
return( status );
}
//
// Set up dispatch entry points for the driver.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch;
DriverObject->DriverUnload = Unload;
//
// Create a symbolic link into user mode for the driver.
//
RtlInitUnicodeString( &usUserName, USER_NAME );
status = IoCreateSymbolicLink( &usUserName, &usSystemName );
if ( !NT_SUCCESS(status) ) {
IoDeleteDevice( pDeviceObject );
KdPrint(("\tIoCreateSymbolicLink returned 0x%x\n", status));
return( status );
}
//
// establish user-buffer access method
//
pDeviceObject->Flags |= DO_BUFFERED_IO;
//
// setup the device extension
//
pDeviceExtension = pDeviceObject->DeviceExtension;
KeInitializeDpc(
&pDeviceExtension->Dpc, // Dpc
CustomTimerDPC, // DeferredRoutine
pDeviceObject // DeferredContext
);
KeInitializeTimer(
&pDeviceExtension->Timer // Timer
);
pDeviceExtension->hEvent = NULL;
KdPrint(("Event!DriverEntry - OUT\n"));
return( status );
}
NTSTATUS
Unload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
This routine gets called to remove the driver from the system.
Arguments:
DriverObject - the system supplied driver object.
Return Value:
NTSTATUS
--*/
{
PDEVICE_OBJECT pDeviceObject = DriverObject->DeviceObject;
PDEVICE_EXTENSION pDeviceExtension = pDeviceObject->DeviceExtension;
UNICODE_STRING usUserName;
KdPrint(("Event!Unload\n"));
//
// dereference the event object or it will NEVER go away until reboot
//
if ( pDeviceExtension->hEvent )
ObDereferenceObject( pDeviceExtension->hEvent );
// Delete the user-mode symbolic link.
RtlInitUnicodeString( &usUserName, USER_NAME );
IoDeleteSymbolicLink( &usUserName );
// Delete the DeviceObject
IoDeleteDevice( pDeviceObject );
return( STATUS_SUCCESS );
}
NTSTATUS
Dispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This device control dispatcher handles IOCTLs.
Arguments:
DeviceObject - Context for the activity.
Irp - The device control argument block.
Return Value:
NTSTATUS
--*/
{
PDEVICE_EXTENSION pDeviceExtension;
PIO_STACK_LOCATION pIrpStack;
PSET_EVENT pSetEvent;
ULONG ulInformation = 0L;
NTSTATUS status = STATUS_NOT_IMPLEMENTED;
KdPrint(("Event!Dispatch - IN\n"));
pDeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
pIrpStack = IoGetCurrentIrpStackLocation( Irp );
switch( pIrpStack->MajorFunction )
{
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
KdPrint(("\t%s\n", (IRP_MJ_CREATE == pIrpStack->MajorFunction) ? "IRP_MJ_CREATE" : "IRP_MJ_CLOSE"));
status = STATUS_SUCCESS;
break;
case IRP_MJ_DEVICE_CONTROL:
switch( pIrpStack->Parameters.DeviceIoControl.IoControlCode )
{
case IOCTL_SET_EVENT:
KdPrint(("\tIOCTL_SET_EVENT\n"));
if ( pIrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_SETEVENT ) {
// Parameters are invalid
KdPrint(("\tSTATUS_INVALID_PARAMETER\n"));
status = STATUS_INVALID_PARAMETER;
} else {
pSetEvent = (PSET_EVENT)Irp->AssociatedIrp.SystemBuffer;
KdPrint(("\tuser-mode HANDLE = 0x%x\n", pSetEvent->hEvent ));
status = ObReferenceObjectByHandle( pSetEvent->hEvent,
SYNCHRONIZE,
NULL,
KernelMode,
&pDeviceExtension->hEvent,
NULL
);
if ( !NT_SUCCESS(status) ) {
KdPrint(("\tUnable to reference User-Mode Event object, Error = 0x%x\n", status));
} else {
KdPrint(("\tkernel-mode HANDLE = 0x%x\n", pDeviceExtension->hEvent ));
//
// Start the timer to run the CustomTimerDPC in DueTime seconds to
// simulate an interrupt (which would queue a DPC).
// The user's event object is signaled in the DPC.
//
// ensure relative time for this sample
if ( pSetEvent->DueTime.QuadPart > 0 )
pSetEvent->DueTime.QuadPart = -(pSetEvent->DueTime.QuadPart);
KdPrint(("\tDueTime = %d\n", pSetEvent->DueTime.QuadPart ));
KeSetTimer(
&pDeviceExtension->Timer, // Timer
pSetEvent->DueTime, // DueTime
&pDeviceExtension->Dpc // Dpc
);
status = STATUS_SUCCESS;
}
}
break;
default:
// should never hit this
ASSERT(0);
status = STATUS_NOT_IMPLEMENTED;
break;
} // switch IoControlCode
break;
default:
// should never hit this
ASSERT(0);
status = STATUS_NOT_IMPLEMENTED;
break;
} // switch MajorFunction
//
// complete the Irp
//
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = ulInformation;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
KdPrint(("Event!Dispatch - OUT\n"));
return status;
}
VOID
CustomTimerDPC(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
)
/*++
Routine Description:
This is the DPC associated with this drivers Timer object setup in DriverEntry.
Arguments:
Dpc - our DPC object associated with our Timer
DeferredContext - Context for the DPC that we setup in DriverEntry
SystemArgument1 -
SystemArgument2 -
Return Value:
Nothing.
--*/
{
PDEVICE_OBJECT pDeviceObject = DeferredContext;
PDEVICE_EXTENSION pDeviceExtension = pDeviceObject->DeviceExtension;
KdPrint(("Event!CustomTimerDPC - IN\n"));
//
// Signal the Event created user-mode
//
// Note:
// Do not call KeSetEvent from your ISR;
// you must call it at IRQL <= DISPATCH_LEVEL.
// Your ISR should queue a DPC and the DPC can
// then call KeSetEvent on the ISR's behalf.
//
KeSetEvent((PKEVENT)pDeviceExtension->hEvent,// Event
0, // Increment
FALSE // Wait
);
// there is no Irp to complete here
KdPrint(("Event!CustomTimerDPC - OUT\n"));
return;
}
// EOF

View File

@@ -1,43 +0,0 @@
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
Event.h
Abstract:
Author:
Jeff Midkiff (jeffmi) 23-Jul-96
Enviroment:
Revision History:
--*/
#ifndef __EVENT__
#define __EVENT__
#include "devioctl.h"
typedef struct _SET_EVENT
{
HANDLE hEvent;
LARGE_INTEGER DueTime; // requested DueTime in 100-nanosecond units
} SET_EVENT, *PSET_EVENT;
#define SIZEOF_SETEVENT sizeof(SET_EVENT)
#define IOCTL_SET_EVENT \
CTL_CODE( FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS )
#endif // __EVENT__

View File

@@ -1,7 +0,0 @@
; note - the service name matches the driver's file (.sys) name
\Registry\Machine\System\CurrentControlSet\Services\Event
Type = REG_DWORD 0x00000001
Start = REG_DWORD 0x00000003
Group = Extended Base
ErrorControl = REG_DWORD 0x00000001

View File

@@ -1,11 +0,0 @@
#include <windows.h>
#include <ntverp.h>
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
#define VER_FILEDESCRIPTION_STR "Sample Event Driver"
#define VER_INTERNALNAME_STR "event.sys"
#include "common.ver"

View File

@@ -1,7 +0,0 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def

View File

@@ -1,6 +0,0 @@
TARGETNAME=event
TARGETPATH=$(BASEDIR)\lib
TARGETTYPE=DRIVER
SOURCES=event.c \
event.rc

View File

@@ -1,444 +0,0 @@
//
// FLOPPY.C - NEC-765/8272A floppy device driver
// written by Rex Jolliff
// with help from various other sources, including but not limited to:
// Art Baker's NT Device Driver Book, Linux Source, and the internet.
//
// Modification History:
// 08/19/98 RJJ Created.
//
// To do:
// FIXME: get it working
// FIXME: add support for DMA hardware
// FIXME: should add support for floppy tape/zip devices
#include <ddk/ntddk.h>
#include "floppy.h"
#define VERSION "V0.0.1"
// --------------------------------------------------- File Statics
typedef struct _FLOPPY_CONTROLLER_PARAMETERS
{
int PortBase;
int Vector;
int IrqL;
int SynchronizeIrqL;
KINTERRUPT_MODE InterruptMode;
KAFFINITY Affinity;
} FLOPPY_CONTROLLER_PARAMETERS, *PFLOPPY_CONTROLLER_PARAMETERS;
#define FLOPPY_MAX_CONTROLLERS 2
FLOPPY_CONTROLLER_PARAMETERS ControllerParameters[FLOPPY_MAX_CONTROLLERS] =
{
{0x03f0, 6, 6, 6, LevelSensitive, 0xffff},
{0x0370, 6, 6, 6, LevelSensitive, 0xffff},
};
FLOPPY_DEVICE_PARAMETERS DeviceTypes[] =
{
/* Unknown */
{0, 500, 16, 16, 8000, 1000, 3000, 0, 20, 5, 80, 3000, 20, {3,1,2,0,2}, 0, 0, { 7, 4, 8, 2, 1, 5, 3,10}, 1500, 0, "unknown"},
/* 5 1/4 360 KB PC*/
{1, 300, 16, 16, 8000, 1000, 3000, 0, 20, 5, 40, 3000, 17, {3,1,2,0,2}, 0, 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 1500, 1, "360K PC"},
/* 5 1/4 HD AT*/
{2, 500, 16, 16, 6000, 400, 3000, 14, 20, 6, 83, 3000, 17, {3,1,2,0,2}, 0, 0, { 2, 5, 6,23,10,20,11, 0}, 1500, 2, "1.2M"},
/* 3 1/2 DD*/
{3, 250, 16, 16, 3000, 1000, 3000, 0, 20, 5, 83, 3000, 20, {3,1,2,0,2}, 0, 0, { 4,22,21,30, 3, 0, 0, 0}, 1500, 4, "720k"},
/* 3 1/2 HD*/
{4, 500, 16, 16, 4000, 400, 3000, 10, 20, 5, 83, 3000, 20, {3,1,2,0,2}, 0, 0, { 7, 4,25,22,31,21,29,11}, 1500, 7, "1.44M"},
/* 3 1/2 ED*/
{5, 1000, 15, 8, 3000, 400, 3000, 10, 20, 5, 83, 3000, 40, {3,1,2,0,2}, 0, 0, { 7, 8, 4,25,28,22,31,21}, 1500, 8, "2.88M AMI BIOS"},
/* 3 1/2 ED*/
{6, 1000, 15, 8, 3000, 400, 3000, 10, 20, 5, 83, 3000, 40, {3,1,2,0,2}, 0, 0, { 7, 8, 4,25,28,22,31,21}, 1500, 8, "2.88M"}
};
static BOOLEAN FloppyInitialized = FALSE;
// ------------------------------------------------------ Functions
// ModuleEntry
//
// DESCRIPTION:
// This function initializes the driver, locates and claims
// hardware resources, and creates various NT objects needed
// to process I/O requests.
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// IN PDRIVER_OBJECT DriverObject System allocated Driver Object
// for this driver
// IN PUNICODE_STRING RegistryPath Name of registry driver service
// key
//
// RETURNS:
// NTSTATUS
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
NTSTATUS RC;
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
// Export other driver entry points...
DriverObject->DriverStartIo = FloppyStartIo;
DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
DriverObject->MajorFunction[IRP_MJ_READ] = FloppyDispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FloppyDispatchDeviceControl;
// Try to detect controller and abort if it fails
if (!FloppyCreateController(DriverObject,
&ControllerParameters[0],
0))
{
DPRINT("Could not find floppy controller");
return STATUS_NO_SUCH_DEVICE;
}
return STATUS_SUCCESS;
}
static BOOLEAN
FloppyCreateController(PDRIVER_OBJECT DriverObject,
PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
int Index)
{
PFLOPPY_CONTROLLER_TYPE ControllerType;
PCONTROLLER_OBJECT ControllerObject;
PFLOPPY_CONTROLLER_EXTENSION ControllerExtension;
/* Detect controller and determine type */
if (!FloppyGetControllerVersion(ControllerParameters, &ControllerType))
{
return FALSE;
}
// FIXME: Register port ranges and interrupts with HAL
/* Create controller object for FDC */
ControllerObject = IoCreateController(sizeof(FLOPPY_CONTROLLER_EXTENSION));
if (ControllerObject == NULL)
{
DPRINT("Could not create controller object for controller %d\n",
Index);
return FALSE;
}
// FIXME: fill out controller data
ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)
ControllerObject->ControllerExtension;
ControllerExtension->Number = Index;
ControllerExtension->PortBase = ControllerParameters->PortBase;
ControllerExtension->Vector = ControllerParameters->Vector;
ControllerExtension->FDCType = ControllerType;
/* Initialize the spin lock in the controller extension */
KeInitializeSpinLock(&ControllerExtension->SpinLock);
/* Register an interrupt handler for this controller */
RC = IoConnectInterrupt(&ControllerExtension->Interrupt,
FloppyIsr,
ControllerExtension,
&ControllerExtension->SpinLock,
ControllerExtension->Vector,
ControllerParameters->IrqL,
ControllerParameters->SynchronizeIrqL,
ControllerParameters->InterruptMode,
FALSE,
ControllerParameters->Affinity,
FALSE);
if (!NT_SUCCESS(RC))
{
DPRINT("Could not Connect Interrupt %d\n", ControllerExtension->Vector);
IoDeleteController(ControllerObject);
return FALSE;
}
// FIXME: setup DMA stuff for controller
// Check for each possible drive and create devices for them
for (DriveIdx = 0; DriveIdx < FLOPPY_MAX_DRIVES; DriveIdx++)
{
// FIXME: try to identify the drive
// FIXME: create a device if it's there
}
return STATUS_SUCCESS;
}
// FloppyGetControllerVersion
//
// DESCRIPTION
// Get the type/version of the floppy controller
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// IN OUT PFLOPPY_DEVICE_EXTENSION DeviceExtension
//
// RETURNS:
// BOOL success or failure
//
// COMMENTS:
// This routine (get_fdc_version) was originally written by David C. Niemi
//
static BOOLEAN
FloppyGetControllerVersion(IN PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
OUT PFLOPPY_CONTROLLER_TYPE ControllerType)
{
BYTE ResultReturned
BYTE Result[FLOPPY_MAX_REPLIES];
int ResultLength;
/* 82072 and better know DUMPREGS */
if (!FloppyWriteCommandByte(ControllerParameters->PortBase,
FLOPPY_CMD_DUMP_FDC))
{
return FALSE;
}
ResultLength = FloppyReadResultCode(PortBase, &Result));
if (ResultLength < 0)
{
return FALSE;
}
/* 8272a/765 don't know DUMPREGS */
if ((ResultLength == 1) && (Result[0] == 0x80))
{
DPRINT("FDC %d is an 8272A\n", PortBase);
*ControllerType = FDC_8272A;
return TRUE;
}
if (r != 10)
{
DPRINT("FDC %d init: DUMP_FDC: unexpected return of %d bytes.\n",
PortBase,
ResultLength);
return FALSE;
}
if (!FloppyConfigure(PortBase, FALSE, 0x0a))
{
DPRINT("FDC %d is an 82072\n", PortBase);
*ControllerType = FDC_82072;
return TRUE;
}
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PPND_RW);
if (FloppyNeedsMoreOutput(PortBase, Result) == FLOPPY_NEEDS_OUTPUT)
{
FloppyWriteCommandByte(PortBase, 0);
}
else
{
DPRINT("FDC %d is an 82072A\n", PortBase);
*ControllerType = FDC_82072A;
return TRUE;
}
/* Pre-1991 82077, doesn't know LOCK/UNLOCK */
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_UNLK_FIFO);
ResultLength = FloppyReadResultCode(PortBase, &Result));
if ((ResultLength == 1) && (Result[0] == 0x80))
{
DPRINT("FDC %d is a pre-1991 82077\n", PortBase);
*ControllerType = FDC_82077_ORIG;
return TRUE;
}
if ((ResultLength != 1) || (Result[0] != 0x00))
{
DPRINT("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
PortBase,
ResultLength);
return FALSE;
}
/* Revised 82077AA passes all the tests */
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PARTID);
ResultLength = FloppyReadResultCode(PortBase, &Result));
if (ResultLength != 1)
{
DPRINT("FDC %d init: PARTID: unexpected return of %d bytes.\n",
PortBase,
ResultLength);
return FALSE;
}
if (Result[0] == 0x80)
{
DPRINT("FDC %d is a post-1991 82077\n", PortBase);
*ControllerType = FDC_82077;
return TRUE;
}
switch (Result[0] >> 5)
{
case 0x0:
/* Either a 82078-1 or a 82078SL running at 5Volt */
DPRINT("FDC %d is an 82078.\n", PortBase);
*ControllerType = FDC_82078;
return TRUE;
case 0x1:
DPRINT("FDC %d is a 44pin 82078\n", PortBase);
*ControllerType = FDC_82078;
return TRUE;
case 0x2:
DPRINT("FDC %d is a S82078B\n", PortBase);
*ControllerType = FDC_S82078B;
return TRUE;
case 0x3:
DPRINT("FDC %d is a National Semiconductor PC87306\n", PortBase);
*ControllerType = FDC_87306;
return TRUE;
default:
DPRINT("FDC %d init: 82078 variant with unknown PARTID=%d.\n",
PortBase,
Result[0] >> 5);
*ControllerType = FDC_82078_UNKN;
return TRUE;
}
}
/* sends a command byte to the fdc */
static BOOLEAN
FloppyWriteCommandByte(WORD PortBase, BYTE Byte)
{
int Status;
if ((Status = FloppyWaitUntilReady()) < 0)
{
return FALSE;
}
if ((Status & (STATUS_READY|STATUS_DIR|STATUS_DMA)) == STATUS_READY)
{
FloppyWriteData(PortBase, Byte);
return 0;
}
if (FloppyInitialized)
{
DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
Byte,
PortBase,
Status);
}
return FALSE;
}
/* gets the response from the fdc */
static int
FloppyReadResultCode(WORD PortBase, PBYTE Result)
{
int Replies;
int Status;
for (Replies = 0; Replies < FLOPPY_MAX_REPLIES; Replies++)
{
if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
{
break;
}
Status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
if ((Status & ~STATUS_BUSY) == STATUS_READY)
{
return Replies;
}
if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
{
Result[Replies] = fd_inb(FD_DATA);
}
else
{
break;
}
}
if (FloppyInitialized)
{
DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
PortBase,
Status,
Replies);
}
return -1;
}
/* waits until the fdc becomes ready */
static int
FloppyWaitUntilReady(WORD PortBase)
{
int Retries;
int Status;
for (Retries = 0; Retries < FLOPPY_MAX_STAT_RETRIES; Retries++)
{
status = FloppyReadSTAT(PortBase);
if (Status & STATUS_READY)
{
return Status;
}
}
if (FloppyInitialized)
{
DPRINT("Getstatus times out (%x) on fdc %d\n",
Status,
PortBase);
}
return -1;
}
#define MORE_OUTPUT -2
/* does the fdc need more output? */
static int
FloppyNeedsMoreOutput(WORD PortBase, PBYTE Result)
{
int Status;
if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
return -1;
if ((Status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
{
return FLOPPY_NEEDS_OUTPUT;
}
return FloppyReadResultCode(PortBase, Result);
}
static BOOLEAN
FloppyConfigure(WORD PortBase, BOOLEAN DisableFIFO, BYTE FIFODepth)
{
BYTE Result[FLOPPY_MAX_REPLIES];
/* Turn on FIFO */
FloppyWriteCommandByte(FLOPPY_CMD_CFG_FIFO);
if (FloppyNeedsOutput(PortBase, Result) != FLOPPY_NEEDS_OUTPUT)
{
return FALSE;
}
FloppyWriteCommandByte(PortBase, 0);
FloppyWriteCommandByte(PortBase,
0x10 |
(DisableFIFO ? 0x20 : 0x00) |
(FIFODepth & 0x0f));
/* pre-compensation from track 0 upwards */
FloppyWriteCommandByte(PortBase, 0);
return TRUE;
}

View File

@@ -1,158 +0,0 @@
#define FLOPPY_MAX_STAT_RETRIES 10000
#define FLOPPY_NEEDS_OUTPUT -2
//
// Floppy register definitions
//
#define FLOPPY_REG_DOR 0x0002
#define FLOPPY_REG_MSTAT 0x0004
#define FLOPPY_MS_DRV0BUSY 0x01
#define FLOPPY_MS_DRV1BUSY 0x02
#define FLOPPY_MS_DRV2BUSY 0x04
#define FLOPPY_MS_DRV3BUSY 0x08
#define FLOPPY_MS_FDCBUSY 0x10
#define FLOPPY_MS_DMAMODE 0x20
#define FLOPPY_MS_DATADIR 0x40
#define FLOPPY_MS_DATARDY 0x80
#define FLOPPY_REG_DATA 0x0005
#define FLOPPY_REG_DIR 0x0007 /* READ ONLY */
#define FLOPPY_DI_DSKCHNG 0x80
#define FLOPPY_REG_CCNTL 0x0007 /* WRITE ONLY */
#define FLOPPY_CMD_RD_TRK 0x02
#define FLOPPY_CMD_SPEC_CHARS 0x03
#define FLOPPY_CSC_SRT_SHIFT 4
#define FLOPPY_CSC_HUT_MASK 0x0f
#define FLOPPY_CSC_HLT_SHIFT 1
#define FLOPPY_CSC_NON_DMA 0x01
#define FLOPPY_CMD_SNS_DRV 0x04
#define FLOPPY_CMD_WRT_DATA 0x05
#define FLOPPY_CMD_RD_DATA 0x06
#define FLOPPY_CMD_RECAL 0x07
#define FLOPPY_CMD_SNS_INTR 0x08
#define FLOPPY_CSI_IC_MASK 0xe0
#define FLOPPY_CSI_IC_RDYCH 0x60
#define FLOPPY_CSI_IC_SEEKGD 0x80
#define FLOPPY_CSI_IC_SEEKBD 0xc0
#define FLOPPY_CMD_WRT_DEL 0x09
#define FLOPPY_CMD_RD_ID 0x0a
#define FLOPPY_CMD_RD_DEL 0x0c
#define FLOPPY_CMD_FMT_TRK 0x0d
#define FLOPPY_CMD_DUMP_FDC 0x0e
#define FLOPPY_CMD_SEEK 0x0f
#define FLOPPY_CMD_VERSION 0x10
#define FLOPPY_CMD_SCN_EQ 0x11
#define FLOPPY_CMD_PPND_RW 0x12
#define FLOPPY_CMD_CFG_FIFO 0x13
#define FLOPPY_CMD_LCK_FIFO 0x14
#define FLOPPY_CMD_PARTID 0x18
#define FLOPPY_CMD_SCN_LE 0x19
#define FLOPPY_CMD_SCN_GE 0x1d
#define FLOPPY_CMD_CFG_PWR 0x27
#define FLOPPY_CMD_SAVE_FDC 0x2e
#define FLOPPY_CMD_FMT_ISO 0x33
#define FLOPPY_CMD_DMA_READ 0x46
#define FLOPPY_CMD_DMA_WRT 0x4a
#define FLOPPY_CMD_REST_FDC 0x4e
#define FLOPPY_CMD_DRV_SPEC 0x8e
#define FLOPPY_CMD_RSEEK_OUT 0x8f
#define FLOPPY_CMD_ULK_FIFO 0x94
#define FLOPPY_CMD_RSEEK_IN 0xcf
#define FLOPPY_CMD_FMT_WRT 0xef
// Command Code modifiers
#define FLOPPY_C0M_SK 0x20
#define FLOPPY_C0M_MFM 0x40
#define FLOPPY_C0M_MT 0x80
#define FLOPPY_C1M_DRVMASK 0x03
#define FLOPPY_C1M_HEAD1 0x04
// Status code values and masks
#define FLOPPY_ST0_INVALID 0x80
// useful command defines
#define FLOPPY_CMD_READ (FLOPPY_CMD_RD_DATA | FLOPPY_C0M_SK | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
#define FLOPPY_CMD_WRITE (FLOPPY_CMD_WRT_DATA | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
#define FLOPPY_CMD_FORMAT (FLOPPY_CMD_FMT_TRK | FLOPPY_C0M_MFM)
//
// HAL floppy register access commands
//
#define FloppyWriteDOR(A, V) (WRITE_BYTE((A) + FLOPPY_REG_DOR, (V)))
#define FloppyReadMSTAT(A) (READ_BYTE((A) + FLOPPY_REG_MSTAT))
#define FloppyReadDATA(A) (READ_BYTE((A) + FLOPPY_REG_DATA))
#define FloppyWriteDATA(A, V) (WRITE_BYTE((A) + FLOPPY_REG_DATA, (V)))
#define FloppyReadDIR(A) (READ_BYTE((A) + FLOPPY_REG_DIR))
#define FloppyWriteCCNTL(A, V) (WRITE_BYTE((A) + FLOPPY_REG_CCNTL, (V)))
//
// Known Floppy controller types
//
typedef enum _FLOPPY_CONTROLLER_TYPE
{
FDC_NONE,
FDC_UNKNOWN,
FDC_8272A, /* Intel 8272a, NEC 765 */
FDC_765ED, /* Non-Intel 1MB-compatible FDC, can't detect */
FDC_82072, /* Intel 82072; 8272a + FIFO + DUMPREGS */
FDC_82072A, /* 82072A (on Sparcs) */
FDC_82077_ORIG, /* Original version of 82077AA, sans LOCK */
FDC_82077, /* 82077AA-1 */
FDC_82078_UNKN, /* Unknown 82078 variant */
FDC_82078, /* 44pin 82078 or 64pin 82078SL */
FDC_82078_1, /* 82078-1 (2Mbps fdc) */
FDC_S82078B, /* S82078B (first seen on Adaptec AVA-2825 VLB SCSI/EIDE/Floppy controller) */
FDC_87306 /* National Semiconductor PC 87306 */
} FLOPPY_CONTROLLER_TYPE, *PFLOPPY_CONTROLLER_TYPE;
typedef struct _FLOPPY_ERROR_THRESHOLDS
{
/* number of errors to be reached before aborting */
unsigned int Abort;
/* maximal number of errors permitted to read an entire track at once */
unsigned int ReadTrack;
/* maximal number of errors before a reset is tried */
unsigned int Reset;
/* maximal number of errors before a recalibrate is tried */
unsigned int Recal;
/*
* Threshold for reporting FDC errors to the console.
* Setting this to zero may flood your screen when using
* ultra cheap floppies ;-)
*/
unsigned int Reporting;
} FLOPPY_ERROR_THRESHOLDS;
#define FDP_DEBUG 0x02
#define FDP_SILENT_DCL_CLEAR 0x04
#define FDP_MSG 0x10
#define FDP_BROKEN_DCL 0x20
#define FDP_INVERTED_DCL 0x80
typedef struct _FLOPPY_DEVICE_PARAMETERS
{
char CMOSType;
unsigned long MaxDTR; /* Step rate, usec */
unsigned long HLT; /* Head load/settle time, msec */
unsigned long HUT; /* Head unload time (remnant of 8" drives) */
unsigned long SRT; /* Step rate, usec */
unsigned long Spinup; /* time needed for spinup */
unsigned long Spindown; /* timeout needed for spindown */
unsigned char SpindownOffset; /* decides in which position the disk will stop */
unsigned char SelectDelay; /* delay to wait after select */
unsigned char RPS; /* rotations per second */
unsigned char Tracks; /* maximum number of tracks */
unsigned long Timeout; /* timeout for interrupt requests */
unsigned char InterleaveSect; /* if there are more sectors, use interleave */
FLOPPY_ERROR_THRESHOLDS MaxErrors;
char Flags; /* various flags, including ftd_msg */
BOOLEAN ReadTrack; /* use readtrack during probing? */
short Autodetect[8]; /* autodetected formats */
int CheckFreq; /* how often should the drive be checked for disk changes */
int NativeFormat; /* native format of this drive */
char *DriveName; /* name of the drive for reporting */
} FLOPPY_DEVICE_PARAMETERS, *PFLOPPY_DEVICE_PARAMETERS;

View File

@@ -1,3 +0,0 @@
base.tmp
junk.tmp
temp.exp

File diff suppressed because it is too large Load Diff

View File

@@ -1,232 +0,0 @@
//
// IDE.H - defines and typedefs for the IDE Driver module.
//
#ifndef __IDE_H
#define __IDE_H
#ifdef __cplusplus
extern "C" {
#endif
#define IDE_MAXIMUM_DEVICES 8
#define IDE_MAX_NAME_LENGTH 50
#define IDE_NT_ROOTDIR_NAME "\\Device"
#define IDE_NT_DEVICE_NAME "\\HardDrive"
#define IDE_NT_PARTITION_NAME "\\Partition"
#define IDE_WIN32_DEVICE_NAME "\\DosDevices\\IDE"
#define IDE_DRIVER_NAME "IDEDRIVER"
#define IDE_SECTOR_BUF_SZ 512
#define IDE_MAX_SECTORS_PER_XFER 256
#define IDE_MAX_RESET_RETRIES 10000
#define IDE_MAX_POLL_RETRIES 100000
#define IDE_MAX_WRITE_RETRIES 1000
#define IDE_MAX_BUSY_RETRIES 100
#define IDE_MAX_DRQ_RETRIES 10000
#define IDE_MAX_CMD_RETRIES 1
#define IDE_CMD_TIMEOUT 5
#define IDE_RESET_BUSY_TIMEOUT 31
#define IDE_RESET_DRDY_TIMEOUT 120
// Control Block offsets and masks
#define IDE_REG_ALT_STATUS 0x0000
#define IDE_REG_DEV_CNTRL 0x0000 /* device control register */
#define IDE_DC_SRST 0x04 /* drive reset (both drives) */
#define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */
#define IDE_REG_DRV_ADDR 0x0001
// Command Block offsets and masks
#define IDE_REG_DATA_PORT 0x0000
#define IDE_REG_ERROR 0x0001 /* error register */
#define IDE_ER_AMNF 0x01 /* addr mark not found */
#define IDE_ER_TK0NF 0x02 /* track 0 not found */
#define IDE_ER_ABRT 0x04 /* command aborted */
#define IDE_ER_MCR 0x08 /* media change requested */
#define IDE_ER_IDNF 0x10 /* ID not found */
#define IDE_ER_MC 0x20 /* Media changed */
#define IDE_ER_UNC 0x40 /* Uncorrectable data error */
#define IDE_REG_PRECOMP 0x0001
#define IDE_REG_SECTOR_CNT 0x0002
#define IDE_REG_SECTOR_NUM 0x0003
#define IDE_REG_CYL_LOW 0x0004
#define IDE_REG_CYL_HIGH 0x0005
#define IDE_REG_DRV_HEAD 0x0006
#define IDE_DH_FIXED 0xA0
#define IDE_DH_LBA 0x40
#define IDE_DH_HDMASK 0x0F
#define IDE_DH_DRV0 0x00
#define IDE_DH_DRV1 0x10
#define IDE_REG_STATUS 0x0007
#define IDE_SR_BUSY 0x80
#define IDE_SR_DRDY 0x40
#define IDE_SR_DRQ 0x08
#define IDE_SR_ERR 0x01
#define IDE_REG_COMMAND 0x0007
#define IDE_CMD_READ 0x20
#define IDE_CMD_READ_RETRY 0x21
#define IDE_CMD_WRITE 0x30
#define IDE_CMD_WRITE_RETRY 0x31
#define IDE_CMD_IDENT_DRV 0xEC
//
// Access macros for command registers
// Each macro takes an address of the command port block, and data
//
#define IDEReadError(Address) (inb_p((Address) + IDE_REG_ERROR))
#define IDEWritePrecomp(Address, Data) (outb_p((Address) + IDE_REG_PRECOMP, (Data)))
#define IDEReadSectorCount(Address) (inb_p((Address) + IDE_REG_SECTOR_CNT))
#define IDEWriteSectorCount(Address, Data) (outb_p((Address) + IDE_REG_SECTOR_CNT, (Data)))
#define IDEReadSectorNum(Address) (inb_p((Address) + IDE_REG_SECTOR_NUM))
#define IDEWriteSectorNum(Address, Data) (outb_p((Address) + IDE_REG_SECTOR_NUM, (Data)))
#define IDEReadCylinderLow(Address) (inb_p((Address) + IDE_REG_CYL_LOW))
#define IDEWriteCylinderLow(Address, Data) (outb_p((Address) + IDE_REG_CYL_LOW, (Data)))
#define IDEReadCylinderHigh(Address) (inb_p((Address) + IDE_REG_CYL_HIGH))
#define IDEWriteCylinderHigh(Address, Data) (outb_p((Address) + IDE_REG_CYL_HIGH, (Data)))
#define IDEReadDriveHead(Address) (inb_p((Address) + IDE_REG_DRV_HEAD))
#define IDEWriteDriveHead(Address, Data) (outb_p((Address) + IDE_REG_DRV_HEAD, (Data)))
#define IDEReadStatus(Address) (inb_p((Address) + IDE_REG_STATUS))
#define IDEWriteCommand(Address, Data) (outb_p((Address) + IDE_REG_COMMAND, (Data)))
//
// Data block read and write commands
//
#define IDEReadBlock(Address, Buffer, Count) \
(insw((Address) + IDE_REG_DATA_PORT, (Buffer), (Count) / 2))
#define IDEWriteBlock(Address, Buffer, Count) \
(outsw((Address) + IDE_REG_DATA_PORT, (Buffer), (Count) / 2))
//
// Access macros for control registers
// Each macro takes an address of the control port blank and data
//
#define IDEWriteDriveControl(Address, Data) (outb_p((Address) + IDE_REG_DEV_CNTRL, (Data)))
// IDE_DEVICE_EXTENSION
//
// DESCRIPTION:
// Extension to be placed in each device object
//
// ACCESS:
// Allocated from NON-PAGED POOL
// Available at any IRQL
//
typedef struct _IDE_DEVICE_EXTENSION {
PDEVICE_OBJECT DeviceObject;
PCONTROLLER_OBJECT ControllerObject;
struct _IDE_DEVICE_EXTESION *DiskExtension;
int UnitNumber;
BOOLEAN LBASupported;
BOOLEAN DMASupported;
int BytesPerSector;
int LogicalHeads;
int SectorsPerLogCyl;
int SectorsPerLogTrk;
int Offset;
int Size;
int Operation;
ULONG BytesRequested;
ULONG BytesToTransfer;
ULONG BytesRemaining;
ULONG StartingSector;
int SectorsTransferred;
BYTE *TargetAddress;
} IDE_DEVICE_EXTENSION, *PIDE_DEVICE_EXTENSION;
// IDE_TIMER_STATES
//
// DESCRIPTION:
// An enumeration containing the states in the timer DFA
//
typedef enum _IDE_TIMER_STATES {
IDETimerIdle,
IDETimerCmdWait,
IDETimerResetWaitForBusyNegate,
IDETimerResetWaitForDrdyAssert
} IDE_TIMER_STATES;
// IDE_CONTROLLER_EXTENSION
//
// DESCRIPTION:
// Driver-defined structure used to hold miscellaneous controller information.
//
// ACCESS:
// Allocated from NON-PAGED POOL
// Available at any IRQL
//
typedef struct _IDE_CONTROLLER_EXTENSION {
KSPIN_LOCK SpinLock;
int Number;
int Vector;
int CommandPortBase;
int ControlPortBase;
BOOLEAN DMASupported;
BOOLEAN ControllerInterruptBug;
PKINTERRUPT Interrupt;
BOOLEAN OperationInProgress;
BYTE DeviceStatus;
PIDE_DEVICE_EXTENSION DeviceForOperation;
PIRP CurrentIrp;
int Retries;
IDE_TIMER_STATES TimerState;
LONG TimerCount;
PDEVICE_OBJECT TimerDevice;
} IDE_CONTROLLER_EXTENSION, *PIDE_CONTROLLER_EXTENSION;
// IDE_DRIVE_IDENTIFY
typedef struct _IDE_DRIVE_IDENTIFY {
WORD ConfigBits; /*00*/
WORD LogicalCyls; /*01*/
WORD Reserved02; /*02*/
WORD LogicalHeads; /*03*/
WORD BytesPerTrack; /*04*/
WORD BytesPerSector; /*05*/
WORD SectorsPerTrack; /*06*/
BYTE InterSectorGap; /*07*/
BYTE InterSectorGapSize;
BYTE Reserved08H; /*08*/
BYTE BytesInPLO;
WORD VendorUniqueCnt; /*09*/
char SerialNumber[20]; /*10*/
WORD ControllerType; /*20*/
WORD BufferSize; /*21*/
WORD ECCByteCnt; /*22*/
char FirmwareRev[8]; /*23*/
char ModelNumber[40]; /*27*/
WORD RWMultImplemented; /*47*/
WORD Reserved48; /*48*/
WORD Capabilities; /*49*/
#define IDE_DRID_STBY_SUPPORTED 0x2000
#define IDE_DRID_IORDY_SUPPORTED 0x0800
#define IDE_DRID_IORDY_DISABLE 0x0400
#define IDE_DRID_LBA_SUPPORTED 0x0200
#define IDE_DRID_DMA_SUPPORTED 0x0100
WORD Reserved50; /*50*/
WORD MinPIOTransTime; /*51*/
WORD MinDMATransTime; /*52*/
WORD TMFieldsValid; /*53*/
WORD TMCylinders; /*54*/
WORD TMHeads; /*55*/
WORD TMSectorsPerTrk; /*56*/
WORD TMCapacity; /*57*/
WORD Reserved53[198]; /*58*/
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
#ifdef __cplusplus
}
#endif
#endif /* __IDE_H */

View File

@@ -1,20 +0,0 @@
#define IOCTL_DISK_GET_DRIVE_GEOMETRY CTL_CODE(FILE_DEVICE_DISK, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_GET_PARTITION_INFO CTL_CODE(FILE_DEVICE_DISK, 1, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_DISK_SET_PARTITION_INFO CTL_CODE(FILE_DEVICE_DISK, 2, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_GET_DRIVE_LAYOUT CTL_CODE(FILE_DEVICE_DISK, 3, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_DISK_SET_DRIVE_LAYOUT CTL_CODE(FILE_DEVICE_DISK, 4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_VERIFY CTL_CODE(FILE_DEVICE_DISK, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_FORMAT_TRACKS CTL_CODE(FILE_DEVICE_DISK, 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_REASSIGN_BLOCKS CTL_CODE(FILE_DEVICE_DISK, 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_PERFORMANCE CTL_CODE(FILE_DEVICE_DISK, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_IS_WRITABLE CTL_CODE(FILE_DEVICE_DISK, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_LOGGING CTL_CODE(FILE_DEVICE_DISK, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_FORMAT_TRACKS_EX CTL_CODE(FILE_DEVICE_DISK, 11, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_DISK_HISTOGRAM_STRUCTURE CTL_CODE(FILE_DEVICE_DISK, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_HISTOGRAM_DATA CTL_CODE(FILE_DEVICE_DISK, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_HISTOGRAM_RESET CTL_CODE(FILE_DEVICE_DISK, 14, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_REQUEST_STRUCTURE CTL_CODE(FILE_DEVICE_DISK, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DISK_REQUEST_DATA CTL_CODE(FILE_DEVICE_DISK, 16, METHOD_BUFFERED, FILE_ANY_ACCESS)

View File

@@ -1,15 +0,0 @@
all: ide.sys
OBJECTS = ide.o ../../../ntoskrnl/ntoskrnl.a
ide.sys: $(OBJECTS)
$(CC) -specs=../../svc_specs -mdll -o junk.tmp -Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ -Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp $(OBJECTS)
- $(RM) junk.tmp
$(DLLTOOL) --dllname ide.sys --base-file base.tmp \
--output-exp temp.exp
- $(RM) base.tmp
$(CC) --verbose -Wl,--image-base,0x10000 -Wl,-e,_DriverEntry@8 \
-specs=../../svc_specs -mdll -o ide.sys $(OBJECTS) -Wl,temp.exp
- $(RM) temp.exp

View File

@@ -1,93 +0,0 @@
/**
*** Partition.h - defines and structs for harddrive partition info
***
*** 05/30/98 RJJ Created
**/
#ifndef __PARTITION_H
#define __PARTITION_H
#define PARTITION_MAGIC 0xaa55
#define PART_MAGIC_OFFSET 0x01fe
#define PARTITION_OFFSET 0x01be
#define PARTITION_TBL_SIZE 4
#define PTCHSToLBA(c, h, s, scnt, hcnt) ((s) & 0x3f) + \
(scnt) * ( (h) + (hcnt) * ((c) | (((s) & 0xc0) << 2)))
#define PTLBAToCHS(lba, c, h, s, scnt, hcnt) ( \
(s) = (lba) % (scnt) + 1, \
(lba) /= (scnt), \
(h) = (lba) % (hcnt), \
(lba) /= (heads), \
(c) = (lba) & 0xff, \
(s) |= ((lba) >> 2) & 0xc0)
/* taken from linux fdisk src */
typedef enum PartitionTypes {
PTEmpty = 0,
PTDOS3xPrimary, /* 1 */
PTXENIXRoot, /* 2 */
PTXENIXUsr, /* 3 */
PTOLDDOS16Bit, /* 4 */
PTDosExtended, /* 5 */
PTDos5xPrimary, /* 6 */
PTOS2HPFS, /* 7 */
PTAIX, /* 8 */
PTAIXBootable, /* 9 */
PTOS2BootMgr, /* 10 */
PTWin95FAT32,
PTWin95FAT32LBA,
PTWin95FAT16LBA,
PTWin95ExtendedLBA,
PTVenix286 = 0x40,
PTNovell = 0x51,
PTMicroport = 0x52,
PTGnuHurd = 0x63,
PTNetware286 = 0x64,
PTNetware386 = 0x65,
PTPCIX = 0x75,
PTOldMinix = 0x80,
PTMinix = 0x81,
PTLinuxSwap = 0x82,
PTLinuxExt2 = 0x83,
PTAmoeba = 0x93,
PTAmoebaBBT = 0x94,
PTBSD = 0xa5,
PTBSDIFS = 0xb7,
PTBSDISwap = 0xb8,
PTSyrinx = 0xc7,
PTCPM = 0xdb,
PTDOSAccess = 0xe1,
PTDOSRO = 0xe3,
PTDOSSecondary = 0xf2,
PTBBT = 0xff
} PARTITIONTYPES;
#define PartitionIsSupported(P) \
((P)->PartitionType == PTDOS3xPrimary || \
(P)->PartitionType == PTOLDDOS16Bit || \
(P)->PartitionType == PTDos5xPrimary || \
(P)->PartitionType == PTWin95FAT32 || \
(P)->PartitionType == PTWin95FAT32LBA || \
(P)->PartitionType == PTWin95FAT16LBA || \
(P)->PartitionType == PTLinuxExt2)
#define PartitionIsExtended(P) \
((P)->PartitionType == PTDosExtended)
typedef struct Partition {
unsigned char BootFlags;
unsigned char StartingHead;
unsigned char StartingSector;
unsigned char StartingCylinder;
unsigned char PartitionType;
unsigned char EndingHead;
unsigned char EndingSector;
unsigned char EndingCylinder;
unsigned int StartingBlock;
unsigned int SectorCount;
} PARTITION;
#endif // PARTITION_H

View File

@@ -1,4 +0,0 @@
base.tmp
junk.tmp
temp.exp

View File

@@ -1,722 +0,0 @@
/*
** File: keyboard.c
** Description: ReactOS keyboard driver
** Current version: 0.0.4
** Last modified: 28 May 1998
**
* 31/08/98: Changed to interrupt driven model
* 29/06/98: NT interface by David Welch (welch@mcmail.com)
*
** Written by Victor Kirhenshtein (sauros@iname.com)
** Initial attempt by Jason Filby
**
** Some parts of this code are based on Linux keyboard driver
** written by Johan Myreen.
**
**
** KNOWN BUGS:
**
** * Repeat counter isn't supported
**
*/
#include <internal/mmhal.h>
#include <internal/halio.h>
#include <ddk/ntddk.h>
#include <string.h>
#include <internal/string.h>
#include <defines.h>
#define NDEBUG
#include <internal/debug.h>
#include "keyboard.h"
/*
* Driver data
*/
static KEY_EVENT_RECORD kbdBuffer[KBD_BUFFER_SIZE];
static int bufHead,bufTail;
static int keysInBuffer;
static int extKey;
static BYTE ledStatus;
static BYTE capsDown,numDown,scrollDown;
static DWORD ctrlKeyState;
static KSPIN_LOCK kbdBufferLock;
static PKINTERRUPT KbdInterrupt;
static KDPC KbdDpc;
/*
* PURPOSE: Current irp being processed
*/
static PIRP CurrentIrp;
/*
* PURPOSE: Number of keys that have been read into the current irp's buffer
*/
static ULONG KeysRead;
static ULONG KeysRequired;
/*
* Virtual key codes table
*
* Comments:
* * PrtSc = VK_PRINT
* * Alt+PrtSc (SysRq) = VK_EXECUTE
* * Alt = VK_MENU
*/
static const WORD vkTable[128]=
{
/* 00 - 07 */ 0, VK_ESCAPE, VK_1, VK_2, VK_3, VK_4, VK_5, VK_6,
/* 08 - 0F */ VK_7, VK_8, VK_9, VK_0, 189, 187, VK_BACK, VK_TAB,
/* 10 - 17 */ VK_Q, VK_W, VK_E, VK_R, VK_T, VK_Y, VK_U, VK_I,
/* 18 - 1F */ VK_O, VK_P, 219, 221, VK_RETURN, VK_CONTROL, VK_A, VK_S,
/* 20 - 27 */ VK_D, VK_F, VK_G, VK_H, VK_J, VK_K, VK_L, 186,
/* 28 - 2F */ 222, 192, VK_SHIFT, 220, VK_Z, VK_X, VK_C, VK_V,
/* 30 - 37 */ VK_B, VK_N, VK_M, 188, 190, 191, VK_SHIFT, VK_MULTIPLY,
/* 38 - 3F */ VK_MENU, VK_SPACE, VK_CAPITAL, VK_F1, VK_F2, VK_F3, VK_F4, VK_F5,
/* 40 - 47 */ VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, VK_NUMLOCK, VK_SCROLL, VK_HOME,
/* 48 - 4F */ VK_UP, VK_PRIOR, VK_SUBTRACT, VK_LEFT, VK_CLEAR, VK_RIGHT, VK_ADD, VK_END,
/* 50 - 57 */ VK_DOWN, VK_NEXT, VK_INSERT, VK_DELETE, VK_EXECUTE, 0, 0, VK_F11,
/* 58 - 5F */ VK_F12, 0, 0, 91, 92, 93, 0, 0,
/* 60 - 67 */ 0, 0, 0, 0, 0, 0, 0, 0,
/* 68 - 6F */ 0, 0, 0, 0, 0, 0, 0, 0,
/* 70 - 77 */ 0, 0, 0, 0, 0, 0, 0, 0,
/* 78 - 7F */ 0, 0, 0, 0, 0, 0, 0, VK_PAUSE
};
static const WORD vkKeypadTable[13]= /* 47 - 53 */
{
VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, VK_SUBTRACT,
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_ADD,
VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD0, VK_DECIMAL
};
/*
* ASCII translation tables
*/
static const BYTE asciiTable1[10]=
{
')','!','@','#','$','%','^','&','*','('
};
static const BYTE asciiTable2[16]=
{
'0','1','2','3','4','5','6','7','8','9','*','+',0,'-','.','/'
};
static const BYTE asciiTable3[37]=
{
';','=',',','-','.','/','`', 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'[', '\\', ']', '\''
};
static const BYTE asciiTable4[37]=
{
':','+','<','_','>','?','~', 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'{', '|', '}', '"'
};
/*
* Write data to keyboard
*/
static void KbdWrite(int addr,BYTE data)
{
BYTE status;
do
{
status=inb_p(KBD_CTRL_PORT); // Wait until input buffer empty
} while(status & KBD_IBF);
outb_p(addr,data);
}
/*
* Read data from port 0x60
*/
static int KbdReadData(void)
{
int i;
BYTE status,data;
i=500000;
do
{
status=inb_p(KBD_CTRL_PORT);
if (!(status & KBD_OBF)) // Check if data available
continue;
data=inb_p(KBD_DATA_PORT);
if (status & (KBD_GTO | KBD_PERR)) // Check for timeout error
continue;
return data;
} while(--i);
return -1; // Timed out
}
/*
* Set keyboard LED's
*/
static void SetKeyboardLEDs(BYTE status)
{
KbdWrite(KBD_DATA_PORT,0xED);
if (KbdReadData()!=KBD_ACK) // Error
return;
KbdWrite(KBD_DATA_PORT,status);
KbdReadData();
}
/*
* Process scan code
*/
static void ProcessScanCode(BYTE scanCode,BOOL isDown)
{
switch(scanCode)
{
case 0x1D: // Ctrl
if (extKey)
{
if (isDown)
ctrlKeyState|=RIGHT_CTRL_PRESSED;
else
ctrlKeyState&=~RIGHT_CTRL_PRESSED;
}
else
{
if (isDown)
ctrlKeyState|=LEFT_CTRL_PRESSED;
else
ctrlKeyState&=~LEFT_CTRL_PRESSED;
}
break;
case 0x2A: // Left shift
case 0x36: // Right shift
if (isDown)
ctrlKeyState|=SHIFT_PRESSED;
else
ctrlKeyState&=~SHIFT_PRESSED;
break;
case 0x38: // Alt
if (extKey)
{
if (isDown)
ctrlKeyState|=RIGHT_ALT_PRESSED;
else
ctrlKeyState&=~RIGHT_ALT_PRESSED;
}
else
{
if (isDown)
ctrlKeyState|=LEFT_ALT_PRESSED;
else
ctrlKeyState&=~LEFT_ALT_PRESSED;
}
break;
case 0x3A: // CapsLock
if (ctrlKeyState & CTRL_PRESSED)
break;
if (isDown)
{
if (!capsDown)
{
capsDown=1;
if (ctrlKeyState & CAPSLOCK_ON)
{
ledStatus&=~KBD_LED_CAPS;
ctrlKeyState&=~CAPSLOCK_ON;
}
else
{
ledStatus|=KBD_LED_CAPS;
ctrlKeyState|=CAPSLOCK_ON;
}
SetKeyboardLEDs(ledStatus);
}
}
else
{
capsDown=0;
}
break;
case 0x45: // NumLock
if (ctrlKeyState & CTRL_PRESSED)
break;
if (isDown)
{
if (!numDown)
{
numDown=1;
if (ctrlKeyState & NUMLOCK_ON)
{
ledStatus&=~KBD_LED_NUM;
ctrlKeyState&=~NUMLOCK_ON;
}
else
{
ledStatus|=KBD_LED_NUM;
ctrlKeyState|=NUMLOCK_ON;
}
SetKeyboardLEDs(ledStatus);
}
}
else
{
numDown=0;
}
break;
case 0x46: // ScrollLock
if (ctrlKeyState & CTRL_PRESSED)
break;
if (isDown)
{
if (!scrollDown)
{
scrollDown=1;
if (ctrlKeyState & SCROLLLOCK_ON)
{
ledStatus&=~KBD_LED_SCROLL;
ctrlKeyState&=~SCROLLLOCK_ON;
}
else
{
ledStatus|=KBD_LED_SCROLL;
ctrlKeyState|=SCROLLLOCK_ON;
}
SetKeyboardLEDs(ledStatus);
}
}
else
{
scrollDown=0;
}
break;
default:
break;
}
}
/*
* Translate virtual key code to ASCII
*/
static BYTE VirtualToAscii(WORD keyCode,BOOL isDown)
{
if ((ctrlKeyState & ALT_PRESSED)&&(ctrlKeyState & CTRL_PRESSED))
return 0; // Ctrl+Alt+char always 0
if ((!isDown)&&(ctrlKeyState & ALT_PRESSED))
return 0; // Alt+char is 0 when key is released
if (ctrlKeyState & CTRL_PRESSED)
{
if ((keyCode>=VK_A)&&(keyCode<=VK_Z))
return keyCode-VK_A+1;
switch(keyCode)
{
case VK_SPACE:
return ' ';
case VK_BACK:
return 127;
case VK_RETURN:
return 10;
case 219: /* [ */
if (ctrlKeyState & SHIFT_PRESSED)
return 0;
return 27;
case 220: /* \ */
if (ctrlKeyState & SHIFT_PRESSED)
return 0;
return 28;
case 221: /* ] */
if (ctrlKeyState & SHIFT_PRESSED)
return 0;
return 29;
default:
return 0;
}
}
if ((keyCode>=VK_A)&&(keyCode<=VK_Z))
if (ctrlKeyState & CAPSLOCK_ON)
if (ctrlKeyState & SHIFT_PRESSED)
return keyCode-VK_A+'a';
else
return keyCode-VK_A+'A';
else
if (ctrlKeyState & SHIFT_PRESSED)
return keyCode-VK_A+'A';
else
return keyCode-VK_A+'a';
if ((keyCode>=VK_0)&&(keyCode<=VK_9))
if (ctrlKeyState & SHIFT_PRESSED)
return asciiTable1[keyCode-VK_0];
else
return keyCode-VK_0+'0';
if ((keyCode>=VK_NUMPAD0)&&(keyCode<=VK_DIVIDE))
return asciiTable2[keyCode-VK_NUMPAD0];
if ((keyCode>=186)&&(keyCode<=222))
if (ctrlKeyState & SHIFT_PRESSED)
return asciiTable4[keyCode-186];
else
return asciiTable3[keyCode-186];
switch(keyCode)
{
case VK_SPACE:
return ' ';
case VK_RETURN:
return '\n';
case VK_BACK:
return 8;
case VK_TAB:
return 9;
}
return 0;
}
/*
* Translate scan code to virtual key code
*/
static WORD ScanToVirtual(BYTE scanCode)
{
if ((scanCode>=0x47)&&(scanCode<=0x53)&&(ctrlKeyState & NUMLOCK_ON)&&
(!extKey)&&(!(ctrlKeyState & SHIFT_PRESSED)))
return vkKeypadTable[scanCode-0x47];
if ((scanCode==0x35)&&(extKey)) // Gray divide
return VK_DIVIDE;
if ((scanCode==0x37)&&(extKey)) // Print screen
return VK_PRINT;
return vkTable[scanCode];
}
/*
* Keyboard IRQ handler
*/
static VOID KbdDpcRoutine(PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2)
{
PIRP Irp = (PIRP)SystemArgument2;
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)SystemArgument1;
CHECKPOINT;
DPRINT("KbdDpcRoutine(DeviceObject %x, Irp %x)\n",
DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
IoStartNextPacket(DeviceObject,FALSE);
}
static unsigned int KeyboardHandler(unsigned int irq)
{
BYTE resp,thisKey;
BOOL isDown;
static BYTE lastKey;
CHECKPOINT;
// Read scan code
thisKey=inb_p(KBD_DATA_PORT);
if ((thisKey==0xE0)||(thisKey==0xE1)) // Extended key
{
extKey=1; // Wait for next byte
lastKey=thisKey;
return 0;
}
isDown=!(thisKey & 0x80);
thisKey&=0x7F;
// The keyboard maintains its own internal caps lock and num lock
// statuses. In caps lock mode E0 AA precedes make code and
// E0 2A follow break code. In num lock mode, E0 2A precedes
// make code and E0 AA follow break code. We maintain our own caps lock
// and num lock statuses, so we will just ignore these.
// Some keyboards have L-Shift/R-Shift modes instead of caps lock
// mode. If right shift pressed, E0 B6 / E0 36 pairs generated.
if (extKey & ((thisKey==0x2A)||(thisKey==0x36)))
{
extKey=0;
return 0;
}
// Check for PAUSE sequence
if (extKey && (lastKey==0xE1))
{
if (thisKey==0x1D)
lastKey=0xFF; // Sequence is OK
else
extKey=0;
return 0;
}
if (extKey && (lastKey==0xFF))
{
if (thisKey!=0x45)
{
extKey=0; // Bad sequence
return 0;
}
thisKey=0x7F; // Pseudo-code for PAUSE
}
ProcessScanCode(thisKey,isDown);
// DbgPrint("Key: %c\n",VirtualToAscii(ScanToVirtual(thisKey),isDown));
// DbgPrint("Key: %x\n",ScanToVirtual(thisKey));
if (ScanToVirtual(thisKey)==0x2a)
{
KeBugCheck(0);
}
if (CurrentIrp!=NULL)
{
KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)
CurrentIrp->AssociatedIrp.SystemBuffer;
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(CurrentIrp);
CHECKPOINT;
rec[KeysRead].bKeyDown=isDown;
rec[KeysRead].wRepeatCount=1;
rec[KeysRead].wVirtualKeyCode=ScanToVirtual(thisKey);
rec[KeysRead].wVirtualScanCode=thisKey;
rec[KeysRead].AsciiChar=VirtualToAscii(rec->wVirtualKeyCode,isDown);
rec[KeysRead].dwControlKeyState=ctrlKeyState;
if (extKey)
{
rec[KeysRead].dwControlKeyState|=ENHANCED_KEY;
}
KeysRead++;
DPRINT("KeysRequired %d KeysRead %x\n",KeysRequired,KeysRead);
if (KeysRead==KeysRequired)
{
KeInsertQueueDpc(&KbdDpc,stk->DeviceObject,CurrentIrp);
CurrentIrp=NULL;
}
CHECKPOINT;
return(TRUE);
}
// Buffer is full ?
if (keysInBuffer==KBD_BUFFER_SIZE) // Buffer is full
{
extKey=0;
return 0;
}
kbdBuffer[bufHead].bKeyDown=isDown;
kbdBuffer[bufHead].wRepeatCount=1;
kbdBuffer[bufHead].wVirtualKeyCode=ScanToVirtual(thisKey);
kbdBuffer[bufHead].wVirtualScanCode=thisKey;
// kbdBuffer[bufHead].uChar.AsciiChar=TranslateScanCode(thisKey);
kbdBuffer[bufHead].AsciiChar=VirtualToAscii(kbdBuffer[bufHead].wVirtualKeyCode,isDown);
kbdBuffer[bufHead].dwControlKeyState=ctrlKeyState;
if (extKey)
kbdBuffer[bufHead].dwControlKeyState|=ENHANCED_KEY;
bufHead++;
bufHead&=KBD_WRAP_MASK; // Modulo KBD_BUFFER_SIZE
keysInBuffer++;
extKey=0;
}
//
// Initialize keyboard
//
static void KeyboardConnectInterrupt(void)
{
ULONG MappedIrq;
KIRQL Dirql;
KAFFINITY Affinity;
NTSTATUS Status;
MappedIrq = HalGetInterruptVector(Internal,
0,
0,
KEYBOARD_IRQ,
&Dirql,
&Affinity);
Status = IoConnectInterrupt(&KbdInterrupt,
KeyboardHandler,
NULL,
NULL,
MappedIrq,
Dirql,
Dirql,
0,
FALSE,
Affinity,
FALSE);
}
static int InitializeKeyboard(void)
{
// Initialize variables
bufHead=0;
bufTail=0;
keysInBuffer=0;
ledStatus=0;
capsDown=0;
numDown=0;
scrollDown=0;
ctrlKeyState=0;
extKey=0;
KeyboardConnectInterrupt();
KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL);
return 0;
}
/*
* Read data from keyboard buffer
*/
static void dummy(void)
{
}
BOOLEAN KbdSynchronizeRoutine(PVOID Context)
{
PIRP Irp = (PIRP)Context;
KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)
Irp->AssociatedIrp.SystemBuffer;
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
ULONG NrToRead = stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD);
int i;
DPRINT("NrToRead %d keysInBuffer %d\n",NrToRead,keysInBuffer);
NrToRead = min(NrToRead,keysInBuffer);
DPRINT("NrToRead %d stk->Parameters.Read.Length %d\n",
NrToRead,stk->Parameters.Read.Length);
DPRINT("sizeof(KEY_EVENT_RECORD) %d\n",sizeof(KEY_EVENT_RECORD));
for (i=0;i<NrToRead;i++)
{
memcpy(&rec[i],&kbdBuffer[bufTail],sizeof(KEY_EVENT_RECORD));
bufTail++;
bufTail&=KBD_WRAP_MASK;
keysInBuffer--;
}
if ((stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD))==NrToRead)
{
return(TRUE);
}
KeysRequired=stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD);
KeysRead=NrToRead;
CurrentIrp=Irp;
return(FALSE);
}
VOID KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
DPRINT("KeyboardStartIo(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
DPRINT("stk->Parameters.Read.Length %d\n",stk->Parameters.Read.Length);
DPRINT("KeysRequired %d\n",KeysRequired);
}
NTSTATUS KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS Status;
DPRINT("DeviceObject %x\n",DeviceObject);
DPRINT("Irp %x\n",Irp);
switch (stk->MajorFunction)
{
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
Status = STATUS_SUCCESS;
break;
case IRP_MJ_READ:
DPRINT("Handling Read request\n");
if (KeSynchronizeExecution(KbdInterrupt,KbdSynchronizeRoutine,Irp))
{
Status = STATUS_SUCCESS;
}
else
{
DPRINT("Queueing packet\n");
IoStartPacket(DeviceObject,Irp,NULL,NULL);
Status = STATUS_PENDING;
}
break;
default:
Status = STATUS_NOT_IMPLEMENTED;
break;
}
if (Status==STATUS_PENDING)
{
DPRINT("Marking irp pending\n");
IoMarkIrpPending(Irp);
}
else
{
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
}
DPRINT("Status %d\n",Status);
return(Status);
}
/*
* Module entry point
*/
STDCALL NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
ANSI_STRING adevice_name;
UNICODE_STRING device_name;
ANSI_STRING asymlink_name;
UNICODE_STRING symlink_name;
DbgPrint("Keyboard Driver 0.0.4\n");
InitializeKeyboard();
DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = KbdDispatch;
DriverObject->DriverStartIo = KbdStartIo;
RtlInitAnsiString(&adevice_name,"\\Device\\Keyboard");
RtlAnsiStringToUnicodeString(&device_name,&adevice_name,TRUE);
IoCreateDevice(DriverObject,0,&device_name,FILE_DEVICE_KEYBOARD,0,
TRUE,&DeviceObject);
DeviceObject->Flags = DO_BUFFERED_IO;
RtlInitAnsiString(&asymlink_name,"\\??\\Keyboard");
RtlAnsiStringToUnicodeString(&symlink_name,&asymlink_name,TRUE);
IoCreateSymbolicLink(&symlink_name,&device_name);
return(STATUS_SUCCESS);
}

View File

@@ -1,67 +0,0 @@
/*
* Some defines
*/
#define KEYBOARD_IRQ 1
#define KBD_BUFFER_SIZE 32
#define KBD_WRAP_MASK 0x1F
#define disable() __asm__("cli\n\t")
#define enable() __asm__("sti\n\t")
#define ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
/*
* Keyboard controller ports
*/
#define KBD_DATA_PORT 0x60
#define KBD_CTRL_PORT 0x64
/*
* Controller commands
*/
#define KBD_READ_MODE 0x20
#define KBD_WRITE_MODE 0x60
#define KBD_SELF_TEST 0xAA
#define KBD_LINE_TEST 0xAB
#define KBD_CTRL_ENABLE 0xAE
/*
* Keyboard commands
*/
#define KBD_ENABLE 0xF4
#define KBD_DISABLE 0xF5
#define KBD_RESET 0xFF
/*
* Keyboard responces
*/
#define KBD_ACK 0xFA
#define KBD_BATCC 0xAA
/*
* Controller status register bits
*/
#define KBD_OBF 0x01
#define KBD_IBF 0x02
#define KBD_GTO 0x40
#define KBD_PERR 0x80
/*
* LED bits
*/
#define KBD_LED_SCROLL 0x01
#define KBD_LED_NUM 0x02
#define KBD_LED_CAPS 0x04

View File

@@ -1,15 +0,0 @@
all: keyboard.sys
OBJECTS = keyboard.o ../../../ntoskrnl/ntoskrnl.a
keyboard.sys: $(OBJECTS)
$(CC) -specs=../../svc_specs -mdll -o junk.tmp -Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ -Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp $(OBJECTS)
- $(RM) junk.tmp
$(DLLTOOL) --dllname keyboard.sys --base-file base.tmp \
--output-exp temp.exp
- $(RM) base.tmp
$(CC) --verbose -Wl,--image-base,0x10000 -Wl,-e,_DriverEntry@8 \
-specs=../../svc_specs -mdll -o keyboard.sys $(OBJECTS) -Wl,temp.exp
- $(RM) temp.exp

View File

@@ -1 +0,0 @@
all: mouse.o

View File

@@ -1,268 +0,0 @@
/*
** Mouse driver 0.0.3
** Written by Jason Filby (jasonfilby@yahoo.com)
** For ReactOS (www.sid-dis.com/reactos)
** Note: The serial.o driver must be loaded before loading this driver
** Known Limitations:
** Only supports mice on COM port 1
*/
#include <internal/mmhal.h>
#include <internal/halio.h>
/* #include <internal/hal/ddk.h> */
#include <funcs.h>
#define MOUSE_IRQ_COM1 4
#define MOUSE_IRQ_COM2 3
#define COM1_PORT 0x3f8
#define COM2_PORT 0x2f8
#define max_screen_x 79
#define max_screen_y 24
static unsigned int MOUSE_IRQ=MOUSE_IRQ_COM1;
static unsigned int MOUSE_COM=COM1_PORT;
static unsigned int bytepos=0, coordinate;
static unsigned char mpacket[3];
static signed int mouse_x=40, mouse_y=12;
static unsigned char mouse_button1, mouse_button2;
static signed int horiz_sensitivity, vert_sensitivity;
BOOLEAN microsoft_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext)
{
unsigned int mbyte=inb(MOUSE_COM);
// Synchronize
if((mbyte&64)==64) { bytepos=0; };
mpacket[bytepos]=mbyte;
bytepos++;
// Process packet
if(bytepos==3) {
// Retrieve change in x and y from packet
int change_x=((mpacket[0] & 3) << 6) + mpacket[1];
int change_y=((mpacket[0] & 12) << 4) + mpacket[2];
// Some mice need this
if(coordinate==1) {
change_x-=128;
change_y-=128;
};
// Change to signed
if(change_x>=128) { change_x=change_x-256; };
if(change_y>=128) { change_y=change_y-256; };
// Adjust mouse position according to sensitivity
mouse_x+=change_x/horiz_sensitivity;
mouse_y+=change_y/vert_sensitivity;
// Check that mouse is still in screen
if(mouse_x<0) { mouse_x=0; };
if(mouse_x>max_screen_x) { mouse_x=max_screen_x; };
if(mouse_y<0) { mouse_y=0; };
if(mouse_y>max_screen_y) { mouse_y=max_screen_y; };
// Retrieve mouse button status from packet
mouse_button1=mpacket[0] & 32;
mouse_button2=mpacket[0] & 16;
bytepos=0;
};
};
void InitializeMouseHardware(unsigned int mtype)
{
char clear_error_bits;
outb_p(MOUSE_COM+3, 0x80); // set DLAB on
outb_p(MOUSE_COM, 0x60); // speed LO byte
outb_p(MOUSE_COM+1, 0); // speed HI byte
outb_p(MOUSE_COM+3, mtype); // 2=MS Mouse; 3=Mouse systems mouse
outb_p(MOUSE_COM+1, 0); // set comm and DLAB to 0
outb_p(MOUSE_COM+4, 1); // DR int enable
clear_error_bits=inb_p(MOUSE_COM+5); // clear error bits
};
int DetMicrosoft(void)
{
char tmp, ind;
int buttons=0, i;
outb_p(MOUSE_COM+4, 0x0b);
tmp=inb_p(MOUSE_COM);
// Check the first for bytes for signs that this is an MS mouse
for(i=0; i<4; i++) {
while((inb_p(MOUSE_COM+5) & 1)==0) ;
ind=inb_p(MOUSE_COM);
if(ind==0x33) buttons=3;
if(ind==0x4d) buttons=2;
};
return buttons;
};
int CheckMouseType(unsigned int mtype)
{
unsigned int retval=0;
InitializeMouseHardware(mtype);
if(mtype==2) retval=DetMicrosoft();
if(mtype==3) {
outb_p(MOUSE_COM+4, 11);
retval=3;
};
outb_p(MOUSE_COM+1, 1);
return retval;
};
void ClearMouse(void)
{
// Waits until the mouse calms down but also quits out after a while
// in case some destructive user wants to keep moving the mouse
// before we're done
unsigned int restarts=0, i;
for (i=0; i<60000; i++)
{
unsigned temp=inb(MOUSE_COM);
if(temp!=0) {
restarts++;
if(restarts<300000) {
i=0;
} else
{
i=60000;
};
};
};
};
void InitializeMouse(void)
{
int mbuttons=0, gotmouse=0;
ULONG MappedIrq;
KIRQL Dirql;
KAFFINITY Affinity;
PKINTERRUPT IrqObject;
horiz_sensitivity=2;
vert_sensitivity=3;
// Check for Microsoft mouse (2 buttons)
if(CheckMouseType(2)!=0)
{
gotmouse=1;
DbgPrint("Microsoft Mouse Detected\n");
ClearMouse();
coordinate=0;
};
// Check for Microsoft Systems mouse (3 buttons)
if(gotmouse==0) {
if(CheckMouseType(3)!=0)
{
gotmouse=1;
DbgPrint("Microsoft Mouse Detected\n");
ClearMouse();
coordinate=1;
};
};
if(gotmouse==0) {
DbgPrint("No Mouse Detected!\n");
} else {
MappedIrq = HalGetInterruptVector(Internal, 0, 0, MOUSE_IRQ,
&Dirql, &Affinity);
IoConnectInterrupt(&IrqObject, microsoft_mouse_handler, NULL,
NULL, MappedIrq, Dirql, Dirql, 0, FALSE,
Affinity, FALSE);
};
};
// For test purposes only
unsigned char get_text_char(int x, int y)
{
unsigned char getchar;
char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2)));
getchar=*vidmem;
return getchar;
};
// For test purposes only
unsigned char get_text_color(int x, int y)
{
unsigned char getcolor;
char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2)));
vidmem++;
getcolor=*vidmem;
return getcolor;
};
// For test purposes only
void put_text_char(int x, int y, unsigned char putchar[2])
{
char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2)));
*vidmem=putchar[0];
vidmem++;
*vidmem=putchar[1];
};
// For test purposes only
void test_mouse(void)
{
static int i=0, forcechange=0;
static int old_x=40, old_y=12;
static unsigned char old_cursor[2], new_cursor[2];
DbgPrint("Testing mouse...");
old_cursor[0]=' ';
old_cursor[1]=7;
new_cursor[0]='<EFBFBD>';
new_cursor[1]=15;
old_cursor[0]=get_text_char(mouse_x, mouse_y);
old_cursor[1]=get_text_color(mouse_x, mouse_y);
put_text_char(mouse_x, mouse_y, new_cursor);
while(i!=1)
{
if(mouse_button1!=0) { new_cursor[1]=10; mouse_button1=0; forcechange=1; };
if(mouse_button2!=0) { new_cursor[1]=12; mouse_button2=0; forcechange=1; };
if((mouse_x!=old_x) || (mouse_y!=old_y) || (forcechange==1)) {
forcechange=0;
put_text_char(old_x, old_y, old_cursor);
old_cursor[0]=get_text_char(mouse_x, mouse_y);
old_cursor[1]=get_text_color(mouse_x, mouse_y);
put_text_char(mouse_x, mouse_y, new_cursor);
old_x=mouse_x;
old_y=mouse_y;
};
};
};
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
DbgPrint("Mouse Driver 0.0.3\n");
InitializeMouse();
test_mouse();
return(STATUS_SUCCESS);
};

View File

@@ -1 +0,0 @@
all: null.o

View File

@@ -1,104 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/null/null.c
* PURPOSE: NULL device driver
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* 13/08/98: Created
*/
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
/* FUNCTIONS **************************************************************/
NTSTATUS NullWrite(PIRP Irp, PIO_STACK_LOCATION stk)
{
Irp->IoStatus.Information = stk->Parameters.Write.Length;
return(STATUS_SUCCESS);
}
NTSTATUS NullRead(PIRP Irp, PIO_STACK_LOCATION stk)
{
Irp->IoStatus.Information = 0;
return(STATUS_END_OF_FILE);
}
NTSTATUS NullDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status;
switch (Stack->MajorFunction)
{
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
status = STATUS_SUCCESS;
break;
case IRP_MJ_WRITE:
status = NullWrite(Irp,Stack);
break;
case IRP_MJ_READ:
status = NullRead(Irp,Stack);
break;
default:
status = STATUS_NOT_IMPLEMENTED;
}
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(status);
}
NTSTATUS NullUnload(PDRIVER_OBJECT DriverObject)
{
return(STATUS_SUCCESS);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS ret;
ANSI_STRING ansi_device_name;
UNICODE_STRING device_name;
DbgPrint("Null Device Driver 0.0.1\n");
RtlInitAnsiString(&ansi_device_name,"\\Device\\NUL");
RtlAnsiStringToUnicodeString(&device_name,&ansi_device_name,TRUE);
ret = IoCreateDevice(DriverObject,0,&device_name,
FILE_DEVICE_NULL,0,FALSE,&DeviceObject);
if (ret!=STATUS_SUCCESS)
{
return(ret);
}
DeviceObject->Flags=0;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NullDispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = NullDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = NullDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = NullDispatch;
DriverObject->DriverUnload = NullUnload;
return(STATUS_SUCCESS);
}

View File

@@ -1 +0,0 @@
all: parallel.o

View File

@@ -1,144 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/parallel/parallel.c
* PURPOSE: Parallel port driver
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* ??/??/??: Created
* 18/06/98: Made more NT like
*/
/* FUNCTIONS **************************************************************/
#include <ddk/ntddk.h>
#include "parallel.h"
#define LP_B (0x378)
#define LP_S (inb_p(LP_B+1))
#define LP_C (LP_B+2)
static void Parallel_Reset(void)
/*
* FUNCTION: Resets the device attached to the parallel port
*/
{
int i;
outb_p(LP_C,0);
for (i=0;i<LP_DELAY;i++);
outb_p(LP_C,LP_PSELECP | LP_PINITP);
}
static void Parallel_putchar(unsigned char ch)
/*
* FUNCTION: Writes a character to the parallel port
* ARGUMENTS:
* ch = character to write
*/
{
int count=0;
int status;
int wait=0;
do
{
status=LP_S;
count++;
}
while ( count < 500000 && !(status & LP_PBUSY) );
if (count==500000)
{
printk("printer_putchar(): timed out\n");
return;
}
outb_p(LP_B,ch);
while (wait != 10000) { wait++; }
outb_p(LP_C, (LP_PSELECP | LP_PINITP | LP_PSTROBE ));
while (wait) { wait--; }
outb_p(LP_C, LP_PSELECP | LP_PINITP);
}
NTSTATUS Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status;
int i;
switch (Stack->MajorFunction)
{
case IRP_MJ_CREATE:
printk("(Parallel Port Driver) Creating\n");
Parallel_Reset();
status = STATUS_SUCCESS;
break;
case IRP_MJ_CLOSE:
status = STATUS_SUCCESS;
break;
case IRP_MJ_WRITE:
printk("(Parallel Port Driver) Writing %d bytes\n",
Stack->Parameters.Write.Length);
for (i=0;i<Stack->Parameters.Write.Length;i++)
{
Parallel_putchar(((char *)Irp->UserBuffer)[i]);
}
status = STATUS_SUCCESS;
break;
default:
status = STATUS_NOT_IMPLEMENTED;
break;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS ret;
printk("Parallel Port Driver 0.0.1\n");
ret = IoCreateDevice(DriverObject,0,"\\Device\\Parallel",
FILE_DEVICE_PARALLEL_PORT,0,FALSE,&DeviceObject);
if (ret!=STATUS_SUCCESS)
{
return(ret);
}
DeviceObject->Flags=0;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
DriverObject->DriverUnload = NULL;
return(STATUS_SUCCESS);
}

View File

@@ -1,137 +0,0 @@
#ifndef _LINUX_LP_H
#define _LINUX_LP_H
/*
* usr/include/linux/lp.h c.1991-1992 James Wiegand
* many modifications copyright (C) 1992 Michael K. Johnson
* Interrupt support added 1993 Nigel Gamble
*/
/*
* Per POSIX guidelines, this module reserves the LP and lp prefixes
* These are the lp_table[minor].flags flags...
*/
#define LP_EXIST 0x0001
#define LP_SELEC 0x0002
#define LP_BUSY 0x0004
#define LP_OFFL 0x0008
#define LP_NOPA 0x0010
#define LP_ERR 0x0020
#define LP_ABORT 0x0040
#define LP_CAREFUL 0x0080
#define LP_ABORTOPEN 0x0100
/* timeout for each character. This is relative to bus cycles -- it
* is the count in a busy loop. THIS IS THE VALUE TO CHANGE if you
* have extremely slow printing, or if the machine seems to slow down
* a lot when you print. If you have slow printing, increase this
* number and recompile, and if your system gets bogged down, decrease
* this number. This can be changed with the tunelp(8) command as well.
*/
#define LP_INIT_CHAR 1000
/* The parallel port specs apparently say that there needs to be
* a .5usec wait before and after the strobe. Since there are wildly
* different computers running linux, I can't come up with a perfect
* value, but since it worked well on most printers before without,
* I'll initialize it to 0.
*/
#define LP_INIT_WAIT 0
/* This is the amount of time that the driver waits for the printer to
* catch up when the printer's buffer appears to be filled. If you
* want to tune this and have a fast printer (i.e. HPIIIP), decrease
* this number, and if you have a slow printer, increase this number.
* This is in hundredths of a second, the default 2 being .05 second.
* Or use the tunelp(8) command, which is especially nice if you want
* change back and forth between character and graphics printing, which
* are wildly different...
*/
#define LP_INIT_TIME 2
/* IOCTL numbers */
#define LPCHAR 0x0601 /* corresponds to LP_INIT_CHAR */
#define LPTIME 0x0602 /* corresponds to LP_INIT_TIME */
#define LPABORT 0x0604 /* call with TRUE arg to abort on error,
FALSE to retry. Default is retry. */
#define LPSETIRQ 0x0605 /* call with new IRQ number,
or 0 for polling (no IRQ) */
#define LPGETIRQ 0x0606 /* get the current IRQ number */
#define LPWAIT 0x0608 /* corresponds to LP_INIT_WAIT */
#define LPCAREFUL 0x0609 /* call with TRUE arg to require out-of-paper, off-
line, and error indicators good on all writes,
FALSE to ignore them. Default is ignore. */
#define LPABORTOPEN 0x060a /* call with TRUE arg to abort open() on error,
FALSE to ignore error. Default is ignore. */
#define LPGETSTATUS 0x060b /* return LP_S(minor) */
#define LPRESET 0x060c /* reset printer */
/* timeout for printk'ing a timeout, in jiffies (100ths of a second).
This is also used for re-checking error conditions if LP_ABORT is
not set. This is the default behavior. */
#define LP_TIMEOUT_INTERRUPT (60 * HZ)
#define LP_TIMEOUT_POLLED (10 * HZ)
#if 0
#define LP_B(minor) lp_table[(minor)].base /* IO address */
#define LP_F(minor) lp_table[(minor)].flags /* flags for busy, etc. */
#define LP_S(minor) inb_p(LP_B((minor)) + 1) /* status port */
#define LP_C(minor) (lp_table[(minor)].base + 2) /* control port */
#define LP_CHAR(minor) lp_table[(minor)].chars /* busy timeout */
#define LP_TIME(minor) lp_table[(minor)].time /* wait time */
#define LP_WAIT(minor) lp_table[(minor)].wait /* strobe wait */
#define LP_IRQ(minor) lp_table[(minor)].irq /* interrupt # */
/* 0 means polled */
#endif
#define LP_BUFFER_SIZE 256
/*
* The following constants describe the various signals of the printer port
* hardware. Note that the hardware inverts some signals and that some
* signals are active low. An example is LP_STROBE, which must be programmed
* with 1 for being active and 0 for being inactive, because the strobe signal
* gets inverted, but it is also active low.
*/
/*
* bit defines for 8255 status port
* base + 1
* accessed with LP_S(minor), which gets the byte...
*/
#define LP_PBUSY 0x80 /* inverted input, active high */
#define LP_PACK 0x40 /* unchanged input, active low */
#define LP_POUTPA 0x20 /* unchanged input, active high */
#define LP_PSELECD 0x10 /* unchanged input, active high */
#define LP_PERRORP 0x08 /* unchanged input, active low */
/*
* defines for 8255 control port
* base + 2
* accessed with LP_C(minor)
*/
#define LP_PINTEN 0x10
#define LP_PSELECP 0x08 /* inverted output, active low */
#define LP_PINITP 0x04 /* unchanged output, active low */
#define LP_PAUTOLF 0x02 /* inverted output, active low */
#define LP_PSTROBE 0x01 /* inverted output, active low */
/*
* the value written to ports to test existence. PC-style ports will
* return the value written. AT-style ports will return 0. so why not
* make them the same ?
*/
#define LP_DUMMY 0x00
/*
* This is the port delay time. Your mileage may vary.
* It is used only in the lp_init() routine.
*/
#define LP_DELAY 150000
#endif

View File

@@ -1,4 +0,0 @@
all: sdisk.o
WIN32_LEAN_AND_MEAN = yes
include ../../../rules.mak

View File

@@ -1,162 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/sdisk/sdisk.c
* PURPOSE: Disk driver for Bochs
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
#include <internal/halio.h>
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS **************************************************************/
#define PORT (0x3ec)
static VOID SdWriteOffset(ULONG Offset)
{
outl_p(PORT,Offset);
}
NTSTATUS Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status;
int i;
PCH Buffer;
ULONG Length;
ULONG Information = 0;
switch (Stack->MajorFunction)
{
case IRP_MJ_CREATE:
DPRINT("Creating\n",0);
status = STATUS_SUCCESS;
break;
case IRP_MJ_CLOSE:
status = STATUS_SUCCESS;
break;
case IRP_MJ_WRITE:
DPRINT("Writing %d bytes\n",
Stack->Parameters.Write.Length);
Length = Stack->Parameters.Write.Length;
if ((Length%512)>0)
{
Length = Length - (Length%512);
}
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
DPRINT("Buffer %x\n",Buffer);
#if 0
for (i=0;i<Length;i++)
{
if ((i%512)==0)
{
DPRINT("Offset %x\n",
GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset)+i);
SdWriteOffset(GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset)+i);
}
outb_p(PORT,Buffer[i]);
DbgPrint("%c",Buffer[i]);
}
#endif
for (i=0;i<(Length/512);i++)
{
DPRINT("Offset %x\n",
GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset)+i);
SdWriteOffset(GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset)+i);
outsb(PORT,Buffer,512);
}
status = STATUS_SUCCESS;
Information = Length;
break;
case IRP_MJ_READ:
DPRINT("Reading %d bytes\n",
Stack->Parameters.Write.Length);
Length = Stack->Parameters.Write.Length;
if ((Length%512)>0)
{
Length = Length - (Length%512);
}
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
for (i=0;i<Length;i++)
{
if ((i%512)==0)
{
DPRINT("Offset %d\n",
GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset)+i);
SdWriteOffset(GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset)+i);
}
Buffer[i]=inb_p(PORT);
}
status = STATUS_SUCCESS;
break;
default:
status = STATUS_NOT_IMPLEMENTED;
break;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = Information;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS ret;
ANSI_STRING astr;
UNICODE_STRING ustr;
ANSI_STRING asymlink;
UNICODE_STRING usymlink;
DbgPrint("Simple Disk Driver 0.0.1\n");
RtlInitAnsiString(&astr,"\\Device\\SDisk");
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
ret = IoCreateDevice(DriverObject,0,&ustr,
FILE_DEVICE_DISK,0,FALSE,&DeviceObject);
if (ret!=STATUS_SUCCESS)
{
return(ret);
}
RtlInitAnsiString(&asymlink,"\\??\\C:");
RtlAnsiStringToUnicodeString(&usymlink,&asymlink,TRUE);
IoCreateSymbolicLink(&usymlink,&ustr);
DeviceObject->Flags=DO_DIRECT_IO;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = Dispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
DriverObject->DriverUnload = NULL;
return(STATUS_SUCCESS);
}

View File

@@ -1 +0,0 @@
all: serial.o

View File

@@ -1,150 +0,0 @@
/*
** Serial driver
** Written by Jason Filby (jasonfilby@yahoo.com)
** For ReactOS (www.sid-dis.com/reactos)
*/
#include <internal/mmhal.h>
#include <internal/halio.h>
#define COM1 0x3F8
#define COM2 0x2F8
#define COM3 0x3E8
#define COM4 0x2E8
#define UART_BAUDRATE 96 // 1200 BPS
#define UART_LCRVAL 0x1b // 0x1b for 8e1
#define UARY_FCRVAL 0x7
int uart_detect(unsigned base)
{
// Returns 0 if no UART detected
int olddata=inb_p(base+4);
outb_p(base+4, 0x10);
if ((inb_p(base+6) & 0xf0)) return 0;
return 1;
};
int irq_setup(unsigned base)
{
// Returns -1 if not found -- otherwise returns interrupt level
char ier, mcr, imrm, imrs, maskm, masks, irqm, irqs;
__asm("cli"); // disable all CPU interrupts
ier = inb_p(base+1); // read IER
outb_p(base+1,0); // disable all UART ints
while (!(inb_p(base+5)&0x20)); // wait for the THR to be empty
mcr = inb_p(base+4); // read MCR
outb_p(base+4,0x0F); // connect UART to irq line
imrm = inb_p(0x21); // read contents of master ICU mask register
imrs = inb_p(0xA1); // read contents of slave ICU mask register
outb_p(0xA0,0x0A); // next read access to 0xA0 reads out IRR
outb_p(0x20,0x0A); // next read access to 0x20 reads out IRR
outb_p(base+1,2); // let's generate interrupts...
maskm = inb_p(0x20); // this clears all bits except for the one
masks = inb_p(0xA0); // that corresponds to the int
outb_p(base+1,0); // drop the int line
maskm &= ~inb_p(0x20); // this clears all bits except for the one
masks &= ~inb_p(0xA0); // that corresponds to the int
outb_p(base+1,2); // and raise it again just to be sure...
maskm &= inb_p(0x20); // this clears all bits except for the one
masks &= inb_p(0xA0); // that corresponds to the int
outb_p(0xA1,~masks); // now let us unmask this interrupt only
outb_p(0x21,~maskm);
outb_p(0xA0,0x0C); // enter polled mode
outb_p(0x20,0x0C); // that order is important with Pentium/PCI systems
irqs = inb_p(0xA0); // and accept the interrupt
irqm = inb_p(0x20);
inb_p(base+2); // reset transmitter interrupt in UART
outb_p(base+4,mcr); // restore old value of MCR
outb_p(base+1,ier); // restore old value of IER
if (masks) outb_p(0xA0,0x20); // send an EOI to slave
if (maskm) outb_p(0x20,0x20); // send an EOI to master
outb_p(0x21,imrm); // restore old mask register contents
outb_p(0xA1,imrs);
__asm("sti");
if (irqs&0x80) // slave interrupt occured
return (irqs&0x07)+8;
if (irqm&0x80) // master interrupt occured
return irqm&0x07;
return -1;
};
void uart_init(unsigned uart_base)
{
// Initialize the UART
outb_p(uart_base+3, 0x80);
outw_p(uart_base, UART_BAUDRATE);
outb_p(uart_base+3, UART_LCRVAL);
outb_p(uart_base+4, 0);
};
unsigned uart_getchar(unsigned uart_base)
{
unsigned x;
x=(inb_p(uart_base+5) & 0x9f) << 8;
if(x & 0x100) x|=((unsigned)inb_p(uart_base)) & 0xff;
return x;
};
void InitializeSerial(void)
{
unsigned comports[4] = { COM1, COM2, COM3, COM4 };
char *comname[4] = { "COM1", "COM2", "COM3", "COM4" };
int i, irq_level;
for (i=0; i<4; i++)
{
if(uart_detect(comports[i])==0)
{
printk("%s not detected\n", comname[i]);
} else {
uart_init(comports[i]);
irq_level=irq_setup(comports[i]);
if(irq_level==-1)
{
printk("Warning: IRQ not detected!\n");
} else {
printk("%s hooked to interrupt level %d\n", comname[i], irq_level);
};
};
};
};
// For testing purposes
void testserial()
{
int i=0;
char testc;
union {
unsigned val;
char character;
} x;
printk("Testing serial input...\n");
while(i==0) {
x.val=uart_getchar(COM1);
// if(!x.val) continue;
// if(x.val & 0x100)
testc=inb_p(COM1);
// printk("(%x-%c) %c\n", x.val, x.character, testc);
};
};
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
printk("Serial Driver 0.0.2\n");
InitializeSerial();
// testserial();
return(STATUS_SUCCESS);
};

View File

@@ -1,61 +0,0 @@
/************************************
* unsigned char read_dsp(void)
*
* Reads the DSP chip
* Arguments: none
* Returns: Byte read
************************************/
unsigned char read_dsp(unsigned short base)
{
while((inb(base+0x0e)&0x80)==0); //Wait until there is something to read
return inb(base+0x0a);
}
/************************************'
* sb_status detect_dsp(void);
*
* Detects if a SB16 is installed
* Arguments: None
* Returns: Success or failure
************************************/
sb_status detect_dsp(SB16* sb16)
{
for(base=0x200;base<0x280;base+=0x10) //Tries to reset all DSP addresses there is
if(reset_dsp(base)==SB_TRUE)
{
sb16->base=base;
return SB_TRUE;
}
return SB_FALSE;
}
/**************************************
* sb_status reset_dsp(unsigned short base_address);
*
* Tries to reset a DSP chip
* Arguments: base address
* Returns: Success of failure
**************************************/
sb_status reset_dsp(unsigned short base_address)
{
int delay;
outb(base_address+DSP_RESET_PORT,1);
for(delay=0;delay<0xffff;delay++);
outb(base_address+DSP_RESET_PORT,0);
for(delay=0;delay<0xffff;delay++);
if((inb(base_address+DSP_READ_STATUS_PORT)&0x80)==0) return SB_FALSE;
if(inb(base_address+DSP_READ_DATA_PORT)!=0xAA) return SB_FALSE;
return SB_TRUE;
}
void write_dsp(unsigned short base,unsigned char data)
{
while ((inb(base+DSP_WRITE_PORT) & 0x80) != 0);
outb(base+DSP_WRITE_PORT, data);
}

View File

@@ -1,17 +0,0 @@
#define SB_TRUE 0
#define SB_FALSE 1
#define DSP_MIXER_ADDRESS_PORT 0x04
#define DSP_MIXER_DATA_PORT 0x05
#define DSP_RESET_PORT 0x06
#define DSP_READ_DATA_PORT 0x0A
#define DSP_WRITE_PORT 0x0C //Same port used for reading status and writing data
#define DSP_READ_STATUS_PORT 0x0E
typedef unsigned char sb_status;
unsigned short base;
unsigned char irq,dma8,dma16;
unsigned char read_dsp(unsigned short base);
void write_dsp(unsigned short base,unsigned char data);
sb_status detect_dsp(SB16* sb16);
sb_status reset_dsp(unsigned short base_address);

View File

@@ -1,2 +0,0 @@
sound.o: sound.c dsp.c mixer.c wave.h wave.c
all: sound.o

View File

@@ -1,32 +0,0 @@
unsigned char read_mixer(unsigned short base,unsigned char reg)
{
outb(base+0x04,reg);
return inb(base+0x05);
}
unsigned char get_irq(SB16* sb16)
{
unsigned char irq;
irq=(read_mixer(sb16->base,MIXER_INTERRUPT_SETUP_REGISTER)&0x0f);
if(irq==1) sb16->irq=2;
if(irq==2) sb16->irq=5;
if(irq==4) sb16->irq=7;
if(irq==8) sb16->irq=10;
return 0;
}
void get_dma(SB16* sb16)
{
unsigned char hi,lo,result=read_mixer(sb16->base,MIXER_DMA_SETUP_REGISTER);
hi=result&0xE0;
lo=result&0x0B;
if(hi==0x80) sb16->dma16=7;
if(hi==0x40) sb16->dma16=6;
if(hi==0x20) sb16->dma16=5;
if(lo==0x08) sb16->dma8=3;
if(lo==0x02) sb16->dma8=1;
if(lo==0x01) sb16->dma8=0;
}

View File

@@ -1,8 +0,0 @@
#define MIXER_INTERRUPT_SETUP_REGISTER 0x80
#define MIXER_DMA_SETUP_REGISTER 0x81
#define MIXER_INTERRUP_STATUS_REGISTEER 0x82
void get_dma(SB16* sb16);
unsigned char read_mixer(unsigned short base,unsigned char reg);
unsigned char get_irq(SB16* sb16);

View File

@@ -1,9 +0,0 @@
typedef struct
{
unsigned short base;
unsigned char irq;
unsigned char dma8;
unsigned char dma16;
unsigned char* buffer;
}SB16;

View File

@@ -1,3 +0,0 @@
void write_wave()
{
}

View File

@@ -1,124 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: mkernel/modules/sound/sound.c
* PURPOSE: SoundBlaster 16 Driver
* PROGRAMMER: Snatched from David Welch (welch@mcmail.com)
* Modified for Soundblaster by Robert Bergkvist (fragdance@hotmail.com)
* UPDATE HISTORY:
* ??/??/??: Created
*
*/
/* FUNCTIONS **************************************************************/
#include <internal/halio.h>
#include <ddk/ntddk.h>
#include <internal/hal/ddk.h>
#include <internal/dma.h>
#include <internal/mm.h>
#include <string.h>
#include <internal/string.h>
#include <devices.h>
#include "sb16.h"
#include "dsp.h"
#include "mixer.h"
#include "in.h"
#include "wave.h"
SB16 sb16;
sb_status sb16_getenvironment(void);
NTSTATUS Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status;
switch (Stack->MajorFunction)
{
case IRP_MJ_CREATE:
printk("(SoundBlaster 16 Driver WaveOut) Creating\n");
reset_dsp(sb16.base);
status = STATUS_SUCCESS;
break;
case IRP_MJ_CLOSE:
status = STATUS_SUCCESS;
break;
case IRP_MJ_WRITE:
printk("(SoundBlaster 16 Driver) Writing %d bytes\n",Stack->Parameters.Write.Length);
sb16_play((WAVE_HDR*)Irp->UserBuffer);
status = STATUS_SUCCESS;
break;
default:
status = STATUS_NOT_IMPLEMENTED;
break;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
}
NTSTATUS ModuleEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS ret;
printk("SoundBlaster 16 Driver 0.0.1\n");
if(sb16_getenvironment()!=SB_TRUE)
{
printk("Soundblaster 16 not found\n");
return 0;
}
ret = IoCreateDevice(DriverObject,0,"\\Device\\WaveOut",FILE_DEVICE_WAVE_OUT,0,FALSE,&DeviceObject);
if (ret!=STATUS_SUCCESS)
return(ret);
DeviceObject->Flags=0;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] =Dispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
DriverObject->DriverUnload = NULL;
return(STATUS_SUCCESS);
}
sb_status sb16_getenvironment(void)
{
if(detect_dsp(&sb16)!=SB_TRUE)
{
printk("Detect DSP failed!!!\n");
return SB_FALSE;
}
printk("DSP base address 0x%x\n",sb16.base);
get_irq(&sb16);
printk("IRQ: %d\n",sb16.irq);
get_dma(&sb16);
printk("DMA8: 0x%x DMA16: 0x%x\n",sb16.dma8,sb16.dma16);
return SB_TRUE;
}
#include "dsp.c"
#include "mixer.c"
#include "wave.c"

View File

@@ -1,126 +0,0 @@
ULONG OldIRQ;
PKINTERRUPT IrqObject;
BOOLEAN DMAOutputISR(PKINTERRUPT Interrupt, PVOID ServiceContext)
{
printk("interrupt\n");
return FALSE;
}
void sb16_play(WAVE_HDR* wave)
{
unsigned int eflags;
ULONG MappedIrq;
KIRQL Dirql;
KAFFINITY Affinity;
PKINTERRUPT IrqObject;
unsigned int mask,newmask;
unsigned int i;
unsigned int tmp[255];
i=0;
dump_wav(wave);
do
{
tmp[i++]=get_dma_page(0x0fffff+IDMAP_BASE);
printk("0x%x ",tmp[i-1]);
}
while((tmp[i-1]&0xffff)!=0);
free_page((tmp[0])-IDMAP_BASE,i-1);
sb16.buffer=((unsigned char*)tmp[i-1]);
/*
* Because this is used by alomost every subsystem including irqs it
* must be atomic. The following code sequence disables interrupts after
* saving the previous state of the interrupt flag
*/
__asm__("pushf\n\tpop %0\n\tcli\n\t"
: "=m" (eflags)
: );
memcpy(sb16.buffer,(&wave->data),wave->dLen);
MappedIrq = HalGetInterruptVector(Internal,0,0,8+sb16.irq,&Dirql,&Affinity);
IoConnectInterrupt(&IrqObject,DMAOutputISR,0,NULL,MappedIrq,Dirql,Dirql,0,FALSE,Affinity,FALSE);
mask=inb(0x21);
newmask=((int)1<<sb16.irq);
outb(0x21,(mask&~newmask));
// Restore the interrupt flag
__asm__("push %0\n\tpopf\n\t"
:
: "m" (eflags));
disable_dma(sb16.dma8);
//outb(0x0a,5);
clear_dma_ff(1);
//outb(0xc,0);
set_dma_count(1,wave->dLen);
set_dma_mode(1,DMA_MODE_WRITE);
//outb(0xb,0x49);
//outb(0x3,(wave->dLen)&0xff);
//outb(0x3,((unsigned int)(wave->dLen)>>8)&0xff);
set_dma_addr(sb16.dma8,(unsigned int)sb16.buffer-IDMAP_BASE);
//outb(0x83,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>16))&0xf);
//outb(0x2,((unsigned int)sb16.buffer&0xff));
//outb(0x2,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>8))&0xff);
enable_dma(sb16.dma8);
//outb(0xa,1);
write_dsp(sb16.base,0x00D1);
write_dsp(sb16.base,0x40);
write_dsp(sb16.base,((unsigned char)256-(1000000/wave->nSamplesPerSec)));
outb(sb16.base + 4, (int) 0xa);
outb(sb16.base + 5, (int) 0x00);
outb(sb16.base + 4, (int) 4);
outb(sb16.base + 5, (int) 0xFF);
outb(sb16.base + 4, (int) 0x22);
outb(sb16.base + 5, (int) 0xFF);
write_dsp(sb16.base,0x14);
write_dsp(sb16.base,(wave->dLen&0x00ff));
write_dsp(sb16.base,((wave->dLen)&0xff00)>>8);
// write_dsp(sb16.base,0xc0);
// write_dsp(sb16.base,0x0);
// OldIRQ=HalGetInterruptVector(Internal,0,0,irq+8,&irql,&affinity);
// printk("OldIRQ: 0x%x\n",OldIRQ);
// status=IoConnectInterrupt(&IrqObject,playRoutine,0,NULL,OldIRQ,irql,irql,0,FALSE,affinity,FALSE);
// if(status!=STATUS_SUCCESS) printk("Couldn't set irq\n");
// else printk("IRQ set\n");
}
void dump_wav(WAVE_HDR* wave)
{
printk("wave.rID: %c%c%c%c\n",wave->rID[0],wave->rID[1],wave->rID[2],wave->rID[3]);
printk("wave.rLen: 0x%x\n",wave->rLen);
printk("wave.wID: %c%c%c%c\n",wave->wID[0],wave->wID[1],wave->wID[2],wave->wID[3]);
printk("wave.fID: %c%c%c%c\n",wave->fID[0],wave->fID[1],wave->fID[2],wave->fID[3]);
printk("wave.fLen: 0x%x\n",wave->fLen);
printk("wave.wFormatTag: 0x%x\n",wave->wFormatTag);
printk("wave.nChannels: 0x%x\n",wave->nChannels);
printk("wave.nSamplesPerSec: 0x%x\n",wave->nSamplesPerSec);
printk("wave.nAvgBytesPerSec: 0x%x\n",wave->nAvgBytesPerSec);
printk("wave.nBlockAlign: 0x%x\n",wave->nBlockAlign);
printk("wave.FormatSpecific: 0x%x\n",wave->FormatSpecific);
printk("wave.dID: %c%c%c%c\n",wave->dID[0],wave->dID[1],wave->dID[2],wave->dID[3]);
printk("wave.dLen: 0x%x\n",wave->dLen);
}
BOOLEAN playRoutine(PKINTERRUPT Interrupt,PVOID ServiceContext)
{
return FALSE;
}

View File

@@ -1,24 +0,0 @@
KIRQL irql;
KAFFINITY affinity;
typedef struct
{
unsigned char rID[4] __attribute__((packed)); //4 0
unsigned int rLen __attribute__((packed)); //4 4
unsigned char wID[4] __attribute__((packed)); //4 8
unsigned char fID[4] __attribute__((packed)); //4 12
unsigned int fLen __attribute__((packed)); //4 16
unsigned short wFormatTag __attribute__((packed)); //2 18
unsigned short nChannels __attribute__((packed)); //2 20
unsigned int nSamplesPerSec __attribute__((packed)); //2 22
unsigned int nAvgBytesPerSec __attribute__((packed)); //2 24
unsigned short nBlockAlign __attribute__((packed)); //2 26
unsigned short FormatSpecific __attribute__((packed)); //2 28
unsigned char dID[4] __attribute__((packed)); //4 30
unsigned int dLen __attribute__((packed));
unsigned char* data;
}WAVE_HDR;
void sb16_play(WAVE_HDR* wave);
void dump_wav(WAVE_HDR* wave);
BOOLEAN playRoutine(PKINTERRUPT Interrupt,PVOID ServiceContext);

View File

@@ -1,4 +0,0 @@
base.tmp
junk.tmp
temp.exp

View File

@@ -1,16 +0,0 @@
all: test.sys
OBJECTS = test.o ../../../ntoskrnl/ntoskrnl.a
# --def test.def --def test.def
test.sys: test.o
$(DLLTOOL) --dllname test.sys --output-lib test.a
$(CC) -specs=$(KM_SPECS) -mdll -o junk.tmp -Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ -Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp $(OBJECTS)
- $(RM) junk.tmp
$(DLLTOOL) --dllname test.sys --base-file base.tmp \
--output-exp temp.exp
- $(RM) base.tmp
$(CC) --verbose -Wl,--image-base,0x10000 -Wl,-e,_DriverEntry -specs=$(KM_SPECS) -mdll -o test.sys $(OBJECTS) -Wl,temp.exp
- $(RM) temp.exp

View File

@@ -1,107 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/test/test.c
* PURPOSE: Testing driver
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* ??/??/??: Created
* 18/06/98: Made more NT like
*/
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
/* FUNCTIONS **************************************************************/
#if 0
NTSTATUS TestWrite(PIRP Irp, PIO_STACK_LOCATION Stk)
{
PVOID Address;
Address = MmGetSystemAddressForMdl(Irp->MdlAddress);
DbgPrint("Asked to write '%s'\n",(PCH)Address);
return(STATUS_SUCCESS);
}
NTSTATUS TestDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status;
int i;
switch (Stack->MajorFunction)
{
case IRP_MJ_CREATE:
DbgPrint("(Test Driver) Creating\n");
status = STATUS_SUCCESS;
break;
case IRP_MJ_CLOSE:
status = STATUS_SUCCESS;
break;
case IRP_MJ_WRITE:
DbgPrint("(Test Driver) Writing\n");
status = TestWrite(Irp,Stack);
break;
default:
status = STATUS_NOT_IMPLEMENTED;
break;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
}
#endif
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS ret;
ANSI_STRING astr;
UNICODE_STRING ustr;
DbgPrint("Test Driver 0.0.1\n");
#if 0
RtlInitAnsiString(&astr,"\\Device\\Test");
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
ret = IoCreateDevice(DriverObject,0,&ustr,
FILE_DEVICE_PARALLEL_PORT,0,FALSE,&DeviceObject);
if (ret!=STATUS_SUCCESS)
{
return(ret);
}
DeviceObject->Flags=DO_DIRECT_IO;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = TestDispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = TestDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = TestDispatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = TestDispatch;
DriverObject->DriverUnload = NULL;
#endif
return(STATUS_SUCCESS);
}

View File

@@ -1,155 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/blockdev.c
* PURPOSE: Temporary sector reading support
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <string.h>
#include <internal/string.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* FUNCTIONS ***************************************************************/
BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN PVOID Buffer)
{
LARGE_INTEGER sectorNumber;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
NTSTATUS status;
ULONG sectorSize;
int j;
DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
pDeviceObject,DiskSector,Buffer);
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
(unsigned long) DiskSector,
(unsigned long) BLOCKSIZE,
(unsigned long) GET_LARGE_INTEGER_HIGH_PART(sectorNumber),
(unsigned long) GET_LARGE_INTEGER_LOW_PART(sectorNumber));
KeInitializeEvent(&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE*SectorCount;
DPRINT("Building synchronous FSD Request...\n");
irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
pDeviceObject,
Buffer,
sectorSize,
&sectorNumber,
&event,
&ioStatus );
if (!irp) {
DbgPrint("READ failed!!!\n");
return FALSE;
}
DPRINT("Calling IO Driver...\n");
status = IoCallDriver(pDeviceObject,
irp);
DPRINT("Waiting for IO Operation...\n");
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event,
Suspended,
KernelMode,
FALSE,
NULL);
DPRINT("Getting IO Status...\n");
status = ioStatus.Status;
}
if (!NT_SUCCESS(status)) {
DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status);
return FALSE;
}
return TRUE;
}
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN UCHAR* Buffer)
{
LARGE_INTEGER sectorNumber;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
NTSTATUS status;
ULONG sectorSize;
PULONG mbr;
int j;
DPRINT("VFATWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
pDeviceObject,DiskSector,Buffer);
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
KeInitializeEvent(&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE*SectorCount;
DPRINT("Building synchronous FSD Request...\n");
irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
pDeviceObject,
Buffer,
sectorSize,
&sectorNumber,
&event,
&ioStatus );
if (!irp) {
DbgPrint("WRITE failed!!!\n");
return FALSE;
}
DPRINT("Calling IO Driver...\n");
status = IoCallDriver(pDeviceObject,
irp);
DPRINT("Waiting for IO Operation...\n");
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event,
Suspended,
KernelMode,
FALSE,
NULL);
DPRINT("Getting IO Status...\n");
status = ioStatus.Status;
}
if (!NT_SUCCESS(status)) {
DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status);
return FALSE;
}
ExFreePool(mbr);
DPRINT("Block request succeeded\n");
return TRUE;
}

View File

@@ -1,326 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/dir.c
* PURPOSE: ext2 filesystem
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <wchar.h>
#include <internal/string.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* FUNCTIONS *****************************************************************/
VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len)
{
ULONG i;
for (i=0; i<Len; i++)
{
*Out = *In;
Out++;
In++;
}
*Out = 0;
}
PVOID Ext2ProcessDirEntry(PDEVICE_EXTENSION DeviceExt,
struct ext2_dir_entry* dir_entry,
PIO_STACK_LOCATION IoStack,
PVOID Buffer,
ULONG FileIndex)
{
PFILE_DIRECTORY_INFORMATION FDI;
PFILE_NAMES_INFORMATION FNI;
PFILE_BOTH_DIRECTORY_INFORMATION FBI;
ULONG i;
PWSTR FileName;
struct ext2_inode inode;
DPRINT("FileIndex %d\n",FileIndex);
DPRINT("Buffer %x\n",Buffer);
Ext2ReadInode(DeviceExt,
dir_entry->inode,
&inode);
switch (IoStack->Parameters.QueryDirectory.FileInformationClass)
{
case FileNamesInformation:
FNI = (PFILE_NAMES_INFORMATION)Buffer;
FNI->NextEntryOffset = sizeof(FileDirectoryInformation) +
dir_entry->name_len + 1;
FNI->FileNameLength = dir_entry->name_len;
Ext2ConvertName(FNI->FileName, dir_entry->name, dir_entry->name_len);
Buffer = Buffer + FNI->NextEntryOffset;
break;
case FileDirectoryInformation:
FDI = (PFILE_DIRECTORY_INFORMATION)Buffer;
FDI->NextEntryOffset = sizeof(FileDirectoryInformation) +
dir_entry->name_len + 1;
FDI->FileIndex = FileIndex;
// FDI->CreationTime = 0;
// FDI->LastAccessTime = 0;
// FDI->LastWriteTime = 0;
// FDI->ChangeTime = 0;
FDI->AllocationSize = FDI->EndOfFile = inode.i_size;
FDI->FileAttributes = 0;
FDI->FileNameLength = dir_entry->name_len;
Ext2ConvertName(FDI->FileName, dir_entry->name, dir_entry->name_len);
Buffer = Buffer + FDI->NextEntryOffset;
break;
case FileBothDirectoryInformation:
FBI = (PFILE_BOTH_DIRECTORY_INFORMATION)Buffer;
FBI->NextEntryOffset = sizeof(FileBothDirectoryInformation) +
dir_entry->name_len + 1;
FBI->FileIndex = FileIndex;
FBI->AllocationSize = FBI->EndOfFile = inode.i_size;
FBI->FileAttributes = 0;
FBI->FileNameLength = dir_entry->name_len;
Ext2ConvertName(FBI->FileName, dir_entry->name, dir_entry->name_len);
memset(FBI->ShortName, 0, sizeof(FBI->ShortName));
Buffer = Buffer + FBI->NextEntryOffset;
break;
default:
UNIMPLEMENTED;
}
return(Buffer);
}
NTSTATUS Ext2QueryDirectory(PDEVICE_EXTENSION DeviceExt,
PEXT2_FCB Fcb,
PIRP Irp,
PIO_STACK_LOCATION IoStack)
{
ULONG Max;
ULONG i;
ULONG StartIndex;
PVOID Buffer;
struct ext2_dir_entry dir_entry;
ULONG CurrentIndex;
DPRINT("Buffer %x\n",Buffer);
Buffer = Irp->UserBuffer;
DPRINT("IoStack->Flags %x\n",IoStack->Flags);
if (IoStack->Flags & SL_RETURN_SINGLE_ENTRY)
{
Max = 1;
}
else
{
UNIMPLEMENTED;
}
DPRINT("Buffer->FileIndex %d\n",
((PFILE_DIRECTORY_INFORMATION)Buffer)->FileIndex);
if (IoStack->Flags & SL_INDEX_SPECIFIED)
{
StartIndex = ((PFILE_DIRECTORY_INFORMATION)Buffer)->FileIndex;
}
else
{
StartIndex = 0;
}
if (IoStack->Flags & SL_RESTART_SCAN)
{
StartIndex = 0;
}
DPRINT("StartIndex %d\n",StartIndex);
for (i=0; i<Max ;i++)
{
if (!Ext2ScanDir(DeviceExt,&Fcb->inode,"*",&dir_entry,&StartIndex))
{
((PFILE_DIRECTORY_INFORMATION)Buffer)->NextEntryOffset = 0;
return(STATUS_NO_MORE_FILES);
}
Buffer = Ext2ProcessDirEntry(DeviceExt,
&dir_entry,
IoStack,
Buffer,
StartIndex);
}
return(STATUS_SUCCESS);
}
NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PEXT2_FCB Fcb = (PVOID)FileObject->FsContext;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
DPRINT("Ext2DirectoryControl(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DeviceExt = DeviceObject->DeviceExtension;
switch (Stack->MinorFunction)
{
case IRP_MN_QUERY_DIRECTORY:
Status = Ext2QueryDirectory(DeviceExt, Fcb, Irp, Stack);
break;
default:
Status = STATUS_UNSUCCESSFUL;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,
struct ext2_inode* dir,
PCH filename,
struct ext2_dir_entry* ret,
PULONG StartIndex)
{
ULONG i;
char* buffer;
ULONG offset;
char name[255];
struct ext2_dir_entry* current;
ULONG block;
DPRINT("Ext2ScanDir(dir %x, filename %s, ret %x)\n",dir,filename,ret);
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
for (i=0; i<((*StartIndex)/BLOCKSIZE); i++);
for (; (block = Ext2BlockMap(DeviceExt, dir, i)) != 0; i++)
{
DPRINT("block %d\n",block);
Ext2ReadSectors(DeviceExt->StorageDevice,
block,
1,
buffer);
offset = (*StartIndex)%BLOCKSIZE;
while (offset < BLOCKSIZE)
{
current = &buffer[offset];
strncpy(name,current->name,current->name_len);
name[current->name_len]=0;
DPRINT("Scanning offset %d inode %d name %s\n",
offset,current->inode,name);
DPRINT("Comparing %s %s\n",name,filename);
if (strcmp(name,filename)==0 || strcmp(filename,"*")==0)
{
DPRINT("Match found\n");
*StartIndex = (i*BLOCKSIZE) + offset + current->rec_len;
memcpy(ret,current,sizeof(struct ext2_dir_entry));
ExFreePool(buffer);
return(TRUE);
}
offset = offset + current->rec_len;
assert(current->rec_len != 0);
DPRINT("offset %d\n",offset);
}
DPRINT("Onto next block\n");
}
DPRINT("No match\n");
ExFreePool(buffer);
return(FALSE);
}
void unicode_to_ansi(PCH StringA, PWSTR StringW)
{
while((*StringW)!=0)
{
*StringA = *StringW;
StringA++;
StringW++;
}
*StringA = 0;
}
NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PWSTR FileName)
/*
* FUNCTION: Opens a file
*/
{
struct ext2_inode parent_inode;
struct ext2_dir_entry entry;
char name[255];
ULONG current_inode = 2;
char* current_segment;
PEXT2_FCB Fcb;
ULONG StartIndex = 0;
DPRINT("Ext2OpenFile(DeviceExt %x, FileObject %x, FileName %w)\n",
DeviceExt,FileObject,FileName);
Fcb = ExAllocatePool(NonPagedPool, sizeof(EXT2_FCB));
unicode_to_ansi(name,FileName);
DPRINT("name %s\n",name);
current_segment = strtok(name,"\\");
while (current_segment!=NULL)
{
Ext2ReadInode(DeviceExt,
current_inode,
&parent_inode);
if (!Ext2ScanDir(DeviceExt,&parent_inode,current_segment,&entry,
&StartIndex))
{
ExFreePool(Fcb);
return(STATUS_UNSUCCESSFUL);
}
current_inode = entry.inode;
current_segment = strtok(NULL,"\\");
StartIndex = 0;
}
DPRINT("Found file\n");
Ext2ReadInode(DeviceExt,
current_inode,
&Fcb->inode);
FileObject->FsContext = Fcb;
return(STATUS_SUCCESS);
}
NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
DPRINT("Ext2Create(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DeviceExt = DeviceObject->DeviceExtension;
Status = Ext2OpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}

View File

@@ -1,242 +0,0 @@
BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN PVOID Buffer);
#define BLOCKSIZE (1024)
struct ext2_super_block {
ULONG s_inodes_count; /* Inodes count */
ULONG s_blocks_count; /* Blocks count */
ULONG s_r_blocks_count; /* Reserved blocks count */
ULONG s_free_blocks_count; /* Free blocks count */
ULONG s_free_inodes_count; /* Free inodes count */
ULONG s_first_data_block; /* First Data Block */
ULONG s_log_block_size; /* Block size */
LONG s_log_frag_size; /* Fragment size */
ULONG s_blocks_per_group; /* # Blocks per group */
ULONG s_frags_per_group; /* # Fragments per group */
ULONG s_inodes_per_group; /* # Inodes per group */
ULONG s_mtime; /* Mount time */
ULONG s_wtime; /* Write time */
USHORT s_mnt_count; /* Mount count */
SHORT s_max_mnt_count; /* Maximal mount count */
USHORT s_magic; /* Magic signature */
USHORT s_state; /* File system state */
USHORT s_errors; /* Behaviour when detecting errors */
USHORT s_minor_rev_level; /* minor revision level */
ULONG s_lastcheck; /* time of last check */
ULONG s_checkinterval; /* max. time between checks */
ULONG s_creator_os; /* OS */
ULONG s_rev_level; /* Revision level */
USHORT s_def_resuid; /* Default uid for reserved blocks */
USHORT s_def_resgid; /* Default gid for reserved blocks */
/*
* These fields are for EXT2_DYNAMIC_REV superblocks only.
*
* Note: the difference between the compatible feature set and
* the incompatible feature set is that if there is a bit set
* in the incompatible feature set that the kernel doesn't
* know about, it should refuse to mount the filesystem.
*
* e2fsck's requirements are more strict; if it doesn't know
* about a feature in either the compatible or incompatible
* feature set, it must abort and not try to meddle with
* things it doesn't understand...
*/
ULONG s_first_ino; /* First non-reserved inode */
USHORT s_inode_size; /* size of inode structure */
USHORT s_block_group_nr; /* block group # of this superblock */
ULONG s_feature_compat; /* compatible feature set */
ULONG s_feature_incompat; /* incompatible feature set */
ULONG s_feature_ro_compat; /* readonly-compatible feature set */
ULONG s_reserved[230]; /* Padding to the end of the block */
};
/*
* Codes for operating systems
*/
#define EXT2_OS_LINUX 0
#define EXT2_OS_HURD 1
#define EXT2_OS_MASIX 2
#define EXT2_OS_FREEBSD 3
#define EXT2_OS_LITES 4
/*
* Revision levels
*/
#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
/*
* The second extended file system magic number
*/
#define EXT2_SUPER_MAGIC 0xEF53
/*
* Constants relative to the data blocks
*/
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
USHORT i_mode; /* File mode */
USHORT i_uid; /* Owner Uid */
ULONG i_size; /* Size in bytes */
ULONG i_atime; /* Access time */
ULONG i_ctime; /* Creation time */
ULONG i_mtime; /* Modification time */
ULONG i_dtime; /* Deletion Time */
USHORT i_gid; /* Group Id */
USHORT i_links_count; /* Links count */
ULONG i_blocks; /* Blocks count */
ULONG i_flags; /* File flags */
union {
struct {
ULONG l_i_reserved1;
} linux1;
struct {
ULONG h_i_translator;
} hurd1;
struct {
ULONG m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
ULONG i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
ULONG i_version; /* File version (for NFS) */
ULONG i_file_acl; /* File ACL */
ULONG i_dir_acl; /* Directory ACL */
ULONG i_faddr; /* Fragment address */
union {
struct {
UCHAR l_i_frag; /* Fragment number */
UCHAR l_i_fsize; /* Fragment size */
USHORT i_pad1;
ULONG l_i_reserved2[2];
} linux2;
struct {
UCHAR h_i_frag; /* Fragment number */
UCHAR h_i_fsize; /* Fragment size */
USHORT h_i_mode_high;
USHORT h_i_uid_high;
USHORT h_i_gid_high;
ULONG h_i_author;
} hurd2;
struct {
UCHAR m_i_frag; /* Fragment number */
UCHAR m_i_fsize; /* Fragment size */
USHORT m_pad1;
ULONG m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
};
#if defined(__KERNEL__) || defined(__linux__)
#define i_reserved1 osd1.linux1.l_i_reserved1
#define i_frag osd2.linux2.l_i_frag
#define i_fsize osd2.linux2.l_i_fsize
#define i_reserved2 osd2.linux2.l_i_reserved2
#endif
#ifdef __hurd__
#define i_translator osd1.hurd1.h_i_translator
#define i_frag osd2.hurd2.h_i_frag;
#define i_fsize osd2.hurd2.h_i_fsize;
#define i_uid_high osd2.hurd2.h_i_uid_high
#define i_gid_high osd2.hurd2.h_i_gid_high
#define i_author osd2.hurd2.h_i_author
#endif
#ifdef __masix__
#define i_reserved1 osd1.masix1.m_i_reserved1
#define i_frag osd2.masix2.m_i_frag
#define i_fsize osd2.masix2.m_i_fsize
#define i_reserved2 osd2.masix2.m_i_reserved2
#endif
/*
* Constants relative to the data blocks
*/
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
/*
* Inode flags
*/
#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
#define EXT2_UNRM_FL 0x00000002 /* Undelete */
#define EXT2_COMPR_FL 0x00000004 /* Compress file */
#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
/*
* Structure of a blocks group descriptor
*/
struct ext2_group_desc
{
ULONG bg_block_bitmap; /* Blocks bitmap block */
ULONG bg_inode_bitmap; /* Inodes bitmap block */
ULONG bg_inode_table; /* Inodes table block */
USHORT bg_free_blocks_count; /* Free blocks count */
USHORT bg_free_inodes_count; /* Free inodes count */
USHORT bg_used_dirs_count; /* Directories count */
USHORT bg_pad;
ULONG bg_reserved[3];
};
#define EXT2_NAME_LEN 255
struct ext2_dir_entry {
ULONG inode; /* Inode number */
USHORT rec_len; /* Directory entry length */
USHORT name_len; /* Name length */
char name[EXT2_NAME_LEN]; /* File name */
};
typedef struct
{
PDEVICE_OBJECT StorageDevice;
struct ext2_super_block* superblock;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
ULONG ino,
struct ext2_inode* inode);
struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
ULONG block_group);
typedef struct _EXT2_FCB
{
struct ext2_inode inode;
} EXT2_FCB, *PEXT2_FCB;
ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,
struct ext2_inode* inode,
ULONG offset);
NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PWSTR FileName);
NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PVOID Buffer,
ULONG Length,
LARGE_INTEGER Offset);
NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);

View File

@@ -1,53 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/super.c
* PURPOSE: ext2 filesystem
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* FUNCTIONS ****************************************************************/
#define addr_per_block (BLOCKSIZE / sizeof(ULONG))
ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,
struct ext2_inode* inode,
ULONG offset)
{
ULONG block;
PULONG TempBuffer;
DPRINT("Ext2BlockMap(DeviceExt %x, inode %x, offset %d)\n",
DeviceExt,inode,offset);
if (offset < EXT2_NDIR_BLOCKS)
{
block = inode->i_block[offset];
DPRINT("block %d\n",block);
return(block);
}
offset = offset - EXT2_NDIR_BLOCKS;
if (offset < addr_per_block)
{
block = inode->i_block[EXT2_IND_BLOCK];
TempBuffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
Ext2ReadSectors(DeviceExt->StorageDevice,
block,
1,
TempBuffer);
block = TempBuffer[offset];
ExFreePool(TempBuffer);
return(block);
}
DbgPrint("Failed at %s:%d\n",__FILE__,__LINE__);
for(;;);
}

View File

@@ -1,80 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/inode.c
* PURPOSE: Manipulating inodes
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* 26/12/98: Created
*/
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
#include <string.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* FUNCTIONS ***************************************************************/
struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
ULONG block_group)
{
struct ext2_group_desc* buffer;
ULONG block;
struct ext2_group_desc* gdp;
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
block = block_group / (BLOCKSIZE / sizeof(struct ext2_group_desc));
Ext2ReadSectors(DeviceExt->StorageDevice,
2 + block,
1,
buffer);
gdp = &buffer[block_group % (BLOCKSIZE / sizeof(struct ext2_group_desc))];
DPRINT("gdp->bg_free_blocks_count %d\n",gdp->bg_free_blocks_count);
DPRINT("gdp->bg_inode_table %d\n",gdp->bg_inode_table);
return(gdp);
}
#define INODES_PER_BLOCK (BLOCKSIZE / sizeof(struct ext2_inode))
VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
ULONG ino,
struct ext2_inode* inode)
{
ULONG block_group;
struct ext2_group_desc* gdp;
ULONG offset;
struct ext2_inode* buffer;
DPRINT("Ext2ReadInode(DeviceExt %x, ino %d, inode %x)\n",
DeviceExt,ino,inode);
block_group = (ino - 1) / DeviceExt->superblock->s_inodes_per_group;
gdp = Ext2LoadGroupDesc(DeviceExt, block_group);
offset = (ino - 1) % DeviceExt->superblock->s_inodes_per_group;
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
Ext2ReadSectors(DeviceExt->StorageDevice,
gdp->bg_inode_table + (offset / INODES_PER_BLOCK),
1,
buffer);
memcpy(inode,&buffer[offset % INODES_PER_BLOCK],sizeof(struct ext2_inode));
DPRINT("inode->i_uid %d\n",inode->i_uid);
DPRINT("inode->i_links_count %d\n",inode->i_links_count);
DPRINT("inode->i_blocks %d\n",inode->i_blocks);
}

View File

@@ -1,16 +0,0 @@
all: ext2fs.sys
OBJECTS = super.o blockdev.o inode.o file.o dir.o rw.o \
../../../ntoskrnl/ntoskrnl.a
ext2fs.sys: $(OBJECTS)
$(CC) -specs=$(KM_SPECS) -mdll -o junk.tmp -Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ -Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp $(OBJECTS)
$(RM) junk.tmp
$(DLLTOOL) --dllname ext2fs.sys --base-file base.tmp \
--output-exp temp.exp
$(RM) base.tmp
$(CC) --verbose -Wl,--image-base,0x10000 -Wl,-e,_DriverEntry \
-specs=$(KM_SPECS) -mdll -o ext2fs.sys $(OBJECTS) -Wl,temp.exp
$(RM) temp.exp

View File

@@ -1,94 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/super.c
* PURPOSE: ext2 filesystem
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* FUNCTIONS *****************************************************************/
NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PVOID Buffer,
ULONG Length,
LARGE_INTEGER OffsetL)
/*
* FUNCTION: Reads data from a file
*/
{
PEXT2_FCB Fcb;
PVOID TempBuffer;
ULONG Offset = OffsetL;
ULONG block;
ULONG Delta;
ULONG i;
DPRINT("Ext2ReadFile(DeviceExt %x, FileObject %x, Buffer %x, Length %d, \n"
"OffsetL %d)\n",DeviceExt,FileObject,Buffer,Length,(ULONG)OffsetL);
Fcb = (PEXT2_FCB)FileObject->FsContext;
TempBuffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
if (Offset >= Fcb->inode.i_size)
{
ExFreePool(TempBuffer);
return(STATUS_END_OF_FILE);
}
if ((Offset + Length) > Fcb->inode.i_size)
{
Length = Fcb->inode.i_size - Offset;
}
CHECKPOINT;
if ((Offset % BLOCKSIZE) != 0)
{
block = Ext2BlockMap(DeviceExt, &Fcb->inode, Offset / BLOCKSIZE);
Delta = min(BLOCKSIZE - (Offset % BLOCKSIZE),Length);
Ext2ReadSectors(DeviceExt->StorageDevice,
block,
1,
TempBuffer);
memcpy(Buffer, TempBuffer + (Offset % BLOCKSIZE), Delta);
Length = Length - Delta;
Offset = Offset + Delta;
Buffer = Buffer + Delta;
}
CHECKPOINT;
for (i=0; i<(Length/BLOCKSIZE); i++)
{
block = Ext2BlockMap(DeviceExt, &Fcb->inode,
(Offset / BLOCKSIZE)+i);
Ext2ReadSectors(DeviceExt->StorageDevice,
block,
1,
Buffer);
Length = Length - BLOCKSIZE;
Offset = Offset + BLOCKSIZE;
Buffer = Buffer + BLOCKSIZE;
}
CHECKPOINT;
if ((Length % BLOCKSIZE) != 0)
{
block = Ext2BlockMap(DeviceExt, &Fcb->inode, Offset / BLOCKSIZE);
Ext2ReadSectors(DeviceExt->StorageDevice,
block,
1,
TempBuffer);
memcpy(Buffer,TempBuffer,Length);
}
ExFreePool(TempBuffer);
return(STATUS_SUCCESS);
}

View File

@@ -1,192 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/super.c
* PURPOSE: ext2 filesystem
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <wchar.h>
#include <internal/string.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* GLOBALS *****************************************************************/
static PDRIVER_OBJECT DriverObject;
/* FUNCTIONS ****************************************************************/
NTSTATUS Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
PDEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
DPRINT("Ext2Close(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
DeviceExtension = DeviceObject->DeviceExtension;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
ULONG Length;
PVOID Buffer;
ULONG Offset;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
NTSTATUS Status;
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
Length = Stack->Parameters.Read.Length;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Offset = Stack->Parameters.Read.ByteOffset;
Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
}
NTSTATUS Ext2Mount(PDEVICE_OBJECT DeviceToMount)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_EXTENSION DeviceExt;
PVOID BlockBuffer;
struct ext2_super_block* superblock;
DPRINT("Ext2Mount(DeviceToMount %x)\n",DeviceToMount);
BlockBuffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
Ext2ReadSectors(DeviceToMount,
1,
1,
BlockBuffer);
superblock = BlockBuffer;
if (superblock->s_magic != EXT2_SUPER_MAGIC)
{
ExFreePool(BlockBuffer);
return(STATUS_UNRECOGNIZED_VOLUME);
}
DPRINT("Volume recognized\n");
DPRINT("s_inodes_count %d\n",superblock->s_inodes_count);
DPRINT("s_blocks_count %d\n",superblock->s_blocks_count);
IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
DeviceToMount);
DeviceExt->superblock = superblock;
return(STATUS_SUCCESS);
}
NTSTATUS Ext2FileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PVPB vpb = Stack->Parameters.Mount.Vpb;
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
NTSTATUS Status;
Status = Ext2Mount(DeviceToMount);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS ret;
UNICODE_STRING DeviceNameU;
ANSI_STRING DeviceNameA;
DbgPrint("Ext2 FSD 0.0.1\n");
DriverObject = _DriverObject;
RtlInitAnsiString(&DeviceNameA,"\\Device\\Ext2Fsd");
RtlAnsiStringToUnicodeString(&DeviceNameU,&DeviceNameA,TRUE);
ret = IoCreateDevice(DriverObject,
0,
&DeviceNameU,
FILE_DEVICE_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
if (ret!=STATUS_SUCCESS)
{
return(ret);
}
DeviceObject->Flags=0;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2Close;
DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2Create;
DriverObject->MajorFunction[IRP_MJ_READ] = Ext2Read;
DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2Write;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
Ext2FileSystemControl;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]=
Ext2DirectoryControl;
DriverObject->DriverUnload = NULL;
DPRINT("DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] %x\n",
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]);
DPRINT("IRP_MJ_DIRECTORY_CONTROL %d\n",IRP_MJ_DIRECTORY_CONTROL);
IoRegisterFileSystem(DeviceObject);
return(STATUS_SUCCESS);
}

View File

@@ -1,76 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/minix/minix.c
* PURPOSE: Minix FSD
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#define NDEBUG
#include <internal/debug.h>
#include "minix.h"
/* FUNCTIONS ****************************************************************/
static unsigned int MinixGetBlock(PMINIX_DEVICE_EXTENSION DeviceExt,
struct minix_inode* inode,
int blk)
{
int block;
PCCB Ccb;
DPRINT("MinixGetBlock(inode %x, blk %d)\n",inode,blk);
if (blk < 7)
{
block = inode->i_zone[blk];
return(block);
}
blk = blk - 7;
if (blk < 512)
{
block = inode->i_zone[7];
Ccb = CbAcquireForRead(&DeviceExt->Dccb,block);
block = ((PUSHORT)Ccb->Buffer)[blk];
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
return(block);
}
blk = blk - 512;
block = inode->i_zone[8];
Ccb = CbAcquireForRead(&DeviceExt->Dccb,block);
block = ((PUSHORT)Ccb->Buffer)[(blk>>9)&511];
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
Ccb = CbAcquireForRead(&DeviceExt->Dccb,block);
block = ((PUSHORT)Ccb->Buffer)[blk&512];
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
return(block);
}
NTSTATUS MinixReadBlock(PMINIX_DEVICE_EXTENSION DeviceExt,
struct minix_inode* inode,
int blk,
PCCB* Ccb)
{
unsigned int block;
DPRINT("DeviceExt %x\n",DeviceExt);
DPRINT("inode %x\n",inode);
DPRINT("blk %d\n",blk);
DPRINT("Ccb %x\n",Ccb);
DPRINT("MinixReadBlock(DeviceExt %x, inode %x, blk %d, Ccb %x)\n",
DeviceExt,inode,blk,Ccb);
block = MinixGetBlock(DeviceExt,inode,blk);
(*Ccb) = CbAcquireForRead(&DeviceExt->Dccb,block);
return(STATUS_SUCCESS);
}

View File

@@ -10,13 +10,12 @@
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <string.h>
#include <internal/string.h>
#define NDEBUG
#include <internal/debug.h>
#include "minix.h"
#include "minix_fs.h"
/* FUNCTIONS ***************************************************************/
@@ -35,8 +34,7 @@ BOOLEAN MinixReadSector(IN PDEVICE_OBJECT pDeviceObject,
DPRINT("MinixReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
pDeviceObject,DiskSector,Buffer);
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
sectorNumber.LowPart = DiskSector * BLOCKSIZE;
KeInitializeEvent(&event, NotificationEvent, FALSE);
@@ -84,52 +82,3 @@ BOOLEAN MinixReadSector(IN PDEVICE_OBJECT pDeviceObject,
ExFreePool(mbr);
return TRUE;
}
BOOLEAN MinixWriteSector(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN UCHAR* Buffer)
{
LARGE_INTEGER sectorNumber;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
NTSTATUS status;
ULONG sectorSize;
DPRINT("MinixWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
pDeviceObject,DiskSector,Buffer);
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
KeInitializeEvent(&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE;
irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
pDeviceObject,
Buffer,
sectorSize,
&sectorNumber,
&event,
&ioStatus );
status = IoCallDriver(pDeviceObject,
irp);
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event,
Suspended,
KernelMode,
FALSE,
NULL);
status = ioStatus.Status;
}
if (!NT_SUCCESS(status)) {
return FALSE;
}
return TRUE;
}

View File

@@ -1,215 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/minix/minix.c
* PURPOSE: Minix FSD
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#define NDEBUG
#include <internal/debug.h>
#include "minix.h"
/* FUNCTIONS ****************************************************************/
BOOLEAN MinixCompareUnicodeStringToAnsi(PCH AnsiStr, PWCHAR UnicodeStr,
ULONG MaxLen)
{
unsigned int i = 0;
while (i<MaxLen)
{
if ((*AnsiStr)!=(*UnicodeStr))
{
return(FALSE);
}
if ((*AnsiStr)==0 && (*UnicodeStr)==0)
{
return(TRUE);
}
AnsiStr++;
UnicodeStr++;
i++;
}
return(TRUE);
}
#define ENTRIES_PER_BLOCK (BLOCKSIZE / MINIX_DIR_ENTRY_SIZE)
ULONG MinixDirLookup(PMINIX_DEVICE_EXTENSION DeviceExt,
struct minix_inode* dir,
PWCHAR Name)
{
struct minix_dir_entry* current_entry = NULL;
unsigned int offset;
unsigned int i;
unsigned int inode;
PCCB Ccb = NULL;
DPRINT("MinixDirLookup(DeviceExt %x, dir %x, Name %w)\n",DeviceExt,dir,
Name);
for (i=0;i<(dir->i_size/MINIX_DIR_ENTRY_SIZE);i++)
{
CHECKPOINT;
offset = i*MINIX_DIR_ENTRY_SIZE;
if ((offset%BLOCKSIZE)==0)
{
CHECKPOINT;
if (Ccb != NULL)
{
CHECKPOINT;
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
}
CHECKPOINT;
MinixReadBlock(DeviceExt,
dir,
offset/BLOCKSIZE,
&Ccb);
}
current_entry = (struct minix_dir_entry *)
(Ccb->Buffer+offset%BLOCKSIZE);
DPRINT("Inode %x Name %.30s\n",current_entry->inode,
current_entry->name);
if (MinixCompareUnicodeStringToAnsi(current_entry->name,
Name,30))
{
inode = current_entry->inode;
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
DPRINT("MinixDirLookup() = %d\n",inode);
return(inode);
}
}
CHECKPOINT;
if (Ccb != NULL)
{
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
}
DPRINT("MinixDirLookup() = %d\n",0);
return(0);
}
NTSTATUS MinixOpen(PDEVICE_OBJECT DeviceObject,
MINIX_DEVICE_EXTENSION* DeviceExt,
PWSTR DeviceName,
struct minix_inode* result,
PULONG Information)
{
PWSTR current;
PWSTR next;
PWSTR string = DeviceName;
struct minix_inode current_dir;
unsigned int current_ino;
DbgPrint("MinixOpen(DeviceObject %x, DeviceName %w, result %x)\n",
DeviceObject,DeviceName,result);
DPRINT("DeviceName %x\n",DeviceName);
next = &string[0];
current = next+1;
current_ino = MINIX_ROOT_INO;
while (next!=NULL && current_ino!=0)
{
MinixReadInode(DeviceObject,DeviceExt,current_ino,&current_dir);
DPRINT("current %w next %x\n",current,next);
*next = '\\';
current = next+1;
next = wcschr(next+1,'\\');
if (next!=NULL)
{
*next=0;
}
current_ino = MinixDirLookup(DeviceExt,&current_dir,current);
}
if (next==NULL && current_ino!=0)
{
MinixReadInode(DeviceObject,DeviceExt,current_ino,&current_dir);
}
else
{
(*Information) = FILE_DOES_NOT_EXIST;
return(STATUS_UNSUCCESSFUL);
}
memcpy(result,&current_dir,sizeof(struct minix_inode));
DPRINT("MinxOpen() = STATUS_SUCCESS\n",0);
return(STATUS_SUCCESS);
}
NTSTATUS MinixClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
DPRINT("MinixClose(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
ExFreePool(FileObject->FsContext);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
NTSTATUS MinixDirectoryControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
if (Stack->MinorFunction != IRP_MN_QUERY_DIRECTORY)
{
return(STATUS_NOT_IMPLEMENTED);
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
NTSTATUS MinixCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
NTSTATUS Status;
struct minix_inode* result;
MINIX_DEVICE_EXTENSION* DeviceExt;
DPRINT("MinixCreate(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DPRINT("Opening file %x %w\n",FileObject->FileName.Buffer,
FileObject->FileName.Buffer);
DPRINT("FileObject->FileName.Buffer %x\n",
FileObject->FileName.Buffer);
DeviceExt = (MINIX_DEVICE_EXTENSION *)DeviceObject->DeviceExtension;
result = ExAllocatePool(NonPagedPool,sizeof(struct minix_inode));
DPRINT("result %x\n",result);
Status = MinixOpen(DeviceExt->AttachedDevice,DeviceExt,
FileObject->FileName.Buffer,result,
&Irp->IoStatus.Information);
if (Status==STATUS_SUCCESS)
{
FileObject->FsContext=result;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}

View File

@@ -1,132 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/minix/minix.c
* PURPOSE: Minix FSD
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <string.h>
#include <internal/string.h>
#include <internal/bitops.h>
#include <ddk/ntifs.h>
#define NDEBUG
#include <internal/debug.h>
#include "minix.h"
/* FUNCTIONS ****************************************************************/
NTSTATUS MinixDeleteInode(PDEVICE_OBJECT Volume,
MINIX_DEVICE_EXTENSION* DeviceExt,
ULONG ino)
{
PULONG Buffer;
ULONG off;
Buffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
MinixReadSector(Volume, (ino / 8192)+2, (PVOID)Buffer);
off = ino % 8192;
clear_bit(off%32,&Buffer[off/32]);
MinixWriteSector(Volume, (ino / 8192)+2, (PVOID)Buffer);
return(STATUS_SUCCESS);
}
static ULONG MinixAllocateInode(PDEVICE_OBJECT Volume,
MINIX_DEVICE_EXTENSION* DeviceExt)
{
ULONG i;
PULONG Buffer;
ULONG ino;
Buffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
for (i=0; i<DeviceExt->sb->s_imap_blocks; i++)
{
MinixReadSector(Volume,i + 2,Buffer);
ino = find_first_zero_bit(Buffer,8192);
if (ino < 8192)
{
set_bit(ino%32,&Buffer[32]);
MinixWriteSector(Volume,i + 2,Buffer);
ExFreePool(Buffer);
return(ino + (i*8192));
}
}
ExFreePool(Buffer);
return(0);
}
ULONG MinixNewInode(PDEVICE_OBJECT Volume,
MINIX_DEVICE_EXTENSION* DeviceExt,
struct minix_inode* new_inode)
{
ULONG ino;
ino = MinixAllocateInode(Volume,DeviceExt);
if (ino == 0)
{
return(0);
}
MinixWriteInode(Volume,DeviceExt,ino,new_inode);
return(ino);
}
NTSTATUS MinixWriteInode(PDEVICE_OBJECT Volume,
MINIX_DEVICE_EXTENSION* DeviceExt,
ULONG ino,
struct minix_inode* result)
{
int block;
char* buffer;
struct minix_inode* inodes;
DPRINT("MinixWriteInode(ino %x, result %x)\n",ino,result);
buffer = ExAllocatePool(NonPagedPool,1024);
inodes = (struct minix_inode *)buffer;
block = 2 + DeviceExt->sb->s_imap_blocks + DeviceExt->sb->s_zmap_blocks
+ ((ino-1) / MINIX_INODES_PER_BLOCK);
MinixReadSector(Volume,block,buffer);
memcpy(&inodes[(ino-1)%MINIX_INODES_PER_BLOCK],result,
sizeof(struct minix_inode));
MinixWriteSector(Volume,block,buffer);
ExFreePool(buffer);
return(STATUS_SUCCESS);
}
NTSTATUS MinixReadInode(PDEVICE_OBJECT DeviceObject,
MINIX_DEVICE_EXTENSION* DeviceExt,
ULONG ino,
struct minix_inode* result)
{
PCCB Ccb;
int block;
struct minix_inode* inodes;
DPRINT("MinixReadInode(ino %x, result %x)\n",ino,result);
block = 2 + DeviceExt->sb->s_imap_blocks + DeviceExt->sb->s_zmap_blocks
+ ((ino-1) / MINIX_INODES_PER_BLOCK);
DPRINT("Reading block %x offset %x\n",block,block*BLOCKSIZE);
DPRINT("Index %x\n",(ino-1)%MINIX_INODES_PER_BLOCK);
Ccb = CbAcquireForRead(&DeviceExt->Dccb,
block);
inodes = (struct minix_inode *)Ccb->Buffer;
memcpy(result,&inodes[(ino-1)%MINIX_INODES_PER_BLOCK],
sizeof(struct minix_inode));
DPRINT("result->i_uid %x\n",result->i_uid);
DPRINT("result->i_size %x\n",result->i_size);
CbReleaseFromRead(&DeviceExt->Dccb,Ccb);
return(STATUS_SUCCESS);
}

View File

@@ -1,9 +1,2 @@
OBJECTS = block.o rw.o inode.o dir.o mount.o blockdev.o
all: minix.o
minix.o: $(OBJECTS)
$(LD) -r $(OBJECTS) -o minix.o
WIN32_LEAN_AND_MEAN = yes
include ../../../rules.mak
all: minix.o blockdev.o
$(LD) -r minix.o blockdev.o -o minixfsd.o

View File

@@ -445,8 +445,6 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
DriverObject->MajorFunction[IRP_MJ_WRITE] = MinixWrite;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
MinixFileSystemControl;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
MinixDirectoryControl;
DriverObject->DriverUnload = NULL;
IoRegisterFileSystem(DeviceObject);

View File

@@ -1,122 +0,0 @@
#include <ddk/ntddk.h>
#include <ddk/ntifs.h>
#define MINIX_ROOT_INO 1
/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
#define MINIX_LINK_MAX 250
#define MINIX_I_MAP_SLOTS 8
#define MINIX_Z_MAP_SLOTS 64
#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */
#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */
#define MINIX_VALID_FS 0x0001 /* Clean fs. */
#define MINIX_ERROR_FS 0x0002 /* fs has errors. */
#define MINIX_INODES_PER_BLOCK ((BLOCKSIZE)/(sizeof (struct minix_inode)))
#define MINIX2_INODES_PER_BLOCK ((BLOCKSIZE)/(sizeof (struct minix2_inode)))
#define MINIX_V1 0x0001 /* original minix fs */
#define MINIX_V2 0x0002 /* minix V2 fs */
/*
* This is the original minix inode layout on disk.
* Note the 8-bit gid and atime and ctime.
*/
struct minix_inode {
unsigned short int i_mode;
unsigned short int i_uid;
unsigned long i_size;
unsigned long i_time;
unsigned char i_gid;
unsigned char i_nlinks;
unsigned short int i_zone[9];
};
/*
* The new minix inode has all the time entries, as well as
* long block numbers and a third indirect block (7+1+1+1
* instead of 7+1+1). Also, some previously 8-bit values are
* now 16-bit. The inode is now 64 bytes instead of 32.
*/
struct minix2_inode {
unsigned short int i_mode;
unsigned short int i_nlinks;
unsigned short int i_uid;
unsigned short int i_gid;
unsigned long i_size;
unsigned long i_atime;
unsigned long i_mtime;
unsigned long i_ctime;
unsigned long i_zone[10];
};
/*
* minix super-block data on disk
*/
struct minix_super_block {
unsigned short int s_ninodes;
unsigned short int s_nzones;
unsigned short int s_imap_blocks;
unsigned short int s_zmap_blocks;
unsigned short int s_firstdatazone;
unsigned short int s_log_zone_size;
unsigned long s_max_size;
unsigned short int s_magic;
unsigned short int s_state;
unsigned long s_zones;
};
struct minix_dir_entry {
unsigned short int inode;
char name[0];
};
#define MINIX_DIR_ENTRY_SIZE (sizeof(struct minix_dir_entry)+30)
BOOLEAN MinixReadSector(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN UCHAR* Buffer);
BOOLEAN MinixWriteSector(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN UCHAR* Buffer);
#define BLOCKSIZE (1024)
//extern PDRIVER_OBJECT DriverObject;
typedef struct
{
PDEVICE_OBJECT AttachedDevice;
struct minix_inode root_inode;
char superblock_buf[BLOCKSIZE];
struct minix_super_block* sb;
DCCB Dccb;
} MINIX_DEVICE_EXTENSION, *PMINIX_DEVICE_EXTENSION;
NTSTATUS MinixCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MinixClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MinixWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS MinixRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
ULONG MinixNewInode(PDEVICE_OBJECT Volume,
MINIX_DEVICE_EXTENSION* DeviceExt,
struct minix_inode* new_inode);
NTSTATUS MinixWriteInode(PDEVICE_OBJECT Volume,
MINIX_DEVICE_EXTENSION* DeviceExt,
ULONG ino,
struct minix_inode* result);
NTSTATUS MinixReadInode(PDEVICE_OBJECT DeviceObject,
MINIX_DEVICE_EXTENSION* DeviceExt,
ULONG ino,
struct minix_inode* result);
NTSTATUS MinixDeleteInode(PDEVICE_OBJECT Volume,
MINIX_DEVICE_EXTENSION* DeviceExt,
ULONG ino);
NTSTATUS MinixReadBlock(PMINIX_DEVICE_EXTENSION DeviceExt,
struct minix_inode* inode,
int blk,
PCCB* Ccb);

View File

@@ -1,156 +0,0 @@
U _CbAcquireForRead
U _CbInitDccb
U _CbReleaseFromRead
U _DbgPrint
U _ExAllocatePool
U _ExFreePool
U _IoAttachDeviceToDeviceStack
U _IoBuildSynchronousFsdRequest
U _IoCallDriver
U _IoCompleteRequest
U _IoCreateDevice
U _IoGetCurrentIrpStackLocation
U _IoRegisterFileSystem
U _KeInitializeEvent
U _KeWaitForSingleObject
U _MmGetSystemAddressForMdl
U _RtlAnsiStringToUnicodeString
U _RtlCopyMemory
U _RtlInitAnsiString
U _wcschr
00000000 t .text
00000000 t LC0
00000000 t ___gnu_compiled_c
00000000 t gcc2_compiled.
00000008 t LC1
00000011 t LC2
00000022 T _MinixCheckPoint
0000004b t LC3
0000006c t _MinixGetBlock
000000b0 t L147
0000010a t L148
00000124 t L151
0000012b t L150
00000135 t LC4
00000143 t LC5
0000014d t LC6
00000155 t LC7
0000015d t LC8
00000196 T _MinixReadBlock
0000029c t .text
0000029c t LC0
0000029c t ___gnu_compiled_c
0000029c t gcc2_compiled.
000002a1 t LC1
000002aa t LC2
000002ce T _MinixWrite
00000319 t LC3
0000033d t LC4
0000035c t LC5
00000363 t LC6
00000388 t LC7
00000393 t LC8
000003ba T _MinixRead
00000492 t L151
000004a2 t L152
00000508 t L181
0000059e t L191
000005d1 t L153
000005d6 t L199
00000635 t L257
000006a1 t L228
000006bb t L256
000006c4 t .text
000006c4 T _MinixDeleteInode
000006c4 t ___gnu_compiled_c
000006c4 t gcc2_compiled.
0000071a t _MinixAllocateInode
00000778 t L167
000007c2 t L166
000007de t L165
000007e6 t L173
000007ee T _MinixNewInode
0000081a t L175
0000081c t L176
00000824 T _MinixWriteInode
000008a2 T _MinixReadInode
0000090c t .text
0000090c T _MinixCompareUnicodeStringToAnsi
0000090c t ___gnu_compiled_c
0000090c t gcc2_compiled.
00000920 t L140
00000936 t L141
0000093f t L142
0000094b t L139
00000950 t L144
00000958 t LC0
0000095e t LC1
00000967 t LC2
00000996 t LC3
0000099d t LC4
000009b2 t LC5
000009ca T _MinixDirLookup
00000a26 t L153
00000aa3 t L163
00000ad8 t L158
00000b68 t L152
00000b80 t L151
00000bb6 t L186
00000bde t L191
00000be6 t LC6
00000c1c t LC7
00000c2b t LC8
00000c3f t LC9
00000c5c T _MinixOpen
00000cc0 t L206
00000d26 t L205
00000d3d t L198
00000d43 t L237
00000d5c t L207
00000d6c t L208
00000da7 t L236
00000daf t LC10
00000dd4 T _MinixClose
00000e40 t LC11
00000e66 t LC12
00000e7a t LC13
00000e9a t LC14
00000ea6 T _MinixCreate
00000fa7 t L260
00000fc8 t .text
00000fc8 T _MinixMount
00000fc8 t ___gnu_compiled_c
00000fc8 t gcc2_compiled.
0000103b t LC0
0000106c T _MinixFileSystemControl
000010bc t L139
000010c1 t L140
000010e2 t LC1
000010f3 t LC2
00001102 T _DriverEntry
000011b1 t L142
000011b8 t .text
000011b8 T _MinixReadSector
000011b8 t ___gnu_compiled_c
000011b8 t gcc2_compiled.
00001232 t L140
00001252 t L141
00001258 t L143
0000125a t L142
00001262 T _MinixWriteSector
000012c3 t L145
000012ce t L146
000012d0 t L147
00002000 b .bss
00002000 b .bss
00002000 b .bss
00002000 b .bss
00002000 b .bss
00002000 d .data
00002000 d .data
00002000 d .data
00002000 d .data
00002000 d .data
00002000 d .data
00002000 b _DriverObject
00002004 b .bss

View File

@@ -1,131 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/minix/minix.c
* PURPOSE: Minix FSD
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <ddk/ntifs.h>
#define NDEBUG
#include <internal/debug.h>
#include "minix.h"
/* GLOBALS *******************************************************************/
static PDRIVER_OBJECT DriverObject;
/* FUNCTIONS ****************************************************************/
VOID MinixMount(PDEVICE_OBJECT DeviceToMount)
{
PDEVICE_OBJECT DeviceObject;
MINIX_DEVICE_EXTENSION* DeviceExt;
IoCreateDevice(DriverObject,
sizeof(MINIX_DEVICE_EXTENSION),
NULL,
FILE_DEVICE_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
DeviceExt = DeviceObject->DeviceExtension;
MinixReadSector(DeviceToMount,1,DeviceExt->superblock_buf);
DeviceExt->sb = (struct minix_super_block *)(DeviceExt->superblock_buf);
DeviceExt->AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject,
DeviceToMount);
CbInitDccb(&DeviceExt->Dccb,DeviceExt->AttachedDevice,
BLOCKSIZE,2880,10);
}
NTSTATUS MinixFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PVPB vpb = Stack->Parameters.Mount.Vpb;
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
NTSTATUS Status;
char* superblock_buf;
struct minix_super_block* sb;
DbgPrint("MinixFileSystemControl(DeviceObject %x, Irp %x)\n",DeviceObject,
Irp);
DPRINT("DeviceToMount %x\n",DeviceToMount);
superblock_buf = ExAllocatePool(NonPagedPool,BLOCKSIZE);
DPRINT("MinixReadSector %x\n",MinixReadSector);
MinixReadSector(DeviceToMount,1,superblock_buf);
sb = (struct minix_super_block *)superblock_buf;
DPRINT("Magic %x\n",sb->s_magic);
DPRINT("Imap blocks %x\n",sb->s_imap_blocks);
DPRINT("Zmap blocks %x\n",sb->s_zmap_blocks);
if (sb->s_magic==MINIX_SUPER_MAGIC2)
{
DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__);
MinixMount(DeviceToMount);
Status = STATUS_SUCCESS;
}
else
{
DPRINT("%s() = STATUS_UNRECOGNIZED_VOLUME\n",__FUNCTION__);
Status = STATUS_UNRECOGNIZED_VOLUME;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS ret;
UNICODE_STRING ustr;
ANSI_STRING astr;
DbgPrint("Minix FSD 0.0.1\n");
DriverObject = _DriverObject;
RtlInitAnsiString(&astr,"\\Device\\Minix");
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
ret = IoCreateDevice(DriverObject,0,&ustr,
FILE_DEVICE_PARALLEL_PORT,0,FALSE,&DeviceObject);
if (ret!=STATUS_SUCCESS)
{
return(ret);
}
DeviceObject->Flags=0;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MinixClose;
DriverObject->MajorFunction[IRP_MJ_CREATE] = MinixCreate;
DriverObject->MajorFunction[IRP_MJ_READ] = MinixRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = MinixWrite;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
MinixFileSystemControl;
DriverObject->DriverUnload = NULL;
IoRegisterFileSystem(DeviceObject);
return(STATUS_SUCCESS);
}

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