diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 98a3c6092db..fb90fdced84 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,49 @@ +2002-06-11 David Welch + + * subsys/system/winlogon/winlogon.c (WinMain): Check for + failure when creating a window system. + +2002-06-11 David Welch + + * ntoskrnl/ob/handle.c (ObDuplicateObject): Added this internal + function for duplicating objects. + * ntoskrnl/ps/process.c (NtCreateProcess): Duplicate the parent + process's window station to the child process. + * ntoskrnl/ps/process.c (PsInitProcessManagement): Initialize the + first process's window station. + +2002-06-11 David Welch + + * ntoskrnl/mm/marea.c (MmCreateMemoryArea): Initialise + page operation structure members. + * ntoskrnl/mm/pageop.c (MmReleasePageOp, MmGetPageOp): Increment + or decrement the page operation count in the memory area. + * ntoskrnl/mm/virtual.c (MmNotPresentFaultVirtualMemory, + MmPageOutVirtualMemory): Check for a deleted memory area before + handling the fault. + * ntoskrnl/mm/virtual.c (MmFreeVirtualMemory): Wait for all + page operations to finish before freeing the memory area. + +2002-06-11 David Welch + + * ntoskrnl/ke/i386/syscall.S (interrupt_handler2e): Corrected + test for previous mode, upper 16-bit of CS on the stack after an + interrupt are arbitary. + +2002-06-11 David Welch + + * lib/user32/misc/winsta.c: Cleaned up indentation. + +2002-06-11 David Welch + + * apps/tests/winhello/winhello.c (WinMain, MainWndProc): + Cleaned up formatting, some more error checks. + +2002-06-04 David Welch + + * ntoskrnl/mm/virtual.c (MmSecureVirtualMemory, + MmUnsecureVirtualMemory, NtQueryVirtualMemory): Corrected indentation. + 2002-06-04 David Welch * ntoskrnl/ke/i386/exp.c (KiDoubleFaultHandler): Print CR3 diff --git a/reactos/apps/tests/winhello/winhello.c b/reactos/apps/tests/winhello/winhello.c index c02321cb179..9c87f7eb414 100644 --- a/reactos/apps/tests/winhello/winhello.c +++ b/reactos/apps/tests/winhello/winhello.c @@ -1,11 +1,13 @@ #include +#include LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpszCmdLine, - int nCmdShow) +int WINAPI +WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) { WNDCLASS wc; MSG msg; @@ -21,21 +23,30 @@ int WINAPI WinMain(HINSTANCE hInstance, wc.lpszMenuName = NULL; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - RegisterClass(&wc); + if (RegisterClass(&wc) == 0) + { + fprintf(stderr, "RegisterClass failed (last error 0x%X)\n", + GetLastError()); + return(1); + } - hWnd = CreateWindow - ( "HelloClass", - "Hello World", - WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, - 0, - 0, - CW_USEDEFAULT, - CW_USEDEFAULT, - NULL, - NULL, - hInstance, - NULL - ); + hWnd = CreateWindow("HelloClass", + "Hello World", + WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, + 0, + 0, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + hInstance, + NULL); + if (hWnd == NULL) + { + fprintf(stderr, "CreateWindow failed (last error 0x%X)\n", + GetLastError()); + return(1); + } ShowWindow(hWnd, nCmdShow); @@ -57,7 +68,8 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { case WM_PAINT: hDC = BeginPaint(hWnd, &ps); - TextOut(hDC, 10, 10, "Hello World from ReactOS!", strlen("Hello World from ReactOS!")); + TextOut(hDC, 10, 10, "Hello World from ReactOS!", + strlen("Hello World from ReactOS!")); EndPaint(hWnd, &ps); break; diff --git a/reactos/install.bochs b/reactos/install.bochs index 5204b982522..ea4cf2e73b2 100644 --- a/reactos/install.bochs +++ b/reactos/install.bochs @@ -2,5 +2,16 @@ /sbin/modprobe loop echo "Installing to disk." mount -t vfat /mnt/hda3/bochs/10M.vga.dos /mnt/floppy -o loop,offset=8704,rw -cp -rv reactos/system32 /mnt/floppy/reactos +cp -rv reactos /mnt/floppy umount /mnt/floppy + + + + + + + + + + + diff --git a/reactos/lib/user32/misc/winsta.c b/reactos/lib/user32/misc/winsta.c index 1075bd2428e..70d26ba1935 100644 --- a/reactos/lib/user32/misc/winsta.c +++ b/reactos/lib/user32/misc/winsta.c @@ -1,4 +1,4 @@ -/* $Id: winsta.c,v 1.2 2001/06/29 19:31:59 ekohl Exp $ +/* $Id: winsta.c,v 1.3 2002/06/11 22:09:01 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -13,121 +13,111 @@ #include -WINBOOL -STDCALL -CloseWindowStation( - HWINSTA hWinSta) +WINBOOL STDCALL +CloseWindowStation(HWINSTA hWinSta) { - return NtUserCloseWindowStation(hWinSta); + return(NtUserCloseWindowStation(hWinSta)); } -HWINSTA -STDCALL -CreateWindowStationA( - LPSTR lpwinsta, - DWORD dwReserved, - ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpsa) +HWINSTA STDCALL +CreateWindowStationA(LPSTR lpwinsta, + DWORD dwReserved, + ACCESS_MASK dwDesiredAccess, + LPSECURITY_ATTRIBUTES lpsa) { ANSI_STRING WindowStationNameA; UNICODE_STRING WindowStationNameU; HWINSTA hWinSta; + + if (lpwinsta != NULL) + { + RtlInitAnsiString(&WindowStationNameA, lpwinsta); + RtlAnsiStringToUnicodeString(&WindowStationNameU, &WindowStationNameA, + TRUE); + } + else + { + RtlInitUnicodeString(&WindowStationNameU, NULL); + } - if (lpwinsta != NULL) { - RtlInitAnsiString(&WindowStationNameA, lpwinsta); - RtlAnsiStringToUnicodeString(&WindowStationNameU, &WindowStationNameA, TRUE); - } else { - RtlInitUnicodeString(&WindowStationNameU, NULL); - } - - hWinSta = CreateWindowStationW( - WindowStationNameU.Buffer, - dwReserved, - dwDesiredAccess, - lpsa); - - RtlFreeUnicodeString(&WindowStationNameU); + hWinSta = CreateWindowStationW(WindowStationNameU.Buffer, + dwReserved, + dwDesiredAccess, + lpsa); + RtlFreeUnicodeString(&WindowStationNameU); + return hWinSta; } -HWINSTA -STDCALL -CreateWindowStationW( - LPWSTR lpwinsta, - DWORD dwReserved, - ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpsa) +HWINSTA STDCALL +CreateWindowStationW(LPWSTR lpwinsta, + DWORD dwReserved, + ACCESS_MASK dwDesiredAccess, + LPSECURITY_ATTRIBUTES lpsa) { UNICODE_STRING WindowStationName; - + RtlInitUnicodeString(&WindowStationName, lpwinsta); - - return NtUserCreateWindowStation( - &WindowStationName, - dwDesiredAccess, - lpsa, 0, 0, 0); + + return NtUserCreateWindowStation(&WindowStationName, + dwDesiredAccess, + lpsa, 0, 0, 0); } -WINBOOL -STDCALL -EnumWindowStationsA( - ENUMWINDOWSTATIONPROC lpEnumFunc, - LPARAM lParam) +WINBOOL STDCALL +EnumWindowStationsA(ENUMWINDOWSTATIONPROC lpEnumFunc, + LPARAM lParam) { return FALSE; } -WINBOOL -STDCALL -EnumWindowStationsW( - ENUMWINDOWSTATIONPROC lpEnumFunc, - LPARAM lParam) +WINBOOL STDCALL +EnumWindowStationsW(ENUMWINDOWSTATIONPROC lpEnumFunc, + LPARAM lParam) { return FALSE; } -HWINSTA -STDCALL +HWINSTA STDCALL GetProcessWindowStation(VOID) { return NtUserGetProcessWindowStation(); } -HWINSTA -STDCALL -OpenWindowStationA( - LPSTR lpszWinSta, - WINBOOL fInherit, - ACCESS_MASK dwDesiredAccess) +HWINSTA STDCALL +OpenWindowStationA(LPSTR lpszWinSta, + WINBOOL fInherit, + ACCESS_MASK dwDesiredAccess) { ANSI_STRING WindowStationNameA; UNICODE_STRING WindowStationNameU; HWINSTA hWinSta; - - if (lpszWinSta != NULL) { - RtlInitAnsiString(&WindowStationNameA, lpszWinSta); - RtlAnsiStringToUnicodeString(&WindowStationNameU, &WindowStationNameA, TRUE); - } else { - RtlInitUnicodeString(&WindowStationNameU, NULL); - } - - hWinSta = OpenWindowStationW( - WindowStationNameU.Buffer, - fInherit, - dwDesiredAccess); - - RtlFreeUnicodeString(&WindowStationNameU); - + + if (lpszWinSta != NULL) + { + RtlInitAnsiString(&WindowStationNameA, lpszWinSta); + RtlAnsiStringToUnicodeString(&WindowStationNameU, &WindowStationNameA, + TRUE); + } + else + { + RtlInitUnicodeString(&WindowStationNameU, NULL); + } + + hWinSta = OpenWindowStationW(WindowStationNameU.Buffer, + fInherit, + dwDesiredAccess); + + RtlFreeUnicodeString(&WindowStationNameU); + return hWinSta; } -HWINSTA -STDCALL -OpenWindowStationW( - LPWSTR lpszWinSta, - WINBOOL fInherit, - ACCESS_MASK dwDesiredAccess) +HWINSTA STDCALL +OpenWindowStationW(LPWSTR lpszWinSta, + WINBOOL fInherit, + ACCESS_MASK dwDesiredAccess) { UNICODE_STRING WindowStationName; @@ -136,10 +126,8 @@ OpenWindowStationW( return NtUserOpenWindowStation(&WindowStationName, dwDesiredAccess); } -WINBOOL -STDCALL -SetProcessWindowStation( - HWINSTA hWinSta) +WINBOOL STDCALL +SetProcessWindowStation(HWINSTA hWinSta) { return NtUserSetProcessWindowStation(hWinSta); } diff --git a/reactos/lib/user32/windows/class.c b/reactos/lib/user32/windows/class.c index bb7c5d96347..43dd0b2eef7 100644 --- a/reactos/lib/user32/windows/class.c +++ b/reactos/lib/user32/windows/class.c @@ -1,4 +1,4 @@ -/* $Id: class.c,v 1.9 2001/06/12 17:50:27 chorns Exp $ +/* $Id: class.c,v 1.10 2002/06/11 22:09:01 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -151,10 +151,8 @@ RealGetWindowClassW( return 0; } -ATOM -STDCALL -RegisterClassA( - CONST WNDCLASS *lpWndClass) +ATOM STDCALL +RegisterClassA(CONST WNDCLASS *lpWndClass) { WNDCLASSEX Class; @@ -164,10 +162,8 @@ RegisterClassA( return RegisterClassExA(&Class); } -ATOM -STDCALL -RegisterClassExA( - CONST WNDCLASSEX *lpwcx) +ATOM STDCALL +RegisterClassExA(CONST WNDCLASSEX *lpwcx) { UNICODE_STRING MenuName; UNICODE_STRING ClassName; @@ -179,58 +175,52 @@ RegisterClassExA( SetLastError(ERROR_NOT_ENOUGH_MEMORY); return (ATOM)0; } - + if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, (PCSZ)lpwcx->lpszMenuName)) - { - RtlFreeUnicodeString(&MenuName); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return (ATOM)0; - } - + { + RtlFreeUnicodeString(&MenuName); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return (ATOM)0; + } + RtlMoveMemory(&Class, lpwcx, sizeof(WNDCLASSEX)); Class.lpszMenuName = (LPCTSTR)MenuName.Buffer; Class.lpszClassName = (LPCTSTR)ClassName.Buffer; - Atom = NtUserRegisterClassExWOW( - (WNDCLASSEX*)lpwcx, - FALSE, - 0, - 0, - 0, - 0); - + Atom = NtUserRegisterClassExWOW((WNDCLASSEX*)lpwcx, + FALSE, + 0, + 0, + 0, + 0); + RtlFreeUnicodeString(&ClassName); - + RtlFreeUnicodeString(&MenuName); - + return (ATOM)Atom; } -ATOM -STDCALL -RegisterClassExW( - CONST WNDCLASSEX *lpwcx) +ATOM STDCALL +RegisterClassExW(CONST WNDCLASSEX *lpwcx) { RTL_ATOM Atom; - - Atom = NtUserRegisterClassExWOW( - (WNDCLASSEX*)lpwcx, - TRUE, - 0, - 0, - 0, - 0); - + + Atom = NtUserRegisterClassExWOW((WNDCLASSEX*)lpwcx, + TRUE, + 0, + 0, + 0, + 0); + return (ATOM)Atom; } -ATOM -STDCALL -RegisterClassW( - CONST WNDCLASS *lpWndClass) +ATOM STDCALL +RegisterClassW(CONST WNDCLASS *lpWndClass) { WNDCLASSEX Class; - + RtlMoveMemory(&Class.style, lpWndClass, sizeof(WNDCLASS)); Class.cbSize = sizeof(WNDCLASSEX); Class.hIconSm = INVALID_HANDLE_VALUE; diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 768b4231e8e..e5dd92c4750 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -119,28 +119,30 @@ typedef struct typedef struct { - ULONG Type; - PVOID BaseAddress; - ULONG Length; - ULONG Attributes; - LIST_ENTRY Entry; - ULONG LockCount; - struct _EPROCESS* Process; - union - { - struct - { - SECTION_OBJECT* Section; - ULONG ViewOffset; - LIST_ENTRY ViewListEntry; - PMM_SECTION_SEGMENT Segment; - BOOLEAN WriteCopyView; - } SectionData; - struct - { - LIST_ENTRY SegmentListHead; - } VirtualMemoryData; - } Data; + ULONG Type; + PVOID BaseAddress; + ULONG Length; + ULONG Attributes; + LIST_ENTRY Entry; + ULONG LockCount; + struct _EPROCESS* Process; + BOOLEAN DeleteInProgress; + ULONG PageOpCount; + union + { + struct + { + SECTION_OBJECT* Section; + ULONG ViewOffset; + LIST_ENTRY ViewListEntry; + PMM_SECTION_SEGMENT Segment; + BOOLEAN WriteCopyView; + } SectionData; + struct + { + LIST_ENTRY SegmentListHead; + } VirtualMemoryData; + } Data; } MEMORY_AREA, *PMEMORY_AREA; typedef struct _MADDRESS_SPACE @@ -520,7 +522,8 @@ VOID MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG* PhysicalAddr); VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address); VOID -MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry); +MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, + SWAPENTRY* SwapEntry); NTSTATUS MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, @@ -532,5 +535,8 @@ VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address); VOID MmInitializeMdlImplementation(VOID); extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress; +PMM_PAGEOP +MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, + PMM_SECTION_SEGMENT Segment, ULONG Offset); #endif diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index fd2a9768f02..b8ad6b79aa0 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -100,5 +100,13 @@ ObpCreateTypeObject(POBJECT_TYPE ObjectType); ULONG ObGetObjectHandleCount(PVOID Object); +NTSTATUS +ObDuplicateObject(PEPROCESS SourceProcess, + PEPROCESS TargetProcess, + HANDLE SourceHandle, + PHANDLE TargetHandle, + ACCESS_MASK DesiredAccess, + BOOLEAN InheritHandle, + ULONG Options); #endif /* __INCLUDE_INTERNAL_OBJMGR_H */ diff --git a/reactos/ntoskrnl/ke/i386/syscall.S b/reactos/ntoskrnl/ke/i386/syscall.S index 3f4b95383a7..6a9702e52cd 100644 --- a/reactos/ntoskrnl/ke/i386/syscall.S +++ b/reactos/ntoskrnl/ke/i386/syscall.S @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: syscall.S,v 1.4 2002/01/15 02:51:32 dwelch Exp $ +/* $Id: syscall.S,v 1.5 2002/06/11 22:09:02 dwelch Exp $ * * FILE: ntoskrnl/hal/x86/syscall.s * PURPOSE: 2E trap handler @@ -63,6 +63,7 @@ _interrupt_handler2e: pushl %ebx /* Set the new previous mode based on the saved CS selector */ movl 0x24(%esp), %ebx + andl $0x0000FFFF, %ebx cmpl $KERNEL_CS, %ebx jne L1 movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi) diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index e06fe1d69c2..6c16cf7a4d0 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -452,6 +452,8 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process, (*Result)->Attributes = Attributes; (*Result)->LockCount = 0; (*Result)->Process = Process; + (*Result)->PageOpCount = 0; + (*Result)->DeleteInProgress = FALSE; MmInsertMemoryArea(AddressSpace, *Result); diff --git a/reactos/ntoskrnl/mm/pageop.c b/reactos/ntoskrnl/mm/pageop.c index 9829e9254d6..01a99c6be7e 100644 --- a/reactos/ntoskrnl/mm/pageop.c +++ b/reactos/ntoskrnl/mm/pageop.c @@ -1,4 +1,4 @@ -/* $Id: pageop.c,v 1.9 2002/05/14 21:19:19 dwelch Exp $ +/* $Id: pageop.c,v 1.10 2002/06/11 22:09:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -45,6 +45,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp) KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); return; } + InterlockedDecrement(&PageOp->MArea->PageOpCount); PrevPageOp = MmPageOpHashTable[PageOp->Hash]; if (PrevPageOp == PageOp) { @@ -68,6 +69,68 @@ MmReleasePageOp(PMM_PAGEOP PageOp) KeBugCheck(0); } +PMM_PAGEOP +MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, + PMM_SECTION_SEGMENT Segment, ULONG Offset) +{ + ULONG Hash; + KIRQL oldIrql; + PMM_PAGEOP PageOp; + + /* + * Calcuate the hash value for pageop structure + */ + if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT) + { + Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGESIZE)); + } + else + { + Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGESIZE)); + } + Hash = Hash % PAGEOP_HASH_TABLE_SIZE; + + KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); + + /* + * Check for an existing pageop structure + */ + PageOp = MmPageOpHashTable[Hash]; + while (PageOp != NULL) + { + if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT) + { + if (PageOp->Segment == Segment && + PageOp->Offset == Offset) + { + break; + } + } + else + { + if (PageOp->Pid == Pid && + PageOp->Address == Address) + { + break; + } + } + PageOp = PageOp->Next; + } + + /* + * If we found an existing pageop then increment the reference count + * and return it. + */ + if (PageOp != NULL) + { + PageOp->ReferenceCount++; + KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); + return(PageOp); + } + KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); + return(NULL); +} + PMM_PAGEOP MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType) @@ -160,8 +223,10 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, PageOp->Abandoned = FALSE; PageOp->Status = STATUS_PENDING; PageOp->OpType = OpType; + PageOp->MArea = MArea; KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE); MmPageOpHashTable[Hash] = PageOp; + InterlockedIncrement(&MArea->PageOpCount); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); return(PageOp); diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index 8455df0f20f..6728a25c530 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -1,4 +1,4 @@ -/* $Id: virtual.c,v 1.60 2002/06/10 21:34:37 hbirr Exp $ +/* $Id: virtual.c,v 1.61 2002/06/11 22:09:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -110,6 +110,14 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n", Address, MemoryArea->Process->UniqueProcessId); + /* + * Check for paging out from a deleted virtual memory area. + */ + if (MemoryArea->DeleteInProgress) + { + return(STATUS_UNSUCCESSFUL); + } + /* * Paging out code or readonly data is easy. */ @@ -241,6 +249,14 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, return(STATUS_SUCCESS); } + /* + * Check for the virtual memory area being deleted. + */ + if (MemoryArea->DeleteInProgress) + { + return(STATUS_UNSUCCESSFUL); + } + /* * Get the segment corresponding to the virtual address */ @@ -1076,9 +1092,53 @@ MmFreeVirtualMemory(PEPROCESS Process, { PLIST_ENTRY current_entry; PMM_SEGMENT current; + ULONG i; - DPRINT("MmFreeVirtualMemory(Process %p MemoryArea %p)\n", Process, MemoryArea); + DPRINT("MmFreeVirtualMemory(Process %p MemoryArea %p)\n", Process, + MemoryArea); + /* Mark this memory area as about to be deleted. */ + MemoryArea->DeleteInProgress = TRUE; + + /* + * Wait for any ongoing paging operations. Notice that since we have + * flagged this memory area as deleted no more page ops will be added. + */ + if (MemoryArea->PageOpCount > 0) + { + for (i = 0; i < (PAGE_ROUND_UP(MemoryArea->Length) / PAGESIZE); i++) + { + PMM_PAGEOP PageOp; + + if (MemoryArea->PageOpCount == 0) + { + break; + } + + PageOp = MmCheckForPageOp(MemoryArea, Process->UniqueProcessId, + MemoryArea->BaseAddress + (i * PAGESIZE), + NULL, 0); + if (PageOp != NULL) + { + NTSTATUS Status; + MmUnlockAddressSpace(&Process->AddressSpace); + Status = KeWaitForSingleObject(&PageOp->CompletionEvent, + 0, + KernelMode, + FALSE, + NULL); + if (Status != STATUS_SUCCESS) + { + DPRINT1("Failed to wait for page op\n"); + KeBugCheck(0); + } + MmLockAddressSpace(&Process->AddressSpace); + MmReleasePageOp(PageOp); + } + } + } + + /* Free all the individual segments. */ current_entry = MemoryArea->Data.VirtualMemoryData.SegmentListHead.Flink; while (current_entry != &MemoryArea->Data.VirtualMemoryData.SegmentListHead) { @@ -1088,6 +1148,7 @@ MmFreeVirtualMemory(PEPROCESS Process, ExFreePool(current); } + /* Actually free the memory area. */ MmFreeMemoryArea(&Process->AddressSpace, MemoryArea->BaseAddress, 0, @@ -1154,21 +1215,13 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle, switch (FreeType) { case MEM_RELEASE: + /* We can only free a memory area in one step. */ if (MemoryArea->BaseAddress != BaseAddress) { MmUnlockAddressSpace(AddressSpace); ObDereferenceObject(Process); return(STATUS_UNSUCCESSFUL); - } -#if 0 - if ((MemoryArea->Type == MEMORY_AREA_COMMIT) && - ((MemoryArea->Attributes & PAGE_READWRITE) || - (MemoryArea->Attributes & PAGE_EXECUTE_READWRITE))) - { - MmDereserveSwapPages(PAGE_ROUND_UP(MemoryArea->Length)); - } -#endif - + } MmFreeVirtualMemory(Process, MemoryArea); MmUnlockAddressSpace(AddressSpace); ObDereferenceObject(Process); @@ -1286,12 +1339,13 @@ NtProtectVirtualMemory(IN HANDLE ProcessHandle, } -NTSTATUS STDCALL NtQueryVirtualMemory (IN HANDLE ProcessHandle, - IN PVOID Address, - IN CINT VirtualMemoryInformationClass, - OUT PVOID VirtualMemoryInformation, - IN ULONG Length, - OUT PULONG ResultLength) +NTSTATUS STDCALL +NtQueryVirtualMemory (IN HANDLE ProcessHandle, + IN PVOID Address, + IN CINT VirtualMemoryInformationClass, + OUT PVOID VirtualMemoryInformation, + IN ULONG Length, + OUT PULONG ResultLength) { NTSTATUS Status; PEPROCESS Process; @@ -1504,26 +1558,20 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle, } -DWORD -STDCALL -MmSecureVirtualMemory ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 - ) +DWORD STDCALL +MmSecureVirtualMemory (DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2) { - UNIMPLEMENTED; - return 0; + UNIMPLEMENTED; + return 0; } -VOID -STDCALL -MmUnsecureVirtualMemory ( - DWORD Unknown0 - ) +VOID STDCALL +MmUnsecureVirtualMemory (DWORD Unknown0) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* EOF */ diff --git a/reactos/ntoskrnl/ob/handle.c b/reactos/ntoskrnl/ob/handle.c index 47ac3fc9b0e..81cdc33d214 100644 --- a/reactos/ntoskrnl/ob/handle.c +++ b/reactos/ntoskrnl/ob/handle.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: handle.c,v 1.37 2002/05/07 22:38:29 hbirr Exp $ +/* $Id: handle.c,v 1.38 2002/06/11 22:09:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -105,14 +105,62 @@ static PHANDLE_REP ObpGetObjectByHandle(PHANDLE_TABLE HandleTable, HANDLE h) return(&(blk->handles[handle%HANDLE_BLOCK_ENTRIES])); } +NTSTATUS +ObDuplicateObject(PEPROCESS SourceProcess, + PEPROCESS TargetProcess, + HANDLE SourceHandle, + PHANDLE TargetHandle, + ACCESS_MASK DesiredAccess, + BOOLEAN InheritHandle, + ULONG Options) +{ + KIRQL oldIrql; + PHANDLE_REP SourceHandleRep; + PVOID ObjectBody; -NTSTATUS STDCALL NtDuplicateObject (IN HANDLE SourceProcessHandle, - IN HANDLE SourceHandle, - IN HANDLE TargetProcessHandle, - OUT PHANDLE UnsafeTargetHandle, - IN ACCESS_MASK DesiredAccess, - IN BOOLEAN InheritHandle, - ULONG Options) + KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql); + SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable, + SourceHandle); + if (SourceHandleRep == NULL) + { + KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql); + return(STATUS_INVALID_HANDLE); + } + ObjectBody = SourceHandleRep->ObjectBody; + ObReferenceObjectByPointer(ObjectBody, + 0, + NULL, + UserMode); + + if (Options & DUPLICATE_SAME_ACCESS) + { + DesiredAccess = SourceHandleRep->GrantedAccess; + } + + KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql); + ObCreateHandle(TargetProcess, + ObjectBody, + DesiredAccess, + InheritHandle, + TargetHandle); + + if (Options & DUPLICATE_CLOSE_SOURCE) + { + ZwClose(SourceHandle); + } + + ObDereferenceObject(ObjectBody); + return(STATUS_SUCCESS); +} + +NTSTATUS STDCALL +NtDuplicateObject (IN HANDLE SourceProcessHandle, + IN HANDLE SourceHandle, + IN HANDLE TargetProcessHandle, + OUT PHANDLE UnsafeTargetHandle, + IN ACCESS_MASK DesiredAccess, + IN BOOLEAN InheritHandle, + ULONG Options) /* * FUNCTION: Copies a handle from one process space to another * ARGUMENTS: @@ -191,15 +239,13 @@ NTSTATUS STDCALL NtDuplicateObject (IN HANDLE SourceProcessHandle, } KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql); - if (!SourceHandleRep->Inherit) - { - ObDereferenceObject(TargetProcess); - ObDereferenceObject(SourceProcess); - ObDereferenceObject(ObjectBody); - return STATUS_INVALID_HANDLE; - } - + { + ObDereferenceObject(TargetProcess); + ObDereferenceObject(SourceProcess); + ObDereferenceObject(ObjectBody); + return STATUS_INVALID_HANDLE; + } ObCreateHandle(TargetProcess, ObjectBody, DesiredAccess, @@ -267,7 +313,7 @@ VOID ObCloseAllHandles(PEPROCESS Process) current->handles[i].ObjectBody = NULL; KeReleaseSpinLock(&HandleTable->ListLock, oldIrql); - KeDetachProcess(); + KeDetachProcess(); if ((Header->ObjectType != NULL) && (Header->ObjectType->Close != NULL)) @@ -277,7 +323,7 @@ VOID ObCloseAllHandles(PEPROCESS Process) } ObDereferenceObject(ObjectBody); - KeAttachProcess( Process ); + KeAttachProcess(Process); KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql); current_entry = &HandleTable->ListHead; break; @@ -370,14 +416,16 @@ VOID ObCreateHandleTable(PEPROCESS Parent, { if (current_block->handles[i].Inherit && Inherit) { - new_block->handles[i].ObjectBody = current_block->handles[i].ObjectBody; - new_block->handles[i].GrantedAccess = current_block->handles[i].GrantedAccess; + new_block->handles[i].ObjectBody = + current_block->handles[i].ObjectBody; + new_block->handles[i].GrantedAccess = + current_block->handles[i].GrantedAccess; new_block->handles[i].Inherit = TRUE; InterlockedIncrement(&(BODY_TO_HEADER(current_block->handles[i].ObjectBody)->HandleCount)); } } } - InsertTailList(&(Process->HandleTable.ListHead), &new_block->entry); + InsertTailList(&Process->HandleTable.ListHead, &new_block->entry); parent_current = parent_current->Flink; } KeReleaseSpinLockFromDpcLevel(&Process->HandleTable.ListLock); diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 37137c63f96..b6ff68272d3 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.80 2002/06/04 15:26:57 dwelch Exp $ +/* $Id: process.c,v 1.81 2002/06/11 22:09:03 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -255,6 +255,7 @@ PsInitProcessManagment(VOID) (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory(); PsInitialSystemProcess->UniqueProcessId = InterlockedIncrement(&PiNextProcessUniqueId); + PsInitialSystemProcess->Win32WindowStation = (HANDLE)0; KeAcquireSpinLock(&PsProcessListLock, &oldIrql); InsertHeadList(&PsProcessListHead, @@ -284,22 +285,24 @@ PiFreeSymbols(PPEB Peb) assert (Peb); assert (Peb->Ldr); - CurrentEntry = Peb->Ldr->InLoadOrderModuleList.Flink; - while ((CurrentEntry != &Peb->Ldr->InLoadOrderModuleList) && (CurrentEntry != NULL)) + CurrentEntry = Peb->Ldr->InLoadOrderModuleList.Flink; + while (CurrentEntry != &Peb->Ldr->InLoadOrderModuleList && + CurrentEntry != NULL) + { + Current = CONTAINING_RECORD(CurrentEntry, LDR_MODULE, + InLoadOrderModuleList); + Symbol = Current->Symbols.Symbols; + while (Symbol != NULL) { - Current = CONTAINING_RECORD (CurrentEntry, LDR_MODULE, InLoadOrderModuleList); - Symbol = Current->Symbols.Symbols; - while (Symbol != NULL) - { - NextSymbol = Symbol->Next; - RtlFreeUnicodeString (&Symbol->Name); - ExFreePool (Symbol); - Symbol = NextSymbol; - } - Current->Symbols.SymbolCount = 0; - Current->Symbols.Symbols = NULL; - CurrentEntry = CurrentEntry->Flink; - } + NextSymbol = Symbol->Next; + RtlFreeUnicodeString (&Symbol->Name); + ExFreePool (Symbol); + Symbol = NextSymbol; + } + Current->Symbols.SymbolCount = 0; + Current->Symbols.Symbols = NULL; + CurrentEntry = CurrentEntry->Flink; + } } #endif /* KDBG */ @@ -515,9 +518,29 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, InheritObjectTable, Process); MmCopyMmInfo(ParentProcess, Process); + if (ParentProcess->Win32WindowStation != (HANDLE)0) + { + /* Always duplicate the process window station. */ + Process->Win32WindowStation = 0; + Status = ObDuplicateObject(ParentProcess, + Process, + ParentProcess->Win32WindowStation, + &Process->Win32WindowStation, + 0, + FALSE, + DUPLICATE_SAME_ACCESS); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(0); + } + } + else + { + Process->Win32WindowStation = (HANDLE)0; + } KeAcquireSpinLock(&PsProcessListLock, &oldIrql); - for (i = 0; i < PiProcessNotifyRoutineCount; i++) + for (i = 0; i < PiProcessNotifyRoutineCount; i++) { PiProcessNotifyRoutine[i](Process->InheritedFromUniqueProcessId, (HANDLE)Process->UniqueProcessId, diff --git a/reactos/subsys/system/winlogon/winlogon.c b/reactos/subsys/system/winlogon/winlogon.c index 1b585ae150c..89485fdd7d4 100644 --- a/reactos/subsys/system/winlogon/winlogon.c +++ b/reactos/subsys/system/winlogon/winlogon.c @@ -1,4 +1,4 @@ -/* $Id: winlogon.c,v 1.8 2002/02/08 02:57:06 chorns Exp $ +/* $Id: winlogon.c,v 1.9 2002/06/11 22:09:03 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -227,6 +227,12 @@ WinMain(HINSTANCE hInstance, */ InteractiveWindowStation = CreateWindowStationW( L"WinSta0", 0, GENERIC_ALL, NULL); + if (InteractiveWindowStation == NULL) + { + DbgPrint("Failed to create window station (0x%X)\n", GetLastError()); + NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, 0, 0, 0); + ExitProcess(1); + } /* * Set the process window station diff --git a/reactos/subsys/win32k/makefile b/reactos/subsys/win32k/makefile index fbc1b86b2c3..47f912c2a82 100644 --- a/reactos/subsys/win32k/makefile +++ b/reactos/subsys/win32k/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.43 2002/05/06 22:20:32 dwelch Exp $ +# $Id: makefile,v 1.44 2002/06/11 22:09:03 dwelch Exp $ PATH_TO_TOP = ../.. @@ -10,10 +10,15 @@ TARGET_BASE = 0x0 TARGET_ENTRY = _DllMain@8 -# from atheos appserver makefile -COPTS = -pipe -O3 -I./freetype/include -c -Wall +include $(PATH_TO_TOP)/config -TARGET_CFLAGS = -I$(PATH_TO_TOP)/ntoskrnl/include -DUNICODE -Wall +ifeq ($(DBG), 1) +CFLAGS_DBG := -g +else +CFLAGS_DBG := +endif + +TARGET_CFLAGS = $(CFLAGS_DBG) -I$(PATH_TO_TOP)/ntoskrnl/include -DUNICODE -Wall ENG_OBJECTS= eng/debug.o eng/mem.o eng/brush.o eng/bitblt.o eng/clip.o \ eng/copybits.o eng/device.o eng/handle.o eng/lineto.o eng/paint.o \ diff --git a/reactos/subsys/win32k/ntuser/class.c b/reactos/subsys/win32k/ntuser/class.c index ab6fb8ee35c..1dd0deb0f2a 100644 --- a/reactos/subsys/win32k/ntuser/class.c +++ b/reactos/subsys/win32k/ntuser/class.c @@ -1,4 +1,4 @@ -/* $Id: class.c,v 1.4 2002/01/27 01:11:24 dwelch Exp $ +/* $Id: class.c,v 1.5 2002/06/11 22:09:03 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -18,7 +18,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include /* FUNCTIONS *****************************************************************/ diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index a142f97307d..59914d9a2f4 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -1,4 +1,4 @@ -/* $Id: winsta.c,v 1.2 2001/06/16 14:11:31 ekohl Exp $ +/* $Id: winsta.c,v 1.3 2002/06/11 22:09:03 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -19,7 +19,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include #define WINSTA_ROOT_NAME L"\\Windows\\WindowStations" @@ -27,7 +27,6 @@ HDESK InputDesktop; /* Currently active desktop */ - NTSTATUS InitWindowStationImpl(VOID) { @@ -37,28 +36,26 @@ InitWindowStationImpl(VOID) NTSTATUS Status; /* - * Create the '\Windows\WindowStations' directory - */ - RtlInitUnicodeString( - &UnicodeString, - WINSTA_ROOT_NAME); + * Create the '\Windows\WindowStations' directory + */ + RtlInitUnicodeString(&UnicodeString, + WINSTA_ROOT_NAME); - InitializeObjectAttributes( - &ObjectAttributes, - &UnicodeString, - 0, - NULL, - NULL); - - Status = ZwCreateDirectoryObject( - &WindowStationsDirectory, - 0, - &ObjectAttributes); + InitializeObjectAttributes(&ObjectAttributes, + &UnicodeString, + 0, + NULL, + NULL); + + Status = ZwCreateDirectoryObject(&WindowStationsDirectory, + 0, + &ObjectAttributes); if (!NT_SUCCESS(Status)) - { - DPRINT("Could not create \\Windows\\WindowStations directory (Status 0x%X)\n", Status); - return Status; - } + { + DPRINT("Could not create \\Windows\\WindowStations directory " + "(Status 0x%X)\n", Status); + return Status; + } return STATUS_SUCCESS; } @@ -71,48 +68,46 @@ CleanupWindowStationImpl(VOID) NTSTATUS -ValidateWindowStationHandle( - HWINSTA WindowStation, - KPROCESSOR_MODE AccessMode, - ACCESS_MASK DesiredAccess, - PWINSTATION_OBJECT *Object) +ValidateWindowStationHandle(HWINSTA WindowStation, + KPROCESSOR_MODE AccessMode, + ACCESS_MASK DesiredAccess, + PWINSTATION_OBJECT *Object) { NTSTATUS Status; - - Status = ObReferenceObjectByHandle( - WindowStation, - DesiredAccess, - ExWindowStationObjectType, - AccessMode, - (PVOID*)Object, - NULL); - if (!NT_SUCCESS(Status)) { - SetLastNtError(Status); - } - + + Status = ObReferenceObjectByHandle(WindowStation, + DesiredAccess, + ExWindowStationObjectType, + AccessMode, + (PVOID*)Object, + NULL); + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + } + return Status; } NTSTATUS -ValidateDesktopHandle( - HDESK Desktop, - KPROCESSOR_MODE AccessMode, - ACCESS_MASK DesiredAccess, - PDESKTOP_OBJECT *Object) +ValidateDesktopHandle(HDESK Desktop, + KPROCESSOR_MODE AccessMode, + ACCESS_MASK DesiredAccess, + PDESKTOP_OBJECT *Object) { NTSTATUS Status; - Status = ObReferenceObjectByHandle( - Desktop, - DesiredAccess, - ExDesktopObjectType, - AccessMode, - (PVOID*)Object, - NULL); - if (!NT_SUCCESS(Status)) { - SetLastNtError(Status); - } - + Status = ObReferenceObjectByHandle(Desktop, + DesiredAccess, + ExDesktopObjectType, + AccessMode, + (PVOID*)Object, + NULL); + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + } + return Status; } @@ -372,29 +367,31 @@ NtUserSetObjectInformation( * RETURNS: * Status */ -BOOL -STDCALL -NtUserSetProcessWindowStation( - HWINSTA hWindowStation) +BOOL STDCALL +NtUserSetProcessWindowStation(HWINSTA hWindowStation) { PWINSTATION_OBJECT Object; NTSTATUS Status; - DPRINT("About to set process window station with handle (0x%X)\n", hWindowStation); - - Status = ValidateWindowStationHandle( - hWindowStation, - KernelMode, - 0, - &Object); - if (!NT_SUCCESS(Status)) { - DPRINT("Validation of window station handle (0x%X) failed\n", hWindowStation); - return FALSE; - } + DPRINT("About to set process window station with handle (0x%X)\n", + hWindowStation); + Status = ValidateWindowStationHandle(hWindowStation, + KernelMode, + 0, + &Object); + if (!NT_SUCCESS(Status)) + { + DPRINT("Validation of window station handle (0x%X) failed\n", + hWindowStation); + return FALSE; + } + ObDereferenceObject(Object); SET_PROCESS_WINDOW_STATION(hWindowStation); + DPRINT("IoGetCurrentProcess()->Win32WindowStation 0x%X\n", + IoGetCurrentProcess()->Win32WindowStation); return TRUE; }