mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 00:20:34 +00:00
Lots of changes to the kernel
svn path=/trunk/; revision=527
This commit is contained in:
parent
0deeaa0d83
commit
126768af64
102 changed files with 3114 additions and 1377 deletions
340
reactos/COPYING
Normal file
340
reactos/COPYING
Normal 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.
|
11
reactos/CREDITS
Normal file
11
reactos/CREDITS
Normal file
|
@ -0,0 +1,11 @@
|
|||
In no particular order
|
||||
|
||||
Rex Jolliff (rex@lvcablemodem.com)
|
||||
Boudewijn Dekker (ariadne@xs4all.nl)
|
||||
Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
||||
Emanuele Aliberti (ea@iol.it)
|
||||
David Welch (welch@cwcom.net)
|
||||
Iwan Fatahi (i_fatahi@hotmail.com)
|
||||
Robert Bergkvist (fragdance@hotmail.com)
|
||||
Victor Kirhenshtein (sauros@iname.com)
|
||||
Jason Filby (jasonfilby@yahoo.com)
|
27
reactos/INSTALL
Normal file
27
reactos/INSTALL
Normal file
|
@ -0,0 +1,27 @@
|
|||
1. Build environment
|
||||
|
||||
To build the system you need either mingw32 installed on Windows or a
|
||||
mingw32 cross compiler running on unix.
|
||||
|
||||
2. Building
|
||||
|
||||
To build from Windows run 'make -fmakefile.dos'. To build from unix, edit
|
||||
rules.mak and change the PREFIX variable to the correct value for your
|
||||
cross-compiler, then run 'make'.
|
||||
|
||||
3. Installation
|
||||
|
||||
Installation isn't yet automated, sorry. The system can only be installed on
|
||||
the first partition which must be formatted for DOS. Set up a directory
|
||||
structure like the following
|
||||
|
||||
make directories C:\reactos,C:\reactos\system,C:\reactos\system\drivers
|
||||
|
||||
Copy apps/shell/shell.exe to C:\reactos\system
|
||||
Copy services/dd/keyboard/keyboard.sys to C:\reactos\system\drivers
|
||||
Copy services/dd/blue/blue.sys to C:\reactos\system\drivers
|
||||
|
||||
The system can only be started from DOS. Copy the following files,
|
||||
services/dd/ide/ide.sys, services/fs/vfat/vfatfsd.sys and
|
||||
loaders/dos/loadros.com, to a suitable directory. The system can then be
|
||||
booted with the command 'loadros.com ide.sys vfatfsd.sys'.
|
24
reactos/README
Normal file
24
reactos/README
Normal file
|
@ -0,0 +1,24 @@
|
|||
About Reactos
|
||||
|
||||
1. What is Reactos
|
||||
|
||||
A project aiming to make an approximate clone of Windows NT, compatible
|
||||
with most Windows applications.
|
||||
|
||||
The project has a website at http://www.sid-dis.com/reactos
|
||||
|
||||
2. Building Reactos
|
||||
|
||||
See the INSTALL file for more details.
|
||||
|
||||
3. More information
|
||||
|
||||
See the doc subdirectory for some sparse notes
|
||||
|
||||
4. Who is responsible
|
||||
|
||||
See the CREDITS file
|
||||
|
||||
5. Recent developments
|
||||
|
||||
See the NEWS file
|
|
@ -25,7 +25,8 @@ void main(int argc, char* argv[])
|
|||
AllocConsole();
|
||||
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
|
||||
printf("GetCommandLineA() %s\n",GetCommandLineA());
|
||||
debug_printf("GetCommandLineA() %s\n",GetCommandLineA());
|
||||
for (i=0; i<argc; i++)
|
||||
{
|
||||
|
|
8
reactos/apps/tests/bench/bench-syscall.c
Normal file
8
reactos/apps/tests/bench/bench-syscall.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
}
|
36
reactos/doc/apc
Normal file
36
reactos/doc/apc
Normal file
|
@ -0,0 +1,36 @@
|
|||
APC
|
||||
|
||||
Asynchronous procedure call
|
||||
|
||||
An APC is a Kernel-defined control object representing a procedure
|
||||
that is called asynchronously. APCs are thread-context dependent; that
|
||||
is, they are queued to a particular thread for execution.
|
||||
|
||||
There are three different kinds of APCs in NT:
|
||||
|
||||
User APCs are used by certain asynchronous NT system services to allow
|
||||
user-mode applications or protected subsystems to synchronize the
|
||||
execution of a thread with the completion of an operation or the
|
||||
occurrence of an event such as a timers expiration. User APCs are, by
|
||||
default, disabled. That is, they are queued to the user-mode thread,
|
||||
but they are not executed except at well-defined points in the
|
||||
program. Specifically, they can only be executed when an application
|
||||
or protected subsystem has called a wait service and has enabled
|
||||
alerts to occur, or if it has called the test-alert service.
|
||||
|
||||
Kernel APCs are normal kernel-mode APCs. They are much like a normal
|
||||
user APC except that they are executable by default. That is, they are
|
||||
enabled except when the thread is already executing a Kernel APC.
|
||||
(Note that a special Kernel APC always preempts these.)
|
||||
|
||||
Special Kernel APCs cannot be blocked except by running at a raised
|
||||
IRQL. They are executed at APC_LEVEL IRQL (see IDT), in kernel mode.
|
||||
These types of APCs are used by the system to force a thread to
|
||||
execute a procedure in the threads context. An example of this is I/O
|
||||
completion: the I/O Manager needs to get back into the context of the
|
||||
original requestor of the I/O operation so that it can copy buffers,
|
||||
and so forth. In order to do this, the I/O Manager must be able to
|
||||
access the virtual address space of the thread/process, and the most
|
||||
efficient way to complete the operation is to be in the calling
|
||||
threads context.
|
||||
|
|
@ -1,24 +1,13 @@
|
|||
/*
|
||||
** 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
|
||||
**
|
||||
*/
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/dd/keyboard/keyboard.c
|
||||
* PURPOSE: Keyboard driver
|
||||
* PROGRAMMER: Victor Kirhenshtein (sauros@iname.com)
|
||||
* Jason Filby (jasonfilby@yahoo.com);
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/mmhal.h>
|
||||
|
@ -32,6 +21,8 @@
|
|||
|
||||
#include "keyboard.h"
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/*
|
||||
* Driver data
|
||||
*/
|
||||
|
@ -43,7 +34,6 @@ static int extKey;
|
|||
static BYTE ledStatus;
|
||||
static BYTE capsDown,numDown,scrollDown;
|
||||
static DWORD ctrlKeyState;
|
||||
static KSPIN_LOCK kbdBufferLock;
|
||||
static PKINTERRUPT KbdInterrupt;
|
||||
static KDPC KbdDpc;
|
||||
|
||||
|
@ -119,12 +109,12 @@ static const BYTE asciiTable4[37]=
|
|||
'{', '|', '}', '"'
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Write data to keyboard
|
||||
*/
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static void KbdWrite(int addr,BYTE data)
|
||||
/*
|
||||
* FUNCTION: Write data to keyboard
|
||||
*/
|
||||
{
|
||||
BYTE status;
|
||||
|
||||
|
@ -135,12 +125,10 @@ static void KbdWrite(int addr,BYTE data)
|
|||
outb_p(addr,data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read data from port 0x60
|
||||
*/
|
||||
|
||||
static int KbdReadData(void)
|
||||
/*
|
||||
* FUNCTION: Read data from port 0x60
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
BYTE status,data;
|
||||
|
@ -371,7 +359,7 @@ static BYTE VirtualToAscii(WORD keyCode,BOOL isDown)
|
|||
return asciiTable2[keyCode-VK_NUMPAD0];
|
||||
|
||||
if ((keyCode>=186)&&(keyCode<=222))
|
||||
{
|
||||
{
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return asciiTable4[keyCode-186];
|
||||
else
|
||||
|
@ -525,7 +513,7 @@ static BOOLEAN KeyboardHandler(PKINTERRUPT Interrupt, PVOID Context)
|
|||
if (keysInBuffer==KBD_BUFFER_SIZE) // Buffer is full
|
||||
{
|
||||
extKey=0;
|
||||
return FALSE;
|
||||
return(TRUE);
|
||||
}
|
||||
kbdBuffer[bufHead].bKeyDown=isDown;
|
||||
kbdBuffer[bufHead].wRepeatCount=1;
|
||||
|
@ -541,7 +529,6 @@ static BOOLEAN KeyboardHandler(PKINTERRUPT Interrupt, PVOID Context)
|
|||
bufHead&=KBD_WRAP_MASK; // Modulo KBD_BUFFER_SIZE
|
||||
keysInBuffer++;
|
||||
extKey=0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -593,16 +580,13 @@ static int InitializeKeyboard(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read data from keyboard buffer
|
||||
*/
|
||||
|
||||
BOOLEAN KbdSynchronizeRoutine(PVOID Context)
|
||||
{
|
||||
PIRP Irp = (PIRP)Context;
|
||||
KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)
|
||||
Irp->AssociatedIrp.SystemBuffer;
|
||||
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;
|
||||
|
@ -634,7 +618,9 @@ BOOLEAN KbdSynchronizeRoutine(PVOID Context)
|
|||
|
||||
VOID KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
#endif
|
||||
|
||||
DPRINT("KeyboardStartIo(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
|
@ -691,18 +677,16 @@ NTSTATUS KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||
PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
* Module entry point
|
||||
* FUNCTION: 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;
|
||||
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING SymlinkName;
|
||||
|
||||
DbgPrint("Keyboard Driver 0.0.4\n");
|
||||
InitializeKeyboard();
|
||||
|
||||
|
@ -710,16 +694,19 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
|||
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);
|
||||
|
||||
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\Keyboard");
|
||||
IoCreateDevice(DriverObject,
|
||||
0,
|
||||
&DeviceName,
|
||||
FILE_DEVICE_KEYBOARD,
|
||||
0,
|
||||
TRUE,
|
||||
&DeviceObject);
|
||||
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
|
||||
|
||||
RtlInitUnicodeString(&SymlinkName, L"\\??\\Keyboard");
|
||||
IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
125
reactos/drivers/fs/ext2/attr.c
Normal file
125
reactos/drivers/fs/ext2/attr.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/ext2/attr.c
|
||||
* PURPOSE: Set/Get file attributes support
|
||||
* 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 ****************************************************************/
|
||||
|
||||
NTSTATUS Ext2SetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
DPRINT("Ext2SetInformation(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
NTSTATUS Ext2QueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION Param;
|
||||
PFILE_OBJECT FileObject;
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
ULONG Length;
|
||||
PFILE_BASIC_INFORMATION PFileBasicInformation;
|
||||
PFILE_STANDARD_INFORMATION PFileStandardInformation;
|
||||
PFILE_INTERNAL_INFORMATION PFileInternalInformation;
|
||||
PFILE_EA_INFORMATION PFileEaInformation;
|
||||
PFILE_ACCESS_INFORMATION PFileAccessInformation;
|
||||
PFILE_NAME_INFORMATION PFileNameInformation;
|
||||
PFILE_POSITION_INFORMATION PFilePositionInformation;
|
||||
PVOID Buffer;
|
||||
|
||||
DPRINT("Ext2QueryInformation(DeviceObject %x Irp %x)\n", DeviceObject, Irp);
|
||||
|
||||
Param = IoGetCurrentIrpStackLocation(Irp);
|
||||
FileObject = Param->FileObject;
|
||||
DeviceExt = DeviceObject->DeviceExtension;
|
||||
Length = Param->Parameters.QueryFile.Length;
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
|
||||
switch (Param->Parameters.QueryFile.FileInformationClass)
|
||||
{
|
||||
case FileDirectoryInformation:
|
||||
case FileFullDirectoryInformation:
|
||||
case FileBothDirectoryInformation:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FileBasicInformation:
|
||||
PFileBasicInformation = (PFILE_BASIC_INFORMATION)Buffer;
|
||||
memset(PFileBasicInformation, 0, sizeof(FILE_BASIC_INFORMATION));
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FileStandardInformation:
|
||||
PFileStandardInformation = (PFILE_STANDARD_INFORMATION)Buffer;
|
||||
memset(PFileStandardInformation, 0, sizeof(FILE_STANDARD_INFORMATION));
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FileInternalInformation:
|
||||
PFileInternalInformation = (PFILE_INTERNAL_INFORMATION)Buffer;
|
||||
memset(PFileInternalInformation, 0, sizeof(FILE_INTERNAL_INFORMATION));
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FileEaInformation:
|
||||
PFileEaInformation = (PFILE_EA_INFORMATION)Buffer;
|
||||
memset(PFileEaInformation, 0, sizeof(FILE_EA_INFORMATION));
|
||||
PFileEaInformation->EaSize = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FileAccessInformation:
|
||||
PFileAccessInformation = (PFILE_ACCESS_INFORMATION)Buffer;
|
||||
memset(PFileAccessInformation, 0, sizeof(FILE_ACCESS_INFORMATION));
|
||||
PFileAccessInformation->AccessFlags = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FileNameInformation:
|
||||
PFileNameInformation = (PFILE_NAME_INFORMATION)Buffer;
|
||||
memset(PFileNameInformation, 0, sizeof(FILE_NAME_INFORMATION));
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FilePositionInformation:
|
||||
PFilePositionInformation = (PFILE_POSITION_INFORMATION)Buffer;
|
||||
memcpy(PFilePositionInformation,
|
||||
&FileObject->CurrentByteOffset,
|
||||
sizeof(FileObject->CurrentByteOffset));
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case FileRenameInformation:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/vfat/blockdev.c
|
||||
* FILE: services/fs/ext2/blockdev.c
|
||||
* PURPOSE: Temporary sector reading support
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
|||
#include <string.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#include "ext2fs.h"
|
||||
|
@ -42,8 +42,8 @@ BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
|||
DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
|
||||
(unsigned long) DiskSector,
|
||||
(unsigned long) BLOCKSIZE,
|
||||
(unsigned long) sectorNumber.HighPart,
|
||||
(unsigned long) sectorNumber.LowPart);
|
||||
(unsigned long) sectorNumber.u.HighPart,
|
||||
(unsigned long) sectorNumber.u.LowPart);
|
||||
|
||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
||||
|
||||
|
@ -59,17 +59,18 @@ BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
|||
&event,
|
||||
&ioStatus );
|
||||
|
||||
if (!irp) {
|
||||
if (!irp)
|
||||
{
|
||||
DbgPrint("READ failed!!!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DPRINT("Calling IO Driver...\n");
|
||||
status = IoCallDriver(pDeviceObject,
|
||||
irp);
|
||||
status = IoCallDriver(pDeviceObject, irp);
|
||||
|
||||
DPRINT("Waiting for IO Operation...\n");
|
||||
if (status == STATUS_PENDING) {
|
||||
if (status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&event,
|
||||
Suspended,
|
||||
KernelMode,
|
||||
|
@ -77,14 +78,15 @@ BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
|||
NULL);
|
||||
DPRINT("Getting IO Status...\n");
|
||||
status = ioStatus.Status;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||
|
|
|
@ -13,14 +13,15 @@
|
|||
#include <wchar.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#include "ext2fs.h"
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len)
|
||||
|
||||
static VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
|
@ -42,8 +43,6 @@ PVOID Ext2ProcessDirEntry(PDEVICE_EXTENSION DeviceExt,
|
|||
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);
|
||||
|
@ -108,13 +107,11 @@ NTSTATUS Ext2QueryDirectory(PDEVICE_EXTENSION DeviceExt,
|
|||
ULONG Max;
|
||||
ULONG i;
|
||||
ULONG StartIndex;
|
||||
PVOID Buffer;
|
||||
PVOID Buffer = NULL;
|
||||
struct ext2_dir_entry dir_entry;
|
||||
ULONG CurrentIndex;
|
||||
|
||||
DPRINT("Buffer %x\n",Buffer);
|
||||
|
||||
Buffer = Irp->UserBuffer;
|
||||
DPRINT("Buffer %x\n",Buffer);
|
||||
DPRINT("IoStack->Flags %x\n",IoStack->Flags);
|
||||
|
||||
if (IoStack->Flags & SL_RETURN_SINGLE_ENTRY)
|
||||
|
@ -201,6 +198,7 @@ BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,
|
|||
char name[255];
|
||||
struct ext2_dir_entry* current;
|
||||
ULONG block;
|
||||
BOOL b;
|
||||
|
||||
DPRINT("Ext2ScanDir(dir %x, filename %s, ret %x)\n",dir,filename,ret);
|
||||
|
||||
|
@ -210,10 +208,15 @@ BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,
|
|||
for (; (block = Ext2BlockMap(DeviceExt, dir, i)) != 0; i++)
|
||||
{
|
||||
DPRINT("block %d\n",block);
|
||||
Ext2ReadSectors(DeviceExt->StorageDevice,
|
||||
block,
|
||||
1,
|
||||
buffer);
|
||||
b = Ext2ReadSectors(DeviceExt->StorageDevice,
|
||||
block,
|
||||
1,
|
||||
buffer);
|
||||
if (!b)
|
||||
{
|
||||
DbgPrint("ext2fs:%s:%d: Disk io failed\n", __FILE__, __LINE__);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
offset = (*StartIndex)%BLOCKSIZE;
|
||||
while (offset < BLOCKSIZE)
|
||||
|
@ -264,7 +267,7 @@ NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
* FUNCTION: Opens a file
|
||||
*/
|
||||
{
|
||||
struct ext2_inode parent_inode;
|
||||
EXT2_INODE parent_inode;
|
||||
struct ext2_dir_entry entry;
|
||||
char name[255];
|
||||
ULONG current_inode = 2;
|
||||
|
@ -279,28 +282,35 @@ NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
|
||||
unicode_to_ansi(name,FileName);
|
||||
DPRINT("name %s\n",name);
|
||||
|
||||
DPRINT("strtok %x\n",strtok);
|
||||
current_segment = strtok(name,"\\");
|
||||
DPRINT("current_segment %x\n", current_segment);
|
||||
while (current_segment!=NULL)
|
||||
{
|
||||
Ext2ReadInode(DeviceExt,
|
||||
Ext2LoadInode(DeviceExt,
|
||||
current_inode,
|
||||
&parent_inode);
|
||||
if (!Ext2ScanDir(DeviceExt,&parent_inode,current_segment,&entry,
|
||||
if (!Ext2ScanDir(DeviceExt,
|
||||
parent_inode.inode,
|
||||
current_segment,
|
||||
&entry,
|
||||
&StartIndex))
|
||||
{
|
||||
Ext2ReleaseInode(DeviceExt,
|
||||
&parent_inode);
|
||||
ExFreePool(Fcb);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
current_inode = entry.inode;
|
||||
current_segment = strtok(NULL,"\\");
|
||||
StartIndex = 0;
|
||||
Ext2ReleaseInode(DeviceExt,
|
||||
&parent_inode);
|
||||
}
|
||||
DPRINT("Found file\n");
|
||||
|
||||
Ext2ReadInode(DeviceExt,
|
||||
current_inode,
|
||||
&Fcb->inode);
|
||||
Fcb->inode = current_inode;
|
||||
CcInitializeFileCache(FileObject, &Fcb->Bcb);
|
||||
FileObject->FsContext = Fcb;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <ddk/ntifs.h>
|
||||
|
||||
BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG SectorCount,
|
||||
|
@ -214,8 +216,22 @@ typedef struct
|
|||
{
|
||||
PDEVICE_OBJECT StorageDevice;
|
||||
struct ext2_super_block* superblock;
|
||||
PFILE_OBJECT FileObject;
|
||||
PBCB Bcb;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
typedef struct _EXT2_GROUP_DESC
|
||||
{
|
||||
ERESOURCE Lock;
|
||||
struct ext2_group_desc* desc;
|
||||
PCACHE_SEGMENT CacheSeg;
|
||||
PVOID BaseAddress;
|
||||
} EXT2_GROUP_DESC, *PEXT2_GROUP_DESC;
|
||||
|
||||
PEXT2_GROUP_DESC Ext2LoadGroup(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG BlockGrp);
|
||||
VOID Ext2ReleaseGroup(PDEVICE_EXTENSION DeviceExt,
|
||||
PEXT2_GROUP_DESC GrpDesc);
|
||||
|
||||
VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ino,
|
||||
|
@ -223,14 +239,23 @@ VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
|
|||
struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG block_group);
|
||||
|
||||
typedef struct _EXT2_INODE
|
||||
{
|
||||
struct ext2_inode* inode;
|
||||
PVOID BaseAddress;
|
||||
PCACHE_SEGMENT CacheSeg;
|
||||
} EXT2_INODE, *PEXT2_INODE;
|
||||
|
||||
typedef struct _EXT2_FCB
|
||||
{
|
||||
struct ext2_inode inode;
|
||||
ULONG inode;
|
||||
EXT2_INODE i;
|
||||
PBCB Bcb;
|
||||
} EXT2_FCB, *PEXT2_FCB;
|
||||
|
||||
ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,
|
||||
struct ext2_inode* inode,
|
||||
ULONG offset);
|
||||
struct ext2_inode* inode,
|
||||
ULONG offset);
|
||||
NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||
PWSTR FileName);
|
||||
NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
|
||||
|
@ -240,3 +265,24 @@ NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
|
|||
LARGE_INTEGER Offset);
|
||||
NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2QueryQuota(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2SetQuota(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2SetSecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2QuerySecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2SetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2QueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2Cleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2FlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2Shutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS Ext2ReadPage(PDEVICE_EXTENSION DeviceExt,
|
||||
PEXT2_FCB Fcb,
|
||||
PVOID Buffer,
|
||||
ULONG Offset);
|
||||
VOID Ext2LoadInode(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ino,
|
||||
PEXT2_INODE Inode);
|
||||
VOID Ext2ReleaseInode(PDEVICE_EXTENSION DeviceExt,
|
||||
PEXT2_INODE Inode);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,
|
|||
{
|
||||
ULONG block;
|
||||
PULONG TempBuffer;
|
||||
BOOL b;
|
||||
|
||||
DPRINT("Ext2BlockMap(DeviceExt %x, inode %x, offset %d)\n",
|
||||
DeviceExt,inode,offset);
|
||||
|
@ -40,14 +41,21 @@ ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,
|
|||
{
|
||||
block = inode->i_block[EXT2_IND_BLOCK];
|
||||
TempBuffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
|
||||
Ext2ReadSectors(DeviceExt->StorageDevice,
|
||||
block,
|
||||
1,
|
||||
TempBuffer);
|
||||
b = Ext2ReadSectors(DeviceExt->StorageDevice,
|
||||
block,
|
||||
1,
|
||||
TempBuffer);
|
||||
if (!b)
|
||||
{
|
||||
DbgPrint("ext2fs:%s:%d: Disk io failed\n", __FILE__, __LINE__);
|
||||
return(0);
|
||||
}
|
||||
block = TempBuffer[offset];
|
||||
ExFreePool(TempBuffer);
|
||||
return(block);
|
||||
}
|
||||
offset = offset - addr_per_block;
|
||||
DbgPrint("Failed at %s:%d\n",__FILE__,__LINE__);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <string.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#include "ext2fs.h"
|
||||
|
@ -45,8 +46,76 @@ struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
|
|||
|
||||
}
|
||||
|
||||
#define INODES_PER_PAGE (PAGESIZE / sizeof(struct ext2_inode))
|
||||
#define INODES_PER_BLOCK (BLOCKSIZE / sizeof(struct ext2_inode))
|
||||
|
||||
VOID Ext2LoadInode(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ino,
|
||||
PEXT2_INODE Inode)
|
||||
{
|
||||
ULONG block_group;
|
||||
struct ext2_group_desc* gdp;
|
||||
ULONG offset;
|
||||
ULONG dsec;
|
||||
BOOLEAN Uptodate;
|
||||
struct ext2_inode* ibuffer;
|
||||
|
||||
DPRINT("Ext2LoadInode(DeviceExt %x, ino %d, Inode %x)\n",
|
||||
DeviceExt, ino, Inode);
|
||||
|
||||
block_group = (ino - 1) / DeviceExt->superblock->s_inodes_per_group;
|
||||
|
||||
DPRINT("block_group %d\n",block_group);
|
||||
|
||||
gdp = Ext2LoadGroupDesc(DeviceExt, block_group);
|
||||
|
||||
offset = (ino - 1) % DeviceExt->superblock->s_inodes_per_group;
|
||||
|
||||
DPRINT("offset %d\n", offset);
|
||||
|
||||
dsec = (gdp->bg_inode_table + (offset / INODES_PER_BLOCK)) * BLOCKSIZE;
|
||||
|
||||
DPRINT("dsec %d (dsec/BLOCKSIZE) %d PAGE_ROUND_DOWN(dsec) %d\n",
|
||||
dsec, (dsec/BLOCKSIZE), PAGE_ROUND_DOWN(dsec));
|
||||
|
||||
CcRequestCachePage(DeviceExt->Bcb,
|
||||
PAGE_ROUND_DOWN(dsec),
|
||||
&Inode->BaseAddress,
|
||||
&Uptodate,
|
||||
&Inode->CacheSeg);
|
||||
DPRINT("PAGE_ROUND_DOWN(dsec)/BLOCKSIZE %d\n",
|
||||
PAGE_ROUND_DOWN(dsec)/BLOCKSIZE);
|
||||
if (!Uptodate)
|
||||
{
|
||||
Ext2ReadSectors(DeviceExt->StorageDevice,
|
||||
PAGE_ROUND_DOWN(dsec) / BLOCKSIZE,
|
||||
4,
|
||||
Inode->BaseAddress);
|
||||
}
|
||||
ibuffer = ((struct ext2_inode *)Inode->BaseAddress) +
|
||||
(dsec - PAGE_ROUND_DOWN(dsec));
|
||||
DPRINT("Inode->BaseAddress 0x%x ibuffer 0x%x\n",
|
||||
Inode->BaseAddress, ibuffer);
|
||||
Inode->inode = &ibuffer[offset % INODES_PER_PAGE];
|
||||
|
||||
DPRINT("inode->i_uid %d\n",Inode->inode->i_uid);
|
||||
DPRINT("inode->i_links_count %d\n",Inode->inode->i_links_count);
|
||||
DPRINT("inode->i_blocks %d\n",Inode->inode->i_blocks);
|
||||
|
||||
DPRINT("Ext2LoadInode() finished\n");
|
||||
}
|
||||
|
||||
VOID Ext2ReleaseInode(PDEVICE_EXTENSION DeviceExt,
|
||||
PEXT2_INODE Inode)
|
||||
{
|
||||
CcReleaseCachePage(DeviceExt->Bcb,
|
||||
Inode->CacheSeg,
|
||||
TRUE);
|
||||
Inode->CacheSeg = NULL;
|
||||
Inode->BaseAddress = NULL;
|
||||
Inode->inode = NULL;
|
||||
}
|
||||
|
||||
VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
|
||||
ULONG ino,
|
||||
struct ext2_inode* inode)
|
||||
|
@ -77,4 +146,5 @@ VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
|
|||
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);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
#
|
||||
#
|
||||
OBJECTS = super.o blockdev.o inode.o file.o dir.o rw.o \
|
||||
../../../ntoskrnl/ntoskrnl.a
|
||||
OBJECTS = super.o blockdev.o inode.o file.o dir.o rw.o quota.o security.o \
|
||||
attr.o ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
all: ext2fs.sys
|
||||
|
||||
|
|
47
reactos/drivers/fs/ext2/quota.c
Normal file
47
reactos/drivers/fs/ext2/quota.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/ext2/quota.c
|
||||
* PURPOSE: Quota support
|
||||
* 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"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS Ext2QueryQuota(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS Ext2SetQuota(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return(Status);
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -18,77 +19,196 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS Ext2ReadPage(PDEVICE_EXTENSION DeviceExt,
|
||||
PEXT2_FCB Fcb,
|
||||
PVOID Buffer,
|
||||
ULONG Offset)
|
||||
{
|
||||
ULONG block, i;
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
block = Ext2BlockMap(DeviceExt,
|
||||
Fcb->i.inode,
|
||||
Offset + i);
|
||||
Ext2ReadSectors(DeviceExt->StorageDevice,
|
||||
block,
|
||||
1,
|
||||
Buffer + (i*BLOCKSIZE));
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_OBJECT FileObject,
|
||||
PVOID Buffer,
|
||||
ULONG Length,
|
||||
LARGE_INTEGER OffsetL)
|
||||
/*
|
||||
* FUNCTION: Reads data from a file
|
||||
*/
|
||||
{
|
||||
PVOID BaseAddress;
|
||||
BOOLEAN Uptodate = FALSE;
|
||||
PCACHE_SEGMENT CacheSeg;
|
||||
ULONG Offset = (ULONG)OffsetL.u.LowPart;
|
||||
PEXT2_FCB Fcb;
|
||||
PVOID TempBuffer;
|
||||
ULONG Offset = OffsetL.u.LowPart;
|
||||
ULONG block;
|
||||
ULONG Delta;
|
||||
ULONG i;
|
||||
|
||||
ULONG block, i, Delta;
|
||||
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);
|
||||
|
||||
Ext2LoadInode(DeviceExt,
|
||||
Fcb->inode,
|
||||
&Fcb->i);
|
||||
|
||||
if (Offset >= Fcb->inode.i_size)
|
||||
if (Offset >= Fcb->i.inode->i_size)
|
||||
{
|
||||
ExFreePool(TempBuffer);
|
||||
DPRINT("Returning end of file\n");
|
||||
return(STATUS_END_OF_FILE);
|
||||
}
|
||||
if ((Offset + Length) > Fcb->inode.i_size)
|
||||
if ((Offset + Length) > Fcb->i.inode->i_size)
|
||||
{
|
||||
Length = Fcb->inode.i_size - Offset;
|
||||
Length = Fcb->i.inode->i_size - Offset;
|
||||
}
|
||||
|
||||
CHECKPOINT;
|
||||
if ((Offset % BLOCKSIZE) != 0)
|
||||
Ext2ReleaseInode(DeviceExt,
|
||||
&Fcb->i);
|
||||
|
||||
if ((Offset % PAGESIZE) != 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);
|
||||
Delta = min(PAGESIZE - (Offset % PAGESIZE),Length);
|
||||
CcRequestCachePage(Fcb->Bcb,
|
||||
Offset,
|
||||
&BaseAddress,
|
||||
&Uptodate,
|
||||
&CacheSeg);
|
||||
if (Uptodate == FALSE)
|
||||
{
|
||||
Ext2ReadPage(DeviceExt,
|
||||
Fcb,
|
||||
BaseAddress,
|
||||
Offset / BLOCKSIZE);
|
||||
}
|
||||
memcpy(Buffer, BaseAddress + (Offset % PAGESIZE), Delta);
|
||||
CcReleaseCachePage(Fcb->Bcb,
|
||||
CacheSeg,
|
||||
TRUE);
|
||||
Length = Length - Delta;
|
||||
Offset = Offset + Delta;
|
||||
Buffer = Buffer + Delta;
|
||||
}
|
||||
CHECKPOINT;
|
||||
for (i=0; i<(Length/BLOCKSIZE); i++)
|
||||
for (i=0; i<(Length/PAGESIZE); i++)
|
||||
{
|
||||
block = Ext2BlockMap(DeviceExt, &Fcb->inode,
|
||||
(Offset / BLOCKSIZE)+i);
|
||||
Ext2ReadSectors(DeviceExt->StorageDevice,
|
||||
block,
|
||||
1,
|
||||
Buffer);
|
||||
Length = Length - BLOCKSIZE;
|
||||
Offset = Offset + BLOCKSIZE;
|
||||
Buffer = Buffer + BLOCKSIZE;
|
||||
CcRequestCachePage(Fcb->Bcb,
|
||||
Offset,
|
||||
&BaseAddress,
|
||||
&Uptodate,
|
||||
&CacheSeg);
|
||||
if (Uptodate == FALSE)
|
||||
{
|
||||
Ext2ReadPage(DeviceExt,
|
||||
Fcb,
|
||||
BaseAddress,
|
||||
(Offset / BLOCKSIZE));
|
||||
}
|
||||
memcpy(Buffer, BaseAddress, PAGESIZE);
|
||||
CcReleaseCachePage(Fcb->Bcb,
|
||||
CacheSeg,
|
||||
TRUE);
|
||||
Length = Length - PAGESIZE;
|
||||
Offset = Offset + PAGESIZE;
|
||||
Buffer = Buffer + PAGESIZE;
|
||||
}
|
||||
CHECKPOINT;
|
||||
if ((Length % BLOCKSIZE) != 0)
|
||||
if ((Length % PAGESIZE) != 0)
|
||||
{
|
||||
block = Ext2BlockMap(DeviceExt, &Fcb->inode, Offset / BLOCKSIZE);
|
||||
Ext2ReadSectors(DeviceExt->StorageDevice,
|
||||
block,
|
||||
1,
|
||||
TempBuffer);
|
||||
memcpy(Buffer,TempBuffer,Length);
|
||||
CcRequestCachePage(Fcb->Bcb,
|
||||
Offset,
|
||||
&BaseAddress,
|
||||
&Uptodate,
|
||||
&CacheSeg);
|
||||
if (Uptodate == FALSE)
|
||||
{
|
||||
Ext2ReadPage(DeviceExt,
|
||||
Fcb,
|
||||
BaseAddress,
|
||||
(Offset / BLOCKSIZE));
|
||||
}
|
||||
DPRINT("Copying %x to %x Length %d\n",BaseAddress,Buffer,Length);
|
||||
memcpy(Buffer,BaseAddress,Length);
|
||||
CcReleaseCachePage(Fcb->Bcb,
|
||||
CacheSeg,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
ExFreePool(TempBuffer);
|
||||
CHECKPOINT;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
DPRINT("Ext2Write(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
NTSTATUS Ext2FlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
DPRINT("Ext2FlushBuffers(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
NTSTATUS Ext2Shutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
DPRINT("Ext2Shutdown(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
NTSTATUS Ext2Cleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
DbgPrint("Ext2Cleanup(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
DbgPrint("Ext2Cleanup() finished\n");
|
||||
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
NTSTATUS Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Ext2Read(DeviceObject %x, FileObject %x, Irp %x)\n",
|
||||
DeviceObject, FileObject, Irp);
|
||||
|
||||
Length = Stack->Parameters.Read.Length;
|
||||
CHECKPOINT;
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
CHECKPOINT;
|
||||
CHECKPOINT;
|
||||
|
||||
Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length,
|
||||
Stack->Parameters.Read.ByteOffset);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Length;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
|
39
reactos/drivers/fs/ext2/security.c
Normal file
39
reactos/drivers/fs/ext2/security.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/ext2/security.c
|
||||
* PURPOSE: Security support
|
||||
* 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"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS Ext2QuerySecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
DPRINT("Ext2QuerySecurity(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
NTSTATUS Ext2SetSecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
DPRINT("Ext2SetSecurity(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
#include <wchar.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#include "ext2fs.h"
|
||||
|
@ -30,13 +30,38 @@ NTSTATUS Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
PFILE_OBJECT FileObject;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
PEXT2_FCB Fcb;
|
||||
|
||||
DPRINT("Ext2Close(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||
DbgPrint("Ext2Close(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FileObject = Stack->FileObject;
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
if (FileObject == DeviceExtension->FileObject)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Fcb = (PEXT2_FCB)FileObject->FsContext;
|
||||
if (Fcb != NULL)
|
||||
{
|
||||
if (Fcb->Bcb != NULL)
|
||||
{
|
||||
CcReleaseFileCache(FileObject, Fcb->Bcb);
|
||||
}
|
||||
ExFreePool(Fcb);
|
||||
FileObject->FsContext = NULL;
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
|
@ -44,41 +69,6 @@ NTSTATUS Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
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;
|
||||
LARGE_INTEGER 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;
|
||||
|
@ -111,12 +101,19 @@ NTSTATUS Ext2Mount(PDEVICE_OBJECT DeviceToMount)
|
|||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
DPRINT("DeviceObject %x\n",DeviceObject);
|
||||
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
||||
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
|
||||
|
||||
DPRINT("DeviceExt %x\n",DeviceExt);
|
||||
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
||||
DeviceToMount);
|
||||
DPRINT("DeviceExt->StorageDevice %x\n", DeviceExt->StorageDevice);
|
||||
DeviceExt->FileObject = IoCreateStreamFileObject(NULL, DeviceObject);
|
||||
DeviceExt->superblock = superblock;
|
||||
CcInitializeFileCache(DeviceExt->FileObject,
|
||||
&DeviceExt->Bcb);
|
||||
|
||||
DPRINT("Ext2Mount() = STATUS_SUCCESS\n");
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
@ -177,13 +174,20 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
|||
DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2Write;
|
||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||
Ext2FileSystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]=
|
||||
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
||||
Ext2DirectoryControl;
|
||||
DriverObject->DriverUnload = NULL;
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
||||
Ext2QueryInformation;
|
||||
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = Ext2SetInformation;
|
||||
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = Ext2FlushBuffers;
|
||||
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = Ext2Shutdown;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Ext2Cleanup;
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = Ext2QuerySecurity;
|
||||
DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = Ext2SetSecurity;
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = Ext2QueryQuota;
|
||||
DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = Ext2SetQuota;
|
||||
|
||||
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);
|
||||
DriverObject->DriverUnload = NULL;
|
||||
|
||||
IoRegisterFileSystem(DeviceObject);
|
||||
|
||||
|
|
|
@ -1679,7 +1679,8 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("VFAT FSC\n");
|
||||
// DPRINT("VFAT FSC\n");
|
||||
DbgPrint("VFAT FSC\n");
|
||||
|
||||
/* FIXME: should make sure that this is actually a mount request! */
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
VOID CbInitDccb(PDCCB Dccb, PDEVICE_OBJECT DeviceObject, ULONG SectorSize,
|
||||
ULONG NrSectors, ULONG PercentageToCache);
|
||||
PCCB CbAcquireForRead(PDCCB Dccb, ULONG BlockNr);
|
||||
VOID CbReleaseFromRead(PDCCB Dccb, PCCB Ccb);
|
|
@ -1,43 +1,4 @@
|
|||
#ifndef __INCLUDE_DDK_CCTYPES_H
|
||||
#define __INCLUDE_DDK_CCTYPES_H
|
||||
|
||||
typedef struct _CCB
|
||||
{
|
||||
ULONG BlockNr;
|
||||
PVOID Buffer;
|
||||
ULONG State;
|
||||
ULONG ActiveReaders;
|
||||
BOOLEAN WriteInProgress;
|
||||
BOOLEAN ActiveWriter;
|
||||
ULONG References;
|
||||
KEVENT FinishedNotify;
|
||||
KSPIN_LOCK Lock;
|
||||
BOOLEAN Modified;
|
||||
LIST_ENTRY Entry;
|
||||
} CCB, *PCCB;
|
||||
|
||||
enum
|
||||
{
|
||||
CCB_INVALID,
|
||||
CCB_NOT_CACHED,
|
||||
CCB_CACHED,
|
||||
CCB_DELETE_PENDING,
|
||||
};
|
||||
|
||||
typedef struct _DCCB
|
||||
/*
|
||||
* PURPOSE: Device cache control block
|
||||
*/
|
||||
{
|
||||
PCCB* HashTbl;
|
||||
ULONG HashTblSize;
|
||||
KSPIN_LOCK HashTblLock;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
ULONG SectorSize;
|
||||
LIST_ENTRY CcbListHead;
|
||||
KSPIN_LOCK CcbListLock;
|
||||
ULONG NrCcbs;
|
||||
ULONG NrModifiedCcbs;
|
||||
} DCCB, *PDCCB;
|
||||
|
||||
#endif /* __INCLUDE_DDK_CCTYPES_H */
|
||||
|
|
|
@ -231,20 +231,8 @@ enum
|
|||
/*
|
||||
* IRQ levels
|
||||
*/
|
||||
enum
|
||||
{
|
||||
PASSIVE_LEVEL,
|
||||
|
||||
/*
|
||||
* Which order for these (only DISPATCH_LEVEL is important for now)
|
||||
*/
|
||||
APC_LEVEL,
|
||||
DISPATCH_LEVEL,
|
||||
|
||||
/*
|
||||
* Above here are device specific IRQ levels
|
||||
*/
|
||||
FIRST_DEVICE_SPECIFIC_LEVEL,
|
||||
HIGH_LEVEL = FIRST_DEVICE_SPECIFIC_LEVEL + NR_DEVICE_SPECIFIC_LEVELS,
|
||||
};
|
||||
|
||||
#define PASSIVE_LEVEL (1)
|
||||
#define APC_LEVEL (2)
|
||||
#define DISPATCH_LEVEL (3)
|
||||
#define FIRST_DEVICE_SPECIFIC_LEVEL (4)
|
||||
#define HIGH_LEVEL (FIRST_DEVICE_SPECIFIC_LEVEL + NR_DEVICE_SPECIFIC_LEVELS)
|
||||
|
|
|
@ -67,42 +67,27 @@ enum
|
|||
IRP_DEFER_IO_COMPLETION = 0x2000,
|
||||
};
|
||||
|
||||
/*
|
||||
* I/O operation flags
|
||||
*/
|
||||
enum
|
||||
{
|
||||
SL_FORCE_ACCESS_CHECK = 0x1,
|
||||
SL_OPEN_PAGING_FILE = 0x2,
|
||||
SL_OPEN_TARGET_DIRECTORY = 0x4,
|
||||
SL_CASE_SENSITIVE = 0x8,
|
||||
SL_KEY_SPECIFIED = 0x10,
|
||||
SL_OVERRIDE_VERIFY_VOLUME = 0x20,
|
||||
SL_WRITE_THROUGH = 0x40,
|
||||
SL_FT_SEQUENTIAL_WRITE = 0x80,
|
||||
SL_FAIL_IMMEDIATELY = 0x100,
|
||||
SL_EXCLUSIVE_LOCK = 0x200,
|
||||
SL_WATCH_TREE = 0x2000,
|
||||
SL_ALLOW_RAW_MOUNT = 0x4000,
|
||||
};
|
||||
|
||||
#define SL_FORCE_ACCESS_CHECK (0x1)
|
||||
#define SL_OPEN_PAGING_FILE (0x2)
|
||||
#define SL_OPEN_TARGET_DIRECTORY (0x4)
|
||||
#define SL_CASE_SENSITIVE (0x8)
|
||||
#define SL_KEY_SPECIFIED (0x10)
|
||||
#define SL_OVERRIDE_VERIFY_VOLUME (0x20)
|
||||
#define SL_WRITE_THROUGHT (0x40)
|
||||
#define SL_FT_SEQUENTIAL_WRITE (0x80)
|
||||
#define SL_FAIL_IMMEDIATELY (0x100)
|
||||
#define SL_EXCLUSIVE_LOCK (0x200)
|
||||
#define SL_WATCH_TREE (0x2000)
|
||||
#define SL_CASE_SENSITIVE (0x80)
|
||||
|
||||
#define SL_KEY_SPECIFIED (0x1)
|
||||
#define SL_OVERRIDE_VERIFY_VOLUME (0x2)
|
||||
#define SL_WRITE_THROUGHT (0x4)
|
||||
#define SL_FT_SEQUENTIAL_WRITE (0x8)
|
||||
|
||||
#define SL_FAIL_IMMEDIATELY (0x1)
|
||||
#define SL_EXCLUSIVE_LOCK (0x2)
|
||||
|
||||
#define SL_WATCH_TREE (0x1)
|
||||
|
||||
#define SL_RESTART_SCAN (0x1)
|
||||
#define SL_RETURN_SINGLE_ENTRY (0x2)
|
||||
#define SL_INDEX_SPECIFIED (0x4)
|
||||
|
||||
#define SL_ALLOW_RAW_MOUNT (0x1)
|
||||
|
||||
#define SL_PENDING_RETURNED 0x01
|
||||
#define SL_INVOKE_ON_CANCEL 0x20
|
||||
#define SL_INVOKE_ON_SUCCESS 0x40
|
||||
|
|
|
@ -527,3 +527,5 @@ OUT PULONG ReturnedLength
|
|||
);
|
||||
VOID IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject);
|
||||
PDEVICE_OBJECT IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject);
|
||||
PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject,
|
||||
PDEVICE_OBJECT DeviceObject);
|
||||
|
|
|
@ -3,23 +3,21 @@
|
|||
|
||||
/* KERNEL FUNCTIONS ********************************************************/
|
||||
|
||||
struct _KAPC;
|
||||
VOID KeInitializeApc(PKAPC Apc,
|
||||
PKTHREAD Thread,
|
||||
UCHAR StateIndex,
|
||||
PKKERNEL_ROUTINE KernelRoutine,
|
||||
PKRUNDOWN_ROUTINE RundownRoutine,
|
||||
PKNORMAL_ROUTINE NormalRoutine,
|
||||
UCHAR Mode,
|
||||
PVOID Context);
|
||||
|
||||
void KeInitializeApc(
|
||||
struct _KAPC *Apc,
|
||||
PKTHREAD Thread,
|
||||
UCHAR StateIndex,
|
||||
PKKERNEL_ROUTINE KernelRoutine,
|
||||
PKRUNDOWN_ROUTINE RundownRoutine,
|
||||
PKNORMAL_ROUTINE NormalRoutine,
|
||||
UCHAR Mode,
|
||||
PVOID Context
|
||||
);
|
||||
|
||||
void KeInsertQueueApc(struct _KAPC *Apc, PVOID SystemArgument1,
|
||||
PVOID SystemArgument2, UCHAR Mode);
|
||||
void KeAttachProcess(struct _EPROCESS* Process);
|
||||
void KeDetachProcess(VOID);
|
||||
VOID KeInsertQueueApc(PKAPC Apc,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2,
|
||||
UCHAR Mode);
|
||||
VOID KeAttachProcess(struct _EPROCESS* Process);
|
||||
VOID KeDetachProcess(VOID);
|
||||
VOID KeDrainApcQueue(VOID);
|
||||
PKPROCESS KeGetCurrentProcess(VOID);
|
||||
|
||||
|
@ -94,7 +92,9 @@ LONG KeSetBasePriorityThread(PKTHREAD Thread, LONG Increment);
|
|||
LONG KeSetEvent(PKEVENT Event, KPRIORITY Increment, BOOLEAN Wait);
|
||||
KPRIORITY KeSetPriorityThread(PKTHREAD Thread, KPRIORITY Priority);
|
||||
BOOLEAN KeSetTimer(PKTIMER Timer, LARGE_INTEGER DueTime, PKDPC Dpc);
|
||||
BOOLEAN KeSetTimerEx(PKTIMER Timer, LARGE_INTEGER DueTime, LONG Period,
|
||||
BOOLEAN KeSetTimerEx(PKTIMER Timer,
|
||||
LARGE_INTEGER DueTime,
|
||||
LONG Period,
|
||||
PKDPC Dpc);
|
||||
VOID KeStallExecutionProcessor(ULONG MicroSeconds);
|
||||
BOOLEAN KeSynchronizeExecution(PKINTERRUPT Interrupt,
|
||||
|
@ -108,12 +108,16 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count,
|
|||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout,
|
||||
PKWAIT_BLOCK WaitBlockArray);
|
||||
NTSTATUS KeWaitForMutexObject(PKMUTEX Mutex, KWAIT_REASON WaitReason,
|
||||
KPROCESSOR_MODE WaitMode, BOOLEAN Alertable,
|
||||
NTSTATUS KeWaitForMutexObject(PKMUTEX Mutex,
|
||||
KWAIT_REASON WaitReason,
|
||||
KPROCESSOR_MODE WaitMode,
|
||||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout);
|
||||
NTSTATUS KeWaitForSingleObject(PVOID Object, KWAIT_REASON WaitReason,
|
||||
NTSTATUS KeWaitForSingleObject(PVOID Object,
|
||||
KWAIT_REASON WaitReason,
|
||||
KPROCESSOR_MODE WaitMode,
|
||||
BOOLEAN Alertable, PLARGE_INTEGER Timeout);
|
||||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout);
|
||||
|
||||
/*
|
||||
* FUNCTION: Initializes a spinlock
|
||||
|
@ -155,17 +159,6 @@ VOID KeBugCheckEx(ULONG BugCheckCode,
|
|||
*/
|
||||
VOID KeBugCheck(ULONG BugCheckCode);
|
||||
|
||||
// kmutant definition slightly modified from nt5 ddk
|
||||
|
||||
typedef struct _KMUTANT
|
||||
{
|
||||
DISPATCHER_HEADER Header;
|
||||
LIST_ENTRY MutantListEntry;
|
||||
struct _KTHREAD* OwnerThread;
|
||||
BOOLEAN Abandoned;
|
||||
UCHAR ApcDisable;
|
||||
} KMUTANT, *PKMUTANT;
|
||||
|
||||
// io permission map has a 8k size
|
||||
// Each bit in the IOPM corresponds to an io port byte address. The bitmap
|
||||
// is initialized to allow IO at any port. [ all bits set ].
|
||||
|
@ -186,7 +179,7 @@ typedef struct _IOPM
|
|||
* is initialized to allow IO at any port. [ all bits set ]. The IOPL determines
|
||||
* the minium privilege level required to perform IO prior to checking the permission map.
|
||||
*/
|
||||
void Ke386SetIoAccessMap(int NewMap, PIOPM *IoPermissionMap);
|
||||
VOID Ke386SetIoAccessMap(ULONG NewMap, PIOPM *IoPermissionMap);
|
||||
|
||||
/*
|
||||
* FUNCTION: Queries the io permission map.
|
||||
|
@ -199,7 +192,7 @@ void Ke386SetIoAccessMap(int NewMap, PIOPM *IoPermissionMap);
|
|||
* is initialized to allow IO at any port. [ all bits set ]. The IOPL determines
|
||||
* the minium privilege level required to perform IO prior to checking the permission map.
|
||||
*/
|
||||
void Ke386QueryIoAccessMap(BOOLEAN NewMap, PIOPM *IoPermissionMap);
|
||||
VOID Ke386QueryIoAccessMap(BOOLEAN NewMap, PIOPM *IoPermissionMap);
|
||||
|
||||
/*
|
||||
* FUNCTION: Set the process IOPL
|
||||
|
@ -215,10 +208,8 @@ NTSTATUS Ke386IoSetAccessProcess(PEPROCESS Eprocess, BOOLEAN EnableIo);
|
|||
* SelArray =
|
||||
* NumOfSelectors =
|
||||
*/
|
||||
NTSTATUS KeI386ReleaseGdtSelectors(
|
||||
OUT PULONG SelArray,
|
||||
IN ULONG NumOfSelectors
|
||||
);
|
||||
NTSTATUS KeI386ReleaseGdtSelectors(OUT PULONG SelArray,
|
||||
IN ULONG NumOfSelectors);
|
||||
|
||||
/*
|
||||
* FUNCTION: Allocates a set of Global Descriptor Table Selectors
|
||||
|
@ -226,17 +217,15 @@ NTSTATUS KeI386ReleaseGdtSelectors(
|
|||
* SelArray =
|
||||
* NumOfSelectors =
|
||||
*/
|
||||
NTSTATUS KeI386AllocateGdtSelectors(
|
||||
OUT PULONG SelArray,
|
||||
IN ULONG NumOfSelectors
|
||||
);
|
||||
NTSTATUS KeI386AllocateGdtSelectors(OUT PULONG SelArray,
|
||||
IN ULONG NumOfSelectors);
|
||||
|
||||
/*
|
||||
* FUNCTION: Raises a user mode exception
|
||||
* ARGUMENTS:
|
||||
* ExceptionCode = Status code of the exception
|
||||
*/
|
||||
void KeRaiseUserException(NTSTATUS ExceptionCode);
|
||||
VOID KeRaiseUserException(NTSTATUS ExceptionCode);
|
||||
|
||||
|
||||
#endif /* __INCLUDE_DDK_KEFUNCS_H */
|
||||
|
|
|
@ -38,16 +38,37 @@ typedef struct
|
|||
|
||||
typedef struct _DISPATCHER_HEADER
|
||||
{
|
||||
UCHAR Type;
|
||||
UCHAR Absolute;
|
||||
UCHAR Size;
|
||||
UCHAR Inserted;
|
||||
LONG SignalState;
|
||||
UCHAR Type;
|
||||
UCHAR Absolute;
|
||||
UCHAR Size;
|
||||
UCHAR Inserted;
|
||||
LONG SignalState;
|
||||
LIST_ENTRY WaitListHead;
|
||||
} DISPATCHER_HEADER;
|
||||
|
||||
|
||||
typedef struct _KQUEUE
|
||||
{
|
||||
DISPATCHER_HEADER Header;
|
||||
LIST_ENTRY EntryListHead;
|
||||
ULONG CurrentCount;
|
||||
ULONG MaximumCount;
|
||||
LIST_ENTRY ThreadListEntry;
|
||||
} KQUEUE, *PKQUEUE;
|
||||
|
||||
struct _KDPC;
|
||||
|
||||
/*
|
||||
typedef struct _KTIMER
|
||||
{
|
||||
DISPATCHER_HEADER Header;
|
||||
ULARGE_INTEGER DueTime;
|
||||
LIST_ENTRY TimerListEntry;
|
||||
struct _KDPC* Dpc;
|
||||
LONG Period;
|
||||
} KTIMER, *PKTIMER;
|
||||
*/
|
||||
|
||||
typedef struct _KTIMER
|
||||
{
|
||||
LIST_ENTRY entry;
|
||||
|
@ -63,7 +84,7 @@ struct _KSPIN_LOCK;
|
|||
|
||||
typedef struct _KSPIN_LOCK
|
||||
{
|
||||
KIRQL irql;
|
||||
ULONG Lock;
|
||||
} KSPIN_LOCK, *PKSPIN_LOCK;
|
||||
|
||||
typedef struct _KDEVICE_QUEUE
|
||||
|
@ -110,7 +131,7 @@ typedef struct
|
|||
struct _KTHREAD* OwnerThread;
|
||||
BOOLEAN Abandoned;
|
||||
UCHAR ApcDisable;
|
||||
} KMUTEX, *PKMUTEX;
|
||||
} KMUTEX, *PKMUTEX, KMUTANT, *PKMUTANT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
@ -18,12 +18,35 @@ typedef struct _BCB
|
|||
KSPIN_LOCK BcbLock;
|
||||
} BCB, *PBCB;
|
||||
|
||||
#define CACHE_SEGMENT_SIZE (0x1000)
|
||||
|
||||
struct _MEMORY_AREA;
|
||||
|
||||
typedef struct _CACHE_SEGMENT
|
||||
{
|
||||
PVOID BaseAddress;
|
||||
struct _MEMORY_AREA* MemoryArea;
|
||||
BOOLEAN Valid;
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG FileOffset;
|
||||
KEVENT Lock;
|
||||
ULONG ReferenceCount;
|
||||
PBCB Bcb;
|
||||
} CACHE_SEGMENT, *PCACHE_SEGMENT;
|
||||
|
||||
NTSTATUS CcFlushCachePage(PCACHE_SEGMENT CacheSeg);
|
||||
NTSTATUS CcReleaseCachePage(PBCB Bcb,
|
||||
PCACHE_SEGMENT CacheSeg,
|
||||
BOOLEAN Valid);
|
||||
NTSTATUS CcRequestCachePage(PBCB Bcb,
|
||||
ULONG FileOffset,
|
||||
PVOID* BaseAddress,
|
||||
PBOOLEAN UptoDate);
|
||||
PBOOLEAN UptoDate,
|
||||
PCACHE_SEGMENT* CacheSeg);
|
||||
NTSTATUS CcInitializeFileCache(PFILE_OBJECT FileObject,
|
||||
PBCB* Bcb);
|
||||
NTSTATUS CcReleaseFileCache(PFILE_OBJECT FileObject,
|
||||
PBCB Bcb);
|
||||
|
||||
#include <ddk/cctypes.h>
|
||||
|
||||
|
|
|
@ -52,9 +52,9 @@ typedef struct _STARTUPINFOW {
|
|||
WCHAR ImageFile[MAX_PATH];
|
||||
WCHAR CommandLine[MAX_PATH];
|
||||
WCHAR DllPath[MAX_PATH];
|
||||
LPWSTR Reserved[MAX_PATH];
|
||||
LPWSTR Desktop[MAX_PATH];
|
||||
LPWSTR Title[MAX_PATH];
|
||||
WCHAR Reserved[MAX_PATH];
|
||||
WCHAR Desktop[MAX_PATH];
|
||||
WCHAR Title[MAX_PATH];
|
||||
DWORD dwX;
|
||||
DWORD dwY;
|
||||
DWORD dwXSize;
|
||||
|
@ -83,24 +83,24 @@ typedef struct _LDR {
|
|||
|
||||
typedef struct _NT_PEB
|
||||
{
|
||||
UCHAR InheritedAddressSpace;
|
||||
UCHAR ReadImageFileExecOptions;
|
||||
UCHAR BeingDebugged;
|
||||
LONG ImageBaseAddress;
|
||||
LDR Ldr;
|
||||
UCHAR InheritedAddressSpace; // 00
|
||||
UCHAR ReadImageFileExecOptions; // 01h
|
||||
UCHAR BeingDebugged; // 02h
|
||||
LONG ImageBaseAddress; // 03h
|
||||
LDR Ldr; // 07h
|
||||
|
||||
WORD NumberOfProcessors;
|
||||
WORD NtGlobalFlag;
|
||||
WORD NumberOfProcessors; // 11h
|
||||
WORD NtGlobalFlag; // 13h
|
||||
|
||||
PPROCESSINFOW StartupInfo;
|
||||
HANDLE ProcessHeap;
|
||||
ATOMTABLE LocalAtomTable;
|
||||
LPCRITICAL_SECTION CriticalSection;
|
||||
DWORD CriticalSectionTimeout;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
WORD BuildNumber;
|
||||
WORD PlatformId;
|
||||
PPROCESSINFOW StartupInfo; // 15h
|
||||
HANDLE ProcessHeap; // 19h
|
||||
ATOMTABLE LocalAtomTable; // 1Dh
|
||||
LPCRITICAL_SECTION CriticalSection; // 35h
|
||||
DWORD CriticalSectionTimeout; // 39h
|
||||
WORD MajorVersion; // 3Dh
|
||||
WORD MinorVersion; // 3Fh
|
||||
WORD BuildNumber; // 41h
|
||||
WORD PlatformId; // 43h
|
||||
} NT_PEB, *PNT_PEB;
|
||||
|
||||
typedef struct _CLIENT_ID
|
||||
|
@ -110,67 +110,116 @@ typedef struct _CLIENT_ID
|
|||
} CLIENT_ID, *PCLIENT_ID;
|
||||
|
||||
typedef struct _NT_TIB {
|
||||
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
|
||||
PVOID StackBase;
|
||||
PVOID StackLimit;
|
||||
PVOID SubSystemTib;
|
||||
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // 00h
|
||||
PVOID StackBase; // 04h
|
||||
PVOID StackLimit; // 08h
|
||||
PVOID SubSystemTib; // 0Ch
|
||||
union {
|
||||
PVOID FiberData;
|
||||
ULONG Version;
|
||||
PVOID FiberData; // 10h
|
||||
ULONG Version; // 10h
|
||||
} Fib;
|
||||
PVOID ArbitraryUserPointer;
|
||||
struct _NT_TIB *Self;
|
||||
PVOID ArbitraryUserPointer; // 14h
|
||||
struct _NT_TIB *Self; // 18h
|
||||
} NT_TIB, *PNT_TIB;
|
||||
|
||||
typedef struct _NT_TEB
|
||||
{
|
||||
NT_TIB Tib;
|
||||
CLIENT_ID Cid;
|
||||
HANDLE RPCHandle;
|
||||
PVOID TlsData[TLS_MINIMUM_AVAILABLE];
|
||||
DWORD dwTlsIndex;
|
||||
NT_PEB *Peb;
|
||||
DWORD LastErrorCode;
|
||||
NTSTATUS LastStatusValue;
|
||||
DWORD LockCount;
|
||||
UCHAR HardErrorMode;
|
||||
NT_TIB Tib; // 0
|
||||
CLIENT_ID Cid; // 28
|
||||
HANDLE RPCHandle; // 36
|
||||
PVOID TlsData[TLS_MINIMUM_AVAILABLE]; // 40
|
||||
DWORD dwTlsIndex; // 230
|
||||
NT_PEB *Peb; // 234
|
||||
DWORD LastErrorCode; // 238
|
||||
NTSTATUS LastStatusValue; // 242
|
||||
DWORD LockCount; // 244
|
||||
UCHAR HardErrorMode; // 248
|
||||
} NT_TEB;
|
||||
|
||||
typedef struct _KTHREAD
|
||||
{
|
||||
DISPATCHER_HEADER DispatcherHeader;
|
||||
TIME ElapsedTime;
|
||||
TIME KernelTime;
|
||||
TIME UserTime;
|
||||
STACK_INFORMATION StackInformation;
|
||||
PVOID ServiceDescriptorTable; // points to KeServiceDescriptorTable
|
||||
KAFFINITY Affinity;
|
||||
KPRIORITY CurrentPriority;
|
||||
KPRIORITY BasePriority;
|
||||
ULONG Quantum;
|
||||
UCHAR ThreadState; //Thread state is a typeless enum, otherwise it should be const integer
|
||||
ULONG FreezeCount;
|
||||
LONG SuspendCount;
|
||||
PTRAP_FRAME TrapFrame;
|
||||
PVOID *Tls;
|
||||
KWAIT_BLOCK WaitBlock[4];
|
||||
struct _KMUTANT* MutantList;
|
||||
PLIST_ENTRY ApcList;
|
||||
UCHAR KernelApcDisable;
|
||||
KTIMER TimerBlock;
|
||||
KDEVICE_QUEUE DeviceQueue;
|
||||
NT_TEB* Teb;
|
||||
|
||||
/*
|
||||
* PURPOSE: CPU state
|
||||
* NOTE: I have temporarily added this to give somewhere to store
|
||||
* cpu state when the thread isn't running
|
||||
*/
|
||||
hal_thread_state Context;
|
||||
LIST_ENTRY Entry;
|
||||
ULONG LastTick;
|
||||
} KTHREAD, *PKTHREAD;
|
||||
struct _KPROCESS;
|
||||
|
||||
typedef struct _KAPC_STATE
|
||||
{
|
||||
LIST_ENTRY ApcListHead[2];
|
||||
struct _KPROCESS* Process;
|
||||
UCHAR KernelApcInProgress;
|
||||
UCHAR KernelApcPending;
|
||||
USHORT UserApcPending;
|
||||
} KAPC_STATE, *PKAPC_STATE;
|
||||
|
||||
typedef struct _KTHREAD
|
||||
{
|
||||
DISPATCHER_HEADER DispatcherHeader; // For waiting for the thread
|
||||
LIST_ENTRY MutantListHead;
|
||||
PVOID InitialStack;
|
||||
ULONG StackLimit;
|
||||
NT_TEB* Teb;
|
||||
PVOID TlsArray;
|
||||
PVOID KernelStack;
|
||||
UCHAR DebugActive;
|
||||
UCHAR State;
|
||||
USHORT Alerted;
|
||||
UCHAR Iopl;
|
||||
UCHAR NpxState;
|
||||
UCHAR Saturation;
|
||||
KPRIORITY Priority;
|
||||
KAPC_STATE ApcState;
|
||||
ULONG ContextSwitches;
|
||||
ULONG WaitStatus;
|
||||
KIRQL WaitIrql;
|
||||
ULONG WaitMode;
|
||||
UCHAR WaitNext;
|
||||
UCHAR WaitReason;
|
||||
PVOID WaitBlockList;
|
||||
LIST_ENTRY WaitListEntry;
|
||||
ULONG WaitTime;
|
||||
KPRIORITY BasePriority;
|
||||
UCHAR DecrementCount;
|
||||
UCHAR PriorityDecrement;
|
||||
UCHAR Quantum;
|
||||
KWAIT_BLOCK WaitBlock[4];
|
||||
PVOID LegoData; // ??
|
||||
LONG KernelApcDisable;
|
||||
KAFFINITY UserAffinity;
|
||||
UCHAR SystemAffinityActive;
|
||||
UCHAR Pad;
|
||||
PKQUEUE Queue;
|
||||
KTIMER Timer;
|
||||
LIST_ENTRY QueueListEntry;
|
||||
KAFFINITY Affinity;
|
||||
UCHAR Preempted;
|
||||
UCHAR ProcessReadyQueue;
|
||||
UCHAR KernelStackResident;
|
||||
UCHAR NextProcessor;
|
||||
PVOID CallbackStack;
|
||||
BOOL Win32Thread;
|
||||
PVOID TrapFrame;
|
||||
PVOID ApcStatePointer; // Is actually eight bytes
|
||||
UCHAR EnableStackSwap;
|
||||
UCHAR LargeStack;
|
||||
UCHAR ResourceIndex;
|
||||
UCHAR PreviousMode;
|
||||
TIME KernelTime;
|
||||
TIME UserTime;
|
||||
KAPC_STATE SavedApcState;
|
||||
UCHAR Alertable;
|
||||
UCHAR ApcQueueable;
|
||||
ULONG AutoAlignment;
|
||||
PVOID StackBase;
|
||||
KAPC SuspendApc;
|
||||
KSEMAPHORE SuspendSemaphore;
|
||||
LIST_ENTRY ThreadListEntry;
|
||||
UCHAR FreezeCount;
|
||||
ULONG SuspendCount;
|
||||
UCHAR IdealProcessor;
|
||||
UCHAR DisableBoost;
|
||||
|
||||
/* Provisionally added by David Welch */
|
||||
hal_thread_state Context;
|
||||
LIST_ENTRY Entry;
|
||||
ULONG LastTick;
|
||||
|
||||
} KTHREAD, *PKTHREAD;
|
||||
|
||||
// According to documentation the stack should have a commited [ 1 page ] and
|
||||
// a reserved part [ 1 M ] but can be specified otherwise in the image file.
|
||||
|
@ -243,7 +292,7 @@ typedef struct _ETHREAD {
|
|||
typedef struct _KPROCESS
|
||||
{
|
||||
DISPATCHER_HEADER DispatcherHeader;
|
||||
PVOID PageTableDirectory; // FIXME: I shoud point to a PTD
|
||||
PVOID PageTableDirectory; // FIXME: I should point to a PTD
|
||||
TIME ElapsedTime;
|
||||
TIME KernelTime;
|
||||
TIME UserTime;
|
||||
|
@ -268,9 +317,64 @@ typedef struct _KPROCESS
|
|||
typedef struct _EPROCESS
|
||||
{
|
||||
KPROCESS Pcb;
|
||||
|
||||
ULONG UniqueProcessId;
|
||||
ULONG InheritedFromUniqueProcessId;
|
||||
NTSTATUS ExitStatus;
|
||||
KEVENT LockEvent;
|
||||
ULONG LockCount;
|
||||
TIME CreateTime;
|
||||
TIME ExitTime;
|
||||
PVOID LockOwner;
|
||||
ULONG UniqueProcessId;
|
||||
LIST_ENTRY ActiveProcessLinks;
|
||||
ULONG QuotaPeakPoolUsage[2];
|
||||
ULONG QuotaPoolUsage[2];
|
||||
ULONG PagefileUsage;
|
||||
ULONG CommitCharge;
|
||||
ULONG PeakPagefileUsage;
|
||||
ULONG PeakVirtualUsage;
|
||||
LARGE_INTEGER VirtualSize;
|
||||
PVOID Vm; // Actually 48 bytes
|
||||
PVOID LastProtoPteFault;
|
||||
PVOID DebugPort;
|
||||
PVOID ExceptionPort;
|
||||
PVOID ObjectTable;
|
||||
PVOID Token;
|
||||
KMUTEX WorkingSetLock;
|
||||
PVOID WorkingSetPage;
|
||||
UCHAR ProcessOutswapEnabled;
|
||||
UCHAR ProcessOutswapped;
|
||||
UCHAR AddressSpaceInitialized;
|
||||
UCHAR AddressSpaceDeleted;
|
||||
KMUTEX AddressCreationLock;
|
||||
PVOID ForkInProgress;
|
||||
PVOID VmOperation;
|
||||
PKEVENT VmOperationEvent;
|
||||
PVOID PageDirectoryPte;
|
||||
LARGE_INTEGER LastFaultCount;
|
||||
PVOID VadRoot;
|
||||
PVOID VadHint;
|
||||
PVOID CloneRoot;
|
||||
ULONG NumberOfPrivatePages;
|
||||
ULONG NumberOfLockedPages;
|
||||
UCHAR ForkWasSuccessFul;
|
||||
UCHAR ExitProcessCalled;
|
||||
UCHAR CreateProcessReported;
|
||||
HANDLE SectionHandle;
|
||||
PNT_PEB Peb;
|
||||
PVOID SectionBaseAddress;
|
||||
PVOID QuotaBlock;
|
||||
NTSTATUS LastThreadExitStatus;
|
||||
LARGE_INTEGER WorkingSetWatch; //
|
||||
ULONG InheritedFromUniqueProcessId;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
ULONG DefaultHardErrorProcessing;
|
||||
PVOID LdtInformation;
|
||||
ULONG VadFreeHint;
|
||||
PVOID VdmObjects;
|
||||
KMUTANT ProcessMutant;
|
||||
CHAR ImageFileName[16];
|
||||
LARGE_INTEGER VmTrimFaultValue;
|
||||
PVOID Win32Process; // Actually 12 bytes
|
||||
PVOID Win32WindowStation;
|
||||
} EPROCESS, *PEPROCESS;
|
||||
|
||||
#define PROCESS_STATE_TERMINATED (1)
|
||||
|
|
|
@ -16,20 +16,44 @@
|
|||
* Possible status codes
|
||||
* FIXME: These may not be the actual values used by NT
|
||||
*/
|
||||
|
||||
#define STATUS_SUCCESS (0x0)
|
||||
#define STATUS_MORE_ENTRIES (0x105)
|
||||
#define STATUS_NOTIFY_ENUM_DIR (0x10C)
|
||||
#define STATUS_OBJECT_EXISTS (0x40000000)
|
||||
#define STATUS_THREAD_WAS_SUSPENDED (0x40000001)
|
||||
#define STATUS_WORKING_SET_LIMIT_RANGE (0x40000002)
|
||||
|
||||
#define STATUS_UNSUCCESSFUL (0xC0000001)
|
||||
#define STATUS_NOT_IMPLEMENTED (0xC0000002)
|
||||
#define STATUS_INVALID_INFO_CLASS (0xC0000003)
|
||||
#define STATUS_INFO_LENGTH_MISMATCH (0xC0000004)
|
||||
#define STATUS_ACCESS_VIOLATION (0xC0000005)
|
||||
#define STATUS_IN_PAGE_ERROR (0xC0000006)
|
||||
#define STATUS_PAGEFILE_QUOTA (0xC0000007)
|
||||
#define STATUS_INVALID_HANDLE (0xC0000008)
|
||||
#define STATUS_BAD_INITIAL_STACK (0xC0000009)
|
||||
#define STATUS_BAD_INITIAL_PC (0xC000000A)
|
||||
#define STATUS_INVALID_CID (0xC000000B)
|
||||
#define STATUS_TIMER_NOT_CANCELED (0xC000000C)
|
||||
#define STATUS_INVALID_PARAMETER (0xC000000D)
|
||||
#define STATUS_NO_SUCH_DEVICE (0xC000000E)
|
||||
#define STATUS_NO_SUCH_FILE (0xC000000F)
|
||||
|
||||
#define STATUS_GUARD_PAGE_VIOLATION (0x80000001)
|
||||
#define STATUS_DATATYPE_MISALIGNMENT (0x80000002)
|
||||
#define STATUS_BREAKPOINT (0x80000003)
|
||||
#define STATUS_SINGLE_STEP (0x80000004)
|
||||
#define STATUS_BUFFER_OVERFLOW (0x80000005)
|
||||
#define STATUS_NO_MORE_FILES (0x80000006)
|
||||
#define STATUS_WAKE_SYSTEM_DEBUGGER (0x80000007)
|
||||
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
STATUS_SUCCESS = 0x0,
|
||||
|
||||
|
||||
STATUS_MORE_ENTRIES=0x00000105,
|
||||
STATUS_NOTIFY_ENUM_DIR=0x0000010C,
|
||||
|
||||
|
||||
|
||||
STATUS_OBJECT_NAME_EXISTS=0x40000000,
|
||||
STATUS_THREAD_WAS_SUSPENDED,
|
||||
STATUS_WORKING_SET_LIMIT_RANGE,
|
||||
STATUS_IMAGE_NOT_AT_BASE,
|
||||
|
||||
STATUS_IMAGE_NOT_AT_BASE = (0x40000003),
|
||||
STATUS_RXACT_STATE_CREATED,
|
||||
STATUS_SEGMENT_NOTIFICATION,
|
||||
STATUS_LOCAL_USER_SESSION_KEY,
|
||||
|
@ -69,15 +93,6 @@ enum
|
|||
STATUS_WX86_CREATEWX86TIB,
|
||||
|
||||
|
||||
STATUS_GUARD_PAGE_VIOLATION=0x80000001,
|
||||
STATUS_DATATYPE_MISALIGNMENT,
|
||||
STATUS_BREAKPOINT,
|
||||
STATUS_SINGLE_STEP,
|
||||
STATUS_BUFFER_OVERFLOW,
|
||||
STATUS_NO_MORE_FILES,
|
||||
STATUS_WAKE_SYSTEM_DEBUGGER,
|
||||
|
||||
|
||||
STATUS_HANDLES_CLOSED=0x8000000A,
|
||||
STATUS_NO_INHERITANCE,
|
||||
STATUS_GUID_SUBSTITUTION_MADE,
|
||||
|
@ -108,21 +123,6 @@ enum
|
|||
STATUS_ALREADY_DISCONNECTED,
|
||||
STATUS_LONGJUMP,
|
||||
|
||||
STATUS_UNSUCCESSFUL=0xC0000001,
|
||||
STATUS_NOT_IMPLEMENTED,
|
||||
STATUS_INVALID_INFO_CLASS,
|
||||
STATUS_INFO_LENGTH_MISMATCH,
|
||||
STATUS_ACCESS_VIOLATION,
|
||||
STATUS_IN_PAGE_ERROR,
|
||||
STATUS_PAGEFILE_QUOTA,
|
||||
STATUS_INVALID_HANDLE,
|
||||
STATUS_BAD_INITIAL_STACK,
|
||||
STATUS_BAD_INITIAL_PC,
|
||||
STATUS_INVALID_CID,
|
||||
STATUS_TIMER_NOT_CANCELED,
|
||||
STATUS_INVALID_PARAMETER,
|
||||
STATUS_NO_SUCH_DEVICE,
|
||||
STATUS_NO_SUCH_FILE,
|
||||
|
||||
// c0000010
|
||||
STATUS_INVALID_DEVICE_REQUEST,
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#define CHECKED
|
||||
#endif
|
||||
|
||||
#ifdef CHECKED
|
||||
#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); for (;;); }
|
||||
#ifndef NASSERT
|
||||
#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); }
|
||||
#else
|
||||
#define assert(x)
|
||||
#endif
|
||||
|
|
|
@ -96,6 +96,10 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest);
|
|||
NTSTATUS MmReleaseMmInfo(PEPROCESS Process);
|
||||
NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process);
|
||||
VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address, BOOL FreePage);
|
||||
NTSTATUS IoPageRead(PFILE_OBJECT FileObject,
|
||||
PVOID Address,
|
||||
PLARGE_INTEGER Offset,
|
||||
PIO_STATUS_BLOCK StatusBlock);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,37 +19,13 @@ VOID PsReleaseThread(PETHREAD Thread);
|
|||
VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
|
||||
VOID PsBeginThreadWithContextInternal(VOID);
|
||||
|
||||
/*
|
||||
* PURPOSE: Thread states
|
||||
*/
|
||||
enum
|
||||
{
|
||||
/*
|
||||
* PURPOSE: Don't touch
|
||||
*/
|
||||
THREAD_STATE_INVALID,
|
||||
#define THREAD_STATE_INVALID (0)
|
||||
#define THREAD_STATE_RUNNABLE (1)
|
||||
#define THREAD_STATE_RUNNING (2)
|
||||
#define THREAD_STATE_SUSPENDED (3)
|
||||
#define THREAD_STATE_TERMINATED (4)
|
||||
#define THREAD_STATE_MAX (5)
|
||||
|
||||
/*
|
||||
* PURPOSE: Waiting to be dispatched
|
||||
*/
|
||||
THREAD_STATE_RUNNABLE,
|
||||
|
||||
/*
|
||||
* PURPOSE: Currently running
|
||||
*/
|
||||
THREAD_STATE_RUNNING,
|
||||
|
||||
/*
|
||||
* PURPOSE: Doesn't want to run
|
||||
*/
|
||||
THREAD_STATE_SUSPENDED,
|
||||
|
||||
/*
|
||||
* Waiting to be freed
|
||||
*/
|
||||
THREAD_STATE_TERMINATED,
|
||||
};
|
||||
|
||||
/*
|
||||
* Functions the HAL must provide
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <windows.h>
|
||||
|
||||
#define UNIMPLEMENTED dprintf("%s at %s:%d is unimplemented\n",__FUNCTION__,__FILE__,__LINE__);
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define DPRINT(args...)
|
||||
#define CHECKPOINT
|
||||
|
@ -28,3 +30,4 @@ PVOID __ErrorReturnNull(ULONG ErrorCode);
|
|||
BOOL KERNEL32_AnsiToUnicode(PWSTR DestStr,
|
||||
LPCSTR SrcStr,
|
||||
ULONG MaxLen);
|
||||
PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength);
|
||||
|
|
1
reactos/include/ntdll/base.h
Normal file
1
reactos/include/ntdll/base.h
Normal file
|
@ -0,0 +1 @@
|
|||
#define NTDLL_BASE (0x77f60000)
|
|
@ -14,3 +14,4 @@ extern void dprintf(char* fmt,...);
|
|||
#define MAGIC(c1,c2,c3,c4) ((c1) + ((c2)<<8) + ((c3)<<16) + ((c4)<<24))
|
||||
|
||||
#define MAGIC_HEAP MAGIC( 'H','E','A','P' )
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ CLEAN_FILES = assert/*.o conio/*.o ctype/*.o direct/*.o dirent/*.o \
|
|||
endif
|
||||
|
||||
crtdll.coff: crtdll.rc ../../include/reactos/resource.h
|
||||
windres crtdll.rc crtdll.coff
|
||||
$(RC) crtdll.rc crtdll.coff
|
||||
|
||||
crtdll.a: $(OBJECTS)
|
||||
$(LD) -r $(OBJECTS) -o crtdll.a
|
||||
|
|
|
@ -65,12 +65,10 @@ LONG
|
|||
STDCALL
|
||||
UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
|
||||
{
|
||||
char message[80];
|
||||
DWORD dbgRet;
|
||||
HANDLE DebugPort;
|
||||
NTSTATUS errCode;
|
||||
|
||||
DWORD DebuggerPresent;
|
||||
|
||||
|
||||
if(ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) {
|
||||
|
|
|
@ -187,7 +187,6 @@ WINBOOL STDCALL CopyFileExA(LPCSTR lpExistingFileName,
|
|||
WINBOOL* pbCancel,
|
||||
DWORD dwCopyFlags)
|
||||
{
|
||||
ULONG i;
|
||||
WCHAR ExistingFileNameW[MAX_PATH];
|
||||
WCHAR NewFileNameW[MAX_PATH];
|
||||
|
||||
|
|
|
@ -11,8 +11,9 @@
|
|||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <kernel32/kernel32.h>
|
||||
|
|
|
@ -501,6 +501,13 @@ DWORD STDCALL GetFullPathNameW(LPCWSTR lpFileName,
|
|||
return wcslen(lpBuffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
GetShortPathNameA(
|
||||
|
@ -683,25 +690,106 @@ DWORD STDCALL SearchPathW(LPCWSTR lpPath,
|
|||
|
||||
HeapFree(GetProcessHeap(),0,EnvironmentBufferW);
|
||||
|
||||
return retCode;
|
||||
// WCHAR BufferW[MAX_PATH];
|
||||
// WCHAR FileAndExtensionW[MAX_PATH];
|
||||
// WCHAR *EnvironmentBufferW = NULL;
|
||||
|
||||
// UNICODE_STRING PathString;
|
||||
// OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
// IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
DPRINT("SearchPath\n");
|
||||
|
||||
|
||||
if (lpPath == NULL)
|
||||
{
|
||||
// check the directory from which the application loaded
|
||||
|
||||
if (GetCurrentDirectoryW(MAX_PATH, BufferW) > 0)
|
||||
{
|
||||
retCode = SearchPathW(BufferW,lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart );
|
||||
if ( retCode != 0 )
|
||||
return retCode;
|
||||
}
|
||||
if ( GetSystemDirectoryW(BufferW, MAX_PATH) > 0 )
|
||||
{
|
||||
retCode = SearchPathW(BufferW,lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart );
|
||||
if ( retCode != 0 )
|
||||
return retCode;
|
||||
}
|
||||
|
||||
if ( GetWindowsDirectoryW(BufferW, MAX_PATH) > 0 )
|
||||
{
|
||||
retCode = SearchPathW(BufferW,lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart );
|
||||
if ( retCode != 0 )
|
||||
return retCode;
|
||||
}
|
||||
|
||||
j = GetEnvironmentVariableW(L"Path",EnvironmentBufferW,0);
|
||||
EnvironmentBufferW = (WCHAR *) HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,(j+1)*sizeof(WCHAR));
|
||||
|
||||
j = GetEnvironmentVariableW(L"Path",EnvironmentBufferW,j+1);
|
||||
|
||||
for(i=0;i<j;i++) {
|
||||
if ( EnvironmentBufferW[i] == L';' )
|
||||
EnvironmentBufferW[i] = 0;
|
||||
}
|
||||
else {
|
||||
i = 0;
|
||||
while ( retCode == 0 && i < j ) {
|
||||
if ( EnvironmentBufferW[i] != 0 )
|
||||
retCode = SearchPathW(&EnvironmentBufferW[i],lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart );
|
||||
i += lstrlenW(&EnvironmentBufferW[i]) + 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
HeapFree(GetProcessHeap(),0,EnvironmentBufferW);
|
||||
|
||||
|
||||
|
||||
FileAndExtensionW[0] = 0;
|
||||
lpBuffer[0] = 0;
|
||||
i = lstrlenW(lpFileName);
|
||||
j = lstrlenW(lpPath);
|
||||
return retCode;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
if ( i + j + 8 < nBufferLength )
|
||||
return i + j + 9;
|
||||
|
||||
if ( lpExtension != NULL ) {
|
||||
FileAndExtensionW[0] = 0;
|
||||
lpBuffer[0] = 0;
|
||||
i = lstrlenW(lpFileName);
|
||||
j = lstrlenW(lpPath);
|
||||
|
||||
if ( i + j + 8 < nBufferLength )
|
||||
return i + j + 9;
|
||||
|
||||
if ( lpExtension != NULL ) {
|
||||
if ( lpFileName[i-4] != L'.' ) {
|
||||
wcscpy(FileAndExtensionW,lpFileName);
|
||||
wcscat(FileAndExtensionW,lpExtension);
|
||||
wcscpy(FileAndExtensionW,lpFileName);
|
||||
wcscat(FileAndExtensionW,lpExtension);
|
||||
}
|
||||
else
|
||||
wcscpy(FileAndExtensionW,lpFileName);
|
||||
}
|
||||
else
|
||||
wcscpy(FileAndExtensionW,lpFileName);
|
||||
|
||||
|
||||
|
||||
|
||||
lstrcatW(BufferW,L"\\??\\");
|
||||
lstrcatW(BufferW,lpPath);
|
||||
|
||||
|
||||
//printf("%S\n",FileAndExtensionW);
|
||||
|
||||
|
||||
i = wcslen(BufferW);
|
||||
if ( BufferW[i-1] != L'\\' ) {
|
||||
BufferW[i] = L'\\';
|
||||
BufferW[i+1] = 0;
|
||||
}
|
||||
if ( lpFilePart != NULL )
|
||||
{
|
||||
*lpFilePart = &BufferW[wcslen(BufferW)+1];
|
||||
wcscpy(FileAndExtensionW,lpFileName);
|
||||
}
|
||||
else
|
||||
|
@ -709,7 +797,7 @@ DWORD STDCALL SearchPathW(LPCWSTR lpPath,
|
|||
|
||||
lstrcatW(BufferW,L"\\??\\");
|
||||
lstrcatW(BufferW,lpPath);
|
||||
|
||||
|
||||
//printf("%S\n",FileAndExtensionW);
|
||||
|
||||
i = wcslen(BufferW);
|
||||
|
@ -720,7 +808,7 @@ DWORD STDCALL SearchPathW(LPCWSTR lpPath,
|
|||
if ( lpFilePart != NULL )
|
||||
*lpFilePart = &BufferW[wcslen(BufferW)+1];
|
||||
wcscat(BufferW,FileAndExtensionW);
|
||||
//printf("%S\n",lpBuffer);
|
||||
//printf("%S\n",lpBuffer);
|
||||
|
||||
PathString.Buffer = BufferW;
|
||||
PathString.Length = lstrlenW(PathString.Buffer)*sizeof(WCHAR);
|
||||
|
@ -751,8 +839,10 @@ DWORD STDCALL SearchPathW(LPCWSTR lpPath,
|
|||
*lpFilePart = wcsrchr(lpBuffer,'\\')+1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return lstrlenW(lpBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ typedef struct _WIN32_FIND_DATA_ASCII {
|
|||
CHAR cAlternateFileName[ 14 ];
|
||||
} WIN32_FIND_DATA_ASCII, *PWIN32_FIND_DATA_ASCII;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
||||
static void FileDataToWin32Data(LPWIN32_FIND_DATA lpFindFileData, PKERNEL32_FIND_FILE_DATA IData)
|
||||
{
|
||||
|
|
|
@ -26,28 +26,31 @@ WINBOOL STDCALL WriteFile(HANDLE hFile,
|
|||
LPDWORD lpNumberOfBytesWritten,
|
||||
LPOVERLAPPED lpOverLapped)
|
||||
{
|
||||
|
||||
LARGE_INTEGER Offset;
|
||||
HANDLE hEvent = NULL;
|
||||
LARGE_INTEGER Offset;
|
||||
NTSTATUS errCode;
|
||||
PIO_STATUS_BLOCK IoStatusBlock;
|
||||
IO_STATUS_BLOCK IIosb;
|
||||
PIO_STATUS_BLOCK IoStatusBlock;
|
||||
PLARGE_INTEGER ptrOffset;
|
||||
|
||||
DPRINT("WriteFile(hFile %x)\n",hFile);
|
||||
|
||||
if (lpOverLapped != NULL )
|
||||
if (lpOverLapped != NULL)
|
||||
{
|
||||
Offset.u.LowPart = lpOverLapped->Offset;
|
||||
Offset.u.HighPart = lpOverLapped->OffsetHigh;
|
||||
lpOverLapped->Internal = STATUS_PENDING;
|
||||
hEvent= lpOverLapped->hEvent;
|
||||
IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
|
||||
hEvent = lpOverLapped->hEvent;
|
||||
IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
|
||||
ptrOffset = &Offset;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
ptrOffset = NULL;
|
||||
IoStatusBlock = &IIosb;
|
||||
Offset.QuadPart = 0;
|
||||
}
|
||||
|
||||
errCode = NtWriteFile(hFile,
|
||||
hEvent,
|
||||
NULL,
|
||||
|
@ -55,7 +58,7 @@ WINBOOL STDCALL WriteFile(HANDLE hFile,
|
|||
IoStatusBlock,
|
||||
(PVOID)lpBuffer,
|
||||
nNumberOfBytesToWrite,
|
||||
&Offset,
|
||||
ptrOffset,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
|
|
|
@ -63,15 +63,15 @@ GetLogicalDriveStringsA(
|
|||
{
|
||||
LPSTR p = lpBuffer;
|
||||
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||
if (DRIVE_IsValid(drive))
|
||||
{
|
||||
*p++ = 'A' + drive;
|
||||
*p++ = ':';
|
||||
*p++ = '\\';
|
||||
*p++ = '\0';
|
||||
}
|
||||
if (DRIVE_IsValid(drive))
|
||||
{
|
||||
*p++ = 'A' + drive;
|
||||
*p++ = ':';
|
||||
*p++ = '\\';
|
||||
*p++ = '\0';
|
||||
}
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
return count * 4 * sizeof(char);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
|
||||
KERNEL32_BASE = 0x77f00000
|
||||
|
||||
CFLAGS = $(CFLAGS) -DKERNEL32_BASE=$(KERNEL32_BASE)
|
||||
|
||||
ifneq ($(HOST),mingw32-windows)
|
||||
ifneq ($(HOST),mingw32-linux)
|
||||
DLLTARGET=kernel32.a
|
||||
|
@ -44,7 +48,7 @@ NLS_OBJECTS = nls/codepage.o nls/cpmisc.o nls/cptable.o\
|
|||
nls/lcSLV.o nls/lcSQI.o nls/lcSRB.o nls/lcSRL.o nls/lcSVE.o nls/lcSVF.o nls/lcTRK.o nls/lcUKR.o\
|
||||
nls/locale.o nls/mbtowc.o nls/wctomb.o nls/ole2nls.o
|
||||
|
||||
THREAD_OBJECTS = thread/thread.o
|
||||
THREAD_OBJECTS = thread/thread.o thread/tls.o
|
||||
|
||||
PROCESS_OBJECTS = process/proc.o process/cmdline.o process/create.o \
|
||||
process/lib.o
|
||||
|
@ -77,7 +81,7 @@ nls/ole2nls.o: nls/ole2nls.c
|
|||
$(CC) $(CFLAGS) -I. nls/ole2nls.c
|
||||
|
||||
kernel32.coff: kernel32.rc ../../include/reactos/resource.h
|
||||
windres kernel32.rc kernel32.coff
|
||||
$(RC) kernel32.rc kernel32.coff
|
||||
|
||||
kernel32.a: $(OBJECTS)
|
||||
$(AR) csr kernel32.a $(OBJECTS)
|
||||
|
@ -93,7 +97,7 @@ kernel32.dll: $(DLLMAIN) $(OBJECTS) kernel32.def
|
|||
--output-exp temp.exp --def kernel32.def
|
||||
- $(RM) base.tmp
|
||||
$(CC) -specs=k32_specs -mdll -o kernel32.dll kernel32.o ../ntdll/ntdll.a\
|
||||
-Wl,--image-base,0x70000000 \
|
||||
-Wl,--image-base,$(KERNEL32_BASE) \
|
||||
-Wl,--file-alignment,0x1000 \
|
||||
-Wl,--section-alignment,0x1000 \
|
||||
-Wl,temp.exp
|
||||
|
@ -107,4 +111,5 @@ $(CLEAN_FILES:%=%_clean): %_clean:
|
|||
|
||||
.PHONY: clean $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
#WARNINGS_ARE_ERRORS = yes
|
||||
include ../../rules.mak
|
||||
|
|
|
@ -91,6 +91,8 @@ HANDLE WINAPI GetProcessHeap(VOID)
|
|||
********************************************************************/
|
||||
DWORD WINAPI GetProcessHeaps(DWORD maxheaps, PHANDLE phandles )
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
@ -125,7 +127,7 @@ UINT HeapCompact(HANDLE hheap, DWORD flags)
|
|||
*********************************************************************/
|
||||
DWORD WINAPI HeapSize(HANDLE hheap, DWORD flags, LPCVOID pmem)
|
||||
{
|
||||
return(RtlSizeHeap(hheap, flags, pmem));
|
||||
return(RtlSizeHeap(hheap, flags, (PVOID)pmem));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
@ -135,6 +137,6 @@ DWORD WINAPI HeapSize(HANDLE hheap, DWORD flags, LPCVOID pmem)
|
|||
*********************************************************************/
|
||||
BOOL WINAPI HeapValidate(HANDLE hheap, DWORD flags, LPCVOID pmem)
|
||||
{
|
||||
return(RtlValidateHeap(hheap, flags, pmem));
|
||||
return(RtlValidateHeap(hheap, flags, (PVOID)pmem));
|
||||
}
|
||||
|
||||
|
|
|
@ -91,9 +91,9 @@ WINBOOL STDCALL VirtualProtectEx(HANDLE hProcess,
|
|||
|
||||
Status = ZwProtectVirtualMemory(hProcess,
|
||||
(PVOID)lpAddress,
|
||||
(PULONG)dwSize,
|
||||
dwSize,
|
||||
flNewProtect,
|
||||
lpflOldProtect);
|
||||
(PULONG)lpflOldProtect);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(Status));
|
||||
|
|
|
@ -1135,7 +1135,7 @@ GetConsoleTitleA(
|
|||
{
|
||||
wchar_t WideTitle [MAX_CONSOLE_TITLE_LENGTH];
|
||||
DWORD nWideTitle = sizeof WideTitle;
|
||||
DWORD nWritten;
|
||||
// DWORD nWritten;
|
||||
|
||||
if (!lpConsoleTitle || !nSize) return 0;
|
||||
nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
|
||||
|
|
|
@ -32,22 +32,23 @@ DWORD STDCALL GetEnvironmentVariableA(LPCSTR lpName,
|
|||
LPSTR lpBuffer,
|
||||
DWORD nSize)
|
||||
{
|
||||
WCHAR BufferW[MAX_VALUE];
|
||||
WCHAR NameW[MAX_PATH];
|
||||
DWORD RetValue;
|
||||
int i=0;
|
||||
while ((*lpName)!=0 && i < MAX_PATH)
|
||||
{
|
||||
NameW[i] = *lpName;
|
||||
lpName++;
|
||||
i++;
|
||||
}
|
||||
NameW[i] = 0;
|
||||
|
||||
RetValue = GetEnvironmentVariableW(NameW,BufferW,nSize);
|
||||
for(i=0;i<nSize;i++)
|
||||
lpBuffer[i] = (char)BufferW[i];
|
||||
return RetValue;
|
||||
WCHAR BufferW[MAX_VALUE];
|
||||
WCHAR NameW[MAX_PATH];
|
||||
DWORD RetValue;
|
||||
int i=0;
|
||||
|
||||
while ((*lpName)!=0 && i < MAX_PATH)
|
||||
{
|
||||
NameW[i] = *lpName;
|
||||
lpName++;
|
||||
i++;
|
||||
}
|
||||
NameW[i] = 0;
|
||||
|
||||
RetValue = GetEnvironmentVariableW(NameW,BufferW,nSize);
|
||||
for(i=0;i<nSize;i++)
|
||||
lpBuffer[i] = (char)BufferW[i];
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
@ -237,11 +238,13 @@ GetVersionExA(
|
|||
|
||||
LPSTR STDCALL GetEnvironmentStringsA(VOID)
|
||||
{
|
||||
#if 0
|
||||
WCHAR *EnvironmentStringsW;
|
||||
char *EnvironmentStringsA;
|
||||
int size = 0;
|
||||
int i;
|
||||
|
||||
#endif
|
||||
|
||||
return(NULL);
|
||||
|
||||
/* FIXME: This doesn't work */
|
||||
|
@ -270,11 +273,13 @@ LPSTR STDCALL GetEnvironmentStringsA(VOID)
|
|||
|
||||
LPWSTR STDCALL GetEnvironmentStringsW(VOID)
|
||||
{
|
||||
#if 0
|
||||
int size = 0;
|
||||
int i;
|
||||
WCHAR *EnvironmentString;
|
||||
WCHAR *EnvironmentStringSave;
|
||||
|
||||
#endif
|
||||
|
||||
return(NULL);
|
||||
|
||||
/* FIXME: This doesn't work, why not? */
|
||||
|
|
|
@ -8,13 +8,19 @@
|
|||
* UPDATE HISTORY:
|
||||
* Created 19/01/99
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <string.h>
|
||||
#include <internal/string.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <kernel32/kernel32.h>
|
||||
|
||||
/* TYPES *********************************************************************/
|
||||
|
||||
typedef struct __DOSTIME
|
||||
{
|
||||
|
@ -65,6 +71,19 @@ static __inline void NormalizeTimeFields(WORD *FieldToNormalize,
|
|||
*CarryField = (WORD) (*CarryField + 1);
|
||||
}
|
||||
|
||||
#define LISECOND RtlEnlargedUnsignedMultiply(SECOND,NSPERSEC)
|
||||
#define LIMINUTE RtlEnlargedUnsignedMultiply(MINUTE,NSPERSEC)
|
||||
#define LIHOUR RtlEnlargedUnsignedMultiply(HOUR,NSPERSEC)
|
||||
#define LIDAY RtlEnlargedUnsignedMultiply(DAY,NSPERSEC)
|
||||
#define LIYEAR RtlEnlargedUnsignedMultiply(YEAR,NSPERSEC)
|
||||
#define LIFOURYEAR RtlEnlargedUnsignedMultiply(FOURYEAR,NSPERSEC)
|
||||
#define LICENTURY RtlEnlargedUnsignedMultiply(CENTURY,NSPERSEC)
|
||||
#define LIMILLENIUM RtlEnlargedUnsignedMultiply(CENTURY,10*NSPERSEC)
|
||||
|
||||
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
|
@ -230,7 +249,10 @@ SystemTimeToFileTime(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// dwDayOfWeek = RtlLargeIntegerDivide(FileTime,LIDAY,&dwRemDay);
|
||||
// lpSystemTime->wDayOfWeek = 1 + GET_LARGE_INTEGER_LOW_PART(dwDayOfWeek) % 7;
|
||||
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <internal/i386/segment.h>
|
||||
#include <ntdll/ldr.h>
|
||||
#include <internal/teb.h>
|
||||
#include <ntdll/base.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <kernel32/kernel32.h>
|
||||
|
@ -107,8 +108,7 @@ HANDLE STDCALL CreateFirstThread(HANDLE ProcessHandle,
|
|||
PVOID BaseAddress;
|
||||
ULONG BytesWritten;
|
||||
HANDLE DupNTDllSectionHandle, DupSectionHandle;
|
||||
|
||||
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
ObjectAttributes.ObjectName = NULL;
|
||||
|
@ -340,8 +340,6 @@ HANDLE KERNEL32_MapFile(LPCWSTR lpApplicationName,
|
|||
return(hSection);
|
||||
}
|
||||
|
||||
#define NTDLL_BASE (0x80000000)
|
||||
|
||||
static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
@ -353,7 +351,7 @@ static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine)
|
|||
ULONG StartupInfoSize;
|
||||
PROCESSINFOW StartupInfo;
|
||||
|
||||
PebBase = PEB_BASE;
|
||||
PebBase = (PVOID)PEB_BASE;
|
||||
PebSize = 0x1000;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&PebBase,
|
||||
|
@ -368,7 +366,7 @@ static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine)
|
|||
|
||||
|
||||
memset(&Peb, 0, sizeof(Peb));
|
||||
Peb.StartupInfo = PEB_STARTUPINFO;
|
||||
Peb.StartupInfo = (PPROCESSINFOW)PEB_STARTUPINFO;
|
||||
|
||||
ZwWriteVirtualMemory(ProcessHandle,
|
||||
(PVOID)PEB_BASE,
|
||||
|
@ -376,7 +374,7 @@ static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine)
|
|||
sizeof(Peb),
|
||||
&BytesWritten);
|
||||
|
||||
StartupInfoBase = PEB_STARTUPINFO;
|
||||
StartupInfoBase = (PVOID)PEB_STARTUPINFO;
|
||||
StartupInfoSize = 0x1000;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&StartupInfoBase,
|
||||
|
@ -440,7 +438,8 @@ WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
|
|||
|
||||
hSection = KERNEL32_MapFile(lpApplicationName,
|
||||
lpCommandLine,
|
||||
&Headers, &DosHeader);
|
||||
&Headers,
|
||||
&DosHeader);
|
||||
|
||||
Status = NtCreateProcess(&hProcess,
|
||||
PROCESS_ALL_ACCESS,
|
||||
|
|
|
@ -25,15 +25,18 @@
|
|||
|
||||
HINSTANCE LoadLibraryW(LPCWSTR lpLibFileName)
|
||||
{
|
||||
dprintf("LoadLibraryW is unimplemented\n");
|
||||
UNIMPLEMENTED;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
|
||||
{
|
||||
dprintf("LoadLibraryA is unimplemented\n");
|
||||
UNIMPLEMENTED;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
BOOL STDCALL FreeLibrary(HMODULE hLibModule)
|
||||
{
|
||||
dprintf("FreeLibrary is unimplemented\n");
|
||||
UNIMPLEMENTED;
|
||||
return(FALSE);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,30 @@
|
|||
#define NDEBUG
|
||||
#include <kernel32/kernel32.h>
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
/* TYPES *********************************************************************/
|
||||
|
||||
typedef struct _WSTARTUPINFO {
|
||||
DWORD cb;
|
||||
LPWSTR lpReserved;
|
||||
LPWSTR lpDesktop;
|
||||
LPWSTR lpTitle;
|
||||
DWORD dwX;
|
||||
DWORD dwY;
|
||||
DWORD dwXSize;
|
||||
DWORD dwYSize;
|
||||
DWORD dwXCountChars;
|
||||
DWORD dwYCountChars;
|
||||
DWORD dwFillAttribute;
|
||||
DWORD dwFlags;
|
||||
WORD wShowWindow;
|
||||
WORD cbReserved2;
|
||||
LPBYTE lpReserved2;
|
||||
HANDLE hStdInput;
|
||||
HANDLE hStdOutput;
|
||||
HANDLE hStdError;
|
||||
} WSTARTUPINFO, *LPWSTARTUPINFO;
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
|
||||
|
||||
|
@ -34,7 +57,8 @@ WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId);
|
|||
|
||||
FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
||||
{
|
||||
dprintf("GetProcAddress is unimplemented\n");
|
||||
UNIMPLEMENTED;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL GetProcessTimes(HANDLE hProcess,
|
||||
|
@ -62,7 +86,7 @@ DWORD STDCALL GetCurrentProcessId(VOID)
|
|||
return (DWORD)(GetTeb()->Cid).UniqueProcess;
|
||||
}
|
||||
|
||||
WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode )
|
||||
WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
PROCESS_BASIC_INFORMATION ProcessBasic;
|
||||
|
@ -78,7 +102,7 @@ WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode )
|
|||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
|
||||
memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -156,25 +180,13 @@ HANDLE STDCALL OpenProcess(DWORD dwDesiredAccess,
|
|||
return ProcessHandle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow)
|
||||
UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow)
|
||||
{
|
||||
STARTUPINFO StartupInfo;
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
HINSTANCE hInst;
|
||||
DWORD dosErr;
|
||||
|
||||
|
||||
StartupInfo.cb = sizeof(STARTUPINFO);
|
||||
StartupInfo.wShowWindow = uCmdShow ;
|
||||
StartupInfo.dwFlags = 0;
|
||||
|
@ -203,10 +215,11 @@ UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow)
|
|||
|
||||
|
||||
|
||||
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
|
||||
VOID RegisterWaitForInputIdle(WaitForInputIdleType
|
||||
lpfnRegisterWaitForInputIdle)
|
||||
{
|
||||
lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
|
||||
return;
|
||||
lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD STDCALL WaitForInputIdle(HANDLE hProcess,
|
||||
|
@ -215,22 +228,13 @@ DWORD STDCALL WaitForInputIdle(HANDLE hProcess,
|
|||
return 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
Sleep(
|
||||
DWORD dwMilliseconds
|
||||
)
|
||||
VOID STDCALL Sleep(DWORD dwMilliseconds)
|
||||
{
|
||||
SleepEx(dwMilliseconds,FALSE);
|
||||
return;
|
||||
SleepEx(dwMilliseconds,FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
SleepEx(
|
||||
DWORD dwMilliseconds,
|
||||
BOOL bAlertable
|
||||
)
|
||||
DWORD STDCALL SleepEx(DWORD dwMilliseconds, BOOL bAlertable)
|
||||
{
|
||||
TIME Interval;
|
||||
NTSTATUS errCode;
|
||||
|
@ -245,13 +249,10 @@ SleepEx(
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
VOID STDCALL GetStartupInfoW(LPSTARTUPINFO lpStartupInfo)
|
||||
VOID STDCALL GetStartupInfoW(LPSTARTUPINFO _lpStartupInfo)
|
||||
{
|
||||
NT_PEB *pPeb = NtCurrentPeb();
|
||||
LPWSTARTUPINFO lpStartupInfo = (LPWSTARTUPINFO)_lpStartupInfo;
|
||||
|
||||
if (lpStartupInfo == NULL)
|
||||
{
|
||||
|
@ -259,6 +260,22 @@ VOID STDCALL GetStartupInfoW(LPSTARTUPINFO lpStartupInfo)
|
|||
return;
|
||||
}
|
||||
|
||||
lpStartupInfo->cb = sizeof(STARTUPINFO);
|
||||
// lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop);
|
||||
// lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title);
|
||||
lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
|
||||
lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
|
||||
lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
|
||||
lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize;
|
||||
lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars;
|
||||
lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars;
|
||||
lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute;
|
||||
lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags;
|
||||
lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow;
|
||||
//lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved;
|
||||
//lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1;
|
||||
//lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2;
|
||||
|
||||
lpStartupInfo->cb = sizeof(STARTUPINFO);
|
||||
lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop);
|
||||
lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title);
|
||||
|
@ -301,7 +318,8 @@ VOID STDCALL GetStartupInfoA(LPSTARTUPINFO lpStartupInfo)
|
|||
|
||||
while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH)
|
||||
{
|
||||
lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i];
|
||||
lpStartupInfo->lpDesktop[i] = (unsigned char)
|
||||
pPeb->StartupInfo->Desktop[i];
|
||||
i++;
|
||||
}
|
||||
lpStartupInfo->lpDesktop[i] = 0;
|
||||
|
|
|
@ -11,31 +11,33 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
#include <kernel32/kernel32.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
lpCriticalSection->Reserved = -1;
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID InitializeCriticalSection(LPCRITICAL_SECTION pcritical)
|
||||
{
|
||||
pcritical->LockCount = -1;
|
||||
pcritical->RecursionCount = 0;
|
||||
pcritical->LockSemaphore = NULL;
|
||||
pcritical->OwningThread = (HANDLE)-1;
|
||||
pcritical->Reserved = 0;
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
WINBOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,46 +4,44 @@
|
|||
* FILE: lib/kernel32/thread/thread.c
|
||||
* PURPOSE: Thread functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
Tls functions are modified from WINE
|
||||
* Tls functions are modified from WINE
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <kernel32/thread.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <string.h>
|
||||
#include <internal/i386/segment.h>
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
CreateThread(
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
DWORD dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId
|
||||
)
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
DWORD dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId)
|
||||
{
|
||||
return CreateRemoteThread(NtCurrentProcess(),lpThreadAttributes,dwStackSize,
|
||||
lpStartAddress,lpParameter,dwCreationFlags,lpThreadId);
|
||||
return(CreateRemoteThread(NtCurrentProcess(),
|
||||
lpThreadAttributes,
|
||||
dwStackSize,
|
||||
lpStartAddress,
|
||||
lpParameter,
|
||||
dwCreationFlags,
|
||||
lpThreadId));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
CreateRemoteThread(
|
||||
HANDLE hProcess,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
DWORD dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId
|
||||
)
|
||||
HANDLE STDCALL CreateRemoteThread(HANDLE hProcess,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
DWORD dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
HANDLE ThreadHandle;
|
||||
|
@ -52,42 +50,44 @@ CreateRemoteThread(
|
|||
CONTEXT ThreadContext;
|
||||
INITIAL_TEB InitialTeb;
|
||||
BOOLEAN CreateSuspended = FALSE;
|
||||
ULONG BaseAddress;
|
||||
PVOID BaseAddress;
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
ObjectAttributes.ObjectName = NULL;
|
||||
ObjectAttributes.Attributes = 0;
|
||||
if ( lpThreadAttributes != NULL ) {
|
||||
if ( lpThreadAttributes->bInheritHandle )
|
||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||
ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
|
||||
}
|
||||
if (lpThreadAttributes != NULL)
|
||||
{
|
||||
if (lpThreadAttributes->bInheritHandle)
|
||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||
ObjectAttributes.SecurityDescriptor =
|
||||
lpThreadAttributes->lpSecurityDescriptor;
|
||||
}
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
|
||||
if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
|
||||
CreateSuspended = TRUE;
|
||||
if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED)
|
||||
CreateSuspended = TRUE;
|
||||
else
|
||||
CreateSuspended = FALSE;
|
||||
|
||||
|
||||
BaseAddress = 0;
|
||||
ZwAllocateVirtualMemory(hProcess,
|
||||
&BaseAddress,
|
||||
0,
|
||||
&dwStackSize,
|
||||
(PULONG)&dwStackSize,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
|
||||
|
||||
memset(&ThreadContext,0,sizeof(CONTEXT));
|
||||
ThreadContext.Eip = lpStartAddress;
|
||||
ThreadContext.Eip = (LONG)lpStartAddress;
|
||||
ThreadContext.SegGs = USER_DS;
|
||||
ThreadContext.SegFs = USER_DS;
|
||||
ThreadContext.SegEs = USER_DS;
|
||||
ThreadContext.SegDs = USER_DS;
|
||||
ThreadContext.SegCs = USER_CS;
|
||||
ThreadContext.SegSs = USER_DS;
|
||||
ThreadContext.Esp = BaseAddress + dwStackSize;
|
||||
ThreadContext.Esp = (ULONG)(BaseAddress + dwStackSize);
|
||||
ThreadContext.EFlags = (1<<1) + (1<<9);
|
||||
|
||||
|
||||
|
@ -110,263 +110,190 @@ NT_TEB *GetTeb(VOID)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
WINBOOL STDCALL SwitchToThread(VOID )
|
||||
WINBOOL STDCALL SwitchToThread(VOID)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
errCode = NtYieldExecution();
|
||||
return TRUE;
|
||||
NTSTATUS errCode;
|
||||
errCode = NtYieldExecution();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD STDCALL GetCurrentThreadId()
|
||||
{
|
||||
|
||||
return (DWORD)(GetTeb()->Cid).UniqueThread;
|
||||
return((DWORD)(GetTeb()->Cid).UniqueThread);
|
||||
}
|
||||
|
||||
VOID STDCALL ExitThread(UINT uExitCode)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
NTSTATUS errCode;
|
||||
|
||||
errCode = NtTerminateThread(
|
||||
NtCurrentThread() ,
|
||||
uExitCode
|
||||
);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
}
|
||||
return;
|
||||
errCode = NtTerminateThread(NtCurrentThread(),
|
||||
uExitCode);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
}
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetThreadTimes(
|
||||
HANDLE hThread,
|
||||
LPFILETIME lpCreationTime,
|
||||
LPFILETIME lpExitTime,
|
||||
LPFILETIME lpKernelTime,
|
||||
LPFILETIME lpUserTime
|
||||
)
|
||||
WINBOOL STDCALL GetThreadTimes(HANDLE hThread,
|
||||
LPFILETIME lpCreationTime,
|
||||
LPFILETIME lpExitTime,
|
||||
LPFILETIME lpKernelTime,
|
||||
LPFILETIME lpUserTime)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
KERNEL_USER_TIMES KernelUserTimes;
|
||||
ULONG ReturnLength;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadTimes,&KernelUserTimes,sizeof(KERNEL_USER_TIMES),&ReturnLength);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME));
|
||||
memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME));
|
||||
memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME));
|
||||
memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME));
|
||||
return TRUE;
|
||||
|
||||
NTSTATUS errCode;
|
||||
KERNEL_USER_TIMES KernelUserTimes;
|
||||
ULONG ReturnLength;
|
||||
|
||||
errCode = NtQueryInformationThread(hThread,
|
||||
ThreadTimes,
|
||||
&KernelUserTimes,
|
||||
sizeof(KERNEL_USER_TIMES),
|
||||
&ReturnLength);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME));
|
||||
memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME));
|
||||
memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME));
|
||||
memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL GetThreadContext(
|
||||
HANDLE hThread,
|
||||
LPCONTEXT lpContext
|
||||
)
|
||||
WINBOOL STDCALL GetThreadContext(HANDLE hThread,
|
||||
LPCONTEXT lpContext)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
errCode = NtGetContextThread(hThread,lpContext);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
NTSTATUS errCode;
|
||||
|
||||
errCode = NtGetContextThread(hThread,
|
||||
lpContext);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
SetThreadContext(
|
||||
HANDLE hThread,
|
||||
CONST CONTEXT *lpContext
|
||||
)
|
||||
WINBOOL STDCALL SetThreadContext(HANDLE hThread,
|
||||
CONST CONTEXT *lpContext)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
|
||||
errCode = NtSetContextThread(hThread,(void *)lpContext);
|
||||
if (!NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
NTSTATUS errCode;
|
||||
|
||||
errCode = NtSetContextThread(hThread,
|
||||
(void *)lpContext);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetExitCodeThread(
|
||||
HANDLE hThread,
|
||||
LPDWORD lpExitCode
|
||||
)
|
||||
WINBOOL STDCALL GetExitCodeThread(HANDLE hThread,
|
||||
LPDWORD lpExitCode)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy( lpExitCode ,&ThreadBasic.ExitStatus,sizeof(DWORD));
|
||||
return TRUE;
|
||||
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
|
||||
errCode = NtQueryInformationThread(hThread,
|
||||
ThreadBasicInformation,
|
||||
&ThreadBasic,
|
||||
sizeof(THREAD_BASIC_INFORMATION),
|
||||
&DataWritten);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(lpExitCode, &ThreadBasic.ExitStatus, sizeof(DWORD));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
ResumeThread(
|
||||
HANDLE hThread
|
||||
)
|
||||
DWORD STDCALL ResumeThread(HANDLE hThread)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
ULONG PreviousResumeCount;
|
||||
|
||||
errCode = NtResumeThread(hThread,&PreviousResumeCount );
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return -1;
|
||||
}
|
||||
return PreviousResumeCount;
|
||||
NTSTATUS errCode;
|
||||
ULONG PreviousResumeCount;
|
||||
|
||||
errCode = NtResumeThread(hThread,
|
||||
&PreviousResumeCount);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return -1;
|
||||
}
|
||||
return PreviousResumeCount;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
SuspendThread(
|
||||
HANDLE hThread
|
||||
)
|
||||
DWORD STDCALL SuspendThread(HANDLE hThread)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
ULONG PreviousSuspendCount;
|
||||
|
||||
errCode = NtSuspendThread(hThread,&PreviousSuspendCount );
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return -1;
|
||||
}
|
||||
return PreviousSuspendCount;
|
||||
NTSTATUS errCode;
|
||||
ULONG PreviousSuspendCount;
|
||||
|
||||
errCode = NtSuspendThread(hThread,
|
||||
&PreviousSuspendCount);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return -1;
|
||||
}
|
||||
return PreviousSuspendCount;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
SetThreadAffinityMask(
|
||||
HANDLE hThread,
|
||||
DWORD dwThreadAffinityMask
|
||||
)
|
||||
DWORD STDCALL SetThreadAffinityMask(HANDLE hThread,
|
||||
DWORD dwThreadAffinityMask)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
SetThreadPriority(
|
||||
HANDLE hThread,
|
||||
int nPriority
|
||||
)
|
||||
WINBOOL STDCALL SetThreadPriority(HANDLE hThread,
|
||||
int nPriority)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
ThreadBasic.BasePriority = nPriority;
|
||||
errCode = NtSetInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION));
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
|
||||
errCode = NtQueryInformationThread(hThread,
|
||||
ThreadBasicInformation,
|
||||
&ThreadBasic,
|
||||
sizeof(THREAD_BASIC_INFORMATION),
|
||||
&DataWritten);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
ThreadBasic.BasePriority = nPriority;
|
||||
errCode = NtSetInformationThread(hThread,
|
||||
ThreadBasicInformation,
|
||||
&ThreadBasic,
|
||||
sizeof(THREAD_BASIC_INFORMATION));
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
STDCALL
|
||||
GetThreadPriority(
|
||||
HANDLE hThread
|
||||
)
|
||||
int STDCALL GetThreadPriority(HANDLE hThread)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return THREAD_PRIORITY_ERROR_RETURN;
|
||||
}
|
||||
return ThreadBasic.BasePriority;
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
|
||||
errCode = NtQueryInformationThread(hThread,
|
||||
ThreadBasicInformation,
|
||||
&ThreadBasic,
|
||||
sizeof(THREAD_BASIC_INFORMATION),
|
||||
&DataWritten);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return THREAD_PRIORITY_ERROR_RETURN;
|
||||
}
|
||||
return ThreadBasic.BasePriority;
|
||||
}
|
||||
|
||||
|
||||
/* (WIN32) Thread Local Storage ******************************************** */
|
||||
|
||||
DWORD STDCALL
|
||||
TlsAlloc(VOID)
|
||||
{
|
||||
DWORD dwTlsIndex = GetTeb()->dwTlsIndex;
|
||||
|
||||
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
|
||||
if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
|
||||
{
|
||||
TlsData[dwTlsIndex] = NULL;
|
||||
return (dwTlsIndex++);
|
||||
}
|
||||
return (0xFFFFFFFFUL);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL
|
||||
TlsFree(DWORD dwTlsIndex)
|
||||
{
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
LPVOID STDCALL
|
||||
TlsGetValue(DWORD dwTlsIndex)
|
||||
{
|
||||
|
||||
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
|
||||
if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
|
||||
{
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
return (TlsData[dwTlsIndex]);
|
||||
}
|
||||
SetLastError(1);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL
|
||||
TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
|
||||
{
|
||||
|
||||
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
|
||||
if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
|
||||
{
|
||||
|
||||
TlsData[dwTlsIndex] = lpTlsValue;
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
|
62
reactos/lib/kernel32/thread/tls.c
Normal file
62
reactos/lib/kernel32/thread/tls.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/thread/tls.c
|
||||
* PURPOSE: Thread functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* Tls functions are modified from WINE
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <kernel32/thread.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <string.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
DWORD STDCALL TlsAlloc(VOID)
|
||||
{
|
||||
DWORD dwTlsIndex = GetTeb()->dwTlsIndex;
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
if (dwTlsIndex < (sizeof(TlsData) / sizeof(TlsData[0])))
|
||||
{
|
||||
TlsData[dwTlsIndex] = NULL;
|
||||
return (dwTlsIndex++);
|
||||
}
|
||||
return (0xFFFFFFFFUL);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL TlsFree(DWORD dwTlsIndex)
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
LPVOID STDCALL TlsGetVlue(DWORD dwTlsIndex)
|
||||
{
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
if (dwTlsIndex < (sizeof(TlsData) / sizeof(TlsData[0])))
|
||||
{
|
||||
SetLastError(NO_ERROR);
|
||||
return (TlsData[dwTlsIndex]);
|
||||
}
|
||||
SetLastError(1);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
|
||||
{
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
if (dwTlsIndex < (sizeof(TlsData) / sizeof(TlsData[0])))
|
||||
{
|
||||
TlsData[dwTlsIndex] = lpTlsValue;
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
IMAGE_BASE = 0x77f60000
|
||||
|
||||
ifneq ($(HOST),mingw32-windows)
|
||||
ifneq ($(HOST),mingw32-linux)
|
||||
DLLTARGET=ntdll.a
|
||||
|
@ -39,7 +41,7 @@ CLEAN_FILES = napi.o ldr/*.o rtl/*.o stdio/*.o stdlib/*.o string/*.o stubs/*.o \
|
|||
endif
|
||||
|
||||
ntdll.coff: ntdll.rc ../../include/reactos/resource.h
|
||||
windres ntdll.rc ntdll.coff
|
||||
$(RC) ntdll.rc ntdll.coff
|
||||
|
||||
ntdll.a: $(OBJECTS)
|
||||
$(AR) csr ntdll.a $(OBJECTS)
|
||||
|
@ -58,7 +60,7 @@ ntdll.dll: $(DLLMAIN) $(OBJECTS) def/ntdll.def
|
|||
- $(RM) base.tmp
|
||||
$(CC) -specs=ntdll_specs -mdll -o ntdll.dll ntdll.o \
|
||||
-Wl,--entry=_LdrStartup \
|
||||
-Wl,--image-base,0x80000000 \
|
||||
-Wl,--image-base,$(IMAGE_BASE) \
|
||||
-Wl,--file-alignment,0x1000 \
|
||||
-Wl,--section-alignment,0x1000 \
|
||||
-Wl,temp.exp
|
||||
|
|
|
@ -35,7 +35,7 @@ LOADERS = dos
|
|||
#
|
||||
DEVICE_DRIVERS = blue ide keyboard mouse null parallel serial
|
||||
# DEVICE_DRIVERS = beep event floppy ide_test sound test test1
|
||||
FS_DRIVERS = minix vfat ext2
|
||||
FS_DRIVERS = vfat ext2
|
||||
# FS_DRIVERS = template
|
||||
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS)
|
||||
|
||||
|
|
|
@ -14,36 +14,55 @@
|
|||
#include <ddk/ntifs.h>
|
||||
#include <internal/mm.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* TYPES *********************************************************************/
|
||||
|
||||
#define CACHE_SEGMENT_SIZE (0x1000)
|
||||
|
||||
typedef struct _CACHE_SEGMENT
|
||||
{
|
||||
PVOID BaseAddress;
|
||||
PMEMORY_AREA MemoryArea;
|
||||
BOOLEAN Valid;
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG FileOffset;
|
||||
KEVENT Lock;
|
||||
ULONG ReferenceCount;
|
||||
} CACHE_SEGMENT, *PCACHE_SEGMENT;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS CcFlushCachePage(PCACHE_SEGMENT CacheSeg)
|
||||
/*
|
||||
* FUNCTION: Asks the FSD to flush the contents of the page back to disk
|
||||
*/
|
||||
{
|
||||
KeWaitForSingleObject(&CacheSeg->Lock,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
/* Build an IRP_MJ_WRITE and send it to the filesystem */
|
||||
KeSetEvent(&CacheSeg->Lock, IO_NO_INCREMENT, 0);
|
||||
return(STATUS_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
NTSTATUS CcReleaseCachePage(PBCB Bcb,
|
||||
PCACHE_SEGMENT CacheSeg,
|
||||
BOOLEAN Valid)
|
||||
{
|
||||
DPRINT("CcReleaseCachePage(Bcb %x, CacheSeg %x, Valid %d)\n",
|
||||
Bcb, CacheSeg, Valid);
|
||||
|
||||
CacheSeg->ReferenceCount--;
|
||||
CacheSeg->Valid = Valid;
|
||||
KeSetEvent(&CacheSeg->Lock, IO_NO_INCREMENT, FALSE);
|
||||
|
||||
DPRINT("CcReleaseCachePage() finished\n");
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS CcRequestCachePage(PBCB Bcb,
|
||||
ULONG FileOffset,
|
||||
PVOID* BaseAddress,
|
||||
PBOOLEAN UptoDate)
|
||||
PBOOLEAN UptoDate,
|
||||
PCACHE_SEGMENT* CacheSeg)
|
||||
{
|
||||
KIRQL oldirql;
|
||||
PLIST_ENTRY current_entry;
|
||||
PCACHE_SEGMENT current;
|
||||
|
||||
DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x)\n");
|
||||
DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
|
||||
"UptoDate %x, CacheSeg %x)\n", Bcb, FileOffset, BaseAddress,
|
||||
UptoDate, CacheSeg);
|
||||
|
||||
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
|
||||
|
||||
|
@ -53,42 +72,96 @@ NTSTATUS CcRequestCachePage(PBCB Bcb,
|
|||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
|
||||
if (current->FileOffset == PAGE_ROUND_DOWN(FileOffset))
|
||||
{
|
||||
DPRINT("Found existing segment at %x\n", current);
|
||||
current->ReferenceCount++;
|
||||
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
||||
DPRINT("Waiting for segment\n");
|
||||
KeWaitForSingleObject(¤t->Lock,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
*UptoDate = current->Valid;
|
||||
BaseAddress = current->BaseAddress;
|
||||
*BaseAddress = current->BaseAddress;
|
||||
*CacheSeg = current;
|
||||
DPRINT("Returning %x (UptoDate %d)\n", current, current->Valid);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
|
||||
DPRINT("Creating new segment\n");
|
||||
|
||||
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
||||
|
||||
current = ExAllocatePool(NonPagedPool, sizeof(CACHE_SEGMENT));
|
||||
current->BaseAddress = NULL;
|
||||
MmCreateMemoryArea(KernelMode,
|
||||
PsGetCurrentProcess(),
|
||||
NULL,
|
||||
MEMORY_AREA_CACHE_SEGMENT,
|
||||
¤t->BaseAddress,
|
||||
CACHE_SEGMENT_SIZE,
|
||||
PAGE_READWRITE,
|
||||
¤t->MemoryArea);
|
||||
(PMEMORY_AREA*)¤t->MemoryArea);
|
||||
CHECKPOINT;
|
||||
current->Valid = FALSE;
|
||||
current->FileOffset = PAGE_ROUND_DOWN(FileOffset);
|
||||
KeInitializeEvent(¤t->Lock, SynchronizationEvent, TRUE);
|
||||
current->Bcb = Bcb;
|
||||
CHECKPOINT;
|
||||
KeInitializeEvent(¤t->Lock, SynchronizationEvent, FALSE);
|
||||
current->ReferenceCount = 1;
|
||||
CHECKPOINT;
|
||||
InsertTailList(&Bcb->CacheSegmentListHead, ¤t->ListEntry);
|
||||
CHECKPOINT;
|
||||
*UptoDate = current->Valid;
|
||||
*BaseAddress = current->BaseAddress;
|
||||
MmSetPage(PsGetCurrentProcess(),
|
||||
current->BaseAddress,
|
||||
(ULONG)MmAllocPage(),
|
||||
PAGE_READWRITE);
|
||||
*CacheSeg = current;
|
||||
CHECKPOINT;
|
||||
MmSetPage(NULL,
|
||||
current->BaseAddress,
|
||||
PAGE_READWRITE,
|
||||
(ULONG)MmAllocPage());
|
||||
|
||||
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
|
||||
|
||||
DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS CcFreeCacheSegment(PFILE_OBJECT FileObject,
|
||||
PBCB Bcb,
|
||||
PCACHE_SEGMENT CacheSeg)
|
||||
{
|
||||
MmFreeMemoryArea(NULL,
|
||||
CacheSeg->BaseAddress,
|
||||
CACHE_SEGMENT_SIZE,
|
||||
TRUE);
|
||||
ExFreePool(CacheSeg);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS CcReleaseFileCache(PFILE_OBJECT FileObject,
|
||||
PBCB Bcb)
|
||||
{
|
||||
PLIST_ENTRY current_entry;
|
||||
PCACHE_SEGMENT current;
|
||||
|
||||
DPRINT("CcReleaseFileCache(FileObject %x, Bcb %x)\n",
|
||||
FileObject, Bcb);
|
||||
|
||||
current_entry = Bcb->CacheSegmentListHead.Flink;
|
||||
while (current_entry != (&Bcb->CacheSegmentListHead))
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
|
||||
current_entry = current_entry->Flink;
|
||||
CcFreeCacheSegment(FileObject,
|
||||
Bcb,
|
||||
current);
|
||||
}
|
||||
|
||||
ExFreePool(Bcb);
|
||||
|
||||
DPRINT("CcReleaseFileCache() finished\n");
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* #define PROTO_REG 1 /* Comment out to disable */
|
||||
// #define PROTO_REG 1 /* Comment out to disable */
|
||||
|
||||
/* FILE STATICS *************************************************************/
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ static struct _ERRLIST
|
|||
{
|
||||
{STATUS_SUCCESS, "SUCCESS", NULL},
|
||||
{STATUS_INSUFFICIENT_RESOURCES, "INSUFFICIENT_RESOURCES", NULL},
|
||||
{STATUS_OBJECT_NAME_EXISTS, "OBJECT_NAME_EXISTS", NULL},
|
||||
// {STATUS_OBJECT_NAME_EXISTS, "OBJECT_NAME_EXISTS", NULL},
|
||||
{STATUS_OBJECT_NAME_COLLISION, "OBJECT_NAME_COLLISION", NULL},
|
||||
{STATUS_CTL_FILE_NOT_SUPPORTED, "CTL_FILE_NOT_SUPPORTED", NULL},
|
||||
{STATUS_PORT_ALREADY_SET, "PORT_ALREADY_SET", NULL},
|
||||
|
|
|
@ -29,8 +29,11 @@ VOID ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
|
|||
return;
|
||||
}
|
||||
FastMutex->Contention++;
|
||||
KeWaitForSingleObject(&(FastMutex->Event),Executive,KernelMode,
|
||||
FALSE,NULL);
|
||||
KeWaitForSingleObject(&(FastMutex->Event),
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
FastMutex->Owner=KeGetCurrentThread();
|
||||
}
|
||||
|
||||
|
@ -39,12 +42,14 @@ VOID ExInitializeFastMutex(PFAST_MUTEX FastMutex)
|
|||
FastMutex->Count=1;
|
||||
FastMutex->Owner=NULL;
|
||||
FastMutex->Contention=0;
|
||||
KeInitializeEvent(&(FastMutex->Event),SynchronizationEvent,FALSE);
|
||||
KeInitializeEvent(&(FastMutex->Event),
|
||||
SynchronizationEvent,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
VOID ExReleaseFastMutexUnsafe(PFAST_MUTEX FastMutex)
|
||||
{
|
||||
assert(FastMutex->Owner==KeGetCurrentThread());
|
||||
assert(FastMutex->Owner == KeGetCurrentThread());
|
||||
FastMutex->Owner=NULL;
|
||||
if (InterlockedIncrement(&(FastMutex->Count))<=0)
|
||||
{
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: kernel/excutive/resource.c
|
||||
* PURPOSE: Graceful system shutdown if a bug is detected
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* FILE: ntoskrnl/ex/resource.c
|
||||
* PURPOSE: Resource synchronization construct
|
||||
* PROGRAMMER: Unknown
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
*/
|
||||
|
@ -40,304 +40,507 @@
|
|||
#include <stddef.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
||||
BOOLEAN ExTryToAcquireResourceExclusiveLite(PERESOURCE Resource)
|
||||
/*
|
||||
* FUNCTION: Attempts to require the resource for exclusive access
|
||||
* ARGUMENTS:
|
||||
* Resource = Points to the resource of be acquired
|
||||
* RETURNS: TRUE if the resource was acquired for the caller
|
||||
* NOTES: Must be acquired at IRQL < DISPATCH_LEVEL
|
||||
*/
|
||||
{
|
||||
return(ExAcquireResourceExclusiveLite(Resource,FALSE));
|
||||
}
|
||||
|
||||
BOOLEAN ExAcquireResourceExclusive(PERESOURCE Resource, BOOLEAN Wait)
|
||||
{
|
||||
return ExAcquireResourceExclusiveLite(Resource,Wait);
|
||||
return(ExAcquireResourceExclusiveLite(Resource,Wait));
|
||||
}
|
||||
|
||||
BOOLEAN ExAcquireResourceExclusiveLite(PERESOURCE Resource, BOOLEAN Wait)
|
||||
{
|
||||
// FIXME : protect essential tasks of this function from interrupts
|
||||
// perhaps with KeRaiseIrql(SYNCH_LEVEL);
|
||||
if(Resource->ActiveCount) // resource already locked
|
||||
{
|
||||
if((Resource->Flag & ResourceOwnedExclusive)
|
||||
&& Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
|
||||
{ // it's ok : same lock for same thread
|
||||
Resource->OwnerThreads[0].a.OwnerCount++;
|
||||
return TRUE;
|
||||
}
|
||||
if( ! Wait) return FALSE;
|
||||
Resource->NumberOfExclusiveWaiters++;
|
||||
if(KeWaitForSingleObject(Resource->ExclusiveWaiters,Executive,KernelMode,FALSE,NULL)
|
||||
==STATUS_TIMEOUT)
|
||||
{
|
||||
//FIXME : what to do if timeout ?
|
||||
Resource->NumberOfExclusiveWaiters--;
|
||||
return FALSE;
|
||||
}
|
||||
Resource->NumberOfExclusiveWaiters--;
|
||||
}
|
||||
Resource->OwnerThreads[0].a.OwnerCount=1;
|
||||
/*
|
||||
* FUNCTION: Acquires a resource exclusively for the calling thread
|
||||
* ARGUMENTS:
|
||||
* Resource = Points to the resource to acquire
|
||||
* Wait = Is set to TRUE if the caller should wait to acquire the
|
||||
* resource if it can't be acquired immediately
|
||||
* RETURNS: TRUE if the resource was acquired,
|
||||
* FALSE otherwise
|
||||
* NOTES: Must be called at IRQL < DISPATCH_LEVEL
|
||||
*/
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
|
||||
DPRINT("ExAcquireResourceExclusiveLite(Resource %x, Wait %d)\n",
|
||||
Resource, Wait);
|
||||
|
||||
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
|
||||
|
||||
/* resource already locked */
|
||||
if((Resource->Flag & ResourceOwnedExclusive)
|
||||
&& Resource->OwnerThreads[0].OwnerThread == ExGetCurrentResourceThread())
|
||||
{
|
||||
/* it's ok : same lock for same thread */
|
||||
Resource->OwnerThreads[0].a.OwnerCount++;
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (Resource->ActiveCount && !Wait)
|
||||
{
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireResourceExclusiveLite() = FALSE\n");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is slightly better than it looks because other exclusive
|
||||
* threads who are waiting won't be woken up but there is a race
|
||||
* with new threads trying to grab the resource so we must have
|
||||
* the spinlock, still normally this loop will only be executed
|
||||
* once
|
||||
* NOTE: We might want to set a timeout to detect deadlock
|
||||
* (10 minutes?)
|
||||
*/
|
||||
while (Resource->ActiveCount)
|
||||
{
|
||||
Resource->NumberOfExclusiveWaiters++;
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
KeWaitForSingleObject(Resource->ExclusiveWaiters,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
|
||||
Resource->NumberOfExclusiveWaiters--;
|
||||
}
|
||||
Resource->Flag |= ResourceOwnedExclusive;
|
||||
Resource->ActiveCount=1;
|
||||
Resource->OwnerThreads[0].OwnerThread=ExGetCurrentResourceThread();
|
||||
return TRUE;
|
||||
Resource->ActiveCount = 1;
|
||||
Resource->OwnerThreads[0].OwnerThread = ExGetCurrentResourceThread();
|
||||
Resource->OwnerThreads[0].a.OwnerCount = 1;
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
static BOOLEAN EiRemoveSharedOwner(PERESOURCE Resource,
|
||||
ERESOURCE_THREAD ResourceThreadId)
|
||||
/*
|
||||
* FUNCTION: Removes the current thread from the shared owners of the resource
|
||||
* ARGUMENTS:
|
||||
* Resource = Pointer to the resource for which the thread is to be
|
||||
* added
|
||||
* NOTE: Must be called with the resource spinlock held
|
||||
*/
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if (Resource->OwnerThreads[1].OwnerThread == ResourceThreadId)
|
||||
{
|
||||
Resource->OwnerThreads[1].a.OwnerCount--;
|
||||
Resource->ActiveCount--;
|
||||
if (Resource->OwnerThreads[1].a.OwnerCount == 0)
|
||||
{
|
||||
Resource->OwnerThreads[1].OwnerThread = 0;
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (Resource->OwnerThreads[1].OwnerThread)
|
||||
{
|
||||
/* Oh dear, the caller didn't own the resource after all */
|
||||
return(FALSE);;
|
||||
}
|
||||
|
||||
for (i=0; i<Resource->OwnerThreads[1].a.TableSize; i++)
|
||||
{
|
||||
if (Resource->OwnerTable[i].OwnerThread == ResourceThreadId)
|
||||
{
|
||||
Resource->OwnerTable[1].a.OwnerCount--;
|
||||
Resource->ActiveCount--;
|
||||
if (Resource->OwnerTable[1].a.OwnerCount == 0)
|
||||
{
|
||||
Resource->OwnerTable[i].OwnerThread = 0;
|
||||
}
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static BOOLEAN EiAddSharedOwner(PERESOURCE Resource)
|
||||
/*
|
||||
* FUNCTION: Adds the current thread to the shared owners of the resource
|
||||
* ARGUMENTS:
|
||||
* Resource = Pointer to the resource for which the thread is to be
|
||||
* added
|
||||
* NOTE: Must be called with the resource spinlock held
|
||||
*/
|
||||
{
|
||||
ERESOURCE_THREAD CurrentThread = ExGetCurrentResourceThread();
|
||||
POWNER_ENTRY freeEntry;
|
||||
ULONG i;
|
||||
|
||||
/*
|
||||
* now, we must search if this thread has already acquired this resource
|
||||
* then increase ownercount if found, else create new entry or reuse free
|
||||
* entry
|
||||
*/
|
||||
if (!Resource->OwnerThreads[1].a.TableSize)
|
||||
{
|
||||
/* allocate ownertable,memset to 0, initialize first entry */
|
||||
Resource->OwnerTable = ExAllocatePool(NonPagedPool,
|
||||
sizeof(OWNER_ENTRY)*3);
|
||||
if (Resource->OwnerTable == NULL)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
return(FALSE);
|
||||
}
|
||||
memset(Resource->OwnerTable,sizeof(OWNER_ENTRY)*3,0);
|
||||
memcpy(&Resource->OwnerTable[0], &Resource->OwnerThreads[1],
|
||||
sizeof(OWNER_ENTRY));
|
||||
|
||||
Resource->OwnerThreads[1].OwnerThread = 0;
|
||||
Resource->OwnerThreads[1].a.TableSize = 3;
|
||||
|
||||
Resource->OwnerTable[1].OwnerThread = CurrentThread;
|
||||
Resource->OwnerTable[1].a.OwnerCount = 1;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
freeEntry = NULL;
|
||||
for (i=0; i<Resource->OwnerThreads[1].a.TableSize; i++)
|
||||
{
|
||||
if (Resource->OwnerTable[i].OwnerThread == CurrentThread)
|
||||
{
|
||||
Resource->OwnerTable[i].a.OwnerCount++;
|
||||
return(TRUE);
|
||||
}
|
||||
if (Resource->OwnerTable[i].OwnerThread == 0)
|
||||
{
|
||||
freeEntry = &Resource->OwnerTable[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!freeEntry)
|
||||
{
|
||||
/* reallocate ownertable with one more entry */
|
||||
freeEntry = ExAllocatePool(NonPagedPool,
|
||||
sizeof(OWNER_ENTRY)*
|
||||
(Resource->OwnerThreads[1].a.TableSize+1));
|
||||
if (freeEntry == NULL)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
return(FALSE);
|
||||
}
|
||||
memcpy(freeEntry,Resource->OwnerTable,
|
||||
sizeof(OWNER_ENTRY)*(Resource->OwnerThreads[1].a.TableSize));
|
||||
ExFreePool(Resource->OwnerTable);
|
||||
Resource->OwnerTable=freeEntry;
|
||||
freeEntry=&Resource->OwnerTable[Resource->OwnerThreads[1].a.TableSize];
|
||||
Resource->OwnerThreads[1].a.TableSize ++;
|
||||
}
|
||||
freeEntry->OwnerThread=ExGetCurrentResourceThread();
|
||||
freeEntry->a.OwnerCount=1;
|
||||
Resource->ActiveCount++;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN ExAcquireResourceSharedLite(PERESOURCE Resource, BOOLEAN Wait)
|
||||
/*
|
||||
* FUNCTION: Acquires the given resource for shared access by the calling
|
||||
* thread
|
||||
* ARGUMENTS:
|
||||
* Resource = Points to the resource to acquire
|
||||
* Wait = Is set to TRUE if the caller should be put into wait state
|
||||
* until the resource can be acquired if it cannot be acquired
|
||||
* immediately
|
||||
* RETURNS: TRUE, if the resource is acquire
|
||||
* FALSE otherwise
|
||||
*/
|
||||
{
|
||||
POWNER_ENTRY freeEntry;
|
||||
unsigned long i;
|
||||
// FIXME : protect from interrupts
|
||||
// first, resolve trivial cases
|
||||
if(Resource->ActiveCount==0) // no owner, it's easy
|
||||
{
|
||||
Resource->OwnerThreads[1].OwnerThread=ExGetCurrentResourceThread();
|
||||
Resource->OwnerThreads[1].a.OwnerCount=1;
|
||||
Resource->ActiveCount=1;
|
||||
return TRUE;
|
||||
}
|
||||
if((Resource->Flag & ResourceOwnedExclusive)
|
||||
&& Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
|
||||
{// exclusive, but by same thread : it's ok
|
||||
Resource->OwnerThreads[0].a.OwnerCount++;
|
||||
return TRUE;
|
||||
}
|
||||
if((Resource->Flag & ResourceOwnedExclusive)
|
||||
KIRQL oldIrql;
|
||||
|
||||
DPRINT("ExAcquireResourceSharedLite(Resource %x, Wait %d)\n",
|
||||
Resource, Wait);
|
||||
|
||||
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
|
||||
|
||||
/* first, resolve trivial cases */
|
||||
if (Resource->ActiveCount == 0)
|
||||
{
|
||||
/* no owner, it's easy */
|
||||
Resource->OwnerThreads[1].OwnerThread = ExGetCurrentResourceThread();
|
||||
Resource->OwnerThreads[1].a.OwnerCount = 1;
|
||||
Resource->ActiveCount = 1;
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if ((Resource->Flag & ResourceOwnedExclusive)
|
||||
&& Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
|
||||
{
|
||||
/* exclusive, but by same thread : it's ok */
|
||||
/*
|
||||
* NOTE: Is this correct? Seems the same as ExConvertExclusiveToShared
|
||||
*/
|
||||
Resource->OwnerThreads[0].a.OwnerCount++;
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if ((Resource->Flag & ResourceOwnedExclusive)
|
||||
|| Resource->NumberOfExclusiveWaiters)
|
||||
{ //exclusive by another thread , or thread waiting for exclusive
|
||||
if(!Wait) return FALSE;
|
||||
else
|
||||
{
|
||||
Resource->NumberOfSharedWaiters++;
|
||||
// wait for the semaphore
|
||||
if(KeWaitForSingleObject(Resource->SharedWaiters,0,0,0,0)==STATUS_TIMEOUT)
|
||||
{
|
||||
//FIXME : what to do ?
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
//now, we must search if this thread has already acquired this resource
|
||||
//then increase ownercount if found, else create new entry or reuse free entry
|
||||
if(!Resource->OwnerThreads[1].a.TableSize)
|
||||
{
|
||||
// allocate ownertable,memset to 0, initialize first entry
|
||||
Resource->OwnerTable=ExAllocatePool(NonPagedPool,sizeof(OWNER_ENTRY)*3);
|
||||
memset(Resource->OwnerTable,sizeof(OWNER_ENTRY)*3,0);
|
||||
Resource->OwnerTable[0].OwnerThread = Resource->OwnerThreads[1].OwnerThread;
|
||||
Resource->OwnerTable[0].a.OwnerCount=Resource->OwnerThreads[1].a.OwnerCount;
|
||||
Resource->OwnerThreads[1].OwnerThread=0;;
|
||||
Resource->OwnerThreads[1].a.TableSize=3;
|
||||
Resource->OwnerTable[1].OwnerThread=ExGetCurrentResourceThread();
|
||||
Resource->OwnerTable[1].a.OwnerCount=1;
|
||||
return TRUE;
|
||||
}
|
||||
freeEntry=NULL;
|
||||
for(i=0;i<Resource->OwnerThreads[1].a.TableSize;i++)
|
||||
{
|
||||
if(Resource->OwnerTable[i].OwnerThread==ExGetCurrentResourceThread())
|
||||
{// old entry for this thread found
|
||||
Resource->OwnerTable[i].a.OwnerCount++;
|
||||
return TRUE;
|
||||
}
|
||||
if(Resource->OwnerTable[i].OwnerThread==0)
|
||||
freeEntry = &Resource->OwnerTable[i];
|
||||
}
|
||||
if(! freeEntry)
|
||||
{
|
||||
// reallocate ownertable with one more entry
|
||||
freeEntry=ExAllocatePool(NonPagedPool
|
||||
,sizeof(OWNER_ENTRY)*(Resource->OwnerThreads[1].a.TableSize+1));
|
||||
memcpy(freeEntry,Resource->OwnerTable
|
||||
,sizeof(OWNER_ENTRY)*(Resource->OwnerThreads[1].a.TableSize));
|
||||
ExFreePool(Resource->OwnerTable);
|
||||
Resource->OwnerTable=freeEntry;
|
||||
freeEntry=&Resource->OwnerTable[Resource->OwnerThreads[1].a.TableSize];
|
||||
Resource->OwnerThreads[1].a.TableSize ++;
|
||||
}
|
||||
freeEntry->OwnerThread=ExGetCurrentResourceThread();
|
||||
freeEntry->a.OwnerCount=1;
|
||||
Resource->ActiveCount++;
|
||||
return TRUE;
|
||||
{
|
||||
/* exclusive by another thread , or thread waiting for exclusive */
|
||||
if (!Wait)
|
||||
{
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireResourceExclusiveLite() = FALSE\n");
|
||||
return(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Resource->NumberOfSharedWaiters++;
|
||||
/* wait for the semaphore */
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
KeWaitForSingleObject(Resource->SharedWaiters,0,0,0,0);
|
||||
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
|
||||
Resource->NumberOfSharedWaiters--;
|
||||
}
|
||||
}
|
||||
|
||||
EiAddSharedOwner(Resource);
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireResourceExclusiveLite() = TRUE\n");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
VOID ExConvertExclusiveToSharedLite(PERESOURCE Resource)
|
||||
/*
|
||||
* FUNCTION: Converts a given resource from acquired for exclusive access
|
||||
* to acquire for shared access
|
||||
* ARGUMENTS:
|
||||
* Resource = Points to the resource for which the access should be
|
||||
* converted
|
||||
* NOTES: Caller must be running at IRQL < DISPATCH_LEVEL
|
||||
*/
|
||||
{
|
||||
int oldWaiters=Resource->NumberOfSharedWaiters;
|
||||
if(!Resource->Flag & ResourceOwnedExclusive) return;
|
||||
//transfer infos from entry 0 to entry 1 and erase entry 0
|
||||
Resource->OwnerThreads[1].OwnerThread=Resource->OwnerThreads[0].OwnerThread;
|
||||
Resource->OwnerThreads[1].a.OwnerCount=Resource->OwnerThreads[0].a.OwnerCount;
|
||||
Resource->OwnerThreads[0].OwnerThread=0;
|
||||
Resource->OwnerThreads[0].a.OwnerCount=0;
|
||||
//erase exclusive flag
|
||||
Resource->Flag &= (~ResourceOwnedExclusive);
|
||||
//if no shared waiters, that's all :
|
||||
if(!oldWaiters) return;
|
||||
//else, awake the waiters :
|
||||
Resource->ActiveCount += oldWaiters;
|
||||
Resource->NumberOfSharedWaiters=0;
|
||||
KeReleaseSemaphore(Resource->SharedWaiters,0,oldWaiters,0);
|
||||
ULONG oldWaiters;
|
||||
KIRQL oldIrql;
|
||||
|
||||
DPRINT("ExConvertExclusiveToSharedLite(Resource %x)\n", Resource);
|
||||
|
||||
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
|
||||
|
||||
oldWaiters = Resource->NumberOfSharedWaiters;
|
||||
|
||||
if (!(Resource->Flag & ResourceOwnedExclusive))
|
||||
{
|
||||
/* Might not be what the caller expects, better bug check */
|
||||
KeBugCheck(0);
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
return;
|
||||
}
|
||||
|
||||
//transfer infos from entry 0 to entry 1 and erase entry 0
|
||||
Resource->OwnerThreads[1].OwnerThread=Resource->OwnerThreads[0].OwnerThread;
|
||||
Resource->OwnerThreads[1].a.OwnerCount=Resource->OwnerThreads[0].a.OwnerCount;
|
||||
Resource->OwnerThreads[0].OwnerThread=0;
|
||||
Resource->OwnerThreads[0].a.OwnerCount=0;
|
||||
/* erase exclusive flag */
|
||||
Resource->Flag &= (~ResourceOwnedExclusive);
|
||||
/* if no shared waiters, that's all */
|
||||
if (!oldWaiters)
|
||||
{
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
return;
|
||||
}
|
||||
/* else, awake the waiters */
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
KeReleaseSemaphore(Resource->SharedWaiters,0,oldWaiters,0);
|
||||
DPRINT("ExConvertExclusiveToSharedLite() finished\n");
|
||||
}
|
||||
|
||||
ULONG ExGetExclusiveWaiterCount(PERESOURCE Resource)
|
||||
{
|
||||
return Resource->NumberOfExclusiveWaiters;
|
||||
return(Resource->NumberOfExclusiveWaiters);
|
||||
}
|
||||
|
||||
BOOLEAN ExAcquireSharedStarveExclusive(PERESOURCE Resource, BOOLEAN Wait)
|
||||
/*
|
||||
* FUNCTION: Acquires a given resource for shared access without waiting
|
||||
* for any pending attempts to acquire exclusive access to the
|
||||
* same resource
|
||||
* ARGUMENTS:
|
||||
* Resource = Points to the resource to be acquired for shared access
|
||||
* Wait = Is set to TRUE if the caller will wait until the resource
|
||||
* becomes available when access can't be granted immediately
|
||||
* RETURNS: TRUE if the requested access is granted. The routine returns
|
||||
* FALSE if the input Wait is FALSE and shared access can't be
|
||||
* granted immediately
|
||||
*/
|
||||
{
|
||||
POWNER_ENTRY freeEntry;
|
||||
unsigned long i;
|
||||
// FIXME : protect from interrupts
|
||||
// first, resolve trivial cases
|
||||
if(Resource->ActiveCount==0) // no owner, it's easy
|
||||
{
|
||||
Resource->OwnerThreads[1].OwnerThread=ExGetCurrentResourceThread();
|
||||
Resource->OwnerThreads[1].a.OwnerCount=1;
|
||||
Resource->ActiveCount=1;
|
||||
return TRUE;
|
||||
}
|
||||
if((Resource->Flag & ResourceOwnedExclusive)
|
||||
&& Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
|
||||
{// exclusive, but by same thread : it's ok
|
||||
Resource->OwnerThreads[0].a.OwnerCount++;
|
||||
return TRUE;
|
||||
}
|
||||
if(Resource->Flag & ResourceOwnedExclusive)
|
||||
{ //exclusive by another thread , or thread waiting for exclusive
|
||||
if(!Wait) return FALSE;
|
||||
else
|
||||
{
|
||||
Resource->NumberOfSharedWaiters++;
|
||||
// wait for the semaphore
|
||||
if(KeWaitForSingleObject(Resource->SharedWaiters,0,0,0,0)==STATUS_TIMEOUT)
|
||||
{
|
||||
//FIXME : what to do ?
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
//now, we must search if this thread has already acquired this resource
|
||||
//then increase ownercount if found, else create new entry or reuse free entry
|
||||
if(!Resource->OwnerThreads[1].a.TableSize)
|
||||
{
|
||||
// allocate ownertable,memset to 0, initialize first entry
|
||||
Resource->OwnerTable=ExAllocatePool(NonPagedPool,sizeof(OWNER_ENTRY)*3);
|
||||
memset(Resource->OwnerTable,sizeof(OWNER_ENTRY)*3,0);
|
||||
Resource->OwnerTable[0].OwnerThread = Resource->OwnerThreads[1].OwnerThread;
|
||||
Resource->OwnerTable[0].a.OwnerCount=Resource->OwnerThreads[1].a.OwnerCount;
|
||||
Resource->OwnerThreads[1].OwnerThread=0;;
|
||||
Resource->OwnerThreads[1].a.TableSize=3;
|
||||
Resource->OwnerTable[1].OwnerThread=ExGetCurrentResourceThread();
|
||||
Resource->OwnerTable[1].a.OwnerCount=1;
|
||||
return TRUE;
|
||||
}
|
||||
freeEntry=NULL;
|
||||
for(i=0;i<Resource->OwnerThreads[1].a.TableSize;i++)
|
||||
{
|
||||
if(Resource->OwnerTable[i].OwnerThread==ExGetCurrentResourceThread())
|
||||
{// old entry for this thread found
|
||||
Resource->OwnerTable[i].a.OwnerCount++;
|
||||
return TRUE;
|
||||
}
|
||||
if(Resource->OwnerTable[i].OwnerThread==0)
|
||||
freeEntry = &Resource->OwnerTable[i];
|
||||
}
|
||||
if(! freeEntry)
|
||||
{
|
||||
// reallocate ownertable with one more entry
|
||||
freeEntry=ExAllocatePool(NonPagedPool
|
||||
,sizeof(OWNER_ENTRY)*(Resource->OwnerThreads[1].a.TableSize+1));
|
||||
memcpy(freeEntry,Resource->OwnerTable
|
||||
,sizeof(OWNER_ENTRY)*(Resource->OwnerThreads[1].a.TableSize));
|
||||
ExFreePool(Resource->OwnerTable);
|
||||
Resource->OwnerTable=freeEntry;
|
||||
freeEntry=&Resource->OwnerTable[Resource->OwnerThreads[1].a.TableSize];
|
||||
Resource->OwnerThreads[1].a.TableSize ++;
|
||||
}
|
||||
freeEntry->OwnerThread=ExGetCurrentResourceThread();
|
||||
freeEntry->a.OwnerCount=1;
|
||||
Resource->ActiveCount++;
|
||||
return TRUE;
|
||||
KIRQL oldIrql;
|
||||
|
||||
DPRINT("ExAcquireSharedStarveExclusive(Resource %x, Wait %d)\n",
|
||||
Resource, Wait);
|
||||
|
||||
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
|
||||
|
||||
/* no owner, it's easy */
|
||||
if (Resource->ActiveCount == 0)
|
||||
{
|
||||
Resource->OwnerThreads[1].OwnerThread=ExGetCurrentResourceThread();
|
||||
Resource->OwnerThreads[1].a.OwnerCount=1;
|
||||
Resource->ActiveCount=1;
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireSharedStarveExclusive() = TRUE\n");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if ((Resource->Flag & ResourceOwnedExclusive)
|
||||
&& Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
|
||||
{
|
||||
/* exclusive, but by same thread : it's ok */
|
||||
Resource->OwnerThreads[0].a.OwnerCount++;
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireSharedStarveExclusive() = TRUE\n");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if (Resource->Flag & ResourceOwnedExclusive)
|
||||
{
|
||||
/* exclusive by another thread */
|
||||
if (!Wait)
|
||||
{
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireSharedStarveExclusive() = FALSE\n");
|
||||
return(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Resource->NumberOfSharedWaiters++;
|
||||
/* wait for the semaphore */
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
KeWaitForSingleObject(Resource->SharedWaiters,0,0,0,0);
|
||||
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
|
||||
Resource->NumberOfSharedWaiters--;
|
||||
}
|
||||
}
|
||||
EiAddSharedOwner(Resource);
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExAcquireSharedStarveExclusive() = TRUE\n");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN ExAcquireSharedWaitForExclusive(PERESOURCE Resource, BOOLEAN Wait)
|
||||
{
|
||||
return ExAcquireResourceSharedLite(Resource,Wait);
|
||||
return(ExAcquireResourceSharedLite(Resource,Wait));
|
||||
}
|
||||
|
||||
NTSTATUS ExDeleteResource(PERESOURCE Resource)
|
||||
{
|
||||
if(Resource->OwnerTable) ExFreePool(Resource->OwnerTable);
|
||||
if(Resource->SharedWaiters) ExFreePool(Resource->SharedWaiters);
|
||||
if(Resource->ExclusiveWaiters) ExFreePool(Resource->ExclusiveWaiters);
|
||||
return 0;
|
||||
return(ExDeleteResourceLite(Resource));
|
||||
}
|
||||
|
||||
NTSTATUS ExDeleteResourceLite(PERESOURCE Resource)
|
||||
{
|
||||
if(Resource->OwnerTable) ExFreePool(Resource->OwnerTable);
|
||||
if(Resource->SharedWaiters) ExFreePool(Resource->SharedWaiters);
|
||||
if(Resource->ExclusiveWaiters) ExFreePool(Resource->ExclusiveWaiters);
|
||||
return 0;
|
||||
DPRINT("ExDeleteResourceLite(Resource %x)\n", Resource);
|
||||
if (Resource->OwnerTable) ExFreePool(Resource->OwnerTable);
|
||||
if (Resource->SharedWaiters) ExFreePool(Resource->SharedWaiters);
|
||||
if (Resource->ExclusiveWaiters) ExFreePool(Resource->ExclusiveWaiters);
|
||||
return(STATUS_SUCCESS);;
|
||||
}
|
||||
|
||||
ERESOURCE_THREAD ExGetCurrentResourceThread()
|
||||
{
|
||||
return ((ERESOURCE_THREAD)PsGetCurrentThread() );
|
||||
return((ERESOURCE_THREAD)PsGetCurrentThread());
|
||||
}
|
||||
|
||||
ULONG ExGetSharedWaiterCount(PERESOURCE Resource)
|
||||
{
|
||||
return Resource->NumberOfSharedWaiters;
|
||||
return(Resource->NumberOfSharedWaiters);
|
||||
}
|
||||
|
||||
NTSTATUS ExInitializeResource(PERESOURCE Resource)
|
||||
{
|
||||
return ExInitializeResourceLite(Resource);
|
||||
return(ExInitializeResourceLite(Resource));
|
||||
}
|
||||
|
||||
NTSTATUS ExInitializeResourceLite(PERESOURCE Resource)
|
||||
{
|
||||
DPRINT("ExInitializeResourceLite(Resource %x)\n", Resource);
|
||||
memset(Resource,0,sizeof(ERESOURCE));
|
||||
// Resource->NumberOfSharedWaiters = 0;
|
||||
// Resource->NumberOfExclusiveWaiters = 0;
|
||||
Resource->NumberOfSharedWaiters = 0;
|
||||
Resource->NumberOfExclusiveWaiters = 0;
|
||||
KeInitializeSpinLock(&Resource->SpinLock);
|
||||
// Resource->Flag=0;
|
||||
// FIXME : I'm not sure it's a good idea to allocate and initialize
|
||||
// immediately Waiters.
|
||||
Resource->ExclusiveWaiters=ExAllocatePool(NonPagedPool , sizeof(KEVENT));
|
||||
KeInitializeEvent(Resource->ExclusiveWaiters,SynchronizationEvent,
|
||||
Resource->Flag = 0;
|
||||
Resource->ExclusiveWaiters = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
|
||||
KeInitializeEvent(Resource->ExclusiveWaiters,
|
||||
SynchronizationEvent,
|
||||
FALSE);
|
||||
Resource->SharedWaiters=ExAllocatePool(NonPagedPool ,sizeof(KSEMAPHORE));
|
||||
Resource->SharedWaiters = ExAllocatePool(NonPagedPool ,sizeof(KSEMAPHORE));
|
||||
KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff);
|
||||
// Resource->ActiveCount = 0;
|
||||
return 0;
|
||||
Resource->ActiveCount = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
BOOLEAN ExIsResourceAcquiredExclusiveLite(PERESOURCE Resource)
|
||||
/*
|
||||
* FUNCTION: Returns whether the current thread has exclusive access to
|
||||
* a given resource
|
||||
* ARGUMENTS:
|
||||
* Resource = Points to the resource to be queried
|
||||
* RETURNS: TRUE if the caller has exclusive access to the resource,
|
||||
* FALSE otherwise
|
||||
*/
|
||||
{
|
||||
return((Resource->Flag & ResourceOwnedExclusive)
|
||||
&& Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread());
|
||||
return((Resource->Flag & ResourceOwnedExclusive)
|
||||
&& Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
/* note : this function is defined USHORT in nt4, but ULONG in nt5
|
||||
* ULONG is more logical, since return value is number of times the resource
|
||||
* is acquired by the caller, and this value is defined ULONG in
|
||||
* PERESOURCE struct
|
||||
*/
|
||||
ULONG ExIsResourceAcquiredSharedLite(PERESOURCE Resource)
|
||||
/*
|
||||
* FUNCTION: Returns whether the current thread has shared access to a given
|
||||
* resource
|
||||
* ARGUMENTS:
|
||||
* Resource = Points to the resource to be queried
|
||||
* RETURNS: The number of times the caller has acquired shared access to the
|
||||
* given resource
|
||||
*/
|
||||
{
|
||||
long i;
|
||||
if(Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
|
||||
return Resource->OwnerThreads[0].a.OwnerCount;
|
||||
if(Resource->OwnerThreads[1].OwnerThread==ExGetCurrentResourceThread())
|
||||
return Resource->OwnerThreads[1].a.OwnerCount;
|
||||
if(!Resource->OwnerThreads[1].a.TableSize) return 0;
|
||||
for(i=0;i<Resource->OwnerThreads[1].a.TableSize;i++)
|
||||
{
|
||||
if(Resource->OwnerTable[i].OwnerThread==ExGetCurrentResourceThread())
|
||||
return Resource->OwnerTable[i].a.OwnerCount;
|
||||
}
|
||||
return 0;
|
||||
ULONG i;
|
||||
if (Resource->OwnerThreads[0].OwnerThread == ExGetCurrentResourceThread())
|
||||
{
|
||||
return(Resource->OwnerThreads[0].a.OwnerCount);
|
||||
}
|
||||
if (Resource->OwnerThreads[1].OwnerThread == ExGetCurrentResourceThread())
|
||||
{
|
||||
return(Resource->OwnerThreads[1].a.OwnerCount);
|
||||
}
|
||||
if (!Resource->OwnerThreads[1].a.TableSize)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
for (i=0; i<Resource->OwnerThreads[1].a.TableSize; i++)
|
||||
{
|
||||
if (Resource->OwnerTable[i].OwnerThread==ExGetCurrentResourceThread())
|
||||
{
|
||||
return Resource->OwnerTable[i].a.OwnerCount;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
VOID ExReinitializeResourceLite(PERESOURCE Resource)
|
||||
|
@ -350,7 +553,10 @@ VOID ExReinitializeResourceLite(PERESOURCE Resource)
|
|||
FALSE);
|
||||
KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff);
|
||||
Resource->ActiveCount = 0;
|
||||
if(Resource->OwnerTable) ExFreePool(Resource->OwnerTable);
|
||||
if (Resource->OwnerTable)
|
||||
{
|
||||
ExFreePool(Resource->OwnerTable);
|
||||
}
|
||||
Resource->OwnerThreads[0].OwnerThread=0;
|
||||
Resource->OwnerThreads[0].a.OwnerCount=0;
|
||||
Resource->OwnerThreads[1].OwnerThread=0;
|
||||
|
@ -359,7 +565,8 @@ VOID ExReinitializeResourceLite(PERESOURCE Resource)
|
|||
|
||||
VOID ExReleaseResourceLite(PERESOURCE Resource)
|
||||
{
|
||||
return ExReleaseResourceForThreadLite(Resource,ExGetCurrentResourceThread());
|
||||
return(ExReleaseResourceForThreadLite(Resource,
|
||||
ExGetCurrentResourceThread()));
|
||||
}
|
||||
|
||||
VOID ExReleaseResource(PERESOURCE Resource)
|
||||
|
@ -370,81 +577,79 @@ VOID ExReleaseResource(PERESOURCE Resource)
|
|||
VOID ExReleaseResourceForThread(PERESOURCE Resource,
|
||||
ERESOURCE_THREAD ResourceThreadId)
|
||||
{
|
||||
return ExReleaseResourceForThreadLite(Resource,ResourceThreadId);
|
||||
return(ExReleaseResourceForThreadLite(Resource,ResourceThreadId));
|
||||
}
|
||||
|
||||
VOID ExReleaseResourceForThreadLite(PERESOURCE Resource,
|
||||
ERESOURCE_THREAD ResourceThreadId)
|
||||
/*
|
||||
* FUNCTION: Releases a resource for the given thread
|
||||
* ARGUMENTS:
|
||||
* Resource = Points to the release to release
|
||||
* ResourceThreadId = Identifies the thread that originally acquired
|
||||
* the resource
|
||||
* NOTES: Must be running at IRQL < DISPATCH_LEVEL
|
||||
* BUG: We don't support starving exclusive waiters
|
||||
*/
|
||||
{
|
||||
long i;
|
||||
//FIXME : protect this function from interrupts
|
||||
// perhaps with KeRaiseIrql(SYNCH_LEVEL);
|
||||
if (Resource->Flag & ResourceOwnedExclusive)
|
||||
{
|
||||
if(--Resource->OwnerThreads[0].a.OwnerCount == 0)
|
||||
{//release the resource
|
||||
Resource->OwnerThreads[0].OwnerThread=0;
|
||||
assert(--Resource->ActiveCount == 0);
|
||||
if(Resource->NumberOfExclusiveWaiters)
|
||||
{// get resource to first exclusive waiter
|
||||
KeDispatcherObjectWake(&Resource->ExclusiveWaiters->Header);
|
||||
return;
|
||||
}
|
||||
else
|
||||
Resource->Flag &=(~ResourceOwnedExclusive);
|
||||
if(Resource->NumberOfSharedWaiters)
|
||||
{// get resource to waiters
|
||||
Resource->ActiveCount=Resource->NumberOfSharedWaiters;
|
||||
Resource->NumberOfSharedWaiters=0;
|
||||
KeReleaseSemaphore(Resource->SharedWaiters,0,Resource->ActiveCount,0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//search the entry for this thread
|
||||
if(Resource->OwnerThreads[1].OwnerThread==ResourceThreadId)
|
||||
{
|
||||
if( --Resource->OwnerThreads[1].a.OwnerCount == 0)
|
||||
{
|
||||
Resource->OwnerThreads[1].OwnerThread=0;
|
||||
if( --Resource->ActiveCount ==0) //normally always true
|
||||
{
|
||||
if(Resource->NumberOfExclusiveWaiters)
|
||||
{// get resource to first exclusive waiter
|
||||
KeDispatcherObjectWake(&Resource->ExclusiveWaiters->Header);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(Resource->OwnerThreads[1].OwnerThread) return ;
|
||||
for(i=0;i<Resource->OwnerThreads[1].a.TableSize;i++)
|
||||
{
|
||||
if(Resource->OwnerTable[i].OwnerThread==ResourceThreadId)
|
||||
{
|
||||
if( --Resource->OwnerTable[1].a.OwnerCount == 0)
|
||||
{
|
||||
Resource->OwnerTable[i].OwnerThread=0;
|
||||
if( --Resource->ActiveCount ==0)
|
||||
{
|
||||
ExFreePool(Resource->OwnerTable);
|
||||
Resource->OwnerTable=NULL;
|
||||
Resource->OwnerThreads[1].a.TableSize=0;
|
||||
if(Resource->NumberOfExclusiveWaiters)
|
||||
{// get resource to first exclusive waiter
|
||||
KeDispatcherObjectWake(&Resource->ExclusiveWaiters->Header);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN ExTryToAcquireResourceExclusiveLite(PERESOURCE Resource)
|
||||
{
|
||||
return ExAcquireResourceExclusiveLite(Resource,FALSE);
|
||||
KIRQL oldIrql;
|
||||
|
||||
DPRINT("ExReleaseResourceForThreadLite(Resource %x, ResourceThreadId %x)\n",
|
||||
Resource, ResourceThreadId);
|
||||
|
||||
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
|
||||
|
||||
if (Resource->Flag & ResourceOwnedExclusive)
|
||||
{
|
||||
Resource->OwnerThreads[0].a.OwnerCount--;
|
||||
if (Resource->OwnerThreads[0].a.OwnerCount > 0)
|
||||
{
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExReleaseResourceForThreadLite() finished\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Resource->OwnerThreads[0].OwnerThread = 0;
|
||||
Resource->ActiveCount--;
|
||||
Resource->Flag &=(~ResourceOwnedExclusive);
|
||||
assert(Resource->ActiveCount == 0);
|
||||
if (Resource->NumberOfExclusiveWaiters)
|
||||
{
|
||||
/* get resource to first exclusive waiter */
|
||||
KeSetEvent(Resource->ExclusiveWaiters,
|
||||
IO_NO_INCREMENT,
|
||||
FALSE);
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExReleaseResourceForThreadLite() finished\n");
|
||||
return;
|
||||
}
|
||||
if (Resource->NumberOfSharedWaiters)
|
||||
{
|
||||
KeReleaseSemaphore(Resource->SharedWaiters,
|
||||
IO_NO_INCREMENT,
|
||||
Resource->ActiveCount,
|
||||
FALSE);
|
||||
}
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExReleaseResourceForThreadLite() finished\n");
|
||||
return;
|
||||
}
|
||||
|
||||
EiRemoveSharedOwner(Resource, ResourceThreadId);
|
||||
|
||||
if (Resource->ActiveCount == 0)
|
||||
{
|
||||
if (Resource->NumberOfExclusiveWaiters)
|
||||
{
|
||||
/* get resource to first exclusive waiter */
|
||||
KeSetEvent(Resource->ExclusiveWaiters,
|
||||
IO_NO_INCREMENT,
|
||||
FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
|
||||
DPRINT("ExReleaseResourceForThreadLite() finished\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ex/stamp.c
|
||||
* PURPOSE: Graceful system shutdown if a bug is detected
|
||||
* PURPOSE: Versioning
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
|
|
|
@ -7,9 +7,6 @@
|
|||
#
|
||||
#
|
||||
#
|
||||
CbInitDccb
|
||||
CbAcquireForRead
|
||||
CbReleaseFromRead
|
||||
DbgPrint
|
||||
ExAcquireFastMutex
|
||||
ExAcquireFastMutexUnsafe
|
||||
|
@ -121,6 +118,7 @@ IoConnectInterrupt
|
|||
IoCreateController
|
||||
IoCreateDevice
|
||||
IoCreateNotificationEvent
|
||||
IoCreateStreamFileObject
|
||||
IoCreateSymbolicLink
|
||||
IoCreateSynchronizationEvent
|
||||
IoCreateUnprotectedSymbolicLink
|
||||
|
@ -397,3 +395,12 @@ wcschr
|
|||
wcscpy
|
||||
wcsncat
|
||||
wcsncpy
|
||||
#wtolower
|
||||
tolower
|
||||
toupper
|
||||
memcpy
|
||||
strtok
|
||||
CcInitializeFileCache
|
||||
CcRequestCachePage
|
||||
CcReleaseCachePage
|
||||
CcReleaseFileCache
|
||||
|
|
|
@ -226,11 +226,17 @@ asmlinkage void exception_handler(unsigned int edi,
|
|||
DbgPrint("EDI: %.8x EFLAGS: %.8x ",edi,eflags);
|
||||
if ((cs&0xffff) == KERNEL_CS)
|
||||
{
|
||||
DbgPrint("ESP %.8x\n",esp);
|
||||
DbgPrint("kESP %.8x\n",esp);
|
||||
if (PsGetCurrentThread() != NULL)
|
||||
{
|
||||
DbgPrint("kernel stack base %x\n",
|
||||
PsGetCurrentThread()->Tcb.Context.KernelStackBase);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("ESP %.8x\n",esp);
|
||||
DbgPrint("kernel ESP %.8x\n",esp);
|
||||
}
|
||||
|
||||
if ((cs & 0xffff) == KERNEL_CS)
|
||||
|
@ -288,6 +294,8 @@ asmlinkage void exception_handler(unsigned int edi,
|
|||
}
|
||||
}
|
||||
|
||||
DPRINT("Killing current task\n");
|
||||
KeLowerIrql(PASSIVE_LEVEL);
|
||||
if ((cs&0xffff) == USER_CS)
|
||||
{
|
||||
ZwTerminateProcess(NtCurrentProcess(),
|
||||
|
@ -307,7 +315,8 @@ VOID KeDumpStackFrames(ULONG DummyArg, ULONG NrFrames)
|
|||
DbgPrint("Frames:\n");
|
||||
for (i=0; i<NrFrames; i++)
|
||||
{
|
||||
if (Stack[i] > KERNEL_BASE && Stack[i] < ((ULONG)&etext))
|
||||
// if (Stack[i] > KERNEL_BASE && Stack[i] < ((ULONG)&etext))
|
||||
if (Stack[i] > KERNEL_BASE)
|
||||
{
|
||||
DbgPrint("%.8x ",Stack[i]);
|
||||
}
|
||||
|
|
|
@ -105,7 +105,10 @@ asmlinkage VOID KiInterruptDispatch(ULONG irq)
|
|||
* Notify the rest of the kernel of the raised irq level
|
||||
*/
|
||||
old_level = KeGetCurrentIrql();
|
||||
// DPRINT("old_level %d\n",old_level);
|
||||
if (irq != 0)
|
||||
{
|
||||
DPRINT("old_level %d\n",old_level);
|
||||
}
|
||||
KeSetCurrentIrql(HIGH_LEVEL - irq);
|
||||
|
||||
/*
|
||||
|
@ -120,7 +123,7 @@ asmlinkage VOID KiInterruptDispatch(ULONG irq)
|
|||
}
|
||||
else
|
||||
{
|
||||
DPRINT("KiInterruptDispatch(irq %x)\n",irq);
|
||||
DPRINT("KiInterruptDispatch(irq %d)\n",irq);
|
||||
/*
|
||||
* Iterate the list until one of the isr tells us its device interrupted
|
||||
*/
|
||||
|
@ -299,7 +302,6 @@ NTSTATUS IoConnectInterrupt(PKINTERRUPT* InterruptObject,
|
|||
{
|
||||
isr_lock[Vector]=ExAllocatePool(NonPagedPool,sizeof(KSPIN_LOCK));
|
||||
KeInitializeSpinLock(isr_lock[Vector]);
|
||||
isr_lock[Vector]->irql = SynchronizeIrql;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -52,10 +52,14 @@ static void HiSwitchIrql(void)
|
|||
*/
|
||||
{
|
||||
unsigned int i;
|
||||
PKTHREAD CurrentThread;
|
||||
|
||||
CurrentThread = KeGetCurrentThread();
|
||||
|
||||
if (CurrentIrql == HIGH_LEVEL)
|
||||
{
|
||||
HiSetCurrentPICMask(0xffff);
|
||||
// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = TRUE;
|
||||
return;
|
||||
}
|
||||
if (CurrentIrql > DISPATCH_LEVEL)
|
||||
|
@ -68,16 +72,28 @@ static void HiSwitchIrql(void)
|
|||
}
|
||||
|
||||
HiSetCurrentPICMask(current_mask);
|
||||
// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = TRUE;
|
||||
__asm__("sti\n\t");
|
||||
return;
|
||||
}
|
||||
|
||||
if (CurrentIrql <= DISPATCH_LEVEL)
|
||||
if (CurrentIrql == DISPATCH_LEVEL)
|
||||
{
|
||||
// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = TRUE;
|
||||
HiSetCurrentPICMask(0);
|
||||
__asm__("sti\n\t");
|
||||
return;
|
||||
}
|
||||
if (CurrentIrql == APC_LEVEL)
|
||||
{
|
||||
// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = TRUE;
|
||||
HiSetCurrentPICMask(0);
|
||||
__asm__("sti\n\t");
|
||||
return;
|
||||
}
|
||||
// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = FALSE;
|
||||
HiSetCurrentPICMask(0);
|
||||
__asm__("sti\n\t");
|
||||
}
|
||||
|
||||
VOID KeSetCurrentIrql(KIRQL newlvl)
|
||||
|
@ -135,6 +151,7 @@ VOID KeRaiseIrql(KIRQL NewIrql, PKIRQL OldIrql)
|
|||
{
|
||||
DbgPrint("%s:%d CurrentIrql %x NewIrql %x OldIrql %x\n",
|
||||
__FILE__,__LINE__,CurrentIrql,NewIrql,OldIrql);
|
||||
KeBugCheck(0);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
|
|
|
@ -354,7 +354,6 @@ void HalInitConsole(boot_param* bp)
|
|||
* bp = Parameters setup by the boot loader
|
||||
*/
|
||||
{
|
||||
// int offset;
|
||||
|
||||
#ifdef SERIAL_DEBUGGING
|
||||
/* turn on DTR and RTS */
|
||||
|
|
|
@ -56,7 +56,7 @@ VOID KeInitializeSpinLock(PKSPIN_LOCK SpinLock)
|
|||
* SpinLock = Caller supplied storage for the spinlock
|
||||
*/
|
||||
{
|
||||
SpinLock->irql = DISPATCH_LEVEL;
|
||||
SpinLock->Lock = 0;
|
||||
}
|
||||
|
||||
VOID KeAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock)
|
||||
|
@ -67,6 +67,11 @@ VOID KeAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock)
|
|||
* SpinLock = Spinlock to acquire
|
||||
*/
|
||||
{
|
||||
while(InterlockedExchange(&SpinLock->Lock, 1) == 1)
|
||||
{
|
||||
DbgPrint("Spinning on spinlock\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
}
|
||||
|
||||
VOID KeReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock)
|
||||
|
@ -77,6 +82,12 @@ VOID KeReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock)
|
|||
* SpinLock = Spinlock to release
|
||||
*/
|
||||
{
|
||||
if (SpinLock->Lock != 1)
|
||||
{
|
||||
DbgPrint("Releasing unacquired spinlock\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
(void)InterlockedExchange(&SpinLock->Lock, 0);
|
||||
}
|
||||
|
||||
VOID KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
|
||||
|
@ -88,6 +99,7 @@ VOID KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
|
|||
*/
|
||||
{
|
||||
KeRaiseIrql(DISPATCH_LEVEL,OldIrql);
|
||||
KeAcquireSpinLockAtDpcLevel(SpinLock);
|
||||
}
|
||||
|
||||
VOID KeReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL NewIrql)
|
||||
|
@ -98,6 +110,7 @@ VOID KeReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL NewIrql)
|
|||
* NewIrql = Irql level before acquiring the spinlock
|
||||
*/
|
||||
{
|
||||
KeReleaseSpinLockFromDpcLevel(SpinLock);
|
||||
KeLowerIrql(NewIrql);
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ PIRP IoBuildFilesystemControlRequest(ULONG MinorFunction,
|
|||
|
||||
Irp->UserIosb = IoStatusBlock;
|
||||
Irp->UserEvent = UserEvent;
|
||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
|
||||
|
@ -153,6 +154,9 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
|
|||
return(NULL);
|
||||
}
|
||||
|
||||
Irp->UserIosb = IoStatusBlock;
|
||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->MajorFunction = MajorFunction;
|
||||
StackPtr->MinorFunction = 0;
|
||||
|
@ -161,30 +165,32 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
|
|||
StackPtr->DeviceObject = DeviceObject;
|
||||
StackPtr->FileObject = NULL;
|
||||
StackPtr->CompletionRoutine = NULL;
|
||||
StackPtr->Parameters.Write.Length = Length;
|
||||
|
||||
if (MajorFunction == IRP_MJ_READ || MajorFunction == IRP_MJ_WRITE)
|
||||
if (Buffer != NULL)
|
||||
{
|
||||
Irp->UserBuffer = (LPVOID)Buffer;
|
||||
if (DeviceObject->Flags&DO_BUFFERED_IO)
|
||||
IoPrepareIrpBuffer(Irp,
|
||||
DeviceObject,
|
||||
Buffer,
|
||||
Length,
|
||||
MajorFunction);
|
||||
}
|
||||
|
||||
if (MajorFunction == IRP_MJ_READ)
|
||||
{
|
||||
StackPtr->Parameters.Read.Length = Length;
|
||||
if (StartingOffset!=NULL)
|
||||
{
|
||||
DPRINT("Doing buffer i/o\n",0);
|
||||
Irp->AssociatedIrp.SystemBuffer = (PVOID)
|
||||
ExAllocatePool(NonPagedPool,Length);
|
||||
if (Irp->AssociatedIrp.SystemBuffer==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
|
||||
}
|
||||
if (DeviceObject->Flags&DO_DIRECT_IO)
|
||||
else
|
||||
{
|
||||
DPRINT("Doing direct i/o\n",0);
|
||||
|
||||
Irp->MdlAddress = MmCreateMdl(NULL,Buffer,Length);
|
||||
MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
|
||||
Irp->UserBuffer = NULL;
|
||||
Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
}
|
||||
StackPtr->Parameters.Read.ByteOffset.u.LowPart = 0;
|
||||
StackPtr->Parameters.Read.ByteOffset.u.LowPart = 0;
|
||||
}
|
||||
}
|
||||
else if (MajorFunction == IRP_MJ_WRITE)
|
||||
{
|
||||
StackPtr->Parameters.Write.Length = Length;
|
||||
if (StartingOffset!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
|
||||
|
@ -194,7 +200,7 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
|
|||
StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Irp->UserIosb = IoStatusBlock;
|
||||
|
||||
return(Irp);
|
||||
|
@ -246,6 +252,7 @@ PIRP IoBuildDeviceIoControlRequest(ULONG IoControlCode,
|
|||
|
||||
Irp->UserEvent = Event;
|
||||
Irp->UserIosb = IoStatusBlock;
|
||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->MajorFunction = InternalDeviceIoControl ? IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
|
||||
|
@ -396,6 +403,7 @@ PIRP IoBuildSynchronousFsdRequest(ULONG MajorFunction,
|
|||
|
||||
Irp->UserEvent = Event;
|
||||
Irp->UserIosb = IoStatusBlock;
|
||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->MajorFunction = MajorFunction;
|
||||
|
|
|
@ -69,6 +69,11 @@ NTSTATUS IopCreateFile(PVOID ObjectBody,
|
|||
DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %w)\n",
|
||||
ObjectBody,Parent,RemainingPath);
|
||||
|
||||
if (DeviceObject == NULL)
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByPointer(DeviceObject,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
IoDeviceType,
|
||||
|
@ -120,6 +125,41 @@ NTSTATUS IopCreateFile(PVOID ObjectBody,
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject,
|
||||
PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
PFILE_OBJECT CreatedFileObject;
|
||||
|
||||
DbgPrint("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
|
||||
FileObject, DeviceObject);
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
CreatedFileObject = ObCreateObject(&FileHandle,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
IoFileType);
|
||||
if (CreatedFileObject == NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (FileObject != NULL)
|
||||
{
|
||||
DeviceObject = FileObject->DeviceObject;
|
||||
}
|
||||
DeviceObject = IoGetAttachedDevice(DeviceObject);
|
||||
CreatedFileObject->DeviceObject = DeviceObject;
|
||||
CreatedFileObject->Vpb = DeviceObject->Vpb;
|
||||
CreatedFileObject->Type = ID_FILE_OBJECT;
|
||||
CreatedFileObject->Flags = CreatedFileObject->Flags | FO_DIRECT_DEVICE_OPEN;
|
||||
|
||||
ZwClose(FileHandle);
|
||||
|
||||
return(CreatedFileObject);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwCreateFile(PHANDLE FileHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
|
@ -215,10 +255,12 @@ NTSTATUS STDCALL ZwCreateFile(PHANDLE FileHandle,
|
|||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Failing create request with status %x\n",Status);
|
||||
ZwClose(*FileHandle);
|
||||
(*FileHandle) = 0;
|
||||
}
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
DPRINT("Finished ZwCreateFile() (*FileHandle) %x\n",(*FileHandle));
|
||||
return(Status);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/io/device.c
|
||||
* PURPOSE: Manage devices
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
* UPDATE HISTORY:
|
||||
* 15/05/98: Created
|
||||
*/
|
||||
|
@ -82,25 +82,29 @@ PDEVICE_OBJECT IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
|
|||
{
|
||||
PDEVICE_OBJECT Current = DeviceObject;
|
||||
|
||||
DPRINT("IoGetAttachDevice(DeviceObject %x)\n",DeviceObject);
|
||||
// DPRINT("IoGetAttachedDevice(DeviceObject %x)\n",DeviceObject);
|
||||
|
||||
while (Current->AttachedDevice!=NULL)
|
||||
{
|
||||
Current = Current->AttachedDevice;
|
||||
DPRINT("Current %x\n",Current);
|
||||
// DPRINT("Current %x\n",Current);
|
||||
}
|
||||
|
||||
// DPRINT("IoGetAttachedDevice() = %x\n",DeviceObject);
|
||||
return(Current);
|
||||
}
|
||||
|
||||
PDEVICE_OBJECT IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,
|
||||
PDEVICE_OBJECT TargetDevice)
|
||||
{
|
||||
PDEVICE_OBJECT AttachedDevice = IoGetAttachedDevice(TargetDevice);
|
||||
PDEVICE_OBJECT AttachedDevice;
|
||||
|
||||
DPRINT("IoAttachDeviceToDeviceStack(SourceDevice %x, TargetDevice %x)\n",
|
||||
SourceDevice,TargetDevice);
|
||||
|
||||
AttachedDevice = IoGetAttachedDevice(TargetDevice);
|
||||
AttachedDevice->AttachedDevice = SourceDevice;
|
||||
SourceDevice->AttachedDevice = NULL;
|
||||
SourceDevice->StackSize = AttachedDevice->StackSize + 1;
|
||||
SourceDevice->Vpb = AttachedDevice->Vpb;
|
||||
return(AttachedDevice);
|
||||
|
@ -223,7 +227,9 @@ NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject,
|
|||
PDEVICE_OBJECT CreatedDeviceObject;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
HANDLE DeviceHandle;
|
||||
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
if (DeviceName != NULL)
|
||||
{
|
||||
DPRINT("IoCreateDevice(DriverObject %x, DeviceName %w)\n",DriverObject,
|
||||
|
@ -250,7 +256,7 @@ NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject,
|
|||
IoDeviceType);
|
||||
}
|
||||
|
||||
*DeviceObject=NULL;
|
||||
*DeviceObject = NULL;
|
||||
|
||||
if (CreatedDeviceObject == NULL)
|
||||
{
|
||||
|
|
|
@ -184,6 +184,8 @@ NTSTATUS IoAskFileSystemToMountDevice(PDEVICE_OBJECT DeviceObject,
|
|||
DPRINT("IoAskFileSystemToMountDevice(DeviceObject %x, DeviceToMount %x)\n",
|
||||
DeviceObject,DeviceToMount);
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||
Irp = IoBuildFilesystemControlRequest(IRP_MN_MOUNT_VOLUME,
|
||||
DeviceObject,
|
||||
|
@ -217,6 +219,8 @@ NTSTATUS IoTryToMountStorageDevice(PDEVICE_OBJECT DeviceObject)
|
|||
FILE_SYSTEM_OBJECT* current;
|
||||
NTSTATUS Status;
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
DPRINT("IoTryToMountStorageDevice(DeviceObject %x)\n",DeviceObject);
|
||||
|
||||
KeAcquireSpinLock(&FileSystemListLock,&oldlvl);
|
||||
|
@ -224,8 +228,10 @@ NTSTATUS IoTryToMountStorageDevice(PDEVICE_OBJECT DeviceObject)
|
|||
while (current_entry!=(&FileSystemListHead))
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry,FILE_SYSTEM_OBJECT,Entry);
|
||||
KeReleaseSpinLock(&FileSystemListLock,oldlvl);
|
||||
Status = IoAskFileSystemToMountDevice(current->DeviceObject,
|
||||
DeviceObject);
|
||||
KeAcquireSpinLock(&FileSystemListLock,&oldlvl);
|
||||
switch (Status)
|
||||
{
|
||||
case STATUS_FS_DRIVER_REQUIRED:
|
||||
|
|
|
@ -84,10 +84,6 @@ VOID IoMarkIrpPending(PIRP Irp)
|
|||
DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",
|
||||
IoGetCurrentIrpStackLocation(Irp));
|
||||
IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED;
|
||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||
DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n",
|
||||
IoGetCurrentIrpStackLocation(Irp)->Control);
|
||||
DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED);
|
||||
}
|
||||
|
||||
USHORT IoSizeOfIrp(CCHAR StackSize)
|
||||
|
@ -112,10 +108,10 @@ VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)
|
|||
{
|
||||
assert(Irp != NULL);
|
||||
|
||||
memset(Irp,0,PacketSize);
|
||||
Irp->StackCount=StackSize;
|
||||
Irp->CurrentLocation=StackSize;
|
||||
Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp);
|
||||
memset(Irp, 0, PacketSize);
|
||||
Irp->StackCount = StackSize;
|
||||
Irp->CurrentLocation = StackSize;
|
||||
Irp->Tail.Overlay.CurrentStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
}
|
||||
|
||||
PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
|
||||
|
@ -132,10 +128,9 @@ PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
|
|||
Irp->CurrentLocation,
|
||||
Irp->StackCount);
|
||||
|
||||
return &Irp->Stack[(ULONG)Irp->CurrentLocation];
|
||||
return(&Irp->Stack[(ULONG)Irp->CurrentLocation]);
|
||||
}
|
||||
|
||||
|
||||
VOID IoSetNextIrpStackLocation(PIRP Irp)
|
||||
{
|
||||
Irp->CurrentLocation--;
|
||||
|
@ -160,25 +155,25 @@ PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)
|
|||
|
||||
NTSTATUS IoCallDriver(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Sends an IRP to the next lower driver
|
||||
* FUNCTION: Sends an IRP to the next lower driver
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
PIO_STACK_LOCATION param;
|
||||
PIO_STACK_LOCATION Param;
|
||||
|
||||
DPRINT("IoCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
DriverObject = DeviceObject->DriverObject;
|
||||
param = IoGetNextIrpStackLocation(Irp);
|
||||
Param = IoGetNextIrpStackLocation(Irp);
|
||||
|
||||
Irp->Tail.Overlay.CurrentStackLocation--;
|
||||
Irp->CurrentLocation--;
|
||||
|
||||
DPRINT("MajorFunction %d\n",param->MajorFunction);
|
||||
DPRINT("DriverObject->MajorFunction[param->MajorFunction] %x\n",
|
||||
DriverObject->MajorFunction[param->MajorFunction]);
|
||||
Status = DriverObject->MajorFunction[param->MajorFunction](DeviceObject,
|
||||
DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
|
||||
DriverObject->MajorFunction[Param->MajorFunction]);
|
||||
Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject,
|
||||
Irp);
|
||||
return Status;
|
||||
}
|
||||
|
@ -270,6 +265,7 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
|
|||
{
|
||||
unsigned int i;
|
||||
NTSTATUS Status;
|
||||
PKTHREAD Thread;
|
||||
|
||||
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",
|
||||
Irp,PriorityBoost);
|
||||
|
@ -295,15 +291,20 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
|
|||
|
||||
if (Irp->PendingReturned)
|
||||
{
|
||||
Thread = &Irp->Tail.Overlay.Thread->Tcb;
|
||||
KeInitializeApc(&Irp->Tail.Apc,
|
||||
&Irp->Tail.Overlay.Thread->Tcb,
|
||||
Thread,
|
||||
0,
|
||||
IopCompleteRequest,
|
||||
NULL,
|
||||
NULL,
|
||||
(PKNORMAL_ROUTINE)
|
||||
Irp->Overlay.AsynchronousParameters.UserApcRoutine,
|
||||
0,
|
||||
Irp);
|
||||
KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0);
|
||||
(PVOID)Irp);
|
||||
KeInsertQueueApc(&Irp->Tail.Apc,
|
||||
Irp->Overlay.AsynchronousParameters.UserApcContext,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -109,7 +109,7 @@ VOID IoStartPacket(PDEVICE_OBJECT DeviceObject,
|
|||
else
|
||||
{
|
||||
stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
|
||||
&Irp->Tail.Overlay.DeviceQueueEntry);
|
||||
&Irp->Tail.Overlay.DeviceQueueEntry);
|
||||
}
|
||||
|
||||
IoReleaseCancelSpinLock(oldirql);
|
||||
|
|
|
@ -59,11 +59,11 @@ NTSTATUS ZwReadFile(HANDLE FileHandle,
|
|||
PKEVENT ptrEvent = NULL;
|
||||
KEVENT Event;
|
||||
|
||||
assert(KeGetCurrentIrql()==PASSIVE_LEVEL);
|
||||
|
||||
DPRINT("ZwReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, "
|
||||
"IoStatusBlock %x)\n",
|
||||
FileHandle,Buffer,Length,ByteOffset,IoStatusBlock);
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
Status = ObReferenceObjectByHandle(FileHandle,
|
||||
FILE_READ_DATA,
|
||||
|
@ -71,7 +71,7 @@ NTSTATUS ZwReadFile(HANDLE FileHandle,
|
|||
UserMode,
|
||||
(PVOID *) &FileObject,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(STATUS_SUCCESS))
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwReadFile() = %x\n",Status);
|
||||
return(Status);
|
||||
|
@ -112,7 +112,10 @@ NTSTATUS ZwReadFile(HANDLE FileHandle,
|
|||
ByteOffset,
|
||||
ptrEvent,
|
||||
IoStatusBlock);
|
||||
|
||||
|
||||
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
|
||||
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->FileObject = FileObject;
|
||||
if (Key!=NULL)
|
||||
|
@ -124,13 +127,14 @@ NTSTATUS ZwReadFile(HANDLE FileHandle,
|
|||
StackPtr->Parameters.Read.Key = 0;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(FileObject->DeviceObject,Irp);
|
||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||
{
|
||||
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
|
||||
Status = IoStatusBlock->Status;
|
||||
}
|
||||
DPRINT("ZwReadFile() = %x\n",Status);
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
@ -180,7 +184,7 @@ NTSTATUS ZwWriteFile(HANDLE FileHandle,
|
|||
UserMode,
|
||||
(PVOID *) &FileObject,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
@ -197,17 +201,21 @@ NTSTATUS ZwWriteFile(HANDLE FileHandle,
|
|||
ByteOffset,
|
||||
&Event,
|
||||
IoStatusBlock);
|
||||
|
||||
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
|
||||
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
|
||||
|
||||
DPRINT("FileObject->DeviceObject %x\n",FileObject->DeviceObject);
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->FileObject = FileObject;
|
||||
if (Key!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.Key = *Key;
|
||||
}
|
||||
{
|
||||
StackPtr->Parameters.Write.Key = *Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
StackPtr->Parameters.Write.Key = 0;
|
||||
}
|
||||
}
|
||||
Status = IoCallDriver(FileObject->DeviceObject,Irp);
|
||||
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||
{
|
||||
|
|
|
@ -182,6 +182,8 @@ NTSTATUS IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName,
|
|||
HANDLE SymbolicLinkHandle;
|
||||
PSYMLNK_OBJECT SymbolicLink;
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
DPRINT("IoCreateSymbolicLink(SymbolicLinkName %w, DeviceName %w)\n",
|
||||
SymbolicLinkName->Buffer,DeviceName->Buffer);
|
||||
|
||||
|
|
|
@ -23,8 +23,44 @@ extern VOID KeApcProlog(VOID);
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID KeApcProlog2(PKAPC Apc)
|
||||
BOOLEAN KiTestAlert(PKTHREAD Thread,
|
||||
PCONTEXT UserContext)
|
||||
/*
|
||||
* FUNCTION: Tests whether there are any pending APCs for the current thread
|
||||
* and if so the APCs will be delivered on exit from kernel mode.
|
||||
* ARGUMENTS:
|
||||
* Thread = Thread to test for alerts
|
||||
* UserContext = The user context saved on entry to kernel mode
|
||||
*/
|
||||
{
|
||||
PLIST_ENTRY current_entry;
|
||||
PKAPC Apc;
|
||||
PULONG Esp = (PULONG)UserContext->Esp;
|
||||
|
||||
current_entry = Thread->ApcState.ApcListHead[0].Flink;
|
||||
while (current_entry != &Thread->ApcState.ApcListHead[0])
|
||||
{
|
||||
Apc = CONTAINING_RECORD(current_entry, KAPC, ApcListEntry);
|
||||
|
||||
Esp = Esp - 16;
|
||||
Esp[0] = (ULONG)Apc->SystemArgument2;
|
||||
Esp[1] = (ULONG)Apc->SystemArgument1;
|
||||
Esp[2] = (ULONG)Apc->NormalContext;
|
||||
Esp[3] = UserContext->Eip;
|
||||
UserContext->Eip = (ULONG)Apc->NormalRoutine;
|
||||
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
VOID KeApcProlog2(PKAPC Apc)
|
||||
/*
|
||||
* FUNCTION: This is called from the prolog proper (in assembly) to deliver
|
||||
* a kernel APC
|
||||
*/
|
||||
{
|
||||
DPRINT("KeApcProlog2(Apc %x)\n",Apc);
|
||||
Apc->KernelRoutine(Apc,
|
||||
&Apc->NormalRoutine,
|
||||
&Apc->NormalContext,
|
||||
|
@ -42,7 +78,15 @@ VOID KeDeliverKernelApc(PKAPC Apc)
|
|||
PKTHREAD TargetThread;
|
||||
PULONG Stack;
|
||||
|
||||
DPRINT("KeDeliverKernelApc(Apc %x)\n", Apc);
|
||||
|
||||
TargetThread = Apc->Thread;
|
||||
|
||||
if (TargetThread->KernelApcDisable <= 0)
|
||||
{
|
||||
DbgPrint("Queueing apc for thread %x\n", TargetThread);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TargetThread == KeGetCurrentThread())
|
||||
{
|
||||
|
@ -69,12 +113,12 @@ VOID KeDeliverKernelApc(PKAPC Apc)
|
|||
{
|
||||
TargetThread->Context.esp = TargetThread->Context.esp - 40;
|
||||
Stack = (PULONG)TargetThread->Context.esp;
|
||||
Stack[9] = TargetThread->Context.ss;
|
||||
Stack[8] = TargetThread->Context.esp;
|
||||
Stack[7] = TargetThread->Context.gs;
|
||||
Stack[6] = TargetThread->Context.fs;
|
||||
Stack[5] = TargetThread->Context.ds;
|
||||
Stack[4] = TargetThread->Context.es;
|
||||
Stack[9] = TargetThread->Context.gs;
|
||||
Stack[8] = TargetThread->Context.fs;
|
||||
Stack[7] = TargetThread->Context.ds;
|
||||
Stack[6] = TargetThread->Context.es;
|
||||
Stack[5] = TargetThread->Context.ss;
|
||||
Stack[4] = TargetThread->Context.esp;
|
||||
Stack[3] = TargetThread->Context.eflags;
|
||||
Stack[2] = TargetThread->Context.cs;
|
||||
Stack[1] = TargetThread->Context.eip;
|
||||
|
@ -86,17 +130,33 @@ VOID KeDeliverKernelApc(PKAPC Apc)
|
|||
PsResumeThread(CONTAINING_RECORD(TargetThread,ETHREAD,Tcb));
|
||||
}
|
||||
|
||||
void KeInsertQueueApc(struct _KAPC *Apc, PVOID SystemArgument1,
|
||||
PVOID SystemArgument2, UCHAR Mode)
|
||||
void KeInsertQueueApc(PKAPC Apc,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2,
|
||||
UCHAR Mode)
|
||||
{
|
||||
KIRQL oldlvl;
|
||||
PKTHREAD TargetThread;
|
||||
|
||||
DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
|
||||
"SystemArgument2 %x, Mode %d)\n",Apc,SystemArgument1,
|
||||
SystemArgument2,Mode);
|
||||
|
||||
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
|
||||
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
|
||||
|
||||
if (Apc->Inserted)
|
||||
{
|
||||
DbgPrint("KeInsertQueueApc(): multiple APC insertations\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
TargetThread = Apc->Thread;
|
||||
InsertTailList(&TargetThread->ApcState.ApcListHead[0], &Apc->ApcListEntry);
|
||||
Apc->Inserted = TRUE;
|
||||
|
||||
DPRINT("TargetThread->KernelApcDisable %d\n",
|
||||
TargetThread->KernelApcDisable);
|
||||
DPRINT("Apc->KernelRoutine %x\n", Apc->KernelRoutine);
|
||||
if (Apc->KernelRoutine != NULL)
|
||||
{
|
||||
KeDeliverKernelApc(Apc);
|
||||
|
@ -113,17 +173,21 @@ VOID KeInitializeApc(PKAPC Apc,
|
|||
UCHAR Mode,
|
||||
PVOID Context)
|
||||
{
|
||||
memset(Apc,0,sizeof(KAPC));
|
||||
DPRINT("KeInitializeApc(Apc %x, Thread %x, StateIndex %d, "
|
||||
"KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, "
|
||||
"Context %x)\n",Apc,Thread,StateIndex,KernelRoutine,RundownRoutine,
|
||||
NormalRoutine,Mode,Context);
|
||||
memset(Apc, 0, sizeof(KAPC));
|
||||
Apc->Thread = Thread;
|
||||
Apc->ApcListEntry.Flink=NULL;
|
||||
Apc->ApcListEntry.Blink=NULL;
|
||||
Apc->KernelRoutine=KernelRoutine;
|
||||
Apc->RundownRoutine=RundownRoutine;
|
||||
Apc->NormalRoutine=NormalRoutine;
|
||||
Apc->NormalContext=Context;
|
||||
Apc->Inserted=FALSE;
|
||||
Apc->ApcStateIndex=StateIndex;
|
||||
Apc->ApcMode=Mode;
|
||||
Apc->ApcListEntry.Flink = NULL;
|
||||
Apc->ApcListEntry.Blink = NULL;
|
||||
Apc->KernelRoutine = KernelRoutine;
|
||||
Apc->RundownRoutine = RundownRoutine;
|
||||
Apc->NormalRoutine = NormalRoutine;
|
||||
Apc->NormalContext = Context;
|
||||
Apc->Inserted = FALSE;
|
||||
Apc->ApcStateIndex = StateIndex;
|
||||
Apc->ApcMode = Mode;
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,5 +220,7 @@ NTSTATUS STDCALL NtTestAlert(VOID)
|
|||
|
||||
NTSTATUS STDCALL ZwTestAlert(VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
KiTestAlert(KeGetCurrentThread(),
|
||||
NULL /* ?? */);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ VOID KeBugCheckEx(ULONG BugCheckCode,
|
|||
BugCheckParameter1,BugCheckParameter2,BugCheckParameter3,
|
||||
BugCheckParameter4);
|
||||
KeDumpStackFrames(0,64);
|
||||
__asm__("cli\n\t");
|
||||
for(;;);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,16 +12,19 @@
|
|||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID KeEnterCriticalRegion()
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
DPRINT("KeEnterCriticalRegion()\n");
|
||||
KeGetCurrentThread()->KernelApcDisable -= 1;
|
||||
}
|
||||
|
||||
VOID KeLeaveCriticalRegion()
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
DPRINT("KeLeaveCriticalRegion()\n");
|
||||
KeGetCurrentThread()->KernelApcDisable += 1;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,10 @@ void KeDrainDpcQueue(void)
|
|||
PKDPC current;
|
||||
KIRQL oldlvl;
|
||||
|
||||
if (DpcQueueSize == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DPRINT("KeDrainDpcQueue()\n");
|
||||
|
||||
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
|
||||
|
@ -109,7 +113,9 @@ BOOLEAN KeInsertQueueDpc(PKDPC dpc, PVOID SystemArgument1,
|
|||
* FALSE otherwise
|
||||
*/
|
||||
{
|
||||
DPRINT("KeInsertQueueDpc()\n",0);
|
||||
DPRINT("KeInsertQueueDpc(dpc %x, SystemArgument1 %x, SystemArgument2 %x)\n",
|
||||
dpc, SystemArgument1, SystemArgument2);
|
||||
|
||||
assert(KeGetCurrentIrql()>=DISPATCH_LEVEL);
|
||||
|
||||
dpc->Number=0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PURPOSE: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/device.c
|
||||
* FILE: ntoskrnl/ke/kqueue.c
|
||||
* PURPOSE: Implement device queues
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* REVISION HISTORY:
|
||||
|
@ -10,7 +10,6 @@
|
|||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
#define NDEBUG
|
||||
|
|
|
@ -172,11 +172,11 @@ NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
|
|||
|
||||
DPRINT("KeAddThreadTimeout(Thread %x, Interval %x)\n",Thread,Interval);
|
||||
|
||||
KeInitializeTimer(&(Thread->TimerBlock));
|
||||
KeSetTimer(&(Thread->TimerBlock),*Interval,NULL);
|
||||
KeInitializeTimer(&(Thread->Timer));
|
||||
KeSetTimer(&(Thread->Timer),*Interval,NULL);
|
||||
|
||||
DPRINT("Thread->TimerBlock.entry.Flink %x\n",
|
||||
Thread->TimerBlock.entry.Flink);
|
||||
DPRINT("Thread->Timer.entry.Flink %x\n",
|
||||
Thread->Timer.entry.Flink);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ NTSTATUS KeDelayExecutionThread(KPROCESSOR_MODE WaitMode,
|
|||
{
|
||||
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||
KeAddThreadTimeout(CurrentThread,Interval);
|
||||
return(KeWaitForSingleObject(&(CurrentThread->TimerBlock),Executive,
|
||||
return(KeWaitForSingleObject(&(CurrentThread->Timer),Executive,
|
||||
KernelMode,Alertable,NULL));
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
if (Timeout!=NULL)
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
KeAddThreadTimeout(KeGetCurrentThread(),Timeout);
|
||||
}
|
||||
|
@ -228,11 +228,13 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
|
|||
// DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
|
||||
// hdr->WaitListHead.Flink,hdr->WaitListHead.Blink);
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__,
|
||||
KeGetCurrentIrql());
|
||||
PsSuspendThread(PsGetCurrentThread());
|
||||
|
||||
if (Timeout!=NULL)
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
KeCancelTimer(&KeGetCurrentThread()->TimerBlock);
|
||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||
}
|
||||
DPRINT("Returning from KeWaitForSingleObject()\n");
|
||||
return(STATUS_SUCCESS);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <internal/teb.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
@ -56,7 +56,7 @@ static NTSTATUS LdrCreatePeb(HANDLE ProcessHandle)
|
|||
NT_PEB Peb;
|
||||
ULONG BytesWritten;
|
||||
|
||||
PebBase = PEB_BASE;
|
||||
PebBase = (PVOID)PEB_BASE;
|
||||
PebSize = 0x1000;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&PebBase,
|
||||
|
@ -71,7 +71,7 @@ static NTSTATUS LdrCreatePeb(HANDLE ProcessHandle)
|
|||
|
||||
|
||||
memset(&Peb, 0, sizeof(Peb));
|
||||
Peb.StartupInfo = PEB_STARTUPINFO;
|
||||
Peb.StartupInfo = (PPROCESSINFOW)PEB_STARTUPINFO;
|
||||
|
||||
ZwWriteVirtualMemory(ProcessHandle,
|
||||
(PVOID)PEB_BASE,
|
||||
|
|
|
@ -687,7 +687,7 @@ LdrPEProcessModule(PVOID ModuleLoadBase)
|
|||
*ImportAddressList = (PVOID) LdrGetKernelSymbolAddr(SymbolNameBuf);
|
||||
if (*ImportAddressList == 0L)
|
||||
{
|
||||
DbgPrint("Unresolved kernel symbol: %s\n", pName);
|
||||
DbgPrint("Unresolved kernel symbol: %s\n", pName);
|
||||
}
|
||||
}
|
||||
ImportAddressList++;
|
||||
|
|
|
@ -51,7 +51,7 @@ DBG_OBJECTS = dbg/brkpoint.o dbg/errinfo.o
|
|||
|
||||
LDR_OBJECTS = ldr/loader.o ldr/init.o
|
||||
|
||||
CC_OBJECTS = cc/cacheman.o cc/block.o cc/view.o
|
||||
CC_OBJECTS = cc/cacheman.o cc/view.o
|
||||
|
||||
RESOURCE_OBJECT = ntoskrnl.coff
|
||||
|
||||
|
@ -101,7 +101,7 @@ objects/cc.o: $(CC_OBJECTS)
|
|||
$(LD) -r $(CC_OBJECTS) -o objects/cc.o
|
||||
|
||||
objects/ntoskrnl.coff: ntoskrnl.rc ../include/reactos/resource.h
|
||||
windres ntoskrnl.rc objects/ntoskrnl.coff
|
||||
$(RC) ntoskrnl.rc objects/ntoskrnl.coff
|
||||
|
||||
|
||||
OBJECTS = objects/hal.o objects/ke.o objects/rtl.o objects/mm.o \
|
||||
|
@ -133,28 +133,26 @@ else
|
|||
endif
|
||||
$(CC) $(CFLAGS) -c ke/exports.c -o ke/exports.o
|
||||
|
||||
all: ntoskrnl.a ntoskrnl.exe ntoskrnl.sym
|
||||
|
||||
.PHONY: all
|
||||
|
||||
ntoskrnl.exe: ntoskrnl.o ntoskrnl.def
|
||||
$(CC) -specs=../specs -mdll -o junk.tmp \
|
||||
ntoskrnl.exe: $(OBJECTS) ntoskrnl.def
|
||||
$(LD) -r $(OBJECTS) -o ntoskrnl.o
|
||||
$(DLLTOOL) --dllname ntoskrnl.exe --def ntoskrnl.def \
|
||||
--output-lib ntoskrnl.a
|
||||
$(CC) -Wl,-d -specs=../specs -mdll -o junk.tmp \
|
||||
-Wl,--image-base,0xc0000000 \
|
||||
-Wl,--file-alignment,0x1000 \
|
||||
-Wl,--section-alignment,0x1000 \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext -Wl,--base-file,base.tmp \
|
||||
ntoskrnl.o
|
||||
-Wl,--defsym,_end=__bss_end__ \
|
||||
-Wl,--defsym,_etext=etext -Wl,--base-file,base.tmp ntoskrnl.o
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) --dllname ntoskrnl.exe --base-file base.tmp \
|
||||
--output-exp temp.exp --def ntoskrnl.def
|
||||
- $(RM) base.tmp
|
||||
$(CC) -specs=../specs -mdll -o ntoskrnl.exe ntoskrnl.o \
|
||||
$(CC) -Wl,-d -specs=../specs -mdll -o ntoskrnl.exe ntoskrnl.o \
|
||||
-Wl,--image-base,0xc0000000 \
|
||||
-Wl,--file-alignment,0x1000 \
|
||||
-Wl,--section-alignment,0x1000 \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_end=__bss_end__ \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext -Wl,temp.exp
|
||||
- $(RM) temp.exp
|
||||
|
|
|
@ -118,6 +118,7 @@ static MEMORY_AREA* MmInternalOpenMemoryAreaByAddress(PLIST_ENTRY ListHead,
|
|||
{
|
||||
PLIST_ENTRY current_entry;
|
||||
MEMORY_AREA* current;
|
||||
PLIST_ENTRY previous_entry;
|
||||
|
||||
// MmDumpMemoryAreas();
|
||||
|
||||
|
@ -129,10 +130,16 @@ static MEMORY_AREA* MmInternalOpenMemoryAreaByAddress(PLIST_ENTRY ListHead,
|
|||
return(NULL);
|
||||
}
|
||||
|
||||
previous_entry = ListHead;
|
||||
current_entry = ListHead->Flink;
|
||||
while (current_entry!=ListHead)
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
|
||||
DPRINT("Scanning %x BaseAddress %x Length %x\n",
|
||||
current, current->BaseAddress, current->Length);
|
||||
assert(current_entry->Blink->Flink == current_entry);
|
||||
assert(current_entry->Flink->Blink == current_entry);
|
||||
assert(previous_entry->Flink == current_entry);
|
||||
if (current->BaseAddress <= Address &&
|
||||
(current->BaseAddress + current->Length) > Address)
|
||||
{
|
||||
|
@ -144,6 +151,7 @@ static MEMORY_AREA* MmInternalOpenMemoryAreaByAddress(PLIST_ENTRY ListHead,
|
|||
DPRINT("%s() = NULL\n",__FUNCTION__);
|
||||
return(NULL);
|
||||
}
|
||||
previous_entry = current_entry;
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
DPRINT("%s() = NULL\n",__FUNCTION__);
|
||||
|
@ -307,13 +315,14 @@ static VOID MmInsertMemoryAreaWithoutLock(PEPROCESS Process,
|
|||
current_entry->Flink = inserted_entry;
|
||||
inserted_entry->Flink=ListHead;
|
||||
inserted_entry->Blink=current_entry;
|
||||
ListHead->Blink = inserted_entry;
|
||||
return;
|
||||
}
|
||||
if (current->BaseAddress < marea->BaseAddress &&
|
||||
next->BaseAddress > marea->BaseAddress)
|
||||
{
|
||||
inserted_entry->Flink = current_entry->Flink;
|
||||
inserted_entry->Blink = current_entry->Blink;
|
||||
inserted_entry->Blink = current_entry;
|
||||
inserted_entry->Flink->Blink = inserted_entry;
|
||||
current_entry->Flink=inserted_entry;
|
||||
return;
|
||||
|
@ -399,7 +408,20 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process,
|
|||
|
||||
DPRINT("MmFreeMemoryArea(Process %x, BaseAddress %x, Length %x,"
|
||||
"FreePages %d)\n",Process,BaseAddress,Length,FreePages);
|
||||
|
||||
|
||||
if (SystemAreaList.Flink != (&SystemAreaList) &&
|
||||
SystemAreaList.Flink->Flink != (&SystemAreaList))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
PMEMORY_AREA Snd = CONTAINING_RECORD(SystemAreaList.Flink->Flink,
|
||||
MEMORY_AREA,
|
||||
Entry);
|
||||
DPRINT("SystemAreaList.Flink->Flink->BaseAddress %x\n",
|
||||
Snd->BaseAddress);
|
||||
#endif
|
||||
// assert(Snd->BaseAddress == (PVOID)0x0c001c000);
|
||||
}
|
||||
|
||||
MmLockMemoryAreaList(BaseAddress, &oldlvl);
|
||||
|
||||
MemoryArea = MmOpenMemoryAreaByAddressWithoutLock(Process,
|
||||
|
@ -407,6 +429,7 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process,
|
|||
if (MemoryArea==NULL)
|
||||
{
|
||||
MmUnlockMemoryAreaList(BaseAddress, &oldlvl);
|
||||
KeBugCheck(0);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (FreePages)
|
||||
|
@ -429,6 +452,20 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process,
|
|||
RemoveEntryList(&(MemoryArea->Entry));
|
||||
ExFreePool(MemoryArea);
|
||||
MmUnlockMemoryAreaList(BaseAddress, &oldlvl);
|
||||
|
||||
if (SystemAreaList.Flink != (&SystemAreaList) &&
|
||||
SystemAreaList.Flink->Flink != (&SystemAreaList))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
PMEMORY_AREA Snd = CONTAINING_RECORD(SystemAreaList.Flink->Flink,
|
||||
MEMORY_AREA,
|
||||
Entry);
|
||||
DPRINT("SystemAreaList.Flink->Flink->BaseAddress %x\n",
|
||||
Snd->BaseAddress);
|
||||
#endif
|
||||
// assert(Snd->BaseAddress == (PVOID)0x0c001c000);
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -507,7 +544,19 @@ NTSTATUS MmCreateMemoryArea(KPROCESSOR_MODE Mode,
|
|||
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
|
||||
Mode,Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
|
||||
|
||||
|
||||
if (SystemAreaList.Flink != (&SystemAreaList) &&
|
||||
SystemAreaList.Flink->Flink != (&SystemAreaList))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
PMEMORY_AREA Snd = CONTAINING_RECORD(SystemAreaList.Flink->Flink,
|
||||
MEMORY_AREA,
|
||||
Entry);
|
||||
DPRINT("SystemAreaList.Flink->Flink->BaseAddress %x\n",
|
||||
Snd->BaseAddress);
|
||||
// assert(Snd->BaseAddress == (PVOID)0x0c001c000);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((*BaseAddress)==0)
|
||||
{
|
||||
MmLockMemoryAreaListByMode(Mode,&oldlvl);
|
||||
|
@ -551,6 +600,18 @@ NTSTATUS MmCreateMemoryArea(KPROCESSOR_MODE Mode,
|
|||
MmInsertMemoryAreaWithoutLock(Process,*Result);
|
||||
MmUnlockMemoryAreaList(*BaseAddress,&oldlvl);
|
||||
|
||||
if (SystemAreaList.Flink != (&SystemAreaList) &&
|
||||
SystemAreaList.Flink->Flink != (&SystemAreaList))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
PMEMORY_AREA Snd = CONTAINING_RECORD(SystemAreaList.Flink->Flink,
|
||||
MEMORY_AREA,
|
||||
Entry);
|
||||
DPRINT("SystemAreaList.Flink->Flink->BaseAddress %x\n",
|
||||
Snd->BaseAddress);
|
||||
#endif
|
||||
// assert(Snd->BaseAddress == (PVOID)0x0c001c000);
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -50,12 +50,14 @@ PVOID MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
|||
ULONG* mdl_pages=NULL;
|
||||
MEMORY_AREA* Result;
|
||||
|
||||
DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
|
||||
|
||||
DPRINT("Mdl->ByteCount %x\n",Mdl->ByteCount);
|
||||
DPRINT("PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE) %x\n",
|
||||
PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE);
|
||||
|
||||
MmCreateMemoryArea(KernelMode,
|
||||
PsGetCurrentProcess(),
|
||||
NULL,
|
||||
MEMORY_AREA_MDL_MAPPING,
|
||||
&base,
|
||||
Mdl->ByteCount + Mdl->ByteOffset,
|
||||
|
@ -85,8 +87,12 @@ VOID MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
|||
* MemoryDescriptorList = MDL describing the mapped pages
|
||||
*/
|
||||
{
|
||||
(void)MmFreeMemoryArea(PsGetCurrentProcess(),BaseAddress-Mdl->ByteOffset,
|
||||
Mdl->ByteCount,FALSE);
|
||||
DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", Mdl, BaseAddress);
|
||||
(void)MmFreeMemoryArea(NULL,
|
||||
BaseAddress-Mdl->ByteOffset,
|
||||
Mdl->ByteCount,
|
||||
FALSE);
|
||||
DPRINT("MmUnmapLockedPages() finished\n");
|
||||
}
|
||||
|
||||
VOID MmPrepareMdlForReuse(PMDL Mdl)
|
||||
|
@ -118,7 +124,7 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode,
|
|||
DPRINT("MmProbeAndLockPages(Mdl %x)\n",Mdl);
|
||||
DPRINT("StartVa %x\n",Mdl->StartVa);
|
||||
|
||||
marea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),
|
||||
marea = MmOpenMemoryAreaByAddress(Mdl->Process,
|
||||
Mdl->StartVa);
|
||||
DPRINT("marea %x\n",marea);
|
||||
|
||||
|
@ -203,11 +209,14 @@ PVOID MmGetSystemAddressForMdl(PMDL Mdl)
|
|||
* pages described by the given MDL.
|
||||
*/
|
||||
{
|
||||
DPRINT("MmGetSystemAddressForMdl(Mdl %x)\n", Mdl);
|
||||
|
||||
if (!( (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) ||
|
||||
(Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) ))
|
||||
{
|
||||
Mdl->MappedSystemVa = MmMapLockedPages(Mdl,KernelMode);
|
||||
}
|
||||
DPRINT("Returning %x\n",Mdl->MappedSystemVa);
|
||||
return(Mdl->MappedSystemVa);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <internal/hal/io.h>
|
||||
#include <internal/i386/segment.h>
|
||||
#include <internal/stddef.h>
|
||||
#include <internal/mm.h>
|
||||
|
@ -43,7 +44,7 @@ static BOOLEAN IsThisAnNtAsSystem = FALSE;
|
|||
static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem;
|
||||
|
||||
extern unsigned int etext;
|
||||
extern unsigned int end;
|
||||
extern unsigned int _bss_end__;
|
||||
|
||||
static MEMORY_AREA* kernel_text_desc = NULL;
|
||||
static MEMORY_AREA* kernel_data_desc = NULL;
|
||||
|
@ -52,7 +53,7 @@ static MEMORY_AREA* kernel_pool_desc = NULL;
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
void VirtualInit(boot_param* bp)
|
||||
VOID MmInitVirtualMemory(boot_param* bp)
|
||||
/*
|
||||
* FUNCTION: Intialize the memory areas list
|
||||
* ARGUMENTS:
|
||||
|
@ -65,7 +66,7 @@ void VirtualInit(boot_param* bp)
|
|||
ULONG Length;
|
||||
ULONG ParamLength = kernel_len;
|
||||
|
||||
DPRINT("VirtualInit() %x\n",bp);
|
||||
DPRINT("MmInitVirtualMemory(%x)\n",bp);
|
||||
|
||||
MmInitMemoryAreas();
|
||||
ExInitNonPagedPool(KERNEL_BASE+ PAGE_ROUND_UP(kernel_len) + PAGESIZE);
|
||||
|
@ -80,10 +81,12 @@ void VirtualInit(boot_param* bp)
|
|||
MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,
|
||||
Length,0,&kernel_text_desc);
|
||||
|
||||
Length = PAGE_ROUND_UP(((ULONG)&end)) - PAGE_ROUND_UP(((ULONG)&etext));
|
||||
Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) -
|
||||
PAGE_ROUND_UP(((ULONG)&etext));
|
||||
ParamLength = ParamLength - Length;
|
||||
DPRINT("Length %x\n",Length);
|
||||
BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&etext));
|
||||
DPRINT("BaseAddress %x\n",BaseAddress);
|
||||
MmCreateMemoryArea(KernelMode,
|
||||
NULL,
|
||||
MEMORY_AREA_SYSTEM,
|
||||
|
@ -92,7 +95,6 @@ void VirtualInit(boot_param* bp)
|
|||
0,
|
||||
&kernel_data_desc);
|
||||
|
||||
|
||||
BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&end));
|
||||
Length = ParamLength;
|
||||
MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,
|
||||
|
@ -106,6 +108,8 @@ void VirtualInit(boot_param* bp)
|
|||
// MmDumpMemoryAreas();
|
||||
CHECKPOINT;
|
||||
|
||||
// while (inb_p(0x60)!=0x1); inb_p(0x60);
|
||||
|
||||
MmInitSectionImplementation();
|
||||
}
|
||||
|
||||
|
@ -173,9 +177,9 @@ asmlinkage int page_fault_handler(unsigned int cs,
|
|||
|
||||
cr2 = PAGE_ROUND_DOWN(cr2);
|
||||
|
||||
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
|
||||
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
|
||||
{
|
||||
DbgPrint("Page fault at high IRQL\n");
|
||||
DbgPrint("Page fault at high IRQL was %d\n", KeGetCurrentIrql());
|
||||
return(0);
|
||||
// KeBugCheck(0);
|
||||
}
|
||||
|
@ -307,8 +311,9 @@ void MmInitialize(boot_param* bp, ULONG LastKernelAddress)
|
|||
MmSetPage(NULL, (PVOID)(i), PAGE_NOACCESS, 0);
|
||||
}
|
||||
DPRINT("Almost done MmInit()\n");
|
||||
|
||||
/*
|
||||
* Intialize memory areas
|
||||
*/
|
||||
VirtualInit(bp);
|
||||
MmInitVirtualMemory(bp);
|
||||
}
|
||||
|
|
|
@ -27,17 +27,17 @@
|
|||
|
||||
NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
||||
{
|
||||
ULONG i;
|
||||
PHYSICAL_ADDRESS addr;
|
||||
PVOID i;
|
||||
|
||||
DPRINT("MmReleaseMemoryArea(Process %x, Marea %x)\n",Process,Marea);
|
||||
|
||||
DPRINT("Releasing %x between %x %x\n",
|
||||
Marea, Marea->BaseAddress, Marea->BaseAddress + Marea->Length);
|
||||
for (i=Marea->BaseAddress; i<(Marea->BaseAddress + Marea->Length);
|
||||
i=i+PAGESIZE)
|
||||
for (i = Marea->BaseAddress;
|
||||
i < (Marea->BaseAddress + Marea->Length);
|
||||
i = i+PAGESIZE)
|
||||
{
|
||||
MmDeletePageEntry(Process, (PVOID)i, TRUE);
|
||||
MmDeletePageEntry(Process, i, TRUE);
|
||||
}
|
||||
ExFreePool(Marea);
|
||||
|
||||
|
@ -46,7 +46,6 @@ NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
|||
|
||||
NTSTATUS MmReleaseMmInfo(PEPROCESS Process)
|
||||
{
|
||||
ULONG i,j,addr;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PMEMORY_AREA Current;
|
||||
|
||||
|
|
|
@ -182,8 +182,8 @@ NTSTATUS STDCALL NtListenPort(HANDLE PortHandle,
|
|||
MmUnmapLockedPages(Data, KMsg->Mdl);
|
||||
Status = ObCreateHandle(PsGetCurrentProcess(),
|
||||
KMsg->ReplyPort,
|
||||
FALSE,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
FALSE,
|
||||
&Msg->ReplyPort);
|
||||
ObDereferenceObject(PortHandle);
|
||||
return(Status);
|
||||
|
|
|
@ -1,10 +1,70 @@
|
|||
EXPORTS
|
||||
CbInitDccb
|
||||
CbAcquireForRead
|
||||
CbReleaseFromRead
|
||||
DbgPrint
|
||||
ExAcquireResourceExclusive
|
||||
ExAcquireResourceExclusiveLite
|
||||
ExAcquireResourceSharedLite
|
||||
ExAcquireSharedStarveExclusive
|
||||
ExAcquireSharedWaitForExclusive
|
||||
ExAllocateFromNPagedLookasideList
|
||||
ExAllocateFromPagedLookasideList
|
||||
ExAllocateFromZone
|
||||
ExAllocatePool
|
||||
ExAllocatePoolWithQuota
|
||||
;ExAllocatePoolWithQuotaTag
|
||||
ExAllocatePoolWithTag
|
||||
ExConvertExclusiveToSharedLite
|
||||
ExDeleteNPagedLookasideList
|
||||
ExDeletePagedLookasideList
|
||||
ExDeleteResource
|
||||
ExDeleteResourceLite
|
||||
ExExtendZone
|
||||
ExFreePool
|
||||
ExFreeToNPagedLookasideList
|
||||
ExFreeToPagedLookasideList
|
||||
ExFreeToZone
|
||||
ExGetCurrentResourceThread
|
||||
ExGetExclusiveWaiterCount
|
||||
ExGetSharedWaiterCount
|
||||
ExInitializeFastMutex
|
||||
ExInitializeNPagedLookasideList
|
||||
ExInitializePagedLookasideList
|
||||
ExInitializeResource
|
||||
ExInitializeResourceLite
|
||||
ExInitializeSListHead
|
||||
ExInitializeWorkItem
|
||||
ExInitializeZone
|
||||
ExInterlockedAddLargeInteger
|
||||
ExInterlockedAddUlong
|
||||
ExInterlockedAllocateFromZone
|
||||
ExInterlockedDecrementLong
|
||||
ExInterlockedExchangeUlong
|
||||
ExInterlockedExtendZone
|
||||
ExInterlockedFreeToZone
|
||||
ExInterlockedIncrementLong
|
||||
ExInterlockedInsertHeadList
|
||||
ExInterlockedInsertTailList
|
||||
ExInterlockedPopEntryList
|
||||
ExInterlockedPopEntrySList
|
||||
ExInterlockedPushEntryList
|
||||
ExInterlockedPushEntrySList
|
||||
ExInterlockedRemoveHeadList
|
||||
ExIsFullZone
|
||||
ExIsObjectInFirstZoneSegment
|
||||
ExIsResourceAcquiredExclusiveLite
|
||||
ExIsResourceAcquiredSharedLite
|
||||
ExLocalTimeToSystemTime
|
||||
ExQueryDepthSListHead
|
||||
ExQueueWorkItem
|
||||
ExRaiseStatus
|
||||
ExReinitializeResourceLite
|
||||
ExReleaseFastMutex
|
||||
ExReleaseFastMutexUnsafe
|
||||
ExReleaseResource
|
||||
ExReleaseResourceForThread
|
||||
ExReleaseResourceForThreadLite
|
||||
ExSystemTimeToLocalTime
|
||||
ExTryToAcquireFastMutex
|
||||
ExTryToAcquireResourceExclusiveLite
|
||||
HalGetInterruptVector
|
||||
KeBugCheck
|
||||
KeBugCheckEx
|
||||
|
@ -27,6 +87,7 @@ IoCompleteRequest
|
|||
IoConnectInterrupt
|
||||
IoCreateController
|
||||
IoCreateDevice
|
||||
IoCreateStreamFileObject
|
||||
IoCreateSymbolicLink
|
||||
IoDeleteController
|
||||
IoDisconnectInterrupt
|
||||
|
@ -58,6 +119,10 @@ RtlTimeFieldsToTime
|
|||
RtlTimeToTimeFields
|
||||
RtlZeroMemory
|
||||
ZwCreateDirectoryObject@12
|
||||
CcInitializeFileCache
|
||||
CcRequestCachePage
|
||||
CcReleaseCachePage
|
||||
CcReleaseFileCache
|
||||
isdigit
|
||||
islower
|
||||
isprint
|
||||
|
|
|
@ -60,7 +60,7 @@ static PHANDLE_REP ObpGetObjectByHandle(PEPROCESS Process,
|
|||
for (i=0;i<count;i++)
|
||||
{
|
||||
current = current->Flink;
|
||||
if (current==(&(Process->Pcb.HandleTable.ListHead)))
|
||||
if (current == (&(Process->Pcb.HandleTable.ListHead)))
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
@ -122,6 +122,8 @@ NTSTATUS STDCALL ZwDuplicateObject(IN HANDLE SourceProcessHandle,
|
|||
PEPROCESS SourceProcess;
|
||||
PEPROCESS TargetProcess;
|
||||
PHANDLE_REP SourceHandleRep;
|
||||
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
|
||||
ObReferenceObjectByHandle(SourceProcessHandle,
|
||||
PROCESS_DUP_HANDLE,
|
||||
|
@ -340,18 +342,30 @@ NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
|
|||
DPRINT("Referencing current process %x\n", PsGetCurrentProcess());
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
else if (Handle == NtCurrentProcess())
|
||||
{
|
||||
CHECKPOINT;
|
||||
return(STATUS_OBJECT_TYPE_MISMATCH);
|
||||
}
|
||||
if (Handle == NtCurrentThread() &&
|
||||
(ObjectType == PsThreadType || ObjectType == NULL))
|
||||
{
|
||||
BODY_TO_HEADER(PsGetCurrentThread())->RefCount++;
|
||||
*Object = PsGetCurrentThread();
|
||||
CHECKPOINT;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
else if (Handle == NtCurrentThread())
|
||||
{
|
||||
CHECKPOINT;
|
||||
return(STATUS_OBJECT_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
HandleRep = ObpGetObjectByHandle(PsGetCurrentProcess(),
|
||||
Handle);
|
||||
if (HandleRep == NULL || HandleRep->ObjectBody == NULL)
|
||||
{
|
||||
CHECKPOINT;
|
||||
return(STATUS_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
|
@ -359,11 +373,13 @@ NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
|
|||
|
||||
if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)
|
||||
{
|
||||
CHECKPOINT;
|
||||
return(STATUS_OBJECT_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
if (!(HandleRep->GrantedAccess & DesiredAccess))
|
||||
{
|
||||
CHECKPOINT;
|
||||
return(STATUS_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
|
@ -371,6 +387,7 @@ NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
|
|||
|
||||
*Object = HandleRep->ObjectBody;
|
||||
|
||||
CHECKPOINT;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -129,6 +129,8 @@ PVOID ObCreateObject(PHANDLE Handle,
|
|||
POBJECT_HEADER Header;
|
||||
NTSTATUS Status;
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n");
|
||||
if (ObjectAttributes != NULL &&
|
||||
ObjectAttributes->ObjectName != NULL)
|
||||
|
|
|
@ -49,7 +49,7 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
|
|||
ObDereferenceObject(CurrentThread->ThreadsProcess);
|
||||
CurrentThread->ThreadsProcess = NULL;
|
||||
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
|
||||
CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;
|
||||
CurrentThread->Tcb.State = THREAD_STATE_TERMINATED;
|
||||
ZwYieldExecution();
|
||||
for(;;);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ HANDLE SystemProcessHandle = NULL;
|
|||
|
||||
POBJECT_TYPE PsProcessType = NULL;
|
||||
|
||||
static ULONG NextUniqueProcessId = 0;
|
||||
static ULONG PiNextProcessUniqueId = 0;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -80,9 +80,8 @@ VOID PsInitProcessManagment(VOID)
|
|||
InitializeListHead(&(KProcess->MemoryAreaList));
|
||||
ObCreateHandleTable(NULL,FALSE,SystemProcess);
|
||||
KProcess->PageTableDirectory = get_page_directory();
|
||||
|
||||
SystemProcess->UniqueProcessId = NextUniqueProcessId;
|
||||
SystemProcess->InheritedFromUniqueProcessId = NextUniqueProcessId;
|
||||
SystemProcess->UniqueProcessId =
|
||||
InterlockedIncrement(&PiNextProcessUniqueId);
|
||||
|
||||
ObCreateHandle(SystemProcess,
|
||||
SystemProcess,
|
||||
|
@ -197,12 +196,13 @@ NTSTATUS STDCALL ZwCreateProcess(
|
|||
KProcess = &(Process->Pcb);
|
||||
|
||||
InitializeListHead(&(KProcess->MemoryAreaList));
|
||||
Process->UniqueProcessId = InterlockedIncrement(&NextUniqueProcessId);
|
||||
Process->UniqueProcessId = InterlockedIncrement(&PiNextProcessUniqueId);
|
||||
Process->InheritedFromUniqueProcessId = ParentProcess->UniqueProcessId;
|
||||
ObCreateHandleTable(ParentProcess,
|
||||
InheritObjectTable,
|
||||
Process);
|
||||
MmCopyMmInfo(ParentProcess, Process);
|
||||
Process->UniqueProcessId = InterlockedIncrement(&PiNextProcessUniqueId);
|
||||
|
||||
/*
|
||||
* FIXME: I don't what I'm supposed to know with a section handle
|
||||
|
|
|
@ -52,7 +52,7 @@ ULONG PiNrRunnableThreads = 0;
|
|||
|
||||
static PETHREAD CurrentThread = NULL;
|
||||
|
||||
static ULONG NextUniqueThreadId = 0;
|
||||
static ULONG PiNextThreadUniqueId = 0;
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
|
@ -98,7 +98,8 @@ static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
|
|||
KIRQL oldlvl;
|
||||
|
||||
DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority,
|
||||
Thread);
|
||||
Thread);
|
||||
DPRINT("Offset %x\n", THREAD_PRIORITY_MAX + Priority);
|
||||
|
||||
KeAcquireSpinLock(&ThreadListLock,&oldlvl);
|
||||
InsertTailList(&PriorityListHead[THREAD_PRIORITY_MAX+Priority],
|
||||
|
@ -110,7 +111,7 @@ VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
|
|||
{
|
||||
NTSTATUS Ret;
|
||||
|
||||
KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL);
|
||||
// KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL);
|
||||
Ret = StartRoutine(StartContext);
|
||||
PsTerminateSystemThread(Ret);
|
||||
KeBugCheck(0);
|
||||
|
@ -130,13 +131,13 @@ static PETHREAD PsScanThreadList(KPRIORITY Priority)
|
|||
{
|
||||
current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.Entry);
|
||||
|
||||
if (current->Tcb.ThreadState == THREAD_STATE_TERMINATED &&
|
||||
if (current->Tcb.State == THREAD_STATE_TERMINATED &&
|
||||
current != CurrentThread)
|
||||
{
|
||||
PsReleaseThread(current);
|
||||
}
|
||||
|
||||
if (current->Tcb.ThreadState == THREAD_STATE_RUNNABLE)
|
||||
if (current->Tcb.State == THREAD_STATE_RUNNABLE)
|
||||
{
|
||||
if (oldest == NULL || oldest_time > current->Tcb.LastTick)
|
||||
{
|
||||
|
@ -166,9 +167,9 @@ VOID PsDispatchThread(VOID)
|
|||
|
||||
DPRINT("PsDispatchThread() Current %x\n",CurrentThread);
|
||||
|
||||
if (CurrentThread->Tcb.ThreadState==THREAD_STATE_RUNNING)
|
||||
if (CurrentThread->Tcb.State==THREAD_STATE_RUNNING)
|
||||
{
|
||||
CurrentThread->Tcb.ThreadState=THREAD_STATE_RUNNABLE;
|
||||
CurrentThread->Tcb.State=THREAD_STATE_RUNNABLE;
|
||||
}
|
||||
|
||||
for (CurrentPriority=THREAD_PRIORITY_TIME_CRITICAL;
|
||||
|
@ -181,7 +182,7 @@ VOID PsDispatchThread(VOID)
|
|||
DPRINT("Scheduling current thread\n");
|
||||
KeQueryTickCount(&TickCount);
|
||||
CurrentThread->Tcb.LastTick = TickCount.u.LowPart;
|
||||
CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
|
||||
CurrentThread->Tcb.State = THREAD_STATE_RUNNING;
|
||||
KeReleaseSpinLock(&ThreadListLock,irql);
|
||||
return;
|
||||
}
|
||||
|
@ -189,7 +190,7 @@ VOID PsDispatchThread(VOID)
|
|||
{
|
||||
DPRINT("Scheduling %x\n",Candidate);
|
||||
|
||||
Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING;
|
||||
Candidate->Tcb.State = THREAD_STATE_RUNNING;
|
||||
|
||||
KeQueryTickCount(&TickCount);
|
||||
CurrentThread->Tcb.LastTick = TickCount.u.LowPart;
|
||||
|
@ -197,7 +198,7 @@ VOID PsDispatchThread(VOID)
|
|||
CurrentThread = Candidate;
|
||||
|
||||
HalTaskSwitch(&CurrentThread->Tcb);
|
||||
KeReleaseSpinLock(&ThreadListLock,irql);
|
||||
KeReleaseSpinLock(&ThreadListLock, irql);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -222,11 +223,13 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
|
|||
PsThreadType);
|
||||
DPRINT("Thread = %x\n",Thread);
|
||||
Thread->Tcb.LastTick = 0;
|
||||
Thread->Tcb.ThreadState=THREAD_STATE_SUSPENDED;
|
||||
Thread->Tcb.BasePriority=THREAD_PRIORITY_NORMAL;
|
||||
Thread->Tcb.CurrentPriority=THREAD_PRIORITY_NORMAL;
|
||||
Thread->Tcb.ApcList=ExAllocatePool(NonPagedPool,sizeof(LIST_ENTRY));
|
||||
Thread->Tcb.State = THREAD_STATE_SUSPENDED;
|
||||
Thread->Tcb.BasePriority = THREAD_PRIORITY_NORMAL;
|
||||
Thread->Tcb.SuspendCount = 1;
|
||||
InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[0]);
|
||||
InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[1]);
|
||||
Thread->Tcb.KernelApcDisable = 1;
|
||||
|
||||
if (ProcessHandle != NULL)
|
||||
{
|
||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||
|
@ -253,18 +256,16 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
|
|||
PROCESS_CREATE_THREAD,
|
||||
PsProcessType,
|
||||
UserMode);
|
||||
InitializeListHead(Thread->Tcb.ApcList);
|
||||
InitializeListHead(&(Thread->IrpList));
|
||||
Thread->Cid.UniqueThread = (HANDLE)InterlockedIncrement(
|
||||
&NextUniqueThreadId);
|
||||
&PiNextThreadUniqueId);
|
||||
Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId;
|
||||
DbgPrint("Thread->Cid.UniqueThread %d\nThread->Cid.UniqueProcess %d\n",
|
||||
Thread->Cid.UniqueThread, Thread->Cid.UniqueThread);
|
||||
DbgPrint("Thread->Cid.UniqueThread %d\n",Thread->Cid.UniqueThread);
|
||||
ObReferenceObjectByPointer(Thread,
|
||||
THREAD_ALL_ACCESS,
|
||||
PsThreadType,
|
||||
UserMode);
|
||||
PsInsertIntoThreadList(Thread->Tcb.CurrentPriority,Thread);
|
||||
PsInsertIntoThreadList(Thread->Tcb.BasePriority,Thread);
|
||||
|
||||
*ThreadPtr = Thread;
|
||||
|
||||
|
@ -277,10 +278,10 @@ VOID PsResumeThread(PETHREAD Thread)
|
|||
DPRINT("PsResumeThread(Thread %x)\n",Thread);
|
||||
Thread->Tcb.SuspendCount--;
|
||||
if (Thread->Tcb.SuspendCount <= 0 &&
|
||||
Thread->Tcb.ThreadState != THREAD_STATE_RUNNING)
|
||||
Thread->Tcb.State != THREAD_STATE_RUNNING)
|
||||
{
|
||||
DPRINT("Setting thread to runnable\n");
|
||||
Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;
|
||||
Thread->Tcb.State = THREAD_STATE_RUNNABLE;
|
||||
}
|
||||
DPRINT("Finished PsResumeThread()\n");
|
||||
}
|
||||
|
@ -291,7 +292,7 @@ VOID PsSuspendThread(PETHREAD Thread)
|
|||
Thread->Tcb.SuspendCount++;
|
||||
if (Thread->Tcb.SuspendCount > 0)
|
||||
{
|
||||
Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;
|
||||
Thread->Tcb.State = THREAD_STATE_SUSPENDED;
|
||||
if (Thread == CurrentThread)
|
||||
{
|
||||
PsDispatchThread();
|
||||
|
@ -343,7 +344,7 @@ VOID PsInitThreadManagment(VOID)
|
|||
PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle,
|
||||
THREAD_ALL_ACCESS,NULL);
|
||||
HalInitFirstTask(FirstThread);
|
||||
FirstThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
|
||||
FirstThread->Tcb.State = THREAD_STATE_RUNNING;
|
||||
FirstThread->Tcb.SuspendCount = 0;
|
||||
|
||||
DPRINT("FirstThread %x\n",FirstThread);
|
||||
|
@ -477,11 +478,11 @@ LONG KeSetBasePriorityThread(PKTHREAD Thread, LONG Increment)
|
|||
KPRIORITY KeSetPriorityThread(PKTHREAD Thread, KPRIORITY Priority)
|
||||
{
|
||||
KPRIORITY OldPriority;
|
||||
OldPriority = Thread->CurrentPriority;
|
||||
Thread->CurrentPriority = Priority;
|
||||
OldPriority = Thread->BasePriority;
|
||||
Thread->BasePriority = Priority;
|
||||
|
||||
RemoveEntryList(&Thread->Entry);
|
||||
PsInsertIntoThreadList(Thread->CurrentPriority,
|
||||
PsInsertIntoThreadList(Thread->BasePriority,
|
||||
CONTAINING_RECORD(Thread,ETHREAD,Tcb));
|
||||
|
||||
return(OldPriority);
|
||||
|
@ -576,7 +577,7 @@ NTSTATUS STDCALL ZwResumeThread(IN HANDLE ThreadHandle,
|
|||
(*SuspendCount) = InterlockedDecrement(&Thread->Tcb.SuspendCount);
|
||||
if (Thread->Tcb.SuspendCount <= 0)
|
||||
{
|
||||
Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;
|
||||
Thread->Tcb.State = THREAD_STATE_RUNNABLE;
|
||||
}
|
||||
|
||||
ObDereferenceObject(Thread);
|
||||
|
@ -634,7 +635,7 @@ NTSTATUS STDCALL ZwSuspendThread(IN HANDLE ThreadHandle,
|
|||
(*PreviousSuspendCount) = InterlockedIncrement(&Thread->Tcb.SuspendCount);
|
||||
if (Thread->Tcb.SuspendCount > 0)
|
||||
{
|
||||
Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;
|
||||
Thread->Tcb.State = THREAD_STATE_SUSPENDED;
|
||||
if (Thread == PsGetCurrentThread())
|
||||
{
|
||||
PsDispatchThread();
|
||||
|
|
|
@ -23,8 +23,7 @@ char* strtok(char *s, const char *delim)
|
|||
int c, sc;
|
||||
char *tok;
|
||||
static char *last;
|
||||
|
||||
|
||||
|
||||
if (s == NULL && (s = last) == NULL)
|
||||
return (NULL);
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue