From 126768af64cc314122b71fdc9053440065865c68 Mon Sep 17 00:00:00 2001 From: David Welch Date: Sat, 29 May 1999 00:15:17 +0000 Subject: [PATCH] Lots of changes to the kernel svn path=/trunk/; revision=527 --- reactos/COPYING | 340 ++++++++++ reactos/CREDITS | 11 + reactos/INSTALL | 27 + reactos/README | 24 + reactos/apps/tests/args/args.c | 3 +- reactos/apps/tests/bench/bench-syscall.c | 8 + reactos/doc/apc | 36 + reactos/drivers/dd/keyboard/keyboard.c | 95 ++- reactos/drivers/fs/ext2/attr.c | 125 ++++ reactos/drivers/fs/ext2/blockdev.c | 34 +- reactos/drivers/fs/ext2/dir.c | 48 +- reactos/drivers/fs/ext2/ext2fs.h | 52 +- reactos/drivers/fs/ext2/file.c | 16 +- reactos/drivers/fs/ext2/inode.c | 72 +- reactos/drivers/fs/ext2/makefile | 4 +- reactos/drivers/fs/ext2/quota.c | 47 ++ reactos/drivers/fs/ext2/rw.c | 206 ++++-- reactos/drivers/fs/ext2/security.c | 39 ++ reactos/drivers/fs/ext2/super.c | 86 +-- reactos/drivers/fs/vfat/iface.c | 3 +- reactos/include/ddk/ccfuncs.h | 4 - reactos/include/ddk/cctypes.h | 39 -- reactos/include/ddk/defines.h | 22 +- reactos/include/ddk/iodef.h | 39 +- reactos/include/ddk/iofuncs.h | 2 + reactos/include/ddk/kefuncs.h | 77 +-- reactos/include/ddk/ketypes.h | 35 +- reactos/include/ddk/ntifs.h | 25 +- reactos/include/ddk/pstypes.h | 256 ++++--- reactos/include/ddk/status.h | 68 +- reactos/include/internal/debug.h | 4 +- reactos/include/internal/mm.h | 4 + reactos/include/internal/ps.h | 36 +- reactos/include/kernel32/kernel32.h | 3 + reactos/include/ntdll/base.h | 1 + reactos/include/ntdll/ntdll.h | 1 + reactos/lib/crtdll/makefile | 2 +- reactos/lib/kernel32/except/except.c | 2 - reactos/lib/kernel32/file/copy.c | 1 - reactos/lib/kernel32/file/curdir.c | 3 +- reactos/lib/kernel32/file/dir.c | 122 +++- reactos/lib/kernel32/file/find.c | 3 +- reactos/lib/kernel32/file/rw.c | 19 +- reactos/lib/kernel32/file/volume.c | 16 +- reactos/lib/kernel32/makefile | 11 +- reactos/lib/kernel32/mem/heap.c | 6 +- reactos/lib/kernel32/mem/virtual.c | 4 +- reactos/lib/kernel32/misc/console.c | 2 +- reactos/lib/kernel32/misc/env.c | 41 +- reactos/lib/kernel32/misc/time.c | 22 + reactos/lib/kernel32/process/create.c | 15 +- reactos/lib/kernel32/process/lib.c | 9 +- reactos/lib/kernel32/process/proc.c | 98 +-- reactos/lib/kernel32/synch/critical.c | 14 +- reactos/lib/kernel32/thread/thread.c | 449 ++++++------- reactos/lib/kernel32/thread/tls.c | 62 ++ reactos/lib/ntdll/makefile | 6 +- reactos/makefile_rex | 2 +- reactos/ntoskrnl/cc/view.c | 123 +++- reactos/ntoskrnl/cm/registry.c | 2 +- reactos/ntoskrnl/dbg/errinfo.c | 2 +- reactos/ntoskrnl/ex/fmutex.c | 13 +- reactos/ntoskrnl/ex/resource.c | 817 ++++++++++++++--------- reactos/ntoskrnl/ex/stamp.c | 2 +- reactos/ntoskrnl/exports.lst | 13 +- reactos/ntoskrnl/hal/x86/exp.c | 15 +- reactos/ntoskrnl/hal/x86/irq.c | 8 +- reactos/ntoskrnl/hal/x86/irql.c | 19 +- reactos/ntoskrnl/hal/x86/printk.c | 1 - reactos/ntoskrnl/hal/x86/spinlock.c | 15 +- reactos/ntoskrnl/io/buildirp.c | 48 +- reactos/ntoskrnl/io/create.c | 42 ++ reactos/ntoskrnl/io/device.c | 18 +- reactos/ntoskrnl/io/fs.c | 6 + reactos/ntoskrnl/io/irp.c | 41 +- reactos/ntoskrnl/io/queue.c | 2 +- reactos/ntoskrnl/io/rw.c | 30 +- reactos/ntoskrnl/io/symlink.c | 2 + reactos/ntoskrnl/ke/apc.c | 106 ++- reactos/ntoskrnl/ke/bug.c | 1 + reactos/ntoskrnl/ke/critical.c | 7 +- reactos/ntoskrnl/ke/dpc.c | 8 +- reactos/ntoskrnl/ke/kqueue.c | 3 +- reactos/ntoskrnl/ke/timer.c | 10 +- reactos/ntoskrnl/ke/wait.c | 8 +- reactos/ntoskrnl/ldr/init.c | 6 +- reactos/ntoskrnl/ldr/loader.c | 2 +- reactos/ntoskrnl/makefile_rex | 24 +- reactos/ntoskrnl/mm/marea.c | 67 +- reactos/ntoskrnl/mm/mdl.c | 17 +- reactos/ntoskrnl/mm/mm.c | 21 +- reactos/ntoskrnl/mm/virtual.c | 11 +- reactos/ntoskrnl/nt/port.c | 2 +- reactos/ntoskrnl/ntoskrnl.def | 71 +- reactos/ntoskrnl/ob/handle.c | 19 +- reactos/ntoskrnl/ob/object.c | 2 + reactos/ntoskrnl/ps/kill.c | 2 +- reactos/ntoskrnl/ps/process.c | 10 +- reactos/ntoskrnl/ps/thread.c | 57 +- reactos/ntoskrnl/rtl/strtok.c | 3 +- reactos/rules.mak | 2 + reactos/subsys/win32k/makefile | 2 +- 102 files changed, 3109 insertions(+), 1372 deletions(-) create mode 100644 reactos/COPYING create mode 100644 reactos/CREDITS create mode 100644 reactos/INSTALL create mode 100644 reactos/README create mode 100644 reactos/apps/tests/bench/bench-syscall.c create mode 100644 reactos/doc/apc create mode 100644 reactos/drivers/fs/ext2/attr.c create mode 100644 reactos/drivers/fs/ext2/quota.c create mode 100644 reactos/drivers/fs/ext2/security.c create mode 100644 reactos/include/ntdll/base.h create mode 100644 reactos/lib/kernel32/thread/tls.c diff --git a/reactos/COPYING b/reactos/COPYING new file mode 100644 index 00000000000..dc63aaca038 --- /dev/null +++ b/reactos/COPYING @@ -0,0 +1,340 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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. + + , 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. diff --git a/reactos/CREDITS b/reactos/CREDITS new file mode 100644 index 00000000000..86b040c884b --- /dev/null +++ b/reactos/CREDITS @@ -0,0 +1,11 @@ +In no particular order + +Rex Jolliff (rex@lvcablemodem.com) +Boudewijn Dekker (ariadne@xs4all.nl) +Eric Kohl (ekohl@abo.rhein-zeitung.de) +Emanuele Aliberti (ea@iol.it) +David Welch (welch@cwcom.net) +Iwan Fatahi (i_fatahi@hotmail.com) +Robert Bergkvist (fragdance@hotmail.com) +Victor Kirhenshtein (sauros@iname.com) +Jason Filby (jasonfilby@yahoo.com) diff --git a/reactos/INSTALL b/reactos/INSTALL new file mode 100644 index 00000000000..ceefb015729 --- /dev/null +++ b/reactos/INSTALL @@ -0,0 +1,27 @@ +1. Build environment + +To build the system you need either mingw32 installed on Windows or a +mingw32 cross compiler running on unix. + +2. Building + +To build from Windows run 'make -fmakefile.dos'. To build from unix, edit +rules.mak and change the PREFIX variable to the correct value for your +cross-compiler, then run 'make'. + +3. Installation + +Installation isn't yet automated, sorry. The system can only be installed on +the first partition which must be formatted for DOS. Set up a directory +structure like the following + +make directories C:\reactos,C:\reactos\system,C:\reactos\system\drivers + +Copy apps/shell/shell.exe to C:\reactos\system +Copy services/dd/keyboard/keyboard.sys to C:\reactos\system\drivers +Copy services/dd/blue/blue.sys to C:\reactos\system\drivers + +The system can only be started from DOS. Copy the following files, +services/dd/ide/ide.sys, services/fs/vfat/vfatfsd.sys and +loaders/dos/loadros.com, to a suitable directory. The system can then be +booted with the command 'loadros.com ide.sys vfatfsd.sys'. diff --git a/reactos/README b/reactos/README new file mode 100644 index 00000000000..7d8bcabd268 --- /dev/null +++ b/reactos/README @@ -0,0 +1,24 @@ +About Reactos + +1. What is Reactos + +A project aiming to make an approximate clone of Windows NT, compatible +with most Windows applications. + +The project has a website at http://www.sid-dis.com/reactos + +2. Building Reactos + +See the INSTALL file for more details. + +3. More information + +See the doc subdirectory for some sparse notes + +4. Who is responsible + +See the CREDITS file + +5. Recent developments + +See the NEWS file diff --git a/reactos/apps/tests/args/args.c b/reactos/apps/tests/args/args.c index 9e3aca04e8d..ace8b49e33e 100644 --- a/reactos/apps/tests/args/args.c +++ b/reactos/apps/tests/args/args.c @@ -25,7 +25,8 @@ void main(int argc, char* argv[]) AllocConsole(); InputHandle = GetStdHandle(STD_INPUT_HANDLE); OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); - + + printf("GetCommandLineA() %s\n",GetCommandLineA()); debug_printf("GetCommandLineA() %s\n",GetCommandLineA()); for (i=0; i #include @@ -32,6 +21,8 @@ #include "keyboard.h" +/* GLOBALS *******************************************************************/ + /* * Driver data */ @@ -43,7 +34,6 @@ static int extKey; static BYTE ledStatus; static BYTE capsDown,numDown,scrollDown; static DWORD ctrlKeyState; -static KSPIN_LOCK kbdBufferLock; static PKINTERRUPT KbdInterrupt; static KDPC KbdDpc; @@ -119,12 +109,12 @@ static const BYTE asciiTable4[37]= '{', '|', '}', '"' }; +/* 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; @@ -135,12 +125,10 @@ static void KbdWrite(int addr,BYTE data) 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; @@ -371,7 +359,7 @@ static BYTE VirtualToAscii(WORD keyCode,BOOL isDown) return asciiTable2[keyCode-VK_NUMPAD0]; if ((keyCode>=186)&&(keyCode<=222)) - { + { if (ctrlKeyState & SHIFT_PRESSED) return asciiTable4[keyCode-186]; else @@ -525,7 +513,7 @@ static BOOLEAN KeyboardHandler(PKINTERRUPT Interrupt, PVOID Context) if (keysInBuffer==KBD_BUFFER_SIZE) // Buffer is full { extKey=0; - return FALSE; + return(TRUE); } kbdBuffer[bufHead].bKeyDown=isDown; kbdBuffer[bufHead].wRepeatCount=1; @@ -541,7 +529,6 @@ static BOOLEAN KeyboardHandler(PKINTERRUPT Interrupt, PVOID Context) bufHead&=KBD_WRAP_MASK; // Modulo KBD_BUFFER_SIZE keysInBuffer++; extKey=0; - return TRUE; } @@ -593,16 +580,13 @@ static int InitializeKeyboard(void) return 0; } - /* * Read data from keyboard buffer */ - BOOLEAN KbdSynchronizeRoutine(PVOID Context) { PIRP Irp = (PIRP)Context; - KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *) - Irp->AssociatedIrp.SystemBuffer; + KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)Irp->AssociatedIrp.SystemBuffer; PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp); ULONG NrToRead = stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD); int i; @@ -634,7 +618,9 @@ BOOLEAN KbdSynchronizeRoutine(PVOID Context) VOID KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp) { +#ifndef NDEBUG PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp); +#endif DPRINT("KeyboardStartIo(DeviceObject %x Irp %x)\n",DeviceObject,Irp); @@ -691,18 +677,16 @@ NTSTATUS KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) return(Status); } +NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath) /* - * Module entry point + * FUNCTION: Module entry point */ -STDCALL NTSTATUS -DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { PDEVICE_OBJECT DeviceObject; - ANSI_STRING adevice_name; - UNICODE_STRING device_name; - ANSI_STRING asymlink_name; - UNICODE_STRING symlink_name; - + UNICODE_STRING DeviceName; + UNICODE_STRING SymlinkName; + DbgPrint("Keyboard Driver 0.0.4\n"); InitializeKeyboard(); @@ -710,16 +694,19 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdDispatch; DriverObject->MajorFunction[IRP_MJ_READ] = KbdDispatch; DriverObject->DriverStartIo = KbdStartIo; - - RtlInitAnsiString(&adevice_name,"\\Device\\Keyboard"); - RtlAnsiStringToUnicodeString(&device_name,&adevice_name,TRUE); - IoCreateDevice(DriverObject,0,&device_name,FILE_DEVICE_KEYBOARD,0, - TRUE,&DeviceObject); - DeviceObject->Flags = DO_BUFFERED_IO; - - RtlInitAnsiString(&asymlink_name,"\\??\\Keyboard"); - RtlAnsiStringToUnicodeString(&symlink_name,&asymlink_name,TRUE); - IoCreateSymbolicLink(&symlink_name,&device_name); - + + RtlInitUnicodeString(&DeviceName, L"\\Device\\Keyboard"); + IoCreateDevice(DriverObject, + 0, + &DeviceName, + FILE_DEVICE_KEYBOARD, + 0, + TRUE, + &DeviceObject); + DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO; + + RtlInitUnicodeString(&SymlinkName, L"\\??\\Keyboard"); + IoCreateSymbolicLink(&SymlinkName, &DeviceName); + return(STATUS_SUCCESS); } diff --git a/reactos/drivers/fs/ext2/attr.c b/reactos/drivers/fs/ext2/attr.c new file mode 100644 index 00000000000..cc31ef576b5 --- /dev/null +++ b/reactos/drivers/fs/ext2/attr.c @@ -0,0 +1,125 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/fs/ext2/attr.c + * PURPOSE: Set/Get file attributes support + * PROGRAMMER: David Welch (welch@cwcom.net) + * UPDATE HISTORY: + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include + +//#define NDEBUG +#include + +#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); +} + diff --git a/reactos/drivers/fs/ext2/blockdev.c b/reactos/drivers/fs/ext2/blockdev.c index 1b72df6ab62..9bd1fec05bc 100644 --- a/reactos/drivers/fs/ext2/blockdev.c +++ b/reactos/drivers/fs/ext2/blockdev.c @@ -1,9 +1,9 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: services/fs/vfat/blockdev.c + * FILE: services/fs/ext2/blockdev.c * PURPOSE: Temporary sector reading support - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: */ @@ -13,7 +13,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include #include "ext2fs.h" @@ -42,8 +42,8 @@ BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject, DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n", (unsigned long) DiskSector, (unsigned long) BLOCKSIZE, - (unsigned long) sectorNumber.HighPart, - (unsigned long) sectorNumber.LowPart); + (unsigned long) sectorNumber.u.HighPart, + (unsigned long) sectorNumber.u.LowPart); KeInitializeEvent(&event, NotificationEvent, FALSE); @@ -59,17 +59,18 @@ BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject, &event, &ioStatus ); - if (!irp) { + if (!irp) + { DbgPrint("READ failed!!!\n"); return FALSE; - } - + } + DPRINT("Calling IO Driver...\n"); - status = IoCallDriver(pDeviceObject, - irp); + status = IoCallDriver(pDeviceObject, irp); DPRINT("Waiting for IO Operation...\n"); - if (status == STATUS_PENDING) { + if (status == STATUS_PENDING) + { KeWaitForSingleObject(&event, Suspended, KernelMode, @@ -77,14 +78,15 @@ BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject, NULL); DPRINT("Getting IO Status...\n"); status = ioStatus.Status; - } + } - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(status)) + { DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status); return FALSE; - } - - return TRUE; + } + + return TRUE; } BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject, diff --git a/reactos/drivers/fs/ext2/dir.c b/reactos/drivers/fs/ext2/dir.c index 7b2ad1a61a3..8441dba9bc0 100644 --- a/reactos/drivers/fs/ext2/dir.c +++ b/reactos/drivers/fs/ext2/dir.c @@ -13,14 +13,15 @@ #include #include -#define NDEBUG +//#define NDEBUG #include #include "ext2fs.h" /* FUNCTIONS *****************************************************************/ -VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len) + +static VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len) { ULONG i; @@ -42,8 +43,6 @@ PVOID Ext2ProcessDirEntry(PDEVICE_EXTENSION DeviceExt, PFILE_DIRECTORY_INFORMATION FDI; PFILE_NAMES_INFORMATION FNI; PFILE_BOTH_DIRECTORY_INFORMATION FBI; - ULONG i; - PWSTR FileName; struct ext2_inode inode; DPRINT("FileIndex %d\n",FileIndex); @@ -108,13 +107,11 @@ NTSTATUS Ext2QueryDirectory(PDEVICE_EXTENSION DeviceExt, ULONG Max; ULONG i; ULONG StartIndex; - PVOID Buffer; + PVOID Buffer = NULL; struct ext2_dir_entry dir_entry; - ULONG CurrentIndex; - - DPRINT("Buffer %x\n",Buffer); Buffer = Irp->UserBuffer; + DPRINT("Buffer %x\n",Buffer); DPRINT("IoStack->Flags %x\n",IoStack->Flags); if (IoStack->Flags & SL_RETURN_SINGLE_ENTRY) @@ -201,6 +198,7 @@ BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt, char name[255]; struct ext2_dir_entry* current; ULONG block; + BOOL b; DPRINT("Ext2ScanDir(dir %x, filename %s, ret %x)\n",dir,filename,ret); @@ -210,10 +208,15 @@ BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt, for (; (block = Ext2BlockMap(DeviceExt, dir, i)) != 0; i++) { DPRINT("block %d\n",block); - Ext2ReadSectors(DeviceExt->StorageDevice, - block, - 1, - buffer); + b = Ext2ReadSectors(DeviceExt->StorageDevice, + block, + 1, + buffer); + if (!b) + { + DbgPrint("ext2fs:%s:%d: Disk io failed\n", __FILE__, __LINE__); + return(FALSE); + } offset = (*StartIndex)%BLOCKSIZE; while (offset < BLOCKSIZE) @@ -264,7 +267,7 @@ NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, * FUNCTION: Opens a file */ { - struct ext2_inode parent_inode; + EXT2_INODE parent_inode; struct ext2_dir_entry entry; char name[255]; ULONG current_inode = 2; @@ -279,28 +282,35 @@ NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, unicode_to_ansi(name,FileName); DPRINT("name %s\n",name); - + DPRINT("strtok %x\n",strtok); current_segment = strtok(name,"\\"); + DPRINT("current_segment %x\n", current_segment); while (current_segment!=NULL) { - Ext2ReadInode(DeviceExt, + Ext2LoadInode(DeviceExt, current_inode, &parent_inode); - if (!Ext2ScanDir(DeviceExt,&parent_inode,current_segment,&entry, + if (!Ext2ScanDir(DeviceExt, + parent_inode.inode, + current_segment, + &entry, &StartIndex)) { + Ext2ReleaseInode(DeviceExt, + &parent_inode); ExFreePool(Fcb); return(STATUS_UNSUCCESSFUL); } current_inode = entry.inode; current_segment = strtok(NULL,"\\"); StartIndex = 0; + Ext2ReleaseInode(DeviceExt, + &parent_inode); } DPRINT("Found file\n"); - Ext2ReadInode(DeviceExt, - current_inode, - &Fcb->inode); + Fcb->inode = current_inode; + CcInitializeFileCache(FileObject, &Fcb->Bcb); FileObject->FsContext = Fcb; return(STATUS_SUCCESS); diff --git a/reactos/drivers/fs/ext2/ext2fs.h b/reactos/drivers/fs/ext2/ext2fs.h index 5b5bf995d4f..f00395ab5e2 100644 --- a/reactos/drivers/fs/ext2/ext2fs.h +++ b/reactos/drivers/fs/ext2/ext2fs.h @@ -1,3 +1,5 @@ +#include + BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject, IN ULONG DiskSector, IN ULONG SectorCount, @@ -214,8 +216,22 @@ typedef struct { PDEVICE_OBJECT StorageDevice; struct ext2_super_block* superblock; + PFILE_OBJECT FileObject; + PBCB Bcb; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; +typedef struct _EXT2_GROUP_DESC +{ + ERESOURCE Lock; + struct ext2_group_desc* desc; + PCACHE_SEGMENT CacheSeg; + PVOID BaseAddress; +} EXT2_GROUP_DESC, *PEXT2_GROUP_DESC; + +PEXT2_GROUP_DESC Ext2LoadGroup(PDEVICE_EXTENSION DeviceExt, + ULONG BlockGrp); +VOID Ext2ReleaseGroup(PDEVICE_EXTENSION DeviceExt, + PEXT2_GROUP_DESC GrpDesc); VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt, ULONG ino, @@ -223,14 +239,23 @@ VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt, struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt, ULONG block_group); +typedef struct _EXT2_INODE +{ + struct ext2_inode* inode; + PVOID BaseAddress; + PCACHE_SEGMENT CacheSeg; +} EXT2_INODE, *PEXT2_INODE; + typedef struct _EXT2_FCB { - struct ext2_inode inode; + ULONG inode; + EXT2_INODE i; + PBCB Bcb; } EXT2_FCB, *PEXT2_FCB; ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt, - struct ext2_inode* inode, - ULONG offset); + struct ext2_inode* inode, + ULONG offset); NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PWSTR FileName); NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt, @@ -240,3 +265,24 @@ NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt, LARGE_INTEGER Offset); NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2QueryQuota(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2SetQuota(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2SetSecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2QuerySecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2SetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2QueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2Cleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2FlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2Shutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS Ext2ReadPage(PDEVICE_EXTENSION DeviceExt, + PEXT2_FCB Fcb, + PVOID Buffer, + ULONG Offset); +VOID Ext2LoadInode(PDEVICE_EXTENSION DeviceExt, + ULONG ino, + PEXT2_INODE Inode); +VOID Ext2ReleaseInode(PDEVICE_EXTENSION DeviceExt, + PEXT2_INODE Inode); + diff --git a/reactos/drivers/fs/ext2/file.c b/reactos/drivers/fs/ext2/file.c index 7cdb4b2c3ca..f3f42400536 100644 --- a/reactos/drivers/fs/ext2/file.c +++ b/reactos/drivers/fs/ext2/file.c @@ -26,6 +26,7 @@ ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt, { ULONG block; PULONG TempBuffer; + BOOL b; DPRINT("Ext2BlockMap(DeviceExt %x, inode %x, offset %d)\n", DeviceExt,inode,offset); @@ -40,14 +41,21 @@ ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt, { block = inode->i_block[EXT2_IND_BLOCK]; TempBuffer = ExAllocatePool(NonPagedPool, BLOCKSIZE); - Ext2ReadSectors(DeviceExt->StorageDevice, - block, - 1, - TempBuffer); + b = Ext2ReadSectors(DeviceExt->StorageDevice, + block, + 1, + TempBuffer); + if (!b) + { + DbgPrint("ext2fs:%s:%d: Disk io failed\n", __FILE__, __LINE__); + return(0); + } block = TempBuffer[offset]; ExFreePool(TempBuffer); return(block); } + offset = offset - addr_per_block; DbgPrint("Failed at %s:%d\n",__FILE__,__LINE__); for(;;); } + diff --git a/reactos/drivers/fs/ext2/inode.c b/reactos/drivers/fs/ext2/inode.c index 741085a357e..f95646007cc 100644 --- a/reactos/drivers/fs/ext2/inode.c +++ b/reactos/drivers/fs/ext2/inode.c @@ -12,8 +12,9 @@ #include #include +#include -#define NDEBUG +//#define NDEBUG #include #include "ext2fs.h" @@ -45,8 +46,76 @@ struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt, } +#define INODES_PER_PAGE (PAGESIZE / sizeof(struct ext2_inode)) #define INODES_PER_BLOCK (BLOCKSIZE / sizeof(struct ext2_inode)) +VOID Ext2LoadInode(PDEVICE_EXTENSION DeviceExt, + ULONG ino, + PEXT2_INODE Inode) +{ + ULONG block_group; + struct ext2_group_desc* gdp; + ULONG offset; + ULONG dsec; + BOOLEAN Uptodate; + struct ext2_inode* ibuffer; + + DPRINT("Ext2LoadInode(DeviceExt %x, ino %d, Inode %x)\n", + DeviceExt, ino, Inode); + + block_group = (ino - 1) / DeviceExt->superblock->s_inodes_per_group; + + DPRINT("block_group %d\n",block_group); + + gdp = Ext2LoadGroupDesc(DeviceExt, block_group); + + offset = (ino - 1) % DeviceExt->superblock->s_inodes_per_group; + + DPRINT("offset %d\n", offset); + + dsec = (gdp->bg_inode_table + (offset / INODES_PER_BLOCK)) * BLOCKSIZE; + + DPRINT("dsec %d (dsec/BLOCKSIZE) %d PAGE_ROUND_DOWN(dsec) %d\n", + dsec, (dsec/BLOCKSIZE), PAGE_ROUND_DOWN(dsec)); + + CcRequestCachePage(DeviceExt->Bcb, + PAGE_ROUND_DOWN(dsec), + &Inode->BaseAddress, + &Uptodate, + &Inode->CacheSeg); + DPRINT("PAGE_ROUND_DOWN(dsec)/BLOCKSIZE %d\n", + PAGE_ROUND_DOWN(dsec)/BLOCKSIZE); + if (!Uptodate) + { + Ext2ReadSectors(DeviceExt->StorageDevice, + PAGE_ROUND_DOWN(dsec) / BLOCKSIZE, + 4, + Inode->BaseAddress); + } + ibuffer = ((struct ext2_inode *)Inode->BaseAddress) + + (dsec - PAGE_ROUND_DOWN(dsec)); + DPRINT("Inode->BaseAddress 0x%x ibuffer 0x%x\n", + Inode->BaseAddress, ibuffer); + Inode->inode = &ibuffer[offset % INODES_PER_PAGE]; + + DPRINT("inode->i_uid %d\n",Inode->inode->i_uid); + DPRINT("inode->i_links_count %d\n",Inode->inode->i_links_count); + DPRINT("inode->i_blocks %d\n",Inode->inode->i_blocks); + + DPRINT("Ext2LoadInode() finished\n"); +} + +VOID Ext2ReleaseInode(PDEVICE_EXTENSION DeviceExt, + PEXT2_INODE Inode) +{ + CcReleaseCachePage(DeviceExt->Bcb, + Inode->CacheSeg, + TRUE); + Inode->CacheSeg = NULL; + Inode->BaseAddress = NULL; + Inode->inode = NULL; +} + VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt, ULONG ino, struct ext2_inode* inode) @@ -77,4 +146,5 @@ VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt, DPRINT("inode->i_uid %d\n",inode->i_uid); DPRINT("inode->i_links_count %d\n",inode->i_links_count); DPRINT("inode->i_blocks %d\n",inode->i_blocks); + } diff --git a/reactos/drivers/fs/ext2/makefile b/reactos/drivers/fs/ext2/makefile index 5884846ddb7..1d170445897 100644 --- a/reactos/drivers/fs/ext2/makefile +++ b/reactos/drivers/fs/ext2/makefile @@ -1,8 +1,8 @@ # # # -OBJECTS = super.o blockdev.o inode.o file.o dir.o rw.o \ - ../../../ntoskrnl/ntoskrnl.a +OBJECTS = super.o blockdev.o inode.o file.o dir.o rw.o quota.o security.o \ + attr.o ../../../ntoskrnl/ntoskrnl.a all: ext2fs.sys diff --git a/reactos/drivers/fs/ext2/quota.c b/reactos/drivers/fs/ext2/quota.c new file mode 100644 index 00000000000..0cb061b7970 --- /dev/null +++ b/reactos/drivers/fs/ext2/quota.c @@ -0,0 +1,47 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/fs/ext2/quota.c + * PURPOSE: Quota support + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include + +//#define NDEBUG +#include + +#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); +} diff --git a/reactos/drivers/fs/ext2/rw.c b/reactos/drivers/fs/ext2/rw.c index 33800fc4e63..d5b3c1da1b5 100644 --- a/reactos/drivers/fs/ext2/rw.c +++ b/reactos/drivers/fs/ext2/rw.c @@ -10,6 +10,7 @@ /* INCLUDES *****************************************************************/ #include +#include #define NDEBUG #include @@ -18,77 +19,196 @@ /* FUNCTIONS *****************************************************************/ +NTSTATUS Ext2ReadPage(PDEVICE_EXTENSION DeviceExt, + PEXT2_FCB Fcb, + PVOID Buffer, + ULONG Offset) +{ + ULONG block, i; + + for (i=0; i<4; i++) + { + block = Ext2BlockMap(DeviceExt, + Fcb->i.inode, + Offset + i); + Ext2ReadSectors(DeviceExt->StorageDevice, + block, + 1, + Buffer + (i*BLOCKSIZE)); + } + return(STATUS_SUCCESS); +} + NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PVOID Buffer, ULONG Length, LARGE_INTEGER OffsetL) -/* - * FUNCTION: Reads data from a file - */ { + PVOID BaseAddress; + BOOLEAN Uptodate = FALSE; + PCACHE_SEGMENT CacheSeg; + ULONG Offset = (ULONG)OffsetL.u.LowPart; PEXT2_FCB Fcb; - PVOID TempBuffer; - ULONG Offset = OffsetL.u.LowPart; - ULONG block; - ULONG Delta; - ULONG i; - + ULONG block, i, Delta; DPRINT("Ext2ReadFile(DeviceExt %x, FileObject %x, Buffer %x, Length %d, \n" "OffsetL %d)\n",DeviceExt,FileObject,Buffer,Length,(ULONG)OffsetL); - + Fcb = (PEXT2_FCB)FileObject->FsContext; - TempBuffer = ExAllocatePool(NonPagedPool, BLOCKSIZE); + + Ext2LoadInode(DeviceExt, + Fcb->inode, + &Fcb->i); - if (Offset >= Fcb->inode.i_size) + if (Offset >= Fcb->i.inode->i_size) { - ExFreePool(TempBuffer); + DPRINT("Returning end of file\n"); return(STATUS_END_OF_FILE); } - if ((Offset + Length) > Fcb->inode.i_size) + if ((Offset + Length) > Fcb->i.inode->i_size) { - Length = Fcb->inode.i_size - Offset; + Length = Fcb->i.inode->i_size - Offset; } - CHECKPOINT; - if ((Offset % BLOCKSIZE) != 0) + Ext2ReleaseInode(DeviceExt, + &Fcb->i); + + if ((Offset % PAGESIZE) != 0) { - block = Ext2BlockMap(DeviceExt, &Fcb->inode, Offset / BLOCKSIZE); - Delta = min(BLOCKSIZE - (Offset % BLOCKSIZE),Length); - Ext2ReadSectors(DeviceExt->StorageDevice, - block, - 1, - TempBuffer); - memcpy(Buffer, TempBuffer + (Offset % BLOCKSIZE), Delta); + Delta = min(PAGESIZE - (Offset % PAGESIZE),Length); + CcRequestCachePage(Fcb->Bcb, + Offset, + &BaseAddress, + &Uptodate, + &CacheSeg); + if (Uptodate == FALSE) + { + Ext2ReadPage(DeviceExt, + Fcb, + BaseAddress, + Offset / BLOCKSIZE); + } + memcpy(Buffer, BaseAddress + (Offset % PAGESIZE), Delta); + CcReleaseCachePage(Fcb->Bcb, + CacheSeg, + TRUE); Length = Length - Delta; Offset = Offset + Delta; Buffer = Buffer + Delta; } CHECKPOINT; - for (i=0; i<(Length/BLOCKSIZE); i++) + for (i=0; i<(Length/PAGESIZE); i++) { - block = Ext2BlockMap(DeviceExt, &Fcb->inode, - (Offset / BLOCKSIZE)+i); - Ext2ReadSectors(DeviceExt->StorageDevice, - block, - 1, - Buffer); - Length = Length - BLOCKSIZE; - Offset = Offset + BLOCKSIZE; - Buffer = Buffer + BLOCKSIZE; + CcRequestCachePage(Fcb->Bcb, + Offset, + &BaseAddress, + &Uptodate, + &CacheSeg); + if (Uptodate == FALSE) + { + Ext2ReadPage(DeviceExt, + Fcb, + BaseAddress, + (Offset / BLOCKSIZE)); + } + memcpy(Buffer, BaseAddress, PAGESIZE); + CcReleaseCachePage(Fcb->Bcb, + CacheSeg, + TRUE); + Length = Length - PAGESIZE; + Offset = Offset + PAGESIZE; + Buffer = Buffer + PAGESIZE; } CHECKPOINT; - if ((Length % BLOCKSIZE) != 0) + if ((Length % PAGESIZE) != 0) { - block = Ext2BlockMap(DeviceExt, &Fcb->inode, Offset / BLOCKSIZE); - Ext2ReadSectors(DeviceExt->StorageDevice, - block, - 1, - TempBuffer); - memcpy(Buffer,TempBuffer,Length); + CcRequestCachePage(Fcb->Bcb, + Offset, + &BaseAddress, + &Uptodate, + &CacheSeg); + if (Uptodate == FALSE) + { + Ext2ReadPage(DeviceExt, + Fcb, + BaseAddress, + (Offset / BLOCKSIZE)); + } + DPRINT("Copying %x to %x Length %d\n",BaseAddress,Buffer,Length); + memcpy(Buffer,BaseAddress,Length); + CcReleaseCachePage(Fcb->Bcb, + CacheSeg, + TRUE); } - - ExFreePool(TempBuffer); + CHECKPOINT; return(STATUS_SUCCESS); } + + +NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + DPRINT("Ext2Write(DeviceObject %x Irp %x)\n",DeviceObject,Irp); + + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + return(STATUS_UNSUCCESSFUL); +} + +NTSTATUS Ext2FlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + DPRINT("Ext2FlushBuffers(DeviceObject %x Irp %x)\n",DeviceObject,Irp); + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + return(STATUS_UNSUCCESSFUL); +} + +NTSTATUS Ext2Shutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + DPRINT("Ext2Shutdown(DeviceObject %x Irp %x)\n",DeviceObject,Irp); + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + return(STATUS_UNSUCCESSFUL); +} + +NTSTATUS Ext2Cleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + DbgPrint("Ext2Cleanup(DeviceObject %x Irp %x)\n",DeviceObject,Irp); + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + DbgPrint("Ext2Cleanup() finished\n"); + + return(STATUS_UNSUCCESSFUL); +} + +NTSTATUS Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + ULONG Length; + PVOID Buffer; + PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); + PFILE_OBJECT FileObject = Stack->FileObject; + PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; + NTSTATUS Status; + + DPRINT("Ext2Read(DeviceObject %x, FileObject %x, Irp %x)\n", + DeviceObject, FileObject, Irp); + + Length = Stack->Parameters.Read.Length; + CHECKPOINT; + Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); + CHECKPOINT; + CHECKPOINT; + + Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length, + Stack->Parameters.Read.ByteOffset); + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = Length; + IoCompleteRequest(Irp,IO_NO_INCREMENT); + + return(Status); +} diff --git a/reactos/drivers/fs/ext2/security.c b/reactos/drivers/fs/ext2/security.c new file mode 100644 index 00000000000..122415770c4 --- /dev/null +++ b/reactos/drivers/fs/ext2/security.c @@ -0,0 +1,39 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: services/fs/ext2/security.c + * PURPOSE: Security support + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include + +//#define NDEBUG +#include + +#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); +} diff --git a/reactos/drivers/fs/ext2/super.c b/reactos/drivers/fs/ext2/super.c index a9bac494387..130c27e3482 100644 --- a/reactos/drivers/fs/ext2/super.c +++ b/reactos/drivers/fs/ext2/super.c @@ -13,7 +13,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include #include "ext2fs.h" @@ -30,55 +30,45 @@ NTSTATUS Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp) PFILE_OBJECT FileObject; PDEVICE_EXTENSION DeviceExtension; NTSTATUS Status; + PEXT2_FCB Fcb; - DPRINT("Ext2Close(DeviceObject %x, Irp %x)\n",DeviceObject,Irp); + DbgPrint("Ext2Close(DeviceObject %x, Irp %x)\n",DeviceObject,Irp); Stack = IoGetCurrentIrpStackLocation(Irp); FileObject = Stack->FileObject; DeviceExtension = DeviceObject->DeviceExtension; - - 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; @@ -111,12 +101,19 @@ NTSTATUS Ext2Mount(PDEVICE_OBJECT DeviceToMount) 0, FALSE, &DeviceObject); + DPRINT("DeviceObject %x\n",DeviceObject); DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO; DeviceExt = (PVOID)DeviceObject->DeviceExtension; - + DPRINT("DeviceExt %x\n",DeviceExt); DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, DeviceToMount); + DPRINT("DeviceExt->StorageDevice %x\n", DeviceExt->StorageDevice); + DeviceExt->FileObject = IoCreateStreamFileObject(NULL, DeviceObject); DeviceExt->superblock = superblock; + CcInitializeFileCache(DeviceExt->FileObject, + &DeviceExt->Bcb); + + DPRINT("Ext2Mount() = STATUS_SUCCESS\n"); return(STATUS_SUCCESS); } @@ -177,13 +174,20 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject, DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2Write; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = Ext2FileSystemControl; - DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]= + DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = Ext2DirectoryControl; - DriverObject->DriverUnload = NULL; + DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = + Ext2QueryInformation; + DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = Ext2SetInformation; + DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = Ext2FlushBuffers; + DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = Ext2Shutdown; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Ext2Cleanup; + DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = Ext2QuerySecurity; + DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = Ext2SetSecurity; + DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = Ext2QueryQuota; + DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = Ext2SetQuota; - DPRINT("DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] %x\n", - DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]); - DPRINT("IRP_MJ_DIRECTORY_CONTROL %d\n",IRP_MJ_DIRECTORY_CONTROL); + DriverObject->DriverUnload = NULL; IoRegisterFileSystem(DeviceObject); diff --git a/reactos/drivers/fs/vfat/iface.c b/reactos/drivers/fs/vfat/iface.c index ca8a8f55430..8c1c86ba97c 100644 --- a/reactos/drivers/fs/vfat/iface.c +++ b/reactos/drivers/fs/vfat/iface.c @@ -1679,7 +1679,8 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject; NTSTATUS Status; - DPRINT("VFAT FSC\n"); +// DPRINT("VFAT FSC\n"); + DbgPrint("VFAT FSC\n"); /* FIXME: should make sure that this is actually a mount request! */ diff --git a/reactos/include/ddk/ccfuncs.h b/reactos/include/ddk/ccfuncs.h index f536530defe..e69de29bb2d 100644 --- a/reactos/include/ddk/ccfuncs.h +++ b/reactos/include/ddk/ccfuncs.h @@ -1,4 +0,0 @@ -VOID CbInitDccb(PDCCB Dccb, PDEVICE_OBJECT DeviceObject, ULONG SectorSize, - ULONG NrSectors, ULONG PercentageToCache); -PCCB CbAcquireForRead(PDCCB Dccb, ULONG BlockNr); -VOID CbReleaseFromRead(PDCCB Dccb, PCCB Ccb); diff --git a/reactos/include/ddk/cctypes.h b/reactos/include/ddk/cctypes.h index 0955e83050e..148ed6b4a1d 100644 --- a/reactos/include/ddk/cctypes.h +++ b/reactos/include/ddk/cctypes.h @@ -1,43 +1,4 @@ #ifndef __INCLUDE_DDK_CCTYPES_H #define __INCLUDE_DDK_CCTYPES_H -typedef struct _CCB -{ - ULONG BlockNr; - PVOID Buffer; - ULONG State; - ULONG ActiveReaders; - BOOLEAN WriteInProgress; - BOOLEAN ActiveWriter; - ULONG References; - KEVENT FinishedNotify; - KSPIN_LOCK Lock; - BOOLEAN Modified; - LIST_ENTRY Entry; -} CCB, *PCCB; - -enum -{ - CCB_INVALID, - CCB_NOT_CACHED, - CCB_CACHED, - CCB_DELETE_PENDING, -}; - -typedef struct _DCCB -/* - * PURPOSE: Device cache control block - */ -{ - PCCB* HashTbl; - ULONG HashTblSize; - KSPIN_LOCK HashTblLock; - PDEVICE_OBJECT DeviceObject; - ULONG SectorSize; - LIST_ENTRY CcbListHead; - KSPIN_LOCK CcbListLock; - ULONG NrCcbs; - ULONG NrModifiedCcbs; -} DCCB, *PDCCB; - #endif /* __INCLUDE_DDK_CCTYPES_H */ diff --git a/reactos/include/ddk/defines.h b/reactos/include/ddk/defines.h index 07c7c8af4ae..f4f4b0ff66a 100644 --- a/reactos/include/ddk/defines.h +++ b/reactos/include/ddk/defines.h @@ -231,20 +231,8 @@ enum /* * IRQ levels */ -enum -{ - PASSIVE_LEVEL, - - /* - * Which order for these (only DISPATCH_LEVEL is important for now) - */ - APC_LEVEL, - DISPATCH_LEVEL, - - /* - * Above here are device specific IRQ levels - */ - FIRST_DEVICE_SPECIFIC_LEVEL, - HIGH_LEVEL = FIRST_DEVICE_SPECIFIC_LEVEL + NR_DEVICE_SPECIFIC_LEVELS, -}; - +#define PASSIVE_LEVEL (1) +#define APC_LEVEL (2) +#define DISPATCH_LEVEL (3) +#define FIRST_DEVICE_SPECIFIC_LEVEL (4) +#define HIGH_LEVEL (FIRST_DEVICE_SPECIFIC_LEVEL + NR_DEVICE_SPECIFIC_LEVELS) diff --git a/reactos/include/ddk/iodef.h b/reactos/include/ddk/iodef.h index 431564c35dc..bec861fb693 100644 --- a/reactos/include/ddk/iodef.h +++ b/reactos/include/ddk/iodef.h @@ -67,42 +67,27 @@ enum IRP_DEFER_IO_COMPLETION = 0x2000, }; -/* - * I/O operation flags - */ -enum -{ - SL_FORCE_ACCESS_CHECK = 0x1, - SL_OPEN_PAGING_FILE = 0x2, - SL_OPEN_TARGET_DIRECTORY = 0x4, - SL_CASE_SENSITIVE = 0x8, - SL_KEY_SPECIFIED = 0x10, - SL_OVERRIDE_VERIFY_VOLUME = 0x20, - SL_WRITE_THROUGH = 0x40, - SL_FT_SEQUENTIAL_WRITE = 0x80, - SL_FAIL_IMMEDIATELY = 0x100, - SL_EXCLUSIVE_LOCK = 0x200, - SL_WATCH_TREE = 0x2000, - SL_ALLOW_RAW_MOUNT = 0x4000, -}; - #define SL_FORCE_ACCESS_CHECK (0x1) #define SL_OPEN_PAGING_FILE (0x2) #define SL_OPEN_TARGET_DIRECTORY (0x4) -#define SL_CASE_SENSITIVE (0x8) -#define SL_KEY_SPECIFIED (0x10) -#define SL_OVERRIDE_VERIFY_VOLUME (0x20) -#define SL_WRITE_THROUGHT (0x40) -#define SL_FT_SEQUENTIAL_WRITE (0x80) -#define SL_FAIL_IMMEDIATELY (0x100) -#define SL_EXCLUSIVE_LOCK (0x200) -#define SL_WATCH_TREE (0x2000) +#define SL_CASE_SENSITIVE (0x80) + +#define SL_KEY_SPECIFIED (0x1) +#define SL_OVERRIDE_VERIFY_VOLUME (0x2) +#define SL_WRITE_THROUGHT (0x4) +#define SL_FT_SEQUENTIAL_WRITE (0x8) +#define SL_FAIL_IMMEDIATELY (0x1) +#define SL_EXCLUSIVE_LOCK (0x2) + +#define SL_WATCH_TREE (0x1) #define SL_RESTART_SCAN (0x1) #define SL_RETURN_SINGLE_ENTRY (0x2) #define SL_INDEX_SPECIFIED (0x4) +#define SL_ALLOW_RAW_MOUNT (0x1) + #define SL_PENDING_RETURNED 0x01 #define SL_INVOKE_ON_CANCEL 0x20 #define SL_INVOKE_ON_SUCCESS 0x40 diff --git a/reactos/include/ddk/iofuncs.h b/reactos/include/ddk/iofuncs.h index 2f66cc99e69..aca389d9370 100644 --- a/reactos/include/ddk/iofuncs.h +++ b/reactos/include/ddk/iofuncs.h @@ -527,3 +527,5 @@ OUT PULONG ReturnedLength ); VOID IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject); PDEVICE_OBJECT IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject); +PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject, + PDEVICE_OBJECT DeviceObject); diff --git a/reactos/include/ddk/kefuncs.h b/reactos/include/ddk/kefuncs.h index 2d35f8092a0..bf89c8c75d5 100644 --- a/reactos/include/ddk/kefuncs.h +++ b/reactos/include/ddk/kefuncs.h @@ -3,23 +3,21 @@ /* 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); @@ -94,7 +92,9 @@ LONG KeSetBasePriorityThread(PKTHREAD Thread, LONG Increment); LONG KeSetEvent(PKEVENT Event, KPRIORITY Increment, BOOLEAN Wait); KPRIORITY KeSetPriorityThread(PKTHREAD Thread, KPRIORITY Priority); BOOLEAN KeSetTimer(PKTIMER Timer, LARGE_INTEGER DueTime, PKDPC Dpc); -BOOLEAN KeSetTimerEx(PKTIMER Timer, LARGE_INTEGER DueTime, LONG Period, +BOOLEAN KeSetTimerEx(PKTIMER Timer, + LARGE_INTEGER DueTime, + LONG Period, PKDPC Dpc); VOID KeStallExecutionProcessor(ULONG MicroSeconds); BOOLEAN KeSynchronizeExecution(PKINTERRUPT Interrupt, @@ -108,12 +108,16 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count, BOOLEAN Alertable, PLARGE_INTEGER Timeout, PKWAIT_BLOCK WaitBlockArray); -NTSTATUS KeWaitForMutexObject(PKMUTEX Mutex, KWAIT_REASON WaitReason, - KPROCESSOR_MODE WaitMode, BOOLEAN Alertable, +NTSTATUS KeWaitForMutexObject(PKMUTEX Mutex, + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode, + BOOLEAN Alertable, PLARGE_INTEGER Timeout); -NTSTATUS KeWaitForSingleObject(PVOID Object, KWAIT_REASON WaitReason, +NTSTATUS KeWaitForSingleObject(PVOID Object, + KWAIT_REASON WaitReason, KPROCESSOR_MODE WaitMode, - BOOLEAN Alertable, PLARGE_INTEGER Timeout); + BOOLEAN Alertable, + PLARGE_INTEGER Timeout); /* * FUNCTION: Initializes a spinlock @@ -155,17 +159,6 @@ VOID KeBugCheckEx(ULONG BugCheckCode, */ VOID KeBugCheck(ULONG BugCheckCode); -// kmutant definition slightly modified from nt5 ddk - -typedef struct _KMUTANT -{ - DISPATCHER_HEADER Header; - LIST_ENTRY MutantListEntry; - struct _KTHREAD* OwnerThread; - BOOLEAN Abandoned; - UCHAR ApcDisable; -} KMUTANT, *PKMUTANT; - // io permission map has a 8k size // Each bit in the IOPM corresponds to an io port byte address. The bitmap // is initialized to allow IO at any port. [ all bits set ]. @@ -186,7 +179,7 @@ typedef struct _IOPM * is initialized to allow IO at any port. [ all bits set ]. The IOPL determines * the minium privilege level required to perform IO prior to checking the permission map. */ -void Ke386SetIoAccessMap(int NewMap, PIOPM *IoPermissionMap); +VOID Ke386SetIoAccessMap(ULONG NewMap, PIOPM *IoPermissionMap); /* * FUNCTION: Queries the io permission map. @@ -199,7 +192,7 @@ void Ke386SetIoAccessMap(int NewMap, PIOPM *IoPermissionMap); * is initialized to allow IO at any port. [ all bits set ]. The IOPL determines * the minium privilege level required to perform IO prior to checking the permission map. */ -void Ke386QueryIoAccessMap(BOOLEAN NewMap, PIOPM *IoPermissionMap); +VOID Ke386QueryIoAccessMap(BOOLEAN NewMap, PIOPM *IoPermissionMap); /* * FUNCTION: Set the process IOPL @@ -215,10 +208,8 @@ NTSTATUS Ke386IoSetAccessProcess(PEPROCESS Eprocess, BOOLEAN EnableIo); * SelArray = * NumOfSelectors = */ -NTSTATUS KeI386ReleaseGdtSelectors( - OUT PULONG SelArray, - IN ULONG NumOfSelectors - ); +NTSTATUS KeI386ReleaseGdtSelectors(OUT PULONG SelArray, + IN ULONG NumOfSelectors); /* * FUNCTION: Allocates a set of Global Descriptor Table Selectors @@ -226,17 +217,15 @@ NTSTATUS KeI386ReleaseGdtSelectors( * SelArray = * NumOfSelectors = */ -NTSTATUS KeI386AllocateGdtSelectors( - OUT PULONG SelArray, - IN ULONG NumOfSelectors - ); +NTSTATUS KeI386AllocateGdtSelectors(OUT PULONG SelArray, + IN ULONG NumOfSelectors); /* * FUNCTION: Raises a user mode exception * ARGUMENTS: * ExceptionCode = Status code of the exception */ -void KeRaiseUserException(NTSTATUS ExceptionCode); +VOID KeRaiseUserException(NTSTATUS ExceptionCode); #endif /* __INCLUDE_DDK_KEFUNCS_H */ diff --git a/reactos/include/ddk/ketypes.h b/reactos/include/ddk/ketypes.h index a466ecbd252..2ef9d375216 100644 --- a/reactos/include/ddk/ketypes.h +++ b/reactos/include/ddk/ketypes.h @@ -38,16 +38,37 @@ typedef struct typedef struct _DISPATCHER_HEADER { - UCHAR Type; - UCHAR Absolute; - UCHAR Size; - UCHAR Inserted; - LONG SignalState; + UCHAR Type; + UCHAR Absolute; + UCHAR Size; + UCHAR Inserted; + LONG SignalState; LIST_ENTRY WaitListHead; } DISPATCHER_HEADER; + +typedef struct _KQUEUE +{ + DISPATCHER_HEADER Header; + LIST_ENTRY EntryListHead; + ULONG CurrentCount; + ULONG MaximumCount; + LIST_ENTRY ThreadListEntry; +} KQUEUE, *PKQUEUE; + struct _KDPC; +/* +typedef struct _KTIMER + { + DISPATCHER_HEADER Header; + ULARGE_INTEGER DueTime; + LIST_ENTRY TimerListEntry; + struct _KDPC* Dpc; + LONG Period; + } KTIMER, *PKTIMER; + */ + typedef struct _KTIMER { LIST_ENTRY entry; @@ -63,7 +84,7 @@ struct _KSPIN_LOCK; typedef struct _KSPIN_LOCK { - KIRQL irql; + ULONG Lock; } KSPIN_LOCK, *PKSPIN_LOCK; typedef struct _KDEVICE_QUEUE @@ -110,7 +131,7 @@ typedef struct struct _KTHREAD* OwnerThread; BOOLEAN Abandoned; UCHAR ApcDisable; -} KMUTEX, *PKMUTEX; +} KMUTEX, *PKMUTEX, KMUTANT, *PKMUTANT; typedef struct { diff --git a/reactos/include/ddk/ntifs.h b/reactos/include/ddk/ntifs.h index 737a09d6874..3892787c3c0 100644 --- a/reactos/include/ddk/ntifs.h +++ b/reactos/include/ddk/ntifs.h @@ -18,12 +18,35 @@ typedef struct _BCB KSPIN_LOCK BcbLock; } BCB, *PBCB; +#define CACHE_SEGMENT_SIZE (0x1000) + +struct _MEMORY_AREA; + +typedef struct _CACHE_SEGMENT +{ + PVOID BaseAddress; + struct _MEMORY_AREA* MemoryArea; + BOOLEAN Valid; + LIST_ENTRY ListEntry; + ULONG FileOffset; + KEVENT Lock; + ULONG ReferenceCount; + PBCB Bcb; +} CACHE_SEGMENT, *PCACHE_SEGMENT; + +NTSTATUS CcFlushCachePage(PCACHE_SEGMENT CacheSeg); +NTSTATUS CcReleaseCachePage(PBCB Bcb, + PCACHE_SEGMENT CacheSeg, + BOOLEAN Valid); NTSTATUS CcRequestCachePage(PBCB Bcb, ULONG FileOffset, PVOID* BaseAddress, - PBOOLEAN UptoDate); + PBOOLEAN UptoDate, + PCACHE_SEGMENT* CacheSeg); NTSTATUS CcInitializeFileCache(PFILE_OBJECT FileObject, PBCB* Bcb); +NTSTATUS CcReleaseFileCache(PFILE_OBJECT FileObject, + PBCB Bcb); #include diff --git a/reactos/include/ddk/pstypes.h b/reactos/include/ddk/pstypes.h index 93164312c9c..92742bf233d 100644 --- a/reactos/include/ddk/pstypes.h +++ b/reactos/include/ddk/pstypes.h @@ -52,9 +52,9 @@ typedef struct _STARTUPINFOW { WCHAR ImageFile[MAX_PATH]; WCHAR CommandLine[MAX_PATH]; WCHAR DllPath[MAX_PATH]; - LPWSTR Reserved[MAX_PATH]; - LPWSTR Desktop[MAX_PATH]; - LPWSTR Title[MAX_PATH]; + WCHAR Reserved[MAX_PATH]; + WCHAR Desktop[MAX_PATH]; + WCHAR Title[MAX_PATH]; DWORD dwX; DWORD dwY; DWORD dwXSize; @@ -83,24 +83,24 @@ typedef struct _LDR { typedef struct _NT_PEB { - UCHAR InheritedAddressSpace; - UCHAR ReadImageFileExecOptions; - UCHAR BeingDebugged; - LONG ImageBaseAddress; - LDR Ldr; - - 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 @@ -110,67 +110,116 @@ typedef struct _CLIENT_ID } CLIENT_ID, *PCLIENT_ID; typedef struct _NT_TIB { - struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; - PVOID StackBase; - PVOID StackLimit; - PVOID SubSystemTib; + struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // 00h + PVOID StackBase; // 04h + PVOID StackLimit; // 08h + PVOID SubSystemTib; // 0Ch union { - PVOID FiberData; - ULONG Version; + PVOID FiberData; // 10h + ULONG Version; // 10h } Fib; - PVOID ArbitraryUserPointer; - struct _NT_TIB *Self; + PVOID ArbitraryUserPointer; // 14h + struct _NT_TIB *Self; // 18h } NT_TIB, *PNT_TIB; typedef struct _NT_TEB { - NT_TIB Tib; - CLIENT_ID Cid; - HANDLE RPCHandle; - PVOID TlsData[TLS_MINIMUM_AVAILABLE]; - DWORD dwTlsIndex; - NT_PEB *Peb; - DWORD LastErrorCode; - NTSTATUS LastStatusValue; - DWORD LockCount; - UCHAR HardErrorMode; + NT_TIB Tib; // 0 + CLIENT_ID Cid; // 28 + HANDLE RPCHandle; // 36 + PVOID TlsData[TLS_MINIMUM_AVAILABLE]; // 40 + DWORD dwTlsIndex; // 230 + NT_PEB *Peb; // 234 + DWORD LastErrorCode; // 238 + NTSTATUS LastStatusValue; // 242 + DWORD LockCount; // 244 + UCHAR HardErrorMode; // 248 } NT_TEB; -typedef struct _KTHREAD +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. @@ -243,7 +292,7 @@ typedef struct _ETHREAD { typedef struct _KPROCESS { DISPATCHER_HEADER DispatcherHeader; - PVOID PageTableDirectory; // FIXME: I shoud point to a PTD + PVOID PageTableDirectory; // FIXME: I should point to a PTD TIME ElapsedTime; TIME KernelTime; TIME UserTime; @@ -268,9 +317,64 @@ typedef struct _KPROCESS typedef struct _EPROCESS { KPROCESS Pcb; - - ULONG UniqueProcessId; - ULONG InheritedFromUniqueProcessId; + NTSTATUS ExitStatus; + KEVENT LockEvent; + ULONG LockCount; + TIME CreateTime; + TIME ExitTime; + PVOID LockOwner; + ULONG UniqueProcessId; + LIST_ENTRY ActiveProcessLinks; + ULONG QuotaPeakPoolUsage[2]; + ULONG QuotaPoolUsage[2]; + ULONG PagefileUsage; + ULONG CommitCharge; + ULONG PeakPagefileUsage; + ULONG PeakVirtualUsage; + LARGE_INTEGER VirtualSize; + PVOID Vm; // Actually 48 bytes + PVOID LastProtoPteFault; + PVOID DebugPort; + PVOID ExceptionPort; + PVOID ObjectTable; + PVOID Token; + KMUTEX WorkingSetLock; + PVOID WorkingSetPage; + UCHAR ProcessOutswapEnabled; + UCHAR ProcessOutswapped; + UCHAR AddressSpaceInitialized; + UCHAR AddressSpaceDeleted; + KMUTEX AddressCreationLock; + PVOID ForkInProgress; + PVOID VmOperation; + PKEVENT VmOperationEvent; + PVOID PageDirectoryPte; + LARGE_INTEGER LastFaultCount; + PVOID VadRoot; + PVOID VadHint; + PVOID CloneRoot; + ULONG NumberOfPrivatePages; + ULONG NumberOfLockedPages; + UCHAR ForkWasSuccessFul; + UCHAR ExitProcessCalled; + UCHAR CreateProcessReported; + HANDLE SectionHandle; + PNT_PEB Peb; + PVOID SectionBaseAddress; + PVOID QuotaBlock; + NTSTATUS LastThreadExitStatus; + LARGE_INTEGER WorkingSetWatch; // + ULONG InheritedFromUniqueProcessId; + ACCESS_MASK GrantedAccess; + ULONG DefaultHardErrorProcessing; + PVOID LdtInformation; + ULONG VadFreeHint; + PVOID VdmObjects; + KMUTANT ProcessMutant; + CHAR ImageFileName[16]; + LARGE_INTEGER VmTrimFaultValue; + PVOID Win32Process; // Actually 12 bytes + PVOID Win32WindowStation; } EPROCESS, *PEPROCESS; #define PROCESS_STATE_TERMINATED (1) diff --git a/reactos/include/ddk/status.h b/reactos/include/ddk/status.h index 6361cdebf5a..ce97f10f9eb 100644 --- a/reactos/include/ddk/status.h +++ b/reactos/include/ddk/status.h @@ -16,20 +16,44 @@ * 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, @@ -69,15 +93,6 @@ enum STATUS_WX86_CREATEWX86TIB, - STATUS_GUARD_PAGE_VIOLATION=0x80000001, - STATUS_DATATYPE_MISALIGNMENT, - STATUS_BREAKPOINT, - STATUS_SINGLE_STEP, - STATUS_BUFFER_OVERFLOW, - STATUS_NO_MORE_FILES, - STATUS_WAKE_SYSTEM_DEBUGGER, - - STATUS_HANDLES_CLOSED=0x8000000A, STATUS_NO_INHERITANCE, STATUS_GUID_SUBSTITUTION_MADE, @@ -108,21 +123,6 @@ enum STATUS_ALREADY_DISCONNECTED, STATUS_LONGJUMP, - STATUS_UNSUCCESSFUL=0xC0000001, - STATUS_NOT_IMPLEMENTED, - STATUS_INVALID_INFO_CLASS, - STATUS_INFO_LENGTH_MISMATCH, - STATUS_ACCESS_VIOLATION, - STATUS_IN_PAGE_ERROR, - STATUS_PAGEFILE_QUOTA, - STATUS_INVALID_HANDLE, - STATUS_BAD_INITIAL_STACK, - STATUS_BAD_INITIAL_PC, - STATUS_INVALID_CID, - STATUS_TIMER_NOT_CANCELED, - STATUS_INVALID_PARAMETER, - STATUS_NO_SUCH_DEVICE, - STATUS_NO_SUCH_FILE, // c0000010 STATUS_INVALID_DEVICE_REQUEST, diff --git a/reactos/include/internal/debug.h b/reactos/include/internal/debug.h index 28869d2c526..beb983c9b2a 100644 --- a/reactos/include/internal/debug.h +++ b/reactos/include/internal/debug.h @@ -30,8 +30,8 @@ #define CHECKED #endif -#ifdef CHECKED -#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); for (;;); } +#ifndef NASSERT +#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); } #else #define assert(x) #endif diff --git a/reactos/include/internal/mm.h b/reactos/include/internal/mm.h index 3981e339b65..89befc8f862 100644 --- a/reactos/include/internal/mm.h +++ b/reactos/include/internal/mm.h @@ -96,6 +96,10 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest); NTSTATUS MmReleaseMmInfo(PEPROCESS Process); NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process); VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address, BOOL FreePage); +NTSTATUS IoPageRead(PFILE_OBJECT FileObject, + PVOID Address, + PLARGE_INTEGER Offset, + PIO_STATUS_BLOCK StatusBlock); #endif diff --git a/reactos/include/internal/ps.h b/reactos/include/internal/ps.h index 659fbba3e45..c81b1b25d96 100644 --- a/reactos/include/internal/ps.h +++ b/reactos/include/internal/ps.h @@ -19,37 +19,13 @@ VOID PsReleaseThread(PETHREAD Thread); VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext); VOID PsBeginThreadWithContextInternal(VOID); -/* - * PURPOSE: Thread states - */ -enum -{ - /* - * PURPOSE: Don't touch - */ - THREAD_STATE_INVALID, - - /* - * 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 */ diff --git a/reactos/include/kernel32/kernel32.h b/reactos/include/kernel32/kernel32.h index 2bcf0201789..dd1ffd0c946 100644 --- a/reactos/include/kernel32/kernel32.h +++ b/reactos/include/kernel32/kernel32.h @@ -1,5 +1,7 @@ #include +#define UNIMPLEMENTED dprintf("%s at %s:%d is unimplemented\n",__FUNCTION__,__FILE__,__LINE__); + #ifdef NDEBUG #define DPRINT(args...) #define CHECKPOINT @@ -28,3 +30,4 @@ PVOID __ErrorReturnNull(ULONG ErrorCode); BOOL KERNEL32_AnsiToUnicode(PWSTR DestStr, LPCSTR SrcStr, ULONG MaxLen); +PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength); diff --git a/reactos/include/ntdll/base.h b/reactos/include/ntdll/base.h new file mode 100644 index 00000000000..8d45888be34 --- /dev/null +++ b/reactos/include/ntdll/base.h @@ -0,0 +1 @@ +#define NTDLL_BASE (0x77f60000) diff --git a/reactos/include/ntdll/ntdll.h b/reactos/include/ntdll/ntdll.h index 9369ef89e25..3d0dde7958d 100644 --- a/reactos/include/ntdll/ntdll.h +++ b/reactos/include/ntdll/ntdll.h @@ -14,3 +14,4 @@ extern void dprintf(char* fmt,...); #define MAGIC(c1,c2,c3,c4) ((c1) + ((c2)<<8) + ((c3)<<16) + ((c4)<<24)) #define MAGIC_HEAP MAGIC( 'H','E','A','P' ) + diff --git a/reactos/lib/crtdll/makefile b/reactos/lib/crtdll/makefile index 61485687f97..c764706263a 100644 --- a/reactos/lib/crtdll/makefile +++ b/reactos/lib/crtdll/makefile @@ -158,7 +158,7 @@ CLEAN_FILES = assert/*.o conio/*.o ctype/*.o direct/*.o dirent/*.o \ endif crtdll.coff: crtdll.rc ../../include/reactos/resource.h - windres crtdll.rc crtdll.coff + $(RC) crtdll.rc crtdll.coff crtdll.a: $(OBJECTS) $(LD) -r $(OBJECTS) -o crtdll.a diff --git a/reactos/lib/kernel32/except/except.c b/reactos/lib/kernel32/except/except.c index 10d98c21389..378d9e619cc 100644 --- a/reactos/lib/kernel32/except/except.c +++ b/reactos/lib/kernel32/except/except.c @@ -65,12 +65,10 @@ LONG STDCALL UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo) { - char message[80]; DWORD dbgRet; HANDLE DebugPort; NTSTATUS errCode; - DWORD DebuggerPresent; if(ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) { diff --git a/reactos/lib/kernel32/file/copy.c b/reactos/lib/kernel32/file/copy.c index 501fe9f044d..343960cea18 100644 --- a/reactos/lib/kernel32/file/copy.c +++ b/reactos/lib/kernel32/file/copy.c @@ -187,7 +187,6 @@ WINBOOL STDCALL CopyFileExA(LPCSTR lpExistingFileName, WINBOOL* pbCancel, DWORD dwCopyFlags) { - ULONG i; WCHAR ExistingFileNameW[MAX_PATH]; WCHAR NewFileNameW[MAX_PATH]; diff --git a/reactos/lib/kernel32/file/curdir.c b/reactos/lib/kernel32/file/curdir.c index f3e694d57d5..a15648374ba 100644 --- a/reactos/lib/kernel32/file/curdir.c +++ b/reactos/lib/kernel32/file/curdir.c @@ -11,8 +11,9 @@ /* INCLUDES ******************************************************************/ #include -#include +#include #include +#include #define NDEBUG #include diff --git a/reactos/lib/kernel32/file/dir.c b/reactos/lib/kernel32/file/dir.c index 6566eb06941..67295ef8e18 100644 --- a/reactos/lib/kernel32/file/dir.c +++ b/reactos/lib/kernel32/file/dir.c @@ -501,6 +501,13 @@ DWORD STDCALL GetFullPathNameW(LPCWSTR lpFileName, return wcslen(lpBuffer); } + + + + + + + DWORD STDCALL GetShortPathNameA( @@ -683,25 +690,106 @@ DWORD STDCALL SearchPathW(LPCWSTR lpPath, HeapFree(GetProcessHeap(),0,EnvironmentBufferW); - return retCode; +// WCHAR BufferW[MAX_PATH]; +// WCHAR FileAndExtensionW[MAX_PATH]; +// WCHAR *EnvironmentBufferW = NULL; + +// UNICODE_STRING PathString; +// OBJECT_ATTRIBUTES ObjectAttributes; +// IO_STATUS_BLOCK IoStatusBlock; + DPRINT("SearchPath\n"); + + + if (lpPath == NULL) + { + // check the directory from which the application loaded + + if (GetCurrentDirectoryW(MAX_PATH, BufferW) > 0) + { + retCode = SearchPathW(BufferW,lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart ); + if ( retCode != 0 ) + return retCode; + } + if ( GetSystemDirectoryW(BufferW, MAX_PATH) > 0 ) + { + retCode = SearchPathW(BufferW,lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart ); + if ( retCode != 0 ) + return retCode; + } + + if ( GetWindowsDirectoryW(BufferW, MAX_PATH) > 0 ) + { + retCode = SearchPathW(BufferW,lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart ); + if ( retCode != 0 ) + return retCode; + } + + j = GetEnvironmentVariableW(L"Path",EnvironmentBufferW,0); + EnvironmentBufferW = (WCHAR *) HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,(j+1)*sizeof(WCHAR)); + + j = GetEnvironmentVariableW(L"Path",EnvironmentBufferW,j+1); + + for(i=0;iOffset; Offset.u.HighPart = lpOverLapped->OffsetHigh; lpOverLapped->Internal = STATUS_PENDING; - hEvent= lpOverLapped->hEvent; - IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped; + hEvent = lpOverLapped->hEvent; + IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped; + ptrOffset = &Offset; } - else + else { + ptrOffset = NULL; IoStatusBlock = &IIosb; Offset.QuadPart = 0; } + errCode = NtWriteFile(hFile, hEvent, NULL, @@ -55,7 +58,7 @@ WINBOOL STDCALL WriteFile(HANDLE hFile, IoStatusBlock, (PVOID)lpBuffer, nNumberOfBytesToWrite, - &Offset, + ptrOffset, NULL); if (!NT_SUCCESS(errCode)) { diff --git a/reactos/lib/kernel32/file/volume.c b/reactos/lib/kernel32/file/volume.c index 90cb49b28cf..479f5988754 100644 --- a/reactos/lib/kernel32/file/volume.c +++ b/reactos/lib/kernel32/file/volume.c @@ -63,15 +63,15 @@ GetLogicalDriveStringsA( { LPSTR p = lpBuffer; for (drive = 0; drive < MAX_DOS_DRIVES; drive++) - if (DRIVE_IsValid(drive)) - { - *p++ = 'A' + drive; - *p++ = ':'; - *p++ = '\\'; - *p++ = '\0'; - } + if (DRIVE_IsValid(drive)) + { + *p++ = 'A' + drive; + *p++ = ':'; + *p++ = '\\'; + *p++ = '\0'; + } *p = '\0'; - } + } return count * 4 * sizeof(char); } diff --git a/reactos/lib/kernel32/makefile b/reactos/lib/kernel32/makefile index 4013cb11bb2..ff97924a690 100644 --- a/reactos/lib/kernel32/makefile +++ b/reactos/lib/kernel32/makefile @@ -1,4 +1,8 @@ +KERNEL32_BASE = 0x77f00000 + +CFLAGS = $(CFLAGS) -DKERNEL32_BASE=$(KERNEL32_BASE) + ifneq ($(HOST),mingw32-windows) ifneq ($(HOST),mingw32-linux) DLLTARGET=kernel32.a @@ -44,7 +48,7 @@ NLS_OBJECTS = nls/codepage.o nls/cpmisc.o nls/cptable.o\ nls/lcSLV.o nls/lcSQI.o nls/lcSRB.o nls/lcSRL.o nls/lcSVE.o nls/lcSVF.o nls/lcTRK.o nls/lcUKR.o\ nls/locale.o nls/mbtowc.o nls/wctomb.o nls/ole2nls.o -THREAD_OBJECTS = thread/thread.o +THREAD_OBJECTS = thread/thread.o thread/tls.o PROCESS_OBJECTS = process/proc.o process/cmdline.o process/create.o \ process/lib.o @@ -77,7 +81,7 @@ nls/ole2nls.o: nls/ole2nls.c $(CC) $(CFLAGS) -I. nls/ole2nls.c kernel32.coff: kernel32.rc ../../include/reactos/resource.h - windres kernel32.rc kernel32.coff + $(RC) kernel32.rc kernel32.coff kernel32.a: $(OBJECTS) $(AR) csr kernel32.a $(OBJECTS) @@ -93,7 +97,7 @@ kernel32.dll: $(DLLMAIN) $(OBJECTS) kernel32.def --output-exp temp.exp --def kernel32.def - $(RM) base.tmp $(CC) -specs=k32_specs -mdll -o kernel32.dll kernel32.o ../ntdll/ntdll.a\ - -Wl,--image-base,0x70000000 \ + -Wl,--image-base,$(KERNEL32_BASE) \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ -Wl,temp.exp @@ -107,4 +111,5 @@ $(CLEAN_FILES:%=%_clean): %_clean: .PHONY: clean $(CLEAN_FILES:%=%_clean) +#WARNINGS_ARE_ERRORS = yes include ../../rules.mak diff --git a/reactos/lib/kernel32/mem/heap.c b/reactos/lib/kernel32/mem/heap.c index 300bd69b9f4..c0e36a6161a 100644 --- a/reactos/lib/kernel32/mem/heap.c +++ b/reactos/lib/kernel32/mem/heap.c @@ -91,6 +91,8 @@ HANDLE WINAPI GetProcessHeap(VOID) ********************************************************************/ DWORD WINAPI GetProcessHeaps(DWORD maxheaps, PHANDLE phandles ) { + UNIMPLEMENTED; + return(ERROR_CALL_NOT_IMPLEMENTED); } /********************************************************************* @@ -125,7 +127,7 @@ UINT HeapCompact(HANDLE hheap, DWORD flags) *********************************************************************/ DWORD WINAPI HeapSize(HANDLE hheap, DWORD flags, LPCVOID pmem) { - return(RtlSizeHeap(hheap, flags, pmem)); + return(RtlSizeHeap(hheap, flags, (PVOID)pmem)); } /********************************************************************* @@ -135,6 +137,6 @@ DWORD WINAPI HeapSize(HANDLE hheap, DWORD flags, LPCVOID pmem) *********************************************************************/ BOOL WINAPI HeapValidate(HANDLE hheap, DWORD flags, LPCVOID pmem) { - return(RtlValidateHeap(hheap, flags, pmem)); + return(RtlValidateHeap(hheap, flags, (PVOID)pmem)); } diff --git a/reactos/lib/kernel32/mem/virtual.c b/reactos/lib/kernel32/mem/virtual.c index 205a9189de4..c90d8b67cf1 100644 --- a/reactos/lib/kernel32/mem/virtual.c +++ b/reactos/lib/kernel32/mem/virtual.c @@ -91,9 +91,9 @@ WINBOOL STDCALL VirtualProtectEx(HANDLE hProcess, Status = ZwProtectVirtualMemory(hProcess, (PVOID)lpAddress, - (PULONG)dwSize, + dwSize, flNewProtect, - lpflOldProtect); + (PULONG)lpflOldProtect); if (Status != STATUS_SUCCESS) { SetLastError(RtlNtStatusToDosError(Status)); diff --git a/reactos/lib/kernel32/misc/console.c b/reactos/lib/kernel32/misc/console.c index 682730767c4..4248dde44c9 100644 --- a/reactos/lib/kernel32/misc/console.c +++ b/reactos/lib/kernel32/misc/console.c @@ -1135,7 +1135,7 @@ GetConsoleTitleA( { wchar_t WideTitle [MAX_CONSOLE_TITLE_LENGTH]; DWORD nWideTitle = sizeof WideTitle; - DWORD nWritten; +// DWORD nWritten; if (!lpConsoleTitle || !nSize) return 0; nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle ); diff --git a/reactos/lib/kernel32/misc/env.c b/reactos/lib/kernel32/misc/env.c index 17c2268a32c..00eac4f3751 100644 --- a/reactos/lib/kernel32/misc/env.c +++ b/reactos/lib/kernel32/misc/env.c @@ -32,22 +32,23 @@ DWORD STDCALL GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize) { - WCHAR BufferW[MAX_VALUE]; - WCHAR NameW[MAX_PATH]; - DWORD RetValue; - int i=0; - while ((*lpName)!=0 && i < MAX_PATH) - { - NameW[i] = *lpName; - lpName++; - i++; - } - NameW[i] = 0; - - RetValue = GetEnvironmentVariableW(NameW,BufferW,nSize); - for(i=0;i #include #include +#include +#include #define NDEBUG #include +/* TYPES *********************************************************************/ typedef struct __DOSTIME { @@ -65,6 +71,19 @@ static __inline void NormalizeTimeFields(WORD *FieldToNormalize, *CarryField = (WORD) (*CarryField + 1); } +#define LISECOND RtlEnlargedUnsignedMultiply(SECOND,NSPERSEC) +#define LIMINUTE RtlEnlargedUnsignedMultiply(MINUTE,NSPERSEC) +#define LIHOUR RtlEnlargedUnsignedMultiply(HOUR,NSPERSEC) +#define LIDAY RtlEnlargedUnsignedMultiply(DAY,NSPERSEC) +#define LIYEAR RtlEnlargedUnsignedMultiply(YEAR,NSPERSEC) +#define LIFOURYEAR RtlEnlargedUnsignedMultiply(FOURYEAR,NSPERSEC) +#define LICENTURY RtlEnlargedUnsignedMultiply(CENTURY,NSPERSEC) +#define LIMILLENIUM RtlEnlargedUnsignedMultiply(CENTURY,10*NSPERSEC) + + + + +/* FUNCTIONS ****************************************************************/ WINBOOL STDCALL @@ -230,7 +249,10 @@ SystemTimeToFileTime( return TRUE; } +// dwDayOfWeek = RtlLargeIntegerDivide(FileTime,LIDAY,&dwRemDay); +// lpSystemTime->wDayOfWeek = 1 + GET_LARGE_INTEGER_LOW_PART(dwDayOfWeek) % 7; + WINBOOL STDCALL diff --git a/reactos/lib/kernel32/process/create.c b/reactos/lib/kernel32/process/create.c index d648969d0ea..f8cb6b12c9b 100644 --- a/reactos/lib/kernel32/process/create.c +++ b/reactos/lib/kernel32/process/create.c @@ -20,6 +20,7 @@ #include #include #include +#include //#define NDEBUG #include @@ -107,8 +108,7 @@ HANDLE STDCALL CreateFirstThread(HANDLE ProcessHandle, PVOID BaseAddress; ULONG BytesWritten; HANDLE DupNTDllSectionHandle, DupSectionHandle; - - + ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); ObjectAttributes.RootDirectory = NULL; ObjectAttributes.ObjectName = NULL; @@ -340,8 +340,6 @@ HANDLE KERNEL32_MapFile(LPCWSTR lpApplicationName, return(hSection); } -#define NTDLL_BASE (0x80000000) - static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine) { NTSTATUS Status; @@ -353,7 +351,7 @@ static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine) ULONG StartupInfoSize; PROCESSINFOW StartupInfo; - PebBase = PEB_BASE; + PebBase = (PVOID)PEB_BASE; PebSize = 0x1000; Status = ZwAllocateVirtualMemory(ProcessHandle, &PebBase, @@ -368,7 +366,7 @@ static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine) memset(&Peb, 0, sizeof(Peb)); - Peb.StartupInfo = PEB_STARTUPINFO; + Peb.StartupInfo = (PPROCESSINFOW)PEB_STARTUPINFO; ZwWriteVirtualMemory(ProcessHandle, (PVOID)PEB_BASE, @@ -376,7 +374,7 @@ static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine) sizeof(Peb), &BytesWritten); - StartupInfoBase = PEB_STARTUPINFO; + StartupInfoBase = (PVOID)PEB_STARTUPINFO; StartupInfoSize = 0x1000; Status = ZwAllocateVirtualMemory(ProcessHandle, &StartupInfoBase, @@ -440,7 +438,8 @@ WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName, hSection = KERNEL32_MapFile(lpApplicationName, lpCommandLine, - &Headers, &DosHeader); + &Headers, + &DosHeader); Status = NtCreateProcess(&hProcess, PROCESS_ALL_ACCESS, diff --git a/reactos/lib/kernel32/process/lib.c b/reactos/lib/kernel32/process/lib.c index a9eec9b6ba0..fb9cf056545 100644 --- a/reactos/lib/kernel32/process/lib.c +++ b/reactos/lib/kernel32/process/lib.c @@ -25,15 +25,18 @@ HINSTANCE LoadLibraryW(LPCWSTR lpLibFileName) { - dprintf("LoadLibraryW is unimplemented\n"); + UNIMPLEMENTED; + return(NULL); } HINSTANCE LoadLibraryA(LPCSTR lpLibFileName) { - dprintf("LoadLibraryA is unimplemented\n"); + UNIMPLEMENTED; + return(NULL); } BOOL STDCALL FreeLibrary(HMODULE hLibModule) { - dprintf("FreeLibrary is unimplemented\n"); + UNIMPLEMENTED; + return(FALSE); } diff --git a/reactos/lib/kernel32/process/proc.c b/reactos/lib/kernel32/process/proc.c index 07d3c59dcc0..385401ed9dc 100644 --- a/reactos/lib/kernel32/process/proc.c +++ b/reactos/lib/kernel32/process/proc.c @@ -22,7 +22,30 @@ #define NDEBUG #include -/* GLOBALS *****************************************************************/ +/* TYPES *********************************************************************/ + +typedef struct _WSTARTUPINFO { + DWORD cb; + LPWSTR lpReserved; + LPWSTR lpDesktop; + LPWSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + LPBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; +} WSTARTUPINFO, *LPWSTARTUPINFO; + +/* GLOBALS *******************************************************************/ WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle; @@ -34,7 +57,8 @@ WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId); FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName) { - dprintf("GetProcAddress is unimplemented\n"); + UNIMPLEMENTED; + return(NULL); } WINBOOL STDCALL GetProcessTimes(HANDLE hProcess, @@ -62,7 +86,7 @@ DWORD STDCALL GetCurrentProcessId(VOID) return (DWORD)(GetTeb()->Cid).UniqueProcess; } -WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode ) +WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) { NTSTATUS errCode; PROCESS_BASIC_INFORMATION ProcessBasic; @@ -78,7 +102,7 @@ WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode ) SetLastError(RtlNtStatusToDosError(errCode)); return FALSE; } - memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD)); + memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD)); return TRUE; } @@ -156,25 +180,13 @@ HANDLE STDCALL OpenProcess(DWORD dwDesiredAccess, return ProcessHandle; } - - - - - - - - - - - - -UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow) +UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow) { STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInformation; HINSTANCE hInst; DWORD dosErr; - + StartupInfo.cb = sizeof(STARTUPINFO); StartupInfo.wShowWindow = uCmdShow ; StartupInfo.dwFlags = 0; @@ -203,10 +215,11 @@ UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow) -VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle) +VOID RegisterWaitForInputIdle(WaitForInputIdleType + lpfnRegisterWaitForInputIdle) { - lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle; - return; + lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle; + return; } DWORD STDCALL WaitForInputIdle(HANDLE hProcess, @@ -215,22 +228,13 @@ DWORD STDCALL WaitForInputIdle(HANDLE hProcess, return 0; } -VOID -STDCALL -Sleep( - DWORD dwMilliseconds - ) +VOID STDCALL Sleep(DWORD dwMilliseconds) { - SleepEx(dwMilliseconds,FALSE); - return; + SleepEx(dwMilliseconds,FALSE); + return; } -DWORD -STDCALL -SleepEx( - DWORD dwMilliseconds, - BOOL bAlertable - ) +DWORD STDCALL SleepEx(DWORD dwMilliseconds, BOOL bAlertable) { TIME Interval; NTSTATUS errCode; @@ -245,13 +249,10 @@ SleepEx( return 0; } - - - - -VOID STDCALL GetStartupInfoW(LPSTARTUPINFO lpStartupInfo) +VOID STDCALL GetStartupInfoW(LPSTARTUPINFO _lpStartupInfo) { NT_PEB *pPeb = NtCurrentPeb(); + LPWSTARTUPINFO lpStartupInfo = (LPWSTARTUPINFO)_lpStartupInfo; if (lpStartupInfo == NULL) { @@ -259,6 +260,22 @@ VOID STDCALL GetStartupInfoW(LPSTARTUPINFO lpStartupInfo) return; } + lpStartupInfo->cb = sizeof(STARTUPINFO); +// lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop); +// lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title); + lpStartupInfo->dwX = pPeb->StartupInfo->dwX; + lpStartupInfo->dwY = pPeb->StartupInfo->dwY; + lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize; + lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize; + lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars; + lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars; + lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute; + lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags; + lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow; + //lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved; + //lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1; + //lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2; + lpStartupInfo->cb = sizeof(STARTUPINFO); lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop); lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title); @@ -301,7 +318,8 @@ VOID STDCALL GetStartupInfoA(LPSTARTUPINFO lpStartupInfo) while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH) { - lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i]; + lpStartupInfo->lpDesktop[i] = (unsigned char) + pPeb->StartupInfo->Desktop[i]; i++; } lpStartupInfo->lpDesktop[i] = 0; diff --git a/reactos/lib/kernel32/synch/critical.c b/reactos/lib/kernel32/synch/critical.c index 63e655b163e..7b982f80bc1 100644 --- a/reactos/lib/kernel32/synch/critical.c +++ b/reactos/lib/kernel32/synch/critical.c @@ -11,31 +11,33 @@ #include +#include + /* 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); } diff --git a/reactos/lib/kernel32/thread/thread.c b/reactos/lib/kernel32/thread/thread.c index bb8d88a8eb9..b131df281de 100644 --- a/reactos/lib/kernel32/thread/thread.c +++ b/reactos/lib/kernel32/thread/thread.c @@ -4,46 +4,44 @@ * FILE: lib/kernel32/thread/thread.c * PURPOSE: Thread functions * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) - Tls functions are modified from WINE + * Tls functions are modified from WINE * UPDATE HISTORY: * Created 01/11/98 */ +/* INCLUDES ******************************************************************/ + #include #include #include #include #include -HANDLE -STDCALL -CreateThread( - LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter, - DWORD dwCreationFlags, - LPDWORD lpThreadId - ) +/* FUNCTIONS *****************************************************************/ + +HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId) { - return CreateRemoteThread(NtCurrentProcess(),lpThreadAttributes,dwStackSize, - lpStartAddress,lpParameter,dwCreationFlags,lpThreadId); + return(CreateRemoteThread(NtCurrentProcess(), + lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + lpThreadId)); } - - - -HANDLE -STDCALL -CreateRemoteThread( - HANDLE hProcess, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter, - DWORD dwCreationFlags, - LPDWORD lpThreadId - ) +HANDLE STDCALL CreateRemoteThread(HANDLE hProcess, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId) { NTSTATUS errCode; HANDLE ThreadHandle; @@ -52,42 +50,44 @@ CreateRemoteThread( CONTEXT ThreadContext; INITIAL_TEB InitialTeb; BOOLEAN CreateSuspended = FALSE; - ULONG BaseAddress; + PVOID BaseAddress; ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); ObjectAttributes.RootDirectory = NULL; ObjectAttributes.ObjectName = NULL; ObjectAttributes.Attributes = 0; - if ( lpThreadAttributes != NULL ) { - if ( lpThreadAttributes->bInheritHandle ) - ObjectAttributes.Attributes = OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor; - } + if (lpThreadAttributes != NULL) + { + if (lpThreadAttributes->bInheritHandle) + ObjectAttributes.Attributes = OBJ_INHERIT; + ObjectAttributes.SecurityDescriptor = + lpThreadAttributes->lpSecurityDescriptor; + } ObjectAttributes.SecurityQualityOfService = NULL; - if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED ) - CreateSuspended = TRUE; + if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED) + CreateSuspended = TRUE; else CreateSuspended = FALSE; - + BaseAddress = 0; ZwAllocateVirtualMemory(hProcess, &BaseAddress, 0, - &dwStackSize, + (PULONG)&dwStackSize, MEM_COMMIT, PAGE_READWRITE); memset(&ThreadContext,0,sizeof(CONTEXT)); - ThreadContext.Eip = lpStartAddress; + ThreadContext.Eip = (LONG)lpStartAddress; ThreadContext.SegGs = USER_DS; ThreadContext.SegFs = USER_DS; ThreadContext.SegEs = USER_DS; ThreadContext.SegDs = USER_DS; ThreadContext.SegCs = USER_CS; ThreadContext.SegSs = USER_DS; - ThreadContext.Esp = BaseAddress + dwStackSize; + ThreadContext.Esp = (ULONG)(BaseAddress + dwStackSize); ThreadContext.EFlags = (1<<1) + (1<<9); @@ -110,263 +110,190 @@ NT_TEB *GetTeb(VOID) return NULL; } -WINBOOL STDCALL SwitchToThread(VOID ) +WINBOOL STDCALL SwitchToThread(VOID) { - NTSTATUS errCode; - errCode = NtYieldExecution(); - return TRUE; + NTSTATUS errCode; + errCode = NtYieldExecution(); + return TRUE; } DWORD STDCALL GetCurrentThreadId() { - - return (DWORD)(GetTeb()->Cid).UniqueThread; + return((DWORD)(GetTeb()->Cid).UniqueThread); } VOID STDCALL ExitThread(UINT uExitCode) { - NTSTATUS errCode; - - 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; } - -/*************************************************************/ diff --git a/reactos/lib/kernel32/thread/tls.c b/reactos/lib/kernel32/thread/tls.c new file mode 100644 index 00000000000..677028cd6a6 --- /dev/null +++ b/reactos/lib/kernel32/thread/tls.c @@ -0,0 +1,62 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/thread/tls.c + * PURPOSE: Thread functions + * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) + * Tls functions are modified from WINE + * UPDATE HISTORY: + * Created 01/11/98 + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +#include +#include + +/* 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); +} diff --git a/reactos/lib/ntdll/makefile b/reactos/lib/ntdll/makefile index 066765b9826..6df015fc31e 100644 --- a/reactos/lib/ntdll/makefile +++ b/reactos/lib/ntdll/makefile @@ -1,4 +1,6 @@ +IMAGE_BASE = 0x77f60000 + ifneq ($(HOST),mingw32-windows) ifneq ($(HOST),mingw32-linux) DLLTARGET=ntdll.a @@ -39,7 +41,7 @@ CLEAN_FILES = napi.o ldr/*.o rtl/*.o stdio/*.o stdlib/*.o string/*.o stubs/*.o \ endif ntdll.coff: ntdll.rc ../../include/reactos/resource.h - windres ntdll.rc ntdll.coff + $(RC) ntdll.rc ntdll.coff ntdll.a: $(OBJECTS) $(AR) csr ntdll.a $(OBJECTS) @@ -58,7 +60,7 @@ ntdll.dll: $(DLLMAIN) $(OBJECTS) def/ntdll.def - $(RM) base.tmp $(CC) -specs=ntdll_specs -mdll -o ntdll.dll ntdll.o \ -Wl,--entry=_LdrStartup \ - -Wl,--image-base,0x80000000 \ + -Wl,--image-base,$(IMAGE_BASE) \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ -Wl,temp.exp diff --git a/reactos/makefile_rex b/reactos/makefile_rex index 70ac1cdff90..f2d411cce57 100644 --- a/reactos/makefile_rex +++ b/reactos/makefile_rex @@ -35,7 +35,7 @@ LOADERS = dos # DEVICE_DRIVERS = blue ide keyboard mouse null parallel serial # DEVICE_DRIVERS = beep event floppy ide_test sound test test1 -FS_DRIVERS = minix vfat ext2 +FS_DRIVERS = vfat ext2 # FS_DRIVERS = template KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS) diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index 666d339d934..db78d51e61f 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -14,36 +14,55 @@ #include #include -//#define NDEBUG +#define NDEBUG #include -/* 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); @@ -53,42 +72,96 @@ NTSTATUS CcRequestCachePage(PBCB Bcb, current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry); if (current->FileOffset == PAGE_ROUND_DOWN(FileOffset)) { + DPRINT("Found existing segment at %x\n", current); current->ReferenceCount++; KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + DPRINT("Waiting for segment\n"); KeWaitForSingleObject(¤t->Lock, Executive, KernelMode, FALSE, NULL); *UptoDate = current->Valid; - BaseAddress = current->BaseAddress; + *BaseAddress = current->BaseAddress; + *CacheSeg = current; + DPRINT("Returning %x (UptoDate %d)\n", current, current->Valid); return(STATUS_SUCCESS); } current_entry = current_entry->Flink; } + DPRINT("Creating new segment\n"); + + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + current = ExAllocatePool(NonPagedPool, sizeof(CACHE_SEGMENT)); current->BaseAddress = NULL; MmCreateMemoryArea(KernelMode, - PsGetCurrentProcess(), + NULL, MEMORY_AREA_CACHE_SEGMENT, ¤t->BaseAddress, CACHE_SEGMENT_SIZE, PAGE_READWRITE, - ¤t->MemoryArea); + (PMEMORY_AREA*)¤t->MemoryArea); + CHECKPOINT; current->Valid = FALSE; current->FileOffset = PAGE_ROUND_DOWN(FileOffset); - KeInitializeEvent(¤t->Lock, SynchronizationEvent, TRUE); + current->Bcb = Bcb; + CHECKPOINT; + KeInitializeEvent(¤t->Lock, SynchronizationEvent, FALSE); current->ReferenceCount = 1; + CHECKPOINT; InsertTailList(&Bcb->CacheSegmentListHead, ¤t->ListEntry); + CHECKPOINT; *UptoDate = current->Valid; *BaseAddress = current->BaseAddress; - MmSetPage(PsGetCurrentProcess(), - current->BaseAddress, - (ULONG)MmAllocPage(), - PAGE_READWRITE); + *CacheSeg = current; + CHECKPOINT; + MmSetPage(NULL, + current->BaseAddress, + PAGE_READWRITE, + (ULONG)MmAllocPage()); - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + + DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress); + + return(STATUS_SUCCESS); +} + +NTSTATUS CcFreeCacheSegment(PFILE_OBJECT FileObject, + PBCB Bcb, + PCACHE_SEGMENT CacheSeg) +{ + MmFreeMemoryArea(NULL, + CacheSeg->BaseAddress, + CACHE_SEGMENT_SIZE, + TRUE); + ExFreePool(CacheSeg); + return(STATUS_SUCCESS); +} + +NTSTATUS CcReleaseFileCache(PFILE_OBJECT FileObject, + PBCB Bcb) +{ + PLIST_ENTRY current_entry; + PCACHE_SEGMENT current; + + DPRINT("CcReleaseFileCache(FileObject %x, Bcb %x)\n", + FileObject, Bcb); + + current_entry = Bcb->CacheSegmentListHead.Flink; + while (current_entry != (&Bcb->CacheSegmentListHead)) + { + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry); + current_entry = current_entry->Flink; + CcFreeCacheSegment(FileObject, + Bcb, + current); + } + + ExFreePool(Bcb); + + DPRINT("CcReleaseFileCache() finished\n"); return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 9ad65b460f3..95d803e0be7 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -14,7 +14,7 @@ #include -/* #define PROTO_REG 1 /* Comment out to disable */ +// #define PROTO_REG 1 /* Comment out to disable */ /* FILE STATICS *************************************************************/ diff --git a/reactos/ntoskrnl/dbg/errinfo.c b/reactos/ntoskrnl/dbg/errinfo.c index 687fcde65d3..8dc423507f2 100644 --- a/reactos/ntoskrnl/dbg/errinfo.c +++ b/reactos/ntoskrnl/dbg/errinfo.c @@ -38,7 +38,7 @@ static struct _ERRLIST { {STATUS_SUCCESS, "SUCCESS", NULL}, {STATUS_INSUFFICIENT_RESOURCES, "INSUFFICIENT_RESOURCES", NULL}, - {STATUS_OBJECT_NAME_EXISTS, "OBJECT_NAME_EXISTS", NULL}, +// {STATUS_OBJECT_NAME_EXISTS, "OBJECT_NAME_EXISTS", NULL}, {STATUS_OBJECT_NAME_COLLISION, "OBJECT_NAME_COLLISION", NULL}, {STATUS_CTL_FILE_NOT_SUPPORTED, "CTL_FILE_NOT_SUPPORTED", NULL}, {STATUS_PORT_ALREADY_SET, "PORT_ALREADY_SET", NULL}, diff --git a/reactos/ntoskrnl/ex/fmutex.c b/reactos/ntoskrnl/ex/fmutex.c index b15b24888a6..7c915f4b5b7 100644 --- a/reactos/ntoskrnl/ex/fmutex.c +++ b/reactos/ntoskrnl/ex/fmutex.c @@ -29,8 +29,11 @@ VOID ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex) return; } FastMutex->Contention++; - KeWaitForSingleObject(&(FastMutex->Event),Executive,KernelMode, - FALSE,NULL); + KeWaitForSingleObject(&(FastMutex->Event), + Executive, + KernelMode, + FALSE, + NULL); FastMutex->Owner=KeGetCurrentThread(); } @@ -39,12 +42,14 @@ VOID ExInitializeFastMutex(PFAST_MUTEX FastMutex) FastMutex->Count=1; FastMutex->Owner=NULL; FastMutex->Contention=0; - KeInitializeEvent(&(FastMutex->Event),SynchronizationEvent,FALSE); + KeInitializeEvent(&(FastMutex->Event), + SynchronizationEvent, + FALSE); } VOID ExReleaseFastMutexUnsafe(PFAST_MUTEX FastMutex) { - assert(FastMutex->Owner==KeGetCurrentThread()); + assert(FastMutex->Owner == KeGetCurrentThread()); FastMutex->Owner=NULL; if (InterlockedIncrement(&(FastMutex->Count))<=0) { diff --git a/reactos/ntoskrnl/ex/resource.c b/reactos/ntoskrnl/ex/resource.c index c383ea54fde..f4631ebf441 100644 --- a/reactos/ntoskrnl/ex/resource.c +++ b/reactos/ntoskrnl/ex/resource.c @@ -1,9 +1,9 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: kernel/excutive/resource.c - * PURPOSE: Graceful system shutdown if a bug is detected - * PROGRAMMER: David Welch (welch@mcmail.com) + * FILE: ntoskrnl/ex/resource.c + * PURPOSE: Resource synchronization construct + * PROGRAMMER: Unknown * UPDATE HISTORY: * Created 22/05/98 */ @@ -40,304 +40,507 @@ #include #include -#define NDEBUG +//#define NDEBUG #include /* 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; iOwnerThreads[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; iOwnerThreads[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;iOwnerThreads[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;iOwnerThreads[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;iOwnerThreads[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; iOwnerThreads[1].a.TableSize; i++) + { + if (Resource->OwnerTable[i].OwnerThread==ExGetCurrentResourceThread()) + { + return Resource->OwnerTable[i].a.OwnerCount; + } + } + return(0); } VOID ExReinitializeResourceLite(PERESOURCE Resource) @@ -350,7 +553,10 @@ VOID ExReinitializeResourceLite(PERESOURCE Resource) FALSE); KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff); Resource->ActiveCount = 0; - if(Resource->OwnerTable) ExFreePool(Resource->OwnerTable); + if (Resource->OwnerTable) + { + ExFreePool(Resource->OwnerTable); + } Resource->OwnerThreads[0].OwnerThread=0; Resource->OwnerThreads[0].a.OwnerCount=0; Resource->OwnerThreads[1].OwnerThread=0; @@ -359,7 +565,8 @@ VOID ExReinitializeResourceLite(PERESOURCE Resource) VOID ExReleaseResourceLite(PERESOURCE Resource) { - return ExReleaseResourceForThreadLite(Resource,ExGetCurrentResourceThread()); + return(ExReleaseResourceForThreadLite(Resource, + ExGetCurrentResourceThread())); } VOID ExReleaseResource(PERESOURCE Resource) @@ -370,81 +577,79 @@ VOID ExReleaseResource(PERESOURCE Resource) VOID ExReleaseResourceForThread(PERESOURCE Resource, ERESOURCE_THREAD ResourceThreadId) { - return ExReleaseResourceForThreadLite(Resource,ResourceThreadId); + return(ExReleaseResourceForThreadLite(Resource,ResourceThreadId)); } VOID ExReleaseResourceForThreadLite(PERESOURCE Resource, ERESOURCE_THREAD ResourceThreadId) +/* + * FUNCTION: Releases a resource for the given thread + * ARGUMENTS: + * Resource = Points to the release to release + * ResourceThreadId = Identifies the thread that originally acquired + * the resource + * NOTES: Must be running at IRQL < DISPATCH_LEVEL + * BUG: We don't support starving exclusive waiters + */ { - long i; - //FIXME : protect this function from interrupts - // perhaps with KeRaiseIrql(SYNCH_LEVEL); - if (Resource->Flag & ResourceOwnedExclusive) - { - if(--Resource->OwnerThreads[0].a.OwnerCount == 0) - {//release the resource - Resource->OwnerThreads[0].OwnerThread=0; - assert(--Resource->ActiveCount == 0); - if(Resource->NumberOfExclusiveWaiters) - {// get resource to first exclusive waiter - KeDispatcherObjectWake(&Resource->ExclusiveWaiters->Header); - return; - } - else - Resource->Flag &=(~ResourceOwnedExclusive); - if(Resource->NumberOfSharedWaiters) - {// get resource to waiters - Resource->ActiveCount=Resource->NumberOfSharedWaiters; - Resource->NumberOfSharedWaiters=0; - KeReleaseSemaphore(Resource->SharedWaiters,0,Resource->ActiveCount,0); - return; - } - } - return; - } - //search the entry for this thread - if(Resource->OwnerThreads[1].OwnerThread==ResourceThreadId) - { - if( --Resource->OwnerThreads[1].a.OwnerCount == 0) - { - Resource->OwnerThreads[1].OwnerThread=0; - if( --Resource->ActiveCount ==0) //normally always true - { - if(Resource->NumberOfExclusiveWaiters) - {// get resource to first exclusive waiter - KeDispatcherObjectWake(&Resource->ExclusiveWaiters->Header); - } - } - } - return; - } - if(Resource->OwnerThreads[1].OwnerThread) return ; - for(i=0;iOwnerThreads[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"); } diff --git a/reactos/ntoskrnl/ex/stamp.c b/reactos/ntoskrnl/ex/stamp.c index b58b1e14401..d86f9960bc3 100644 --- a/reactos/ntoskrnl/ex/stamp.c +++ b/reactos/ntoskrnl/ex/stamp.c @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/ex/stamp.c - * PURPOSE: Graceful system shutdown if a bug is detected + * PURPOSE: Versioning * PROGRAMMER: David Welch (welch@mcmail.com) * UPDATE HISTORY: * Created 22/05/98 diff --git a/reactos/ntoskrnl/exports.lst b/reactos/ntoskrnl/exports.lst index d9a38803ff9..39f6b003b27 100644 --- a/reactos/ntoskrnl/exports.lst +++ b/reactos/ntoskrnl/exports.lst @@ -7,9 +7,6 @@ # # # -CbInitDccb -CbAcquireForRead -CbReleaseFromRead DbgPrint ExAcquireFastMutex ExAcquireFastMutexUnsafe @@ -121,6 +118,7 @@ IoConnectInterrupt IoCreateController IoCreateDevice IoCreateNotificationEvent +IoCreateStreamFileObject IoCreateSymbolicLink IoCreateSynchronizationEvent IoCreateUnprotectedSymbolicLink @@ -397,3 +395,12 @@ wcschr wcscpy wcsncat wcsncpy +#wtolower +tolower +toupper +memcpy +strtok +CcInitializeFileCache +CcRequestCachePage +CcReleaseCachePage +CcReleaseFileCache diff --git a/reactos/ntoskrnl/hal/x86/exp.c b/reactos/ntoskrnl/hal/x86/exp.c index dc06b4cfb53..467b8bfd65c 100644 --- a/reactos/ntoskrnl/hal/x86/exp.c +++ b/reactos/ntoskrnl/hal/x86/exp.c @@ -226,11 +226,17 @@ asmlinkage void exception_handler(unsigned int edi, DbgPrint("EDI: %.8x EFLAGS: %.8x ",edi,eflags); if ((cs&0xffff) == KERNEL_CS) { - DbgPrint("ESP %.8x\n",esp); + DbgPrint("kESP %.8x\n",esp); + if (PsGetCurrentThread() != NULL) + { + DbgPrint("kernel stack base %x\n", + PsGetCurrentThread()->Tcb.Context.KernelStackBase); + + } } else { - DbgPrint("ESP %.8x\n",esp); + DbgPrint("kernel ESP %.8x\n",esp); } if ((cs & 0xffff) == KERNEL_CS) @@ -288,6 +294,8 @@ asmlinkage void exception_handler(unsigned int edi, } } + DPRINT("Killing current task\n"); + KeLowerIrql(PASSIVE_LEVEL); if ((cs&0xffff) == USER_CS) { ZwTerminateProcess(NtCurrentProcess(), @@ -307,7 +315,8 @@ VOID KeDumpStackFrames(ULONG DummyArg, ULONG NrFrames) DbgPrint("Frames:\n"); for (i=0; i KERNEL_BASE && Stack[i] < ((ULONG)&etext)) +// if (Stack[i] > KERNEL_BASE && Stack[i] < ((ULONG)&etext)) + if (Stack[i] > KERNEL_BASE) { DbgPrint("%.8x ",Stack[i]); } diff --git a/reactos/ntoskrnl/hal/x86/irq.c b/reactos/ntoskrnl/hal/x86/irq.c index 9693322a544..0cb45219e63 100644 --- a/reactos/ntoskrnl/hal/x86/irq.c +++ b/reactos/ntoskrnl/hal/x86/irq.c @@ -105,7 +105,10 @@ asmlinkage VOID KiInterruptDispatch(ULONG irq) * Notify the rest of the kernel of the raised irq level */ old_level = KeGetCurrentIrql(); -// DPRINT("old_level %d\n",old_level); + if (irq != 0) + { + DPRINT("old_level %d\n",old_level); + } KeSetCurrentIrql(HIGH_LEVEL - irq); /* @@ -120,7 +123,7 @@ asmlinkage VOID KiInterruptDispatch(ULONG irq) } else { - DPRINT("KiInterruptDispatch(irq %x)\n",irq); + DPRINT("KiInterruptDispatch(irq %d)\n",irq); /* * Iterate the list until one of the isr tells us its device interrupted */ @@ -299,7 +302,6 @@ NTSTATUS IoConnectInterrupt(PKINTERRUPT* InterruptObject, { isr_lock[Vector]=ExAllocatePool(NonPagedPool,sizeof(KSPIN_LOCK)); KeInitializeSpinLock(isr_lock[Vector]); - isr_lock[Vector]->irql = SynchronizeIrql; } /* diff --git a/reactos/ntoskrnl/hal/x86/irql.c b/reactos/ntoskrnl/hal/x86/irql.c index 8b13b52d416..7b4bd5c456e 100644 --- a/reactos/ntoskrnl/hal/x86/irql.c +++ b/reactos/ntoskrnl/hal/x86/irql.c @@ -52,10 +52,14 @@ static void HiSwitchIrql(void) */ { unsigned int i; + PKTHREAD CurrentThread; + + CurrentThread = KeGetCurrentThread(); if (CurrentIrql == HIGH_LEVEL) { HiSetCurrentPICMask(0xffff); +// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = TRUE; return; } if (CurrentIrql > DISPATCH_LEVEL) @@ -68,16 +72,28 @@ static void HiSwitchIrql(void) } HiSetCurrentPICMask(current_mask); +// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = TRUE; __asm__("sti\n\t"); return; } - if (CurrentIrql <= DISPATCH_LEVEL) + if (CurrentIrql == DISPATCH_LEVEL) + { +// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = TRUE; + HiSetCurrentPICMask(0); + __asm__("sti\n\t"); + return; + } + if (CurrentIrql == APC_LEVEL) { +// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = TRUE; HiSetCurrentPICMask(0); __asm__("sti\n\t"); return; } +// if (CurrentThread != NULL) CurrentThread->KernelApcDisable = FALSE; + HiSetCurrentPICMask(0); + __asm__("sti\n\t"); } VOID KeSetCurrentIrql(KIRQL newlvl) @@ -135,6 +151,7 @@ VOID KeRaiseIrql(KIRQL NewIrql, PKIRQL OldIrql) { DbgPrint("%s:%d CurrentIrql %x NewIrql %x OldIrql %x\n", __FILE__,__LINE__,CurrentIrql,NewIrql,OldIrql); + KeBugCheck(0); for(;;); } diff --git a/reactos/ntoskrnl/hal/x86/printk.c b/reactos/ntoskrnl/hal/x86/printk.c index fe4608af274..d6a0e9a804d 100644 --- a/reactos/ntoskrnl/hal/x86/printk.c +++ b/reactos/ntoskrnl/hal/x86/printk.c @@ -354,7 +354,6 @@ void HalInitConsole(boot_param* bp) * bp = Parameters setup by the boot loader */ { -// int offset; #ifdef SERIAL_DEBUGGING /* turn on DTR and RTS */ diff --git a/reactos/ntoskrnl/hal/x86/spinlock.c b/reactos/ntoskrnl/hal/x86/spinlock.c index 435d7229dbb..fcaff40f516 100644 --- a/reactos/ntoskrnl/hal/x86/spinlock.c +++ b/reactos/ntoskrnl/hal/x86/spinlock.c @@ -56,7 +56,7 @@ VOID KeInitializeSpinLock(PKSPIN_LOCK SpinLock) * SpinLock = Caller supplied storage for the spinlock */ { - SpinLock->irql = DISPATCH_LEVEL; + SpinLock->Lock = 0; } VOID KeAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock) @@ -67,6 +67,11 @@ VOID KeAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock) * SpinLock = Spinlock to acquire */ { + while(InterlockedExchange(&SpinLock->Lock, 1) == 1) + { + DbgPrint("Spinning on spinlock\n"); + KeBugCheck(0); + } } VOID KeReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock) @@ -77,6 +82,12 @@ VOID KeReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock) * SpinLock = Spinlock to release */ { + if (SpinLock->Lock != 1) + { + DbgPrint("Releasing unacquired spinlock\n"); + KeBugCheck(0); + } + (void)InterlockedExchange(&SpinLock->Lock, 0); } VOID KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql) @@ -88,6 +99,7 @@ VOID KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql) */ { KeRaiseIrql(DISPATCH_LEVEL,OldIrql); + KeAcquireSpinLockAtDpcLevel(SpinLock); } VOID KeReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL NewIrql) @@ -98,6 +110,7 @@ VOID KeReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL NewIrql) * NewIrql = Irql level before acquiring the spinlock */ { + KeReleaseSpinLockFromDpcLevel(SpinLock); KeLowerIrql(NewIrql); } diff --git a/reactos/ntoskrnl/io/buildirp.c b/reactos/ntoskrnl/io/buildirp.c index 6b01632a75a..12ce04c13a4 100644 --- a/reactos/ntoskrnl/io/buildirp.c +++ b/reactos/ntoskrnl/io/buildirp.c @@ -90,6 +90,7 @@ PIRP IoBuildFilesystemControlRequest(ULONG MinorFunction, Irp->UserIosb = IoStatusBlock; Irp->UserEvent = UserEvent; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL; @@ -153,6 +154,9 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction, return(NULL); } + Irp->UserIosb = IoStatusBlock; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); + StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = MajorFunction; StackPtr->MinorFunction = 0; @@ -161,30 +165,32 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction, StackPtr->DeviceObject = DeviceObject; StackPtr->FileObject = NULL; StackPtr->CompletionRoutine = NULL; - StackPtr->Parameters.Write.Length = Length; - if (MajorFunction == IRP_MJ_READ || MajorFunction == IRP_MJ_WRITE) + if (Buffer != NULL) + { + 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; @@ -194,7 +200,7 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction, StackPtr->Parameters.Write.ByteOffset.QuadPart = 0; } } - + Irp->UserIosb = IoStatusBlock; return(Irp); @@ -246,6 +252,7 @@ PIRP IoBuildDeviceIoControlRequest(ULONG IoControlCode, Irp->UserEvent = Event; Irp->UserIosb = IoStatusBlock; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = InternalDeviceIoControl ? IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL; @@ -396,6 +403,7 @@ PIRP IoBuildSynchronousFsdRequest(ULONG MajorFunction, Irp->UserEvent = Event; Irp->UserIosb = IoStatusBlock; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = MajorFunction; diff --git a/reactos/ntoskrnl/io/create.c b/reactos/ntoskrnl/io/create.c index 210606cdc7a..f0bd7eec933 100644 --- a/reactos/ntoskrnl/io/create.c +++ b/reactos/ntoskrnl/io/create.c @@ -69,6 +69,11 @@ NTSTATUS IopCreateFile(PVOID ObjectBody, DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %w)\n", ObjectBody,Parent,RemainingPath); + if (DeviceObject == NULL) + { + return(STATUS_SUCCESS); + } + Status = ObReferenceObjectByPointer(DeviceObject, STANDARD_RIGHTS_REQUIRED, IoDeviceType, @@ -120,6 +125,41 @@ NTSTATUS IopCreateFile(PVOID ObjectBody, return(STATUS_SUCCESS); } +PFILE_OBJECT IoCreateStreamFileObject(PFILE_OBJECT FileObject, + PDEVICE_OBJECT DeviceObject) +{ + HANDLE FileHandle; + PFILE_OBJECT CreatedFileObject; + + DbgPrint("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n", + FileObject, DeviceObject); + + assert_irql(PASSIVE_LEVEL); + + CreatedFileObject = ObCreateObject(&FileHandle, + STANDARD_RIGHTS_REQUIRED, + NULL, + IoFileType); + if (CreatedFileObject == NULL) + { + return(NULL); + } + + if (FileObject != NULL) + { + DeviceObject = FileObject->DeviceObject; + } + DeviceObject = IoGetAttachedDevice(DeviceObject); + CreatedFileObject->DeviceObject = DeviceObject; + CreatedFileObject->Vpb = DeviceObject->Vpb; + CreatedFileObject->Type = ID_FILE_OBJECT; + CreatedFileObject->Flags = CreatedFileObject->Flags | FO_DIRECT_DEVICE_OPEN; + + ZwClose(FileHandle); + + return(CreatedFileObject); +} + NTSTATUS STDCALL ZwCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, @@ -215,10 +255,12 @@ NTSTATUS STDCALL ZwCreateFile(PHANDLE FileHandle, if (!NT_SUCCESS(Status)) { + DPRINT("Failing create request with status %x\n",Status); ZwClose(*FileHandle); (*FileHandle) = 0; } + assert_irql(PASSIVE_LEVEL); DPRINT("Finished ZwCreateFile() (*FileHandle) %x\n",(*FileHandle)); return(Status); } diff --git a/reactos/ntoskrnl/io/device.c b/reactos/ntoskrnl/io/device.c index 69e3af30763..7882aaae7b1 100644 --- a/reactos/ntoskrnl/io/device.c +++ b/reactos/ntoskrnl/io/device.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/io/device.c * PURPOSE: Manage devices - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * 15/05/98: Created */ @@ -82,25 +82,29 @@ PDEVICE_OBJECT IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject) { PDEVICE_OBJECT Current = DeviceObject; - DPRINT("IoGetAttachDevice(DeviceObject %x)\n",DeviceObject); +// DPRINT("IoGetAttachedDevice(DeviceObject %x)\n",DeviceObject); while (Current->AttachedDevice!=NULL) { Current = Current->AttachedDevice; - DPRINT("Current %x\n",Current); +// DPRINT("Current %x\n",Current); } + +// DPRINT("IoGetAttachedDevice() = %x\n",DeviceObject); return(Current); } PDEVICE_OBJECT IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice, PDEVICE_OBJECT TargetDevice) { - PDEVICE_OBJECT AttachedDevice = IoGetAttachedDevice(TargetDevice); + PDEVICE_OBJECT AttachedDevice; DPRINT("IoAttachDeviceToDeviceStack(SourceDevice %x, TargetDevice %x)\n", SourceDevice,TargetDevice); + AttachedDevice = IoGetAttachedDevice(TargetDevice); AttachedDevice->AttachedDevice = SourceDevice; + SourceDevice->AttachedDevice = NULL; SourceDevice->StackSize = AttachedDevice->StackSize + 1; SourceDevice->Vpb = AttachedDevice->Vpb; return(AttachedDevice); @@ -223,7 +227,9 @@ NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT CreatedDeviceObject; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE DeviceHandle; - + + assert_irql(PASSIVE_LEVEL); + if (DeviceName != NULL) { DPRINT("IoCreateDevice(DriverObject %x, DeviceName %w)\n",DriverObject, @@ -250,7 +256,7 @@ NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject, IoDeviceType); } - *DeviceObject=NULL; + *DeviceObject = NULL; if (CreatedDeviceObject == NULL) { diff --git a/reactos/ntoskrnl/io/fs.c b/reactos/ntoskrnl/io/fs.c index cb4aafd11dc..de1fe263717 100644 --- a/reactos/ntoskrnl/io/fs.c +++ b/reactos/ntoskrnl/io/fs.c @@ -184,6 +184,8 @@ NTSTATUS IoAskFileSystemToMountDevice(PDEVICE_OBJECT DeviceObject, DPRINT("IoAskFileSystemToMountDevice(DeviceObject %x, DeviceToMount %x)\n", DeviceObject,DeviceToMount); + assert_irql(PASSIVE_LEVEL); + KeInitializeEvent(&Event,NotificationEvent,FALSE); Irp = IoBuildFilesystemControlRequest(IRP_MN_MOUNT_VOLUME, DeviceObject, @@ -217,6 +219,8 @@ NTSTATUS IoTryToMountStorageDevice(PDEVICE_OBJECT DeviceObject) FILE_SYSTEM_OBJECT* current; NTSTATUS Status; + assert_irql(PASSIVE_LEVEL); + DPRINT("IoTryToMountStorageDevice(DeviceObject %x)\n",DeviceObject); KeAcquireSpinLock(&FileSystemListLock,&oldlvl); @@ -224,8 +228,10 @@ NTSTATUS IoTryToMountStorageDevice(PDEVICE_OBJECT DeviceObject) while (current_entry!=(&FileSystemListHead)) { current = CONTAINING_RECORD(current_entry,FILE_SYSTEM_OBJECT,Entry); + KeReleaseSpinLock(&FileSystemListLock,oldlvl); Status = IoAskFileSystemToMountDevice(current->DeviceObject, DeviceObject); + KeAcquireSpinLock(&FileSystemListLock,&oldlvl); switch (Status) { case STATUS_FS_DRIVER_REQUIRED: diff --git a/reactos/ntoskrnl/io/irp.c b/reactos/ntoskrnl/io/irp.c index bed029a9a22..dae4646daba 100644 --- a/reactos/ntoskrnl/io/irp.c +++ b/reactos/ntoskrnl/io/irp.c @@ -84,10 +84,6 @@ VOID IoMarkIrpPending(PIRP Irp) DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n", IoGetCurrentIrpStackLocation(Irp)); IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED; - Irp->Tail.Overlay.Thread = PsGetCurrentThread(); - DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n", - IoGetCurrentIrpStackLocation(Irp)->Control); - DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED); } USHORT IoSizeOfIrp(CCHAR StackSize) @@ -112,10 +108,10 @@ VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize) { assert(Irp != NULL); - memset(Irp,0,PacketSize); - Irp->StackCount=StackSize; - Irp->CurrentLocation=StackSize; - Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp); + memset(Irp, 0, PacketSize); + Irp->StackCount = StackSize; + Irp->CurrentLocation = StackSize; + Irp->Tail.Overlay.CurrentStackLocation = IoGetCurrentIrpStackLocation(Irp); } PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp) @@ -132,10 +128,9 @@ PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp) Irp->CurrentLocation, Irp->StackCount); - return &Irp->Stack[(ULONG)Irp->CurrentLocation]; + return(&Irp->Stack[(ULONG)Irp->CurrentLocation]); } - VOID IoSetNextIrpStackLocation(PIRP Irp) { Irp->CurrentLocation--; @@ -160,25 +155,25 @@ PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp) NTSTATUS IoCallDriver(PDEVICE_OBJECT DeviceObject, PIRP Irp) /* - * FUNCTION: Sends an IRP to the next lower driver + * FUNCTION: Sends an IRP to the next lower driver */ { NTSTATUS Status; PDRIVER_OBJECT DriverObject; - PIO_STACK_LOCATION param; + PIO_STACK_LOCATION Param; DPRINT("IoCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp); DriverObject = DeviceObject->DriverObject; - param = IoGetNextIrpStackLocation(Irp); + Param = IoGetNextIrpStackLocation(Irp); Irp->Tail.Overlay.CurrentStackLocation--; Irp->CurrentLocation--; DPRINT("MajorFunction %d\n",param->MajorFunction); - DPRINT("DriverObject->MajorFunction[param->MajorFunction] %x\n", - DriverObject->MajorFunction[param->MajorFunction]); - Status = DriverObject->MajorFunction[param->MajorFunction](DeviceObject, + DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n", + DriverObject->MajorFunction[Param->MajorFunction]); + Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp); return Status; } @@ -270,6 +265,7 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost) { unsigned int i; NTSTATUS Status; + PKTHREAD Thread; DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n", Irp,PriorityBoost); @@ -295,15 +291,20 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost) if (Irp->PendingReturned) { + Thread = &Irp->Tail.Overlay.Thread->Tcb; KeInitializeApc(&Irp->Tail.Apc, - &Irp->Tail.Overlay.Thread->Tcb, + Thread, 0, IopCompleteRequest, NULL, - NULL, + (PKNORMAL_ROUTINE) + Irp->Overlay.AsynchronousParameters.UserApcRoutine, 0, - Irp); - KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0); + (PVOID)Irp); + KeInsertQueueApc(&Irp->Tail.Apc, + Irp->Overlay.AsynchronousParameters.UserApcContext, + NULL, + 0); } else { diff --git a/reactos/ntoskrnl/io/queue.c b/reactos/ntoskrnl/io/queue.c index 46e25d34df7..a9d8dfb15d9 100644 --- a/reactos/ntoskrnl/io/queue.c +++ b/reactos/ntoskrnl/io/queue.c @@ -109,7 +109,7 @@ VOID IoStartPacket(PDEVICE_OBJECT DeviceObject, else { stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue, - &Irp->Tail.Overlay.DeviceQueueEntry); + &Irp->Tail.Overlay.DeviceQueueEntry); } IoReleaseCancelSpinLock(oldirql); diff --git a/reactos/ntoskrnl/io/rw.c b/reactos/ntoskrnl/io/rw.c index 29f8cc4eb70..b383480b48e 100644 --- a/reactos/ntoskrnl/io/rw.c +++ b/reactos/ntoskrnl/io/rw.c @@ -59,11 +59,11 @@ NTSTATUS ZwReadFile(HANDLE FileHandle, PKEVENT ptrEvent = NULL; KEVENT Event; - assert(KeGetCurrentIrql()==PASSIVE_LEVEL); - DPRINT("ZwReadFile(FileHandle %x Buffer %x Length %x ByteOffset %x, " "IoStatusBlock %x)\n", FileHandle,Buffer,Length,ByteOffset,IoStatusBlock); + + assert_irql(PASSIVE_LEVEL); Status = ObReferenceObjectByHandle(FileHandle, FILE_READ_DATA, @@ -71,7 +71,7 @@ NTSTATUS ZwReadFile(HANDLE FileHandle, UserMode, (PVOID *) &FileObject, NULL); - if (!NT_SUCCESS(STATUS_SUCCESS)) + if (!NT_SUCCESS(Status)) { DPRINT("ZwReadFile() = %x\n",Status); return(Status); @@ -112,7 +112,10 @@ NTSTATUS ZwReadFile(HANDLE FileHandle, ByteOffset, ptrEvent, IoStatusBlock); - + + Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; + Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; + StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->FileObject = FileObject; if (Key!=NULL) @@ -124,13 +127,14 @@ NTSTATUS ZwReadFile(HANDLE FileHandle, StackPtr->Parameters.Read.Key = 0; } - Status = IoCallDriver(FileObject->DeviceObject,Irp); + Status = IoCallDriver(FileObject->DeviceObject, Irp); if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) { KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); Status = IoStatusBlock->Status; } DPRINT("ZwReadFile() = %x\n",Status); + assert_irql(PASSIVE_LEVEL); return(Status); } @@ -180,7 +184,7 @@ NTSTATUS ZwWriteFile(HANDLE FileHandle, UserMode, (PVOID *) &FileObject, NULL); - if (Status != STATUS_SUCCESS) + if (!NT_SUCCESS(Status)) { return(Status); } @@ -197,17 +201,21 @@ NTSTATUS ZwWriteFile(HANDLE FileHandle, ByteOffset, &Event, IoStatusBlock); + + Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; + Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext; + DPRINT("FileObject->DeviceObject %x\n",FileObject->DeviceObject); StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->FileObject = FileObject; if (Key!=NULL) - { - StackPtr->Parameters.Write.Key = *Key; - } + { + StackPtr->Parameters.Write.Key = *Key; + } else - { + { StackPtr->Parameters.Write.Key = 0; - } + } Status = IoCallDriver(FileObject->DeviceObject,Irp); if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) { diff --git a/reactos/ntoskrnl/io/symlink.c b/reactos/ntoskrnl/io/symlink.c index c7049ce3c2d..2be022bc96a 100644 --- a/reactos/ntoskrnl/io/symlink.c +++ b/reactos/ntoskrnl/io/symlink.c @@ -182,6 +182,8 @@ NTSTATUS IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName, HANDLE SymbolicLinkHandle; PSYMLNK_OBJECT SymbolicLink; + assert_irql(PASSIVE_LEVEL); + DPRINT("IoCreateSymbolicLink(SymbolicLinkName %w, DeviceName %w)\n", SymbolicLinkName->Buffer,DeviceName->Buffer); diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 7624e2007a9..1ea54347c54 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -23,8 +23,44 @@ extern VOID KeApcProlog(VOID); /* 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, @@ -42,7 +78,15 @@ VOID KeDeliverKernelApc(PKAPC Apc) PKTHREAD TargetThread; PULONG Stack; + DPRINT("KeDeliverKernelApc(Apc %x)\n", Apc); + TargetThread = Apc->Thread; + + if (TargetThread->KernelApcDisable <= 0) + { + DbgPrint("Queueing apc for thread %x\n", TargetThread); + return; + } if (TargetThread == KeGetCurrentThread()) { @@ -69,12 +113,12 @@ VOID KeDeliverKernelApc(PKAPC Apc) { TargetThread->Context.esp = TargetThread->Context.esp - 40; Stack = (PULONG)TargetThread->Context.esp; - Stack[9] = TargetThread->Context.ss; - Stack[8] = TargetThread->Context.esp; - Stack[7] = TargetThread->Context.gs; - Stack[6] = TargetThread->Context.fs; - Stack[5] = TargetThread->Context.ds; - Stack[4] = TargetThread->Context.es; + Stack[9] = TargetThread->Context.gs; + Stack[8] = TargetThread->Context.fs; + Stack[7] = TargetThread->Context.ds; + Stack[6] = TargetThread->Context.es; + Stack[5] = TargetThread->Context.ss; + Stack[4] = TargetThread->Context.esp; Stack[3] = TargetThread->Context.eflags; Stack[2] = TargetThread->Context.cs; Stack[1] = TargetThread->Context.eip; @@ -86,17 +130,33 @@ VOID KeDeliverKernelApc(PKAPC Apc) PsResumeThread(CONTAINING_RECORD(TargetThread,ETHREAD,Tcb)); } -void KeInsertQueueApc(struct _KAPC *Apc, PVOID SystemArgument1, - PVOID SystemArgument2, UCHAR Mode) +void KeInsertQueueApc(PKAPC Apc, + PVOID SystemArgument1, + PVOID SystemArgument2, + UCHAR Mode) { KIRQL oldlvl; + PKTHREAD TargetThread; DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, " "SystemArgument2 %x, Mode %d)\n",Apc,SystemArgument1, SystemArgument2,Mode); - KeRaiseIrql(DISPATCH_LEVEL,&oldlvl); + KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); + if (Apc->Inserted) + { + DbgPrint("KeInsertQueueApc(): multiple APC insertations\n"); + KeBugCheck(0); + } + + TargetThread = Apc->Thread; + InsertTailList(&TargetThread->ApcState.ApcListHead[0], &Apc->ApcListEntry); + Apc->Inserted = TRUE; + + DPRINT("TargetThread->KernelApcDisable %d\n", + TargetThread->KernelApcDisable); + DPRINT("Apc->KernelRoutine %x\n", Apc->KernelRoutine); if (Apc->KernelRoutine != NULL) { KeDeliverKernelApc(Apc); @@ -113,17 +173,21 @@ VOID KeInitializeApc(PKAPC Apc, UCHAR Mode, PVOID Context) { - memset(Apc,0,sizeof(KAPC)); + DPRINT("KeInitializeApc(Apc %x, Thread %x, StateIndex %d, " + "KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, " + "Context %x)\n",Apc,Thread,StateIndex,KernelRoutine,RundownRoutine, + NormalRoutine,Mode,Context); + memset(Apc, 0, sizeof(KAPC)); Apc->Thread = Thread; - Apc->ApcListEntry.Flink=NULL; - Apc->ApcListEntry.Blink=NULL; - Apc->KernelRoutine=KernelRoutine; - Apc->RundownRoutine=RundownRoutine; - Apc->NormalRoutine=NormalRoutine; - Apc->NormalContext=Context; - Apc->Inserted=FALSE; - Apc->ApcStateIndex=StateIndex; - Apc->ApcMode=Mode; + Apc->ApcListEntry.Flink = NULL; + Apc->ApcListEntry.Blink = NULL; + Apc->KernelRoutine = KernelRoutine; + Apc->RundownRoutine = RundownRoutine; + Apc->NormalRoutine = NormalRoutine; + Apc->NormalContext = Context; + Apc->Inserted = FALSE; + Apc->ApcStateIndex = StateIndex; + Apc->ApcMode = Mode; } @@ -156,5 +220,7 @@ NTSTATUS STDCALL NtTestAlert(VOID) NTSTATUS STDCALL ZwTestAlert(VOID) { - UNIMPLEMENTED; + KiTestAlert(KeGetCurrentThread(), + NULL /* ?? */); + return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/ke/bug.c b/reactos/ntoskrnl/ke/bug.c index 19d658c3613..43d4ea45c19 100644 --- a/reactos/ntoskrnl/ke/bug.c +++ b/reactos/ntoskrnl/ke/bug.c @@ -68,6 +68,7 @@ VOID KeBugCheckEx(ULONG BugCheckCode, BugCheckParameter1,BugCheckParameter2,BugCheckParameter3, BugCheckParameter4); KeDumpStackFrames(0,64); + __asm__("cli\n\t"); for(;;); } diff --git a/reactos/ntoskrnl/ke/critical.c b/reactos/ntoskrnl/ke/critical.c index c4b66dbd725..4db4307db56 100644 --- a/reactos/ntoskrnl/ke/critical.c +++ b/reactos/ntoskrnl/ke/critical.c @@ -12,16 +12,19 @@ #include +//#define NDEBUG #include /* FUNCTIONS *****************************************************************/ VOID KeEnterCriticalRegion() { - UNIMPLEMENTED; + DPRINT("KeEnterCriticalRegion()\n"); + KeGetCurrentThread()->KernelApcDisable -= 1; } VOID KeLeaveCriticalRegion() { - UNIMPLEMENTED; + DPRINT("KeLeaveCriticalRegion()\n"); + KeGetCurrentThread()->KernelApcDisable += 1; } diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index a75006f386c..ef0a32af6b9 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -55,6 +55,10 @@ void KeDrainDpcQueue(void) PKDPC current; KIRQL oldlvl; + if (DpcQueueSize == 0) + { + return; + } DPRINT("KeDrainDpcQueue()\n"); KeAcquireSpinLockAtDpcLevel(&DpcQueueLock); @@ -109,7 +113,9 @@ BOOLEAN KeInsertQueueDpc(PKDPC dpc, PVOID SystemArgument1, * FALSE otherwise */ { - DPRINT("KeInsertQueueDpc()\n",0); + DPRINT("KeInsertQueueDpc(dpc %x, SystemArgument1 %x, SystemArgument2 %x)\n", + dpc, SystemArgument1, SystemArgument2); + assert(KeGetCurrentIrql()>=DISPATCH_LEVEL); dpc->Number=0; diff --git a/reactos/ntoskrnl/ke/kqueue.c b/reactos/ntoskrnl/ke/kqueue.c index b0fe05b77a2..722a1a7838f 100644 --- a/reactos/ntoskrnl/ke/kqueue.c +++ b/reactos/ntoskrnl/ke/kqueue.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PURPOSE: ReactOS kernel - * FILE: ntoskrnl/ke/device.c + * FILE: ntoskrnl/ke/kqueue.c * PURPOSE: Implement device queues * PROGRAMMER: David Welch (welch@mcmail.com) * REVISION HISTORY: @@ -10,7 +10,6 @@ /* INCLUDES ****************************************************************/ -#include #include #define NDEBUG diff --git a/reactos/ntoskrnl/ke/timer.c b/reactos/ntoskrnl/ke/timer.c index d2af8cc831e..f32b31b800e 100644 --- a/reactos/ntoskrnl/ke/timer.c +++ b/reactos/ntoskrnl/ke/timer.c @@ -172,11 +172,11 @@ NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval) DPRINT("KeAddThreadTimeout(Thread %x, Interval %x)\n",Thread,Interval); - KeInitializeTimer(&(Thread->TimerBlock)); - KeSetTimer(&(Thread->TimerBlock),*Interval,NULL); + KeInitializeTimer(&(Thread->Timer)); + KeSetTimer(&(Thread->Timer),*Interval,NULL); - DPRINT("Thread->TimerBlock.entry.Flink %x\n", - Thread->TimerBlock.entry.Flink); + DPRINT("Thread->Timer.entry.Flink %x\n", + Thread->Timer.entry.Flink); return STATUS_SUCCESS; } @@ -210,7 +210,7 @@ NTSTATUS KeDelayExecutionThread(KPROCESSOR_MODE WaitMode, { PKTHREAD CurrentThread = KeGetCurrentThread(); KeAddThreadTimeout(CurrentThread,Interval); - return(KeWaitForSingleObject(&(CurrentThread->TimerBlock),Executive, + return(KeWaitForSingleObject(&(CurrentThread->Timer),Executive, KernelMode,Alertable,NULL)); } diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 399b90ecfe5..da779dc7adc 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -214,7 +214,7 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, return(STATUS_SUCCESS); } - if (Timeout!=NULL) + if (Timeout != NULL) { KeAddThreadTimeout(KeGetCurrentThread(),Timeout); } @@ -228,11 +228,13 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, // DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", // hdr->WaitListHead.Flink,hdr->WaitListHead.Blink); KeReleaseDispatcherDatabaseLock(FALSE); + DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__, + KeGetCurrentIrql()); PsSuspendThread(PsGetCurrentThread()); - if (Timeout!=NULL) + if (Timeout != NULL) { - KeCancelTimer(&KeGetCurrentThread()->TimerBlock); + KeCancelTimer(&KeGetCurrentThread()->Timer); } DPRINT("Returning from KeWaitForSingleObject()\n"); return(STATUS_SUCCESS); diff --git a/reactos/ntoskrnl/ldr/init.c b/reactos/ntoskrnl/ldr/init.c index c7b4bc4c32e..f423fbc3fcb 100644 --- a/reactos/ntoskrnl/ldr/init.c +++ b/reactos/ntoskrnl/ldr/init.c @@ -30,7 +30,7 @@ #include #include -//#define NDEBUG +#define NDEBUG #include /* FUNCTIONS ****************************************************************/ @@ -56,7 +56,7 @@ static NTSTATUS LdrCreatePeb(HANDLE ProcessHandle) NT_PEB Peb; ULONG BytesWritten; - PebBase = PEB_BASE; + PebBase = (PVOID)PEB_BASE; PebSize = 0x1000; Status = ZwAllocateVirtualMemory(ProcessHandle, &PebBase, @@ -71,7 +71,7 @@ static NTSTATUS LdrCreatePeb(HANDLE ProcessHandle) memset(&Peb, 0, sizeof(Peb)); - Peb.StartupInfo = PEB_STARTUPINFO; + Peb.StartupInfo = (PPROCESSINFOW)PEB_STARTUPINFO; ZwWriteVirtualMemory(ProcessHandle, (PVOID)PEB_BASE, diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index fb9eb341b2b..5e313f191bd 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -687,7 +687,7 @@ LdrPEProcessModule(PVOID ModuleLoadBase) *ImportAddressList = (PVOID) LdrGetKernelSymbolAddr(SymbolNameBuf); if (*ImportAddressList == 0L) { - DbgPrint("Unresolved kernel symbol: %s\n", pName); + DbgPrint("Unresolved kernel symbol: %s\n", pName); } } ImportAddressList++; diff --git a/reactos/ntoskrnl/makefile_rex b/reactos/ntoskrnl/makefile_rex index 1b1d51d1231..10405287a93 100644 --- a/reactos/ntoskrnl/makefile_rex +++ b/reactos/ntoskrnl/makefile_rex @@ -51,7 +51,7 @@ DBG_OBJECTS = dbg/brkpoint.o dbg/errinfo.o LDR_OBJECTS = ldr/loader.o ldr/init.o -CC_OBJECTS = cc/cacheman.o cc/block.o cc/view.o +CC_OBJECTS = cc/cacheman.o cc/view.o RESOURCE_OBJECT = ntoskrnl.coff @@ -101,7 +101,7 @@ objects/cc.o: $(CC_OBJECTS) $(LD) -r $(CC_OBJECTS) -o objects/cc.o objects/ntoskrnl.coff: ntoskrnl.rc ../include/reactos/resource.h - windres ntoskrnl.rc objects/ntoskrnl.coff + $(RC) ntoskrnl.rc objects/ntoskrnl.coff OBJECTS = objects/hal.o objects/ke.o objects/rtl.o objects/mm.o \ @@ -133,28 +133,26 @@ else endif $(CC) $(CFLAGS) -c ke/exports.c -o ke/exports.o -all: ntoskrnl.a ntoskrnl.exe ntoskrnl.sym - -.PHONY: all - -ntoskrnl.exe: ntoskrnl.o ntoskrnl.def - $(CC) -specs=../specs -mdll -o junk.tmp \ +ntoskrnl.exe: $(OBJECTS) ntoskrnl.def + $(LD) -r $(OBJECTS) -o ntoskrnl.o + $(DLLTOOL) --dllname ntoskrnl.exe --def ntoskrnl.def \ + --output-lib ntoskrnl.a + $(CC) -Wl,-d -specs=../specs -mdll -o junk.tmp \ -Wl,--image-base,0xc0000000 \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ - -Wl,--defsym,_end=end \ -Wl,--defsym,_edata=__data_end__ \ - -Wl,--defsym,_etext=etext -Wl,--base-file,base.tmp \ - ntoskrnl.o + -Wl,--defsym,_end=__bss_end__ \ + -Wl,--defsym,_etext=etext -Wl,--base-file,base.tmp ntoskrnl.o - $(RM) junk.tmp $(DLLTOOL) --dllname ntoskrnl.exe --base-file base.tmp \ --output-exp temp.exp --def ntoskrnl.def - $(RM) base.tmp - $(CC) -specs=../specs -mdll -o ntoskrnl.exe ntoskrnl.o \ + $(CC) -Wl,-d -specs=../specs -mdll -o ntoskrnl.exe ntoskrnl.o \ -Wl,--image-base,0xc0000000 \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ - -Wl,--defsym,_end=end \ + -Wl,--defsym,_end=__bss_end__ \ -Wl,--defsym,_edata=__data_end__ \ -Wl,--defsym,_etext=etext -Wl,temp.exp - $(RM) temp.exp diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index 9c58bab2611..66f024b7a2f 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -118,6 +118,7 @@ static MEMORY_AREA* MmInternalOpenMemoryAreaByAddress(PLIST_ENTRY ListHead, { PLIST_ENTRY current_entry; MEMORY_AREA* current; + PLIST_ENTRY previous_entry; // MmDumpMemoryAreas(); @@ -129,10 +130,16 @@ static MEMORY_AREA* MmInternalOpenMemoryAreaByAddress(PLIST_ENTRY ListHead, return(NULL); } + previous_entry = ListHead; current_entry = ListHead->Flink; while (current_entry!=ListHead) { current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + DPRINT("Scanning %x BaseAddress %x Length %x\n", + current, current->BaseAddress, current->Length); + assert(current_entry->Blink->Flink == current_entry); + assert(current_entry->Flink->Blink == current_entry); + assert(previous_entry->Flink == current_entry); if (current->BaseAddress <= Address && (current->BaseAddress + current->Length) > Address) { @@ -144,6 +151,7 @@ static MEMORY_AREA* MmInternalOpenMemoryAreaByAddress(PLIST_ENTRY ListHead, DPRINT("%s() = NULL\n",__FUNCTION__); return(NULL); } + previous_entry = current_entry; current_entry = current_entry->Flink; } DPRINT("%s() = NULL\n",__FUNCTION__); @@ -307,13 +315,14 @@ static VOID MmInsertMemoryAreaWithoutLock(PEPROCESS Process, current_entry->Flink = inserted_entry; inserted_entry->Flink=ListHead; inserted_entry->Blink=current_entry; + ListHead->Blink = inserted_entry; return; } if (current->BaseAddress < marea->BaseAddress && next->BaseAddress > marea->BaseAddress) { inserted_entry->Flink = current_entry->Flink; - inserted_entry->Blink = current_entry->Blink; + inserted_entry->Blink = current_entry; inserted_entry->Flink->Blink = inserted_entry; current_entry->Flink=inserted_entry; return; @@ -399,7 +408,20 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process, DPRINT("MmFreeMemoryArea(Process %x, BaseAddress %x, Length %x," "FreePages %d)\n",Process,BaseAddress,Length,FreePages); - + + if (SystemAreaList.Flink != (&SystemAreaList) && + SystemAreaList.Flink->Flink != (&SystemAreaList)) + { + #ifndef NDEBUG + PMEMORY_AREA Snd = CONTAINING_RECORD(SystemAreaList.Flink->Flink, + MEMORY_AREA, + Entry); + DPRINT("SystemAreaList.Flink->Flink->BaseAddress %x\n", + Snd->BaseAddress); + #endif +// assert(Snd->BaseAddress == (PVOID)0x0c001c000); + } + MmLockMemoryAreaList(BaseAddress, &oldlvl); MemoryArea = MmOpenMemoryAreaByAddressWithoutLock(Process, @@ -407,6 +429,7 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process, if (MemoryArea==NULL) { MmUnlockMemoryAreaList(BaseAddress, &oldlvl); + KeBugCheck(0); return(STATUS_UNSUCCESSFUL); } if (FreePages) @@ -429,6 +452,20 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process, RemoveEntryList(&(MemoryArea->Entry)); ExFreePool(MemoryArea); MmUnlockMemoryAreaList(BaseAddress, &oldlvl); + + if (SystemAreaList.Flink != (&SystemAreaList) && + SystemAreaList.Flink->Flink != (&SystemAreaList)) + { + #ifndef NDEBUG + PMEMORY_AREA Snd = CONTAINING_RECORD(SystemAreaList.Flink->Flink, + MEMORY_AREA, + Entry); + DPRINT("SystemAreaList.Flink->Flink->BaseAddress %x\n", + Snd->BaseAddress); + #endif +// assert(Snd->BaseAddress == (PVOID)0x0c001c000); + } + return(STATUS_SUCCESS); } @@ -507,7 +544,19 @@ NTSTATUS MmCreateMemoryArea(KPROCESSOR_MODE Mode, "*BaseAddress %x, Length %x, Attributes %x, Result %x)\n", Mode,Type,BaseAddress,*BaseAddress,Length,Attributes,Result); - + if (SystemAreaList.Flink != (&SystemAreaList) && + SystemAreaList.Flink->Flink != (&SystemAreaList)) + { + #ifndef NDEBUG + PMEMORY_AREA Snd = CONTAINING_RECORD(SystemAreaList.Flink->Flink, + MEMORY_AREA, + Entry); + DPRINT("SystemAreaList.Flink->Flink->BaseAddress %x\n", + Snd->BaseAddress); +// assert(Snd->BaseAddress == (PVOID)0x0c001c000); + #endif + } + if ((*BaseAddress)==0) { MmLockMemoryAreaListByMode(Mode,&oldlvl); @@ -551,6 +600,18 @@ NTSTATUS MmCreateMemoryArea(KPROCESSOR_MODE Mode, MmInsertMemoryAreaWithoutLock(Process,*Result); MmUnlockMemoryAreaList(*BaseAddress,&oldlvl); + if (SystemAreaList.Flink != (&SystemAreaList) && + SystemAreaList.Flink->Flink != (&SystemAreaList)) + { + #ifndef NDEBUG + PMEMORY_AREA Snd = CONTAINING_RECORD(SystemAreaList.Flink->Flink, + MEMORY_AREA, + Entry); + DPRINT("SystemAreaList.Flink->Flink->BaseAddress %x\n", + Snd->BaseAddress); + #endif +// assert(Snd->BaseAddress == (PVOID)0x0c001c000); + } return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index 2c05a42d569..3873746204e 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -50,12 +50,14 @@ PVOID MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode) ULONG* mdl_pages=NULL; MEMORY_AREA* Result; + DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode); + DPRINT("Mdl->ByteCount %x\n",Mdl->ByteCount); DPRINT("PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE) %x\n", PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE); MmCreateMemoryArea(KernelMode, - PsGetCurrentProcess(), + NULL, MEMORY_AREA_MDL_MAPPING, &base, Mdl->ByteCount + Mdl->ByteOffset, @@ -85,8 +87,12 @@ VOID MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl) * MemoryDescriptorList = MDL describing the mapped pages */ { - (void)MmFreeMemoryArea(PsGetCurrentProcess(),BaseAddress-Mdl->ByteOffset, - Mdl->ByteCount,FALSE); + DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", Mdl, BaseAddress); + (void)MmFreeMemoryArea(NULL, + BaseAddress-Mdl->ByteOffset, + Mdl->ByteCount, + FALSE); + DPRINT("MmUnmapLockedPages() finished\n"); } VOID MmPrepareMdlForReuse(PMDL Mdl) @@ -118,7 +124,7 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode, DPRINT("MmProbeAndLockPages(Mdl %x)\n",Mdl); DPRINT("StartVa %x\n",Mdl->StartVa); - marea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(), + marea = MmOpenMemoryAreaByAddress(Mdl->Process, Mdl->StartVa); DPRINT("marea %x\n",marea); @@ -203,11 +209,14 @@ PVOID MmGetSystemAddressForMdl(PMDL Mdl) * pages described by the given MDL. */ { + DPRINT("MmGetSystemAddressForMdl(Mdl %x)\n", Mdl); + if (!( (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) || (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) )) { Mdl->MappedSystemVa = MmMapLockedPages(Mdl,KernelMode); } + DPRINT("Returning %x\n",Mdl->MappedSystemVa); return(Mdl->MappedSystemVa); } diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index 5096bf14f77..e955cbf1fb4 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -10,6 +10,7 @@ /* INCLUDES *****************************************************************/ +#include #include #include #include @@ -43,7 +44,7 @@ static BOOLEAN IsThisAnNtAsSystem = FALSE; static MM_SYSTEM_SIZE MmSystemSize = MmSmallSystem; extern unsigned int etext; -extern unsigned int end; +extern unsigned int _bss_end__; static MEMORY_AREA* kernel_text_desc = NULL; static MEMORY_AREA* kernel_data_desc = NULL; @@ -52,7 +53,7 @@ static MEMORY_AREA* kernel_pool_desc = NULL; /* FUNCTIONS ****************************************************************/ -void VirtualInit(boot_param* bp) +VOID MmInitVirtualMemory(boot_param* bp) /* * FUNCTION: Intialize the memory areas list * ARGUMENTS: @@ -65,7 +66,7 @@ void VirtualInit(boot_param* bp) ULONG Length; ULONG ParamLength = kernel_len; - DPRINT("VirtualInit() %x\n",bp); + DPRINT("MmInitVirtualMemory(%x)\n",bp); MmInitMemoryAreas(); ExInitNonPagedPool(KERNEL_BASE+ PAGE_ROUND_UP(kernel_len) + PAGESIZE); @@ -80,10 +81,12 @@ void VirtualInit(boot_param* bp) MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress, Length,0,&kernel_text_desc); - Length = PAGE_ROUND_UP(((ULONG)&end)) - PAGE_ROUND_UP(((ULONG)&etext)); + Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) - + PAGE_ROUND_UP(((ULONG)&etext)); ParamLength = ParamLength - Length; DPRINT("Length %x\n",Length); BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&etext)); + DPRINT("BaseAddress %x\n",BaseAddress); MmCreateMemoryArea(KernelMode, NULL, MEMORY_AREA_SYSTEM, @@ -92,7 +95,6 @@ void VirtualInit(boot_param* bp) 0, &kernel_data_desc); - BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&end)); Length = ParamLength; MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress, @@ -106,6 +108,8 @@ void VirtualInit(boot_param* bp) // MmDumpMemoryAreas(); CHECKPOINT; +// while (inb_p(0x60)!=0x1); inb_p(0x60); + MmInitSectionImplementation(); } @@ -173,9 +177,9 @@ asmlinkage int page_fault_handler(unsigned int cs, cr2 = PAGE_ROUND_DOWN(cr2); - if (KeGetCurrentIrql() != PASSIVE_LEVEL) + if (KeGetCurrentIrql() >= DISPATCH_LEVEL) { - DbgPrint("Page fault at high IRQL\n"); + DbgPrint("Page fault at high IRQL was %d\n", KeGetCurrentIrql()); return(0); // KeBugCheck(0); } @@ -307,8 +311,9 @@ void MmInitialize(boot_param* bp, ULONG LastKernelAddress) MmSetPage(NULL, (PVOID)(i), PAGE_NOACCESS, 0); } DPRINT("Almost done MmInit()\n"); + /* * Intialize memory areas */ - VirtualInit(bp); + MmInitVirtualMemory(bp); } diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index c73767391cc..3875c2f76d7 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -27,17 +27,17 @@ NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea) { - ULONG i; - PHYSICAL_ADDRESS addr; + PVOID i; DPRINT("MmReleaseMemoryArea(Process %x, Marea %x)\n",Process,Marea); DPRINT("Releasing %x between %x %x\n", Marea, Marea->BaseAddress, Marea->BaseAddress + Marea->Length); - for (i=Marea->BaseAddress; i<(Marea->BaseAddress + Marea->Length); - i=i+PAGESIZE) + for (i = Marea->BaseAddress; + i < (Marea->BaseAddress + Marea->Length); + i = i+PAGESIZE) { - MmDeletePageEntry(Process, (PVOID)i, TRUE); + MmDeletePageEntry(Process, i, TRUE); } ExFreePool(Marea); @@ -46,7 +46,6 @@ NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea) NTSTATUS MmReleaseMmInfo(PEPROCESS Process) { - ULONG i,j,addr; PLIST_ENTRY CurrentEntry; PMEMORY_AREA Current; diff --git a/reactos/ntoskrnl/nt/port.c b/reactos/ntoskrnl/nt/port.c index 3a38cfa079d..c19f0137566 100644 --- a/reactos/ntoskrnl/nt/port.c +++ b/reactos/ntoskrnl/nt/port.c @@ -182,8 +182,8 @@ NTSTATUS STDCALL NtListenPort(HANDLE PortHandle, MmUnmapLockedPages(Data, KMsg->Mdl); Status = ObCreateHandle(PsGetCurrentProcess(), KMsg->ReplyPort, - FALSE, STANDARD_RIGHTS_REQUIRED, + FALSE, &Msg->ReplyPort); ObDereferenceObject(PortHandle); return(Status); diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index e2e4f5f8fbd..d9984829b1f 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -1,10 +1,70 @@ EXPORTS -CbInitDccb -CbAcquireForRead -CbReleaseFromRead DbgPrint +ExAcquireResourceExclusive +ExAcquireResourceExclusiveLite +ExAcquireResourceSharedLite +ExAcquireSharedStarveExclusive +ExAcquireSharedWaitForExclusive +ExAllocateFromNPagedLookasideList +ExAllocateFromPagedLookasideList +ExAllocateFromZone ExAllocatePool +ExAllocatePoolWithQuota +;ExAllocatePoolWithQuotaTag +ExAllocatePoolWithTag +ExConvertExclusiveToSharedLite +ExDeleteNPagedLookasideList +ExDeletePagedLookasideList +ExDeleteResource +ExDeleteResourceLite +ExExtendZone ExFreePool +ExFreeToNPagedLookasideList +ExFreeToPagedLookasideList +ExFreeToZone +ExGetCurrentResourceThread +ExGetExclusiveWaiterCount +ExGetSharedWaiterCount +ExInitializeFastMutex +ExInitializeNPagedLookasideList +ExInitializePagedLookasideList +ExInitializeResource +ExInitializeResourceLite +ExInitializeSListHead +ExInitializeWorkItem +ExInitializeZone +ExInterlockedAddLargeInteger +ExInterlockedAddUlong +ExInterlockedAllocateFromZone +ExInterlockedDecrementLong +ExInterlockedExchangeUlong +ExInterlockedExtendZone +ExInterlockedFreeToZone +ExInterlockedIncrementLong +ExInterlockedInsertHeadList +ExInterlockedInsertTailList +ExInterlockedPopEntryList +ExInterlockedPopEntrySList +ExInterlockedPushEntryList +ExInterlockedPushEntrySList +ExInterlockedRemoveHeadList +ExIsFullZone +ExIsObjectInFirstZoneSegment +ExIsResourceAcquiredExclusiveLite +ExIsResourceAcquiredSharedLite +ExLocalTimeToSystemTime +ExQueryDepthSListHead +ExQueueWorkItem +ExRaiseStatus +ExReinitializeResourceLite +ExReleaseFastMutex +ExReleaseFastMutexUnsafe +ExReleaseResource +ExReleaseResourceForThread +ExReleaseResourceForThreadLite +ExSystemTimeToLocalTime +ExTryToAcquireFastMutex +ExTryToAcquireResourceExclusiveLite HalGetInterruptVector KeBugCheck KeBugCheckEx @@ -27,6 +87,7 @@ IoCompleteRequest IoConnectInterrupt IoCreateController IoCreateDevice +IoCreateStreamFileObject IoCreateSymbolicLink IoDeleteController IoDisconnectInterrupt @@ -58,6 +119,10 @@ RtlTimeFieldsToTime RtlTimeToTimeFields RtlZeroMemory ZwCreateDirectoryObject@12 +CcInitializeFileCache +CcRequestCachePage +CcReleaseCachePage +CcReleaseFileCache isdigit islower isprint diff --git a/reactos/ntoskrnl/ob/handle.c b/reactos/ntoskrnl/ob/handle.c index a20a4736f89..5d649b24918 100644 --- a/reactos/ntoskrnl/ob/handle.c +++ b/reactos/ntoskrnl/ob/handle.c @@ -60,7 +60,7 @@ static PHANDLE_REP ObpGetObjectByHandle(PEPROCESS Process, for (i=0;iFlink; - if (current==(&(Process->Pcb.HandleTable.ListHead))) + if (current == (&(Process->Pcb.HandleTable.ListHead))) { return(NULL); } @@ -122,6 +122,8 @@ NTSTATUS STDCALL ZwDuplicateObject(IN HANDLE SourceProcessHandle, PEPROCESS SourceProcess; PEPROCESS TargetProcess; PHANDLE_REP SourceHandleRep; + + ASSERT_IRQL(PASSIVE_LEVEL); ObReferenceObjectByHandle(SourceProcessHandle, PROCESS_DUP_HANDLE, @@ -340,18 +342,30 @@ NTSTATUS ObReferenceObjectByHandle(HANDLE Handle, DPRINT("Referencing current process %x\n", PsGetCurrentProcess()); return(STATUS_SUCCESS); } + else if (Handle == NtCurrentProcess()) + { + CHECKPOINT; + return(STATUS_OBJECT_TYPE_MISMATCH); + } if (Handle == NtCurrentThread() && (ObjectType == PsThreadType || ObjectType == NULL)) { BODY_TO_HEADER(PsGetCurrentThread())->RefCount++; *Object = PsGetCurrentThread(); + CHECKPOINT; return(STATUS_SUCCESS); } + else if (Handle == NtCurrentThread()) + { + CHECKPOINT; + return(STATUS_OBJECT_TYPE_MISMATCH); + } HandleRep = ObpGetObjectByHandle(PsGetCurrentProcess(), Handle); if (HandleRep == NULL || HandleRep->ObjectBody == NULL) { + CHECKPOINT; return(STATUS_INVALID_HANDLE); } @@ -359,11 +373,13 @@ NTSTATUS ObReferenceObjectByHandle(HANDLE Handle, if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType) { + CHECKPOINT; return(STATUS_OBJECT_TYPE_MISMATCH); } if (!(HandleRep->GrantedAccess & DesiredAccess)) { + CHECKPOINT; return(STATUS_ACCESS_DENIED); } @@ -371,6 +387,7 @@ NTSTATUS ObReferenceObjectByHandle(HANDLE Handle, *Object = HandleRep->ObjectBody; + CHECKPOINT; return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index 2b05283050d..8d3251e1199 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -129,6 +129,8 @@ PVOID ObCreateObject(PHANDLE Handle, POBJECT_HEADER Header; NTSTATUS Status; + assert_irql(PASSIVE_LEVEL); + DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n"); if (ObjectAttributes != NULL && ObjectAttributes->ObjectName != NULL) diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index e85a1a903b9..730ed57bd64 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -49,7 +49,7 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus) ObDereferenceObject(CurrentThread->ThreadsProcess); CurrentThread->ThreadsProcess = NULL; KeRaiseIrql(DISPATCH_LEVEL,&oldlvl); - CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED; + CurrentThread->Tcb.State = THREAD_STATE_TERMINATED; ZwYieldExecution(); for(;;); } diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index fd4def4144c..3fff4cbfd14 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -29,7 +29,7 @@ HANDLE SystemProcessHandle = NULL; POBJECT_TYPE PsProcessType = NULL; -static ULONG NextUniqueProcessId = 0; +static ULONG PiNextProcessUniqueId = 0; /* FUNCTIONS *****************************************************************/ @@ -80,9 +80,8 @@ VOID PsInitProcessManagment(VOID) InitializeListHead(&(KProcess->MemoryAreaList)); ObCreateHandleTable(NULL,FALSE,SystemProcess); KProcess->PageTableDirectory = get_page_directory(); - - SystemProcess->UniqueProcessId = NextUniqueProcessId; - SystemProcess->InheritedFromUniqueProcessId = NextUniqueProcessId; + SystemProcess->UniqueProcessId = + InterlockedIncrement(&PiNextProcessUniqueId); ObCreateHandle(SystemProcess, SystemProcess, @@ -197,12 +196,13 @@ NTSTATUS STDCALL ZwCreateProcess( KProcess = &(Process->Pcb); InitializeListHead(&(KProcess->MemoryAreaList)); - Process->UniqueProcessId = InterlockedIncrement(&NextUniqueProcessId); + Process->UniqueProcessId = InterlockedIncrement(&PiNextProcessUniqueId); Process->InheritedFromUniqueProcessId = ParentProcess->UniqueProcessId; ObCreateHandleTable(ParentProcess, InheritObjectTable, Process); MmCopyMmInfo(ParentProcess, Process); + Process->UniqueProcessId = InterlockedIncrement(&PiNextProcessUniqueId); /* * FIXME: I don't what I'm supposed to know with a section handle diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index bb50c05d3b1..d515c5fd543 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -52,7 +52,7 @@ ULONG PiNrRunnableThreads = 0; static PETHREAD CurrentThread = NULL; -static ULONG NextUniqueThreadId = 0; +static ULONG PiNextThreadUniqueId = 0; /* FUNCTIONS ***************************************************************/ @@ -98,7 +98,8 @@ static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread) KIRQL oldlvl; DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority, - Thread); + Thread); + DPRINT("Offset %x\n", THREAD_PRIORITY_MAX + Priority); KeAcquireSpinLock(&ThreadListLock,&oldlvl); InsertTailList(&PriorityListHead[THREAD_PRIORITY_MAX+Priority], @@ -110,7 +111,7 @@ VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext) { NTSTATUS Ret; - KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL); +// KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL); Ret = StartRoutine(StartContext); PsTerminateSystemThread(Ret); KeBugCheck(0); @@ -130,13 +131,13 @@ static PETHREAD PsScanThreadList(KPRIORITY Priority) { current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.Entry); - if (current->Tcb.ThreadState == THREAD_STATE_TERMINATED && + if (current->Tcb.State == THREAD_STATE_TERMINATED && current != CurrentThread) { PsReleaseThread(current); } - if (current->Tcb.ThreadState == THREAD_STATE_RUNNABLE) + if (current->Tcb.State == THREAD_STATE_RUNNABLE) { if (oldest == NULL || oldest_time > current->Tcb.LastTick) { @@ -166,9 +167,9 @@ VOID PsDispatchThread(VOID) DPRINT("PsDispatchThread() Current %x\n",CurrentThread); - if (CurrentThread->Tcb.ThreadState==THREAD_STATE_RUNNING) + if (CurrentThread->Tcb.State==THREAD_STATE_RUNNING) { - CurrentThread->Tcb.ThreadState=THREAD_STATE_RUNNABLE; + CurrentThread->Tcb.State=THREAD_STATE_RUNNABLE; } for (CurrentPriority=THREAD_PRIORITY_TIME_CRITICAL; @@ -181,7 +182,7 @@ VOID PsDispatchThread(VOID) DPRINT("Scheduling current thread\n"); KeQueryTickCount(&TickCount); CurrentThread->Tcb.LastTick = TickCount.u.LowPart; - CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING; + CurrentThread->Tcb.State = THREAD_STATE_RUNNING; KeReleaseSpinLock(&ThreadListLock,irql); return; } @@ -189,7 +190,7 @@ VOID PsDispatchThread(VOID) { DPRINT("Scheduling %x\n",Candidate); - Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING; + Candidate->Tcb.State = THREAD_STATE_RUNNING; KeQueryTickCount(&TickCount); CurrentThread->Tcb.LastTick = TickCount.u.LowPart; @@ -197,7 +198,7 @@ VOID PsDispatchThread(VOID) CurrentThread = Candidate; HalTaskSwitch(&CurrentThread->Tcb); - KeReleaseSpinLock(&ThreadListLock,irql); + KeReleaseSpinLock(&ThreadListLock, irql); return; } } @@ -222,11 +223,13 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle, PsThreadType); DPRINT("Thread = %x\n",Thread); Thread->Tcb.LastTick = 0; - Thread->Tcb.ThreadState=THREAD_STATE_SUSPENDED; - Thread->Tcb.BasePriority=THREAD_PRIORITY_NORMAL; - Thread->Tcb.CurrentPriority=THREAD_PRIORITY_NORMAL; - Thread->Tcb.ApcList=ExAllocatePool(NonPagedPool,sizeof(LIST_ENTRY)); + Thread->Tcb.State = THREAD_STATE_SUSPENDED; + Thread->Tcb.BasePriority = THREAD_PRIORITY_NORMAL; Thread->Tcb.SuspendCount = 1; + InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[0]); + InitializeListHead(&Thread->Tcb.ApcState.ApcListHead[1]); + Thread->Tcb.KernelApcDisable = 1; + if (ProcessHandle != NULL) { Status = ObReferenceObjectByHandle(ProcessHandle, @@ -253,18 +256,16 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle, PROCESS_CREATE_THREAD, PsProcessType, UserMode); - InitializeListHead(Thread->Tcb.ApcList); InitializeListHead(&(Thread->IrpList)); Thread->Cid.UniqueThread = (HANDLE)InterlockedIncrement( - &NextUniqueThreadId); + &PiNextThreadUniqueId); Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId; - DbgPrint("Thread->Cid.UniqueThread %d\nThread->Cid.UniqueProcess %d\n", - Thread->Cid.UniqueThread, Thread->Cid.UniqueThread); + DbgPrint("Thread->Cid.UniqueThread %d\n",Thread->Cid.UniqueThread); ObReferenceObjectByPointer(Thread, THREAD_ALL_ACCESS, PsThreadType, UserMode); - PsInsertIntoThreadList(Thread->Tcb.CurrentPriority,Thread); + PsInsertIntoThreadList(Thread->Tcb.BasePriority,Thread); *ThreadPtr = Thread; @@ -277,10 +278,10 @@ VOID PsResumeThread(PETHREAD Thread) DPRINT("PsResumeThread(Thread %x)\n",Thread); Thread->Tcb.SuspendCount--; if (Thread->Tcb.SuspendCount <= 0 && - Thread->Tcb.ThreadState != THREAD_STATE_RUNNING) + Thread->Tcb.State != THREAD_STATE_RUNNING) { DPRINT("Setting thread to runnable\n"); - Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE; + Thread->Tcb.State = THREAD_STATE_RUNNABLE; } DPRINT("Finished PsResumeThread()\n"); } @@ -291,7 +292,7 @@ VOID PsSuspendThread(PETHREAD Thread) Thread->Tcb.SuspendCount++; if (Thread->Tcb.SuspendCount > 0) { - Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED; + Thread->Tcb.State = THREAD_STATE_SUSPENDED; if (Thread == CurrentThread) { PsDispatchThread(); @@ -343,7 +344,7 @@ VOID PsInitThreadManagment(VOID) PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle, THREAD_ALL_ACCESS,NULL); HalInitFirstTask(FirstThread); - FirstThread->Tcb.ThreadState = THREAD_STATE_RUNNING; + FirstThread->Tcb.State = THREAD_STATE_RUNNING; FirstThread->Tcb.SuspendCount = 0; DPRINT("FirstThread %x\n",FirstThread); @@ -477,11 +478,11 @@ LONG KeSetBasePriorityThread(PKTHREAD Thread, LONG Increment) KPRIORITY KeSetPriorityThread(PKTHREAD Thread, KPRIORITY Priority) { KPRIORITY OldPriority; - OldPriority = Thread->CurrentPriority; - Thread->CurrentPriority = Priority; + OldPriority = Thread->BasePriority; + Thread->BasePriority = Priority; RemoveEntryList(&Thread->Entry); - PsInsertIntoThreadList(Thread->CurrentPriority, + PsInsertIntoThreadList(Thread->BasePriority, CONTAINING_RECORD(Thread,ETHREAD,Tcb)); return(OldPriority); @@ -576,7 +577,7 @@ NTSTATUS STDCALL ZwResumeThread(IN HANDLE ThreadHandle, (*SuspendCount) = InterlockedDecrement(&Thread->Tcb.SuspendCount); if (Thread->Tcb.SuspendCount <= 0) { - Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE; + Thread->Tcb.State = THREAD_STATE_RUNNABLE; } ObDereferenceObject(Thread); @@ -634,7 +635,7 @@ NTSTATUS STDCALL ZwSuspendThread(IN HANDLE ThreadHandle, (*PreviousSuspendCount) = InterlockedIncrement(&Thread->Tcb.SuspendCount); if (Thread->Tcb.SuspendCount > 0) { - Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED; + Thread->Tcb.State = THREAD_STATE_SUSPENDED; if (Thread == PsGetCurrentThread()) { PsDispatchThread(); diff --git a/reactos/ntoskrnl/rtl/strtok.c b/reactos/ntoskrnl/rtl/strtok.c index 4f18a67d3bb..535c1c70456 100644 --- a/reactos/ntoskrnl/rtl/strtok.c +++ b/reactos/ntoskrnl/rtl/strtok.c @@ -23,8 +23,7 @@ char* strtok(char *s, const char *delim) int c, sc; char *tok; static char *last; - - + if (s == NULL && (s = last) == NULL) return (NULL); diff --git a/reactos/rules.mak b/reactos/rules.mak index 1e46fbecf2a..ff9c75e6715 100644 --- a/reactos/rules.mak +++ b/reactos/rules.mak @@ -70,6 +70,8 @@ CPP = $(PREFIX)cpp AR = $(PREFIX)ar RC = $(PREFIX)windres +%.o: %.cc + $(CC) $(CFLAGS) -c $< -o $@ %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ %.o: %.asm diff --git a/reactos/subsys/win32k/makefile b/reactos/subsys/win32k/makefile index 2413bcc0a59..f98ad919736 100644 --- a/reactos/subsys/win32k/makefile +++ b/reactos/subsys/win32k/makefile @@ -10,7 +10,7 @@ OBJECTS = $(MAIN_OBJECTS) $(STUBS_OBJECTS) $(RESOURCE_OBJECT) 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 \ -- 2.17.1