--- /dev/null
+
+ 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.
+\f
+ 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.)
+\f
+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.
+\f
+ 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.
+\f
+ 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
+\f
+ 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.
--- /dev/null
+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)
--- /dev/null
+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'.
--- /dev/null
+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
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++)
{
--- /dev/null
+/*
+ *
+ */
+
+int main(int argc, char* argv[])
+{
+
+}
--- /dev/null
+ 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.
+
/*
-** 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>
#include "keyboard.h"
+/* GLOBALS *******************************************************************/
+
/*
* Driver data
*/
static BYTE ledStatus;
static BYTE capsDown,numDown,scrollDown;
static DWORD ctrlKeyState;
-static KSPIN_LOCK kbdBufferLock;
static PKINTERRUPT KbdInterrupt;
static KDPC KbdDpc;
'{', '|', '}', '"'
};
+/* FUNCTIONS *****************************************************************/
+static void KbdWrite(int addr,BYTE data)
/*
- * Write data to keyboard
+ * FUNCTION: Write data to keyboard
*/
-
-static void KbdWrite(int addr,BYTE data)
{
BYTE status;
outb_p(addr,data);
}
-
+static int KbdReadData(void)
/*
- * Read data from port 0x60
+ * FUNCTION: Read data from port 0x60
*/
-
-static int KbdReadData(void)
{
int i;
BYTE status,data;
return asciiTable2[keyCode-VK_NUMPAD0];
if ((keyCode>=186)&&(keyCode<=222))
- {
+ {
if (ctrlKeyState & SHIFT_PRESSED)
return asciiTable4[keyCode-186];
else
if (keysInBuffer==KBD_BUFFER_SIZE) // Buffer is full
{
extKey=0;
- return FALSE;
+ return(TRUE);
}
kbdBuffer[bufHead].bKeyDown=isDown;
kbdBuffer[bufHead].wRepeatCount=1;
bufHead&=KBD_WRAP_MASK; // Modulo KBD_BUFFER_SIZE
keysInBuffer++;
extKey=0;
-
return TRUE;
}
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;
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);
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();
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);
}
--- /dev/null
+/*
+ * 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);
+}
+
/*
* 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:
*/
#include <string.h>
#include <internal/string.h>
-#define NDEBUG
+//#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
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);
&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,
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,
#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;
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);
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)
char name[255];
struct ext2_dir_entry* current;
ULONG block;
+ BOOL b;
DPRINT("Ext2ScanDir(dir %x, filename %s, ret %x)\n",dir,filename,ret);
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)
* 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;
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);
+#include <ddk/ntifs.h>
+
BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
{
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,
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,
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);
+
{
ULONG block;
PULONG TempBuffer;
+ BOOL b;
DPRINT("Ext2BlockMap(DeviceExt %x, inode %x, offset %d)\n",
DeviceExt,inode,offset);
{
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(;;);
}
+
#include <ddk/ntddk.h>
#include <string.h>
+#include <internal/string.h>
-#define NDEBUG
+//#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
}
+#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)
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);
+
}
#
#
#
-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
--- /dev/null
+/*
+ * 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);
+}
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
+#include <string.h>
#define NDEBUG
#include <internal/debug.h>
/* 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);
+}
--- /dev/null
+/*
+ * 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);
+}
#include <wchar.h>
#include <internal/string.h>
-#define NDEBUG
+//#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
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;
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return(Status);
-}
-
-NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
- DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
+ if (FileObject == DeviceExtension->FileObject)
+ {
+ Status = STATUS_SUCCESS;
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- return(STATUS_UNSUCCESSFUL);
-}
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return(Status);
+ }
-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;
+ Fcb = (PEXT2_FCB)FileObject->FsContext;
+ if (Fcb != NULL)
+ {
+ if (Fcb->Bcb != NULL)
+ {
+ CcReleaseFileCache(FileObject, Fcb->Bcb);
+ }
+ ExFreePool(Fcb);
+ FileObject->FsContext = NULL;
+ }
- Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
+ Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = Length;
- IoCompleteRequest(Irp,IO_NO_INCREMENT);
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
-
NTSTATUS Ext2Mount(PDEVICE_OBJECT DeviceToMount)
{
PDEVICE_OBJECT DeviceObject;
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);
}
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);
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! */
-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);
#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 */
/*
* 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)
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
);
VOID IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject);
PDEVICE_OBJECT IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject);
+PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject,
+ PDEVICE_OBJECT DeviceObject);
/* KERNEL FUNCTIONS ********************************************************/
-struct _KAPC;
-
-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 KeInitializeApc(PKAPC Apc,
+ PKTHREAD Thread,
+ UCHAR StateIndex,
+ PKKERNEL_ROUTINE KernelRoutine,
+ PKRUNDOWN_ROUTINE RundownRoutine,
+ PKNORMAL_ROUTINE NormalRoutine,
+ UCHAR Mode,
+ PVOID Context);
+
+VOID KeInsertQueueApc(PKAPC Apc,
+ PVOID SystemArgument1,
+ PVOID SystemArgument2,
+ UCHAR Mode);
+VOID KeAttachProcess(struct _EPROCESS* Process);
+VOID KeDetachProcess(VOID);
VOID KeDrainApcQueue(VOID);
PKPROCESS KeGetCurrentProcess(VOID);
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,
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
*/
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 ].
* 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.
* 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
* 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
* 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 */
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;
typedef struct _KSPIN_LOCK
{
- KIRQL irql;
+ ULONG Lock;
} KSPIN_LOCK, *PKSPIN_LOCK;
typedef struct _KDEVICE_QUEUE
struct _KTHREAD* OwnerThread;
BOOLEAN Abandoned;
UCHAR ApcDisable;
-} KMUTEX, *PKMUTEX;
+} KMUTEX, *PKMUTEX, KMUTANT, *PKMUTANT;
typedef struct
{
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>
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;
typedef struct _NT_PEB
{
- UCHAR InheritedAddressSpace;
- UCHAR ReadImageFileExecOptions;
- UCHAR BeingDebugged;
- LONG ImageBaseAddress;
- LDR Ldr;
-
- WORD NumberOfProcessors;
- WORD NtGlobalFlag;
-
- PPROCESSINFOW StartupInfo;
- HANDLE ProcessHeap;
- ATOMTABLE LocalAtomTable;
- LPCRITICAL_SECTION CriticalSection;
- DWORD CriticalSectionTimeout;
- WORD MajorVersion;
- WORD MinorVersion;
- WORD BuildNumber;
- WORD PlatformId;
+ UCHAR InheritedAddressSpace; // 00
+ UCHAR ReadImageFileExecOptions; // 01h
+ UCHAR BeingDebugged; // 02h
+ LONG ImageBaseAddress; // 03h
+ LDR Ldr; // 07h
+
+ WORD NumberOfProcessors; // 11h
+ WORD NtGlobalFlag; // 13h
+
+ 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
} 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
+struct _KPROCESS;
+
+typedef struct _KAPC_STATE
{
- 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;
+ 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.
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;
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)
* Possible status codes
* FIXME: These may not be the actual values used by NT
*/
-enum
-{
- STATUS_SUCCESS = 0x0,
+#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)
- 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,
+enum
+{
+
+ STATUS_IMAGE_NOT_AT_BASE = (0x40000003),
STATUS_RXACT_STATE_CREATED,
STATUS_SEGMENT_NOTIFICATION,
STATUS_LOCAL_USER_SESSION_KEY,
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,
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,
#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
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
VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
VOID PsBeginThreadWithContextInternal(VOID);
-/*
- * PURPOSE: Thread states
- */
-enum
-{
- /*
- * PURPOSE: Don't touch
- */
- THREAD_STATE_INVALID,
-
- /*
- * PURPOSE: Waiting to be dispatched
- */
- THREAD_STATE_RUNNABLE,
+#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: 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
*/
#include <windows.h>
+#define UNIMPLEMENTED dprintf("%s at %s:%d is unimplemented\n",__FUNCTION__,__FILE__,__LINE__);
+
#ifdef NDEBUG
#define DPRINT(args...)
#define CHECKPOINT
BOOL KERNEL32_AnsiToUnicode(PWSTR DestStr,
LPCSTR SrcStr,
ULONG MaxLen);
+PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength);
--- /dev/null
+#define NTDLL_BASE (0x77f60000)
#define MAGIC(c1,c2,c3,c4) ((c1) + ((c2)<<8) + ((c3)<<16) + ((c4)<<24))
#define MAGIC_HEAP MAGIC( 'H','E','A','P' )
+
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
STDCALL
UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
- char message[80];
DWORD dbgRet;
HANDLE DebugPort;
NTSTATUS errCode;
- DWORD DebuggerPresent;
if(ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) {
WINBOOL* pbCancel,
DWORD dwCopyFlags)
{
- ULONG i;
WCHAR ExistingFileNameW[MAX_PATH];
WCHAR NewFileNameW[MAX_PATH];
/* INCLUDES ******************************************************************/
#include <windows.h>
-#include <string.h>
+#include <wchar.h>
#include <ctype.h>
+#include <string.h>
#define NDEBUG
#include <kernel32/kernel32.h>
return wcslen(lpBuffer);
}
+
+
+
+
+
+
+
DWORD
STDCALL
GetShortPathNameA(
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 {
-
- FileAndExtensionW[0] = 0;
- lpBuffer[0] = 0;
- i = lstrlenW(lpFileName);
- j = lstrlenW(lpPath);
-
- if ( i + j + 8 < nBufferLength )
- return i + j + 9;
+ 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);
+
+
- if ( lpExtension != NULL ) {
+ return retCode;
+
+ }
+ else {
+
+ 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
lstrcatW(BufferW,L"\\??\\");
lstrcatW(BufferW,lpPath);
-
+
//printf("%S\n",FileAndExtensionW);
i = wcslen(BufferW);
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);
*lpFilePart = wcsrchr(lpBuffer,'\\')+1;
}
- }
+
return lstrlenW(lpBuffer);
+ }
+ }
}
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)
{
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,
IoStatusBlock,
(PVOID)lpBuffer,
nNumberOfBytesToWrite,
- &Offset,
+ ptrOffset,
NULL);
if (!NT_SUCCESS(errCode))
{
{
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);
}
+KERNEL32_BASE = 0x77f00000
+
+CFLAGS = $(CFLAGS) -DKERNEL32_BASE=$(KERNEL32_BASE)
+
ifneq ($(HOST),mingw32-windows)
ifneq ($(HOST),mingw32-linux)
DLLTARGET=kernel32.a
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
$(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)
--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
.PHONY: clean $(CLEAN_FILES:%=%_clean)
+#WARNINGS_ARE_ERRORS = yes
include ../../rules.mak
********************************************************************/
DWORD WINAPI GetProcessHeaps(DWORD maxheaps, PHANDLE phandles )
{
+ UNIMPLEMENTED;
+ return(ERROR_CALL_NOT_IMPLEMENTED);
}
/*********************************************************************
*********************************************************************/
DWORD WINAPI HeapSize(HANDLE hheap, DWORD flags, LPCVOID pmem)
{
- return(RtlSizeHeap(hheap, flags, pmem));
+ return(RtlSizeHeap(hheap, flags, (PVOID)pmem));
}
/*********************************************************************
*********************************************************************/
BOOL WINAPI HeapValidate(HANDLE hheap, DWORD flags, LPCVOID pmem)
{
- return(RtlValidateHeap(hheap, flags, pmem));
+ return(RtlValidateHeap(hheap, flags, (PVOID)pmem));
}
Status = ZwProtectVirtualMemory(hProcess,
(PVOID)lpAddress,
- (PULONG)dwSize,
+ dwSize,
flNewProtect,
- lpflOldProtect);
+ (PULONG)lpflOldProtect);
if (Status != STATUS_SUCCESS)
{
SetLastError(RtlNtStatusToDosError(Status));
{
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 );
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
LPSTR STDCALL GetEnvironmentStringsA(VOID)
{
+#if 0
WCHAR *EnvironmentStringsW;
char *EnvironmentStringsA;
int size = 0;
int i;
-
+#endif
+
return(NULL);
/* FIXME: This doesn't work */
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? */
* 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
{
*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
return TRUE;
}
+// dwDayOfWeek = RtlLargeIntegerDivide(FileTime,LIDAY,&dwRemDay);
+// lpSystemTime->wDayOfWeek = 1 + GET_LARGE_INTEGER_LOW_PART(dwDayOfWeek) % 7;
+
WINBOOL
STDCALL
#include <internal/i386/segment.h>
#include <ntdll/ldr.h>
#include <internal/teb.h>
+#include <ntdll/base.h>
//#define NDEBUG
#include <kernel32/kernel32.h>
PVOID BaseAddress;
ULONG BytesWritten;
HANDLE DupNTDllSectionHandle, DupSectionHandle;
-
-
+
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.ObjectName = NULL;
return(hSection);
}
-#define NTDLL_BASE (0x80000000)
-
static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine)
{
NTSTATUS Status;
ULONG StartupInfoSize;
PROCESSINFOW StartupInfo;
- PebBase = PEB_BASE;
+ PebBase = (PVOID)PEB_BASE;
PebSize = 0x1000;
Status = ZwAllocateVirtualMemory(ProcessHandle,
&PebBase,
memset(&Peb, 0, sizeof(Peb));
- Peb.StartupInfo = PEB_STARTUPINFO;
+ Peb.StartupInfo = (PPROCESSINFOW)PEB_STARTUPINFO;
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)PEB_BASE,
sizeof(Peb),
&BytesWritten);
- StartupInfoBase = PEB_STARTUPINFO;
+ StartupInfoBase = (PVOID)PEB_STARTUPINFO;
StartupInfoSize = 0x1000;
Status = ZwAllocateVirtualMemory(ProcessHandle,
&StartupInfoBase,
hSection = KERNEL32_MapFile(lpApplicationName,
lpCommandLine,
- &Headers, &DosHeader);
+ &Headers,
+ &DosHeader);
Status = NtCreateProcess(&hProcess,
PROCESS_ALL_ACCESS,
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);
}
#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;
FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
- dprintf("GetProcAddress is unimplemented\n");
+ UNIMPLEMENTED;
+ return(NULL);
}
WINBOOL STDCALL GetProcessTimes(HANDLE hProcess,
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;
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
- memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
+ memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD));
return TRUE;
}
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;
-VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
+VOID RegisterWaitForInputIdle(WaitForInputIdleType
+ lpfnRegisterWaitForInputIdle)
{
- lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
- return;
+ lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
+ return;
}
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;
return 0;
}
-
-
-
-
-VOID STDCALL GetStartupInfoW(LPSTARTUPINFO lpStartupInfo)
+VOID STDCALL GetStartupInfoW(LPSTARTUPINFO _lpStartupInfo)
{
NT_PEB *pPeb = NtCurrentPeb();
+ LPWSTARTUPINFO lpStartupInfo = (LPWSTARTUPINFO)_lpStartupInfo;
if (lpStartupInfo == NULL)
{
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);
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;
#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);
}
* 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;
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);
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;
-
- errCode = NtTerminateThread(
- NtCurrentThread() ,
- uExitCode
- );
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- }
- return;
+ NTSTATUS errCode;
+
+ errCode = NtTerminateThread(NtCurrentThread(),
+ uExitCode);
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ }
}
-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;
-
-}
-
-
-WINBOOL
-STDCALL GetThreadContext(
- HANDLE hThread,
- LPCONTEXT lpContext
- )
+WINBOOL STDCALL GetThreadTimes(HANDLE hThread,
+ LPFILETIME lpCreationTime,
+ LPFILETIME lpExitTime,
+ LPFILETIME lpKernelTime,
+ LPFILETIME lpUserTime)
{
- 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
- )
-{
- 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
- )
-{
- 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;
+ 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;
}
-DWORD
-STDCALL
-ResumeThread(
- HANDLE hThread
- )
+WINBOOL STDCALL GetThreadContext(HANDLE hThread,
+ LPCONTEXT lpContext)
{
- NTSTATUS errCode;
- ULONG PreviousResumeCount;
-
- errCode = NtResumeThread(hThread,&PreviousResumeCount );
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- return -1;
- }
- return PreviousResumeCount;
-}
-
-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;
+
+ errCode = NtGetContextThread(hThread,
+ lpContext);
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ return TRUE;
}
-
-DWORD
-STDCALL
-SetThreadAffinityMask(
- HANDLE hThread,
- DWORD dwThreadAffinityMask
- )
+WINBOOL STDCALL SetThreadContext(HANDLE hThread,
+ CONST CONTEXT *lpContext)
{
- return 0;
+ NTSTATUS errCode;
+
+ errCode = NtSetContextThread(hThread,
+ (void *)lpContext);
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ return TRUE;
}
-
-WINBOOL
-STDCALL
-SetThreadPriority(
- HANDLE hThread,
- int nPriority
- )
+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;
- }
- 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;
+ }
+ memcpy(lpExitCode, &ThreadBasic.ExitStatus, sizeof(DWORD));
+ return TRUE;
}
-
-int
-STDCALL
-GetThreadPriority(
- HANDLE hThread
- )
+DWORD STDCALL ResumeThread(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;
+ ULONG PreviousResumeCount;
+
+ errCode = NtResumeThread(hThread,
+ &PreviousResumeCount);
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return -1;
+ }
+ return PreviousResumeCount;
}
-
-/* (WIN32) Thread Local Storage ******************************************** */
-
-DWORD STDCALL
-TlsAlloc(VOID)
+DWORD STDCALL SuspendThread(HANDLE hThread)
{
- DWORD dwTlsIndex = GetTeb()->dwTlsIndex;
-
-
- void **TlsData = GetTeb()->TlsData;
-
-
- if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
- {
- TlsData[dwTlsIndex] = NULL;
- return (dwTlsIndex++);
- }
- return (0xFFFFFFFFUL);
+ NTSTATUS errCode;
+ ULONG PreviousSuspendCount;
+
+ errCode = NtSuspendThread(hThread,
+ &PreviousSuspendCount);
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return -1;
+ }
+ return PreviousSuspendCount;
}
-WINBOOL STDCALL
-TlsFree(DWORD dwTlsIndex)
+DWORD STDCALL SetThreadAffinityMask(HANDLE hThread,
+ DWORD dwThreadAffinityMask)
{
-
- return (TRUE);
+ return 0;
}
-LPVOID STDCALL
-TlsGetValue(DWORD dwTlsIndex)
+WINBOOL STDCALL SetThreadPriority(HANDLE hThread,
+ int nPriority)
{
-
-
- void **TlsData = GetTeb()->TlsData;
-
-
- if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
- {
-
- SetLastError(NO_ERROR);
- return (TlsData[dwTlsIndex]);
- }
- SetLastError(1);
- return (NULL);
+ 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;
}
-WINBOOL STDCALL
-TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
+int STDCALL GetThreadPriority(HANDLE hThread)
{
-
-
- void **TlsData = GetTeb()->TlsData;
-
-
- if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
- {
-
- TlsData[dwTlsIndex] = lpTlsValue;
- return (TRUE);
- }
- return (FALSE);
+ 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;
}
-
-/*************************************************************/
--- /dev/null
+/*
+ * 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);
+}
+IMAGE_BASE = 0x77f60000
+
ifneq ($(HOST),mingw32-windows)
ifneq ($(HOST),mingw32-linux)
DLLTARGET=ntdll.a
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)
- $(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
#
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)
#include <ddk/ntifs.h>
#include <internal/mm.h>
-//#define NDEBUG
+#define NDEBUG
#include <internal/debug.h>
-/* TYPES *********************************************************************/
-
-#define CACHE_SEGMENT_SIZE (0x1000)
+/* FUNCTIONS *****************************************************************/
-typedef struct _CACHE_SEGMENT
+NTSTATUS CcFlushCachePage(PCACHE_SEGMENT CacheSeg)
+/*
+ * FUNCTION: Asks the FSD to flush the contents of the page back to disk
+ */
{
- PVOID BaseAddress;
- PMEMORY_AREA MemoryArea;
- BOOLEAN Valid;
- LIST_ENTRY ListEntry;
- ULONG FileOffset;
- KEVENT Lock;
- ULONG ReferenceCount;
-} CACHE_SEGMENT, *PCACHE_SEGMENT;
+ 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);
+}
-/* FUNCTIONS *****************************************************************/
+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);
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);
}
#include <internal/debug.h>
-/* #define PROTO_REG 1 /* Comment out to disable */
+// #define PROTO_REG 1 /* Comment out to disable */
/* FILE STATICS *************************************************************/
{
{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},
return;
}
FastMutex->Contention++;
- KeWaitForSingleObject(&(FastMutex->Event),Executive,KernelMode,
- FALSE,NULL);
+ KeWaitForSingleObject(&(FastMutex->Event),
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
FastMutex->Owner=KeGetCurrentThread();
}
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)
{
/*
* 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
*/
#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)
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;
VOID ExReleaseResourceLite(PERESOURCE Resource)
{
- return ExReleaseResourceForThreadLite(Resource,ExGetCurrentResourceThread());
+ return(ExReleaseResourceForThreadLite(Resource,
+ ExGetCurrentResourceThread()));
}
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");
}
* 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
#
#
#
-CbInitDccb
-CbAcquireForRead
-CbReleaseFromRead
DbgPrint
ExAcquireFastMutex
ExAcquireFastMutexUnsafe
IoCreateController
IoCreateDevice
IoCreateNotificationEvent
+IoCreateStreamFileObject
IoCreateSymbolicLink
IoCreateSynchronizationEvent
IoCreateUnprotectedSymbolicLink
wcscpy
wcsncat
wcsncpy
+#wtolower
+tolower
+toupper
+memcpy
+strtok
+CcInitializeFileCache
+CcRequestCachePage
+CcReleaseCachePage
+CcReleaseFileCache
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)
}
}
+ DPRINT("Killing current task\n");
+ KeLowerIrql(PASSIVE_LEVEL);
if ((cs&0xffff) == USER_CS)
{
ZwTerminateProcess(NtCurrentProcess(),
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]);
}
* 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);
/*
}
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
*/
{
isr_lock[Vector]=ExAllocatePool(NonPagedPool,sizeof(KSPIN_LOCK));
KeInitializeSpinLock(isr_lock[Vector]);
- isr_lock[Vector]->irql = SynchronizeIrql;
}
/*
*/
{
unsigned int i;
+ PKTHREAD CurrentThread;
+
+ CurrentThread = KeGetCurrentThread();
if (CurrentIrql == HIGH_LEVEL)
{
HiSetCurrentPICMask(0xffff);
+// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = TRUE;
return;
}
if (CurrentIrql > DISPATCH_LEVEL)
}
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)
{
DbgPrint("%s:%d CurrentIrql %x NewIrql %x OldIrql %x\n",
__FILE__,__LINE__,CurrentIrql,NewIrql,OldIrql);
+ KeBugCheck(0);
for(;;);
}
* bp = Parameters setup by the boot loader
*/
{
-// int offset;
#ifdef SERIAL_DEBUGGING
/* turn on DTR and RTS */
* SpinLock = Caller supplied storage for the spinlock
*/
{
- SpinLock->irql = DISPATCH_LEVEL;
+ SpinLock->Lock = 0;
}
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)
* 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)
*/
{
KeRaiseIrql(DISPATCH_LEVEL,OldIrql);
+ KeAcquireSpinLockAtDpcLevel(SpinLock);
}
VOID KeReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL NewIrql)
* NewIrql = Irql level before acquiring the spinlock
*/
{
+ KeReleaseSpinLockFromDpcLevel(SpinLock);
KeLowerIrql(NewIrql);
}
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = UserEvent;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
return(NULL);
}
+ Irp->UserIosb = IoStatusBlock;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
+
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = MajorFunction;
StackPtr->MinorFunction = 0;
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)
+ {
+ IoPrepareIrpBuffer(Irp,
+ DeviceObject,
+ Buffer,
+ Length,
+ MajorFunction);
+ }
+
+ if (MajorFunction == IRP_MJ_READ)
{
- Irp->UserBuffer = (LPVOID)Buffer;
- if (DeviceObject->Flags&DO_BUFFERED_IO)
+ 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;
StackPtr->Parameters.Write.ByteOffset.QuadPart = 0;
}
}
-
+
Irp->UserIosb = IoStatusBlock;
return(Irp);
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;
Irp->UserEvent = Event;
Irp->UserIosb = IoStatusBlock;
+ Irp->Tail.Overlay.Thread = PsGetCurrentThread();
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = MajorFunction;
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,
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,
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);
}
* 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
*/
{
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);
PDEVICE_OBJECT CreatedDeviceObject;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE DeviceHandle;
-
+
+ assert_irql(PASSIVE_LEVEL);
+
if (DeviceName != NULL)
{
DPRINT("IoCreateDevice(DriverObject %x, DeviceName %w)\n",DriverObject,
IoDeviceType);
}
- *DeviceObject=NULL;
+ *DeviceObject = NULL;
if (CreatedDeviceObject == NULL)
{
DPRINT("IoAskFileSystemToMountDevice(DeviceObject %x, DeviceToMount %x)\n",
DeviceObject,DeviceToMount);
+ assert_irql(PASSIVE_LEVEL);
+
KeInitializeEvent(&Event,NotificationEvent,FALSE);
Irp = IoBuildFilesystemControlRequest(IRP_MN_MOUNT_VOLUME,
DeviceObject,
FILE_SYSTEM_OBJECT* current;
NTSTATUS Status;
+ assert_irql(PASSIVE_LEVEL);
+
DPRINT("IoTryToMountStorageDevice(DeviceObject %x)\n",DeviceObject);
KeAcquireSpinLock(&FileSystemListLock,&oldlvl);
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:
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)
{
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)
Irp->CurrentLocation,
Irp->StackCount);
- return &Irp->Stack[(ULONG)Irp->CurrentLocation];
+ return(&Irp->Stack[(ULONG)Irp->CurrentLocation]);
}
-
VOID IoSetNextIrpStackLocation(PIRP Irp)
{
Irp->CurrentLocation--;
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;
}
{
unsigned int i;
NTSTATUS Status;
+ PKTHREAD Thread;
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",
Irp,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
{
else
{
stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
- &Irp->Tail.Overlay.DeviceQueueEntry);
+ &Irp->Tail.Overlay.DeviceQueueEntry);
}
IoReleaseCancelSpinLock(oldirql);
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,
UserMode,
(PVOID *) &FileObject,
NULL);
- if (!NT_SUCCESS(STATUS_SUCCESS))
+ if (!NT_SUCCESS(Status))
{
DPRINT("ZwReadFile() = %x\n",Status);
return(Status);
ByteOffset,
ptrEvent,
IoStatusBlock);
-
+
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
+
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
if (Key!=NULL)
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);
}
UserMode,
(PVOID *) &FileObject,
NULL);
- if (Status != STATUS_SUCCESS)
+ if (!NT_SUCCESS(Status))
{
return(Status);
}
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))
{
HANDLE SymbolicLinkHandle;
PSYMLNK_OBJECT SymbolicLink;
+ assert_irql(PASSIVE_LEVEL);
+
DPRINT("IoCreateSymbolicLink(SymbolicLinkName %w, DeviceName %w)\n",
SymbolicLinkName->Buffer,DeviceName->Buffer);
/* FUNCTIONS *****************************************************************/
+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,
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())
{
{
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;
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);
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;
}
NTSTATUS STDCALL ZwTestAlert(VOID)
{
- UNIMPLEMENTED;
+ KiTestAlert(KeGetCurrentThread(),
+ NULL /* ?? */);
+ return(STATUS_SUCCESS);
}
BugCheckParameter1,BugCheckParameter2,BugCheckParameter3,
BugCheckParameter4);
KeDumpStackFrames(0,64);
+ __asm__("cli\n\t");
for(;;);
}
#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;
}
PKDPC current;
KIRQL oldlvl;
+ if (DpcQueueSize == 0)
+ {
+ return;
+ }
DPRINT("KeDrainDpcQueue()\n");
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
* 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;
/*
* 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:
/* INCLUDES ****************************************************************/
-#include <windows.h>
#include <ddk/ntddk.h>
#define NDEBUG
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;
}
{
PKTHREAD CurrentThread = KeGetCurrentThread();
KeAddThreadTimeout(CurrentThread,Interval);
- return(KeWaitForSingleObject(&(CurrentThread->TimerBlock),Executive,
+ return(KeWaitForSingleObject(&(CurrentThread->Timer),Executive,
KernelMode,Alertable,NULL));
}
return(STATUS_SUCCESS);
}
- if (Timeout!=NULL)
+ if (Timeout != NULL)
{
KeAddThreadTimeout(KeGetCurrentThread(),Timeout);
}
// 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);
#include <internal/teb.h>
#include <ddk/ntddk.h>
-//#define NDEBUG
+#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ****************************************************************/
NT_PEB Peb;
ULONG BytesWritten;
- PebBase = PEB_BASE;
+ PebBase = (PVOID)PEB_BASE;
PebSize = 0x1000;
Status = ZwAllocateVirtualMemory(ProcessHandle,
&PebBase,
memset(&Peb, 0, sizeof(Peb));
- Peb.StartupInfo = PEB_STARTUPINFO;
+ Peb.StartupInfo = (PPROCESSINFOW)PEB_STARTUPINFO;
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)PEB_BASE,
*ImportAddressList = (PVOID) LdrGetKernelSymbolAddr(SymbolNameBuf);
if (*ImportAddressList == 0L)
{
- DbgPrint("Unresolved kernel symbol: %s\n", pName);
+ DbgPrint("Unresolved kernel symbol: %s\n", pName);
}
}
ImportAddressList++;
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
$(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 \
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
{
PLIST_ENTRY current_entry;
MEMORY_AREA* current;
+ PLIST_ENTRY previous_entry;
// MmDumpMemoryAreas();
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)
{
DPRINT("%s() = NULL\n",__FUNCTION__);
return(NULL);
}
+ previous_entry = current_entry;
current_entry = current_entry->Flink;
}
DPRINT("%s() = NULL\n",__FUNCTION__);
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;
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,
if (MemoryArea==NULL)
{
MmUnlockMemoryAreaList(BaseAddress, &oldlvl);
+ KeBugCheck(0);
return(STATUS_UNSUCCESSFUL);
}
if (FreePages)
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);
}
"*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);
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);
}
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,
* 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)
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);
* 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);
}
/* INCLUDES *****************************************************************/
+#include <internal/hal/io.h>
#include <internal/i386/segment.h>
#include <internal/stddef.h>
#include <internal/mm.h>
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;
/* FUNCTIONS ****************************************************************/
-void VirtualInit(boot_param* bp)
+VOID MmInitVirtualMemory(boot_param* bp)
/*
* FUNCTION: Intialize the memory areas list
* ARGUMENTS:
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);
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,
0,
&kernel_data_desc);
-
BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&end));
Length = ParamLength;
MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,
// MmDumpMemoryAreas();
CHECKPOINT;
+// while (inb_p(0x60)!=0x1); inb_p(0x60);
+
MmInitSectionImplementation();
}
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);
}
MmSetPage(NULL, (PVOID)(i), PAGE_NOACCESS, 0);
}
DPRINT("Almost done MmInit()\n");
+
/*
* Intialize memory areas
*/
- VirtualInit(bp);
+ MmInitVirtualMemory(bp);
}
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);
NTSTATUS MmReleaseMmInfo(PEPROCESS Process)
{
- ULONG i,j,addr;
PLIST_ENTRY CurrentEntry;
PMEMORY_AREA Current;
MmUnmapLockedPages(Data, KMsg->Mdl);
Status = ObCreateHandle(PsGetCurrentProcess(),
KMsg->ReplyPort,
- FALSE,
STANDARD_RIGHTS_REQUIRED,
+ FALSE,
&Msg->ReplyPort);
ObDereferenceObject(PortHandle);
return(Status);
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
IoConnectInterrupt
IoCreateController
IoCreateDevice
+IoCreateStreamFileObject
IoCreateSymbolicLink
IoDeleteController
IoDisconnectInterrupt
RtlTimeToTimeFields
RtlZeroMemory
ZwCreateDirectoryObject@12
+CcInitializeFileCache
+CcRequestCachePage
+CcReleaseCachePage
+CcReleaseFileCache
isdigit
islower
isprint
for (i=0;i<count;i++)
{
current = current->Flink;
- if (current==(&(Process->Pcb.HandleTable.ListHead)))
+ if (current == (&(Process->Pcb.HandleTable.ListHead)))
{
return(NULL);
}
PEPROCESS SourceProcess;
PEPROCESS TargetProcess;
PHANDLE_REP SourceHandleRep;
+
+ ASSERT_IRQL(PASSIVE_LEVEL);
ObReferenceObjectByHandle(SourceProcessHandle,
PROCESS_DUP_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);
}
if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)
{
+ CHECKPOINT;
return(STATUS_OBJECT_TYPE_MISMATCH);
}
if (!(HandleRep->GrantedAccess & DesiredAccess))
{
+ CHECKPOINT;
return(STATUS_ACCESS_DENIED);
}
*Object = HandleRep->ObjectBody;
+ CHECKPOINT;
return(STATUS_SUCCESS);
}
POBJECT_HEADER Header;
NTSTATUS Status;
+ assert_irql(PASSIVE_LEVEL);
+
DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n");
if (ObjectAttributes != NULL &&
ObjectAttributes->ObjectName != NULL)
ObDereferenceObject(CurrentThread->ThreadsProcess);
CurrentThread->ThreadsProcess = NULL;
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
- CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;
+ CurrentThread->Tcb.State = THREAD_STATE_TERMINATED;
ZwYieldExecution();
for(;;);
}
POBJECT_TYPE PsProcessType = NULL;
-static ULONG NextUniqueProcessId = 0;
+static ULONG PiNextProcessUniqueId = 0;
/* FUNCTIONS *****************************************************************/
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,
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
static PETHREAD CurrentThread = NULL;
-static ULONG NextUniqueThreadId = 0;
+static ULONG PiNextThreadUniqueId = 0;
/* FUNCTIONS ***************************************************************/
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],
{
NTSTATUS Ret;
- KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL);
+// KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL);
Ret = StartRoutine(StartContext);
PsTerminateSystemThread(Ret);
KeBugCheck(0);
{
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)
{
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;
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;
}
{
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;
CurrentThread = Candidate;
HalTaskSwitch(&CurrentThread->Tcb);
- KeReleaseSpinLock(&ThreadListLock,irql);
+ KeReleaseSpinLock(&ThreadListLock, irql);
return;
}
}
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,
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;
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");
}
Thread->Tcb.SuspendCount++;
if (Thread->Tcb.SuspendCount > 0)
{
- Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;
+ Thread->Tcb.State = THREAD_STATE_SUSPENDED;
if (Thread == CurrentThread)
{
PsDispatchThread();
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);
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);
(*SuspendCount) = InterlockedDecrement(&Thread->Tcb.SuspendCount);
if (Thread->Tcb.SuspendCount <= 0)
{
- Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;
+ Thread->Tcb.State = THREAD_STATE_RUNNABLE;
}
ObDereferenceObject(Thread);
(*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();
int c, sc;
char *tok;
static char *last;
-
-
+
if (s == NULL && (s = last) == NULL)
return (NULL);
AR = $(PREFIX)ar
RC = $(PREFIX)windres
+%.o: %.cc
+ $(CC) $(CFLAGS) -c $< -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.asm
all: win32k.sys
win32k.coff: win32k.rc ../../include/reactos/resource.h
- windres win32k.rc win32k.coff
+ $(RC) win32k.rc win32k.coff
ifeq ($(DOSCLI),yes)
CLEAN_FILES = main\*.o stubs\*.o win32k.coff win32k.o win32k.a junk.tmp base.tmp \